File indexing completed on 2024-05-12 05:12:55
0001 /* 0002 This file is part of Akregator. 0003 0004 SPDX-FileCopyrightText: 2005 Frank Osterfeld <osterfeld@kde.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0 0007 */ 0008 0009 #include "framemanager.h" 0010 #include "akregator_debug.h" 0011 #include "akregatorconfig.h" 0012 #include "frame.h" 0013 #include "openurlrequest.h" 0014 #include "webengine/webengineframe.h" 0015 #include <KConfigGroup> 0016 #include <KMacroExpander> 0017 #include <KProcess> 0018 #include <KShell> 0019 #include <QDesktopServices> 0020 #include <QStringList> 0021 0022 using namespace Akregator; 0023 0024 FrameManager::FrameManager(QObject *parent) 0025 : QObject(parent) 0026 , m_currentFrame(nullptr) 0027 { 0028 } 0029 0030 FrameManager::~FrameManager() = default; 0031 0032 Frame *FrameManager::currentFrame() const 0033 { 0034 return m_currentFrame; 0035 } 0036 0037 void FrameManager::slotAddFrame(Frame *frame) 0038 { 0039 m_frames.insert(frame->id(), frame); 0040 0041 connect(frame, &Frame::signalCanceled, this, &FrameManager::slotSetCanceled); 0042 connect(frame, &Frame::signalStarted, this, &FrameManager::slotSetStarted); 0043 connect(frame, &Frame::signalCaptionChanged, this, &FrameManager::slotSetCaption); 0044 connect(frame, &Frame::signalLoadingProgress, this, &FrameManager::slotSetProgress); 0045 connect(frame, &Frame::signalCompleted, this, &FrameManager::slotSetCompleted); 0046 connect(frame, &Frame::signalTitleChanged, this, &FrameManager::slotSetTitle); 0047 connect(frame, &Frame::signalStatusText, this, &FrameManager::slotSetStatusText); 0048 0049 connect(frame, &Frame::signalOpenUrlRequest, this, [this](OpenUrlRequest &request) { 0050 slotOpenUrlRequest(request); 0051 }); 0052 0053 // setPartGuiActive(frame->part(), false); 0054 0055 Q_EMIT signalFrameAdded(frame); 0056 0057 if (m_frames.count() == 1) { 0058 slotChangeFrame(frame->id()); 0059 } 0060 } 0061 0062 void FrameManager::slotRemoveFrame(int id) 0063 { 0064 Frame *frame = m_frames.value(id); 0065 0066 if (!frame || !frame->isRemovable()) { 0067 return; 0068 } 0069 frame->disconnect(this); 0070 0071 if (m_currentFrame == frame) { 0072 slotChangeFrame(-1); 0073 } 0074 0075 m_frames.insert(id, nullptr); 0076 m_frames.remove(id); 0077 Q_EMIT signalFrameRemoved(id); 0078 delete frame; 0079 } 0080 0081 Frame *FrameManager::findFrameById(int id) const 0082 { 0083 return m_frames.value(id); 0084 } 0085 0086 void FrameManager::slotChangeFrame(int frameId) 0087 { 0088 Frame *frame = m_frames.value(frameId); 0089 if (frame == m_currentFrame) { 0090 return; 0091 } 0092 0093 Frame *oldFrame = m_currentFrame; 0094 m_currentFrame = frame; 0095 0096 // if (oldFrame) { 0097 // setPartGuiActive(oldFrame->part(), false); 0098 //} 0099 0100 if (frame) { 0101 // setPartGuiActive(frame->part(), true); 0102 0103 // TODO: handle removable flag 0104 0105 switch (frame->state()) { 0106 case Frame::Started: 0107 Q_EMIT signalStarted(); 0108 break; 0109 case Frame::Canceled: 0110 Q_EMIT signalCanceled(QString()); 0111 break; 0112 case Frame::Idle: 0113 case Frame::Completed: 0114 Q_EMIT signalCompleted(); 0115 } 0116 0117 Q_EMIT signalCaptionChanged(frame->caption()); 0118 Q_EMIT signalTitleChanged(frame->title()); 0119 Q_EMIT signalLoadingProgress(frame->progress()); 0120 Q_EMIT signalStatusText(frame->statusText()); 0121 } else { 0122 Q_EMIT signalCompleted(); 0123 Q_EMIT signalCaptionChanged(QString()); 0124 Q_EMIT signalTitleChanged(QString()); 0125 Q_EMIT signalLoadingProgress(100); 0126 Q_EMIT signalStatusText(QString()); 0127 } 0128 0129 Q_EMIT signalCurrentFrameChanged(oldFrame, frame); 0130 } 0131 0132 void FrameManager::slotSetStarted(Frame *frame) 0133 { 0134 if (frame == m_currentFrame) { 0135 Q_EMIT signalStarted(); 0136 } 0137 } 0138 0139 void FrameManager::slotSetCanceled(Frame *frame, const QString &reason) 0140 { 0141 if (frame == m_currentFrame) { 0142 Q_EMIT signalCanceled(reason); 0143 } 0144 } 0145 0146 void FrameManager::slotSetCompleted(Frame *frame) 0147 { 0148 if (frame == m_currentFrame) { 0149 Q_EMIT signalCompleted(); 0150 } 0151 } 0152 0153 void FrameManager::slotSetProgress(Frame *frame, int progress) 0154 { 0155 if (frame == m_currentFrame) { 0156 Q_EMIT signalLoadingProgress(progress); 0157 } 0158 } 0159 0160 void FrameManager::slotSetCaption(Frame *frame, const QString &caption) 0161 { 0162 if (frame == m_currentFrame) { 0163 Q_EMIT signalCaptionChanged(caption); 0164 } 0165 } 0166 0167 void FrameManager::slotSetTitle(Frame *frame, const QString &title) 0168 { 0169 if (frame == m_currentFrame) { 0170 Q_EMIT signalTitleChanged(title); 0171 } 0172 } 0173 0174 void FrameManager::slotSetStatusText(Frame *frame, const QString &statusText) 0175 { 0176 if (frame == m_currentFrame) { 0177 Q_EMIT signalStatusText(statusText); 0178 } 0179 } 0180 0181 void FrameManager::openUrl(OpenUrlRequest &request) 0182 { 0183 if (request.options() == OpenUrlRequest::NewTab || (m_currentFrame->id() == 0)) { 0184 int newFrameId = -1; 0185 Q_EMIT signalRequestNewFrame(newFrameId); 0186 request.setFrameId(newFrameId); 0187 } else { 0188 request.setFrameId(m_currentFrame->id()); 0189 } 0190 if (m_frames.contains(request.frameId())) { 0191 Frame *frame = m_frames.value(request.frameId()); 0192 if (frame->openUrl(request)) { 0193 request.setWasHandled(true); 0194 } 0195 } 0196 0197 if (!request.openInBackground()) { 0198 Q_EMIT signalSelectFrame(request.frameId()); 0199 } 0200 } 0201 0202 void FrameManager::openInExternalBrowser(const OpenUrlRequest &request) 0203 { 0204 QUrl url = request.url(); 0205 if (!url.isValid()) { 0206 return; 0207 } 0208 0209 if (!Settings::externalBrowserUseKdeDefault()) { 0210 QHash<QChar, QString> map; 0211 map.insert(QLatin1Char('u'), url.url()); 0212 const QString cmd = KMacroExpander::expandMacrosShellQuote(Settings::externalBrowserCustomCommand(), map); 0213 const QStringList args = KShell::splitArgs(cmd); 0214 if (!args.isEmpty()) { 0215 KProcess::startDetached(args); 0216 return; 0217 } 0218 } 0219 0220 QDesktopServices::openUrl(url); 0221 } 0222 0223 void FrameManager::slotOpenUrlRequest(OpenUrlRequest &request, bool useOpenInBackgroundSetting) 0224 { 0225 qCDebug(AKREGATOR_LOG) << "FrameManager::slotOpenUrlRequest():" << request.debugInfo(); 0226 0227 if (request.options() == OpenUrlRequest::ExternalBrowser) { 0228 openInExternalBrowser(request); 0229 return; 0230 } 0231 0232 if (useOpenInBackgroundSetting) { 0233 // Honour user's preference for foreground/background tabs 0234 if (request.options() == OpenUrlRequest::NewTab) { 0235 request.setOpenInBackground(Settings::lMBBehaviour() == Settings::EnumLMBBehaviour::OpenInBackground); 0236 } 0237 } 0238 openUrl(request); 0239 } 0240 0241 void FrameManager::saveProperties(KConfigGroup &config) 0242 { 0243 // write children 0244 QStringList strlst; 0245 QHash<int, Frame *>::const_iterator i; 0246 QHash<int, Frame *>::const_iterator end(m_frames.constEnd()); 0247 for (i = m_frames.constBegin(); i != end; ++i) { 0248 // No need to save the main frame 0249 Frame *currentFrame = i.value(); 0250 if (currentFrame && qobject_cast<WebEngineFrame *>(currentFrame)) { 0251 const QString newPrefix = QLatin1Char('T') + QString::number(i.key()); 0252 if (currentFrame->saveConfig(config, newPrefix + QLatin1Char('_'))) { 0253 strlst.append(newPrefix); 0254 if (currentFrame == m_currentFrame) { 0255 config.writeEntry(QStringLiteral("CurrentTab"), newPrefix); 0256 } 0257 } 0258 } 0259 } 0260 config.writeEntry(QStringLiteral("Children"), strlst); 0261 } 0262 0263 #include "moc_framemanager.cpp"