File indexing completed on 2024-05-05 17:33:57
0001 /* 0002 * SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org> 0003 * SPDX-FileCopyrightText: 2008 Marco Martin <notmart@gmail.com> 0004 * SPDX-FileCopyrightText: 2008-2011 Matthias Fuchs <mat69@gmx.net> 0005 * SPDX-FileCopyrightText: 2012 Reza Fatahilah Shah <rshah0385@kireihana.com> 0006 * SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org> 0007 * SPDX-FileCopyrightText: 2022 Alexander Lohnau <alexander.lohnau@gmx.de> 0008 * 0009 * SPDX-License-Identifier: GPL-2.0-or-later 0010 */ 0011 0012 #include "comic.h" 0013 #include "checknewstrips.h" 0014 #include "comic_debug.h" 0015 #include "comicsaver.h" 0016 #include "stripselector.h" 0017 0018 #include <QAction> 0019 #include <QDebug> 0020 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 0021 #include <QNetworkInformation> 0022 #endif 0023 #include <QScreen> 0024 #include <QSortFilterProxyModel> 0025 #include <QTimer> 0026 #include <QWindow> 0027 0028 #include <KActionCollection> 0029 #include <KApplicationTrader> 0030 #include <KConfigDialog> 0031 #include <KIO/OpenUrlJob> 0032 #include <KLocalizedString> 0033 #include <KNotification> 0034 #include <KService> 0035 #include <KStandardShortcut> 0036 #include <kuiserverjobtracker.h> 0037 0038 #include <Plasma/Containment> 0039 0040 #include "comicmodel.h" 0041 #include "comicupdater.h" 0042 0043 Q_GLOBAL_STATIC(ComicUpdater, globalComicUpdater) 0044 0045 ComicApplet::ComicApplet(QObject *parent, const KPluginMetaData &data, const QVariantList &args) 0046 : Plasma::Applet(parent, data, args) 0047 , mProxy(nullptr) 0048 , mActiveComicModel(new ActiveComicModel(parent)) 0049 , mDifferentComic(true) 0050 , mShowComicUrl(false) 0051 , mShowComicAuthor(false) 0052 , mShowComicTitle(false) 0053 , mShowComicIdentifier(false) 0054 , mShowErrorPicture(true) 0055 , mArrowsOnHover(true) 0056 , mMiddleClick(true) 0057 , mCheckNewComicStripsInterval(0) 0058 , mMaxComicLimit(0) 0059 , mCheckNewStrips(nullptr) 0060 , mActionShop(nullptr) 0061 , mEngine(new ComicEngine(this)) 0062 , mSavingDir(nullptr) 0063 { 0064 setHasConfigurationInterface(true); 0065 connect(mEngine, &ComicEngine::requestFinished, this, &ComicApplet::dataUpdated); 0066 } 0067 0068 void ComicApplet::init() 0069 { 0070 globalComicUpdater->init(globalConfig()); 0071 mSavingDir = new SavingDir(config()); 0072 0073 configChanged(); 0074 0075 mModel = new ComicModel(mEngine, mTabIdentifier, this); 0076 mProxy = new QSortFilterProxyModel(this); 0077 mProxy->setSourceModel(mModel); 0078 mProxy->setSortCaseSensitivity(Qt::CaseInsensitive); 0079 mProxy->sort(1, Qt::AscendingOrder); 0080 0081 mCurrentDay = QDate::currentDate(); 0082 mDateChangedTimer = new QTimer(this); 0083 connect(mDateChangedTimer, &QTimer::timeout, this, &ComicApplet::checkDayChanged); 0084 mDateChangedTimer->setInterval(5 * 60 * 1000); // every 5 minutes 0085 mDateChangedTimer->start(); 0086 0087 mActionNextNewStripTab = new QAction(QIcon::fromTheme(QStringLiteral("go-next-view")), i18nc("@action comic strip", "&Next Tab with a New Strip"), this); 0088 mActionNextNewStripTab->setShortcuts(KStandardShortcut::openNew()); 0089 actions()->addAction(QStringLiteral("next new strip"), mActionNextNewStripTab); 0090 mActions.append(mActionNextNewStripTab); 0091 connect(mActionNextNewStripTab, &QAction::triggered, this, &ComicApplet::showNextNewStrip); 0092 0093 mActionGoFirst = new QAction(QIcon::fromTheme(QStringLiteral("go-first")), i18nc("@action", "Jump to &First Strip"), this); 0094 mActions.append(mActionGoFirst); 0095 connect(mActionGoFirst, &QAction::triggered, this, &ComicApplet::slotFirstDay); 0096 0097 mActionGoLast = new QAction(QIcon::fromTheme(QStringLiteral("go-last")), i18nc("@action", "Jump to &Current Strip"), this); 0098 mActions.append(mActionGoLast); 0099 connect(mActionGoLast, &QAction::triggered, this, &ComicApplet::slotCurrentDay); 0100 0101 mActionGoJump = new QAction(QIcon::fromTheme(QStringLiteral("go-jump")), i18nc("@action", "Jump to Strip…"), this); 0102 mActions.append(mActionGoJump); 0103 connect(mActionGoJump, &QAction::triggered, this, &ComicApplet::slotGoJump); 0104 0105 mActionWebsite = new QAction(i18nc("@action", "Visit the Website"), this); 0106 KService::Ptr browser = KApplicationTrader::preferredService(QStringLiteral("x-scheme-handler/https")); 0107 0108 if (browser) { 0109 mActionWebsite->setText(i18nc("@action:inmenu %1 is the name of a web browser", "View in %1", browser->name())); 0110 mActionWebsite->setIcon(QIcon::fromTheme(browser->icon())); 0111 } 0112 0113 mActionWebsite->setEnabled(false); 0114 mActions.append(mActionWebsite); 0115 connect(mActionWebsite, &QAction::triggered, this, &ComicApplet::slotWebsite); 0116 0117 mActionShop = new QAction(i18nc("@action", "Visit the Shop &Website"), this); 0118 mActionShop->setEnabled(false); 0119 mActions.append(mActionShop); 0120 connect(mActionShop, &QAction::triggered, this, &ComicApplet::slotShop); 0121 0122 mActionSaveComicAs = new QAction(QIcon::fromTheme(QStringLiteral("document-save-as")), i18nc("@action", "&Save Comic As…"), this); 0123 mActions.append(mActionSaveComicAs); 0124 connect(mActionSaveComicAs, &QAction::triggered, this, &ComicApplet::slotSaveComicAs); 0125 0126 mActionScaleContent = new QAction(QIcon::fromTheme(QStringLiteral("zoom-original")), // 0127 i18nc("@option:check Context menu of comic image", "&Actual Size"), 0128 this); 0129 mActionScaleContent->setCheckable(true); 0130 mActionScaleContent->setChecked(mCurrent.scaleComic()); 0131 mActions.append(mActionScaleContent); 0132 connect(mActionScaleContent, &QAction::triggered, this, &ComicApplet::slotScaleToContent); 0133 0134 mActionStorePosition = 0135 new QAction(QIcon::fromTheme(QStringLiteral("go-home")), i18nc("@option:check Context menu of comic image", "Store Current &Position"), this); 0136 mActionStorePosition->setCheckable(true); 0137 mActionStorePosition->setChecked(mCurrent.hasStored()); 0138 mActions.append(mActionStorePosition); 0139 connect(mActionStorePosition, &QAction::triggered, this, &ComicApplet::slotStorePosition); 0140 0141 // make sure that tabs etc. are displayed even if the comic strip in the first tab does not work 0142 updateView(); 0143 0144 updateUsedComics(); 0145 changeComic(true); 0146 0147 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0148 QT_WARNING_PUSH 0149 QT_WARNING_DISABLE_DEPRECATED 0150 connect(&m_networkConfigurationManager, &QNetworkConfigurationManager::onlineStateChanged, this, [this](bool isOnline) { 0151 if (!isOnline) { 0152 return; 0153 } 0154 qCDebug(PLASMA_COMIC) << "Online status changed to true, requesting comic" << mPreviousFailedIdentifier; 0155 mEngine->requestSource(mPreviousFailedIdentifier); 0156 }); 0157 QT_WARNING_POP 0158 #else 0159 QNetworkInformation::instance()->load(QNetworkInformation::Feature::Reachability); 0160 connect(QNetworkInformation::instance(), &QNetworkInformation::reachabilityChanged, this, [this](auto reachability) { 0161 if (reachability != QNetworkInformation::Reachability::Online) { 0162 return; 0163 } 0164 qCDebug(PLASMA_COMIC) << "Online status changed to true, requesting comic" << mPreviousFailedIdentifier; 0165 mEngine->requestSource(mPreviousFailedIdentifier); 0166 }); 0167 #endif 0168 } 0169 0170 ComicApplet::~ComicApplet() 0171 { 0172 delete mSavingDir; 0173 } 0174 0175 void ComicApplet::dataUpdated(const ComicMetaData &data) 0176 { 0177 const QString source = data.identifier; 0178 setBusy(false); 0179 0180 // disconnect prefetched comic strips 0181 if (source != mOldSource) { 0182 return; 0183 } 0184 0185 setConfigurationRequired(mCurrent.id().isEmpty()); 0186 0187 // there was an error, display information as image 0188 if (data.error) { 0189 mPreviousFailedIdentifier = source; 0190 if (!mShowErrorPicture && !data.previousIdentifier.isEmpty()) { 0191 updateComic(data.previousIdentifier); 0192 } 0193 return; 0194 } 0195 0196 mCurrent.setData(data); 0197 0198 // looking at the last index, thus not mark it as new 0199 KConfigGroup cg = config(); 0200 if (!mCurrent.hasNext() && mCheckNewComicStripsInterval) { 0201 setTabHighlighted(mCurrent.id(), false); 0202 mActionNextNewStripTab->setEnabled(isTabHighlighted(mCurrent.id())); 0203 } 0204 0205 // call the slot to check if the position needs to be saved 0206 slotStorePosition(); 0207 0208 // prefetch the previous and following comic for faster navigation 0209 if (mCurrent.hasNext()) { 0210 const QString prefetch = mCurrent.id() + QLatin1Char(':') + mCurrent.next(); 0211 mEngine->requestSource(prefetch); 0212 } 0213 if (mCurrent.hasPrev()) { 0214 const QString prefetch = mCurrent.id() + QLatin1Char(':') + mCurrent.prev(); 0215 mEngine->requestSource(prefetch); 0216 } 0217 0218 updateView(); 0219 0220 refreshComicData(); 0221 } 0222 0223 void ComicApplet::updateView() 0224 { 0225 updateContextMenu(); 0226 } 0227 0228 void ComicApplet::positionFullView(QWindow *window) 0229 { 0230 if (!window || !window->screen()) { 0231 return; 0232 } 0233 0234 window->setPosition(window->screen()->availableGeometry().center() - QPoint(window->size().width() / 2, window->size().height() / 2)); 0235 } 0236 0237 void ComicApplet::changeComic(bool differentComic) 0238 { 0239 if (differentComic) { 0240 KConfigGroup cg = config(); 0241 mActionStorePosition->setChecked(mCurrent.storePosition()); 0242 0243 // assign mScaleComic the moment the new strip has been loaded (dataUpdated) as up to this point 0244 // the old one should be still shown with its scaling settings 0245 mActionScaleContent->setChecked(mCurrent.scaleComic()); 0246 0247 updateComic(mCurrent.stored()); 0248 } else { 0249 updateComic(mCurrent.current()); 0250 } 0251 } 0252 0253 void ComicApplet::updateUsedComics() 0254 { 0255 const QString oldIdentifier = mCurrent.id(); 0256 0257 mActiveComicModel->clear(); 0258 mCurrent = ComicData(); 0259 0260 bool isFirst = true; 0261 QModelIndex data; 0262 KConfigGroup cg = config(); 0263 int tab = 0; 0264 for (int i = 0; i < mProxy->rowCount(); ++i) { 0265 if (mTabIdentifier.contains(mProxy->index(i, 0).data(Qt::UserRole).toString())) { 0266 data = mProxy->index(i, 1); 0267 0268 if (isFirst) { 0269 isFirst = false; 0270 const QString id = data.data(Qt::UserRole).toString(); 0271 mDifferentComic = (oldIdentifier != id); 0272 const QString title = data.data().toString(); 0273 mCurrent.init(id, config()); 0274 mCurrent.setTitle(title); 0275 } 0276 0277 const QString name = data.data().toString(); 0278 const QString identifier = data.data(Qt::UserRole).toString(); 0279 const QIcon icon = data.data(Qt::DecorationRole).value<QIcon>(); 0280 // found a newer strip last time, which was not visited 0281 0282 if (mCheckNewComicStripsInterval && !cg.readEntry(QLatin1String("lastStripVisited_") + identifier, true)) { 0283 mActiveComicModel->addComic(identifier, name, icon, true); 0284 } else { 0285 mActiveComicModel->addComic(identifier, name, icon); 0286 } 0287 0288 ++tab; 0289 } 0290 } 0291 0292 mActionNextNewStripTab->setVisible(mCheckNewComicStripsInterval); 0293 mActionNextNewStripTab->setEnabled(isTabHighlighted(mCurrent.id())); 0294 0295 delete mCheckNewStrips; 0296 mCheckNewStrips = nullptr; 0297 if (mCheckNewComicStripsInterval) { 0298 mCheckNewStrips = new CheckNewStrips(mTabIdentifier, mEngine, mCheckNewComicStripsInterval, this); 0299 connect(mCheckNewStrips, &CheckNewStrips::lastStrip, this, &ComicApplet::slotFoundLastStrip); 0300 } 0301 0302 Q_EMIT comicModelChanged(); 0303 } 0304 0305 void ComicApplet::slotTabChanged(const QString &identifier) 0306 { 0307 bool differentComic = (mCurrent.id() != identifier); 0308 mCurrent = ComicData(); 0309 mCurrent.init(identifier, config()); 0310 changeComic(differentComic); 0311 } 0312 0313 void ComicApplet::checkDayChanged() 0314 { 0315 if (mCurrentDay != QDate::currentDate()) { 0316 updateComic(mCurrent.current()); 0317 mCurrentDay = QDate::currentDate(); 0318 } else if (!mCurrent.hasImage()) { 0319 updateComic(mCurrent.stored()); 0320 } 0321 } 0322 0323 void ComicApplet::configChanged() 0324 { 0325 KConfigGroup cg = config(); 0326 mTabIdentifier = cg.readEntry("tabIdentifier", QStringList()); 0327 0328 if (mProxy) { 0329 updateUsedComics(); 0330 } 0331 0332 const QString id = mTabIdentifier.count() ? mTabIdentifier.at(0) : QString(); 0333 mCurrent = ComicData(); 0334 mCurrent.init(id, cg); 0335 0336 mShowComicUrl = cg.readEntry("showComicUrl", false); 0337 mShowComicAuthor = cg.readEntry("showComicAuthor", false); 0338 mShowComicTitle = cg.readEntry("showComicTitle", false); 0339 mShowComicIdentifier = cg.readEntry("showComicIdentifier", false); 0340 mShowErrorPicture = cg.readEntry("showErrorPicture", true); 0341 mArrowsOnHover = cg.readEntry("arrowsOnHover", true); 0342 mMiddleClick = cg.readEntry("middleClick", true); 0343 mCheckNewComicStripsInterval = cg.readEntry("checkNewComicStripsIntervall", 30); 0344 0345 auto oldMaxComicLimit = mMaxComicLimit; 0346 mMaxComicLimit = cg.readEntry("maxComicLimit", 29); 0347 if (oldMaxComicLimit != mMaxComicLimit) { 0348 mEngine->setMaxComicLimit(mMaxComicLimit); 0349 } 0350 0351 globalComicUpdater->load(); 0352 } 0353 0354 void ComicApplet::saveConfig() 0355 { 0356 KConfigGroup cg = config(); 0357 cg.writeEntry("comic", mCurrent.id()); 0358 cg.writeEntry("showComicUrl", mShowComicUrl); 0359 cg.writeEntry("showComicAuthor", mShowComicAuthor); 0360 cg.writeEntry("showComicTitle", mShowComicTitle); 0361 cg.writeEntry("showComicIdentifier", mShowComicIdentifier); 0362 cg.writeEntry("showErrorPicture", mShowErrorPicture); 0363 cg.writeEntry("arrowsOnHover", mArrowsOnHover); 0364 cg.writeEntry("middleClick", mMiddleClick); 0365 cg.writeEntry("tabIdentifier", mTabIdentifier); 0366 cg.writeEntry("checkNewComicStripsIntervall", mCheckNewComicStripsInterval); 0367 cg.writeEntry("maxComicLimit", mMaxComicLimit); 0368 0369 globalComicUpdater->save(); 0370 } 0371 0372 void ComicApplet::slotNextDay() 0373 { 0374 updateComic(mCurrent.next()); 0375 } 0376 0377 void ComicApplet::slotPreviousDay() 0378 { 0379 updateComic(mCurrent.prev()); 0380 } 0381 0382 void ComicApplet::slotFirstDay() 0383 { 0384 updateComic(mCurrent.first()); 0385 } 0386 0387 void ComicApplet::slotCurrentDay() 0388 { 0389 updateComic(QString()); 0390 } 0391 0392 void ComicApplet::slotFoundLastStrip(int index, const QString &identifier, const QString &suffix) 0393 { 0394 Q_UNUSED(index) 0395 0396 if (mCurrent.id() != identifier) { 0397 return; 0398 } 0399 0400 KConfigGroup cg = config(); 0401 if (suffix != cg.readEntry(QLatin1String("lastStrip_") + identifier, QString())) { 0402 qDebug() << identifier << "has a newer strip."; 0403 cg.writeEntry(QLatin1String("lastStripVisited_") + identifier, false); 0404 updateComic(suffix); 0405 } 0406 } 0407 0408 void ComicApplet::slotGoJump() 0409 { 0410 StripSelector *selector = StripSelectorFactory::create(mCurrent.type()); 0411 connect(selector, &StripSelector::stripChosen, this, &ComicApplet::updateComic); 0412 0413 selector->select(mCurrent); 0414 } 0415 0416 void ComicApplet::slotStorePosition() 0417 { 0418 mCurrent.storePosition(mActionStorePosition->isChecked()); 0419 } 0420 0421 void ComicApplet::slotWebsite() 0422 { 0423 auto *job = new KIO::OpenUrlJob(mCurrent.websiteUrl()); 0424 job->start(); 0425 } 0426 0427 void ComicApplet::slotShop() 0428 { 0429 auto *job = new KIO::OpenUrlJob(mCurrent.shopUrl()); 0430 job->start(); 0431 } 0432 0433 QList<QAction *> ComicApplet::contextualActions() 0434 { 0435 return mActions; 0436 } 0437 0438 void ComicApplet::updateComic(const QString &identifierSuffix) 0439 { 0440 const QString id = mCurrent.id(); 0441 setConfigurationRequired(id.isEmpty()); 0442 0443 if (!id.isEmpty()) { 0444 setBusy(true); 0445 0446 const QString identifier = id + QLatin1Char(':') + identifierSuffix; 0447 0448 // disconnecting of the oldSource is needed, otherwise you could get data for comics you are not looking at if you use tabs 0449 // if there was an error only disconnect the oldSource if it had nothing to do with the error or if the comic changed, that way updates of the error can 0450 // come in 0451 if (!mIdentifierError.isEmpty() && !mIdentifierError.contains(id)) { 0452 mIdentifierError.clear(); 0453 } 0454 mOldSource = identifier; 0455 mEngine->requestSource(identifier); 0456 slotScaleToContent(); 0457 } else { 0458 setBusy(false); 0459 qWarning() << "Either no identifier was specified or the engine could not be created:" 0460 << "id" << id; 0461 } 0462 updateContextMenu(); 0463 } 0464 0465 void ComicApplet::updateContextMenu() 0466 { 0467 if (mCurrent.id().isEmpty()) { 0468 mActiveComicModel->clear(); 0469 } 0470 0471 if (mCurrent.id().isEmpty() || !mCurrent.ready()) { 0472 mActionNextNewStripTab->setEnabled(false); 0473 mActionGoFirst->setEnabled(false); 0474 mActionGoLast->setEnabled(false); 0475 mActionScaleContent->setEnabled(false); 0476 mActionWebsite->setEnabled(false); 0477 mActionShop->setEnabled(false); 0478 mActionStorePosition->setEnabled(false); 0479 mActionGoJump->setEnabled(false); 0480 mActionSaveComicAs->setEnabled(false); 0481 mActionScaleContent->setChecked(false); 0482 } else { 0483 mActionGoFirst->setVisible(mCurrent.hasFirst()); 0484 mActionGoFirst->setEnabled(mCurrent.hasPrev()); 0485 mActionGoLast->setEnabled(true); 0486 mActionWebsite->setEnabled(true); 0487 mActionShop->setEnabled(mCurrent.shopUrl().isValid()); 0488 mActionScaleContent->setEnabled(true); 0489 mActionStorePosition->setEnabled(true); 0490 mActionGoJump->setEnabled(true); 0491 mActionSaveComicAs->setEnabled(true); 0492 } 0493 } 0494 0495 void ComicApplet::slotSaveComicAs() 0496 { 0497 ComicSaver saver(mSavingDir); 0498 saver.save(mCurrent); 0499 } 0500 0501 void ComicApplet::slotScaleToContent() 0502 { 0503 setShowActualSize(mActionScaleContent->isChecked()); 0504 } 0505 0506 // QML 0507 QObject *ComicApplet::comicsModel() const 0508 { 0509 return mActiveComicModel; 0510 } 0511 0512 QObject *ComicApplet::availableComicsModel() const 0513 { 0514 return mProxy; 0515 } 0516 0517 bool ComicApplet::showComicUrl() const 0518 { 0519 return mShowComicUrl; 0520 } 0521 0522 void ComicApplet::setShowComicUrl(bool show) 0523 { 0524 if (show == mShowComicUrl) { 0525 return; 0526 } 0527 0528 mShowComicUrl = show; 0529 0530 Q_EMIT showComicUrlChanged(); 0531 } 0532 0533 bool ComicApplet::showComicAuthor() const 0534 { 0535 return mShowComicAuthor; 0536 } 0537 0538 void ComicApplet::setShowComicAuthor(bool show) 0539 { 0540 if (show == mShowComicAuthor) { 0541 return; 0542 } 0543 0544 mShowComicAuthor = show; 0545 0546 Q_EMIT showComicAuthorChanged(); 0547 } 0548 0549 bool ComicApplet::showComicTitle() const 0550 { 0551 return mShowComicTitle; 0552 } 0553 0554 void ComicApplet::setShowComicTitle(bool show) 0555 { 0556 if (show == mShowComicTitle) { 0557 return; 0558 } 0559 0560 mShowComicTitle = show; 0561 0562 Q_EMIT showComicTitleChanged(); 0563 } 0564 0565 bool ComicApplet::showComicIdentifier() const 0566 { 0567 return mShowComicIdentifier; 0568 } 0569 0570 void ComicApplet::setShowComicIdentifier(bool show) 0571 { 0572 if (show == mShowComicIdentifier) { 0573 return; 0574 } 0575 0576 mShowComicIdentifier = show; 0577 0578 Q_EMIT showComicIdentifierChanged(); 0579 } 0580 0581 bool ComicApplet::showErrorPicture() const 0582 { 0583 return mShowErrorPicture; 0584 } 0585 0586 void ComicApplet::setShowErrorPicture(bool show) 0587 { 0588 if (show == mShowErrorPicture) { 0589 return; 0590 } 0591 0592 mShowErrorPicture = show; 0593 0594 Q_EMIT showErrorPictureChanged(); 0595 } 0596 0597 bool ComicApplet::arrowsOnHover() const 0598 { 0599 return mArrowsOnHover; 0600 } 0601 0602 void ComicApplet::setArrowsOnHover(bool show) 0603 { 0604 if (show == mArrowsOnHover) { 0605 return; 0606 } 0607 0608 mArrowsOnHover = show; 0609 0610 Q_EMIT arrowsOnHoverChanged(); 0611 } 0612 0613 bool ComicApplet::middleClick() const 0614 { 0615 return mMiddleClick; 0616 } 0617 0618 void ComicApplet::setMiddleClick(bool show) 0619 { 0620 if (show == mMiddleClick) { 0621 return; 0622 } 0623 0624 mMiddleClick = show; 0625 0626 Q_EMIT middleClickChanged(); 0627 saveConfig(); 0628 } 0629 0630 QVariantMap ComicApplet::comicData() const 0631 { 0632 return mComicData; 0633 } 0634 0635 QStringList ComicApplet::tabIdentifiers() const 0636 { 0637 return mTabIdentifier; 0638 } 0639 0640 void ComicApplet::setTabIdentifiers(const QStringList &tabs) 0641 { 0642 if (mTabIdentifier == tabs) { 0643 return; 0644 } 0645 0646 mTabIdentifier = tabs; 0647 Q_EMIT tabIdentifiersChanged(); 0648 saveConfig(); 0649 changeComic(mDifferentComic); 0650 } 0651 0652 void ComicApplet::refreshComicData() 0653 { 0654 mComicData[QStringLiteral("image")] = mCurrent.image(); 0655 mComicData[QStringLiteral("prev")] = mCurrent.prev(); 0656 mComicData[QStringLiteral("next")] = mCurrent.next(); 0657 mComicData[QStringLiteral("additionalText")] = mCurrent.additionalText(); 0658 0659 mComicData[QStringLiteral("websiteUrl")] = mCurrent.websiteUrl().toString(); 0660 mComicData[QStringLiteral("websiteHost")] = mCurrent.websiteUrl().host(); 0661 mComicData[QStringLiteral("imageUrl")] = mCurrent.websiteUrl().toString(); 0662 mComicData[QStringLiteral("shopUrl")] = mCurrent.websiteUrl().toString(); 0663 mComicData[QStringLiteral("first")] = mCurrent.first(); 0664 mComicData[QStringLiteral("stripTitle")] = mCurrent.stripTitle(); 0665 mComicData[QStringLiteral("author")] = mCurrent.author(); 0666 mComicData[QStringLiteral("title")] = mCurrent.title(); 0667 0668 mComicData[QStringLiteral("suffixType")] = QStringLiteral("Date"); 0669 mComicData[QStringLiteral("current")] = mCurrent.current(); 0670 // mComicData[QStringLiteral("last")] = mCurrent.last(); 0671 mComicData[QStringLiteral("currentReadable")] = mCurrent.currentReadable(); 0672 mComicData[QStringLiteral("firstStripNum")] = mCurrent.firstStripNum(); 0673 mComicData[QStringLiteral("maxStripNum")] = mCurrent.maxStripNum(); 0674 mComicData[QStringLiteral("isLeftToRight")] = mCurrent.isLeftToRight(); 0675 mComicData[QStringLiteral("isTopToBottom")] = mCurrent.isTopToBottom(); 0676 0677 Q_EMIT comicDataChanged(); 0678 } 0679 0680 bool ComicApplet::showActualSize() const 0681 { 0682 return mCurrent.scaleComic(); 0683 } 0684 0685 void ComicApplet::setShowActualSize(bool show) 0686 { 0687 if (show == mCurrent.scaleComic()) { 0688 return; 0689 } 0690 0691 mCurrent.setScaleComic(show); 0692 0693 Q_EMIT showActualSizeChanged(); 0694 } 0695 0696 int ComicApplet::checkNewComicStripsInterval() const 0697 { 0698 return mCheckNewComicStripsInterval; 0699 } 0700 0701 void ComicApplet::setCheckNewComicStripsInterval(int interval) 0702 { 0703 if (mCheckNewComicStripsInterval == interval) { 0704 return; 0705 } 0706 0707 mCheckNewComicStripsInterval = interval; 0708 Q_EMIT checkNewComicStripsIntervalChanged(); 0709 } 0710 0711 int ComicApplet::providerUpdateInterval() const 0712 { 0713 return globalComicUpdater->interval(); 0714 } 0715 0716 void ComicApplet::setProviderUpdateInterval(int interval) 0717 { 0718 if (globalComicUpdater->interval() == interval) { 0719 return; 0720 } 0721 0722 globalComicUpdater->setInterval(interval); 0723 Q_EMIT providerUpdateIntervalChanged(); 0724 } 0725 0726 void ComicApplet::setMaxComicLimit(int limit) 0727 { 0728 if (mMaxComicLimit == limit) { 0729 return; 0730 } 0731 0732 mMaxComicLimit = limit; 0733 Q_EMIT maxComicLimitChanged(); 0734 } 0735 0736 int ComicApplet::maxComicLimit() const 0737 { 0738 return mMaxComicLimit; 0739 } 0740 0741 // Endof QML 0742 void ComicApplet::setTabHighlighted(const QString &id, bool highlight) 0743 { 0744 // Search for matching id 0745 for (int i = 0; i < mActiveComicModel->rowCount(); ++i) { 0746 QStandardItem *item = mActiveComicModel->item(i); 0747 0748 QString currentId = item->data(ActiveComicModel::ComicKeyRole).toString(); 0749 if (id == currentId) { 0750 if (highlight != item->data(ActiveComicModel::ComicHighlightRole).toBool()) { 0751 item->setData(highlight, ActiveComicModel::ComicHighlightRole); 0752 Q_EMIT tabHighlightRequest(id, highlight); 0753 } 0754 } 0755 } 0756 } 0757 0758 bool ComicApplet::isTabHighlighted(const QString &id) const 0759 { 0760 for (int i = 0; i < mActiveComicModel->rowCount(); ++i) { 0761 QStandardItem *item = mActiveComicModel->item(i); 0762 0763 QString currentId = item->data(ActiveComicModel::ComicKeyRole).toString(); 0764 if (id == currentId) { 0765 return item->data(ActiveComicModel::ComicHighlightRole).toBool(); 0766 } 0767 } 0768 return false; 0769 } 0770 0771 void ComicApplet::loadProviders() 0772 { 0773 mModel->load(); 0774 } 0775 0776 K_PLUGIN_CLASS(ComicApplet) 0777 0778 #include "comic.moc"