Warning, file /network/falkon/src/lib/tabwidget/tabbar.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* ============================================================ 0002 * Falkon - Qt web browser 0003 * Copyright (C) 2010-2018 David Rosca <nowrep@gmail.com> 0004 * 0005 * This program is free software: you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation, either version 3 of the License, or 0008 * (at your option) any later version. 0009 * 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 * ============================================================ */ 0018 #include "tabbar.h" 0019 #include "tabwidget.h" 0020 #include "browserwindow.h" 0021 #include "webtab.h" 0022 #include "toolbutton.h" 0023 #include "settings.h" 0024 #include "mainapplication.h" 0025 #include "pluginproxy.h" 0026 #include "iconprovider.h" 0027 #include "tabcontextmenu.h" 0028 #include "searchenginesmanager.h" 0029 #include "tabmrumodel.h" 0030 0031 #include <QMimeData> 0032 #include <QMouseEvent> 0033 #include <QStyleOption> 0034 #include <QApplication> 0035 #include <QTimer> 0036 #include <QRect> 0037 #include <QLabel> 0038 #include <QScrollArea> 0039 #include <QHBoxLayout> 0040 #include <QDrag> 0041 0042 #define MIMETYPE QSL("application/falkon.tabbar.tab") 0043 0044 class TabBarTabMetrics : public QWidget 0045 { 0046 Q_OBJECT 0047 Q_PROPERTY(int normalMaxWidth READ normalMaxWidth WRITE setNormalMaxWidth) 0048 Q_PROPERTY(int normalMinWidth READ normalMinWidth WRITE setNormalMinWidth) 0049 Q_PROPERTY(int activeMinWidth READ activeMinWidth WRITE setActiveMinWidth) 0050 Q_PROPERTY(int overflowedWidth READ overflowedWidth WRITE setOverflowedWidth) 0051 Q_PROPERTY(int pinnedWidth READ pinnedWidth WRITE setPinnedWidth) 0052 0053 public: 0054 void init() 0055 { 0056 if (!m_metrics.isEmpty()) { 0057 return; 0058 } 0059 m_metrics[0] = 250; 0060 m_metrics[1] = 100; 0061 m_metrics[2] = 100; 0062 m_metrics[3] = 100; 0063 m_metrics[4] = -1; // Will be initialized from TabBar 0064 } 0065 0066 int normalMaxWidth() const { return m_metrics.value(0); } 0067 void setNormalMaxWidth(int value) { m_metrics[0] = value; } 0068 0069 int normalMinWidth() const { return m_metrics.value(1); } 0070 void setNormalMinWidth(int value) { m_metrics[1] = value; } 0071 0072 int activeMinWidth() const { return m_metrics.value(2); } 0073 void setActiveMinWidth(int value) { m_metrics[2] = value; } 0074 0075 int overflowedWidth() const { return m_metrics.value(3); } 0076 void setOverflowedWidth(int value) { m_metrics[3] = value; } 0077 0078 int pinnedWidth() const { return m_metrics.value(4); } 0079 void setPinnedWidth(int value) { m_metrics[4] = value; } 0080 0081 private: 0082 QHash<int, int> m_metrics; 0083 }; 0084 0085 Q_GLOBAL_STATIC(TabBarTabMetrics, tabMetrics) 0086 0087 TabBar::TabBar(BrowserWindow* window, TabWidget* tabWidget) 0088 : ComboTabBar() 0089 , m_window(window) 0090 , m_tabWidget(tabWidget) 0091 , m_hideTabBarWithOneTab(false) 0092 , m_showCloseOnInactive(0) 0093 , m_normalTabWidth(0) 0094 , m_activeTabWidth(0) 0095 , m_forceHidden(false) 0096 { 0097 setObjectName(QSL("tabbar")); 0098 setElideMode(Qt::ElideRight); 0099 setFocusPolicy(Qt::NoFocus); 0100 setTabsClosable(false); 0101 setMouseTracking(true); 0102 setDocumentMode(true); 0103 setAcceptDrops(true); 0104 setDrawBase(false); 0105 setMovable(true); 0106 0107 connect(this, &ComboTabBar::currentChanged, this, &TabBar::currentTabChanged); 0108 0109 // ComboTabBar features 0110 setUsesScrollButtons(true); 0111 setCloseButtonsToolTip(BrowserWindow::tr("Close Tab")); 0112 connect(this, &ComboTabBar::overFlowChanged, this, &TabBar::overflowChanged); 0113 0114 tabMetrics()->init(); 0115 0116 if (mApp->isPrivate()) { 0117 auto* privateBrowsing = new QLabel(this); 0118 privateBrowsing->setObjectName(QSL("private-browsing-icon")); 0119 privateBrowsing->setPixmap(IconProvider::privateBrowsingIcon().pixmap(16)); 0120 privateBrowsing->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); 0121 privateBrowsing->setFixedWidth(30); 0122 addCornerWidget(privateBrowsing, Qt::TopLeftCorner); 0123 } 0124 } 0125 0126 void TabBar::loadSettings() 0127 { 0128 Settings settings; 0129 settings.beginGroup(QSL("Browser-Tabs-Settings")); 0130 m_hideTabBarWithOneTab = settings.value(QSL("hideTabsWithOneTab"), false).toBool(); 0131 bool activateLastTab = settings.value(QSL("ActivateLastTabWhenClosingActual"), false).toBool(); 0132 m_showCloseOnInactive = settings.value(QSL("showCloseOnInactiveTabs"), 0).toInt(nullptr); 0133 settings.endGroup(); 0134 0135 setSelectionBehaviorOnRemove(activateLastTab ? QTabBar::SelectPreviousTab : QTabBar::SelectRightTab); 0136 setVisible(!(count() <= 1 && m_hideTabBarWithOneTab)); 0137 0138 setUpLayout(); 0139 } 0140 0141 TabWidget* TabBar::tabWidget() const 0142 { 0143 return m_tabWidget; 0144 } 0145 0146 void TabBar::setVisible(bool visible) 0147 { 0148 if (m_forceHidden) { 0149 ComboTabBar::setVisible(false); 0150 return; 0151 } 0152 0153 // Make sure to honor user preference 0154 if (visible) { 0155 visible = !(count() <= 1 && m_hideTabBarWithOneTab); 0156 } 0157 0158 ComboTabBar::setVisible(visible); 0159 } 0160 0161 void TabBar::setForceHidden(bool hidden) 0162 { 0163 m_forceHidden = hidden; 0164 setVisible(!m_forceHidden); 0165 } 0166 0167 void TabBar::overflowChanged(bool overflowed) 0168 { 0169 // Make sure close buttons on inactive tabs are hidden 0170 // This is needed for when leaving fullscreen from non-overflowed to overflowed state 0171 if (overflowed && m_showCloseOnInactive != 1) { 0172 setTabsClosable(false); 0173 showCloseButton(currentIndex()); 0174 } 0175 } 0176 0177 QSize TabBar::tabSizeHint(int index, bool fast) const 0178 { 0179 if (!m_window->isVisible()) { 0180 // Don't calculate it when window is not visible 0181 // It produces invalid size anyway 0182 return QSize(-1, -1); 0183 } 0184 0185 const int pinnedTabWidth = comboTabBarPixelMetric(ComboTabBar::PinnedTabWidth); 0186 const int minTabWidth = comboTabBarPixelMetric(ComboTabBar::NormalTabMinimumWidth); 0187 0188 QSize size = ComboTabBar::tabSizeHint(index); 0189 0190 // The overflowed tabs have same size and we can use this fast method 0191 if (fast) { 0192 size.setWidth(index >= pinnedTabsCount() ? minTabWidth : pinnedTabWidth); 0193 return size; 0194 } 0195 0196 auto* webTab = qobject_cast<WebTab*>(m_tabWidget->widget(index)); 0197 auto* tabBar = const_cast <TabBar*>(this); 0198 0199 if (webTab && webTab->isPinned()) { 0200 size.setWidth(pinnedTabWidth); 0201 } 0202 else { 0203 int availableWidth = mainTabBarWidth() - comboTabBarPixelMetric(ExtraReservedWidth); 0204 0205 if (availableWidth < 0) { 0206 return QSize(-1, -1); 0207 } 0208 0209 const int normalTabsCount = ComboTabBar::normalTabsCount(); 0210 const int maxTabWidth = comboTabBarPixelMetric(ComboTabBar::NormalTabMaximumWidth); 0211 0212 if (availableWidth >= maxTabWidth * normalTabsCount) { 0213 m_normalTabWidth = maxTabWidth; 0214 size.setWidth(m_normalTabWidth); 0215 } 0216 else if (normalTabsCount > 0) { 0217 const int minActiveTabWidth = comboTabBarPixelMetric(ComboTabBar::ActiveTabMinimumWidth); 0218 0219 int maxWidthForTab = availableWidth / normalTabsCount; 0220 int realTabWidth = maxWidthForTab; 0221 bool adjustingActiveTab = false; 0222 0223 if (realTabWidth < minActiveTabWidth) { 0224 maxWidthForTab = normalTabsCount > 1 ? (availableWidth - minActiveTabWidth) / (normalTabsCount - 1) : 0; 0225 realTabWidth = minActiveTabWidth; 0226 adjustingActiveTab = true; 0227 } 0228 0229 bool tryAdjusting = availableWidth >= minTabWidth * normalTabsCount; 0230 0231 if (m_showCloseOnInactive != 1 && tabsClosable() && availableWidth < (minTabWidth + 25) * normalTabsCount) { 0232 // Hiding close buttons to save some space 0233 tabBar->setTabsClosable(false); 0234 tabBar->showCloseButton(currentIndex()); 0235 } 0236 if (m_showCloseOnInactive == 1) { 0237 // Always showing close buttons 0238 tabBar->setTabsClosable(true); 0239 tabBar->showCloseButton(currentIndex()); 0240 } 0241 0242 if (tryAdjusting) { 0243 m_normalTabWidth = maxWidthForTab; 0244 0245 // Fill any empty space (we've got from rounding) with active tab 0246 if (index == mainTabBarCurrentIndex()) { 0247 if (adjustingActiveTab) { 0248 m_activeTabWidth = (availableWidth - minActiveTabWidth 0249 - maxWidthForTab * (normalTabsCount - 1)) + realTabWidth; 0250 } 0251 else { 0252 m_activeTabWidth = (availableWidth - maxWidthForTab * normalTabsCount) + maxWidthForTab; 0253 } 0254 size.setWidth(m_activeTabWidth); 0255 } 0256 else { 0257 size.setWidth(m_normalTabWidth); 0258 } 0259 } 0260 } 0261 0262 // Restore close buttons according to preferences 0263 if (m_showCloseOnInactive != 2 && !tabsClosable() && availableWidth >= (minTabWidth + 25) * normalTabsCount) { 0264 tabBar->setTabsClosable(true); 0265 0266 // Hide close buttons on pinned tabs 0267 for (int i = 0; i < count(); ++i) { 0268 tabBar->updatePinnedTabCloseButton(i); 0269 } 0270 } 0271 } 0272 0273 if (index == count() - 1) { 0274 auto* lastMainActiveTab = qobject_cast<WebTab*>(m_tabWidget->widget(mainTabBarCurrentIndex())); 0275 int xForAddTabButton = cornerWidth(Qt::TopLeftCorner) + pinTabBarWidth() + normalTabsCount() * m_normalTabWidth; 0276 0277 if (lastMainActiveTab && m_activeTabWidth > m_normalTabWidth) { 0278 xForAddTabButton += m_activeTabWidth - m_normalTabWidth; 0279 } 0280 0281 if (QApplication::layoutDirection() == Qt::RightToLeft) { 0282 xForAddTabButton = width() - xForAddTabButton; 0283 } 0284 0285 Q_EMIT tabBar->moveAddTabButton(xForAddTabButton); 0286 } 0287 0288 return size; 0289 } 0290 0291 int TabBar::comboTabBarPixelMetric(ComboTabBar::SizeType sizeType) const 0292 { 0293 switch (sizeType) { 0294 case ComboTabBar::PinnedTabWidth: 0295 return tabMetrics()->pinnedWidth() > 0 ? tabMetrics()->pinnedWidth() : 32; 0296 0297 case ComboTabBar::ActiveTabMinimumWidth: 0298 return tabMetrics()->activeMinWidth(); 0299 0300 case ComboTabBar::NormalTabMinimumWidth: 0301 return tabMetrics()->normalMinWidth(); 0302 0303 case ComboTabBar::OverflowedTabWidth: 0304 return tabMetrics()->overflowedWidth(); 0305 0306 case ComboTabBar::NormalTabMaximumWidth: 0307 return tabMetrics()->normalMaxWidth(); 0308 0309 case ComboTabBar::ExtraReservedWidth: 0310 return m_tabWidget->extraReservedWidth(); 0311 0312 default: 0313 break; 0314 } 0315 0316 return -1; 0317 } 0318 0319 WebTab* TabBar::webTab(int index) const 0320 { 0321 if (index == -1) { 0322 return qobject_cast<WebTab*>(m_tabWidget->widget(currentIndex())); 0323 } 0324 return qobject_cast<WebTab*>(m_tabWidget->widget(index)); 0325 } 0326 0327 void TabBar::showCloseButton(int index) 0328 { 0329 if (!validIndex(index)) { 0330 return; 0331 } 0332 0333 auto* webTab = qobject_cast<WebTab*>(m_tabWidget->widget(index)); 0334 auto* button = qobject_cast<QAbstractButton*>(tabButton(index, closeButtonPosition())); 0335 0336 if (button || (webTab && webTab->isPinned())) { 0337 return; 0338 } 0339 0340 insertCloseButton(index); 0341 } 0342 0343 void TabBar::contextMenuEvent(QContextMenuEvent* event) 0344 { 0345 if (isDragInProgress()) { 0346 return; 0347 } 0348 0349 int index = tabAt(event->pos()); 0350 0351 TabContextMenu menu(index, m_window); 0352 0353 // Prevent choosing first option with double rightclick 0354 const QPoint pos = event->globalPos(); 0355 QPoint p(pos.x(), pos.y() + 1); 0356 menu.exec(p); 0357 } 0358 0359 void TabBar::hideCloseButton(int index) 0360 { 0361 if (!validIndex(index) || tabsClosable()) { 0362 return; 0363 } 0364 0365 auto* button = qobject_cast<CloseButton*>(tabButton(index, closeButtonPosition())); 0366 if (!button) { 0367 return; 0368 } 0369 0370 setTabButton(index, closeButtonPosition(), nullptr); 0371 button->deleteLater(); 0372 } 0373 0374 void TabBar::updatePinnedTabCloseButton(int index) 0375 { 0376 if (!validIndex(index)) { 0377 return; 0378 } 0379 0380 auto* webTab = qobject_cast<WebTab*>(m_tabWidget->widget(index)); 0381 auto* button = qobject_cast<QAbstractButton*>(tabButton(index, closeButtonPosition())); 0382 0383 bool pinned = webTab && webTab->isPinned(); 0384 0385 if (pinned) { 0386 if (button) { 0387 button->hide(); 0388 } 0389 } 0390 else { 0391 if (button) { 0392 button->show(); 0393 } 0394 else { 0395 showCloseButton(index); 0396 } 0397 } 0398 } 0399 0400 void TabBar::closeTabFromButton() 0401 { 0402 QWidget* button = qobject_cast<QWidget*>(sender()); 0403 0404 int tabToClose = -1; 0405 0406 for (int i = 0; i < count(); ++i) { 0407 if (tabButton(i, closeButtonPosition()) == button) { 0408 tabToClose = i; 0409 break; 0410 } 0411 } 0412 0413 if (tabToClose != -1) { 0414 m_tabWidget->requestCloseTab(tabToClose); 0415 } 0416 } 0417 0418 void TabBar::currentTabChanged(int index) 0419 { 0420 if (!validIndex(index)) { 0421 return; 0422 } 0423 0424 // Don't hide close buttons when dragging tabs 0425 if (m_dragStartPosition.isNull() && !m_isRestoring) { 0426 showCloseButton(index); 0427 if (m_lastTab) { 0428 hideCloseButton(m_lastTab->tabIndex()); 0429 } 0430 QTimer::singleShot(100, this, [this]() { ensureVisible(); }); 0431 } 0432 0433 m_lastTab = webTab(index); 0434 m_tabWidget->currentTabChanged(index); 0435 } 0436 0437 void TabBar::setTabText(int index, const QString &text) 0438 { 0439 if (m_isRestoring) { 0440 return; 0441 } 0442 0443 QString tabText = text; 0444 0445 // Avoid Alt+letter shortcuts 0446 tabText.replace(QLatin1Char('&'), QLatin1String("&&")); 0447 0448 if (WebTab* tab = webTab(index)) { 0449 if (tab->isPinned()) { 0450 tabText.clear(); 0451 } 0452 } 0453 0454 setTabToolTip(index, text); 0455 ComboTabBar::setTabText(index, tabText); 0456 } 0457 0458 void TabBar::tabInserted(int index) 0459 { 0460 Q_UNUSED(index) 0461 0462 // Initialize pinned tab metrics 0463 if (tabMetrics()->pinnedWidth() == -1) { 0464 QTimer::singleShot(0, this, [this]() { 0465 if (tabMetrics()->pinnedWidth() != -1) { 0466 return; 0467 } 0468 QWidget *w = tabButton(0, iconButtonPosition()); 0469 if (w && w->parentWidget()) { 0470 const QRect wg = w->parentWidget()->geometry(); 0471 const QRect wr = QStyle::visualRect(layoutDirection(), wg, w->geometry()); 0472 tabMetrics()->setPinnedWidth(iconButtonSize().width() + wr.x() * 2); 0473 setUpLayout(); 0474 } 0475 }); 0476 } 0477 0478 setVisible(!(count() <= 1 && m_hideTabBarWithOneTab)); 0479 } 0480 0481 void TabBar::tabRemoved(int index) 0482 { 0483 Q_UNUSED(index) 0484 0485 showCloseButton(currentIndex()); 0486 setVisible(!(count() <= 1 && m_hideTabBarWithOneTab)); 0487 0488 // Make sure to move add tab button to correct position when there are no normal tabs 0489 if (normalTabsCount() == 0) { 0490 int xForAddTabButton = cornerWidth(Qt::TopLeftCorner) + pinTabBarWidth(); 0491 if (QApplication::layoutDirection() == Qt::RightToLeft) 0492 xForAddTabButton = width() - xForAddTabButton; 0493 Q_EMIT moveAddTabButton(xForAddTabButton); 0494 } 0495 } 0496 0497 void TabBar::mouseDoubleClickEvent(QMouseEvent* event) 0498 { 0499 if (mApp->plugins()->processMouseDoubleClick(Qz::ON_TabBar, this, event)) { 0500 return; 0501 } 0502 0503 if (event->buttons() == Qt::LeftButton && emptyArea(event->position().toPoint())) { 0504 m_tabWidget->addView(QUrl(), Qz::NT_SelectedTabAtTheEnd, true); 0505 return; 0506 } 0507 0508 ComboTabBar::mouseDoubleClickEvent(event); 0509 } 0510 0511 void TabBar::mousePressEvent(QMouseEvent* event) 0512 { 0513 ComboTabBar::mousePressEvent(event); 0514 0515 if (mApp->plugins()->processMousePress(Qz::ON_TabBar, this, event)) { 0516 return; 0517 } 0518 0519 if (event->buttons() == Qt::LeftButton && !emptyArea(event->position().toPoint())) { 0520 m_dragStartPosition = event->position().toPoint(); 0521 } else { 0522 m_dragStartPosition = QPoint(); 0523 } 0524 } 0525 0526 void TabBar::mouseMoveEvent(QMouseEvent* event) 0527 { 0528 ComboTabBar::mouseMoveEvent(event); 0529 0530 if (mApp->plugins()->processMouseMove(Qz::ON_TabBar, this, event)) { 0531 return; 0532 } 0533 0534 if (count() == 1 && mApp->windowCount() == 1) { 0535 return; 0536 } 0537 0538 if (!m_dragStartPosition.isNull()) { 0539 int offset = 0; 0540 const int eventY = event->position().toPoint().y(); 0541 if (eventY < 0) { 0542 offset = qAbs(eventY); 0543 } else if (eventY > height()) { 0544 offset = eventY - height(); 0545 } 0546 if (offset > QApplication::startDragDistance() * 3) { 0547 const QPoint global = mapToGlobal(m_dragStartPosition); 0548 QWidget *w = QApplication::widgetAt(global); 0549 if (w) { 0550 QMouseEvent mouse(QEvent::MouseButtonRelease, event->position(), w->mapFromGlobal(global), Qt::LeftButton, Qt::LeftButton, event->modifiers()); 0551 QApplication::sendEvent(w, &mouse); 0552 } 0553 auto *drag = new QDrag(this); 0554 auto *mime = new QMimeData; 0555 mime->setData(MIMETYPE, QByteArray()); 0556 drag->setMimeData(mime); 0557 drag->setPixmap(tabPixmap(currentIndex())); 0558 if (drag->exec() == Qt::IgnoreAction) { 0559 m_tabWidget->detachTab(currentIndex()); 0560 } 0561 return; 0562 } 0563 } 0564 } 0565 0566 void TabBar::mouseReleaseEvent(QMouseEvent* event) 0567 { 0568 ComboTabBar::mouseReleaseEvent(event); 0569 0570 m_dragStartPosition = QPoint(); 0571 0572 if (mApp->plugins()->processMouseRelease(Qz::ON_TabBar, this, event)) { 0573 return; 0574 } 0575 0576 if (!rect().contains(event->position().toPoint())) { 0577 ComboTabBar::mouseReleaseEvent(event); 0578 return; 0579 } 0580 0581 if (event->button() == Qt::MiddleButton) { 0582 if (emptyArea(event->position().toPoint())) { 0583 m_tabWidget->addView(QUrl(), Qz::NT_SelectedTabAtTheEnd, true); 0584 return; 0585 } 0586 0587 int id = tabAt(event->position().toPoint()); 0588 if (id != -1) { 0589 m_tabWidget->requestCloseTab(id); 0590 return; 0591 } 0592 } 0593 } 0594 0595 void TabBar::wheelEvent(QWheelEvent* event) 0596 { 0597 if (mApp->plugins()->processWheelEvent(Qz::ON_TabBar, this, event)) { 0598 return; 0599 } 0600 0601 ComboTabBar::wheelEvent(event); 0602 } 0603 0604 enum TabDropAction { 0605 NoAction, 0606 SelectTab, 0607 PrependTab, 0608 AppendTab 0609 }; 0610 0611 static TabDropAction tabDropAction(const QPoint &pos, const QRect &tabRect, bool allowSelect) 0612 { 0613 if (!tabRect.contains(pos)) { 0614 return NoAction; 0615 } 0616 0617 const QPoint c = tabRect.center(); 0618 const QSize csize = QSize(tabRect.width() * 0.7, tabRect.height() * 0.7); 0619 const QRect center(c.x() - csize.width() / 2, c.y() - csize.height() / 2, csize.width(), csize.height()); 0620 0621 if (allowSelect && center.contains(pos)) { 0622 return SelectTab; 0623 } else if (pos.x() < c.x()) { 0624 return PrependTab; 0625 } else { 0626 return AppendTab; 0627 } 0628 } 0629 0630 void TabBar::dragEnterEvent(QDragEnterEvent* event) 0631 { 0632 const QMimeData* mime = event->mimeData(); 0633 0634 if (mime->hasText() || mime->hasUrls() || (mime->hasFormat(MIMETYPE) && event->source())) { 0635 event->acceptProposedAction(); 0636 return; 0637 } 0638 0639 ComboTabBar::dragEnterEvent(event); 0640 } 0641 0642 void TabBar::dragMoveEvent(QDragMoveEvent *event) 0643 { 0644 const int index = tabAt(event->position().toPoint()); 0645 const QMimeData* mime = event->mimeData(); 0646 0647 if (index == -1) { 0648 ComboTabBar::dragMoveEvent(event); 0649 return; 0650 } 0651 0652 switch (tabDropAction(event->position().toPoint(), tabRect(index), !mime->hasFormat(MIMETYPE))) { 0653 case PrependTab: 0654 showDropIndicator(index, BeforeTab); 0655 break; 0656 case AppendTab: 0657 showDropIndicator(index, AfterTab); 0658 break; 0659 default: 0660 clearDropIndicator(); 0661 break; 0662 } 0663 } 0664 0665 void TabBar::dragLeaveEvent(QDragLeaveEvent *event) 0666 { 0667 clearDropIndicator(); 0668 0669 ComboTabBar::dragLeaveEvent(event); 0670 } 0671 0672 void TabBar::dropEvent(QDropEvent* event) 0673 { 0674 clearDropIndicator(); 0675 0676 const QMimeData* mime = event->mimeData(); 0677 0678 if (!mime->hasText() && !mime->hasUrls() && !mime->hasFormat(MIMETYPE)) { 0679 ComboTabBar::dropEvent(event); 0680 return; 0681 } 0682 0683 event->acceptProposedAction(); 0684 0685 auto *sourceTabBar = qobject_cast<TabBar*>(event->source()); 0686 0687 int index = tabAt(event->position().toPoint()); 0688 if (index == -1) { 0689 if (mime->hasUrls()) { 0690 const auto urls = mime->urls(); 0691 for (const QUrl &url : urls) { 0692 m_tabWidget->addView(url, Qz::NT_SelectedTabAtTheEnd); 0693 } 0694 } else if (mime->hasText()) { 0695 m_tabWidget->addView(mApp->searchEnginesManager()->searchResult(mime->text()), Qz::NT_SelectedNewEmptyTab); 0696 } else if (mime->hasFormat(MIMETYPE) && sourceTabBar) { 0697 WebTab *tab = sourceTabBar->webTab(); 0698 if (tab) { 0699 sourceTabBar->m_tabWidget->detachTab(tab); 0700 tab->setPinned(false); 0701 m_tabWidget->addView(tab, Qz::NT_SelectedTab); 0702 } 0703 } 0704 } else { 0705 LoadRequest req; 0706 WebTab* tab = m_tabWidget->webTab(index); 0707 TabDropAction action = tabDropAction(event->position().toPoint(), tabRect(index), !mime->hasFormat(MIMETYPE)); 0708 if (mime->hasUrls()) { 0709 req = mime->urls().at(0); 0710 } else if (mime->hasText()) { 0711 req = mApp->searchEnginesManager()->searchResult(mime->text()); 0712 } 0713 if (action == SelectTab) { 0714 if (req.isValid()) { 0715 tab->load(req); 0716 } 0717 } else if (action == PrependTab || action == AppendTab) { 0718 const int newIndex = action == PrependTab ? index : index + 1; 0719 if (req.isValid()) { 0720 m_tabWidget->addView(req, QString(), Qz::NT_SelectedNewEmptyTab, false, newIndex, index < pinnedTabsCount()); 0721 } else if (mime->hasFormat(MIMETYPE) && sourceTabBar) { 0722 WebTab *tab = sourceTabBar->webTab(); 0723 if (tab) { 0724 if (sourceTabBar == this) { 0725 tab->moveTab(newIndex > tab->tabIndex() ? newIndex - 1 : newIndex); 0726 } else { 0727 sourceTabBar->m_tabWidget->detachTab(tab); 0728 tab->setPinned(index < pinnedTabsCount()); 0729 m_tabWidget->insertView(newIndex, tab, Qz::NT_SelectedTab); 0730 } 0731 } 0732 } 0733 } 0734 } 0735 } 0736 0737 void TabBar::setIsRestoring(bool restoring) 0738 { 0739 m_isRestoring = restoring; 0740 } 0741 0742 bool TabBar::isRestoring() 0743 { 0744 return m_isRestoring; 0745 } 0746 0747 #include "tabbar.moc"