File indexing completed on 2024-04-14 04:53:16
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 1998-2005 David Faure <faure@kde.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "konqview.h" 0009 0010 #include "KonqViewAdaptor.h" 0011 #include "konqsettingsxt.h" 0012 #include "konqframestatusbar.h" 0013 #include "urlloader.h" 0014 #include <konq_events.h> 0015 #include "konqviewmanager.h" 0016 #include "konqtabs.h" 0017 #include "konqhistorymanager.h" 0018 #include "konqpixmapprovider.h" 0019 #include "implementations/konqbrowserwindowinterface.h" 0020 #include "interfaces/downloaderextension.h" 0021 #include "browserarguments.h" 0022 #include "browserextension.h" 0023 #include "placeholderpart.h" 0024 #include "konqurl.h" 0025 0026 #include <kio/job.h> 0027 #include <kio/jobuidelegate.h> 0028 #include "konqdebug.h" 0029 #include <kcursor.h> 0030 #include <kmessagebox.h> 0031 #include <KLocalizedString> 0032 #include <ktoggleaction.h> 0033 #include <kjobuidelegate.h> 0034 #include <KUrlMimeData> 0035 #include <KIO/CopyJob> 0036 #include <KFileUtils> 0037 0038 #include <QApplication> 0039 #include <QArgument> 0040 #include <QFile> 0041 #include <QDropEvent> 0042 #include <QDBusConnection> 0043 #include <QMimeData> 0044 #include <QFileInfo> 0045 #include <QDir> 0046 0047 #include <config-konqueror.h> 0048 0049 #ifdef KActivities_FOUND 0050 #if QT_VERSION_MAJOR < 6 0051 #include <KActivities/ResourceInstance> 0052 #else //QT_VERSION_MAJOR 0053 #include <PlasmaActivities/ResourceInstance> 0054 #endif //QT_VERSION_MAJOR 0055 #endif //KActivities_FOUND 0056 0057 #include <kparts_version.h> 0058 0059 #include <KJobWidgets> 0060 #include <KParts/Part> 0061 #include <KParts/StatusBarExtension> 0062 #include <KParts/ReadOnlyPart> 0063 #include <KParts/OpenUrlEvent> 0064 #include <KParts/OpenUrlArguments> 0065 #include <QMimeDatabase> 0066 0067 //#define DEBUG_HISTORY 0068 0069 KonqView::KonqView(KonqFrame *viewFrame, KonqMainWindow *mainWindow) : 0070 m_pPart{nullptr}, 0071 m_pageSecurity{KonqMainWindow::NotCrypted}, 0072 m_lstHistoryIndex{-1}, 0073 m_doPost{false}, 0074 m_pMainWindow{mainWindow}, 0075 m_loader{nullptr}, 0076 m_pKonqFrame{viewFrame}, 0077 m_bLoading{false}, 0078 m_bLockedLocation{false}, 0079 m_bPassiveMode{false}, 0080 m_bLinkedView{false}, 0081 m_bToggleView{false}, 0082 m_bLockHistory{false}, 0083 m_bAborted{false}, 0084 m_bGotIconURL{false}, 0085 m_bPopupMenuEnabled{true}, 0086 m_bFollowActive{false}, 0087 m_bPendingRedirection{false}, 0088 m_bBuiltinView{true}, 0089 m_bURLDropHandling{false}, 0090 m_bDisableScrolling{false}, 0091 m_bErrorURL{false} 0092 #if QT_VERSION_MAJOR < 6 0093 #ifdef KActivities_FOUND 0094 , m_activityResourceInstance{new KActivities::ResourceInstance(mainWindow->winId(), this)} 0095 #endif 0096 #endif 0097 { 0098 m_pKonqFrame->setView(this); 0099 KonqViewFactory factory; 0100 switchView(factory, true); 0101 } 0102 0103 KonqView::KonqView(KonqViewFactory &viewFactory, 0104 KonqFrame *viewFrame, 0105 KonqMainWindow *mainWindow, 0106 const KPluginMetaData &service, 0107 const QVector<KPluginMetaData> &partServiceOffers, 0108 const KService::List &appServiceOffers, 0109 const QString &serviceType, 0110 bool passiveMode 0111 ) 0112 { 0113 m_pKonqFrame = viewFrame; 0114 m_pKonqFrame->setView(this); 0115 0116 m_sLocationBarURL = QLatin1String(""); 0117 m_pageSecurity = KonqMainWindow::NotCrypted; 0118 m_bLockHistory = false; 0119 m_doPost = false; 0120 m_pMainWindow = mainWindow; 0121 m_loader = nullptr; 0122 m_pPart = nullptr; 0123 0124 m_service = service; 0125 m_partServiceOffers = partServiceOffers; 0126 m_appServiceOffers = appServiceOffers; 0127 m_serviceType = serviceType; 0128 0129 m_lstHistoryIndex = -1; 0130 m_bLoading = false; 0131 m_bPendingRedirection = false; 0132 m_bPassiveMode = passiveMode; 0133 m_bLockedLocation = false; 0134 m_bLinkedView = false; 0135 m_bAborted = false; 0136 m_bToggleView = false; 0137 m_bDisableScrolling = false; 0138 m_bGotIconURL = false; 0139 m_bPopupMenuEnabled = true; 0140 m_bFollowActive = false; 0141 m_bBuiltinView = false; 0142 m_bURLDropHandling = false; 0143 m_bErrorURL = false; 0144 0145 #if QT_VERSION_MAJOR < 6 0146 #ifdef KActivities_FOUND 0147 m_activityResourceInstance = new KActivities::ResourceInstance(mainWindow->winId(), this); 0148 #endif 0149 #endif 0150 0151 switchView(viewFactory); 0152 } 0153 0154 KonqView::~KonqView() 0155 { 0156 //qCDebug(KONQUEROR_LOG) << "part=" << m_pPart; 0157 0158 // We did so ourselves for passive views 0159 if (m_pPart != nullptr) { 0160 finishedWithCurrentURL(); 0161 if (isPassiveMode()) { 0162 disconnect(m_pPart, SIGNAL(destroyed()), m_pMainWindow->viewManager(), SLOT(slotObjectDestroyed())); 0163 } 0164 0165 if (m_pPart->manager()) { 0166 m_pPart->manager()->removePart(m_pPart); // ~Part does this, but we have to do it before (#213876, #207173) 0167 } 0168 0169 delete m_pPart; 0170 } 0171 0172 qDeleteAll(m_lstHistory); 0173 m_lstHistory.clear(); 0174 0175 setUrlLoader(nullptr); 0176 //qCDebug(KONQUEROR_LOG) << this << "done"; 0177 } 0178 0179 bool KonqView::isWebEngineView() const 0180 { 0181 return m_service.pluginId() == QLatin1String("webenginepart"); 0182 } 0183 0184 void KonqView::openUrl(const QUrl &url, const QString &locationBarURL, 0185 const QString &nameFilter, bool tempFile, const QUrl &requestedUrl) 0186 { 0187 qCDebug(KONQUEROR_LOG) << "url=" << url << "locationBarURL=" << locationBarURL; 0188 0189 setPartMimeType(); 0190 0191 KParts::OpenUrlArguments args; 0192 if (m_pPart) { 0193 args = m_pPart->arguments(); 0194 } 0195 0196 KParts::NavigationExtension *ext = browserExtension(); 0197 BrowserArguments browserArgs; 0198 if (BrowserExtension *browserExtension = qobject_cast<BrowserExtension *>(ext)) { 0199 browserArgs = browserExtension->browserArguments(); 0200 } 0201 0202 // Typing "Enter" again after the URL of an aborted view, triggers a reload. 0203 if (m_bAborted && m_pPart && m_pPart->url() == url && !browserArgs.doPost()) { 0204 if (!prepareReload(args, browserArgs, false /* not softReload */)) { 0205 return; 0206 } 0207 m_pPart->setArguments(args); 0208 } 0209 0210 #ifdef DEBUG_HISTORY 0211 qCDebug(KONQUEROR_LOG) << "m_bLockedLocation=" << m_bLockedLocation << "browserArgs.lockHistory()=" << browserArgs.lockHistory(); 0212 #endif 0213 if (browserArgs.lockHistory()) { 0214 lockHistory(); 0215 } 0216 0217 if (!m_bLockHistory) { 0218 // Store this new URL in the history, removing any existing forward history. 0219 // We do this first so that everything is ready if a part calls completed(). 0220 createHistoryEntry(); 0221 } else { 0222 m_bLockHistory = false; 0223 } 0224 0225 if (m_pPart) { 0226 m_pPart->setProperty("nameFilter", nameFilter); 0227 } 0228 0229 if (m_bDisableScrolling) { 0230 callExtensionMethod("disableScrolling"); 0231 } 0232 0233 // Set location-bar URL, except for error urls, where we know the browser component 0234 // will set back the url with the error anyway. 0235 if (url.scheme() != QLatin1String("error")) { 0236 setLocationBarURL(locationBarURL); 0237 } 0238 0239 setPageSecurity(KonqMainWindow::NotCrypted); 0240 0241 if (!args.reload()) { 0242 // Save the POST data that is necessary to open this URL 0243 // (so that reload can re-post it) 0244 m_doPost = browserArgs.doPost(); 0245 m_postContentType = browserArgs.contentType(); 0246 m_postData = browserArgs.postData; 0247 // Save the referrer 0248 m_pageReferrer = args.metaData()[QStringLiteral("referrer")]; 0249 } 0250 0251 if (tempFile) { 0252 // Store the path to the tempfile. Yes, we could store a bool only, 0253 // but this would be more dangerous. If anything goes wrong in the code, 0254 // we might end up deleting a real file. 0255 if (url.isLocalFile()) { 0256 m_tempFile = url.toLocalFile(); 0257 } else { 0258 qCWarning(KONQUEROR_LOG) << "Tempfile option is set, but URL is remote:" << url; 0259 } 0260 } 0261 0262 m_requestedUrl = !requestedUrl.isEmpty() ? requestedUrl : url; 0263 aboutToOpenURL(url, args); 0264 0265 if (args.metaData().contains("urlRequestedByApp") && isWebEngineView()) { 0266 m_pPart->setProperty("urlRequestedByApp", url); 0267 } 0268 m_pPart->openUrl(url); 0269 0270 updateHistoryEntry(true); 0271 // add pending history entry 0272 KonqHistoryManager::kself()->addPending(url, locationBarURL, QString()); 0273 0274 #ifdef DEBUG_HISTORY 0275 qCDebug(KONQUEROR_LOG) << "Current position:" << historyIndex(); 0276 #endif 0277 0278 #ifdef KActivities_FOUND 0279 #if QT_VERSION_MAJOR < 6 0280 m_activityResourceInstance->setUri(url); 0281 0282 if (m_pPart->widget()->hasFocus()) { 0283 m_activityResourceInstance->notifyFocusedIn(); 0284 } 0285 #else 0286 KActivities::ResourceInstance::notifyAccessed(url); 0287 #endif 0288 #endif 0289 } 0290 0291 void KonqView::switchEmbeddingPart(const QString& newPluginId, const QString& newInternalViewMode) 0292 { 0293 if (service().pluginId() == newPluginId) { 0294 return; 0295 } 0296 //We don't want to delete the temporary file, otherwise the new part won't have a file to display 0297 stop(true); 0298 lockHistory(); 0299 const QUrl origUrl = realUrl(); 0300 const QString locationBarURL = m_sLocationBarURL; 0301 bool tempFile = !m_tempFile.isEmpty(); 0302 changePart(serviceType(), newPluginId); 0303 openUrl(origUrl, locationBarURL, {}, tempFile, url()); 0304 if (!newInternalViewMode.isEmpty() && newInternalViewMode != internalViewMode()){ 0305 setInternalViewMode(newInternalViewMode); 0306 } 0307 } 0308 0309 void KonqView::switchView(KonqViewFactory &viewFactory, bool allowPlaceholder) 0310 { 0311 //qCDebug(KONQUEROR_LOG); 0312 KParts::ReadOnlyPart *oldPart = m_pPart; 0313 KParts::ReadOnlyPart *part = m_pKonqFrame->attach(viewFactory, allowPlaceholder); // creates the part 0314 if (!part) { 0315 return; 0316 } 0317 0318 m_pPart = part; 0319 0320 // Set the statusbar in the BE asap to avoid a KMainWindow statusbar being created. 0321 KParts::StatusBarExtension *sbext = statusBarExtension(); 0322 if (sbext) { 0323 sbext->setStatusBar(frame()->statusbar()); 0324 } 0325 0326 // Activate the new part 0327 if (oldPart) { 0328 m_pPart->setObjectName(oldPart->objectName()); 0329 emit sigPartChanged(this, oldPart, m_pPart); 0330 delete oldPart; 0331 } 0332 0333 connectPart(); 0334 0335 if (m_service.value(QStringLiteral("X-KDE-BrowserView-FollowActive"), false)) { 0336 //qCDebug(KONQUEROR_LOG) << "X-KDE-BrowserView-FollowActive -> setFollowActive"; 0337 setFollowActive(true); 0338 } 0339 0340 m_bBuiltinView = m_service.value(QStringLiteral("X-KDE-BrowserView-Built-Into"), QString()) == QLatin1String("konqueror"); 0341 0342 if (!m_pMainWindow->viewManager()->isLoadingProfile()) { 0343 // Honor "non-removable passive mode" (like the dirtree) 0344 if (m_service.value(QStringLiteral("X-KDE-BrowserView-PassiveMode"), false)) { 0345 qCDebug(KONQUEROR_LOG) << "X-KDE-BrowserView-PassiveMode -> setPassiveMode"; 0346 setPassiveMode(true); // set as passive 0347 } 0348 0349 // Honor "linked view" 0350 if (m_service.value(QStringLiteral("X-KDE-BrowserView-LinkedView"), false)) { 0351 setLinkedView(true); // set as linked 0352 // Two views : link both 0353 if (m_pMainWindow->viewCount() <= 2) { // '1' can happen if this view is not yet in the map 0354 KonqView *otherView = m_pMainWindow->otherView(this); 0355 if (otherView) { 0356 otherView->setLinkedView(true); 0357 } 0358 } 0359 } 0360 } 0361 } 0362 0363 bool KonqView::ensureViewSupports(const QString &mimeType, 0364 bool forceAutoEmbed) 0365 { 0366 if (supportsMimeType(mimeType)) { 0367 // could be more specific, let's store it so that OpenUrlArguments::mimeType is correct 0368 // testcase: http://acid3.acidtests.org/svg.xml should be opened as image/svg+xml 0369 m_serviceType = mimeType; 0370 return true; 0371 } 0372 return changePart(mimeType, QString(), forceAutoEmbed); 0373 } 0374 0375 bool KonqView::changePart(const QString &mimeType, 0376 const QString &serviceName, 0377 bool forceAutoEmbed) 0378 { 0379 // Caller should call stop first. 0380 Q_ASSERT(!m_bLoading); 0381 0382 //qCDebug(KONQUEROR_LOG) << "mimeType=" << mimeType 0383 // << "requested serviceName=" << serviceName 0384 // << "current service name=" << m_service->desktopEntryName(); 0385 0386 if (serviceName == m_service.pluginId()) { 0387 m_serviceType = mimeType; 0388 return true; 0389 } 0390 0391 if (isLockedViewMode()) { 0392 //qCDebug(KONQUEROR_LOG) << "This view's mode is locked - can't change"; 0393 return false; // we can't do that if our view mode is locked 0394 } 0395 0396 QVector<KPluginMetaData> partServiceOffers; 0397 KService::List appServiceOffers; 0398 KPluginMetaData service; 0399 KonqFactory konqFactory; 0400 KonqViewFactory viewFactory = konqFactory.createView(mimeType, serviceName, &service, &partServiceOffers, &appServiceOffers, forceAutoEmbed); 0401 0402 if (viewFactory.isNull()) { 0403 return false; 0404 } 0405 0406 m_serviceType = mimeType; 0407 m_partServiceOffers = partServiceOffers; 0408 m_appServiceOffers = appServiceOffers; 0409 0410 // Check if that's already the kind of part we have -> no need to recreate it 0411 // Note: we should have an operator== for KService... 0412 if (m_service.isValid() && m_service.pluginId() == service.pluginId()) { 0413 qCDebug(KONQUEROR_LOG) << "Reusing service. Service type set to" << m_serviceType; 0414 if (m_pMainWindow->currentView() == this) { 0415 m_pMainWindow->updateViewModeActions(); 0416 } 0417 } else { 0418 m_service = service; 0419 0420 switchView(viewFactory); 0421 } 0422 0423 return true; 0424 } 0425 0426 void KonqView::connectPart() 0427 { 0428 //qCDebug(KONQUEROR_LOG); 0429 connect(m_pPart, SIGNAL(started(KIO::Job*)), 0430 this, SLOT(slotStarted(KIO::Job*))); 0431 connect(m_pPart, SIGNAL(completed()), 0432 this, SLOT(slotCompleted())); 0433 connect(m_pPart, &KParts::ReadOnlyPart::completedWithPendingAction, this, [this](){slotCompleted(true);}); 0434 connect(m_pPart, SIGNAL(canceled(QString)), 0435 this, SLOT(slotCanceled(QString))); 0436 connect(m_pPart, SIGNAL(setWindowCaption(QString)), 0437 this, SLOT(setCaption(QString))); 0438 if (!internalViewMode().isEmpty()) { 0439 // Update checked action in "View Mode" menu when switching view mode in dolphin 0440 connect(m_pPart, SIGNAL(viewModeChanged()), 0441 m_pMainWindow, SLOT(slotInternalViewModeChanged())); 0442 } 0443 0444 if (m_pPart) { 0445 KonqInterfaces::DownloaderExtension *dext = KonqInterfaces::DownloaderExtension::downloader(m_pPart); 0446 if (dext) { 0447 connect(dext, &KonqInterfaces::DownloaderExtension::downloadAndOpenUrl, m_pMainWindow, [dext, this](const QUrl &url, int id, const KParts::OpenUrlArguments &args, const BrowserArguments &bargs, bool temp){ 0448 KonqOpenURLRequest req(args, bargs, dext->part(), true, id); 0449 req.tempFile = temp; 0450 m_pMainWindow->slotOpenURLRequest(url, req); 0451 }); 0452 } 0453 } 0454 0455 KParts::NavigationExtension *ext = browserExtension(); 0456 if (ext) { 0457 0458 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0459 KonqBrowserWindowInterface *bi = new KonqBrowserWindowInterface(mainWindow(), m_pPart); 0460 ext->setBrowserInterface(bi); 0461 0462 connect(ext, &KParts::NavigationExtension::openUrlRequestDelayed, ext, 0463 [ext, this](const QUrl &url, const KParts::OpenUrlArguments &args, const KParts::BrowserArguments &bargs){ 0464 KonqOpenURLRequest req(args, bargs, qobject_cast<KParts::ReadOnlyPart*>(ext->parent())); 0465 m_pMainWindow->slotOpenURLRequest(url, req); 0466 }); 0467 #else 0468 0469 if (auto browserExtension = qobject_cast<BrowserExtension *>(ext)) { 0470 connect(browserExtension, &BrowserExtension::browserOpenUrlRequestDelayed, m_pMainWindow, [ext, this](const QUrl &url, const KParts::OpenUrlArguments &arguments, const BrowserArguments &browserArguments){ 0471 KonqOpenURLRequest req(arguments, browserArguments, qobject_cast<KParts::ReadOnlyPart*>(ext->parent())); 0472 m_pMainWindow->slotOpenURLRequest(url, req); 0473 }); 0474 KonqBrowserWindowInterface *bi = new KonqBrowserWindowInterface(mainWindow(), m_pPart); 0475 browserExtension->setBrowserInterface(bi); 0476 } else { 0477 connect(ext, &BrowserExtension::openUrlRequestDelayed, m_pMainWindow, 0478 [ext, this](const QUrl &url, const KParts::OpenUrlArguments &args){ 0479 KonqOpenURLRequest req(args, {}, qobject_cast<KParts::ReadOnlyPart*>(ext->parent())); 0480 m_pMainWindow->slotOpenURLRequest(url, req); 0481 }); 0482 } 0483 #endif 0484 0485 0486 if (m_bPopupMenuEnabled) { 0487 m_bPopupMenuEnabled = false; // force 0488 enablePopupMenu(true); 0489 } 0490 0491 connect(ext, SIGNAL(setLocationBarUrl(QString)), 0492 this, SLOT(setLocationBarURL(QString))); 0493 0494 connect(ext, SIGNAL(setIconUrl(QUrl)), 0495 this, SLOT(setIconURL(QUrl))); 0496 0497 connect(ext, SIGNAL(setPageSecurity(int)), 0498 this, SLOT(setPageSecurity(int))); 0499 0500 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0501 connect(ext, &KParts::NavigationExtension::createNewWindow, ext, 0502 [ext, this] (const QUrl &url, const KParts::OpenUrlArguments &args, const KParts::BrowserArguments &bargs, const KParts::WindowArgs &wargs ,KParts::ReadOnlyPart** part) { 0503 KonqOpenURLRequest req(args, bargs, qobject_cast<KParts::ReadOnlyPart*>(ext->parent())); 0504 m_pMainWindow->slotCreateNewWindow(url, req, wargs, part); 0505 }); 0506 #else 0507 if (auto browserExtension = qobject_cast<BrowserExtension *>(ext)) { 0508 connect(browserExtension, &BrowserExtension::browserCreateNewWindow, ext, 0509 [ext, this] (const QUrl &url, const KParts::OpenUrlArguments &args, const BrowserArguments &bargs, const WindowArgs &wargs ,KParts::ReadOnlyPart** part) { 0510 KonqOpenURLRequest req(args, bargs, qobject_cast<KParts::ReadOnlyPart*>(ext->parent())); 0511 m_pMainWindow->slotCreateNewWindow(url, req, wargs, part); 0512 }); 0513 } else { 0514 connect(ext, &KParts::NavigationExtension::createNewWindow, ext, 0515 [ext, this] (const QUrl &url) { 0516 KonqOpenURLRequest req({}, {}, qobject_cast<KParts::ReadOnlyPart*>(ext->parent())); 0517 m_pMainWindow->slotCreateNewWindow(url, req); 0518 }); 0519 } 0520 #endif 0521 0522 connect(ext, SIGNAL(loadingProgress(int)), 0523 m_pKonqFrame->statusbar(), SLOT(slotLoadingProgress(int))); 0524 0525 connect(ext, SIGNAL(speedProgress(int)), 0526 m_pKonqFrame->statusbar(), SLOT(slotSpeedProgress(int))); 0527 0528 connect(ext, SIGNAL(selectionInfo(KFileItemList)), 0529 this, SLOT(slotSelectionInfo(KFileItemList))); 0530 0531 connect(ext, SIGNAL(mouseOverInfo(KFileItem)), 0532 this, SLOT(slotMouseOverInfo(KFileItem))); 0533 0534 connect(ext, SIGNAL(openUrlNotify()), 0535 this, SLOT(slotOpenURLNotify())); 0536 0537 connect(ext, SIGNAL(enableAction(const char*,bool)), 0538 this, SLOT(slotEnableAction(const char*,bool))); 0539 0540 connect(ext, SIGNAL(setActionText(const char*,QString)), 0541 this, SLOT(slotSetActionText(const char*,QString))); 0542 0543 connect(ext, SIGNAL(moveTopLevelWidget(int,int)), 0544 this, SLOT(slotMoveTopLevelWidget(int,int))); 0545 0546 connect(ext, SIGNAL(resizeTopLevelWidget(int,int)), 0547 this, SLOT(slotResizeTopLevelWidget(int,int))); 0548 0549 connect(ext, SIGNAL(requestFocus(KParts::ReadOnlyPart*)), 0550 this, SLOT(slotRequestFocus(KParts::ReadOnlyPart*))); 0551 0552 if (service().pluginId() != QLatin1String("konq_sidebartng")) { 0553 connect(ext, &KParts::NavigationExtension::infoMessage, m_pKonqFrame->statusbar(), &KonqFrameStatusBar::message); 0554 0555 //Must use this form of connect because slotAddWebSideBar is private 0556 connect(ext, SIGNAL(addWebSideBar(QUrl,QString)), m_pMainWindow, SLOT(slotAddWebSideBar(QUrl,QString))); 0557 } 0558 } 0559 0560 QVariant urlDropHandling; 0561 0562 if (ext) { 0563 urlDropHandling = ext->property("urlDropHandling"); 0564 } else { 0565 urlDropHandling = QVariant(true); 0566 } 0567 0568 // Handle url drops if 0569 // a) either the property says "ok" 0570 // or 0571 // b) the part is a plain krop (no BE) 0572 m_bURLDropHandling = (urlDropHandling.type() == QVariant::Bool && 0573 urlDropHandling.toBool()); 0574 if (m_bURLDropHandling) { 0575 m_pPart->widget()->setAcceptDrops(true); 0576 } 0577 0578 m_pPart->widget()->installEventFilter(this); 0579 } 0580 0581 void KonqView::slotEnableAction(const char *name, bool enabled) 0582 { 0583 if (m_pMainWindow->currentView() == this) { 0584 m_pMainWindow->enableAction(name, enabled); 0585 } 0586 // Otherwise, we don't have to do anything, the state of the action is 0587 // stored inside the browser-extension. 0588 } 0589 0590 void KonqView::slotSetActionText(const char *name, const QString &text) 0591 { 0592 if (m_pMainWindow->currentView() == this) { 0593 m_pMainWindow->setActionText(name, text); 0594 } 0595 // Otherwise, we don't have to do anything, the state of the action is 0596 // stored inside the browser-extension. 0597 } 0598 0599 void KonqView::slotMoveTopLevelWidget(int x, int y) 0600 { 0601 KonqFrameContainerBase *container = frame()->parentContainer(); 0602 // If tabs are shown, only accept to move the whole window if there's only one tab. 0603 if (container->frameType() != KonqFrameBase::Tabs || static_cast<KonqFrameTabs *>(container)->count() == 1) { 0604 m_pMainWindow->move(x, y); 0605 } 0606 } 0607 0608 void KonqView::slotResizeTopLevelWidget(int w, int h) 0609 { 0610 KonqFrameContainerBase *container = frame()->parentContainer(); 0611 // If tabs are shown, only accept to resize the whole window if there's only one tab. 0612 // ### Maybe we could store the size requested by each tab and resize the window to the biggest one. 0613 if (container->frameType() != KonqFrameBase::Tabs || static_cast<KonqFrameTabs *>(container)->count() == 1) { 0614 m_pMainWindow->resize(w, h); 0615 } 0616 } 0617 0618 void KonqView::slotStarted(KIO::Job *job) 0619 { 0620 //qCDebug(KONQUEROR_LOG) << job; 0621 setLoading(true); 0622 0623 if (job) { 0624 // Manage passwords properly... 0625 //qCDebug(KONQUEROR_LOG) << "Window ID =" << m_pMainWindow->window()->winId(); 0626 KJobWidgets::setWindow(job, m_pMainWindow->window()); 0627 0628 connect(job, SIGNAL(percent(KJob*,ulong)), this, SLOT(slotPercent(KJob*,ulong))); 0629 connect(job, SIGNAL(speed(KJob*,ulong)), this, SLOT(slotSpeed(KJob*,ulong))); 0630 connect(job, SIGNAL(infoMessage(KJob*,QString,QString)), this, SLOT(slotInfoMessage(KJob*,QString))); 0631 } 0632 } 0633 0634 void KonqView::slotRequestFocus(KParts::ReadOnlyPart *) 0635 { 0636 m_pMainWindow->viewManager()->showTab(this); 0637 } 0638 0639 void KonqView::setLoading(bool loading, bool hasPending /*= false*/) 0640 { 0641 //qCDebug(KONQUEROR_LOG) << "loading=" << loading << "hasPending=" << hasPending; 0642 m_bLoading = loading; 0643 m_bPendingRedirection = hasPending; 0644 if (m_pMainWindow->currentView() == this) { 0645 m_pMainWindow->updateToolBarActions(hasPending); 0646 // Make sure the focus is restored on the part's widget and not the combo 0647 // box if it starts loading a request. See #304933. 0648 if (loading) { 0649 QWidget *partWidget = (m_pPart ? m_pPart->widget() : nullptr); 0650 if (partWidget && !partWidget->hasFocus()) { 0651 //qCDebug(KONQUEROR_LOG) << "SET FOCUS on the widget"; 0652 partWidget->setFocus(); 0653 } 0654 } 0655 } 0656 0657 m_pMainWindow->viewManager()->setLoading(this, loading || hasPending); 0658 } 0659 0660 void KonqView::slotPercent(KJob *, unsigned long percent) 0661 { 0662 m_pKonqFrame->statusbar()->slotLoadingProgress(percent); 0663 } 0664 0665 void KonqView::slotSpeed(KJob *, unsigned long bytesPerSecond) 0666 { 0667 m_pKonqFrame->statusbar()->slotSpeedProgress(bytesPerSecond); 0668 } 0669 0670 void KonqView::slotInfoMessage(KJob *, const QString &msg) 0671 { 0672 m_pKonqFrame->statusbar()->message(msg); 0673 } 0674 0675 void KonqView::slotCompleted() 0676 { 0677 slotCompleted(false); 0678 } 0679 0680 void KonqView::slotCompleted(bool hasPending) 0681 { 0682 //qCDebug(KONQUEROR_LOG) << "hasPending=" << hasPending; 0683 m_pKonqFrame->statusbar()->slotLoadingProgress(-1); 0684 0685 if (! m_bLockHistory) { 0686 // Success... update history entry 0687 updateHistoryEntry(false); 0688 0689 if (m_bAborted) { // remove the pending entry on error 0690 KonqHistoryManager::kself()->removePending(url()); 0691 } else if (currentHistoryEntry()) // register as proper history entry 0692 KonqHistoryManager::kself()->confirmPending(url(), typedUrl(), 0693 currentHistoryEntry()->title); 0694 0695 emit viewCompleted(this); 0696 } 0697 setLoading(false, hasPending); 0698 0699 if (!m_bGotIconURL && !m_bAborted) { 0700 if (KonqSettings::enableFavicon() == true) { 0701 // Try to get /favicon.ico. KonqPixmapProvider::downloadHostIcon does nothing if the URL is not http(s) 0702 if (supportsMimeType(QStringLiteral("text/html"))) { 0703 KonqPixmapProvider::self()->downloadHostIcon(url()); 0704 } 0705 } 0706 } 0707 } 0708 0709 void KonqView::slotCanceled(const QString &errorMsg) 0710 { 0711 //qCDebug(KONQUEROR_LOG); 0712 // The errorMsg comes from the ReadOnlyPart (usually from its kio job, but not necessarily). 0713 // It should probably be used in a KMessageBox 0714 // Let's use the statusbar for now 0715 m_pKonqFrame->statusbar()->setMessage(errorMsg, KonqStatusBarMessageLabel::Error); 0716 m_bAborted = true; 0717 slotCompleted(); 0718 } 0719 0720 void KonqView::slotSelectionInfo(const KFileItemList &items) 0721 { 0722 m_selectedItems = items; 0723 KonqFileSelectionEvent ev(items, m_pPart); 0724 QApplication::sendEvent(m_pMainWindow, &ev); 0725 } 0726 0727 void KonqView::slotMouseOverInfo(const KFileItem &item) 0728 { 0729 KonqFileMouseOverEvent ev(item, m_pPart); 0730 QApplication::sendEvent(m_pMainWindow, &ev); 0731 } 0732 0733 void KonqView::setLocationBarURL(const QUrl &locationBarURL) 0734 { 0735 setLocationBarURL(locationBarURL.url(QUrl::PreferLocalFile)); 0736 } 0737 0738 void KonqView::setLocationBarURL(const QString &locationBarURL) 0739 { 0740 //qCDebug(KONQUEROR_LOG) << locationBarURL << "this=" << this; 0741 m_sLocationBarURL = locationBarURL; 0742 if (m_pMainWindow->currentView() == this) { 0743 //qCDebug(KONQUEROR_LOG) << "is current view" << this; 0744 m_pMainWindow->setLocationBarURL(m_sLocationBarURL); 0745 m_pMainWindow->setPageSecurity(m_pageSecurity); 0746 } 0747 if (!m_bPassiveMode) { 0748 setTabIcon(QUrl::fromUserInput(m_sLocationBarURL)); 0749 } 0750 } 0751 0752 void KonqView::setIconURL(const QUrl &iconURL) 0753 // This function sets the favIcon in konqui's window if enabled, 0754 // thus it is responsible for the icon in the taskbar. 0755 // It does not set the tab's favIcon. 0756 { 0757 if (KonqSettings::enableFavicon()) { 0758 KonqPixmapProvider::self()->setIconForUrl(QUrl(m_sLocationBarURL), iconURL); 0759 m_bGotIconURL = true; 0760 } 0761 } 0762 0763 void KonqView::setPageSecurity(int pageSecurity) 0764 { 0765 m_pageSecurity = static_cast<KonqMainWindow::PageSecurity>(pageSecurity); 0766 0767 if (m_pMainWindow->currentView() == this) { 0768 m_pMainWindow->setPageSecurity(m_pageSecurity); 0769 } 0770 } 0771 0772 void KonqView::setTabIcon(const QUrl &url) 0773 { 0774 if (!m_bPassiveMode && url.isValid()) { 0775 frame()->setTabIcon(url, nullptr); 0776 } 0777 } 0778 0779 void KonqView::setCaption(const QString &caption) 0780 { 0781 if (caption.isEmpty()) { 0782 return; 0783 } 0784 0785 QString adjustedCaption = caption; 0786 const QUrl captionUrl(QUrl::fromUserInput(caption)); 0787 0788 // If the URL and the real URL are different, then we don't want to use 0789 // the caption provided by the part (if it is a URL) because it refers to the 0790 // real URL, which is an implementation detail and should be hidden from the user 0791 // Problem: if caption is not itself a URL, but it refers to the part's URL, 0792 // this doesn't work. There's no way around it, however 0793 if (url() != realUrl() && captionUrl.isValid()) { 0794 adjustedCaption = url().toString(); 0795 } else if (url().isLocalFile() && captionUrl.isValid() && captionUrl.path() == url().path()) { 0796 // For local URLs we prefer to use only the file name 0797 adjustedCaption = captionUrl.adjusted(QUrl::StripTrailingSlash).fileName(); 0798 if (adjustedCaption.isEmpty()) { 0799 adjustedCaption = QLatin1Char('/'); 0800 } 0801 } 0802 0803 m_caption = adjustedCaption; 0804 if (!m_bPassiveMode) { 0805 frame()->setTitle(adjustedCaption, nullptr); 0806 } 0807 } 0808 0809 void KonqView::slotOpenURLNotify() 0810 { 0811 #ifdef DEBUG_HISTORY 0812 qCDebug(KONQUEROR_LOG); 0813 #endif 0814 updateHistoryEntry(false); 0815 createHistoryEntry(); 0816 updateHistoryEntry(true); 0817 if (m_pMainWindow->currentView() == this) { 0818 m_pMainWindow->updateToolBarActions(); 0819 } 0820 } 0821 0822 void KonqView::createHistoryEntry() 0823 { 0824 // First, remove any forward history 0825 HistoryEntry *current = currentHistoryEntry(); 0826 if (current) { 0827 #ifdef DEBUG_HISTORY 0828 qCDebug(KONQUEROR_LOG) << "Truncating history"; 0829 #endif 0830 while (current != m_lstHistory.last()) { 0831 delete m_lstHistory.takeLast(); 0832 } 0833 } 0834 // Append a new entry 0835 #ifdef DEBUG_HISTORY 0836 qCDebug(KONQUEROR_LOG) << "Append a new entry"; 0837 #endif 0838 appendHistoryEntry(new HistoryEntry); 0839 setHistoryIndex(m_lstHistory.count() - 1); // made current 0840 #ifdef DEBUG_HISTORY 0841 qCDebug(KONQUEROR_LOG) << "at=" << historyIndex() << "count=" << m_lstHistory.count(); 0842 #endif 0843 } 0844 0845 void KonqView::appendHistoryEntry(HistoryEntry *historyEntry) 0846 { 0847 // If there are too many HistoryEntries remove old ones 0848 while (m_lstHistory.count() > 0 && m_lstHistory.count() >= KonqSettings::maximumHistoryEntriesPerView()) { 0849 delete m_lstHistory.takeFirst(); 0850 } 0851 0852 m_lstHistory.append(historyEntry); 0853 } 0854 0855 void KonqView::updateHistoryEntry(bool needsReload) 0856 { 0857 Q_ASSERT(!m_bLockHistory); // should never happen 0858 0859 HistoryEntry *current = currentHistoryEntry(); 0860 if (!current) { 0861 return; 0862 } 0863 0864 QUrl url = m_requestedUrl; 0865 0866 #ifdef DEBUG_HISTORY 0867 qCDebug(KONQUEROR_LOG) << "Saving part URL:" << url << "in history position" << historyIndex(); 0868 #endif 0869 0870 current->reload = needsReload; // We have a state for it now. 0871 if (!needsReload && browserExtension()) { 0872 current->buffer = QByteArray(); // Start with empty buffer. 0873 QDataStream stream(¤t->buffer, QIODevice::WriteOnly); 0874 0875 browserExtension()->saveState(stream); 0876 } 0877 0878 #ifdef DEBUG_HISTORY 0879 qCDebug(KONQUEROR_LOG) << "Saving part URL:" << url << "in history position" << historyIndex(); 0880 #endif 0881 current->url = url; 0882 0883 if (!needsReload) { 0884 #ifdef DEBUG_HISTORY 0885 qCDebug(KONQUEROR_LOG) << "Saving location bar URL:" << m_sLocationBarURL << "in history position" << historyIndex(); 0886 #endif 0887 current->locationBarURL = m_sLocationBarURL; 0888 current->pageSecurity = m_pageSecurity; 0889 } 0890 #ifdef DEBUG_HISTORY 0891 qCDebug(KONQUEROR_LOG) << "Saving title:" << m_caption << "in history position" << historyIndex(); 0892 #endif 0893 current->title = m_caption; 0894 current->strServiceType = m_serviceType; 0895 current->strServiceName = m_service.pluginId(); 0896 0897 current->doPost = m_doPost; 0898 current->postData = m_doPost ? m_postData : QByteArray(); 0899 current->postContentType = m_doPost ? m_postContentType : QString(); 0900 current->pageReferrer = m_pageReferrer; 0901 } 0902 0903 void KonqView::go(int steps) 0904 { 0905 if (!steps) { // [WildFox] i bet there are sites on the net with stupid devs who do that :) 0906 #ifdef DEBUG_HISTORY 0907 qCDebug(KONQUEROR_LOG) << "go(0) -> reload"; 0908 #endif 0909 // [David] and you're right. And they expect that it reloads, apparently. 0910 // [George] I'm going to make nspluginviewer rely on this too. :-) 0911 m_pMainWindow->slotReload(); 0912 return; 0913 } 0914 0915 int newPos = historyIndex() + steps; 0916 #ifdef DEBUG_HISTORY 0917 qCDebug(KONQUEROR_LOG) << "steps=" << steps 0918 << "newPos=" << newPos 0919 << "m_lstHistory.count()=" << m_lstHistory.count(); 0920 #endif 0921 if (newPos < 0 || newPos >= m_lstHistory.count()) { 0922 return; 0923 } 0924 0925 stop(); 0926 0927 setHistoryIndex(newPos); // sets current item 0928 0929 #ifdef DEBUG_HISTORY 0930 qCDebug(KONQUEROR_LOG) << "New position" << historyIndex(); 0931 #endif 0932 0933 restoreHistory(); 0934 } 0935 0936 void KonqView::restoreHistory() 0937 { 0938 HistoryEntry h(*currentHistoryEntry()); // make a copy of the current history entry, as the data 0939 // the pointer points to will change with the following calls 0940 0941 #ifdef DEBUG_HISTORY 0942 qCDebug(KONQUEROR_LOG) << "Restoring servicetype/name, and location bar URL from history:" << h.locationBarURL; 0943 #endif 0944 setLocationBarURL(h.locationBarURL); 0945 setPageSecurity(h.pageSecurity); 0946 m_sTypedURL.clear(); 0947 0948 if (!changePart(h.strServiceType, h.strServiceName)) { 0949 qCWarning(KONQUEROR_LOG) << "Couldn't change view mode to" << h.strServiceType << h.strServiceName; 0950 return /*false*/; 0951 } 0952 0953 setPartMimeType(); 0954 0955 m_requestedUrl = h.url; 0956 aboutToOpenURL(h.url); 0957 0958 if (h.reload == false && browserExtension() && historyIndex() > 0) { 0959 //qCDebug(KONQUEROR_LOG) << "Restoring view from stream"; 0960 QDataStream stream(h.buffer); 0961 0962 browserExtension()->restoreState(stream); 0963 0964 m_doPost = h.doPost; 0965 m_postContentType = h.postContentType; 0966 m_postData = h.postData; 0967 m_pageReferrer = h.pageReferrer; 0968 } else { 0969 m_pPart->openUrl(h.url); 0970 } 0971 0972 if (m_pMainWindow->currentView() == this) { 0973 m_pMainWindow->updateToolBarActions(); 0974 } 0975 0976 #ifdef DEBUG_HISTORY 0977 qCDebug(KONQUEROR_LOG) << "New position (2)" << historyIndex(); 0978 #endif 0979 } 0980 0981 const HistoryEntry *KonqView::historyAt(int pos) 0982 { 0983 return m_lstHistory.value(pos); 0984 } 0985 0986 void KonqView::copyHistory(KonqView *other) 0987 { 0988 if (!other) { 0989 return; 0990 } 0991 0992 qDeleteAll(m_lstHistory); 0993 m_lstHistory.clear(); 0994 0995 for (HistoryEntry *he: other->m_lstHistory) { 0996 appendHistoryEntry(new HistoryEntry(*he)); 0997 } 0998 setHistoryIndex(other->historyIndex()); 0999 } 1000 1001 QUrl KonqView::realUrl() const 1002 { 1003 Q_ASSERT(m_pPart); 1004 return m_pPart->url(); 1005 } 1006 1007 QUrl KonqView::upUrl() const 1008 { 1009 QUrl currentURL; 1010 if (m_loader) { 1011 currentURL = m_loader->url(); 1012 } else { 1013 currentURL = QUrl::fromUserInput(m_sLocationBarURL); 1014 } 1015 return KIO::upUrl(currentURL); 1016 } 1017 1018 void KonqView::setUrlLoader(UrlLoader *run) 1019 { 1020 if (m_loader) { 1021 // Tell the UrlLoader to abort, but don't delete it ourselves. 1022 // It could be showing a message box right now. It will delete itself anyway. 1023 m_loader->abort(); 1024 // finish() will be emitted later (when back to event loop) 1025 // and we don't want it to call slotRunFinished (which stops the animation and stop button). 1026 m_loader->disconnect(m_pMainWindow); 1027 if (!run) { 1028 frame()->unsetCursor(); 1029 } 1030 } else if (run) { 1031 frame()->setCursor(Qt::BusyCursor); 1032 } 1033 m_loader = run; 1034 } 1035 1036 void KonqView::stop(bool keepTemporaryFile) 1037 { 1038 //qCDebug(KONQUEROR_LOG); 1039 m_bAborted = false; 1040 1041 //Don't remove the temporary file if we're just changing the part used to display it 1042 if (!keepTemporaryFile) { 1043 finishedWithCurrentURL(); 1044 } 1045 if (m_bLoading || m_bPendingRedirection) { 1046 // aborted -> confirm the pending url. We might as well remove it, but 1047 // we decided to keep it :) 1048 KonqHistoryManager::kself()->confirmPending(url(), m_sTypedURL); 1049 1050 //qCDebug(KONQUEROR_LOG) << "m_pPart->closeUrl()"; 1051 m_pPart->closeUrl(); 1052 m_bAborted = true; 1053 m_pKonqFrame->statusbar()->slotLoadingProgress(-1); 1054 setLoading(false, false); 1055 } 1056 if (m_loader) { 1057 // Revert to working URL - unless the URL was typed manually 1058 // This is duplicated with KonqMainWindow::slotRunFinished, but we can't call it 1059 // since it relies on sender()... 1060 if (currentHistoryEntry() && m_loader->request().typedUrl.isEmpty()) { // not typed 1061 setLocationBarURL(currentHistoryEntry()->locationBarURL); 1062 setPageSecurity(currentHistoryEntry()->pageSecurity); 1063 } 1064 1065 setUrlLoader(nullptr); 1066 m_pKonqFrame->statusbar()->slotLoadingProgress(-1); 1067 } 1068 if (!m_bLockHistory && m_lstHistory.count() > 0) { 1069 updateHistoryEntry(false); 1070 } 1071 } 1072 1073 void KonqView::finishedWithCurrentURL() 1074 { 1075 if (!m_tempFile.isEmpty()) { 1076 qCDebug(KONQUEROR_LOG) << "######### Deleting tempfile after use:" << m_tempFile; 1077 QFile::remove(m_tempFile); 1078 m_tempFile.clear(); 1079 } 1080 } 1081 1082 void KonqView::setPassiveMode(bool mode) 1083 { 1084 // In theory, if m_bPassiveMode is true and mode is false, 1085 // the part should be removed from the part manager, 1086 // and if the other way round, it should be readded to the part manager... 1087 m_bPassiveMode = mode; 1088 1089 if (mode && m_pMainWindow->viewCount() > 1 && m_pMainWindow->currentView() == this) { 1090 KParts::Part *part = m_pMainWindow->viewManager()->chooseNextView(this)->part(); // switch active part 1091 m_pMainWindow->viewManager()->setActivePart(part); 1092 } 1093 1094 // Update statusbar stuff 1095 m_pMainWindow->viewManager()->viewCountChanged(); 1096 } 1097 1098 void KonqView::setLinkedView(bool mode) 1099 { 1100 m_bLinkedView = mode; 1101 if (m_pMainWindow->currentView() == this) { 1102 m_pMainWindow->linkViewAction()->setChecked(mode); 1103 } 1104 frame()->statusbar()->setLinkedView(mode); 1105 } 1106 1107 void KonqView::setLockedLocation(bool b) 1108 { 1109 m_bLockedLocation = b; 1110 } 1111 1112 void KonqView::aboutToOpenURL(const QUrl &url, const KParts::OpenUrlArguments &args) 1113 { 1114 m_bErrorURL = url.scheme() == QLatin1String("error"); 1115 1116 KParts::OpenUrlEvent ev(m_pPart, url, args); 1117 QApplication::sendEvent(m_pMainWindow, &ev); 1118 1119 m_bGotIconURL = false; 1120 m_bAborted = false; 1121 } 1122 1123 void KonqView::setPartMimeType() 1124 { 1125 KParts::OpenUrlArguments args(m_pPart->arguments()); 1126 args.setMimeType(m_serviceType); 1127 m_pPart->setArguments(args); 1128 } 1129 1130 bool KonqView::callExtensionMethod(const char *methodName) 1131 { 1132 QObject *obj = KParts::NavigationExtension::childObject(m_pPart); 1133 if (!obj) { // not all views have a browser extension ! 1134 return false; 1135 } 1136 1137 return QMetaObject::invokeMethod(obj, methodName, Qt::DirectConnection); 1138 } 1139 1140 bool KonqView::callExtensionBoolMethod(const char *methodName, bool value) 1141 { 1142 QObject *obj = KParts::NavigationExtension::childObject(m_pPart); 1143 if (!obj) { // not all views have a browser extension ! 1144 return false; 1145 } 1146 1147 return QMetaObject::invokeMethod(obj, methodName, Qt::DirectConnection, Q_ARG(bool, value)); 1148 } 1149 1150 bool KonqView::callExtensionURLMethod(const char *methodName, const QUrl &value) 1151 { 1152 QObject *obj = KParts::NavigationExtension::childObject(m_pPart); 1153 if (!obj) { // not all views have a browser extension ! 1154 return false; 1155 } 1156 1157 return QMetaObject::invokeMethod(obj, methodName, Qt::DirectConnection, Q_ARG(QUrl, value)); 1158 } 1159 1160 void KonqView::setViewName(const QString &name) 1161 { 1162 //qCDebug(KONQUEROR_LOG) << this << "name=" << name; 1163 if (m_pPart) { 1164 m_pPart->setObjectName(name); 1165 } 1166 } 1167 1168 QString KonqView::viewName() const 1169 { 1170 return m_pPart ? m_pPart->objectName() : QString(); 1171 } 1172 1173 void KonqView::enablePopupMenu(bool b) 1174 { 1175 Q_ASSERT(m_pMainWindow); 1176 1177 KParts::NavigationExtension *ext = browserExtension(); 1178 1179 if (!ext) { 1180 return; 1181 } 1182 1183 if (m_bPopupMenuEnabled == b) { 1184 return; 1185 } 1186 1187 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 1188 //Store signal and slot overloads in variable so that they can be reused in both branches 1189 using namespace KParts; 1190 auto sigOverloadFileItem = QOverload<const QPoint&, const KFileItemList&, const OpenUrlArguments &, const BrowserArguments&, 1191 NavigationExtension::PopupFlags, const NavigationExtension::ActionGroupMap&>::of(&NavigationExtension::popupMenu); 1192 auto slotOverloadFileItem = QOverload<const QPoint&, const KFileItemList&, const OpenUrlArguments &, const BrowserArguments&, 1193 NavigationExtension::PopupFlags, const NavigationExtension::ActionGroupMap&>::of(&KonqMainWindow::slotPopupMenu); 1194 auto sigOverloadUrl = QOverload<const QPoint&, const QUrl&, mode_t, const OpenUrlArguments& , const BrowserArguments& , 1195 NavigationExtension::PopupFlags, const NavigationExtension::ActionGroupMap&>::of(&NavigationExtension::popupMenu); 1196 auto slotOverloadUrl = QOverload<const QPoint&, const QUrl&, mode_t, const OpenUrlArguments& , const BrowserArguments& , 1197 NavigationExtension::PopupFlags, const NavigationExtension::ActionGroupMap&>::of(&KonqMainWindow::slotPopupMenu); 1198 if (b) { // enable context popup 1199 m_bPopupMenuEnabled = true; 1200 connect(ext,sigOverloadFileItem, m_pMainWindow, slotOverloadFileItem); 1201 connect(ext, sigOverloadUrl, m_pMainWindow, slotOverloadUrl); 1202 } else { // disable context popup 1203 m_bPopupMenuEnabled = false; 1204 disconnect(ext,sigOverloadFileItem, m_pMainWindow, slotOverloadFileItem); 1205 disconnect(ext, sigOverloadUrl, m_pMainWindow, slotOverloadUrl); 1206 } 1207 #else 1208 if (auto browserExtension = qobject_cast<BrowserExtension *>(ext)) { 1209 if (b) { 1210 m_bPopupMenuEnabled = true; 1211 connect(browserExtension, &BrowserExtension::browserPopupMenuFromFiles, this, &KonqView::slotBrowserPopupMenuFiles); 1212 connect(browserExtension, &BrowserExtension::browserPopupMenuFromUrl, this, &KonqView::slotBrowserPopupMenuUrl); 1213 } else { 1214 m_bPopupMenuEnabled = false; 1215 disconnect(browserExtension, &BrowserExtension::browserPopupMenuFromFiles, this, &KonqView::slotBrowserPopupMenuFiles); 1216 disconnect(browserExtension, &BrowserExtension::browserPopupMenuFromUrl, this, &KonqView::slotBrowserPopupMenuUrl); 1217 } 1218 } else { 1219 //Store signal and slot overloads in variable so that they can be reused in both branches 1220 using namespace KParts; 1221 auto sigOverloadFileItem = QOverload<const QPoint&, const KFileItemList&, const OpenUrlArguments &, 1222 NavigationExtension::PopupFlags, const NavigationExtension::ActionGroupMap&>::of(&NavigationExtension::popupMenu); 1223 auto sigOverloadUrl = QOverload<const QPoint&, const QUrl&, mode_t, const OpenUrlArguments& , 1224 NavigationExtension::PopupFlags, const NavigationExtension::ActionGroupMap&>::of(&NavigationExtension::popupMenu); 1225 if (b) { // enable context popup 1226 m_bPopupMenuEnabled = true; 1227 connect(ext,sigOverloadFileItem, this, &KonqView::slotPopupMenuFiles); 1228 connect(ext, sigOverloadUrl, this, &KonqView::slotPopupMenuUrl); 1229 } else { // disable context popup 1230 m_bPopupMenuEnabled = false; 1231 disconnect(ext,sigOverloadFileItem, this, &KonqView::slotPopupMenuFiles); 1232 disconnect(ext, sigOverloadUrl, this, &KonqView::slotPopupMenuUrl); 1233 } 1234 } 1235 #endif 1236 } 1237 1238 #if QT_VERSION_MAJOR > 5 1239 void KonqView::slotBrowserPopupMenuFiles(const QPoint& global, const KFileItemList& items, 1240 const KParts::OpenUrlArguments& args, const BrowserArguments& bargs, 1241 KParts::NavigationExtension::PopupFlags flags, 1242 const KParts::NavigationExtension::ActionGroupMap& actionGroups) 1243 { 1244 m_pMainWindow->slotPopupMenu(global, items, args, bargs, flags, actionGroups, this); 1245 } 1246 1247 void KonqView::slotBrowserPopupMenuUrl(const QPoint& global, const QUrl& url, mode_t mode, 1248 const KParts::OpenUrlArguments& args, const BrowserArguments& bargs, 1249 KParts::NavigationExtension::PopupFlags flags, 1250 const KParts::NavigationExtension::ActionGroupMap& actionGroups) 1251 { 1252 m_pMainWindow->slotPopupMenu(global, url, mode, args, bargs, flags, actionGroups, this); 1253 } 1254 #endif 1255 1256 void KonqView::slotPopupMenuFiles(const QPoint &global, const KFileItemList &items, 1257 const KParts::OpenUrlArguments &args, KParts::NavigationExtension::PopupFlags flags, 1258 const KParts::NavigationExtension::ActionGroupMap &actionGroups) 1259 { 1260 #if QT_VERSION_MAJOR < 6 1261 m_pMainWindow->slotPopupMenu(global, items, args, {}, flags, actionGroups); 1262 #else 1263 m_pMainWindow->slotPopupMenu(global, items, args, {}, flags, actionGroups, this); 1264 #endif 1265 } 1266 1267 void KonqView::slotPopupMenuUrl(const QPoint &global, const QUrl &url, mode_t mode, const KParts::OpenUrlArguments &arguments, 1268 KParts::NavigationExtension::PopupFlags flags, 1269 const KParts::NavigationExtension::ActionGroupMap &actionGroups) 1270 { 1271 #if QT_VERSION_MAJOR < 6 1272 m_pMainWindow->slotPopupMenu(global, url, mode, arguments, {}, flags, actionGroups); 1273 #else 1274 m_pMainWindow->slotPopupMenu(global, url, mode, arguments, {}, flags, actionGroups, this); 1275 #endif 1276 } 1277 1278 void KonqView::reparseConfiguration() 1279 { 1280 callExtensionMethod("reparseConfiguration"); 1281 } 1282 1283 void KonqView::disableScrolling() 1284 { 1285 m_bDisableScrolling = true; 1286 callExtensionMethod("disableScrolling"); 1287 } 1288 1289 QString KonqView::dbusObjectPath() 1290 { 1291 // TODO maybe this can be improved? 1292 // E.g. using the part's name, but we'd have to update the name in setViewName maybe? 1293 // And to make sure it's a valid dbus object path like in kmainwindow... 1294 static int s_viewNumber = 0; 1295 if (m_dbusObjectPath.isEmpty()) { 1296 m_dbusObjectPath = m_pMainWindow->dbusName() + '/' + QString::number(++s_viewNumber); 1297 new KonqViewAdaptor(this); 1298 QDBusConnection::sessionBus().registerObject(m_dbusObjectPath, this); 1299 } 1300 return m_dbusObjectPath; 1301 } 1302 1303 QString KonqView::partObjectPath() 1304 { 1305 if (!m_pPart) { 1306 return QString(); 1307 } 1308 1309 const QVariant dcopProperty = m_pPart->property("dbusObjectPath"); 1310 return dcopProperty.toString(); 1311 } 1312 1313 bool KonqView::eventFilter(QObject *obj, QEvent *e) 1314 { 1315 if (!m_pPart) { 1316 return false; 1317 } 1318 // qCDebug(KONQUEROR_LOG) << "--" << obj->className() << "--" << e->type() << "--" ; 1319 if (e->type() == QEvent::DragEnter && m_bURLDropHandling && obj == m_pPart->widget()) { 1320 QDragEnterEvent *ev = static_cast<QDragEnterEvent *>(e); 1321 const QMimeData *mimeData = ev->mimeData(); 1322 if (mimeData->hasUrls()) { 1323 QList<QUrl> lstDragURLs = KUrlMimeData::urlsFromMimeData(mimeData); 1324 1325 const QList<QObject *> children = m_pPart->widget()->findChildren<QObject *>(); // ### slow, better write a isChildOf with a loop... 1326 1327 if (!lstDragURLs.isEmpty() 1328 && !lstDragURLs.first().url().startsWith(QLatin1String("javascript:"), Qt::CaseInsensitive) && // ### this looks like a hack to me 1329 ev->source() != m_pPart->widget() && 1330 !children.contains(ev->source())) { 1331 ev->acceptProposedAction(); 1332 } 1333 } 1334 } else if (e->type() == QEvent::Drop && m_bURLDropHandling && obj == m_pPart->widget()) { 1335 QDropEvent *ev = static_cast<QDropEvent *>(e); 1336 const QMimeData *mimeData = ev->mimeData(); 1337 1338 QList<QUrl> lstDragURLs = KUrlMimeData::urlsFromMimeData(mimeData); 1339 KParts::NavigationExtension *ext = browserExtension(); 1340 if (!lstDragURLs.isEmpty() && ext && lstDragURLs.first().isValid()) { 1341 emit ext->openUrlRequest(lstDragURLs.first()); // this will call m_pMainWindow::slotOpenURLRequest delayed 1342 } 1343 } 1344 1345 #if QT_VERSION_MAJOR < 6 1346 #ifdef KActivities_FOUND 1347 if (e->type() == QEvent::FocusIn) { 1348 m_activityResourceInstance->notifyFocusedIn(); 1349 } 1350 1351 if (e->type() == QEvent::FocusOut) { 1352 m_activityResourceInstance->notifyFocusedOut(); 1353 } 1354 #endif 1355 #endif 1356 1357 return false; 1358 } 1359 1360 bool KonqView::prepareReload(KParts::OpenUrlArguments &args, BrowserArguments &browserArgs, bool softReload) 1361 { 1362 args.setReload(true); 1363 if (softReload) { 1364 browserArgs.softReload = true; 1365 } 1366 1367 // Repost form data if this URL is the result of a POST HTML form. 1368 if (m_doPost && !browserArgs.redirectedRequest()) { 1369 if (KMessageBox::warningContinueCancel(nullptr, i18n( 1370 "The page you are trying to view is the result of posted form data. " 1371 "If you resend the data, any action the form carried out (such as search or online purchase) will be repeated. "), 1372 i18nc("@title:window", "Warning"), KGuiItem(i18n("Resend"))) == KMessageBox::Continue) { 1373 browserArgs.setDoPost(true); 1374 browserArgs.setContentType(m_postContentType); 1375 browserArgs.postData = m_postData; 1376 } else { 1377 return false; 1378 } 1379 } 1380 // Re-set referrer 1381 args.metaData()[QStringLiteral("referrer")] = m_pageReferrer; 1382 1383 return true; 1384 } 1385 1386 KParts::NavigationExtension *KonqView::browserExtension() const 1387 { 1388 return m_pPart ? KParts::NavigationExtension::childObject(m_pPart) : nullptr; 1389 } 1390 1391 KParts::StatusBarExtension *KonqView::statusBarExtension() const 1392 { 1393 return KParts::StatusBarExtension::childObject(m_pPart); 1394 } 1395 1396 QMimeType KonqView::mimeType() const 1397 { 1398 QMimeDatabase db; 1399 return db.mimeTypeForName(serviceType()); 1400 } 1401 1402 bool KonqView::supportsMimeType(const QString &mimeType) const 1403 { 1404 QMimeDatabase db; 1405 QMimeType mime = db.mimeTypeForName(mimeType); 1406 if (!mime.isValid()) { 1407 return false; 1408 } 1409 const QStringList lst = m_service.mimeTypes(); 1410 QStringList::const_iterator found = std::find_if(lst.constBegin(), lst.constEnd(), [mime](const QString &name){return mime.inherits(name);}); 1411 return found != lst.constEnd(); 1412 } 1413 1414 bool KonqView::isWebBrowsingPart() const 1415 { 1416 if (!m_pPart) { 1417 return false; 1418 } 1419 const QString partName = m_pPart->componentName(); 1420 return partName == QLatin1String("webenginepart") || partName == QLatin1String("khtml") || partName == QLatin1String("kwebkitpart"); 1421 } 1422 1423 1424 void HistoryEntry::saveConfig(KConfigGroup &config, const QString &prefix, const KonqFrameBase::Options &options) 1425 { 1426 if (options & KonqFrameBase::SaveUrls) { 1427 config.writeEntry(QStringLiteral("Url").prepend(prefix), url.url()); 1428 config.writeEntry(QStringLiteral("LocationBarURL").prepend(prefix), locationBarURL); 1429 config.writeEntry(QStringLiteral("Title").prepend(prefix), title); 1430 config.writeEntry(QStringLiteral("StrServiceType").prepend(prefix), strServiceType); 1431 config.writeEntry(QStringLiteral("StrServiceName").prepend(prefix), strServiceName); 1432 } else if (options & KonqFrameBase::SaveHistoryItems) { 1433 config.writeEntry(QStringLiteral("Url").prepend(prefix), url.url()); 1434 config.writeEntry(QStringLiteral("LocationBarURL").prepend(prefix), locationBarURL); 1435 config.writeEntry(QStringLiteral("LocationBarURL").prepend(prefix), locationBarURL); 1436 config.writeEntry(QStringLiteral("Title").prepend(prefix), title); 1437 config.writeEntry(QStringLiteral("Buffer").prepend(prefix), buffer); 1438 config.writeEntry(QStringLiteral("StrServiceType").prepend(prefix), strServiceType); 1439 config.writeEntry(QStringLiteral("StrServiceName").prepend(prefix), strServiceName); 1440 config.writeEntry(QStringLiteral("PostData").prepend(prefix), postData); 1441 config.writeEntry(QStringLiteral("PostContentType").prepend(prefix), postContentType); 1442 config.writeEntry(QStringLiteral("DoPost").prepend(prefix), doPost); 1443 config.writeEntry(QStringLiteral("PageReferrer").prepend(prefix), pageReferrer); 1444 config.writeEntry(QStringLiteral("PageSecurity").prepend(prefix), static_cast<int>(pageSecurity)); 1445 } 1446 } 1447 1448 HistoryEntry* HistoryEntry::fromDelayedLoadingData(const KConfigGroup& config, const QString& prefix, const KonqFrameBase::Options& options) 1449 { 1450 HistoryEntry *entry = new HistoryEntry; 1451 if (options & (KonqFrameBase::SaveUrls|KonqFrameBase::SaveHistoryItems)) { // eitentryr one 1452 entry->url = QUrl(config.readEntry(QStringLiteral("Url").prepend(prefix), "")); 1453 entry->locationBarURL = config.readEntry(QStringLiteral("LocationBarURL").prepend(prefix), ""); 1454 entry->title = config.readEntry(QStringLiteral("Title").prepend(prefix), ""); 1455 entry->strServiceType = config.readEntry(QStringLiteral("StrServiceType").prepend(prefix), ""); 1456 entry->strServiceName = config.readEntry(QStringLiteral("StrServiceName").prepend(prefix), ""); 1457 } 1458 if (options & KonqFrameBase::SaveUrls) { 1459 entry->reload = true; 1460 } else if (options & KonqFrameBase::SaveHistoryItems) { 1461 entry->buffer = config.readEntry(QStringLiteral("Buffer").prepend(prefix), QByteArray()); 1462 entry->postData = config.readEntry(QStringLiteral("PostData").prepend(prefix), QByteArray()); 1463 entry->postContentType = config.readEntry(QStringLiteral("PostContentType").prepend(prefix), ""); 1464 entry->doPost = config.readEntry(QStringLiteral("DoPost").prepend(prefix), false); 1465 entry->pageReferrer = config.readEntry(QStringLiteral("PageReferrer").prepend(prefix), ""); 1466 entry->pageSecurity = static_cast<KonqMainWindow::PageSecurity>(config.readEntry(QStringLiteral("PageSecurity").prepend(prefix), 0)); 1467 entry->reload = false; 1468 } 1469 return entry; 1470 } 1471 1472 void HistoryEntry::loadItem(const KConfigGroup &config, const QString &prefix, const KonqFrameBase::Options &options) 1473 { 1474 if (options & (KonqFrameBase::SaveUrls|KonqFrameBase::SaveHistoryItems)) { // either one 1475 url = QUrl(config.readEntry(QStringLiteral("Url").prepend(prefix), "")); 1476 locationBarURL = config.readEntry(QStringLiteral("LocationBarURL").prepend(prefix), ""); 1477 title = config.readEntry(QStringLiteral("Title").prepend(prefix), ""); 1478 strServiceType = config.readEntry(QStringLiteral("StrServiceType").prepend(prefix), ""); 1479 strServiceName = config.readEntry(QStringLiteral("StrServiceName").prepend(prefix), ""); 1480 } 1481 if (options & KonqFrameBase::SaveUrls) { 1482 reload = true; 1483 } else if (options & KonqFrameBase::SaveHistoryItems) { 1484 buffer = config.readEntry(QStringLiteral("Buffer").prepend(prefix), QByteArray()); 1485 postData = config.readEntry(QStringLiteral("PostData").prepend(prefix), QByteArray()); 1486 postContentType = config.readEntry(QStringLiteral("PostContentType").prepend(prefix), ""); 1487 doPost = config.readEntry(QStringLiteral("DoPost").prepend(prefix), false); 1488 pageReferrer = config.readEntry(QStringLiteral("PageReferrer").prepend(prefix), ""); 1489 pageSecurity = static_cast<KonqMainWindow::PageSecurity>(config.readEntry( 1490 QStringLiteral("PageSecurity").prepend(prefix), 0)); 1491 reload = false; 1492 } 1493 } 1494 1495 Konq::PlaceholderPart* KonqView::placeholderPart() const 1496 { 1497 return qobject_cast<Konq::PlaceholderPart*>(m_pPart); 1498 } 1499 1500 void KonqView::saveConfig(KConfigGroup &config, const QString &prefix, const KonqFrameBase::Options &options) 1501 { 1502 //If the view has been delayed, these property can't be got from the part (which will be a PlaceholderPart): 1503 //They need to be taken from m_delayedLoadingData. 1504 //This can happen when loading a session with several tabs, then saving it again without activating all the 1505 //tabs 1506 Konq::PlaceholderPart *plPart = placeholderPart(); 1507 QString mimeType = plPart ? plPart->delayedLoadingData().mimeType : serviceType(); 1508 QString serviceName = plPart ? plPart->delayedLoadingData().serviceName : service().pluginId(); 1509 bool locked = plPart ? plPart->delayedLoadingData().lockedLocation : isLockedLocation(); 1510 1511 config.writeEntry(QStringLiteral("ServiceType").prepend(prefix), mimeType); 1512 config.writeEntry(QStringLiteral("ServiceName").prepend(prefix), serviceName); 1513 config.writeEntry(QStringLiteral("PassiveMode").prepend(prefix), isPassiveMode()); 1514 config.writeEntry(QStringLiteral("LinkedView").prepend(prefix), isLinkedView()); 1515 config.writeEntry(QStringLiteral("ToggleView").prepend(prefix), isToggleView()); 1516 config.writeEntry(QStringLiteral("LockedLocation").prepend(prefix), locked); 1517 1518 if (options & KonqFrameBase::SaveUrls) { 1519 config.writePathEntry(QStringLiteral("URL").prepend(prefix), url().url()); 1520 } else if (options & KonqFrameBase::SaveHistoryItems) { 1521 QList<HistoryEntry *>::Iterator it = m_lstHistory.begin(); 1522 for (int i = 0; it != m_lstHistory.end(); ++it, ++i) { 1523 // In order to not end up with a huge config file, we only save full 1524 // history for current history item 1525 KonqFrameBase::Options options; 1526 if (i == m_lstHistoryIndex) { 1527 options = KonqFrameBase::SaveHistoryItems; 1528 } else { 1529 options = KonqFrameBase::SaveUrls; 1530 } 1531 1532 (*it)->saveConfig(config, QLatin1String("HistoryItem") 1533 + QString::number(i).prepend(prefix), options); 1534 } 1535 config.writeEntry(QStringLiteral("CurrentHistoryItem").prepend(prefix), m_lstHistoryIndex); 1536 config.writeEntry(QStringLiteral("NumberOfHistoryItems").prepend(prefix), historyLength()); 1537 } 1538 } 1539 1540 void KonqView::storeDelayedLoadingData(const QString& mimeType, const QString& serviceName, bool openUrl, const QUrl& url, bool lockedLocation, const KConfigGroup& grp, const QString& prefix) 1541 { 1542 Konq::PlaceholderPart *plPart = placeholderPart(); 1543 if (!plPart) { 1544 return; 1545 } 1546 plPart->setDelayedLoadingData({mimeType, serviceName, openUrl, url, lockedLocation}); 1547 1548 const QString keyHistoryItems = QStringLiteral("NumberOfHistoryItems").prepend(prefix); 1549 1550 int historySize = grp.readEntry(keyHistoryItems, 0); 1551 if (historySize < 1) { 1552 //Note: this won't really open the URL because the part will be a PlaceholderPart 1553 m_requestedUrl = url; 1554 m_pPart->openUrl(url); 1555 return; 1556 } 1557 1558 loadHistoryConfig(grp, prefix); 1559 if (!m_lstHistory.isEmpty()) { 1560 //Note: this won't really open the URL because the part will be a PlaceholderPart 1561 QUrl histUrl = m_lstHistory.at(m_lstHistoryIndex)->url; 1562 m_requestedUrl = histUrl; 1563 m_pPart->openUrl(histUrl); 1564 } 1565 } 1566 1567 bool KonqView::isDelayed() const 1568 { 1569 return qobject_cast<Konq::PlaceholderPart*>(m_pPart) != nullptr; 1570 } 1571 1572 void KonqView::loadDelayed() 1573 { 1574 Konq::PlaceholderPart *plPart = placeholderPart(); 1575 if (!plPart) { 1576 return; 1577 } 1578 1579 Konq::PlaceholderPart::DelayedLoadingData data = plPart->delayedLoadingData(); 1580 changePart(data.mimeType, data.serviceName, true); 1581 1582 if (data.openUrl) { 1583 if (m_lstHistory.isEmpty()) { 1584 QUrl url = data.url; 1585 KonqOpenURLRequest req; 1586 if (!KonqUrl::hasKonqScheme(url)) { 1587 req.typedUrl = url.toDisplayString(); 1588 } 1589 m_pMainWindow->openView(data.mimeType, url, this, req); 1590 } else { 1591 restoreHistory(); 1592 } 1593 } 1594 setLockedLocation(data.lockedLocation); 1595 data = {}; 1596 } 1597 1598 void KonqView::loadHistoryConfig(const KConfigGroup &config, const QString &prefix) 1599 { 1600 // First, remove any history 1601 qDeleteAll(m_lstHistory); 1602 m_lstHistory.clear(); 1603 1604 int historySize = config.readEntry(QStringLiteral("NumberOfHistoryItems").prepend(prefix), 0); 1605 int currentIndex = config.readEntry(QStringLiteral("CurrentHistoryItem").prepend(prefix), historySize - 1); 1606 1607 // No history to restore.. 1608 if (historySize == 0) { 1609 createHistoryEntry(); 1610 return; 1611 } 1612 1613 // restore history list 1614 for (int i = 0; i < historySize; ++i) { 1615 1616 // Only current history item saves completely its HistoryEntry 1617 KonqFrameBase::Options options = i == currentIndex ? KonqFrameBase::SaveHistoryItems : KonqFrameBase::SaveUrls; 1618 1619 HistoryEntry *historyEntry = HistoryEntry::fromDelayedLoadingData(config, QLatin1String("HistoryItem") + QString::number(i).prepend(prefix), options); 1620 1621 appendHistoryEntry(historyEntry); 1622 } 1623 1624 // Shouldn't happen, but just in case.. 1625 if (currentIndex >= historyLength()) { 1626 currentIndex = historyLength() - 1; 1627 } 1628 1629 // set and load the correct history index 1630 setHistoryIndex(currentIndex); 1631 } 1632 1633 QString KonqView::internalViewMode() const 1634 { 1635 const QVariant viewModeProperty = m_pPart->property("currentViewMode"); 1636 return viewModeProperty.toString(); 1637 } 1638 1639 void KonqView::setInternalViewMode(const QString &viewMode) 1640 { 1641 m_pPart->setProperty("currentViewMode", viewMode); 1642 } 1643 1644 QString KonqView::nameFilter() const 1645 { 1646 const QVariant nameFilterProperty = m_pPart->property("nameFilter"); 1647 return nameFilterProperty.toString(); 1648 } 1649 1650 bool KonqView::showsDirectory() const 1651 { 1652 return supportsMimeType(QStringLiteral("inode/directory")); 1653 } 1654 1655 bool KonqView::isModified() const 1656 { 1657 if (m_pPart && (m_pPart->metaObject()->indexOfProperty("modified") != -1)) { 1658 const QVariant prop = m_pPart->property("modified"); 1659 return prop.isValid() && prop.toBool(); 1660 } 1661 return false; 1662 } 1663 1664 void KonqView::setFocus() 1665 { 1666 if (m_pPart && m_pPart->widget() && !isErrorUrl()) { 1667 m_pPart->widget()->setFocus(); 1668 } 1669 } 1670 1671 bool KonqView::isErrorUrl() const 1672 { 1673 return m_bErrorURL; 1674 } 1675 1676 bool KonqView::canNavigateTo(const QUrl& newUrl) const 1677 { 1678 if (m_bFollowActive) { 1679 return m_pMainWindow->currentView()->url() == newUrl; 1680 } 1681 return !m_bLockedLocation || newUrl == url(); 1682 } 1683 1684 void KonqView::duplicateView(KonqView* otherView) 1685 { 1686 // openUrl(otherView->requestedUrl(), otherView->locationBarURL(), otherView->nameFilter(), !otherView->m_tempFile.isEmpty()); 1687 1688 //If requested and real URLs are the same, otherView isn't displaying a downloaded file, so just call openUrl 1689 if (otherView->url() == otherView->realUrl()) { 1690 openUrl(otherView->url(), otherView->locationBarURL()); 1691 return; 1692 } 1693 1694 //otherView is displaying a downloaded file. In this case, for efficiency sake, we don't download it again: rather, we create 1695 //a copy of the file (using KIO::copy) and open it 1696 QString existingFile = QFileInfo(otherView->realUrl().path()).fileName(); 1697 QUrl dest = QUrl::fromLocalFile(KFileUtils::suggestName(QUrl::fromLocalFile(QDir::tempPath()), existingFile)); 1698 KIO::CopyJob *j = KIO::copy(otherView->realUrl(), dest); 1699 1700 const QString locBarUrl = otherView->locationBarURL(); 1701 //If displaying a downloaded URL, the reaul URL will always be a temporary one 1702 bool temp = true; 1703 const QString nameFilter = otherView->nameFilter(); 1704 const QUrl reqUrl = otherView->m_requestedUrl; 1705 1706 auto doOpening = [this, dest, temp, nameFilter, reqUrl, locBarUrl](KJob *job) { 1707 if (!job->error()) { 1708 openUrl(dest, locBarUrl, nameFilter, temp, reqUrl); 1709 } 1710 }; 1711 connect(j, &KJob::result, this, doOpening); 1712 }