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