File indexing completed on 2024-04-21 04:58:21

0001 /*  This file is part of the KDE project
0002 
0003     SPDX-FileCopyrightText: 2002-2003 Konqueror Developers <konq-e@kde.org>
0004     SPDX-FileCopyrightText: 2002-2003 Douglas Hanley <douglash@caltech.edu>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #include "konqtabs.h"
0010 
0011 #include <QApplication>
0012 #include <QClipboard>
0013 #include <QMenu>
0014 #include <QDrag>
0015 #include <QIcon>
0016 #include <QMimeData>
0017 
0018 #include <kcolorscheme.h>
0019 #include "konqdebug.h"
0020 #include <kiconloader.h>
0021 #include <KLocalizedString>
0022 #include <kstringhandler.h>
0023 #include <KUrlMimeData>
0024 
0025 #include "konqview.h"
0026 #include "konqviewmanager.h"
0027 #include "konqmisc.h"
0028 #include "konqsettingsxt.h"
0029 #include "konqframevisitor.h"
0030 
0031 #include <kacceleratormanager.h>
0032 #include <konqpixmapprovider.h>
0033 #include <kstandardshortcut.h>
0034 #include "ktabbar.h"
0035 
0036 //###################################################################
0037 
0038 KonqFrameTabs::KonqFrameTabs(QWidget *parent, KonqFrameContainerBase *parentContainer,
0039                              KonqViewManager *viewManager)
0040     : KTabWidget(parent),
0041       m_pPopupMenu(nullptr),
0042       m_pSubPopupMenuTab(nullptr),
0043       m_rightWidget(nullptr), m_leftWidget(nullptr), m_alwaysTabBar(false), m_forceHideTabBar(false)
0044 {
0045     // Set an object name so the widget style can identify this widget.
0046     setObjectName(QStringLiteral("kde_konq_tabwidget"));
0047     setDocumentMode(true);
0048 
0049     KAcceleratorManager::setNoAccel(this);
0050 
0051     tabBar()->setWhatsThis(i18n("This bar contains the list of currently open tabs. Click on a tab to make it "
0052                                 "active. You can also use keyboard shortcuts to "
0053                                 "navigate through tabs. The text on the tab shows the content "
0054                                 "currently open in it; place your mouse over the tab to see the full title, in "
0055                                 "case it has been shortened to fit the tab width."));
0056     //qCDebug(KONQUEROR_LOG) << "KonqFrameTabs::KonqFrameTabs()";
0057 
0058     m_pParentContainer = parentContainer;
0059     m_pActiveChild = nullptr;
0060     m_pViewManager = viewManager;
0061 
0062     m_permanentCloseButtons = KonqSettings::permanentCloseButton();
0063     if (m_permanentCloseButtons) {
0064         setTabsClosable(true);
0065     }
0066     tabBar()->setSelectionBehaviorOnRemove(
0067         KonqSettings::tabCloseActivatePrevious() ? QTabBar::SelectPreviousTab : QTabBar::SelectRightTab);
0068 
0069     applyTabBarPositionOption();
0070 
0071     connect(this, &KonqFrameTabs::tabCloseRequested, this, &KonqFrameTabs::slotCloseRequest);
0072     connect(this, SIGNAL(removeTabPopup()),
0073             m_pViewManager->mainWindow(), SLOT(slotRemoveTabPopup()));
0074 
0075     if (KonqSettings::addTabButton()) {
0076         m_leftWidget = new NewTabToolButton(this);
0077         connect(m_leftWidget, SIGNAL(clicked()),
0078                 m_pViewManager->mainWindow(), SLOT(slotAddTab()));
0079         connect(m_leftWidget, SIGNAL(testCanDecode(const QDragMoveEvent*,bool&)),
0080                 SLOT(slotTestCanDecode(const QDragMoveEvent*,bool&)));
0081         connect(m_leftWidget, SIGNAL(receivedDropEvent(QDropEvent*)),
0082                 SLOT(slotReceivedDropEvent(QDropEvent*)));
0083         m_leftWidget->setIcon(QIcon::fromTheme(QStringLiteral("tab-new")));
0084         m_leftWidget->adjustSize();
0085         m_leftWidget->setToolTip(i18n("Open a new tab"));
0086         setCornerWidget(m_leftWidget, Qt::TopLeftCorner);
0087     }
0088     if (KonqSettings::closeTabButton()) {
0089         m_rightWidget = new QToolButton(this);
0090         connect(m_rightWidget, SIGNAL(clicked()),
0091                 m_pViewManager->mainWindow(), SLOT(slotRemoveTab()));
0092         m_rightWidget->setIcon(QIcon::fromTheme(QStringLiteral("tab-close")));
0093         m_rightWidget->adjustSize();
0094         m_rightWidget->setToolTip(i18n("Close the current tab"));
0095         setCornerWidget(m_rightWidget, Qt::TopRightCorner);
0096     }
0097 
0098     setAutomaticResizeTabs(true);
0099     setMovable(true);
0100 
0101     connect(tabBar(), SIGNAL(tabMoved(int,int)),
0102             SLOT(slotMovedTab(int,int)));
0103     connect(this, SIGNAL(mouseMiddleClick()),
0104             SLOT(slotMouseMiddleClick()));
0105     connect(this, SIGNAL(mouseMiddleClick(QWidget*)),
0106             SLOT(slotMouseMiddleClick(QWidget*)));
0107     connect(this, SIGNAL(mouseDoubleClick()),
0108             m_pViewManager->mainWindow(), SLOT(slotAddTab()));
0109 
0110     connect(this, SIGNAL(testCanDecode(const QDragMoveEvent*,bool&)),
0111             SLOT(slotTestCanDecode(const QDragMoveEvent*,bool&)));
0112     connect(this, SIGNAL(receivedDropEvent(QDropEvent*)),
0113             SLOT(slotReceivedDropEvent(QDropEvent*)));
0114     connect(this, SIGNAL(receivedDropEvent(QWidget*,QDropEvent*)),
0115             SLOT(slotReceivedDropEvent(QWidget*,QDropEvent*)));
0116     connect(this, SIGNAL(initiateDrag(QWidget*)),
0117             SLOT(slotInitiateDrag(QWidget*)));
0118 
0119     tabBar()->installEventFilter(this);
0120     initPopupMenu();
0121 }
0122 
0123 KonqFrameTabs::~KonqFrameTabs()
0124 {
0125     //qCDebug(KONQUEROR_LOG) << "KonqFrameTabs::~KonqFrameTabs() " << this << " - " << className();
0126     qDeleteAll(m_childFrameList);
0127     m_childFrameList.clear();
0128 }
0129 
0130 void KonqFrameTabs::saveConfig(KConfigGroup &config, const QString &prefix, const KonqFrameBase::Options &options,
0131                                KonqFrameBase *docContainer, int id, int depth)
0132 {
0133     //write children
0134     QStringList strlst;
0135     int i = 0;
0136     QString newPrefix;
0137     for (KonqFrameBase *frame: m_childFrameList) {
0138         newPrefix = KonqFrameBase::frameTypeToString(frame->frameType()) + 'T' + QString::number(i);
0139         strlst.append(newPrefix);
0140         newPrefix.append(QLatin1Char('_'));
0141         frame->saveConfig(config, newPrefix, options, docContainer, id, depth + i);
0142         i++;
0143     }
0144 
0145     config.writeEntry(QStringLiteral("Children").prepend(prefix), strlst);
0146 
0147     config.writeEntry(QStringLiteral("activeChildIndex").prepend(prefix),
0148                       currentIndex());
0149 }
0150 
0151 void KonqFrameTabs::copyHistory(KonqFrameBase *other)
0152 {
0153 
0154     if (!other) {
0155         qCDebug(KONQUEROR_LOG) << "The Frame does not exist";
0156         return;
0157     }
0158 
0159     if (other->frameType() != KonqFrameBase::Tabs) {
0160         qCDebug(KONQUEROR_LOG) << "Frame types are not the same";
0161         return;
0162     }
0163 
0164     for (int i = 0; i < m_childFrameList.count(); i++) {
0165         m_childFrameList.at(i)->copyHistory(static_cast<KonqFrameTabs *>(other)->m_childFrameList.at(i));
0166     }
0167 }
0168 
0169 void KonqFrameTabs::setTitle(const QString &title, QWidget *sender)
0170 {
0171     // qCDebug(KONQUEROR_LOG) << "KonqFrameTabs::setTitle( " << title << " , " << sender << " )";
0172     // Make sure that '&' is displayed correctly
0173     QString tabText(title);
0174     setTabText(indexOf(sender), tabText.replace('&', QLatin1String("&&")));
0175 }
0176 
0177 void KonqFrameTabs::setTabIcon(const QUrl &url, QWidget *sender)
0178 {
0179     //qCDebug(KONQUEROR_LOG) << "KonqFrameTabs::setTabIcon( " << url << " , " << sender << " )";
0180     QIcon iconSet = QIcon::fromTheme(KonqPixmapProvider::self()->iconNameFor(url));
0181     const int pos = indexOf(sender);
0182     KTabWidget::setTabIcon(pos, iconSet);
0183 }
0184 
0185 void KonqFrameTabs::activateChild()
0186 {
0187     if (m_pActiveChild) {
0188         setCurrentIndex(indexOf(m_pActiveChild->asQWidget()));
0189         m_pActiveChild->activateChild();
0190     }
0191 }
0192 
0193 void KonqFrameTabs::insertChildFrame(KonqFrameBase *frame, int index)
0194 {
0195     //qCDebug(KONQUEROR_LOG) << "KonqFrameTabs " << this << ": insertChildFrame " << frame;
0196 
0197     if (!frame) {
0198         qCWarning(KONQUEROR_LOG) << "KonqFrameTabs " << this << ": insertChildFrame(0) !";
0199         return;
0200     }
0201 
0202     //qCDebug(KONQUEROR_LOG) << "Adding frame";
0203 
0204     //QTabWidget docs say that inserting tabs while already shown causes
0205     //flicker...
0206     setUpdatesEnabled(false);
0207 
0208     frame->setParentContainer(this);
0209     if (index == -1) {
0210         m_childFrameList.append(frame);
0211     } else {
0212         m_childFrameList.insert(index, frame);
0213     }
0214 
0215     // note that this can call slotCurrentChanged (e.g. when inserting/replacing the first tab)
0216     insertTab(index, frame->asQWidget(), QLatin1String(""));
0217 
0218     // Connect to currentChanged only after inserting the first tab,
0219     // otherwise insertTab() can call slotCurrentChanged, which we don't expect
0220     // (the part isn't in the partmanager yet; better let konqviewmanager take care
0221     // of setting the active part)
0222     connect(this, SIGNAL(currentChanged(int)),
0223             this, SLOT(slotCurrentChanged(int)), Qt::UniqueConnection);
0224 
0225     if (KonqView *activeChildView = frame->activeChildView()) {
0226         activeChildView->setCaption(activeChildView->caption());
0227         //TODO KF6: check whether requestedUrl or realUrl is more suitable here
0228         activeChildView->setTabIcon(activeChildView->url());
0229     }
0230 
0231     updateTabBarVisibility();
0232     setUpdatesEnabled(true);
0233 }
0234 
0235 void KonqFrameTabs::childFrameRemoved(KonqFrameBase *frame)
0236 {
0237     //qCDebug(KONQUEROR_LOG) << "KonqFrameTabs::RemoveChildFrame " << this << ". Child " << frame << " removed";
0238     if (frame) {
0239         removeTab(indexOf(frame->asQWidget()));
0240         m_childFrameList.removeAll(frame);
0241         if (count() == 1) {
0242             updateTabBarVisibility();
0243         }
0244     } else {
0245         qCWarning(KONQUEROR_LOG) << "KonqFrameTabs " << this << ": childFrameRemoved(0L) !";
0246     }
0247 
0248     //qCDebug(KONQUEROR_LOG) << "KonqFrameTabs::RemoveChildFrame finished";
0249 }
0250 
0251 void KonqFrameTabs::moveTabBackward(int index)
0252 {
0253     if (index == 0) {
0254         return;
0255     }
0256     tabBar()->moveTab(index, index - 1);
0257 }
0258 
0259 void KonqFrameTabs::moveTabForward(int index)
0260 {
0261     if (index == count() - 1) {
0262         return;
0263     }
0264     tabBar()->moveTab(index, index + 1);
0265 }
0266 
0267 void KonqFrameTabs::slotMovedTab(int from, int to)
0268 {
0269     KonqFrameBase *fromFrame = m_childFrameList.at(from);
0270     m_childFrameList.removeAll(fromFrame);
0271     m_childFrameList.insert(to, fromFrame);
0272 
0273     KonqFrameBase *currentFrame = dynamic_cast<KonqFrameBase *>(currentWidget());
0274     if (currentFrame && !m_pViewManager->isLoadingProfile()) {
0275         m_pActiveChild = currentFrame;
0276         currentFrame->activateChild();
0277     }
0278 }
0279 
0280 void KonqFrameTabs::slotContextMenu(const QPoint &p)
0281 {
0282     refreshSubPopupMenuTab();
0283     m_popupActions[QStringLiteral("reload")]->setEnabled(false);
0284     m_popupActions[QStringLiteral("duplicatecurrenttab")]->setEnabled(false);
0285     m_popupActions[QStringLiteral("breakoffcurrenttab")]->setEnabled(false);
0286     m_popupActions[QStringLiteral("removecurrenttab")]->setEnabled(false);
0287     m_popupActions[QStringLiteral("othertabs")]->setEnabled(true);
0288     m_popupActions[QStringLiteral("closeothertabs")]->setEnabled(false);
0289 
0290     m_pPopupMenu->exec(p);
0291 }
0292 
0293 void KonqFrameTabs::slotContextMenu(QWidget *w, const QPoint &p)
0294 {
0295     refreshSubPopupMenuTab();
0296     uint tabCount = m_childFrameList.count();
0297     m_popupActions[QStringLiteral("reload")]->setEnabled(true);
0298     m_popupActions[QStringLiteral("duplicatecurrenttab")]->setEnabled(true);
0299     m_popupActions[QStringLiteral("breakoffcurrenttab")]->setEnabled(tabCount > 1);
0300     m_popupActions[QStringLiteral("removecurrenttab")]->setEnabled(true);
0301     m_popupActions[QStringLiteral("othertabs")]->setEnabled(true);
0302     m_popupActions[QStringLiteral("closeothertabs")]->setEnabled(true);
0303 
0304     m_pViewManager->mainWindow()->setWorkingTab(indexOf(w));
0305     m_pPopupMenu->exec(p);
0306 }
0307 
0308 void KonqFrameTabs::refreshSubPopupMenuTab()
0309 {
0310     m_pSubPopupMenuTab->clear();
0311     int i = 0;
0312     m_pSubPopupMenuTab->addAction(QIcon::fromTheme(QStringLiteral("view-refresh")),
0313                                   i18n("&Reload All Tabs"),
0314                                   m_pViewManager->mainWindow(),
0315                                   SLOT(slotReloadAllTabs()),
0316                                   m_pViewManager->mainWindow()->action("reload_all_tabs")->shortcut());
0317     m_pSubPopupMenuTab->addSeparator();
0318     for (KonqFrameBase *frameBase: m_childFrameList) {
0319         KonqFrame *frame = dynamic_cast<KonqFrame *>(frameBase);
0320         if (frame && frame->activeChildView()) {
0321             QString title = frame->title().trimmed();
0322             const QUrl url = frame->activeChildView()->url();
0323             if (title.isEmpty()) {
0324                 title = url.toDisplayString();
0325             }
0326             title = KStringHandler::csqueeze(title, 50);
0327             QAction *action = m_pSubPopupMenuTab->addAction(QIcon::fromTheme(KonqPixmapProvider::self()->iconNameFor(url)), title);
0328             action->setData(i);
0329         }
0330         ++i;
0331     }
0332     m_pSubPopupMenuTab->addSeparator();
0333     m_popupActions[QStringLiteral("closeothertabs")] =
0334         m_pSubPopupMenuTab->addAction(QIcon::fromTheme(QStringLiteral("tab-close-other")),
0335                                       i18n("Close &Other Tabs"),
0336                                       m_pViewManager->mainWindow(),
0337                                       SLOT(slotRemoveOtherTabsPopup()),
0338                                       m_pViewManager->mainWindow()->action("removeothertabs")->shortcut());
0339 }
0340 
0341 void KonqFrameTabs::slotCloseRequest(int idx)
0342 {
0343     m_pViewManager->mainWindow()->setWorkingTab(idx);
0344     emit removeTabPopup();
0345 }
0346 
0347 void KonqFrameTabs::slotSubPopupMenuTabActivated(QAction *action)
0348 {
0349     setCurrentIndex(action->data().toInt());
0350 }
0351 
0352 void KonqFrameTabs::slotMouseMiddleClick()
0353 {
0354     KonqMainWindow *mainWindow = m_pViewManager->mainWindow();
0355     QUrl filteredURL(KonqMisc::konqFilteredURL(mainWindow, QApplication::clipboard()->text(QClipboard::Selection)));
0356     if (filteredURL.isValid() && filteredURL.scheme() != QLatin1String("error")) {
0357         KonqView *newView = m_pViewManager->addTab(QStringLiteral("text/html"), QString(), false, false);
0358         if (newView == nullptr) {
0359             return;
0360         }
0361         mainWindow->openUrl(newView, filteredURL, QString());
0362         m_pViewManager->showTab(newView);
0363         mainWindow->focusLocationBar();
0364     }
0365 }
0366 
0367 void KonqFrameTabs::slotMouseMiddleClick(QWidget *w)
0368 {
0369     QUrl filteredURL(KonqMisc::konqFilteredURL(m_pViewManager->mainWindow(), QApplication::clipboard()->text(QClipboard::Selection)));
0370     if (filteredURL.isValid() && filteredURL.scheme() != QLatin1String("error")) {
0371         KonqFrameBase *frame = dynamic_cast<KonqFrameBase *>(w);
0372         if (frame) {
0373             m_pViewManager->mainWindow()->openUrl(frame->activeChildView(), filteredURL);
0374         }
0375     }
0376 }
0377 
0378 void KonqFrameTabs::slotTestCanDecode(const QDragMoveEvent *e, bool &accept /* result */)
0379 {
0380     accept = e->mimeData()->hasUrls();
0381 }
0382 
0383 void KonqFrameTabs::slotReceivedDropEvent(QDropEvent *e)
0384 {
0385     QList<QUrl> lstDragURLs = KUrlMimeData::urlsFromMimeData(e->mimeData());
0386     if (!lstDragURLs.isEmpty()) {
0387         KonqView *newView = m_pViewManager->addTab(QStringLiteral("text/html"), QString(), false, false);
0388         if (newView == nullptr) {
0389             return;
0390         }
0391         m_pViewManager->mainWindow()->openUrl(newView, lstDragURLs.first(), QString());
0392         m_pViewManager->showTab(newView);
0393         m_pViewManager->mainWindow()->focusLocationBar();
0394     }
0395 }
0396 
0397 void KonqFrameTabs::slotReceivedDropEvent(QWidget *w, QDropEvent *e)
0398 {
0399     QList<QUrl> lstDragURLs = KUrlMimeData::urlsFromMimeData(e->mimeData());
0400     KonqFrameBase *frame = dynamic_cast<KonqFrameBase *>(w);
0401     if (lstDragURLs.count() && frame) {
0402         const QUrl dragUrl = lstDragURLs.first();
0403         if (dragUrl != frame->activeChildView()->url()) {
0404             emit openUrl(frame->activeChildView(), dragUrl);
0405         }
0406     }
0407 }
0408 
0409 void KonqFrameTabs::slotInitiateDrag(QWidget *w)
0410 {
0411     KonqFrameBase *frame = dynamic_cast<KonqFrameBase *>(w);
0412     if (frame) {
0413         QDrag *d = new QDrag(this);
0414         QMimeData *md = new QMimeData;
0415         md->setUrls(QList<QUrl>() << frame->activeChildView()->url());
0416         d->setMimeData(md);
0417         QString iconName = KIO::iconNameForUrl(frame->activeChildView()->url());
0418         d->setPixmap(KIconLoader::global()->loadIcon(iconName, KIconLoader::Small, 0));
0419         d->exec();
0420     }
0421 }
0422 
0423 void KonqFrameTabs::updateTabBarVisibility()
0424 {
0425     if (m_forceHideTabBar) {
0426         tabBar()->hide();
0427     } else if (m_alwaysTabBar) {
0428         tabBar()->show();
0429     } else {
0430         tabBar()->setVisible(count() > 1);
0431     }
0432 }
0433 
0434 void KonqFrameTabs::setAlwaysTabbedMode(bool enable)
0435 {
0436     const bool update = (enable != m_alwaysTabBar);
0437     m_alwaysTabBar = enable;
0438     if (update) {
0439         updateTabBarVisibility();
0440     }
0441 }
0442 
0443 void KonqFrameTabs::forceHideTabBar(bool force)
0444 {
0445     if (m_forceHideTabBar != force) {
0446         m_forceHideTabBar = force;
0447         updateTabBarVisibility();
0448     }
0449 }
0450 
0451 
0452 void KonqFrameTabs::initPopupMenu()
0453 {
0454     m_pPopupMenu = new QMenu(this);
0455     m_popupActions[QStringLiteral("newtab")] = m_pPopupMenu->addAction(QIcon::fromTheme(QStringLiteral("tab-new")),
0456                                i18n("&New Tab"),
0457                                m_pViewManager->mainWindow(),
0458                                SLOT(slotAddTab()),
0459                                m_pViewManager->mainWindow()->action("newtab")->shortcut());
0460     m_popupActions[QStringLiteral("duplicatecurrenttab")] = m_pPopupMenu->addAction(QIcon::fromTheme(QStringLiteral("tab-duplicate")),
0461                                             i18n("&Duplicate Tab"),
0462                                             m_pViewManager->mainWindow(),
0463                                             SLOT(slotDuplicateTabPopup()),
0464                                             m_pViewManager->mainWindow()->action("duplicatecurrenttab")->shortcut());
0465     m_popupActions[QStringLiteral("reload")] = m_pPopupMenu->addAction(QIcon::fromTheme(QStringLiteral("view-refresh")),
0466                                i18n("&Reload Tab"),
0467                                m_pViewManager->mainWindow(),
0468                                SLOT(slotReloadPopup()),
0469                                m_pViewManager->mainWindow()->action("reload")->shortcut());
0470     m_pPopupMenu->addSeparator();
0471     m_pSubPopupMenuTab = new QMenu(this);
0472     m_popupActions[QStringLiteral("othertabs")] = m_pPopupMenu->addMenu(m_pSubPopupMenuTab);
0473     m_popupActions[QStringLiteral("othertabs")]->setText(i18n("Other Tabs"));
0474     connect(m_pSubPopupMenuTab, SIGNAL(triggered(QAction*)),
0475             this, SLOT(slotSubPopupMenuTabActivated(QAction*)));
0476     m_pPopupMenu->addSeparator();
0477     m_popupActions[QStringLiteral("breakoffcurrenttab")] = m_pPopupMenu->addAction(QIcon::fromTheme(QStringLiteral("tab-detach")),
0478                                            i18n("D&etach Tab"),
0479                                            m_pViewManager->mainWindow(),
0480                                            SLOT(slotBreakOffTabPopup()),
0481                                            m_pViewManager->mainWindow()->action("breakoffcurrenttab")->shortcut());
0482     m_pPopupMenu->addSeparator();
0483     m_popupActions[QStringLiteral("removecurrenttab")] = m_pPopupMenu->addAction(QIcon::fromTheme(QStringLiteral("tab-close")),
0484                                          i18n("&Close Tab"),
0485                                          m_pViewManager->mainWindow(),
0486                                          SLOT(slotRemoveTabPopup()),
0487                                          m_pViewManager->mainWindow()->action("removecurrenttab")->shortcut());
0488     connect(this, SIGNAL(contextMenu(QWidget*,QPoint)),
0489             SLOT(slotContextMenu(QWidget*,QPoint)));
0490     connect(this, SIGNAL(contextMenu(QPoint)),
0491             SLOT(slotContextMenu(QPoint)));
0492 
0493 }
0494 
0495 bool KonqFrameTabs::accept(KonqFrameVisitor *visitor)
0496 {
0497     if (!visitor->visit(this)) {
0498         return false;
0499     }
0500     if (visitor->visitAllTabs()) {
0501         for (KonqFrameBase *frame: m_childFrameList) {
0502             Q_ASSERT(frame);
0503             if (!frame->accept(visitor)) {
0504                 return false;
0505             }
0506         }
0507     } else {
0508         // visit only current tab
0509         if (m_pActiveChild) {
0510             if (!m_pActiveChild->accept(visitor)) {
0511                 return false;
0512             }
0513         }
0514     }
0515     if (!visitor->endVisit(this)) {
0516         return false;
0517     }
0518     return true;
0519 }
0520 
0521 void KonqFrameTabs::slotCurrentChanged(int index)
0522 {
0523     const KColorScheme colorScheme(QPalette::Active, KColorScheme::Window);
0524     tabBar()->setTabTextColor(index, colorScheme.foreground(KColorScheme::NormalText).color());
0525 
0526     KonqFrameBase *currentFrame = tabAt(index);
0527     if (currentFrame && !m_pViewManager->isLoadingProfile()) {
0528         m_pActiveChild = currentFrame;
0529         currentFrame->activateChild();
0530     }
0531 
0532     m_pViewManager->mainWindow()->linkableViewCountChanged();
0533 }
0534 
0535 int KonqFrameTabs::tabIndexContaining(KonqFrameBase *frame) const
0536 {
0537     KonqFrameBase *frameBase = frame;
0538     while (frameBase && frameBase->parentContainer() != this) {
0539         frameBase = frameBase->parentContainer();
0540     }
0541     if (frameBase) {
0542         return indexOf(frameBase->asQWidget());
0543     } else {
0544         return -1;
0545     }
0546 }
0547 
0548 int KonqFrameTabs::tabWhereActive(KonqFrameBase *frame) const
0549 {
0550     for (int i = 0; i < m_childFrameList.count(); i++) {
0551         KonqFrameBase *f = m_childFrameList.at(i);
0552         while (f && f != frame) {
0553             f = f->isContainer() ? static_cast<KonqFrameContainerBase *>(f)->activeChild() : nullptr;
0554         }
0555         if (f == frame) {
0556             return i;
0557         }
0558     }
0559     return -1;
0560 }
0561 
0562 void KonqFrameTabs::setLoading(KonqFrameBase *frame, bool loading)
0563 {
0564     const int pos = tabWhereActive(frame);
0565     if (pos == -1) {
0566         return;
0567     }
0568 
0569     const KColorScheme colorScheme(QPalette::Active, KColorScheme::Window);
0570     QColor color;
0571     if (loading) {
0572         color = colorScheme.foreground(KColorScheme::NeutralText).color(); // a tab is currently loading
0573     } else {
0574         if (currentIndex() != pos) {
0575             // another tab has newly loaded contents. Use "link" because you can click on it to read it.
0576             color = colorScheme.foreground(KColorScheme::LinkText).color();
0577         } else {
0578             // the current tab has finished loading.
0579             color = colorScheme.foreground(KColorScheme::NormalText).color();
0580         }
0581     }
0582     tabBar()->setTabTextColor(pos, color);
0583 }
0584 
0585 void KonqFrameTabs::replaceChildFrame(KonqFrameBase *oldFrame, KonqFrameBase *newFrame)
0586 {
0587     const int index = indexOf(oldFrame->asQWidget());
0588     childFrameRemoved(oldFrame);
0589     insertChildFrame(newFrame, index);
0590     setCurrentIndex(index);
0591 }
0592 
0593 KonqFrameBase *KonqFrameTabs::tabAt(int index) const
0594 {
0595     return dynamic_cast<KonqFrameBase *>(widget(index));
0596 }
0597 
0598 KonqFrameBase *KonqFrameTabs::currentTab() const
0599 {
0600     return tabAt(currentIndex());
0601 }
0602 
0603 bool KonqFrameTabs::eventFilter(QObject *watched, QEvent *event)
0604 {
0605     if (KonqSettings::mouseMiddleClickClosesTab()) {
0606         QTabBar *bar = tabBar();
0607         if (watched == bar &&
0608                 (event->type() == QEvent::MouseButtonPress ||
0609                  event->type() == QEvent::MouseButtonRelease)) {
0610             QMouseEvent *e = static_cast<QMouseEvent *>(event);
0611             if (e->button() == Qt::MiddleButton) {
0612                 if (event->type() == QEvent::MouseButtonRelease) {
0613                     const int index = bar->tabAt(e->pos());
0614                     slotCloseRequest(index);
0615                 }
0616                 e->accept();
0617                 return true;
0618             }
0619         }
0620     }
0621     return KTabWidget::eventFilter(watched, event);
0622 }
0623 
0624 void KonqFrameTabs::reparseConfiguration()
0625 {
0626     applyTabBarPositionOption();
0627 }
0628 
0629 void KonqFrameTabs::applyTabBarPositionOption()
0630 {
0631     int tabBarPosition = KonqSettings::tabBarPosition();
0632     if (tabBarPosition < North || tabBarPosition > East) {
0633         tabBarPosition = 0;
0634     }
0635     setTabPosition(static_cast<TabPosition>(tabBarPosition));
0636 }