kdeplasma-addons: remove comic applet and dataengine

it is useless with KNewStuff since comics cannot be added

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2016-04-03 19:34:46 +00:00
parent 1b7de2a878
commit 04a4016fce
62 changed files with 13 additions and 8725 deletions

View file

@ -2,6 +2,15 @@ project(kdeplasma-addons)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
find_package(KDE4 4.14.3 REQUIRED)
include( KDE4Defaults )
include_directories(${KDE4_INCLUDES})
add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
endif()
macro_optional_find_package(KDE4Workspace)
macro_log_feature(KDE4WORKSPACE_FOUND "kdebase workspace" "KDE base workspace libraries" "http://www.kde.org" FALSE "" "Needed for building several Plasma plugins")
@ -44,8 +53,6 @@ add_subdirectory(libs)
add_subdirectory(applets)
add_subdirectory(dataengines)
add_subdirectory(runners)
add_subdirectory(scriptengines)
add_subdirectory(wallpapers)
add_subdirectory(containments)
add_subdirectory(cmake)

View file

@ -7,16 +7,15 @@ if(KDE4WORKSPACE_FOUND)
add_subdirectory(binary-clock)
add_subdirectory(fuzzy-clock)
add_subdirectory(weather)
if(NOT WIN32 AND DBUSMENUQT_FOUND)
if(DBUSMENUQT_FOUND)
add_subdirectory(icontasks)
endif(NOT WIN32 AND DBUSMENUQT_FOUND)
endif()
endif(KDE4WORKSPACE_FOUND)
add_subdirectory(blackboard)
add_subdirectory(bookmarks)
add_subdirectory(bubblemon)
add_subdirectory(calculator)
add_subdirectory(charselect)
add_subdirectory(comic)
add_subdirectory(fifteenPuzzle)
add_subdirectory(fileWatcher)
add_subdirectory(frame)

View file

@ -1,28 +0,0 @@
project(plasma-comic)
set(comic_SRCS
comic.cpp
comicmodel.cpp
configwidget.cpp
comicarchivejob.cpp
comicarchivedialog.cpp
checknewstrips.cpp
comicdata.cpp
comicinfo.cpp
comicsaver.cpp
stripselector.cpp
activecomicmodel.cpp
comicSettings.ui
appearanceSettings.ui
advancedsettings.ui
comicarchivedialog.ui
)
kde4_add_plugin(plasma_applet_comic ${comic_SRCS})
target_link_libraries(plasma_applet_comic ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ${KDE4_SOLID_LIBS} ${KDE4_KIO_LIBS} ${KDE4_KNEWSTUFF3_LIBS} ${QT_QTDECLARATIVE_LIBRARY})
install(TARGETS plasma_applet_comic DESTINATION ${PLUGIN_INSTALL_DIR})
install(FILES plasma-comic-default.desktop DESTINATION ${SERVICES_INSTALL_DIR})
install(FILES comic.knsrc DESTINATION ${CONFIG_INSTALL_DIR})
install(DIRECTORY package/ DESTINATION ${DATA_INSTALL_DIR}/plasma/packages/org.kde.comic)

View file

@ -1,3 +0,0 @@
#! /usr/bin/env bash
$EXTRACTRC *.ui >> rc.cpp
$XGETTEXT *.cpp `find . -name '*.qml'` -o $podir/plasma_applet_comic.pot

View file

@ -1,63 +0,0 @@
/*
* Copyright 2012 Reza Fatahilah Shah <rshah0385@kireihana.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "activecomicmodel.h"
ActiveComicModel::ActiveComicModel(QObject *parent)
: QStandardItemModel(0, 1, parent)
{
QHash<int, QByteArray> newRoleNames = roleNames();
newRoleNames[ComicKeyRole] = "key";
newRoleNames[ComicTitleRole] = "title";
newRoleNames[ComicIconRole] = "icon";
newRoleNames[ComicHighlightRole] = "highlight";
setRoleNames(newRoleNames);
connect(this, SIGNAL(modelReset()),
this, SIGNAL(countChanged()));
connect(this, SIGNAL(rowsInserted(QModelIndex, int, int)),
this, SIGNAL(countChanged()));
connect(this, SIGNAL(rowsRemoved(QModelIndex, int, int)),
this, SIGNAL(countChanged()));
}
void ActiveComicModel::addComic(const QString &key, const QString &title, const QString &iconPath, bool highlight)
{
QList<QStandardItem *> newRow;
QStandardItem *item = new QStandardItem(title);
item->setData(key, ComicKeyRole);
item->setData(title, ComicTitleRole);
item->setData(iconPath, ComicIconRole);
item->setData(highlight, ComicHighlightRole);
newRow << item;
appendRow(newRow);
}
QVariantHash ActiveComicModel::get(int row) const
{
QModelIndex idx = index(row, 0);
QVariantHash hash;
QHash<int, QByteArray>::const_iterator i;
for (i = roleNames().constBegin(); i != roleNames().constEnd(); ++i) {
hash[i.value()] = data(idx, i.key());
}
return hash;
}

View file

@ -1,49 +0,0 @@
/*
* Copyright 2012 Reza Fatahilah Shah <rshah0385@kireihana.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACTIVE_COMIC_MODEL_H
#define ACTIVE_COMIC_MODEL_H
#include <QtGui/QtGui>
#include <QtCore/QtCore>
class ActiveComicModel : public QStandardItemModel
{
Q_OBJECT
Q_PROPERTY(int count READ count NOTIFY countChanged)
public:
enum Roles {
ComicKeyRole = Qt::UserRole+1,
ComicTitleRole = Qt::UserRole+2,
ComicIconRole = Qt::UserRole+3,
ComicHighlightRole = Qt::UserRole+4
};
ActiveComicModel(QObject *parent = 0);
void addComic(const QString &key, const QString &title, const QString &iconPath, bool highlight = true);
int count() { return rowCount(QModelIndex()); }
Q_INVOKABLE QVariantHash get(int i) const;
Q_SIGNALS:
void countChanged();
};
#endif

View file

@ -1,161 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AdvancedSettings</class>
<widget class="QWidget" name="AdvancedSettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>468</width>
<height>300</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string comment="refers to caching of files on the users hd">Cache</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="1">
<widget class="QSpinBox" name="maxComicLimit">
<property name="minimum">
<number>0</number>
</property>
<property name="suffix">
<string> strips per comic</string>
</property>
<property name="specialValueText">
<string>No size limit</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Comic cache:</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Error Handling</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Display error image when getting comic failed:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="errorPicture">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -1,263 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AppearanceSettings</class>
<widget class="QWidget" name="AppearanceSettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>280</width>
<height>182</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="2">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<layout class="QFormLayout" name="formLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Show arrows only on &amp;hover:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>checkBox_arrows</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkBox_arrows">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Information</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Show comic &amp;title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>checkBox_title</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkBox_title">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Show comic &amp;identifier:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>checkBox_identifier</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkBox_identifier">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Show comic &amp;author:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>checkBox_author</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="checkBox_author">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Show comic &amp;URL:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>checkBox_url</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="checkBox_url">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="1">
<widget class="KButtonGroup" name="kbuttongroup">
<property name="title">
<string/>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>0</number>
</property>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KButtonGroup</class>
<extends>QGroupBox</extends>
<header>kbuttongroup.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>checkBox_arrows</tabstop>
<tabstop>checkBox_title</tabstop>
<tabstop>checkBox_identifier</tabstop>
<tabstop>checkBox_author</tabstop>
<tabstop>checkBox_url</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -1,79 +0,0 @@
/***************************************************************************
* Copyright (C) 2011 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "checknewstrips.h"
#include <QtCore/QTimer>
CheckNewStrips::CheckNewStrips( const QStringList &identifiers, Plasma::DataEngine *engine, int minutes, QObject *parent)
: QObject( parent ),
mMinutes( minutes ),
mIndex( 0 ),
mEngine( engine ),
mIdentifiers( identifiers )
{
QTimer *timer = new QTimer( this );
timer->setInterval( minutes * 60 * 1000 );
connect( timer, SIGNAL(timeout()), this, SLOT(start()) );
timer->start();
//start at once, that way the user does not have to wait for minutes to get the initial result
start();
}
void CheckNewStrips::dataUpdated( const QString &source, const Plasma::DataEngine::Data &data )
{
QString lastIdentifierSuffix;
if ( !data[ "Error" ].toBool() ) {
lastIdentifierSuffix = data[ "Identifier" ].toString();
lastIdentifierSuffix.remove( source );
}
mEngine->disconnectSource( source, this );
if ( !lastIdentifierSuffix.isEmpty() ) {
QString temp = source;
temp.remove( ':' );
emit lastStrip( mIndex, temp, lastIdentifierSuffix );
}
++mIndex;
if ( mIndex < mIdentifiers.count() ) {
const QString newSource = mIdentifiers[mIndex] + ':';
mEngine->connectSource( newSource, this );
mEngine->query( newSource );
} else {
mIndex = 0;
}
}
void CheckNewStrips::start()
{
//already running, do nothing
if ( mIndex ) {
return;
}
if ( mIndex < mIdentifiers.count() ) {
const QString newSource = mIdentifiers[mIndex] + ':';
mEngine->connectSource( newSource, this );
mEngine->query( newSource );
}
}

View file

@ -1,58 +0,0 @@
/***************************************************************************
* Copyright (C) 2011 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#ifndef CHECK_NEW_STRIPS_H
#define CHECK_NEW_STRIPS_H
#include <Plasma/DataEngine>
/**
* This class searches for the newest comic strips of predefined comics in a defined intervall.
* Once found it emits lastStrip
*/
class CheckNewStrips : public QObject
{
Q_OBJECT
public:
CheckNewStrips( const QStringList &identifiers, Plasma::DataEngine *engine, int minutes, QObject *parent = 0 );
signals:
/**
* @param index of the identifier in identifiers
* @param identifier of the comic
* @param suffix of the last comic strip
* @see CheckNewStrips
*/
void lastStrip( int index, const QString &identifier, const QString &suffix );
public slots:
void dataUpdated( const QString &name, const Plasma::DataEngine::Data &data );
private slots:
void start();
private:
int mMinutes;
int mIndex;
Plasma::DataEngine *mEngine;
const QStringList mIdentifiers;
};
#endif

View file

@ -1,804 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Tobias Koenig <tokoe@kde.org> *
* Copyright (C) 2008 by Marco Martin <notmart@gmail.com> *
* Copyright (C) 2008-2011 Matthias Fuchs <mat69@gmx.net> *
* Copyright (C) 2012 Reza Fatahilah Shah <rshah0385@kireihana.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "comic.h"
#include "comicarchivedialog.h"
#include "comicarchivejob.h"
#include "checknewstrips.h"
#include "stripselector.h"
#include "comicsaver.h"
#include <QtCore/QTimer>
#include <QtGui/QGraphicsLinearLayout>
#include <QtGui/QGraphicsScene>
#include <QtGui/QGraphicsView>
#include <QtGui/qgraphicssceneevent.h>
#include <QtGui/QSortFilterProxyModel>
#include <QtDeclarative/QDeclarativeEngine>
#include <QtDeclarative/QDeclarativeContext>
#include <KAction>
#include <KConfigDialog>
#include <KDebug>
#include <KNotification>
#include <kuiserverjobtracker.h>
#include <KRun>
#include <KStandardShortcut>
#include <Plasma/Containment>
#include <Plasma/DeclarativeWidget>
#include <Plasma/Package>
#include "comicmodel.h"
#include "configwidget.h"
K_GLOBAL_STATIC( ComicUpdater, globalComicUpdater )
const int ComicApplet::CACHE_LIMIT = 20;
ComicApplet::ComicApplet( QObject *parent, const QVariantList &args )
: Plasma::PopupApplet( parent, args ),
mActiveComicModel(parent),
mDifferentComic( true ),
mShowComicUrl( false ),
mShowComicAuthor( false ),
mShowComicTitle( false ),
mShowComicIdentifier( false ),
mShowErrorPicture( true ),
mArrowsOnHover( true ),
mMiddleClick( true ),
mCheckNewStrips( 0 ),
mDeclarativeWidget( 0 ),
mActionShop( 0 ),
mEngine( 0 ),
mSavingDir(0)
{
setHasConfigurationInterface( true );
resize( 600, 250 );
setAspectRatioMode( Plasma::IgnoreAspectRatio );
setPopupIcon( "face-smile-big" );
}
void ComicApplet::init()
{
globalComicUpdater->init( globalConfig() );
mSavingDir = new SavingDir(config());
configChanged();
//QML
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this);
mDeclarativeWidget = new Plasma::DeclarativeWidget(this);
layout->addItem(mDeclarativeWidget);
mDeclarativeWidget->engine()->rootContext()->setContextProperty("comicApplet", this);
Plasma::PackageStructure::Ptr structure = Plasma::PackageStructure::load("Plasma/Generic");
Plasma::Package package(QString(), "org.kde.comic", structure);
mDeclarativeWidget->setQmlPath(package.filePath("mainscript"));
//End of QML
mEngine = dataEngine( "comic" );
mModel = new ComicModel( mEngine->query( "providers" ), mTabIdentifier, this );
mProxy = new QSortFilterProxyModel( this );
mProxy->setSourceModel( mModel );
mProxy->setSortCaseSensitivity( Qt::CaseInsensitive );
mProxy->sort( 1, Qt::AscendingOrder );
//set maximum number of cached strips per comic, -1 means that there is no limit
KConfigGroup global = globalConfig();
//convert old values
if ( global.hasKey( "useMaxComicLimit" ) ) {
const bool use = global.readEntry( "useMaxComicLimit", false );
if ( !use ) {
global.writeEntry( "maxComicLimit", 0 );
}
global.deleteEntry( "useMaxComicLimit" );
}
const int maxComicLimit = global.readEntry( "maxComicLimit", CACHE_LIMIT );
mEngine->query( QLatin1String( "setting_maxComicLimit:" ) + QString::number( maxComicLimit ) );
mCurrentDay = QDate::currentDate();
mDateChangedTimer = new QTimer( this );
connect( mDateChangedTimer, SIGNAL(timeout()), this, SLOT(checkDayChanged()) );
mDateChangedTimer->setInterval( 5 * 60 * 1000 ); // every 5 minutes
mActionNextNewStripTab = new KAction( KIcon( "go-next-view" ), i18nc( "here strip means comic strip", "&Next Tab with a new Strip" ), this );
mActionNextNewStripTab->setShortcut( KStandardShortcut::openNew() );
addAction( "next new strip" , mActionNextNewStripTab );
mActions.append( mActionNextNewStripTab );
connect( mActionNextNewStripTab, SIGNAL(triggered(bool)), this, SIGNAL(showNextNewStrip()) );
mActionGoFirst = new QAction( KIcon( "go-first" ), i18n( "Jump to &first Strip" ), this );
mActions.append( mActionGoFirst );
connect( mActionGoFirst, SIGNAL(triggered(bool)), this, SLOT(slotFirstDay()) );
mActionGoLast = new QAction( KIcon( "go-last" ), i18n( "Jump to &current Strip" ), this );
mActions.append( mActionGoLast );
connect( mActionGoLast, SIGNAL(triggered(bool)), this, SLOT(slotCurrentDay()) );
mActionGoJump = new QAction( KIcon( "go-jump" ), i18n( "Jump to Strip ..." ), this );
mActions.append( mActionGoJump );
connect( mActionGoJump, SIGNAL(triggered(bool)), this, SLOT(slotGoJump()) );
if ( hasAuthorization( "LaunchApp" ) ) {
mActionShop = new QAction( i18n( "Visit the shop &website" ), this );
mActionShop->setEnabled( false );
mActions.append( mActionShop );
connect( mActionShop, SIGNAL(triggered(bool)), this, SLOT(slotShop()) );
}
if ( hasAuthorization( "FileDialog" ) ) {
QAction *action = new QAction( KIcon( "document-save-as" ), i18n( "&Save Comic As..." ), this );
mActions.append( action );
connect( action, SIGNAL(triggered(bool)), this , SLOT(slotSaveComicAs()) );
}
if ( hasAuthorization( "FileDialog" ) ) {
QAction *action = new QAction( KIcon( "application-epub+zip" ), i18n( "&Create Comic Book Archive..." ), this );
mActions.append( action );
connect( action, SIGNAL(triggered(bool)), this, SLOT(createComicBook()) );
}
mActionScaleContent = new QAction( KIcon( "zoom-original" ), i18nc( "@option:check Context menu of comic image", "&Actual Size" ), this );
mActionScaleContent->setCheckable( true );
mActionScaleContent->setChecked( mCurrent.scaleComic() );
mActions.append( mActionScaleContent );
connect( mActionScaleContent, SIGNAL(triggered(bool)), this , SLOT(slotScaleToContent()) );
mActionStorePosition = new QAction( KIcon( "go-home" ), i18nc( "@option:check Context menu of comic image", "Store current &Position" ), this);
mActionStorePosition->setCheckable( true );
mActionStorePosition->setChecked(mCurrent.hasStored());
mActions.append( mActionStorePosition );
connect( mActionStorePosition, SIGNAL(triggered(bool)), this, SLOT(slotStorePosition()) );
//make sure that tabs etc. are displayed even if the comic strip in the first tab does not work
updateView();
updateUsedComics();
changeComic( true );
}
ComicApplet::~ComicApplet()
{
delete mSavingDir;
}
QGraphicsWidget *ComicApplet::graphicsWidget()
{
return mDeclarativeWidget;
}
void ComicApplet::dataUpdated( const QString &source, const Plasma::DataEngine::Data &data )
{
//disconnect prefetched comic strips
if ( source != mOldSource ) {
mEngine->disconnectSource( source, this );
return;
}
setBusy( false );
setConfigurationRequired( false );
//there was an error, display information as image
const bool hasError = data[ "Error" ].toBool();
const bool errorAutoFixable = data[ "Error automatically fixable" ].toBool();
if ( hasError ) {
const QString previousIdentifierSuffix = data[ "Previous identifier suffix" ].toString();
if ( !mShowErrorPicture && !previousIdentifierSuffix.isEmpty() ) {
mEngine->disconnectSource( source, this );
updateComic( previousIdentifierSuffix );
return;
}
}
mCurrent.setData(data);
setAssociatedApplicationUrls(mCurrent.websiteUrl());
//looking at the last index, thus not mark it as new
KConfigGroup cg = config();
if (!mCurrent.hasNext() && mCheckNewComicStripsIntervall) {
setTabHighlighted( mCurrent.id(), false );
mActionNextNewStripTab->setEnabled( hasHighlightedTabs() );
}
//call the slot to check if the position needs to be saved
slotStorePosition();
//disconnect if there is either no error, or an error that can not be fixed automatically
if ( !errorAutoFixable ) {
mEngine->disconnectSource( source, this );
}
//prefetch the previous and following comic for faster navigation
if (mCurrent.hasNext()) {
const QString prefetch = mCurrent.id() + ':' + mCurrent.next();
mEngine->connectSource( prefetch, this );
mEngine->query( prefetch );
}
if ( mCurrent.hasPrev()) {
const QString prefetch = mCurrent.id() + ':' + mCurrent.prev();
mEngine->connectSource( prefetch, this );
mEngine->query( prefetch );
}
updateView();
refreshComicData();
}
void ComicApplet::updateView()
{
updateContextMenu();
}
void ComicApplet::createConfigurationInterface( KConfigDialog *parent )
{
mConfigWidget = new ConfigWidget( dataEngine( "comic" ), mModel, mProxy, parent );
mConfigWidget->setShowComicUrl( mShowComicUrl );
mConfigWidget->setShowComicAuthor( mShowComicAuthor );
mConfigWidget->setShowComicTitle( mShowComicTitle );
mConfigWidget->setShowComicIdentifier( mShowComicIdentifier );
mConfigWidget->setShowErrorPicture( mShowErrorPicture );
mConfigWidget->setArrowsOnHover( mArrowsOnHover );
mConfigWidget->setMiddleClick( mMiddleClick );
mConfigWidget->setCheckNewComicStripsIntervall( mCheckNewComicStripsIntervall );
//not storing this value, since other applets might have changed it inbetween
KConfigGroup global = globalConfig();
const int maxComicLimit = global.readEntry( "maxComicLimit", CACHE_LIMIT );
mConfigWidget->setMaxComicLimit( maxComicLimit );
const int updateIntervall = global.readEntry( "updateIntervall", 3 );
mConfigWidget->setUpdateIntervall( updateIntervall );
parent->setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Apply );
parent->addPage( mConfigWidget->comicSettings, i18n( "General" ), icon() );
parent->addPage( mConfigWidget->appearanceSettings, i18n( "Appearance" ), "image" );
parent->addPage( mConfigWidget->advancedSettings, i18n( "Advanced" ), "system-run" );
connect( parent, SIGNAL(applyClicked()), this, SLOT(applyConfig()) );
connect( parent, SIGNAL(okClicked()), this, SLOT(applyConfig()) );
connect(mConfigWidget, SIGNAL(enableApply()), parent, SLOT(settingsModified()));
}
void ComicApplet::applyConfig()
{
setShowComicUrl(mConfigWidget->showComicUrl());
setShowComicAuthor(mConfigWidget->showComicAuthor());
setShowComicTitle(mConfigWidget->showComicTitle());
setShowComicIdentifier(mConfigWidget->showComicIdentifier());
setShowErrorPicture(mConfigWidget->showErrorPicture());
setArrowsOnHover(mConfigWidget->arrowsOnHover());
setMiddleClick(mConfigWidget->middleClick());
mCheckNewComicStripsIntervall = mConfigWidget->checkNewComicStripsIntervall();
//not storing this value, since other applets might have changed it inbetween
KConfigGroup global = globalConfig();
const int oldMaxComicLimit = global.readEntry( "maxComicLimit", CACHE_LIMIT );
const int maxComicLimit = mConfigWidget->maxComicLimit();
if ( oldMaxComicLimit != maxComicLimit ) {
global.writeEntry( "maxComicLimit", maxComicLimit );
mEngine->query( QLatin1String( "setting_maxComicLimit:" ) + QString::number( maxComicLimit ) );
}
globalComicUpdater->applyConfig( mConfigWidget );
updateUsedComics();
saveConfig();
//make sure that tabs etc. are displayed even if the comic strip in the first tab does not work
updateView();
changeComic( mDifferentComic );
}
void ComicApplet::changeComic( bool differentComic )
{
if ( differentComic ) {
KConfigGroup cg = config();
mActionStorePosition->setChecked(mCurrent.storePosition());
// assign mScaleComic the moment the new strip has been loaded (dataUpdated) as up to this point
// the old one should be still shown with its scaling settings
mActionScaleContent->setChecked( mCurrent.scaleComic() );
updateComic( mCurrent.stored() );
} else {
updateComic( mCurrent.current() );
}
}
void ComicApplet::updateUsedComics()
{
const QString oldIdentifier = mCurrent.id();
mActiveComicModel.clear();
mTabIdentifier.clear();
mCurrent = ComicData();
bool isFirst = true;
QModelIndex data;
KConfigGroup cg = config();
int tab = 0;
for ( int i = 0; i < mProxy->rowCount(); ++i ) {
if ( mProxy->index( i, 0 ).data( Qt::CheckStateRole) == Qt::Checked ) {
data = mProxy->index( i, 1 );
if ( isFirst ) {
isFirst = false;
const QString id = data.data( Qt::UserRole ).toString();
mDifferentComic = ( oldIdentifier != id );
const QString title = data.data().toString();
mCurrent.init(id, config());
mCurrent.setTitle(title);
}
const QString name = data.data().toString();
const QString identifier = data.data( Qt::UserRole ).toString();
const QString iconPath = data.data( Qt::DecorationRole ).value<QIcon>().name();
//found a newer strip last time, which was not visited
if ( mCheckNewComicStripsIntervall && !cg.readEntry( "lastStripVisited_" + identifier, true ) ) {
mActiveComicModel.addComic(identifier, name, iconPath, true);
} else {
mActiveComicModel.addComic(identifier, name, iconPath);
}
mTabIdentifier << identifier;
++tab;
}
}
mActionNextNewStripTab->setVisible( mCheckNewComicStripsIntervall );
mActionNextNewStripTab->setEnabled( hasHighlightedTabs() );
delete mCheckNewStrips;
mCheckNewStrips = 0;
if ( mCheckNewComicStripsIntervall ) {
mCheckNewStrips = new CheckNewStrips( mTabIdentifier, mEngine, mCheckNewComicStripsIntervall, this );
connect( mCheckNewStrips, SIGNAL(lastStrip(int,QString,QString)), this, SLOT(slotFoundLastStrip(int,QString,QString)) );
}
emit comicModelChanged();
}
void ComicApplet::slotTabChanged(const QString &identifier)
{
bool differentComic = (mCurrent.id() != identifier);
mCurrent = ComicData();
mCurrent.init(identifier, config());
changeComic( differentComic );
}
void ComicApplet::checkDayChanged()
{
if ( ( mCurrentDay != QDate::currentDate() ) || !mCurrent.hasImage() )
updateComic( mCurrent.stored() );
mCurrentDay = QDate::currentDate();
}
void ComicApplet::configChanged()
{
KConfigGroup cg = config();
mTabIdentifier = cg.readEntry( "tabIdentifier", QStringList( QString() ) );
const QString id = mTabIdentifier.count() ? mTabIdentifier.at( 0 ) : QString();
mCurrent = ComicData();
mCurrent.init(id, cg);
mShowComicUrl = cg.readEntry( "showComicUrl", false );
mShowComicAuthor = cg.readEntry( "showComicAuthor", false );
mShowComicTitle = cg.readEntry( "showComicTitle", false );
mShowComicIdentifier = cg.readEntry( "showComicIdentifier", false );
mShowErrorPicture = cg.readEntry( "showErrorPicture", true );
mArrowsOnHover = cg.readEntry( "arrowsOnHover", true );
mMiddleClick = cg.readEntry( "middleClick", true );
mCheckNewComicStripsIntervall = cg.readEntry( "checkNewComicStripsIntervall", 30 );
//use a decent default size
const QSizeF tempMaxSize = isInPanel() ? QSizeF( 600, 250 ) : this->size();
mMaxSize = cg.readEntry( "maxSize", tempMaxSize );
mLastSize = mMaxSize;
globalComicUpdater->load();
}
void ComicApplet::saveConfig()
{
KConfigGroup cg = config();
cg.writeEntry( "comic", mCurrent.id() );
cg.writeEntry( "showComicUrl", mShowComicUrl );
cg.writeEntry( "showComicAuthor", mShowComicAuthor );
cg.writeEntry( "showComicTitle", mShowComicTitle );
cg.writeEntry( "showComicIdentifier", mShowComicIdentifier );
cg.writeEntry( "showErrorPicture", mShowErrorPicture );
cg.writeEntry( "arrowsOnHover", mArrowsOnHover );
cg.writeEntry( "middleClick", mMiddleClick );
cg.writeEntry( "tabIdentifier", mTabIdentifier );
cg.writeEntry( "checkNewComicStripsIntervall", mCheckNewComicStripsIntervall );
globalComicUpdater->save();
}
void ComicApplet::slotNextDay()
{
updateComic(mCurrent.next());
}
void ComicApplet::slotPreviousDay()
{
updateComic(mCurrent.prev());
}
void ComicApplet::slotFirstDay()
{
updateComic(mCurrent.first());
}
void ComicApplet::slotCurrentDay()
{
updateComic(QString());
}
void ComicApplet::slotFoundLastStrip( int index, const QString &identifier, const QString &suffix )
{
KConfigGroup cg = config();
if ( suffix != cg.readEntry( "lastStrip_" + identifier, QString() ) ) {
kDebug() << identifier << "has a newer strip.";
setTabHighlighted( identifier, true );
cg.writeEntry( "lastStripVisited_" + identifier, false );
}
mActionNextNewStripTab->setEnabled( hasHighlightedTabs() );
}
void ComicApplet::slotGoJump()
{
StripSelector *selector = StripSelectorFactory::create(mCurrent.type());
connect(selector, SIGNAL(stripChosen(QString)), this, SLOT(updateComic(QString)));
selector->select(mCurrent);
}
void ComicApplet::slotStorePosition()
{
mCurrent.storePosition(mActionStorePosition->isChecked());
}
void ComicApplet::slotShop()
{
KRun::runUrl(mCurrent.shopUrl(), "text/html", 0);
}
bool ComicApplet::isInPanel() const
{
return ( this->geometry().width() < 70 ) || ( this->geometry().height() < 50 );
}
void ComicApplet::createComicBook()
{
ComicArchiveDialog *dialog = new ComicArchiveDialog(mCurrent.id(), mCurrent.title(), mCurrent.type(), mCurrent.current(),
mCurrent.first(), mSavingDir->getDir());
dialog->setAttribute(Qt::WA_DeleteOnClose);//to have destroyed emitted upon closing
connect( dialog, SIGNAL(archive(int,KUrl,QString,QString)), this, SLOT(slotArchive(int,KUrl,QString,QString)) );
dialog->show();
}
void ComicApplet::slotArchive( int archiveType, const KUrl &dest, const QString &fromIdentifier, const QString &toIdentifier )
{
mSavingDir->setDir(dest.directory());
const QString id = mCurrent.id();
kDebug() << "Archiving:" << id << archiveType << dest << fromIdentifier << toIdentifier;
ComicArchiveJob *job = new ComicArchiveJob(dest, mEngine, static_cast< ComicArchiveJob::ArchiveType >( archiveType ), mCurrent.type(), id, this);
job->setFromIdentifier(id + ':' + fromIdentifier);
job->setToIdentifier(id + ':' + toIdentifier);
if (job->isValid()) {
connect(job, SIGNAL(finished(KJob*)), this, SLOT(slotArchiveFinished(KJob*)));
KIO::getJobTracker()->registerJob(job);
job->start();
} else {
kWarning() << "Archiving job is not valid.";
delete job;
}
}
void ComicApplet::slotArchiveFinished (KJob *job )
{
if ( job->error() ) {
KNotification::event( KNotification::Warning, i18n( "Archiving comic failed" ), job->errorText(), KIcon( "dialog-warning" ).pixmap( KIconLoader::SizeMedium ) );
}
}
QList<QAction*> ComicApplet::contextualActions()
{
return mActions;
}
QSizeF ComicApplet::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
if (which != Qt::PreferredSize) {
return Applet::sizeHint(which, constraint);
} else {
QSize imageSize = mCurrent.image().size();
if (!imageSize.isEmpty()) {
return imageSize;
} else {
return Applet::sizeHint(which, constraint);
}
}
}
void ComicApplet::updateComic( const QString &identifierSuffix )
{
mEngine = dataEngine( "comic" );
const QString id = mCurrent.id();
setConfigurationRequired( id.isEmpty() );
if ( !id.isEmpty() && mEngine && mEngine->isValid() ) {
setBusy( true );
const QString identifier = id + ':' + identifierSuffix;
//disconnecting of the oldSource is needed, otherwise you could get data for comics you are not looking at if you use tabs
//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 come in
if ( !mIdentifierError.isEmpty() && !mIdentifierError.contains( id ) ) {
mEngine->disconnectSource( mIdentifierError, this );
mIdentifierError.clear();
}
if ( ( mIdentifierError != mOldSource ) && ( mOldSource != identifier ) ) {
mEngine->disconnectSource( mOldSource, this );
}
mOldSource = identifier;
mEngine->disconnectSource( identifier, this );
mEngine->connectSource( identifier, this );
const Plasma::DataEngine::Data data = mEngine->query( identifier );
if ( data[ "Error" ].toBool() ) {
dataUpdated( QString(), data );
}
} else {
kError() << "Either no identifier was specified or the engine could not be created:" << "id" << id << "engine valid:" << ( mEngine && mEngine->isValid() );
setConfigurationRequired( true );
}
}
void ComicApplet::updateContextMenu()
{
mActionGoFirst->setVisible(mCurrent.hasFirst());
mActionGoFirst->setEnabled(mCurrent.hasPrev());
mActionGoLast->setEnabled(true);//always enable to have some kind of refresh action
if (mActionShop) {
mActionShop->setEnabled(mCurrent.shopUrl().isValid());
}
}
void ComicApplet::slotSaveComicAs()
{
ComicSaver saver(mSavingDir);
saver.save(mCurrent);
}
void ComicApplet::slotScaleToContent()
{
setShowActualSize(mActionScaleContent->isChecked());
}
//QML
QObject *ComicApplet::comicsModel()
{
return &mActiveComicModel;
}
bool ComicApplet::showComicUrl() const
{
return mShowComicUrl;
}
void ComicApplet::setShowComicUrl(bool show)
{
if (show == mShowComicUrl)
return;
mShowComicUrl = show;
emit showComicUrlChanged();
}
bool ComicApplet::showComicAuthor() const
{
return mShowComicAuthor;
}
void ComicApplet::setShowComicAuthor(bool show)
{
if (show == mShowComicAuthor)
return;
mShowComicAuthor = show;
emit showComicAuthorChanged();
}
bool ComicApplet::showComicTitle() const
{
return mShowComicTitle;
}
void ComicApplet::setShowComicTitle(bool show)
{
if (show == mShowComicTitle)
return;
mShowComicTitle = show;
emit showComicTitleChanged();
}
bool ComicApplet::showComicIdentifier() const
{
return mShowComicIdentifier;
}
void ComicApplet::setShowComicIdentifier(bool show)
{
if (show == mShowComicIdentifier)
return;
mShowComicIdentifier = show;
emit showComicIdentifierChanged();
}
bool ComicApplet::showErrorPicture() const
{
return mShowErrorPicture;
}
void ComicApplet::setShowErrorPicture(bool show)
{
if (show == mShowErrorPicture)
return;
mShowErrorPicture = show;
emit showErrorPictureChanged();
}
bool ComicApplet::arrowsOnHover() const
{
return mArrowsOnHover;
}
void ComicApplet::setArrowsOnHover(bool show)
{
if (show == mArrowsOnHover)
return;
mArrowsOnHover = show;
emit arrowsOnHoverChanged();
}
bool ComicApplet::middleClick() const
{
return mMiddleClick;
}
void ComicApplet::setMiddleClick(bool show)
{
if (show == mMiddleClick)
return;
mMiddleClick = show;
emit middleClickChanged();
}
QVariantHash ComicApplet::comicData()
{
return mComicData;
}
void ComicApplet::refreshComicData()
{
mComicData["image"] = mCurrent.image();
mComicData["prev"] = mCurrent.prev();
mComicData["next"] = mCurrent.next();
mComicData["additionalText"] = mCurrent.additionalText();
mComicData["websiteUrl"] = mCurrent.websiteUrl().prettyUrl();
mComicData["websiteHost"] = mCurrent.websiteUrl().host();
mComicData["imageUrl"] = mCurrent.websiteUrl().prettyUrl();
mComicData["shopUrl"] = mCurrent.websiteUrl().prettyUrl();
mComicData["first"] = mCurrent.first();
mComicData["stripTitle"] = mCurrent.stripTitle();
mComicData["author"] = mCurrent.author();
mComicData["title"] = mCurrent.title();
mComicData["suffixType"] = "Date";
mComicData["current"] = mCurrent.current();
//mComicData["last"] = mCurrent.last();
mComicData["currentReadable"] = mCurrent.currentReadable();
mComicData["firstStripNum"] = mCurrent.firstStripNum();
mComicData["maxStripNum"] = mCurrent.maxStripNum();
mComicData["isLeftToRight"] = mCurrent.isLeftToRight();
mComicData["isTopToBottom"] = mCurrent.isTopToBottom();
emit comicDataChanged();
}
bool ComicApplet::showActualSize() const
{
return mCurrent.scaleComic();
}
void ComicApplet::setShowActualSize(bool show)
{
if (show == mCurrent.scaleComic())
return;
mCurrent.setScaleComic(show);
emit showActualSizeChanged();
}
//Endof QML
void ComicApplet::setTabHighlighted(const QString &id, bool highlight)
{
//Search for matching id
for (int index = 0; index < mActiveComicModel.rowCount(); ++index) {
QStandardItem * item = mActiveComicModel.item(index);
QString currentId = item->data(ActiveComicModel::ComicKeyRole).toString();
if (id == currentId){
if (highlight != item->data(ActiveComicModel::ComicHighlightRole).toBool()) {
item->setData(highlight, ActiveComicModel::ComicHighlightRole);
emit tabHighlightRequest(id, highlight);
}
}
}
}
bool ComicApplet::hasHighlightedTabs()
{
for (int i = 0; i < mActiveComicModel.rowCount(); ++i) {
if (isTabHighlighted(i)) {
return true;
}
}
return false;
}
bool ComicApplet::isTabHighlighted(int index) const
{
if (index < 0 || index >= mActiveComicModel.rowCount()) {
return false;
}
QStandardItem * item = mActiveComicModel.item(index);
return item->data(ActiveComicModel::ComicHighlightRole).toBool();
}
#include "moc_comic.cpp"

View file

@ -1,209 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Tobias Koenig <tokoe@kde.org> *
* Copyright (C) 2008 by Marco Martin <notmart@gmail.com> *
* Copyright (C) 2008-2010 Matthias Fuchs <mat69@gmx.net> *
* Copyright (C) 2012 Reza Fatahilah Shah <rshah0385@kireihana.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#ifndef COMIC_H
#define COMIC_H
#include "comicdata.h"
#include <QtCore/qdatetime.h>
#include <KUrl>
#include <Plasma/DataEngine>
#include <Plasma/PopupApplet>
#include "activecomicmodel.h"
namespace Plasma {
class DeclarativeWidget;
}
class CheckNewStrips;
class ComicModel;
class ConfigWidget;
class KAction;
class KJob;
class QAction;
class QGraphicsLayout;
class QSortFilterProxyModel;
class QTimer;
class SavingDir;
class ComicApplet : public Plasma::PopupApplet
{
Q_OBJECT
Q_PROPERTY(QObject * comicsModel READ comicsModel NOTIFY comicModelChanged)
Q_PROPERTY(bool showComicUrl READ showComicUrl WRITE setShowComicUrl NOTIFY showComicUrlChanged)
Q_PROPERTY(bool showComicAuthor READ showComicAuthor WRITE setShowComicAuthor NOTIFY showComicAuthorChanged)
Q_PROPERTY(bool showComicTitle READ showComicTitle WRITE setShowComicTitle NOTIFY showComicTitleChanged)
Q_PROPERTY(bool showComicIdentifier READ showComicIdentifier WRITE setShowComicIdentifier NOTIFY showComicIdentifierChanged)
Q_PROPERTY(bool showErrorPicture READ showErrorPicture WRITE setShowErrorPicture NOTIFY showErrorPictureChanged)
Q_PROPERTY(bool arrowsOnHover READ arrowsOnHover WRITE setArrowsOnHover NOTIFY arrowsOnHoverChanged)
Q_PROPERTY(bool middleClick READ middleClick WRITE setMiddleClick NOTIFY middleClickChanged)
Q_PROPERTY(QVariantHash comicData READ comicData NOTIFY comicDataChanged)
Q_PROPERTY(bool showActualSize READ showActualSize WRITE setShowActualSize NOTIFY showActualSizeChanged)
public:
ComicApplet( QObject *parent, const QVariantList &args );
~ComicApplet();
void init();
virtual QList<QAction*> contextualActions();
QGraphicsWidget *graphicsWidget();
//For QML
QObject *comicsModel();
QVariantHash comicData();
bool showComicUrl() const;
void setShowComicUrl(bool show);
bool showComicAuthor() const;
void setShowComicAuthor(bool show);
bool showComicTitle() const;
void setShowComicTitle(bool show);
bool showComicIdentifier() const;
void setShowComicIdentifier(bool show);
bool showErrorPicture() const;
void setShowErrorPicture(bool show);
bool arrowsOnHover() const;
void setArrowsOnHover(bool show);
bool middleClick() const;
void setMiddleClick(bool show);
bool showActualSize() const;
void setShowActualSize(bool show);
Q_INVOKABLE bool checkAuthorization(const QString &permissionName) { return hasAuthorization(permissionName); }
//End for QML
Q_SIGNALS:
void comicModelChanged();
void showComicUrlChanged();
void showComicAuthorChanged();
void showComicTitleChanged();
void showComicIdentifierChanged();
void showErrorPictureChanged();
void arrowsOnHoverChanged();
void middleClickChanged();
void comicDataChanged();
void tabHighlightRequest(const QString &id, bool highlight);
void showNextNewStrip();
void showActualSizeChanged();
public Q_SLOTS:
void dataUpdated( const QString &name, const Plasma::DataEngine::Data &data );
void createConfigurationInterface( KConfigDialog *parent );
private Q_SLOTS:
void slotTabChanged( const QString &newIdentifier );
void slotNextDay();
void slotPreviousDay();
void slotFirstDay();
void slotCurrentDay();
void slotFoundLastStrip( int index, const QString &identifier, const QString &suffix );
void slotGoJump();
void slotSaveComicAs();
void slotScaleToContent();
void slotShop();
void slotStorePosition();
void applyConfig();
void checkDayChanged();
void createComicBook();
void slotArchive( int archiveType, const KUrl &dest, const QString &fromIdentifier, const QString &toIdentifier );
void slotArchiveFinished( KJob *job );
public slots:
void configChanged();
Q_INVOKABLE void updateComic(const QString &identifierSuffix = QString());
Q_INVOKABLE void goJump() { slotGoJump();}
Q_INVOKABLE void shop() { slotShop();}
Q_INVOKABLE void tabChanged(const QString &newIdentifier) { slotTabChanged(newIdentifier);}
protected:
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
private:
void changeComic( bool differentComic );
void updateUsedComics();
void updateContextMenu();
void updateView();
void saveConfig();
bool isInPanel() const;
void refreshComicData();
void setTabHighlighted(const QString &id, bool highlight);
bool hasHighlightedTabs();
bool isTabHighlighted(int index) const;
private:
static const int CACHE_LIMIT;
ComicModel *mModel;
QSortFilterProxyModel *mProxy;
ActiveComicModel mActiveComicModel;
QVariantHash mComicData;
QDate mCurrentDay;
QString mIdentifierError;
QString mOldSource;
ConfigWidget *mConfigWidget;
bool mDifferentComic;
bool mShowComicUrl;
bool mShowComicAuthor;
bool mShowComicTitle;
bool mShowComicIdentifier;
bool mShowErrorPicture;
bool mArrowsOnHover;
bool mMiddleClick;
int mCheckNewComicStripsIntervall;
CheckNewStrips *mCheckNewStrips;
QTimer *mDateChangedTimer;
QList<QAction*> mActions;
Plasma::DeclarativeWidget *mDeclarativeWidget;
QAction *mActionGoFirst;
QAction *mActionGoLast;
QAction *mActionGoJump;
QAction *mActionScaleContent;
QAction *mActionShop;
QAction *mActionStorePosition;
KAction *mActionNextNewStripTab;
QSizeF mMaxSize;
QSizeF mLastSize;
QSizeF mIdealSize;
Plasma::DataEngine *mEngine;
//Tabs
bool mTabAdded;
QStringList mTabIdentifier;
ComicData mCurrent;
SavingDir *mSavingDir;
};
K_EXPORT_PLASMA_APPLET( comic, ComicApplet )
#endif

View file

@ -1,8 +0,0 @@
[KNewStuff3]
ProvidersUrl=http://download.kde.org/ocs/providers.xml
Categories=Plasma Comic
TargetDir=plasma/comics
Uncompress=never
InstallationCommand=plasmapkg -t comic -i %f
UninstallCommand=plasmapkg -t comic -r %f

View file

@ -1,238 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ComicSettings</class>
<widget class="QWidget" name="ComicSettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>394</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_8">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Comic</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QTreeView" name="listView_comic">
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
<attribute name="headerCascadingSectionResizes">
<bool>false</bool>
</attribute>
</widget>
</item>
<item row="2" column="1">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QPushButton" name="pushButton_GHNS">
<property name="toolTip">
<string>Download new comics</string>
</property>
<property name="text">
<string>&amp;Get New Comics...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="checkBox_middle">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;Middle-click on the comic to show it at its original size</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QLabel" name="label_13">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Update</string>
</property>
</widget>
</item>
<item row="7" column="1">
<layout class="QFormLayout" name="formLayout_4">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Automatically update comic plugins:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="updateIntervall">
<property name="value">
<number>0</number>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>120</number>
</property>
<property name="suffix">
<string> days</string>
</property>
<property name="prefix">
<string>every </string>
</property>
<property name="specialValueText">
<string>never</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Check for new comic strips:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="updateIntervallComicStrips">
<property name="value">
<number>0</number>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>1200</number>
</property>
<property name="suffix">
<string> minutes</string>
</property>
<property name="prefix">
<string>every </string>
</property>
<property name="specialValueText">
<string>never</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="0">
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
</customwidgets>
<tabstops>
<tabstop>pushButton_GHNS</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -1,200 +0,0 @@
/***************************************************************************
* Copyright (C) 2011 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "comicarchivedialog.h"
#include "comicarchivejob.h"
#include <KFileDialog>
ComicArchiveDialog::ComicArchiveDialog( const QString &pluginName, const QString &comicName, IdentifierType identifierType, const QString &currentIdentifierSuffix, const QString &firstIdentifierSuffix, const QString &savingDir, QWidget *parent )
: KDialog( parent ),
mIdentifierType( identifierType ),
mPluginName( pluginName )
{
QWidget *widget = new QWidget(this);
ui.setupUi(widget);
setCaption( i18n( "Create %1 Comic Book Archive", comicName ) );
setMainWidget( widget );
switch ( mIdentifierType ) {
case Date: {
const QDate current = QDate::fromString( currentIdentifierSuffix, "yyyy-MM-dd" );
const QDate first = QDate::fromString( firstIdentifierSuffix, "yyyy-MM-dd" );
const QDate today = QDate::currentDate();
QDate maxDate = today;
if ( current.isValid() ) {
ui.fromDate->setDate( current );
ui.toDate->setDate( current );
maxDate = ( today > current ? today : current );
}
if ( first.isValid() ) {
ui.fromDate->setMinimumDate( first );
ui.toDate->setMinimumDate( first );
}
connect( ui.fromDate, SIGNAL(dateChanged(QDate)), this, SLOT(fromDateChanged(QDate)) );
connect( ui.toDate, SIGNAL(dateChanged(QDate)), this, SLOT(toDateChanged(QDate)) );
break;
}
case Number: {
bool ok;
const int current = currentIdentifierSuffix.toInt( &ok );
if ( ok ) {
ui.fromNumber->setValue( current );
ui.toNumber->setValue( current );
}
const int first = firstIdentifierSuffix.toInt( &ok );
if ( ok ) {
ui.fromNumber->setMinimum( first );
ui.toNumber->setMinimum( first );
}
break;
}
case String: {
ui.fromString->setText( currentIdentifierSuffix );
ui.toString->setText( currentIdentifierSuffix );
connect( ui.fromString, SIGNAL(textEdited(QString)), this, SLOT(updateOkButton()) );
connect( ui.toString, SIGNAL(textEdited(QString)), this, SLOT(updateOkButton()) );
break;
}
}
ui.types->setCurrentIndex( mIdentifierType );
archiveTypeChanged( ComicArchiveJob::ArchiveAll );
//TODO suggest file name!
ui.dest->fileDialog()->setOperationMode( KFileDialog::Saving );
if ( !savingDir.isEmpty() ) {
ui.dest->setStartDir( savingDir );
}
connect( ui.archiveType, SIGNAL(currentIndexChanged(int)), this, SLOT(archiveTypeChanged(int)) );
connect( ui.dest, SIGNAL(textChanged(QString)), this, SLOT(updateOkButton()) );
connect( this, SIGNAL(okClicked()), this, SLOT(slotOkClicked()) );
}
void ComicArchiveDialog::archiveTypeChanged( int newType )
{
switch ( newType ) {
case ComicArchiveJob::ArchiveAll:
setFromVisible( false );
setToVisibile( false );
break;
break;
case ComicArchiveJob::ArchiveEndTo:
case ComicArchiveJob::ArchiveStartTo:
setFromVisible( false );
setToVisibile( true );
break;
case ComicArchiveJob::ArchiveFromTo:
setFromVisible( true );
setToVisibile( true );
break;
}
updateOkButton();
}
void ComicArchiveDialog::fromDateChanged( const QDate &newDate )
{
if ( ui.toDate->date() < newDate ) {
ui.toDate->setDate( newDate );
}
updateOkButton();
}
void ComicArchiveDialog::toDateChanged( const QDate &newDate )
{
if ( ui.fromDate->date() > newDate ) {
ui.fromDate->setDate( newDate );
}
updateOkButton();
}
void ComicArchiveDialog::updateOkButton()
{
const int archiveType = ui.archiveType->currentIndex();
bool okEnabled = true;
//string is handled here, as it is the only identifier which can be invalid (empty)
if ( mIdentifierType == String ) {
if ( archiveType == ComicArchiveJob::ArchiveAll ) {
okEnabled = true ;
} else if ( ui.archiveType->currentIndex() == ComicArchiveJob::ArchiveFromTo ) {
okEnabled = !ui.fromString->text().isEmpty() && !ui.toString->text().isEmpty();
} else {
okEnabled = !ui.toString->text().isEmpty();
}
}
okEnabled = ( okEnabled && !ui.dest->url().isEmpty() );
enableButtonOk( okEnabled );
}
void ComicArchiveDialog::slotOkClicked()
{
const int archiveType = ui.archiveType->currentIndex();
QString fromIdentifier;
QString toIdentifier;
switch ( mIdentifierType ) {
case Date:
fromIdentifier = ui.fromDate->date().toString( "yyyy-MM-dd" );
toIdentifier = ui.toDate->date().toString( "yyyy-MM-dd" );
break;
case Number: {
fromIdentifier = QString::number( ui.fromNumber->value() );
toIdentifier = QString::number( ui.toNumber->value() );
//the user entered from and to wrong, swap them
if ( ( archiveType == ComicArchiveJob::ArchiveFromTo) && ( ui.toNumber->value() < ui.fromNumber->value() ) ) {
QString temp = fromIdentifier;
fromIdentifier = toIdentifier;
toIdentifier = temp;
}
break;
}
case String:
fromIdentifier = ui.fromString->text();
toIdentifier = ui.toString->text();
break;
}
emit archive( archiveType, ui.dest->url(), fromIdentifier, toIdentifier );
}
void ComicArchiveDialog::setFromVisible( bool visible )
{
ui.fromDateLabel->setVisible( visible );
ui.fromDate->setVisible( visible );
ui.fromNumberLabel->setVisible( visible );
ui.fromNumber->setVisible( visible );
ui.fromStringLabel->setVisible( visible );
ui.fromString->setVisible( visible );
}
void ComicArchiveDialog::setToVisibile( bool visible )
{
ui.toDateLabel->setVisible( visible );
ui.toDate->setVisible( visible );
ui.toNumberLabel->setVisible( visible );
ui.toNumber->setVisible( visible );
ui.toStringLabel->setVisible( visible );
ui.toString->setVisible( visible );
}

View file

@ -1,57 +0,0 @@
/***************************************************************************
* Copyright (C) 2011 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#ifndef COMIC_ARCHIVE_DIALOG_H
#define COMIC_ARCHIVE_DIALOG_H
#include "comicinfo.h"
#include "ui_comicarchivedialog.h"
#include <KDialog>
class ComicArchiveDialog : public KDialog
{
Q_OBJECT
public:
ComicArchiveDialog( const QString &pluginName, const QString &comicName, IdentifierType identifierType, const QString &currentIdentifierSuffix, const QString &firstIdentifierSuffix, const QString &savingDir = QString(), QWidget *parent = 0 );
signals:
void archive( int archiveType, const KUrl &dest, const QString &fromIdentifier, const QString &toIdentifier );
private slots:
void archiveTypeChanged( int newType );
void fromDateChanged( const QDate &newDate );
void toDateChanged( const QDate &newDate );
void slotOkClicked();
void updateOkButton();
private:
void setFromVisible( bool visible );
void setToVisibile( bool visible );
private:
Ui::ComicArchiveDialog ui;
IdentifierType mIdentifierType;
QString mPluginName;
};
#endif

View file

@ -1,218 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ComicArchiveDialog</class>
<widget class="QWidget" name="ComicArchiveDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>469</width>
<height>143</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Destination:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="KUrlRequester" name="dest">
<property name="filter">
<string>*.cbz|Comic Book Archive (Zip)</string>
</property>
<property name="mode">
<set>KFile::File|KFile::LocalOnly</set>
</property>
</widget>
</item>
<item row="1" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="statusTip">
<string>The range of comic strips to archive.</string>
</property>
<property name="text">
<string>Range:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="KComboBox" name="archiveType">
<item>
<property name="text">
<string>All</string>
</property>
</item>
<item>
<property name="text">
<string>From beginning to ...</string>
</property>
</item>
<item>
<property name="text">
<string>From end to ...</string>
</property>
</item>
<item>
<property name="text">
<string>Manual range</string>
</property>
</item>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QStackedWidget" name="types">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="date">
<layout class="QFormLayout" name="formLayout">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="fromDateLabel">
<property name="text">
<string comment="in a range: from to">From:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="toDateLabel">
<property name="text">
<string comment="in a range: from to">To:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDateEdit" name="fromDate">
<property name="displayFormat">
<string>dd.MM.yyyy</string>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDateEdit" name="toDate">
<property name="displayFormat">
<string>dd.MM.yyyy</string>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="number">
<layout class="QFormLayout" name="formLayout_2">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="fromNumberLabel">
<property name="text">
<string comment="in a range: from to">From:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="toNumberLabel">
<property name="text">
<string comment="in a range: from to">To:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="toNumber">
<property name="maximum">
<number>100000</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="fromNumber">
<property name="maximum">
<number>100000</number>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="string">
<layout class="QFormLayout" name="formLayout_3">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="fromStringLabel">
<property name="text">
<string comment="in a range: from to">From:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="toStringLabel">
<property name="text">
<string comment="in a range: from to">To:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="KLineEdit" name="fromString"/>
</item>
<item row="1" column="1">
<widget class="KLineEdit" name="toString"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KUrlRequester</class>
<extends>QFrame</extends>
<header>kurlrequester.h</header>
</customwidget>
<customwidget>
<class>KLineEdit</class>
<extends>QLineEdit</extends>
<header>klineedit.h</header>
</customwidget>
<customwidget>
<class>KComboBox</class>
<extends>QComboBox</extends>
<header>kcombobox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View file

@ -1,395 +0,0 @@
/***************************************************************************
* Copyright (C) 2011 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "comicarchivejob.h"
#include <KDebug>
#include <KIO/NetAccess>
#include <KTemporaryFile>
#include <KZip>
ComicArchiveJob::ComicArchiveJob( const KUrl &dest, Plasma::DataEngine *engine, ComicArchiveJob::ArchiveType archiveType, IdentifierType identifierType, const QString &pluginName, QObject *parent )
: KJob( parent ),
mType( archiveType ),
mDirection( Undefined ),
mIdentifierType( identifierType ),
mSuspend( false ),
mFindAmount( true ),
mHasVariants( false ),
mDone( false ),
mComicNumber( 0 ),
mProcessedFiles( 0 ),
mTotalFiles( -1 ),
mEngine( engine ),
mZipFile( new KTemporaryFile ),
mZip( 0 ),
mPluginName( pluginName ),
mDest( dest )
{
if ( mZipFile->open() ) {
mZip = new KZip( mZipFile->fileName() );
mZip->open( QIODevice::ReadWrite );
mZip->setCompression( KZip::NoCompression );
setCapabilities( Killable | Suspendable );
} else {
kError() << "Could not create a temporary file for the zip file.";
}
}
ComicArchiveJob::~ComicArchiveJob()
{
emitResultIfNeeded();
delete mZip;
delete mZipFile;
qDeleteAll( mBackwardFiles );
}
bool ComicArchiveJob::isValid() const
{
if ( mPluginName.isEmpty() ) {
kWarning() << "No plugin name specified.";
return false;
}
switch ( mType ) {
case ArchiveFromTo:
if ( mToIdentifier.isEmpty() || mFromIdentifier.isEmpty() ) {
kWarning() << "Not enought data provided to archive a range.";
return false;
}
break;
case ArchiveStartTo:
case ArchiveEndTo:
if ( mToIdentifier.isEmpty() ) {
kWarning() << "Not enough data provied to archive StartTo/EndTo.";
return false;
}
break;
default:
break;
}
return mEngine->isValid() && mZip && mZip->isOpen();
}
void ComicArchiveJob::setToIdentifier( const QString &toIdentifier )
{
mToIdentifier = toIdentifier;
mToIdentifierSuffix = mToIdentifier;
mToIdentifierSuffix.remove( mPluginName + ':' );
}
void ComicArchiveJob::setFromIdentifier( const QString &fromIdentifier )
{
mFromIdentifier = fromIdentifier;
mFromIdentifierSuffix = mFromIdentifier;
mFromIdentifierSuffix.remove( mPluginName + ':' );
}
void ComicArchiveJob::start()
{
switch ( mType ) {
case ArchiveAll:
requestComic( suffixToIdentifier( QString() ) );
break;
case ArchiveStartTo:
requestComic( mToIdentifier );
break;
case ArchiveEndTo: {
setFromIdentifier( mToIdentifier );
mToIdentifier.clear();
mToIdentifierSuffix.clear();
requestComic( suffixToIdentifier( QString() ) );
break;
}
case ArchiveFromTo:
mDirection = Foward;
defineTotalNumber();
requestComic( mFromIdentifier );
break;
}
}
void ComicArchiveJob::dataUpdated( const QString &source, const Plasma::DataEngine::Data &data )
{
if ( !mZip ) {
kWarning() << "No zip file, aborting.";
setErrorText( i18n( "No zip file is existing, aborting." ) );
setError( KilledJobError );
emitResultIfNeeded();
return;
}
const QString currentIdentifier = data[ "Identifier" ].toString();
QString currentIdentifierSuffix = currentIdentifier;
currentIdentifierSuffix.remove( mPluginName + ':' );
const QImage image = data[ "Image" ].value<QImage>();
const bool hasError = data[ "Error" ].toBool() || image.isNull();
const QString previousIdentifierSuffix = data[ "Previous identifier suffix" ].toString();
const QString nextIdentifierSuffix = data[ "Next identifier suffix" ].toString();
const QString firstIdentifierSuffix = data[ "First strip identifier suffix" ].toString();
mAuthors << data[ "Comic Author" ].toString().split( ',', QString::SkipEmptyParts );
mAuthors.removeDuplicates();
if ( mComicTitle.isEmpty() ) {
mComicTitle = data[ "Title" ].toString();
}
mEngine->disconnectSource( source, this );
if ( hasError ) {
kWarning() << "An error occured at" << source << "stopping.";
setErrorText( i18n( "An error happened for identifier %1.", source ) );
setError( KilledJobError );
copyZipFileToDestination();
return;
}
if ( mDirection == Undefined ) {
if ( ( mType == ArchiveAll ) || ( mType == ArchiveStartTo ) ) {
if ( !firstIdentifierSuffix.isEmpty() ) {
setFromIdentifier( suffixToIdentifier( firstIdentifierSuffix ) );
}
if ( mType == ArchiveAll ) {
setToIdentifier( currentIdentifier );
}
mDirection = ( firstIdentifierSuffix.isEmpty() ? Backward : Foward );
if ( mDirection == Foward ) {
requestComic( suffixToIdentifier( firstIdentifierSuffix ) );
return;
} else {
//backward, i.e. the to identifier is unknown
mToIdentifier.clear();
mToIdentifierSuffix.clear();
}
} else if ( mType == ArchiveEndTo ) {
mDirection = Foward;
setToIdentifier( currentIdentifier );
requestComic( mFromIdentifier );
return;
}
}
bool worked = false;
++mProcessedFiles;
if ( mDirection == Foward ) {
KTemporaryFile tempFile;
worked = tempFile.open();
worked = worked && tempFile.flush();
worked = ( worked ? image.save( tempFile.fileName(), "PNG" ) : worked );
worked = ( worked ? addFileToZip( tempFile.fileName() ) : worked );
if ( worked ) {
if ( ( currentIdentifier == mToIdentifier ) || ( currentIdentifierSuffix == nextIdentifierSuffix) || nextIdentifierSuffix.isEmpty() ) {
kDebug() << "Done downloading at:" << source;
copyZipFileToDestination();
} else {
requestComic( suffixToIdentifier( nextIdentifierSuffix ) );
}
}
} else if ( mDirection == Backward ) {
KTemporaryFile *tempFile = new KTemporaryFile;
mBackwardFiles << tempFile;
worked = tempFile->open();
worked = worked && tempFile->flush();
worked = ( worked ? image.save( tempFile->fileName(), "PNG" ) : worked );
if ( worked ) {
if ( ( currentIdentifier == mToIdentifier ) || ( currentIdentifierSuffix == previousIdentifierSuffix ) || previousIdentifierSuffix.isEmpty() ) {
kDebug() << "Done downloading at:" << source;
createBackwardZip();
} else {
requestComic( suffixToIdentifier( previousIdentifierSuffix) );
}
}
}
defineTotalNumber( currentIdentifierSuffix );
setProcessedAmount( Files, mProcessedFiles );
if ( mTotalFiles != -1 ) {
setPercent( ( 100 * mProcessedFiles ) / mTotalFiles );
}
if ( !worked ) {
kError() << "Could not write the file, identifier:" << source;
setErrorText( i18n( "Failed creating the file with identifier %1.", source ) );
setError( KilledJobError );
emitResultIfNeeded();
}
}
bool ComicArchiveJob::doKill()
{
mSuspend = true;
return KJob::doKill();
}
bool ComicArchiveJob::doSuspend()
{
mSuspend = true;
return true;
}
bool ComicArchiveJob::doResume()
{
mSuspend = false;
if ( !mRequest.isEmpty() ) {
requestComic( mRequest );
}
return true;
}
void ComicArchiveJob::defineTotalNumber( const QString &currentSuffix )
{
findTotalNumberFromTo();
if ( mTotalFiles == -1 ) {
kDebug() << "Unable to find the total number for" << mPluginName;
return;
}
//calculate a new value for total files, can be different from the previous one,
//if there are no strips for certain days/numbers
if ( !currentSuffix.isEmpty() ) {
if ( mIdentifierType == Date ) {
const QDate current = QDate::fromString( currentSuffix, "yyyy-MM-dd" );
const QDate to = QDate::fromString( mToIdentifierSuffix, "yyyy-MM-dd" );
if ( current.isValid() && to.isValid() ) {
//processed files + files still to download
mTotalFiles = mProcessedFiles + qAbs( current.daysTo( to ) );
}
} else if ( mIdentifierType == Number ) {
bool result = true;
bool ok;
const int current = currentSuffix.toInt( &ok );
result = ( result && ok );
const int to = mToIdentifierSuffix.toInt( &ok );
result = ( result && ok );
if ( result ) {
//processed files + files still to download
mTotalFiles = mProcessedFiles + qAbs( to - current );
}
}
}
if ( mTotalFiles != -1 ) {
setTotalAmount( Files, mTotalFiles );
}
}
void ComicArchiveJob::findTotalNumberFromTo()
{
if ( mTotalFiles != -1 ) {
return;
}
if ( mIdentifierType == Date ) {
const QDate from = QDate::fromString( mFromIdentifierSuffix, "yyyy-MM-dd" );
const QDate to = QDate::fromString( mToIdentifierSuffix, "yyyy-MM-dd" );
if ( from.isValid() && to.isValid() ) {
mTotalFiles = qAbs( from.daysTo( to ) ) + 1;
}
} else if ( mIdentifierType == Number ) {
bool result = true;
bool ok;
const int from = mFromIdentifierSuffix.toInt( &ok );
result = ( result && ok );
const int to = mToIdentifierSuffix.toInt( &ok );
result = ( result && ok );
if ( result ) {
mTotalFiles = qAbs( to - from ) + 1;
}
}
}
QString ComicArchiveJob::suffixToIdentifier( const QString &suffix ) const
{
return mPluginName + ':' + suffix;
}
void ComicArchiveJob::requestComic( QString identifier ) //krazy:exclude=passbyvalue
{
mRequest.clear();
if ( mSuspend ) {
mRequest = identifier;
return;
}
emit description( this, i18n( "Creating Comic Book Archive" ),
qMakePair( QString( "source" ), identifier ),
qMakePair( QString( "destination" ), mDest.prettyUrl() ) );
mEngine->connectSource( identifier, this );
mEngine->query( identifier );
}
bool ComicArchiveJob::addFileToZip( const QString &path )
{
//We use 6 signs, e.g. number 1 --> 000001.png, 123 --> 000123.png
//this way the comics should always be correctly sorted (otherwise evince e.g. has problems)
static const int numSigns = 6;
static const QString zero = QLatin1String( "0" );
QString number = QString::number( ++mComicNumber );
const int length = number.length();
if ( length < numSigns ) {
number = zero.repeated( numSigns - length ) + number;
}
return mZip->addLocalFile( path, number + QLatin1String( ".png" ) );
}
void ComicArchiveJob::createBackwardZip()
{
for ( int i = mBackwardFiles.count() - 1; i >= 0; --i ) {
if ( !addFileToZip( mBackwardFiles[i]->fileName() ) ) {
kWarning() << "Failed adding a file to the archive.";
setErrorText( i18n( "Failed adding a file to the archive." ) );
setError( KilledJobError );
emitResultIfNeeded();
return;
}
}
copyZipFileToDestination();
}
void ComicArchiveJob::copyZipFileToDestination()
{
mZip->close();
const bool worked = KIO::NetAccess::file_copy( KUrl( mZipFile->fileName() ), mDest );
//store additional data using Nepomuk
if (!worked) {
kWarning() << "Could not copy the zip file to the specified destination:" << mDest;
setErrorText( i18n( "Could not create the archive at the specified location." ) );
setError( KilledJobError );
emitResultIfNeeded();
return;
}
emitResultIfNeeded();
}
void ComicArchiveJob::emitResultIfNeeded()
{
if ( !mDone ) {
mDone = true;
emitResult();
}
}

View file

@ -1,144 +0,0 @@
/***************************************************************************
* Copyright (C) 2011 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#ifndef COMIC_ARCHIVE_JOB_H
#define COMIC_ARCHIVE_JOB_H
#include "comicinfo.h"
#include <KIO/Job>
#include <Plasma/DataEngine>
class KTemporaryFile;
class KZip;
class ComicArchiveJob : public KJob
{
Q_OBJECT
public:
enum ArchiveType {
ArchiveAll = 0,
ArchiveStartTo,
ArchiveEndTo,
ArchiveFromTo
};
/**
* Creates a comic archive job.
* The engine has to be a working comic dataengine.
* The archiveType defines what kind of input is given, e.g. if ArchiveAll is
* used no other parameters need to be defined, while ArchiveFromTo needs
* both toIdentifier and fromIdentifier (from <= to!), the other two types need only the toIdentifier.
* You need to define the plugin name in any case, this is part of the identifier e.g.
* "garfield:2010-03-04", here "garfield" is the plugin name
* @see setToIdentifier, setFromIdentifier
*/
ComicArchiveJob( const KUrl &dest, Plasma::DataEngine *engine, ArchiveType archiveType, IdentifierType identifierType, const QString &pluginName, QObject *parent = 0 );
~ComicArchiveJob();
/**
* Checks if all the needed data has been set
*/
bool isValid() const;
/**
* Sets the end to toIdentifier.
* Keep in mind that depending on the ArchiveType this might be ignored
*/
void setToIdentifier( const QString &toIdentifier );
/**
* Sets the beginning to toIdentifier.
* Keep in mind that depending on the ArchiveType this might be ignored
*/
void setFromIdentifier( const QString &fromIdentifier );
virtual void start();
public slots:
void dataUpdated( const QString &source, const Plasma::DataEngine::Data& data );
protected:
virtual bool doKill();
virtual bool doSuspend();
virtual bool doResume();
private:
/**
* Sets the total number of comics to download.
* @param currentSuffix if empty the from and to identifier suffix will be used.
* If a currentSuffix is defined it will check if the total number is different
* e.g. not a comic defined for every day etc.
*/
void defineTotalNumber( const QString &currentSuffix = QString() );
/**
* Sets mTotalFiles if that is -1 and it can calculate at total number
* base on the from and to identifier suffix
*/
void findTotalNumberFromTo();
QString suffixToIdentifier( const QString &suffix ) const;
void requestComic( QString identifier );
bool addFileToZip( const QString &path );
/**
* If the ArchiveDirection is Backward, this will fill the zip
* with mBackwardFiles (beginning from the back), and will call
* copyZipFileToDestination afterwards
*/
void createBackwardZip();
void copyZipFileToDestination();
void emitResultIfNeeded();
private:
enum ArchiveDirection {
Undefined,
Foward,
Backward
};
ArchiveType mType;
ArchiveDirection mDirection;
IdentifierType mIdentifierType;
bool mSuspend;
bool mFindAmount;
bool mHasVariants;
bool mDone;
int mComicNumber;
int mProcessedFiles;
int mTotalFiles;
Plasma::DataEngine *mEngine;
KTemporaryFile *mZipFile;
KZip *mZip;
QString mPluginName;
QString mToIdentifier;
QString mToIdentifierSuffix;
QString mFromIdentifier;
QString mFromIdentifierSuffix;
QString mComicTitle;
QString mRequest;
const KUrl mDest;
QStringList mAuthors;
QList< KTemporaryFile* > mBackwardFiles;
};
#endif

View file

@ -1,160 +0,0 @@
/***************************************************************************
* Copyright (C) 2012 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "comicdata.h"
#include <Plasma/Theme>
#include <QtCore/QDateTime>
#include <QtGui/QPainter>
ComicData::ComicData()
{
}
void ComicData::init(const QString &id, const KConfigGroup &config)
{
mId = id;
mCfg = config;
mFirstStripNum = 0;
mMaxStripNum = 0;
mScaleComic = false;
mIsLeftToRight = true;
mIsTopToBottom = true;
load();
}
void ComicData::load()
{
mScaleComic = mCfg.readEntry("scaleToContent_" + mId, false);
mMaxStripNum = mCfg.readEntry("maxStripNum_" + mId, 0);
mStored = mCfg.readEntry("storedPosition_" + mId, QString());
}
void ComicData::save()
{
mCfg.writeEntry("scaleToContent_" + mId, mScaleComic);
mCfg.writeEntry("maxStripNum_" + mId, mMaxStripNum);
mCfg.writeEntry("storedPosition_" + id(), mStored);
// no next, thus the most recent strip
if (!hasNext()) {
mCfg.writeEntry("lastStripVisited_" + mId, true);
mCfg.writeEntry("lastStrip_" + mId, mLast);
}
}
void ComicData::setScaleComic(bool scale)
{
mScaleComic = scale;
save();
}
void ComicData::storePosition(bool store)
{
mStored = (store ? mCurrent : QString());
save();
}
void ComicData::setData(const Plasma::DataEngine::Data &data)
{
const bool hasError = data[ "Error" ].toBool();
if (!hasError) {
mImage = data["Image"].value<QImage>();
mPrev = data["Previous identifier suffix"].toString();
mNext = data["Next identifier suffix"].toString();
mAdditionalText = data["Additional text"].toString();
}
mWebsiteUrl = data[ "Website Url" ].value<KUrl>();
mImageUrl = data["Image Url"].value<KUrl>();
mShopUrl = data[ "Shop Url" ].value<KUrl>();
mFirst = data[ "First strip identifier suffix" ].toString();
mStripTitle = data[ "Strip title" ].toString();
mAuthor = data[ "Comic Author" ].toString();
mTitle = data[ "Title" ].toString();
const QString suffixType = data[ "SuffixType" ].toString();
if ( suffixType == "Date" ) {
mType = Date;
} else if ( suffixType == "Number" ) {
mType = Number;
} else {
mType = String;
}
QString temp = data["Identifier"].toString();
mCurrent = temp.remove(mId + ':');
//found a new last identifier
if (!hasNext()) {
mLast = mCurrent;
}
mCurrentReadable = "";
if ( mType == Number ) {
mCurrentReadable = i18nc("an abbreviation for Number", "# %1", mCurrent);
int tempNum = mCurrent.toInt();
if ( mMaxStripNum < tempNum ) {
mMaxStripNum = tempNum;
}
temp = mFirst.remove(mId + ':');
mFirstStripNum = temp.toInt();
} else if ( mType == Date && QDate::fromString( temp, "yyyy-MM-dd" ).isValid() ) {
mCurrentReadable = mCurrent;
} else if ( mType == String ) {
mCurrentReadable = mCurrent;
}
mIsLeftToRight = data["isLeftToRight"].toBool();
mIsTopToBottom = data["isTopToBottom"].toBool();
save();
}
void ComicData::createErrorPicture(const Plasma::DataEngine::Data &data)
{
QPixmap errorPic( 500, 400 );
errorPic.fill();
QPainter p( &errorPic );
QFont font = Plasma::Theme::defaultTheme()->font( Plasma::Theme::DefaultFont );
font.setPointSize( 24 );
p.setPen( QColor( 0, 0, 0 ) );
p.setFont( font );
QString title = i18n( "Getting comic strip failed:" );
p.drawText( QRect( 10, 10 , 480, 100 ), Qt::TextWordWrap | Qt::AlignHCenter | Qt::AlignVCenter, title );
QString text = i18n( "Maybe there is no Internet connection.\nMaybe the comic plugin is broken.\nAnother reason might be that there is no comic for this day/number/string, so choosing a different one might work." );
mPrev = data["Previous identifier suffix"].toString();
if (hasPrev()) {
if (!data["Identifier"].toString().isEmpty() ) {
mErrorStrip = data["Identifier"].toString();
}
text.append( i18n( "\n\nChoose the previous strip to go to the last cached strip." ) );
}
font.setPointSize( 16 );
p.setFont( font );
p.drawText( QRect( 10, 120 , 480, 270 ), Qt::TextWordWrap | Qt::AlignLeft, text );
mImage = errorPic.toImage();
mAdditionalText = title + text;
}

View file

@ -1,157 +0,0 @@
/***************************************************************************
* Copyright (C) 2012 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#ifndef COMIC_DATA_H
#define COMIC_DATA_H
#include "comicinfo.h"
#include <KUrl>
#include <Plasma/DataEngine>
#include <QtCore/QString>
class ComicData
{
public:
ComicData();
void init(const QString &id, const KConfigGroup &config);
void setData(const Plasma::DataEngine::Data &data);
IdentifierType type() const { return mType; }
/**
* The identifier of the comic, e.g. "garfield"
*/
QString id() const { return mId; }
/**
* The stored comic e.g. "2007-12-21" for a comic of the Date type
*/
QString stored() const { return mStored; }
void storePosition(bool store);
/**
* The previous comic e.g. "2007-12-21" for a comic of the Date type
*/
QString prev() const { return mPrev; }
/**
* The current comic e.g. "2007-12-21" for a comic of the Date type
*/
QString current() const { return mCurrent; }
/**
* The next comic e.g. "2007-12-21" for a comic of the Date type
*/
QString next() const { return mNext; }
QString currentReadable() const { return mCurrentReadable; }
/**
* The first comic e.g. "2007-12-21" for a comic of the Date type
*/
QString first() const { return mFirst; }
bool hasNext() const { return !mNext.isEmpty(); }
bool hasPrev() const { return !mPrev.isEmpty(); }
bool hasFirst() const { return !mFirst.isEmpty(); }
bool hasStored() const { return !mStored.isEmpty(); }
bool hasImage() const { return !mImage.isNull(); }
QString additionalText() const { return mAdditionalText; }
QString title() const { return mTitle; }
void setTitle(const QString &title) { mTitle = title; }
QString stripTitle() const { return mStripTitle; }
KUrl websiteUrl() const { return mWebsiteUrl; }
KUrl imageUrl() const { return mImageUrl; }
KUrl shopUrl() const { return mShopUrl; }
QString author() const { return mAuthor; }
QImage image() const { return mImage; }
bool scaleComic() const { return mScaleComic; }
bool isLeftToRight() const { return mIsLeftToRight; }
bool isTopToBottom() const { return mIsTopToBottom; }
bool storePosition() const { return !mStored.isEmpty(); }
void setScaleComic(bool scale);
QString errorStrip() const { return mErrorStrip; }
int firstStripNum() const { return mFirstStripNum; }
int maxStripNum() const { return mMaxStripNum; }
void save();
private:
void load();
void createErrorPicture(const Plasma::DataEngine::Data &data);
private:
IdentifierType mType;
QString mId;
QString mFirst;
QString mLast;
QString mCurrent;
QString mNext;
QString mPrev;
QString mStored;
QString mCurrentReadable;
QString mErrorStrip;
QString mAuthor;
QString mTitle;
QString mStripTitle;
QString mAdditionalText;
KUrl mWebsiteUrl;
KUrl mImageUrl;
KUrl mShopUrl;
QImage mImage;
// only applicable if the comic is of type Number
int mFirstStripNum;
int mMaxStripNum;
bool mScaleComic;
bool mIsLeftToRight;
bool mIsTopToBottom;
KConfigGroup mCfg;
};
#endif

View file

@ -1,115 +0,0 @@
/***************************************************************************
* Copyright (C) 2012 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "comicinfo.h"
#include <KConfigGroup>
#include <KGlobalSettings>
#include <QtCore/QDir>
class SavingDir::SavingDirPrivate
{
public:
SavingDirPrivate(const KConfigGroup &cfg);
void init();
QString getDir() const;
void setDir(const QString &dir);
private:
void load();
void save();
bool isValid();
private:
KConfigGroup mCfg;
QString mDir;
};
SavingDir::SavingDirPrivate::SavingDirPrivate(const KConfigGroup &cfg)
: mCfg(cfg)
{
}
void SavingDir::SavingDirPrivate::init()
{
load();
save();
}
QString SavingDir::SavingDirPrivate::getDir() const
{
return mDir;
}
void SavingDir::SavingDirPrivate::setDir(const QString &dir)
{
mDir = dir;
save();
}
void SavingDir::SavingDirPrivate::load()
{
mDir = mCfg.readEntry("savingDir", QString());
if (!isValid()) {
mDir = KGlobalSettings::picturesPath();
}
if (!isValid()) {
mDir = KGlobalSettings::downloadPath();
}
if (!isValid()) {
mDir = QDir::homePath();
}
}
void SavingDir::SavingDirPrivate::save()
{
mCfg.writeEntry("savingDir", mDir);
}
bool SavingDir::SavingDirPrivate::isValid()
{
QDir dir;
return (!mDir.isEmpty() && dir.exists(mDir));
}
SavingDir::SavingDir(const KConfigGroup &cfg)
: d(new SavingDirPrivate(cfg))
{
d->init();
}
SavingDir::~SavingDir()
{
delete d;
}
QString SavingDir::getDir() const
{
return d->getDir();
}
void SavingDir::setDir(const QString &dir)
{
d->setDir(dir);
}

View file

@ -1,66 +0,0 @@
/***************************************************************************
* Copyright (C) 2011-2012 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#ifndef COMIC_TYPE_H
#define COMIC_TYPE_H
class KConfigGroup;
class QString;
enum IdentifierType {
Date = 0,
Number,
String
};
/**
* Provides access (read/write) to the directory that should be used
* whenever the user is presented with a file selection dialog.
*/
class SavingDir
{
public:
/**
* @param config the config that should be used to retrieve
* the saving directory and to store it to in case of changes
*/
SavingDir(const KConfigGroup &config);
~SavingDir();
/**
* @return the directory to be displayed to the user
*/
QString getDir() const;
/**
* Set the directory that should be displayed to the user first
* when choosing a destination. Automatically writes the directory
* to the config, if one was specified in init.
* @param dir the directory to display the user first
* @see init
*/
void setDir(const QString &dir);
private:
class SavingDirPrivate;
SavingDirPrivate *d;
};
#endif

View file

@ -1,137 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Tobias Koenig <tokoe@kde.org> *
* Copyright (C) 2008-2010 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "comicmodel.h"
#include <KIcon>
ComicModel::ComicModel( const Plasma::DataEngine::Data &comics, const QStringList &usedComics, QObject *parent )
: QAbstractTableModel( parent ), mNumSelected( 0 )
{
setComics( comics, usedComics );
}
void ComicModel::setComics( const Plasma::DataEngine::Data &comics, const QStringList &usedComics )
{
beginResetModel();
mNumSelected = 0;
mComics = comics;
mState.clear();
Plasma::DataEngine::Data::const_iterator it;
Plasma::DataEngine::Data::const_iterator itEnd = mComics.constEnd();
for ( it = mComics.constBegin(); it != itEnd; ++it ) {
const bool isChecked = usedComics.contains( it.key() );
mState[ it.key() ] = ( isChecked ? Qt::Checked : Qt::Unchecked );
if ( isChecked ) {
++mNumSelected;
}
}
endResetModel();
}
int ComicModel::rowCount( const QModelIndex &index ) const
{
if ( !index.isValid() ) {
return mComics.count();
}
return 0;
}
int ComicModel::columnCount( const QModelIndex &index ) const
{
Q_UNUSED( index )
return 2;
}
QVariant ComicModel::data( const QModelIndex &index, int role ) const
{
if ( !index.isValid() || index.row() >= mComics.keys().count() ) {
return QVariant();
}
const QString data = mComics.keys()[ index.row() ];
if ( index.column() == 0 ) {
if ( role == Qt::CheckStateRole ) {
return mState[ data ];
}
} else if ( index.column() == 1 ) {
switch( role ) {
case Qt::DisplayRole:
return mComics[ data ].toStringList()[ 0 ];
case Qt::DecorationRole:
return KIcon( mComics[ data ].toStringList()[ 1 ] );
case Qt::UserRole:
return data;
}
}
return QVariant();
}
Qt::ItemFlags ComicModel::flags( const QModelIndex &index ) const
{
if ( index.isValid() && ( index.column() == 0 ) ) {
return QAbstractItemModel::flags( index ) | Qt::ItemIsUserCheckable;
}
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
bool ComicModel::setData( const QModelIndex &index, const QVariant &value, int role )
{
if ( index.isValid() && ( role == Qt::CheckStateRole ) ) {
Qt::CheckState oldState = mState[ mComics.keys()[ index.row() ] ];
Qt::CheckState newState = static_cast< Qt::CheckState >( value.toInt() );
mState[ mComics.keys()[ index.row() ] ] = newState;
if ( newState != oldState ) {
if ( newState == Qt::Checked ) {
++mNumSelected;
} else if ( newState == Qt::Unchecked ) {
--mNumSelected;
}
}
emit dataChanged( index, index );
return true;
}
return false;
}
int ComicModel::numSelected() const
{
return mNumSelected;
}
QStringList ComicModel::selected() const
{
QStringList list;
QHash< QString, Qt::CheckState >::const_iterator it;
QHash< QString, Qt::CheckState >::const_iterator itEnd = mState.constEnd();
for ( it = mState.constBegin(); it != itEnd; ++it ) {
if ( it.value() == Qt::Checked ) {
list << it.key();
}
}
return list;
}

View file

@ -1,50 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Tobias Koenig <tokoe@kde.org> *
* Copyright (C) 2008-2010 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#ifndef COMICMODEL_H
#define COMICMODEL_H
#include <QtCore/qabstractitemmodel.h>
#include <Plasma/DataEngine>
class ComicModel : public QAbstractTableModel
{
public:
ComicModel( const Plasma::DataEngine::Data &comics, const QStringList &usedComics, QObject *parent = 0 );
void setComics( const Plasma::DataEngine::Data &comics, const QStringList &usedComics );
int rowCount( const QModelIndex &index = QModelIndex() ) const;
int columnCount( const QModelIndex &index = QModelIndex() ) const;
QVariant data( const QModelIndex &index, int role = Qt::CheckStateRole ) const;
Qt::ItemFlags flags( const QModelIndex &index ) const;
bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole );
int numSelected() const;
QStringList selected() const;
private:
Plasma::DataEngine::Data mComics;
QHash<QString, Qt::CheckState> mState;
int mNumSelected;
};
#endif

View file

@ -1,62 +0,0 @@
/***************************************************************************
* Copyright (C) 2008-2012 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "comicsaver.h"
#include "comicdata.h"
#include "comicinfo.h"
#include <KFileDialog>
#include <KIO/NetAccess>
#include <KTemporaryFile>
ComicSaver::ComicSaver(SavingDir *savingDir)
: mSavingDir(savingDir)
{
}
bool ComicSaver::save(const ComicData &comic)
{
KTemporaryFile tempFile;
if (!tempFile.open()) {
return false;
}
// save image to temporary file
comic.image().save(tempFile.fileName(), "PNG");
KUrl srcUrl( tempFile.fileName() );
const QString title = comic.title();
const QString name = title + " - " + comic.current() + ".png";
KUrl destUrl = KUrl(mSavingDir->getDir());
destUrl.addPath( name );
destUrl = KFileDialog::getSaveUrl( destUrl, "*.png" );
if ( !destUrl.isValid() ) {
return false;
}
mSavingDir->setDir(destUrl.directory());
KIO::NetAccess::file_copy( srcUrl, destUrl );
return true;
}

View file

@ -1,49 +0,0 @@
/***************************************************************************
* Copyright (C) 2008-2012 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#ifndef COMIC_SAVER_H
#define COMIC_SAVER_H
class ComicData;
class SavingDir;
/**
* ComicSaver takes care of saving a comic strip to a user chosen
* destination.
* Further if available Nepomuk is used to store the title, author
* etc.
*/
class ComicSaver
{
public:
ComicSaver(SavingDir *savingDir);
/**
* Asks the user for a destination to save the specified
* comic to. If possible writes it to that destination.
* @param comic the comic to save
* @return true if saving worked, false if there was a problem
*/
bool save(const ComicData &comic);
private:
SavingDir *mSavingDir;
};
#endif

View file

@ -1,224 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Tobias Koenig <tokoe@kde.org> *
* Copyright (C) 2008-2010 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "configwidget.h"
#include "comicmodel.h"
#include <QtCore/QTimer>
#include <QtGui/QSortFilterProxyModel>
#include <KConfigDialog>
ComicUpdater::ComicUpdater( QObject *parent )
: QObject( parent ),
mUpdateIntervall( 3 ),
m_updateTimer( 0 )
{
}
ComicUpdater::~ComicUpdater()
{
}
void ComicUpdater::init(const KConfigGroup &group)
{
mGroup = group;
}
void ComicUpdater::load()
{
//check when the last update happened and update if necessary
mUpdateIntervall = mGroup.readEntry( "updateIntervall", 3 );
}
void ComicUpdater::save()
{
mGroup.writeEntry( "updateIntervall", mUpdateIntervall );
}
void ComicUpdater::applyConfig( ConfigWidget *widget )
{
mUpdateIntervall = widget->updateIntervall();
}
ConfigWidget::ConfigWidget( Plasma::DataEngine *engine, ComicModel *model, QSortFilterProxyModel *proxy, KConfigDialog *parent )
: QWidget( parent ), mEngine( engine ), mModel( model ), mProxyModel( proxy )
{
comicSettings = new QWidget( this );
comicUi.setupUi( comicSettings );
comicUi.pushButton_GHNS->setIcon( KIcon( "get-hot-new-stuff" ) );
appearanceSettings = new QWidget();
appearanceUi.setupUi( appearanceSettings );
advancedSettings = new QWidget();
advancedUi.setupUi( advancedSettings );
connect( comicUi.pushButton_GHNS, SIGNAL(clicked()), this, SLOT(getNewStuff()) );
comicUi.listView_comic->setModel( mProxyModel );
comicUi.listView_comic->resizeColumnToContents( 0 );
// "Apply" button connections
connect(comicUi.listView_comic , SIGNAL(clicked(QModelIndex)), this , SIGNAL(enableApply()));
connect(comicUi.pushButton_GHNS , SIGNAL(clicked(bool)), this , SIGNAL(enableApply()));
connect(comicUi.checkBox_middle , SIGNAL(toggled(bool)), this , SIGNAL(enableApply()));
connect(comicUi.updateIntervall, SIGNAL(valueChanged(int)), this, SIGNAL(enableApply()));
connect(comicUi.updateIntervallComicStrips, SIGNAL(valueChanged(int)), this, SIGNAL(enableApply()));
connect(appearanceUi.checkBox_arrows, SIGNAL(toggled(bool)), this , SIGNAL(enableApply()));
connect(appearanceUi.checkBox_title, SIGNAL(toggled(bool)), this , SIGNAL(enableApply()));
connect(appearanceUi.checkBox_identifier, SIGNAL(toggled(bool)), this , SIGNAL(enableApply()));
connect(appearanceUi.checkBox_author, SIGNAL(toggled(bool)), this , SIGNAL(enableApply()));
connect(appearanceUi.checkBox_url, SIGNAL(toggled(bool)), this , SIGNAL(enableApply()));
connect(appearanceUi.kbuttongroup, SIGNAL(changed(int)), this , SIGNAL(enableApply()));
connect(advancedUi.maxComicLimit, SIGNAL(valueChanged(int)), this, SIGNAL(enableApply()));
connect(advancedUi.errorPicture, SIGNAL(toggled(bool)), this , SIGNAL(enableApply()));
mEngine->connectSource( QLatin1String( "providers" ), this );
}
ConfigWidget::~ConfigWidget()
{
mEngine->disconnectSource( QLatin1String( "providers" ), this );
}
void ConfigWidget::getNewStuff()
{
}
void ConfigWidget::dataUpdated(const QString &name, const Plasma::DataEngine::Data &data)
{
Q_UNUSED(name);
mModel->setComics( data, mModel->selected() );
comicUi.listView_comic->resizeColumnToContents( 0 );
}
void ConfigWidget::setShowComicUrl( bool show )
{
appearanceUi.checkBox_url->setChecked( show );
}
bool ConfigWidget::showComicUrl() const
{
return appearanceUi.checkBox_url->isChecked();
}
void ConfigWidget::setShowComicAuthor( bool show )
{
appearanceUi.checkBox_author->setChecked( show );
}
bool ConfigWidget::showComicAuthor() const
{
return appearanceUi.checkBox_author->isChecked();
}
void ConfigWidget::setShowComicTitle( bool show )
{
appearanceUi.checkBox_title->setChecked( show );
}
bool ConfigWidget::showComicTitle() const
{
return appearanceUi.checkBox_title->isChecked();
}
void ConfigWidget::setShowComicIdentifier( bool show )
{
appearanceUi.checkBox_identifier->setChecked( show );
}
bool ConfigWidget::showComicIdentifier() const
{
return appearanceUi.checkBox_identifier->isChecked();
}
void ConfigWidget::setShowErrorPicture( bool show )
{
advancedUi.errorPicture->setChecked( show );
}
bool ConfigWidget::showErrorPicture() const
{
return advancedUi.errorPicture->isChecked();
}
void ConfigWidget::setArrowsOnHover( bool arrows )
{
return appearanceUi.checkBox_arrows->setChecked( arrows );
}
bool ConfigWidget::arrowsOnHover() const
{
return appearanceUi.checkBox_arrows->isChecked();
}
void ConfigWidget::setMiddleClick( bool checked )
{
comicUi.checkBox_middle->setChecked( checked );
}
bool ConfigWidget::middleClick() const
{
return comicUi.checkBox_middle->isChecked();
}
void ConfigWidget::setTabView(int tabView)
{
appearanceUi.kbuttongroup->setSelected( tabView );
}
int ConfigWidget::tabView() const
{
return appearanceUi.kbuttongroup->selected();
}
int ConfigWidget::maxComicLimit() const
{
return advancedUi.maxComicLimit->value();
}
void ConfigWidget::setMaxComicLimit( int limit )
{
advancedUi.maxComicLimit->setValue( limit );
}
void ConfigWidget::setUpdateIntervall( int days )
{
comicUi.updateIntervall->setValue( days );
}
int ConfigWidget::updateIntervall() const
{
return comicUi.updateIntervall->value();
}
void ConfigWidget::setCheckNewComicStripsIntervall( int minutes )
{
comicUi.updateIntervallComicStrips->setValue( minutes );
}
int ConfigWidget::checkNewComicStripsIntervall() const
{
return comicUi.updateIntervallComicStrips->value();
}
#include "moc_configwidget.cpp"

View file

@ -1,120 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Tobias Koenig <tokoe@kde.org> *
* Copyright (C) 2008-2010 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#ifndef CONFIGWIDGET_H
#define CONFIGWIDGET_H
#include "ui_appearanceSettings.h"
#include "ui_advancedsettings.h"
#include "ui_comicSettings.h"
#include <QtGui/QWidget>
#include <QtCore/qdatetime.h>
#include <Plasma/DataEngine>
class ComicModel;
class KConfigDialog;
class QCheckBox;
class QComboBox;
class QSortFilterProxyModel;
namespace Plasma {
class DataEngine;
}
class ConfigWidget;
class ComicUpdater : public QObject
{
Q_OBJECT
public:
explicit ComicUpdater( QObject *parent = 0 );
~ComicUpdater();
void init( const KConfigGroup &group );
void load();
void save();
void applyConfig( ConfigWidget *widget );
private:
KConfigGroup mGroup;
int mUpdateIntervall;
QDateTime mLastUpdate;
QTimer *m_updateTimer;
};
class ConfigWidget : public QWidget
{
Q_OBJECT
public:
ConfigWidget( Plasma::DataEngine *engine, ComicModel *model, QSortFilterProxyModel *proxy, KConfigDialog *parent );
~ConfigWidget();
void setShowComicUrl( bool show );
bool showComicUrl() const;
void setShowComicAuthor( bool show );
bool showComicAuthor() const;
void setShowComicTitle( bool show );
bool showComicTitle() const;
void setShowComicIdentifier( bool show );
bool showComicIdentifier() const;
void setShowErrorPicture( bool show );
bool showErrorPicture() const;
void setArrowsOnHover( bool arrows );
bool arrowsOnHover() const;
void setMiddleClick( bool checked );
bool middleClick() const;
void setTabView( int tabView );
int tabView() const;
int maxComicLimit() const;
void setMaxComicLimit( int limit );
void setUpdateIntervall( int days );
int updateIntervall() const;
void setCheckNewComicStripsIntervall( int minutes );
int checkNewComicStripsIntervall() const;
QWidget *comicSettings;
QWidget *appearanceSettings;
QWidget *advancedSettings;
Q_SIGNALS:
void maxSizeClicked();
void enableApply();
public slots:
void dataUpdated( const QString &name, const Plasma::DataEngine::Data &data );
protected slots:
void getNewStuff();
private:
Ui::ComicSettings comicUi;
Ui::AppearanceSettings appearanceUi;
Ui::AdvancedSettings advancedUi;
Plasma::DataEngine *mEngine;
ComicModel *mModel;
QSortFilterProxyModel *mProxyModel;
};
#endif

View file

@ -1,75 +0,0 @@
/*
* Copyright 2012 Reza Fatahilah Shah <rshah0385@kireihana.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 1.1
import org.kde.plasma.core 0.1 as PlasmaCore
import org.kde.plasma.components 0.1 as PlasmaComponents
Item {
id: root
implicitWidth: rowButton.width + background.margins.left + background.margins.right
implicitHeight: rowButton.height + background.margins.top + background.margins.bottom
signal prevClicked
signal nextClicked
signal zoomClicked
PlasmaCore.FrameSvgItem {
id: background
anchors.fill: parent
imagePath: "widgets/toolbar"
prefix: "raised"
}
Row {
id: rowButton
x: background.margins.left
y: background.margins.top
spacing: 4
//ToolButton or Button in C++ use PushButton?
PlasmaComponents.Button {
id: prevButton
iconSource: "arrow-left"
enabled: (comicData.prev != undefined && comicData.prev.length > 0)
}
PlasmaComponents.Button {
id: zoomButton
iconSource: "zoom-original"
}
PlasmaComponents.Button {
id: nextButton
iconSource: "arrow-right"
enabled: (comicData.next != undefined && comicData.next.length > 0)
}
}
Component.onCompleted: {
prevButton.clicked.connect(root.prevClicked);
nextButton.clicked.connect(root.nextClicked);
zoomButton.clicked.connect(root.zoomClicked);
}
}

View file

@ -1,116 +0,0 @@
/*
* Copyright 2012 Reza Fatahilah Shah <rshah0385@kireihana.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 1.1
import org.kde.plasma.core 0.1 as PlasmaCore
import org.kde.plasma.components 0.1 as PlasmaComponents
import org.kde.qtextracomponents 0.1
Item {
id: root
implicitWidth: 10
implicitHeight: comicIdentifier.height
property bool showUrl: false
property bool showIdentifier: false
property variant comicData
visible: (comicIdentifier.text.length > 0 || comicUrl.text.length > 0)
PlasmaComponents.Label {
id: comicIdentifier
anchors {
left: root.left
top: root.top
bottom: root.bottom
right: comicUrl.left
leftMargin: 2
}
color: theme.textColor
visible: (showIdentifier && comicIdentifier.text.length > 0)
text: (showIdentifier && comicData.currentReadable != undefined) ? comicData.currentReadable : ""
MouseArea {
id: idLabelArea
anchors.fill: parent
hoverEnabled: true
onEntered: {
parent.color = theme.highlightColor;
}
onExited: {
parent.color = theme.textColor;
}
onClicked: {
comicApplet.goJump();
}
PlasmaCore.ToolTip {
target: idLabelArea
mainText: i18n( "Jump to Strip ..." )
}
}
}
PlasmaComponents.Label {
id:comicUrl
anchors {
top: root.top
bottom: root.bottom
right: root.right
rightMargin: 2
}
color: theme.textColor
visible: (showUrl && comicUrl.text.length > 0)
text: (showUrl && comicData.websiteHost.length > 0) ? comicData.websiteHost : ""
MouseArea {
id: idUrlLabelArea
anchors.fill: parent
hoverEnabled: true
visible: comicApplet.checkAuthorization("LaunchApp")
onEntered: {
parent.color = theme.highlightColor;
}
onExited: {
parent.color = theme.textColor;
}
onClicked: {
comicApplet.shop();
}
PlasmaCore.ToolTip {
target: idUrlLabelArea
mainText: i18n( "Visit the comic website" )
}
}
}
}

View file

@ -1,143 +0,0 @@
/*
* Copyright 2012 Reza Fatahilah Shah <rshah0385@kireihana.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 1.1
import org.kde.plasma.core 0.1 as PlasmaCore
import org.kde.plasma.components 0.1 as PlasmaComponents
import org.kde.qtextracomponents 0.1
Item {
id: root
width: 10
height: 10
property variant comicData
PlasmaComponents.ToolButton {
id: arrowLeft
anchors {
left: root.left
verticalCenter: root.verticalCenter
}
iconSource: "go-previous"
visible: (!comicApplet.arrowsOnHover && (comicData.prev !== undefined))
onClicked: {
comicApplet.updateComic(comicData.prev);
}
}
MouseArea {
id: comicImageArea
anchors {
left: arrowLeft.visible ? arrowLeft.right : root.left
right: arrowRight.visible ? arrowRight.left : root.right
leftMargin: arrowLeft.visible ? 4 : 0
rightMargin: arrowRight.visible ? 4 : 0
top: root.top
bottom: root.bottom
}
hoverEnabled: true
preventStealing: false
acceptedButtons: Qt.LeftButton | Qt.MiddleButton
onClicked: {
if (mouse.button == Qt.MiddleButton && comicApplet.middleClick) {
fullDialog.open();
}
}
PlasmaCore.ToolTip {
id: tooltip
target: comicImageArea
mainText: comicApplet.comicData.additionalText
}
ImageWidget {
id: comicImage
anchors.fill: parent
image: comicApplet.comicData.image
actualSize: comicApplet.showActualSize
isLeftToRight: comicApplet.comicData.isLeftToRight
isTopToBottom: comicApplet.comicData.isTopToBottom
}
ButtonBar {
id: buttonBar
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
bottomMargin: 10
}
visible: comicApplet.arrowsOnHover && comicImageArea.containsMouse//(comicApplet.arrowsOnHover && (comicImageArea.containsMouse || (comicImageArea.containsMouse && buttonBar.visible)) )
opacity: 0
onPrevClicked: {
comicApplet.updateComic(comicData.prev);
}
onNextClicked: {
comicApplet.updateComic(comicData.next);
}
onZoomClicked: {
fullDialog.open();
}
states: State {
name: "show"; when: (comicApplet.arrowsOnHover && comicImageArea.containsMouse)
PropertyChanges { target: buttonBar; opacity: 1; }
}
transitions: Transition {
from: ""; to: "show"; reversible: true
NumberAnimation { properties: "opacity"; duration: 250; easing.type: Easing.InOutQuad }
}
}
}
PlasmaComponents.ToolButton {
id: arrowRight
anchors {
right: root.right
verticalCenter: root.verticalCenter
}
iconSource: "go-next"
visible: (!comicApplet.arrowsOnHover && (comicData.next !== undefined))
onClicked: {
comicApplet.updateComic(comicData.next);
}
}
FullViewWidget {
id: fullDialog
image: comicApplet.comicData.image
}
}

View file

@ -1,85 +0,0 @@
/*
* Copyright 2012 Reza Fatahilah Shah <rshah0385@kireihana.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 1.1
import org.kde.plasma.core 0.1 as PlasmaCore
import org.kde.plasma.components 0.1 as PlasmaComponents
import org.kde.plasma.extras 0.1 as PlasmaExtras
import org.kde.qtextracomponents 0.1
PlasmaCore.Dialog {
id: root
property alias image: comicPicture.image
windowFlags: Qt.Popup
visible: false
function open()
{
var pos = root.popupPosition(null, Qt.AlignCenter);
root.x = pos.x;
root.y = pos.y;
root.visible = true;
root.activateWindow();
}
function close() {
root.visible = false;
}
mainItem: PlasmaExtras.ScrollArea {
id: mainScrollArea
anchors.fill: parent
width: comicPicture.nativeWidth
height: comicPicture.nativeHeight
Flickable {
id: viewContainer
anchors.fill:parent
contentWidth: comicPicture.nativeWidth
contentHeight: comicPicture.nativeHeight
//clip: true
QImageItem {
id: comicPicture
anchors.fill: parent
smooth: true
fillMode: QImageItem.PreserveAspectFit
MouseArea {
id: dialogMouseArea
anchors.fill: comicPicture
onClicked: {
root.close();
}
}
}
}
}
}

View file

@ -1,78 +0,0 @@
/*
* Copyright 2012 Reza Fatahilah Shah <rshah0385@kireihana.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 1.1
import org.kde.plasma.core 0.1 as PlasmaCore
import org.kde.plasma.components 0.1 as PlasmaComponents
import org.kde.plasma.extras 0.1 as PlasmaExtras
import org.kde.qtextracomponents 0.1
PlasmaExtras.ScrollArea {
id: root
width: comicPicture.nativeWidth
height: comicPicture.nativeHeight
property bool actualSize: false
property bool isLeftToRight: true
property bool isTopToBottom: true
property alias image: comicPicture.image
function calculateContentWidth() {
return actualSize ? (comicPicture.nativeWidth > viewContainer.width ? comicPicture.nativeWidth : viewContainer.width) : viewContainer.width;
}
function calculateContentHeight() {
return actualSize ? (comicPicture.nativeHeight > viewContainer.height ? comicPicture.nativeHeight : viewContainer.height) : viewContainer.height;
}
Flickable {
id: viewContainer
anchors.fill:parent
contentWidth: comicPictureHolder.width
contentHeight: comicPictureHolder.height
clip: true
Item {
id: comicPictureHolder
width: Math.max(comicPicture.width, viewContainer.width);
height: Math.max(comicPicture.height, viewContainer.height);
QImageItem {
id: comicPicture
anchors.centerIn: parent
width: actualSize ? comicPicture.nativeWidth : viewContainer.width
height: actualSize ? comicPicture.nativeHeight : viewContainer.height
onImageChanged: {
viewContainer.contentX = (root.isLeftToRight) ? 0 : ( viewContainer.contentWidth - viewContainer.width);
viewContainer.contentY = (root.isTopToBottom) ? 0 : ( viewContainer.contentHeight - viewContainer.height);
}
smooth: true
fillMode: QImageItem.PreserveAspectFit
}
}
}
}

View file

@ -1,228 +0,0 @@
/*
* Copyright 2012 Reza Fatahilah Shah <rshah0385@kireihana.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 1.1
import org.kde.plasma.core 0.1 as PlasmaCore
import org.kde.plasma.components 0.1 as PlasmaComponents
import org.kde.qtextracomponents 0.1
Item {
id: mainWindow
width: minimumWidth
height: minimumHeight
property int minimumWidth: theme.defaultFont.mSize.width * 35
property int minimumHeight: theme.defaultFont.mSize.height * 12
property bool showComicAuthor: comicApplet.showComicAuthor
property bool showComicTitle: comicApplet.showComicTitle
property bool showErrorPicture: comicApplet.showErrorPicture
property bool middleClick: comicApplet.middleClick
Connections {
target: comicApplet
onComicsModelChanged: {
comicTabbar.currentTab = comicTabbar.layout.children[1];
}
onTabHighlightRequest: {
for (var i = 0; i < comicTabbar.layout.children.length; ++i) {
var button = comicTabbar.layout.children[i];
if (button.key !== undefined && button.key == id) {
button.highlighted = highlight;
}
}
}
onShowNextNewStrip: {
var firstButton = undefined;
for (var i = 0; i < comicTabbar.layout.children.length; ++i) {
var button = comicTabbar.layout.children[i];
if (button.key !== undefined && button.highlighted == true) {
//key is ordered
if (button.key > comicTabbar.currentTab.key) {
comicTabbar.currentTab = button;
return;
} else if (firstButton === undefined){
firstButton = button;
}
}
}
if (firstButton !== undefined) {
comicTabbar.currentTab = firstButton;
}
}
}
PlasmaCore.Theme {
id: theme
}
PlasmaCore.Svg {
id: arrowsSvg
imagePath: "widgets/arrows"
}
PlasmaComponents.TabBar{
id: comicTabbar
anchors {
left: parent.left
right: parent.right
}
visible: (comicApplet.comicsModel.count > 1)
onCurrentTabChanged: {
console.log("onCurrentTabChanged:" + comicTabbar.currentTab.key);
comicApplet.tabChanged(comicTabbar.currentTab.key);
}
Repeater {
model: comicApplet.comicsModel
delegate: PlasmaComponents.TabButton {
id: tabButton
property string key: model.key
property bool highlighted: model.highlight
text: model.title
iconSource: model.icon
Rectangle {
id: highlightMask
anchors {
bottom: parent.bottom
left: parent.left
}
width: Math.max(theme.smallIconSize, tabButton.height)
height: Math.max(theme.smallIconSize, tabButton.height)
color: "white"
opacity: model.highlight ? 0 : 0.5
}
}
}
}
PlasmaComponents.Label {
id: topInfo
anchors {
top: comicTabbar.visible ? comicTabbar.bottom : mainWindow.top
left: mainWindow.left
right: mainWindow.right
}
visible: (topInfo.text.length > 0)
horizontalAlignment: Text.AlignHCenter
text: (showComicAuthor || showComicTitle) ? getTopInfo() : ""
function getTopInfo() {
var tempTop = "";
if ( showComicTitle ) {
tempTop = comicApplet.comicData.title;
tempTop += ( ( (comicApplet.comicData.stripTitle.length > 0) && (comicApplet.comicData.title.length > 0) ) ? " - " : "" ) + comicApplet.comicData.stripTitle;
}
if ( showComicAuthor &&
(comicApplet.comicData.author != undefined || comicApplet.comicData.author.length > 0) ) {
tempTop = ( tempTop.length > 0 ? comicApplet.comicData.author + ": " + tempTop : comicApplet.comicData.author );
}
return tempTop;
}
}
ComicCentralView {
id: centerLayout
anchors {
left: mainWindow.left
right: mainWindow.right
bottom: (bottomInfo.visible) ? bottomInfo.top : mainWindow.bottom
top: (topInfo.visible) ? topInfo.bottom : (comicTabbar.visible ? comicTabbar.bottom : mainWindow.top)
topMargin: (comicTabbar.visible) ? 3 : 0
}
comicData: comicApplet.comicData
}
ComicBottomInfo {
id:bottomInfo
anchors {
left: mainWindow.left
right: mainWindow.right
bottom: mainWindow.bottom
}
comicData: comicApplet.comicData
showUrl: comicApplet.showComicUrl
showIdentifier: comicApplet.showComicIdentifier
}
PlasmaComponents.BusyIndicator {
id: busyIndicator
anchors.centerIn: parent
running: visible
visible: false
}
states: [
State {
name: "topInfoVisible"
when: topInfo.visible && !bottomInfo.visible
AnchorChanges {
target: centerLayout
anchors.top: topInfo.bottom
}
},
State {
name: "bottomInfoVisible"
when: bottomInfo.visible && !topInfo.visible
AnchorChanges {
target: centerLayout
anchors.bottom: bottomInfo.top
}
},
State {
name: "topBottomInfoVisible"
when: bottomInfo.visible && topInfo.visible
AnchorChanges {
target: centerLayout
anchors.top: topInfo.bottom
anchors.bottom: bottomInfo.top
}
}
]
transitions:
Transition {
AnchorAnimation {
duration: 500
easing.type: Easing.InOutQuad
}
}
}

View file

@ -1,128 +0,0 @@
[Desktop Entry]
Name=Comic Strip
Name[ar]=شريط هزلي
Name[ast]=Tira de cómic
Name[bs]=stripovi
Name[ca]=Tira còmica
Name[ca@valencia]=Tira còmica
Name[cs]=Komiksový proužek
Name[csb]=Kòmiksowi sztrépk
Name[da]=Tegneseriestribe
Name[de]=Comic
Name[el]=Σειρά κόμικ
Name[en_GB]=Comic Strip
Name[es]=Tira de cómic
Name[et]=Koomiks
Name[eu]=Komiki zerrenda
Name[fi]=Sarjakuvastrippi
Name[fr]=Bande dessinée
Name[ga]=Stiallchartún
Name[gl]=Banda deseñada
Name[he]=קומיקס
Name[hr]=Strip
Name[hu]=Képregény
Name[is]=Myndasögur
Name[it]=Striscia di fumetti
Name[ja]=
Name[kk]=Комикс
Name[km]=
Name[ko]=
Name[ku]=Pirtûka Qerfî
Name[lv]=Komikss
Name[mr]=ि
Name[nb]=Comic Strip
Name[nds]=Comic
Name[nl]=Stripboek
Name[nn]=Teikneserie
Name[pa]=
Name[pl]=Komiks
Name[pt]=Banda Desenhada
Name[pt_BR]=Tirinha
Name[ro]=Benzi desenate
Name[ru]=Комиксы
Name[sk]=Komiks
Name[sl]=Smešen strip
Name[sr]=стрипови
Name[sr@ijekavian]=стрипови
Name[sr@ijekavianlatin]=stripovi
Name[sr@latin]=stripovi
Name[sv]=Tecknad serie
Name[th]=
Name[tr]=Çizgi Roman
Name[uk]=Комічна стрічка
Name[wa]=Binde d' imådje
Name[x-test]=xxComic Stripxx
Name[zh_CN]=
Name[zh_TW]=
Comment=View comic strips from the Internet
Comment[ar]=اعرض شرائط هزلية من الإنترنت
Comment[ast]=Amuesa tires de cómic d'Internet
Comment[bs]=Pogledajte stripove sa Interneta
Comment[ca]=Mostra una tira còmica des d'Internet
Comment[ca@valencia]=Mostra una tira còmica des d'Internet
Comment[cs]=Ukáže komiksový proužek z internetu
Comment[da]=Se tegneseriestriber fra internettet.
Comment[de]=Comics aus dem Internet anzeigen
Comment[el]=Εμφάνιση σειρών κόμικ από το διαδίκτυο
Comment[en_GB]=View comic strips from the Internet
Comment[es]=Muestra tiras de cómic de Internet
Comment[et]=Internetist hangitud koomiksite näitamine
Comment[eu]=Interneteko komiki zerrendak ikusi
Comment[fi]=Katso sarjakuvia internetistä
Comment[fr]=Affiche une bande dessinée provenant d'Internet
Comment[ga]=Taispeáin stiallchartún ón Idirlíon
Comment[gl]=Mostra bandas deseñadas de internet
Comment[he]=מציג קומיקסים נבחרים מהאינטרנט
Comment[hr]=Prikaži stripove na Internetu
Comment[hu]=Képregények megjelenítése az internetről
Comment[is]=Skoða myndasögur af netinu
Comment[it]=Vedi una striscia di fumetti da Internet.
Comment[ja]=
Comment[kk]=Интернеттен комиксті қарау
Comment[km]=
Comment[ko]=
Comment[ku]=Ji Torê pirtûkên qerfî bibîne
Comment[lv]=Rāda komiksus no interneta
Comment[mr]= ि
Comment[nb]=Vis tegneserier fra Internett
Comment[nds]=Comics ut dat Internet ankieken
Comment[nl]=Toont stripboeken van het internet
Comment[nn]=Vis teikneseriar frå Internett
Comment[pa]=
Comment[pl]=Przeglądanie komiksów z Internetu
Comment[pt]=Mostra bandas desenhadas da Internet
Comment[pt_BR]=Exibe uma tirinha da Internet
Comment[ro]=Afișează benzi desenate din Internet
Comment[ru]=Просмотр комиксов из Интернета
Comment[sk]=Zobrazenie komiksov z internetu
Comment[sl]=Oglejte si smešne stripe z interneta
Comment[sr]=Погледајте стрипове са Интернета
Comment[sr@ijekavian]=Погледајте стрипове са Интернета
Comment[sr@ijekavianlatin]=Pogledajte stripove sa Interneta
Comment[sr@latin]=Pogledajte stripove sa Interneta
Comment[sv]=Visa tecknade serier från Internet
Comment[th]=
Comment[tr]=İnternet'ten çizgi roman karikatürleri göster
Comment[uk]=Показує стрічку з жартами з Інтернету
Comment[wa]=Vey ene binde d' imådje di l' Etrernet
Comment[x-test]=xxView comic strips from the Internetxx
Comment[zh_CN]=
Comment[zh_TW]=
Icon=face-smile-big
Type=Service
X-KDE-ServiceTypes=Plasma/Applet
X-Plasma-API=declarativeappletscript
X-Plasma-MainScript=ui/main.qml
X-Plasma-DefaultSize=600,250
X-KDE-PluginInfo-Author=Reza Fatahilah Shah
X-KDE-PluginInfo-Email=rshah0385@kireihana.com
X-KDE-PluginInfo-Name=comic
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=http://plasma.kde.org/
X-KDE-PluginInfo-Category=Graphics
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-Plasma-Requires-FileDialog=Optional
X-Plasma-Requires-LaunchApp=Optional

View file

@ -1,126 +0,0 @@
[Desktop Entry]
Name=Comic Strip
Name[ar]=شريط هزلي
Name[ast]=Tira de cómic
Name[bs]=stripovi
Name[ca]=Tira còmica
Name[ca@valencia]=Tira còmica
Name[cs]=Komiksový proužek
Name[csb]=Kòmiksowi sztrépk
Name[da]=Tegneseriestribe
Name[de]=Comic
Name[el]=Σειρά κόμικ
Name[en_GB]=Comic Strip
Name[es]=Tira de cómic
Name[et]=Koomiks
Name[eu]=Komiki zerrenda
Name[fi]=Sarjakuvastrippi
Name[fr]=Bande dessinée
Name[ga]=Stiallchartún
Name[gl]=Banda deseñada
Name[he]=קומיקס
Name[hr]=Strip
Name[hu]=Képregény
Name[is]=Myndasögur
Name[it]=Striscia di fumetti
Name[ja]=
Name[kk]=Комикс
Name[km]=
Name[ko]=
Name[ku]=Pirtûka Qerfî
Name[lv]=Komikss
Name[mr]=ि
Name[nb]=Comic Strip
Name[nds]=Comic
Name[nl]=Stripboek
Name[nn]=Teikneserie
Name[pa]=
Name[pl]=Komiks
Name[pt]=Banda Desenhada
Name[pt_BR]=Tirinha
Name[ro]=Benzi desenate
Name[ru]=Комиксы
Name[sk]=Komiks
Name[sl]=Smešen strip
Name[sr]=стрипови
Name[sr@ijekavian]=стрипови
Name[sr@ijekavianlatin]=stripovi
Name[sr@latin]=stripovi
Name[sv]=Tecknad serie
Name[th]=
Name[tr]=Çizgi Roman
Name[uk]=Комічна стрічка
Name[wa]=Binde d' imådje
Name[x-test]=xxComic Stripxx
Name[zh_CN]=
Name[zh_TW]=
Comment=View comic strips from the Internet
Comment[ar]=اعرض شرائط هزلية من الإنترنت
Comment[ast]=Amuesa tires de cómic d'Internet
Comment[bs]=Pogledajte stripove sa Interneta
Comment[ca]=Mostra una tira còmica des d'Internet
Comment[ca@valencia]=Mostra una tira còmica des d'Internet
Comment[cs]=Ukáže komiksový proužek z internetu
Comment[da]=Se tegneseriestriber fra internettet.
Comment[de]=Comics aus dem Internet anzeigen
Comment[el]=Εμφάνιση σειρών κόμικ από το διαδίκτυο
Comment[en_GB]=View comic strips from the Internet
Comment[es]=Muestra tiras de cómic de Internet
Comment[et]=Internetist hangitud koomiksite näitamine
Comment[eu]=Interneteko komiki zerrendak ikusi
Comment[fi]=Katso sarjakuvia internetistä
Comment[fr]=Affiche une bande dessinée provenant d'Internet
Comment[ga]=Taispeáin stiallchartún ón Idirlíon
Comment[gl]=Mostra bandas deseñadas de internet
Comment[he]=מציג קומיקסים נבחרים מהאינטרנט
Comment[hr]=Prikaži stripove na Internetu
Comment[hu]=Képregények megjelenítése az internetről
Comment[is]=Skoða myndasögur af netinu
Comment[it]=Vedi una striscia di fumetti da Internet.
Comment[ja]=
Comment[kk]=Интернеттен комиксті қарау
Comment[km]=
Comment[ko]=
Comment[ku]=Ji Torê pirtûkên qerfî bibîne
Comment[lv]=Rāda komiksus no interneta
Comment[mr]= ि
Comment[nb]=Vis tegneserier fra Internett
Comment[nds]=Comics ut dat Internet ankieken
Comment[nl]=Toont stripboeken van het internet
Comment[nn]=Vis teikneseriar frå Internett
Comment[pa]=
Comment[pl]=Przeglądanie komiksów z Internetu
Comment[pt]=Mostra bandas desenhadas da Internet
Comment[pt_BR]=Exibe uma tirinha da Internet
Comment[ro]=Afișează benzi desenate din Internet
Comment[ru]=Просмотр комиксов из Интернета
Comment[sk]=Zobrazenie komiksov z internetu
Comment[sl]=Oglejte si smešne stripe z interneta
Comment[sr]=Погледајте стрипове са Интернета
Comment[sr@ijekavian]=Погледајте стрипове са Интернета
Comment[sr@ijekavianlatin]=Pogledajte stripove sa Interneta
Comment[sr@latin]=Pogledajte stripove sa Interneta
Comment[sv]=Visa tecknade serier från Internet
Comment[th]=
Comment[tr]=İnternet'ten çizgi roman karikatürleri göster
Comment[uk]=Показує стрічку з жартами з Інтернету
Comment[wa]=Vey ene binde d' imådje di l' Etrernet
Comment[x-test]=xxView comic strips from the Internetxx
Comment[zh_CN]=
Comment[zh_TW]=
Icon=face-smile-big
Type=Service
X-KDE-ServiceTypes=Plasma/Applet
X-KDE-Library=plasma_applet_comic
X-KDE-PluginInfo-Author=Tobias Koenig
X-KDE-PluginInfo-Email=tokoe@kde.org
X-KDE-PluginInfo-Name=comic
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=http://plasma.kde.org/
X-KDE-PluginInfo-Category=Graphics
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-Plasma-Requires-FileDialog=Optional
X-Plasma-Requires-LaunchApp=Optional

View file

@ -1,179 +0,0 @@
/***************************************************************************
* Copyright (C) 2012 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "stripselector.h"
#include "stripselector_p.h"
#include "comicdata.h"
#include <KDatePicker>
#include <KDialog>
#include <KInputDialog>
#include <KNumInput>
#include <QtCore/QScopedPointer>
#include <QtCore/QTimer>
#include <QtGui/QLabel>
#include <QtGui/QVBoxLayout>
//NOTE based on GotoPageDialog KDE/kdegraphics/okular/part.cpp
//BEGIN choose a strip dialog
class ChooseStripNumDialog : public KDialog
{
public:
ChooseStripNumDialog(QWidget *parent, int current, int min, int max)
: KDialog( parent )
{
setCaption(i18n("Go to Strip"));
setButtons(Ok | Cancel);
setDefaultButton(Ok);
QWidget *widget = new QWidget(this);
setMainWidget(widget);
QVBoxLayout *topLayout = new QVBoxLayout(widget);
topLayout->setMargin(0);
topLayout->setSpacing(spacingHint());
numInput = new KIntNumInput(current, widget);
numInput->setRange(min, max);
numInput->setEditFocus(true);
numInput->setSliderEnabled(true);
QLabel *label = new QLabel(i18n("&Strip Number:"), widget);
label->setBuddy(numInput);
topLayout->addWidget(label);
topLayout->addWidget(numInput) ;
// A little bit extra space
topLayout->addSpacing(spacingHint());
topLayout->addStretch(10);
numInput->setFocus();
}
int getStripNumber() const
{
return numInput->value();
}
protected:
KIntNumInput *numInput;
};
//END choose a strip dialog
StripSelector::StripSelector(QObject *parent)
: QObject(parent)
{
}
StripSelector::~StripSelector()
{
}
StripSelector *StripSelectorFactory::create(IdentifierType type)
{
switch (type) {
case Number:
return new NumberStripSelector();
case Date:
return new DateStripSelector();
case String:
return new StringStripSelector();
}
return 0;
}
StringStripSelector::StringStripSelector(QObject *parent)
: StripSelector(parent)
{
}
StringStripSelector::~StringStripSelector()
{
}
void StringStripSelector::select(const ComicData &currentStrip)
{
bool ok;
const QString strip = KInputDialog::getText(i18n("Go to Strip"), i18n("Strip identifier:"),
currentStrip.current(), &ok);
if (ok) {
emit stripChosen(strip);
}
deleteLater();
}
NumberStripSelector::NumberStripSelector(QObject *parent)
: StripSelector(parent)
{
}
NumberStripSelector::~NumberStripSelector()
{
}
void NumberStripSelector::select(const ComicData &currentStrip)
{
QScopedPointer<ChooseStripNumDialog> pageDialog(new ChooseStripNumDialog(0, currentStrip.current().toInt(),
currentStrip.firstStripNum(), currentStrip.maxStripNum()));
if (pageDialog->exec() == QDialog::Accepted) {
emit stripChosen(QString::number(pageDialog->getStripNumber()));
}
deleteLater();
}
DateStripSelector::DateStripSelector(QObject *parent)
: StripSelector(parent)
{
}
DateStripSelector::~DateStripSelector()
{
}
void DateStripSelector::select(const ComicData &currentStrip)
{
mFirstIdentifierSuffix = currentStrip.first();
KDatePicker *calendar = new KDatePicker;
calendar->setAttribute(Qt::WA_DeleteOnClose);//to have destroyed emitted upon closing
calendar->setMinimumSize(calendar->sizeHint());
calendar->setDate(QDate::fromString(currentStrip.current(), "yyyy-MM-dd"));
connect(calendar, SIGNAL(dateSelected(QDate)), this, SLOT(slotChosenDay(QDate)));
connect(calendar, SIGNAL(dateEntered(QDate)), this, SLOT(slotChosenDay(QDate)));
// only delete this if the dialog got closed
connect(calendar, SIGNAL(destroyed(QObject*)), this, SLOT(deleteLater()));
calendar->show();
}
void DateStripSelector::slotChosenDay(const QDate &date)
{
if (date <= QDate::currentDate()) {
QDate temp = QDate::fromString(mFirstIdentifierSuffix, "yyyy-MM-dd");
// only update if date >= first strip date, or if there is no first
// strip date
if (temp.isValid() || date >= temp) {
emit stripChosen(date.toString("yyyy-MM-dd"));
}
}
}
#include "moc_stripselector.cpp"
#include "moc_stripselector_p.cpp"

View file

@ -1,72 +0,0 @@
/***************************************************************************
* Copyright (C) 2012 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#ifndef STRIP_SELECTOR_H
#define STRIP_SELECTOR_H
#include <QtCore/QObject>
#include "comicinfo.h"
class ComicData;
class QDate;
/**
* Enables users to visually select a strip they want to navigate to.
* Subclasses implement different Selectors for the different comic
* types.
* @note use the StripSelectorFactory to retrieve an appropriate
* StripSelector
*/
class StripSelector : public QObject
{
Q_OBJECT
public:
virtual ~StripSelector();
/**
* Select a strip depending on the subclass
* @param currentStrip the currently active strip
* @note StripSelector takes care to delete itself
*/
virtual void select(const ComicData &currentStrip) = 0;
signals:
/**
* @param strip the selected strip, can be empty
*
*/
void stripChosen(const QString &strip);
protected:
explicit StripSelector(QObject *parent = 0);
};
/**
* Class to retrrieve the correct StripSelector depending on the
* specified IdentifierType
*/
class StripSelectorFactory
{
public:
static StripSelector *create(IdentifierType type);
};
#endif

View file

@ -1,62 +0,0 @@
/***************************************************************************
* Copyright (C) 2012 Matthias Fuchs <mat69@gmx.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#ifndef STRIP_SELECTOR_P_H
#define STRIP_SELECTOR_P_H
#include "stripselector.h"
#include <QtCore/QString>
class StringStripSelector : public StripSelector
{
public:
explicit StringStripSelector(QObject *parent = 0);
virtual ~StringStripSelector();
virtual void select(const ComicData &currentStrip);
};
class NumberStripSelector : public StripSelector
{
public:
explicit NumberStripSelector(QObject *parent = 0);
virtual ~NumberStripSelector();
virtual void select(const ComicData &currentStrip);
};
class DateStripSelector : public StripSelector
{
Q_OBJECT
public:
explicit DateStripSelector(QObject *parent = 0);
virtual ~DateStripSelector();
virtual void select(const ComicData &currentStrip);
private slots:
void slotChosenDay(const QDate &date);
private:
QString mFirstIdentifierSuffix;
};
#endif

View file

@ -1,12 +1,10 @@
add_subdirectory(comic)
if (QCA2_FOUND AND QJSON_FOUND AND QTOAUTH_FOUND)
add_subdirectory(microblog)
endif(QCA2_FOUND AND QJSON_FOUND AND QTOAUTH_FOUND)
endif()
if(LIBATTICA_FOUND)
add_subdirectory(ocs)
endif(LIBATTICA_FOUND)
endif()
add_subdirectory(potd)
add_subdirectory(rememberthemilk)

View file

@ -1,49 +0,0 @@
project(plasma_comic_dataengine)
set(comic_engine_SRCS
cachedprovider.cpp
comic.cpp
)
kde4_add_plugin(plasma_engine_comic ${comic_engine_SRCS})
target_link_libraries(plasma_engine_comic plasmacomicprovidercore ${KDE4_KDEUI_LIBS} ${KDE4_SOLID_LIBS} ${KDE4_PLASMA_LIBS})
install(TARGETS plasma_engine_comic DESTINATION ${PLUGIN_INSTALL_DIR})
install(FILES plasma-dataengine-comic.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
########### plugin core library ############
set(comic_provider_core_SRCS
comicprovider.cpp
)
add_library( plasmacomicprovidercore SHARED ${comic_provider_core_SRCS} )
target_link_libraries( plasmacomicprovidercore PRIVATE ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${KDE4_KROSSCORE_LIBS} )
target_link_libraries( plasmacomicprovidercore PUBLIC ${KDE4_KDECORE_LIBS})
set_target_properties(
plasmacomicprovidercore PROPERTIES VERSION 1.0.0 SOVERSION 1
)
install( TARGETS plasmacomicprovidercore ${INSTALL_TARGETS_DEFAULT_ARGS} )
install( FILES plasma_comicprovider.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR} )
########### kross ###############
set( plasma_comic_krossprovider_SRCS
comicproviderkross.cpp
comicproviderwrapper.cpp
comic_package.cpp
)
kde4_add_plugin( plasma_comic_krossprovider ${plasma_comic_krossprovider_SRCS} )
target_link_libraries( plasma_comic_krossprovider plasmacomicprovidercore ${KDE4_KDECORE_LIBS} ${QT_QTGUI_LIBRARY} ${KDE4_KIO_LIBS} ${KDE4_KROSSCORE_LIBS} ${KDE4_PLASMA_LIBS} )
install( TARGETS plasma_comic_krossprovider DESTINATION ${PLUGIN_INSTALL_DIR} )
set(comicpackage_SRCS
comic_package.cpp
comic_package_plugin.cpp
)
kde4_add_plugin( plasma_packagestructure_comic ${comicpackage_SRCS} )
target_link_libraries( plasma_packagestructure_comic ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} )
install( TARGETS plasma_packagestructure_comic DESTINATION ${PLUGIN_INSTALL_DIR} )
install( FILES plasma-packagestructure-comic.desktop DESTINATION ${SERVICES_INSTALL_DIR} )

View file

@ -1,2 +0,0 @@
#! /usr/bin/env bash
$XGETTEXT *.cpp -o $podir/plasma_packagestructure_comic.pot

View file

@ -1,245 +0,0 @@
/*
* Copyright (C) 2007 Tobias Koenig <tokoe@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "cachedprovider.h"
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QSettings>
#include <QtCore/QTimer>
#include <QtGui/QImage>
#include <KDebug>
#include <kstandarddirs.h>
#include <KUrl>
const int CachedProvider::CACHE_DEFAULT = 20;
static QString identifierToPath( const QString &identifier )
{
const QString dataDir = KStandardDirs::locateLocal( "data", QLatin1String( "plasma_engine_comic/" ));
return QString( dataDir + QString::fromAscii( QUrl::toPercentEncoding( identifier ) ) );
}
CachedProvider::CachedProvider( QObject *parent, const QVariantList &args )
: ComicProvider( parent, args )
{
QTimer::singleShot( 0, this, SLOT(triggerFinished()) );
}
CachedProvider::~CachedProvider()
{
}
ComicProvider::IdentifierType CachedProvider::identifierType() const
{
return StringIdentifier;
}
QImage CachedProvider::image() const
{
if ( !QFile::exists( identifierToPath( requestedString() ) ) )
return QImage();
QImage img;
img.load( identifierToPath( requestedString() ), "PNG" );
return img;
}
QString CachedProvider::identifier() const
{
return requestedString();
}
QString CachedProvider::nextIdentifier() const
{
QSettings settings( identifierToPath( requestedString() ) + QLatin1String( ".conf" ), QSettings::IniFormat );
return settings.value( QLatin1String( "nextIdentifier" ), QString() ).toString();
}
QString CachedProvider::previousIdentifier() const
{
QSettings settings( identifierToPath( requestedString() ) + QLatin1String( ".conf" ), QSettings::IniFormat );
return settings.value( QLatin1String( "previousIdentifier" ), QString() ).toString();
}
QString CachedProvider::firstStripIdentifier() const
{
QSettings settings( identifierToPath( requestedComicName() ) + QLatin1String( ".conf" ), QSettings::IniFormat );
return settings.value( QLatin1String( "firstStripIdentifier" ), QString() ).toString();
}
QString CachedProvider::lastCachedStripIdentifier() const
{
QSettings settings( identifierToPath( requestedComicName() ) + QLatin1String( ".conf" ), QSettings::IniFormat );
return settings.value( QLatin1String( "lastCachedStripIdentifier" ), QString() ).toString();
}
QString CachedProvider::comicAuthor() const
{
QSettings settings( identifierToPath( requestedString() ) + QLatin1String( ".conf" ), QSettings::IniFormat );
return settings.value( QLatin1String( "comicAuthor" ), QString() ).toString();
}
QString CachedProvider::stripTitle() const
{
QSettings settings( identifierToPath ( requestedString() ) + QLatin1String( ".conf" ), QSettings::IniFormat );
return settings.value( QLatin1String( "stripTitle" ), QString() ).toString();
}
QString CachedProvider::additionalText() const
{
QSettings settings( identifierToPath ( requestedString() ) + QLatin1String( ".conf" ), QSettings::IniFormat );
return settings.value( QLatin1String( "additionalText" ), QString() ).toString();
}
QString CachedProvider::suffixType() const
{
QSettings settings( identifierToPath ( requestedComicName() ) + QLatin1String( ".conf" ), QSettings::IniFormat );
return settings.value( QLatin1String( "suffixType" ), QString() ).toString();
}
QString CachedProvider::name() const
{
QSettings settings( identifierToPath ( requestedComicName() ) + QLatin1String( ".conf" ), QSettings::IniFormat );
return settings.value( QLatin1String( "title" ), QString() ).toString();
}
void CachedProvider::triggerFinished()
{
emit finished( this );
}
bool CachedProvider::isCached( const QString &identifier )
{
return QFile::exists( identifierToPath( identifier ) );
}
bool CachedProvider::storeInCache( const QString &identifier, const QImage &comic, const Settings &info )
{
const QString path = identifierToPath( identifier );
int index = identifier.indexOf( QLatin1Char( ':' ) );
const QString comicName = identifier.mid( 0, index );
const QString pathMain = identifierToPath( comicName );
const QString dirPath = KStandardDirs::locateLocal( "data", QLatin1String( "plasma_engine_comic/" ) );
if ( !info.isEmpty() ) {
QSettings settings( path + QLatin1String( ".conf" ), QSettings::IniFormat );
QSettings settingsMain( pathMain + QLatin1String( ".conf" ), QSettings::IniFormat );
for ( Settings::const_iterator i = info.constBegin(); i != info.constEnd(); ++i ) {
if ( ( i.key() == QLatin1String( "firstStripIdentifier" ) ) || ( i.key() == QLatin1String( "title" ) ) ||
( i.key() == QLatin1String( "lastCachedStripIdentifier" ) ) || ( i.key() == QLatin1String( "suffixType" ) ) ||
( i.key() == QLatin1String( "shopUrl" ) ) || ( i.key() == QLatin1String( "isLeftToRight" ) ) ||
( i.key() == QLatin1String( "isTopToBottom" ) ) ) {
settingsMain.setValue( i.key(), i.value() );
} else {
settings.setValue( i.key(), i.value() );
}
}
QStringList comics;
if ( settingsMain.contains( QLatin1String( "comics" ) ) ) {
comics = settingsMain.value( QLatin1String( "comics" ), QStringList() ).toStringList();
} else {
//existing strips haven't been stored in the conf-file yet, do that now, oldest first, newest last
QDir dir( dirPath );
comics = dir.entryList( QStringList() << QUrl::toPercentEncoding( comicName + ':' ) + '*', QDir::Files, QDir::Time | QDir::Reversed );
QStringList::iterator it = comics.begin();
while ( it != comics.end() ) {
//only count images, not the conf files
if ( (*it).endsWith( QLatin1String( ".conf" ) ) ) {
it = comics.erase(it);
} else {
++it;
}
}
}
comics.append( QUrl::toPercentEncoding( identifier ) );
const int limit = CachedProvider::maxComicLimit();
//limit is on
if ( limit > 0 ) {
kDebug() << QLatin1String( "MaxComicLimit on." );
int comicsToRemove = comics.count() - limit;
QStringList::iterator it = comics.begin();
while ( comicsToRemove > 0 && it != comics.end() ) {
kDebug() << QLatin1String( "Remove file" ) << (dirPath + (*it));
QFile::remove( dirPath + (*it) );
QFile::remove( dirPath + (*it) + QLatin1String( ".conf" ) );
it = comics.erase(it);
-- comicsToRemove;
}
}
settingsMain.setValue( QLatin1String( "comics" ), comics );
}
return comic.save( path, "PNG" );
}
KUrl CachedProvider::websiteUrl() const
{
QSettings settings( identifierToPath( requestedString() ) + QLatin1String( ".conf" ), QSettings::IniFormat );
return KUrl( settings.value( QLatin1String( "websiteUrl" ), QString() ).toString() );
}
KUrl CachedProvider::imageUrl() const
{
QSettings settings( identifierToPath( requestedString() ) + QLatin1String( ".conf" ), QSettings::IniFormat );
return KUrl( settings.value( QLatin1String( "imageUrl" ), QString() ).toString() );
}
KUrl CachedProvider::shopUrl() const
{
QSettings settings( identifierToPath( requestedComicName() ) + QLatin1String( ".conf" ), QSettings::IniFormat );
return KUrl( settings.value( QLatin1String( "shopUrl" ), QString() ).toString() );
}
bool CachedProvider::isLeftToRight() const
{
QSettings settings( identifierToPath( requestedComicName() ) + QLatin1String( ".conf" ), QSettings::IniFormat );
return settings.value( QLatin1String( "isLeftToRight" ), true ).toBool();
}
bool CachedProvider::isTopToBottom() const
{
QSettings settings( identifierToPath( requestedComicName() ) + QLatin1String( ".conf" ), QSettings::IniFormat );
return settings.value( QLatin1String( "isTopToBottom" ), true ).toBool();
}
int CachedProvider::maxComicLimit()
{
QSettings settings( identifierToPath( QLatin1String( "comic_settings.conf" ) ), QSettings::IniFormat );
return qMax( settings.value( QLatin1String( "maxComics" ), CACHE_DEFAULT ).toInt(), 0 );//old value was -1, thus use qMax
}
void CachedProvider::setMaxComicLimit( int limit )
{
if ( limit < 0 ) {
kDebug() << "Wrong limit, setting to default.";
limit = CACHE_DEFAULT;
}
QSettings settings( identifierToPath( QLatin1String( "comic_settings.conf" ) ), QSettings::IniFormat );
settings.setValue( QLatin1String( "maxComics" ), limit );
}
#include "moc_cachedprovider.cpp"

View file

@ -1,168 +0,0 @@
/*
* Copyright (C) 2007 Tobias Koenig <tokoe@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef CACHEDPROVIDER_H
#define CACHEDPROVIDER_H
#include "comicprovider.h"
#include <QtCore/QHash>
/**
* This class provides comics from the local cache.
*/
class CachedProvider : public ComicProvider
{
Q_OBJECT
public:
/**
* Creates a new cached provider.
*
* @param identifier The identifier of the cached comic.
* @param parent The parent object.
*/
explicit CachedProvider( QObject *parent, const QVariantList &args = QVariantList() );
/**
* Destroys the cached provider.
*/
~CachedProvider();
/**
* Returns the identifier type.
*
* Is always StringIdentifier here.
*/
IdentifierType identifierType() const;
/**
* Returns the type of identifier that is used by this
* comic provider.
*/
virtual QString suffixType() const;
/**
* Returns the requested image.
*
* Note: This method returns only a valid image after the
* finished() signal has been emitted.
*/
virtual QImage image() const;
/**
* Returns the identifier of the comic request (name + date).
*/
virtual QString identifier() const;
/**
* Returns the identifier suffix of the next comic.
*/
virtual QString nextIdentifier() const;
/**
* Returns the identifier suffix of the previous comic.
*/
virtual QString previousIdentifier() const;
/**
* Returns the identifier of the first strip.
*/
virtual QString firstStripIdentifier() const;
/**
* Returns the identifier of the last cached strip.
*/
QString lastCachedStripIdentifier() const;
/**
* Returns the title of the strip.
*/
virtual QString stripTitle() const;
/**
* Returns the author of the comic.
*/
virtual QString comicAuthor() const;
/**
* Returns additionalText of the comic.
*/
virtual QString additionalText() const;
/**
* Returns the name for the comic
*/
virtual QString name() const;
/**
* Returns wether the comic is leftToRight or not
*/
virtual bool isLeftToRight() const;
/**
* Returns wether the comic is topToBottom or not
*/
virtual bool isTopToBottom() const;
/**
* Returns whether a comic with the given @p identifier is cached.
*/
static bool isCached( const QString &identifier );
/**
* Map of keys and values to store in the config file for an individual identifier
*/
typedef QHash<QString, QString> Settings;
/**
* Stores the given @p comic with the given @p identifier in the cache.
*/
static bool storeInCache( const QString &identifier, const QImage &comic, const Settings &info = Settings() );
/**
* Returns the website of the comic.
*/
virtual KUrl websiteUrl() const;
virtual KUrl imageUrl() const;
/**
* Returns the shop website of the comic.
*/
virtual KUrl shopUrl() const;
/**
* Returns the maximum number of cached strips per comic, -1 means that there is no limit
* @note defaulte is -1
*/
static int maxComicLimit();
/**
* Sets the maximum number of cached strips per comic, -1 means that there is no limit
*/
static void setMaxComicLimit( int limit );
private Q_SLOTS:
void triggerFinished();
private:
static const int CACHE_DEFAULT;
};
#endif

View file

@ -1,333 +0,0 @@
/*
* Copyright (C) 2007 Tobias Koenig <tokoe@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "comic.h"
#include <QtCore/qdatetime.h>
#include <QtCore/QFileInfo>
#include <QtCore/QSettings>
#include <KDebug>
#include <KServiceTypeTrader>
#include <KSycoca>
#include <KStandardDirs>
#include "cachedprovider.h"
ComicEngine::ComicEngine( QObject* parent, const QVariantList& args )
: Plasma::DataEngine( parent, args ), mEmptySuffix( false )
{
setPollingInterval( 0 );
updateFactories();
}
ComicEngine::~ComicEngine()
{
}
void ComicEngine::init()
{
connect( Solid::Networking::notifier(), SIGNAL(statusChanged(Solid::Networking::Status)),
this, SLOT(networkStatusChanged(Solid::Networking::Status)) );
connect( KSycoca::self(), SIGNAL(databaseChanged(QStringList)), this, SLOT(sycocaUpdated(QStringList)) );
}
void ComicEngine::networkStatusChanged( Solid::Networking::Status status )
{
if ( ( status == Solid::Networking::Connected || status == Solid::Networking::Unknown ) &&
!mIdentifierError.isEmpty() ) {
sourceRequestEvent( mIdentifierError );
}
}
void ComicEngine::sycocaUpdated( const QStringList &changedResources )
{
if ( changedResources.contains( QLatin1String( "services" ) ) ) {
updateFactories();
}
}
void ComicEngine::updateFactories()
{
mFactories.clear();
removeAllData( QLatin1String( "providers" ) );
KService::List services = KServiceTypeTrader::self()->query( QLatin1String( "Plasma/Comic" ) );
Q_FOREACH ( const KService::Ptr &service, services ) {
mFactories.insert( service->property( QLatin1String( "X-KDE-PluginInfo-Name" ), QVariant::String ).toString(),
service );
if ( service->isDeleted() ) {
continue;
}
QStringList data;
data << service->name();
QFileInfo file( service->icon() );
if ( file.isRelative() ) {
data << KStandardDirs::locate( "data", QString( QLatin1String( "plasma-comic/%1.png" ) ).arg( service->icon() ) );
} else {
data << service->icon();
}
setData( QLatin1String( "providers" ), service->property( QLatin1String( "X-KDE-PluginInfo-Name" ), QVariant::String ).toString(), data );
}
}
bool ComicEngine::updateSourceEvent( const QString &identifier )
{
if ( identifier == QLatin1String( "providers" ) ) {
updateFactories();
return true;
} else if ( identifier.startsWith( QLatin1String( "setting_maxComicLimit:" ) ) ) {
bool worked;
const int maxComicLimit = identifier.mid( 22 ).toInt( &worked );
if ( worked ) {
CachedProvider::setMaxComicLimit( maxComicLimit );
}
return worked;
} else {
if ( m_jobs.contains(identifier) ) {
return true;
}
// check whether it is cached already...
if ( CachedProvider::isCached( identifier ) ) {
QVariantList args;
args << QLatin1String( "String" ) << identifier;
ComicProvider *provider = new CachedProvider( this, args );
m_jobs[identifier] = provider;
connect( provider, SIGNAL(finished(ComicProvider*)), this, SLOT(finished(ComicProvider*)) );
connect( provider, SIGNAL(error(ComicProvider*)), this, SLOT(error(ComicProvider*)) );
return true;
}
// ... start a new query otherwise
const QStringList parts = identifier.split( QLatin1Char( ':' ), QString::KeepEmptyParts );
//: are mandatory
if ( parts.count() < 2 ) {
setData( identifier, QLatin1String( "Error" ), true );
kError() << "Less than two arguments specified.";
return false;
}
if ( !mFactories.contains( parts[ 0 ] ) ) {
// User might have installed more from GHNS
updateFactories();
if ( !mFactories.contains( parts[ 0 ] ) ) {
setData( identifier, QLatin1String( "Error" ), true );
kError() << identifier << "comic plugin does not seem to be installed.";
return false;
}
}
// check if there is a connection
Solid::Networking::Status status = Solid::Networking::status();
if ( status != Solid::Networking::Connected && status != Solid::Networking::Unknown ) {
mIdentifierError = identifier;
setData( identifier, QLatin1String( "Error" ), true );
setData( identifier, QLatin1String( "Error automatically fixable" ), true );
setData( identifier, QLatin1String( "Identifier" ), identifier );
setData( identifier, QLatin1String( "Previous identifier suffix" ), lastCachedIdentifier( identifier ) );
kWarning() << "No connection.";
return true;
}
const KService::Ptr service = mFactories[ parts[ 0 ] ];
bool isCurrentComic = parts[ 1 ].isEmpty();
QVariantList args;
ComicProvider *provider = 0;
const QString type = service->property( QLatin1String( "X-KDE-PlasmaComicProvider-SuffixType" ), QVariant::String ).toString();
if ( type == QLatin1String( "Date" ) ) {
QDate date = QDate::fromString( parts[ 1 ], Qt::ISODate );
if ( !date.isValid() )
date = QDate::currentDate();
args << QLatin1String( "Date" ) << date;
} else if ( type == QLatin1String( "Number" ) ) {
args << QLatin1String( "Number" ) << parts[ 1 ].toInt();
} else if ( type == QLatin1String( "String" ) ) {
args << QLatin1String( "String" ) << parts[ 1 ];
}
args << service->storageId();
provider = service->createInstance<ComicProvider>( this, args );
if ( !provider ) {
setData( identifier, QLatin1String( "Error" ), true );
kError() << identifier << "plugin could be created.";
return false;
}
provider->setIsCurrent( isCurrentComic );
m_jobs[identifier] = provider;
connect( provider, SIGNAL(finished(ComicProvider*)), this, SLOT(finished(ComicProvider*)) );
connect( provider, SIGNAL(error(ComicProvider*)), this, SLOT(error(ComicProvider*)) );
return true;
}
}
bool ComicEngine::sourceRequestEvent( const QString &identifier )
{
setData( identifier, DataEngine::Data() );
return updateSourceEvent( identifier );
}
void ComicEngine::finished( ComicProvider *provider )
{
// sets the data
setComicData( provider );
if ( provider->image().isNull() ) {
error( provider );
return;
}
// different comic -- with no error yet -- has been chosen, old error is invalidated
QString temp = mIdentifierError.left( mIdentifierError.indexOf( QLatin1Char( ':' ) ) + 1 );
if ( !mIdentifierError.isEmpty() && provider->identifier().indexOf( temp ) == -1 ) {
mIdentifierError.clear();
}
// comic strip with error worked now
if ( !mIdentifierError.isEmpty() && ( mIdentifierError == provider->identifier() ) ){
mIdentifierError.clear();
}
// store in cache if it's not the response of a CachedProvider,
// if there is a valid image and if there is a next comic
// (if we're on today's comic it could become stale)
if ( !provider->inherits("CachedProvider") && !provider->image().isNull() &&
!provider->nextIdentifier().isEmpty() ) {
CachedProvider::Settings info;
info[ QLatin1String( "websiteUrl" ) ] = provider->websiteUrl().prettyUrl();
info[ QLatin1String( "imageUrl" ) ] = provider->imageUrl().url();
info[ QLatin1String( "shopUrl" ) ] = provider->shopUrl().prettyUrl();
info[ QLatin1String( "nextIdentifier" ) ] = provider->nextIdentifier();
info[ QLatin1String( "previousIdentifier" ) ] = provider->previousIdentifier();
info[ QLatin1String( "title" ) ] = provider->name();
info[ QLatin1String( "suffixType" ) ] = provider->suffixType();
info[ QLatin1String( "lastCachedStripIdentifier" ) ] = provider->identifier().mid( provider->identifier().indexOf( QLatin1Char( ':' ) ) + 1 );
QString isLeftToRight;
QString isTopToBottom;
info[ QLatin1String( "isLeftToRight" ) ] = isLeftToRight.setNum( provider->isLeftToRight() );
info[ QLatin1String( "isTopToBottom" ) ] = isTopToBottom.setNum( provider->isTopToBottom() );
//data that should be only written if available
if ( !provider->comicAuthor().isEmpty() ) {
info[ QLatin1String( "comicAuthor" ) ] = provider->comicAuthor();
}
if ( !provider->firstStripIdentifier().isEmpty() ) {
info[ QLatin1String( "firstStripIdentifier" ) ] = provider->firstStripIdentifier();
}
if ( !provider->additionalText().isEmpty() ) {
info[ QLatin1String( "additionalText" ) ] = provider->additionalText();
}
if ( !provider->stripTitle().isEmpty() ) {
info[ QLatin1String( "stripTitle" ) ] = provider->stripTitle();
}
CachedProvider::storeInCache( provider->identifier(), provider->image(), info );
}
provider->deleteLater();
const QString key = m_jobs.key(provider);
if (!key.isEmpty()) {
m_jobs.remove(key);
}
}
void ComicEngine::error( ComicProvider *provider )
{
// sets the data
setComicData( provider );
QString identifier( provider->identifier() );
mIdentifierError = identifier;
kWarning() << identifier << "pluging reported an error.";
/**
* Requests for the current day have no suffix (date or id)
* set initially, so we have to remove the 'faked' suffix
* here again to not confuse the applet.
*/
if ( provider->isCurrent() )
identifier = identifier.left( identifier.indexOf( QLatin1Char( ':' ) ) + 1 );
setData( identifier, QLatin1String( "Identifier" ), identifier );
setData( identifier, QLatin1String( "Error" ), true );
// if there was an error loading the last cached comic strip, do not return its id anymore
const QString lastCachedId = lastCachedIdentifier( identifier );
if ( lastCachedId != provider->identifier().mid( provider->identifier().indexOf( QLatin1Char( ':' ) ) + 1 ) ) {
// sets the previousIdentifier to the identifier of a strip that has been cached before
setData( identifier, QLatin1String( "Previous identifier suffix" ), lastCachedId );
}
setData( identifier, QLatin1String( "Next identifier suffix" ), QString() );
const QString key = m_jobs.key(provider);
if (!key.isEmpty()) {
m_jobs.remove(key);
}
provider->deleteLater();
}
void ComicEngine::setComicData( ComicProvider *provider )
{
QString identifier( provider->identifier() );
/**
* Requests for the current day have no suffix (date or id)
* set initially, so we have to remove the 'faked' suffix
* here again to not confuse the applet.
*/
if ( provider->isCurrent() )
identifier = identifier.left( identifier.indexOf( QLatin1Char( ':' ) ) + 1 );
setData( identifier, QLatin1String( "Image" ), provider->image() );
setData( identifier, QLatin1String( "Website Url" ), provider->websiteUrl() );
setData( identifier, QLatin1String( "Image Url" ), provider->imageUrl() );
setData( identifier, QLatin1String( "Shop Url" ), provider->shopUrl() );
setData( identifier, QLatin1String( "Next identifier suffix" ), provider->nextIdentifier() );
setData( identifier, QLatin1String( "Previous identifier suffix" ), provider->previousIdentifier() );
setData( identifier, QLatin1String( "Comic Author" ), provider->comicAuthor() );
setData( identifier, QLatin1String( "Additional text" ), provider->additionalText() );
setData( identifier, QLatin1String( "Strip title" ), provider->stripTitle() );
setData( identifier, QLatin1String( "First strip identifier suffix" ), provider->firstStripIdentifier() );
setData( identifier, QLatin1String( "Identifier" ), provider->identifier() );
setData( identifier, QLatin1String( "Title" ), provider->name() );
setData( identifier, QLatin1String( "SuffixType" ), provider->suffixType() );
setData( identifier, QLatin1String( "isLeftToRight" ), provider->isLeftToRight() );
setData( identifier, QLatin1String( "isTopToBottom" ), provider->isTopToBottom() );
setData( identifier, QLatin1String( "Error" ), false );
}
QString ComicEngine::lastCachedIdentifier( const QString &identifier ) const
{
const QString id = identifier.left( identifier.indexOf( QLatin1Char( ':' ) ) );
QString data = KStandardDirs::locateLocal( "data", QLatin1String( "plasma_engine_comic/" ) );
data += QString::fromAscii( QUrl::toPercentEncoding( id ) );
QSettings settings( data + QLatin1String( ".conf" ), QSettings::IniFormat );
QString previousIdentifier = settings.value( QLatin1String( "lastCachedStripIdentifier" ), QString() ).toString();
return previousIdentifier;
}
#include "moc_comic.cpp"

View file

@ -1,73 +0,0 @@
/*
* Copyright (C) 2007 Tobias Koenig <tokoe@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef COMIC_DATAENGINE_H
#define COMIC_DATAENGINE_H
#include "plasma/dataengine.h"
#include <solid/networking.h>
class ComicProvider;
/**
* This class provides the comic strip.
*
* The query keys have the following structure:
* <comic_identifier>:<suffix>
* usually the suffix is the date
* e.g.
* userfriendly:2007-07-19
* but some other comics uses numerical identifiers, like
* xkcd:378
* if the suffix is empty the latest comic will be returned
*
*/
class ComicEngine : public Plasma::DataEngine
{
Q_OBJECT
public:
ComicEngine( QObject* parent, const QVariantList& args );
~ComicEngine();
protected:
void init();
bool sourceRequestEvent( const QString &identifier );
void updateFactories();
protected Q_SLOTS:
bool updateSourceEvent( const QString &identifier );
private Q_SLOTS:
void finished( ComicProvider* );
void error( ComicProvider* );
void networkStatusChanged( Solid::Networking::Status );
void sycocaUpdated( const QStringList &changedResources );
private:
bool mEmptySuffix;
void setComicData( ComicProvider *provider );
QString lastCachedIdentifier( const QString &identifier ) const;
QString mIdentifierError;
QMap<QString, KService::Ptr> mFactories;
QHash<QString, ComicProvider*> m_jobs;
};
K_EXPORT_PLASMA_DATAENGINE( comic, ComicEngine )
#endif

View file

@ -1,42 +0,0 @@
/*
* Copyright (C) 2008 Petri Damstén <damu@iki.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "comic_package.h"
#include "plasma/applet.h"
#include "plasma/package.h"
ComicPackage::ComicPackage( QObject *parent, const QVariantList& args )
: Plasma::PackageStructure( parent, QLatin1String( "Plasma/Comic" ) )
{
Q_UNUSED( args )
addDirectoryDefinition( "images", QLatin1String( "images" ), i18n( "Images" ) );
QStringList mimetypes;
mimetypes << QLatin1String( "image/svg+xml" ) << QLatin1String( "image/png" ) << QLatin1String( "image/jpeg" );
setMimetypes( "images", mimetypes );
addDirectoryDefinition( "scripts", QLatin1String( "code" ), i18n( "Executable Scripts" ) );
mimetypes.clear();
mimetypes << QLatin1String( "text/*" );
setMimetypes( "scripts", mimetypes );
addFileDefinition( "mainscript", QLatin1String( "code/main" ), i18n( "Main Script File" ) );
setDefaultPackageRoot( QLatin1String( "plasma/comics/" ) );
setServicePrefix( QLatin1String( "plasma-comic-" ) );
}

View file

@ -1,30 +0,0 @@
/*
* Copyright (C) 2008 Petri Damstén <damu@iki.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef COMIC_PACKAGE_H
#define COMIC_PACKAGE_H
#include <plasma/packagestructure.h>
class ComicPackage : public Plasma::PackageStructure
{
public:
explicit ComicPackage( QObject *parent = 0, const QVariantList& args = QVariantList() );
};
#endif

View file

@ -1,21 +0,0 @@
/*
* Copyright (C) 2008 Petri Damstén <damu@iki.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "comic_package.h"
K_EXPORT_PLASMA_PACKAGESTRUCTURE(comic, ComicPackage)

View file

@ -1,343 +0,0 @@
/*
* Copyright (C) 2007 Tobias Koenig <tokoe@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "comicprovider.h"
#include <QtCore/QTimer>
#include <KDebug>
#include <KIO/Job>
#include <KIO/StoredTransferJob>
#include <KUrl>
class ComicProvider::Private
{
public:
Private( KService::Ptr service, ComicProvider *parent )
: mParent( parent ),
mIsCurrent( false ),
mFirstStripNumber( 1 ),
mComicDescription( service )
{
mTimer = new QTimer( parent );
mTimer->setSingleShot( true );
mTimer->setInterval( 15000 );//timeout after 15 seconds
connect( mTimer, SIGNAL(timeout()), mParent, SLOT(slotTimeout()) );
}
void jobDone( KJob *job )
{
if ( job->error() ) {
mParent->pageError( job->property( "uid" ).toInt(), job->errorText() );
} else {
KIO::StoredTransferJob *storedJob = qobject_cast<KIO::StoredTransferJob*>( job );
mParent->pageRetrieved( job->property( "uid" ).toInt(), storedJob->data() );
}
}
void slotRedirection( KIO::Job *job, KUrl newUrl )
{
slotRedirection( job, KUrl(), newUrl );
}
void slotRedirection( KIO::Job *job, KUrl oldUrl, KUrl newUrl )
{
Q_UNUSED(oldUrl)
mParent->redirected( job->property( "uid" ).toInt(), newUrl );
mRedirections.remove( job );
}
void slotRedirectionDone( KJob *job )
{
if ( job->error() ) {
kDebug() << "Redirection job with id" << job->property( "uid" ).toInt() << "finished with an error.";
}
if ( mRedirections.contains( job ) ) {
//no redirection took place, return the original url
mParent->redirected( job->property( "uid" ).toInt(), mRedirections[ job ] );
mRedirections.remove( job );
}
}
void slotTimeout()
{
//operation took too long, abort it
mParent->error( mParent );
}
void slotFinished()
{
//everything finished, stop the timeout timer
mTimer->stop();
}
ComicProvider *mParent;
QString mRequestedId;
QString mRequestedComicName;
QString mComicAuthor;
KUrl mImageUrl;
bool mIsCurrent;
bool mIsLeftToRight;
bool mIsTopToBottom;
QDate mRequestedDate;
QDate mFirstStripDate;
int mRequestedNumber;
int mFirstStripNumber;
KPluginInfo mComicDescription;
QTimer *mTimer;
QHash< KJob*, KUrl > mRedirections;
};
ComicProvider::ComicProvider( QObject *parent, const QVariantList &args )
: QObject( parent ), d( new Private(
KService::serviceByStorageId( args.count() > 2 ? args[2].toString() : QString() ), this ) )
{
Q_ASSERT( args.count() >= 2 );
const QString type = args[ 0 ].toString();
if ( type == QLatin1String( "Date" ) )
d->mRequestedDate = args[ 1 ].toDate();
else if ( type == QLatin1String( "Number" ) )
d->mRequestedNumber = args[ 1 ].toInt();
else if ( type == QLatin1String( "String" ) ) {
d->mRequestedId = args[ 1 ].toString();
int index = d->mRequestedId.indexOf( QLatin1Char( ':' ) );
d->mRequestedComicName = d->mRequestedId.mid( 0, index );
}
else {
Q_ASSERT( false && "Invalid type passed to comic provider" );
}
d->mTimer->start();
connect( this, SIGNAL(finished(ComicProvider*)), this, SLOT(slotFinished()) );
}
ComicProvider::~ComicProvider()
{
delete d;
}
QString ComicProvider::nextIdentifier() const
{
if ( identifierType() == DateIdentifier && d->mRequestedDate != QDate::currentDate() )
return d->mRequestedDate.addDays( 1 ).toString( Qt::ISODate );
return QString();
}
QString ComicProvider::previousIdentifier() const
{
if ( ( identifierType() == DateIdentifier ) && ( !firstStripDate().isValid() || d->mRequestedDate > firstStripDate() ) )
return d->mRequestedDate.addDays( -1 ).toString( Qt::ISODate );
return QString();
}
QString ComicProvider::stripTitle() const
{
return QString();
}
QString ComicProvider::additionalText() const
{
return QString();
}
void ComicProvider::setIsCurrent( bool value )
{
d->mIsCurrent = value;
}
bool ComicProvider::isCurrent() const
{
return d->mIsCurrent;
}
QDate ComicProvider::requestedDate() const
{
return d->mRequestedDate;
}
QDate ComicProvider::firstStripDate() const
{
return d->mFirstStripDate;
}
QString ComicProvider::comicAuthor() const
{
return d->mComicAuthor;
}
void ComicProvider::setComicAuthor( const QString &author )
{
d->mComicAuthor = author;
}
void ComicProvider::setFirstStripDate( const QDate &date )
{
d->mFirstStripDate = date;
}
int ComicProvider::firstStripNumber() const
{
return d->mFirstStripNumber;
}
void ComicProvider::setFirstStripNumber( int number )
{
d->mFirstStripNumber = number;
}
QString ComicProvider::firstStripIdentifier() const
{
if ( ( identifierType() == DateIdentifier ) && d->mFirstStripDate.isValid() ) {
return d->mFirstStripDate.toString( Qt::ISODate );
} else if ( identifierType() == NumberIdentifier ) {
return QString::number( d->mFirstStripNumber );
}
return QString();
}
int ComicProvider::requestedNumber() const
{
return d->mRequestedNumber;
}
QString ComicProvider::requestedString() const
{
return d->mRequestedId;
}
QString ComicProvider::requestedComicName() const
{
return d->mRequestedComicName;
}
void ComicProvider::requestPage( const KUrl &url, int id, const MetaInfos &infos )
{
//each request restarts the timer
d->mTimer->start();
if (id == Image) {
d->mImageUrl = url;
}
KIO::StoredTransferJob *job;
if ( id == Image ) {
//use cached information for the image if available
job = KIO::storedGet( url, KIO::NoReload, KIO::HideProgressInfo );
} else {
//for webpages we always reload, making sure, that changes are recognised
job = KIO::storedGet( url, KIO::Reload, KIO::HideProgressInfo );
}
job->setProperty( "uid", id );
connect( job, SIGNAL(result(KJob*)), this, SLOT(jobDone(KJob*)) );
if ( !infos.isEmpty() ) {
QMapIterator<QString, QString> it( infos );
while ( it.hasNext() ) {
it.next();
job->addMetaData( it.key(), it.value() );
}
}
}
void ComicProvider::requestRedirectedUrl( const KUrl &url, int id, const MetaInfos &infos )
{
KIO::MimetypeJob *job = KIO::mimetype( url, KIO::HideProgressInfo );
job->setProperty( "uid", id );
d->mRedirections[job] = url;
connect(job, SIGNAL(redirection(KIO::Job*,KUrl)), this, SLOT(slotRedirection(KIO::Job*,KUrl)) );
connect(job, SIGNAL(permanentRedirection(KIO::Job*,KUrl,KUrl)), this, SLOT(slotRedirection(KIO::Job*,KUrl,KUrl)) );
connect(job, SIGNAL(result(KJob*)), this, SLOT(slotRedirectionDone(KJob*)) );
if ( !infos.isEmpty() ) {
QMapIterator<QString, QString> it( infos );
while ( it.hasNext() ) {
it.next();
job->addMetaData( it.key(), it.value() );
}
}
}
void ComicProvider::pageRetrieved( int, const QByteArray& )
{
}
void ComicProvider::pageError( int, const QString& )
{
}
void ComicProvider::redirected( int, const KUrl& )
{
}
QString ComicProvider::pluginName() const
{
if ( !d->mComicDescription.isValid() ) {
return QString();
}
return d->mComicDescription.pluginName();
}
QString ComicProvider::name() const
{
if ( !d->mComicDescription.isValid() ) {
return QString();
}
return d->mComicDescription.name();
}
QString ComicProvider::suffixType() const
{
if ( !d->mComicDescription.isValid() ) {
return QString();
}
return d->mComicDescription.property( QLatin1String( "X-KDE-PlasmaComicProvider-SuffixType" ) ).toString();
}
KPluginInfo ComicProvider::description() const
{
return d->mComicDescription;
}
KUrl ComicProvider::shopUrl() const
{
return KUrl();
}
KUrl ComicProvider::imageUrl() const
{
return d->mImageUrl;
}
bool ComicProvider::isLeftToRight() const
{
return true;
}
bool ComicProvider::isTopToBottom() const
{
return true;
}
#include "moc_comicprovider.cpp"

View file

@ -1,303 +0,0 @@
/*
* Copyright (C) 2007 Tobias Koenig <tokoe@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef COMICPROVIDER_H
#define COMICPROVIDER_H
#include <QtCore/qdatetime.h>
#include <QtCore/QObject>
#include <KPluginInfo>
#include <KPluginFactory>
#include "plasma_comic_export.h"
class QImage;
class KUrl;
#define COMICPROVIDER_EXPORT_PLUGIN( classname, componentName, catalogName ) \
K_PLUGIN_FACTORY( classname ## Factory, registerPlugin< classname >(); ) \
K_EXPORT_PLUGIN( classname ## Factory( componentName, catalogName ) )
/**
* This class is an interface for comic providers.
*/
class PLASMA_COMIC_EXPORT ComicProvider : public QObject
{
Q_OBJECT
public:
/**
* Describes the type of how this comic provider
* references the previous or next comic strip.
*/
enum IdentifierType {
DateIdentifier = 0, ///< References by date
NumberIdentifier, ///< References by numerical identifier
StringIdentifier ///< References by arbitrary string
};
enum RequestType {
Page = 0,
Image,
User
};
/**
* Creates a new comic provider.
*
* @param parent The parent object.
* @param args Arguments passed by the plugin loader.
*/
ComicProvider( QObject *parent, const QVariantList &args );
/**
* Destroys the comic provider.
*/
virtual ~ComicProvider();
/**
* Returns the type of identifier that is used by this
* comic provider.
*/
virtual IdentifierType identifierType() const = 0;
/**
* Returns the type of suffix that is used by this
* comic provider.
*/
virtual QString suffixType() const;
/**
* Returns the url of the website where the comic of that particular date resides.
*/
virtual KUrl websiteUrl() const = 0;
/**
* Returns the direct url to the comic, if the comic strip is a combination of multiple
* images, then this should return the url to one part of it
* @note the image url is automatically set by requestPage with the ComicProvider::Image id
* @see requestPage
*/
virtual KUrl imageUrl() const;
/**
* Returns the url of the website where the comic has a shop.
*/
virtual KUrl shopUrl() const;
/**
* Returns the requested image.
*
* Note: This method returns only a valid image after the
* finished() signal has been emitted.
*/
virtual QImage image() const = 0;
/**
* Returns the identifier of the comic request.
*/
virtual QString identifier() const = 0;
/**
* Returns the identifier of the next comic (default: date of next day).
*/
virtual QString nextIdentifier() const;
/**
* Returns the identifier of the previous comic (default: date of previous day
* as long).
*/
virtual QString previousIdentifier() const;
/**
* Returns the identifier of the first strip.
*/
virtual QString firstStripIdentifier() const;
/**
* Returns the author of the comic.
*/
virtual QString comicAuthor() const;
/**
* Returns the title of the strip.
*/
virtual QString stripTitle() const;
/**
* Returns additionalText of the comic.
*/
virtual QString additionalText() const;
/**
* Returns the identifier for the comic
*/
virtual QString pluginName() const;
/**
* Returns the name for the comic
*/
virtual QString name() const;
/**
* Returns wether the comic is leftToRight or not
*/
virtual bool isLeftToRight() const;
/**
* Returns wether the comic is topToBottom or not
*/
virtual bool isTopToBottom() const;
/**
* Returns the plugin info for the comic
*/
KPluginInfo description() const;
/**
* Set whether this request is for the current comic (only used internally).
*/
void setIsCurrent( bool value );
/**
* Returns whether this request is for the current comic (only used internally).
*/
bool isCurrent() const;
Q_SIGNALS:
/**
* This signal is emitted whenever a request has been finished
* successfully.
*
* @param provider The provider which emitted the signal.
*/
void finished( ComicProvider *provider );
/**
* This signal is emitted whenever an error has occurred.
*
* @param provider The provider which emitted the signal.
*/
void error( ComicProvider *provider );
protected:
/**
* Returns the date identifier that was requested by the applet.
*/
QDate requestedDate() const;
/**
* Returns the numeric identifier that was requested by the applet.
*/
int requestedNumber() const;
/**
* Returns the string identifier that was requested by the applet.
*/
QString requestedString() const;
/**
* @internal
*
* Returns the comic name of the string identifier that was requested by the applet.
*/
QString requestedComicName() const;
/**
* Returns the date of the first available comic strip.
*/
QDate firstStripDate() const;
/**
* Sets the date of the first available comic strip.
*/
void setFirstStripDate( const QDate &date );
/**
* Returns the number of the first available comic strip (default: 1 ).
*/
int firstStripNumber() const;
/**
* Sets the number of the first available comic strip.
*/
void setFirstStripNumber( int number );
/**
* Sets the name of the comic author.
*/
void setComicAuthor( const QString &author );
typedef QMap<QString, QString> MetaInfos;
/**
* This method should be used by all comic providers to request
* websites or images from the web. It encapsulates the HTTP
* handling and calls pageRetrieved() or pageError() on success or error.
*
* @param url The url to access.
* @param id A unique id that identifies this request.
* @param infos A list of meta information passed to http.
*/
void requestPage( const KUrl &url, int id, const MetaInfos &infos = MetaInfos() );
/**
* This method can be used to find the place url points to, when finished
* urlRetrieved() is called, either with the original url or a redirected url
* @param url to check for redirections
* @param id A unique id that identifies this request.
* @param infos A list of meta information passed to KIO.
*/
void requestRedirectedUrl( const KUrl &url, int id, const MetaInfos &infos = MetaInfos() );
/**
* This method is called whenever a request done by requestPage() was successful.
*
* @param id The unique identifier of that request.
* @param data The data of the fetched object.
*/
virtual void pageRetrieved( int id, const QByteArray &data );
/**
* This method is called whenever a request done by requestPage() has failed.
*
* @param id The unique identifier of that request.
* @param message The error message.
*/
virtual void pageError( int id, const QString &message );
/**
* This method is called whenever a request by requestRedirectedUrl() was done
* @param id The unique identifier of that request.
* @param newUrl The redirected Url
*/
virtual void redirected( int id, const KUrl &newUrl );
private:
class Private;
Private* const d;
Q_PRIVATE_SLOT( d, void jobDone( KJob* ) )
Q_PRIVATE_SLOT( d, void slotRedirection( KIO::Job*, KUrl ) )
Q_PRIVATE_SLOT( d, void slotRedirection( KIO::Job*, KUrl, KUrl ) )
Q_PRIVATE_SLOT( d, void slotRedirectionDone( KJob* ) )
Q_PRIVATE_SLOT( d, void slotTimeout() )
Q_PRIVATE_SLOT( d, void slotFinished() )
};
#endif

View file

@ -1,132 +0,0 @@
/*
* Copyright (C) 2008 Petri Damstén <damu@iki.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "comicproviderkross.h"
#include "comic_package.h"
COMICPROVIDER_EXPORT_PLUGIN( ComicProviderKross, "ComicProviderKross", "" )
Plasma::PackageStructure::Ptr ComicProviderKross::m_packageStructure( 0 );
ComicProviderKross::ComicProviderKross( QObject *parent, const QVariantList &args )
: ComicProvider( parent, args ), m_wrapper( this )
{
}
ComicProviderKross::~ComicProviderKross()
{
}
bool ComicProviderKross::isLeftToRight() const
{
return m_wrapper.isLeftToRight();
}
bool ComicProviderKross::isTopToBottom() const
{
return m_wrapper.isTopToBottom();
}
ComicProvider::IdentifierType ComicProviderKross::identifierType() const
{
return m_wrapper.identifierType();
}
KUrl ComicProviderKross::websiteUrl() const
{
return m_wrapper.websiteUrl();
}
KUrl ComicProviderKross::shopUrl() const
{
return m_wrapper.shopUrl();
}
QImage ComicProviderKross::image() const
{
return m_wrapper.comicImage();
}
QString ComicProviderKross::identifierToString( const QVariant &identifier ) const
{
QString result;
if ( !identifier.isNull() && identifier.type() != QVariant::Bool ) {
if ( identifierType() == ComicProvider::DateIdentifier ) {
result = identifier.toDate().toString( Qt::ISODate );
} else {
result = identifier.toString();
}
}
return result;
}
QString ComicProviderKross::identifier() const
{
return pluginName() + QLatin1Char( ':' ) + identifierToString( m_wrapper.identifierVariant() );
}
QString ComicProviderKross::nextIdentifier() const
{
return identifierToString( m_wrapper.nextIdentifierVariant() );
}
QString ComicProviderKross::previousIdentifier() const
{
return identifierToString( m_wrapper.previousIdentifierVariant() );
}
QString ComicProviderKross::firstStripIdentifier() const
{
return identifierToString( m_wrapper.firstIdentifierVariant() );
}
QString ComicProviderKross::stripTitle() const
{
return m_wrapper.title();
}
QString ComicProviderKross::additionalText() const
{
return m_wrapper.additionalText();
}
void ComicProviderKross::pageRetrieved( int id, const QByteArray &data )
{
m_wrapper.pageRetrieved( id, data );
}
void ComicProviderKross::pageError( int id, const QString &message )
{
m_wrapper.pageError( id, message );
}
void ComicProviderKross::redirected( int id, const KUrl &newUrl )
{
m_wrapper.redirected( id, newUrl );
}
Plasma::PackageStructure::Ptr ComicProviderKross::packageStructure()
{
if ( !m_packageStructure ) {
m_packageStructure = new ComicPackage();
}
return m_packageStructure;
}
#include "moc_comicproviderkross.cpp"

View file

@ -1,64 +0,0 @@
/*
* Copyright (C) 2008 Petri Damstén <damu@iki.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef COMICPROVIDERKROSS_H
#define COMICPROVIDERKROSS_H
#include "comicprovider.h"
#include "comicproviderwrapper.h"
#include <QtGui/QImage>
#include <KUrl>
#include "Plasma/PackageStructure"
class ComicProviderKross : public ComicProvider
{
friend class ComicProviderWrapper;
Q_OBJECT
public:
ComicProviderKross( QObject *parent, const QVariantList &args );
virtual ~ComicProviderKross();
static Plasma::PackageStructure::Ptr packageStructure();
virtual bool isLeftToRight() const;
virtual bool isTopToBottom() const;
virtual IdentifierType identifierType() const;
virtual KUrl websiteUrl() const;
virtual KUrl shopUrl() const;
virtual QImage image() const;
virtual QString identifier() const;
virtual QString nextIdentifier() const;
virtual QString previousIdentifier() const;
virtual QString firstStripIdentifier() const;
virtual QString stripTitle() const;
virtual QString additionalText() const;
protected:
virtual void pageRetrieved( int id, const QByteArray &data );
virtual void pageError( int id, const QString &message );
virtual void redirected( int id, const KUrl &newUrl );
QString identifierToString( const QVariant &identifier ) const;
private:
mutable ComicProviderWrapper m_wrapper;
static Plasma::PackageStructure::Ptr m_packageStructure;
};
#endif

View file

@ -1,883 +0,0 @@
/*
* Copyright (C) 2008 Petri Damstén <damu@iki.fi>
* Copyright (C) 2010 Matthias Fuchs <mat69@gmx.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "comicproviderwrapper.h"
#include "comicproviderkross.h"
#include "comicprovider.h"
#include <QTimer>
#include <QBuffer>
#include <QPainter>
#include <QTextCodec>
#include <KUrl>
#include <KDebug>
#include <KStandardDirs>
#include <Plasma/Package>
#include <kross/core/action.h>
#include <kross/core/interpreter.h>
#include <kross/core/manager.h>
QStringList ComicProviderWrapper::mExtensions;
ImageWrapper::ImageWrapper( QObject *parent, const QByteArray &data )
: QObject( parent ),
mImage( QImage::fromData( data ) ),
mRawData( data )
{
resetImageReader();
}
QImage ImageWrapper::image() const
{
return mImage;
}
void ImageWrapper::setImage( const QImage &image )
{
mImage = image;
mRawData.clear();
resetImageReader();
}
QByteArray ImageWrapper::rawData() const
{
if ( mRawData.isNull() ) {
QBuffer buffer( &mRawData );
mImage.save( &buffer );
}
return mRawData;
}
void ImageWrapper::setRawData( const QByteArray &rawData )
{
mRawData = rawData;
mImage = QImage::fromData( mRawData );
resetImageReader();
}
void ImageWrapper::resetImageReader()
{
if ( mBuffer.isOpen() ) {
mBuffer.close();
}
rawData(); //to update the rawData if needed
mBuffer.setBuffer( &mRawData );
mBuffer.open( QIODevice::ReadOnly );
mImageReader.setDevice( &mBuffer );
}
int ImageWrapper::imageCount() const
{
return mImageReader.imageCount();
}
QImage ImageWrapper::read()
{
return mImageReader.read();
}
DateWrapper::DateWrapper( QObject *parent, const QDate &date )
: QObject( parent )
, mDate( date )
{
}
QDate DateWrapper::date() const
{
return mDate;
}
void DateWrapper::setDate( const QDate &date )
{
mDate = date;
}
QDate DateWrapper::fromVariant( const QVariant &variant )
{
if ( variant.type() == QVariant::Date || variant.type() == QVariant::DateTime ) {
return variant.toDate();
} else if ( variant.type() == QVariant::String ) {
return QDate::fromString( variant.toString(), Qt::ISODate );
} else {
DateWrapper* dw = qobject_cast<DateWrapper*>( variant.value<QObject*>() );
if ( dw ) {
return dw->date();
}
}
return QDate();
}
QObject* DateWrapper::addDays( int ndays )
{
return new DateWrapper( this, mDate.addDays( ndays ) );
}
QObject* DateWrapper::addMonths( int nmonths )
{
return new DateWrapper( this, mDate.addMonths( nmonths ) );
}
QObject* DateWrapper::addYears( int nyears )
{
return new DateWrapper( this, mDate.addYears( nyears ) );
}
int DateWrapper::day() const
{
return mDate.day();
}
int DateWrapper::dayOfWeek() const
{
return mDate.dayOfWeek();
}
int DateWrapper::dayOfYear() const
{
return mDate.dayOfYear();
}
int DateWrapper::daysInMonth() const
{
return mDate.daysInMonth();
}
int DateWrapper::daysInYear() const
{
return mDate.daysInYear();
}
int DateWrapper::daysTo( const QVariant d ) const
{
return mDate.daysTo( fromVariant( d ) );
}
bool DateWrapper::isNull() const
{
return mDate.isNull();
}
bool DateWrapper::isValid() const
{
return mDate.isValid();
}
int DateWrapper::month() const
{
return mDate.month();
}
bool DateWrapper::setDate( int year, int month, int day )
{
return mDate.setDate( year, month, day );
}
int DateWrapper::toJulianDay() const
{
return mDate.toJulianDay();
}
QString DateWrapper::toString( const QString &format ) const
{
return mDate.toString( format );
}
QString DateWrapper::toString( int format ) const
{
return mDate.toString( ( Qt::DateFormat )format );
}
int DateWrapper::weekNumber() const
{
return mDate.weekNumber();
}
int DateWrapper::year() const
{
return mDate.year();
}
StaticDateWrapper::StaticDateWrapper( QObject *parent )
: QObject( parent )
{
}
QObject* StaticDateWrapper::currentDate()
{
return new DateWrapper( this, QDate::currentDate() );
}
QObject* StaticDateWrapper::fromJulianDay( int jd )
{
return new DateWrapper( this, QDate::fromJulianDay( jd ) );
}
QObject* StaticDateWrapper::fromString( const QString &string, int format )
{
return new DateWrapper( this, QDate::fromString( string, ( Qt::DateFormat )format ) );
}
QObject* StaticDateWrapper::fromString( const QString &string, const QString &format )
{
return new DateWrapper( this, QDate::fromString( string, format ) );
}
bool StaticDateWrapper::isLeapYear ( int year )
{
return QDate::isLeapYear( year );
}
bool StaticDateWrapper::isValid ( int year, int month, int day )
{
return QDate::isValid( year, month, day );
}
QString StaticDateWrapper::longDayName ( int weekday )
{
return QDate::longDayName( weekday );
}
QString StaticDateWrapper::longMonthName ( int month )
{
return QDate::longMonthName( month );
}
QString StaticDateWrapper::shortDayName ( int weekday )
{
return QDate::shortDayName( weekday );
}
QString StaticDateWrapper::shortMonthName ( int month )
{
return QDate::shortMonthName( month );
}
ComicProviderWrapper::ComicProviderWrapper( ComicProviderKross *parent )
: QObject( parent ),
mAction( 0 ),
mProvider( parent ),
mKrossImage( 0 ),
mPackage( 0 ),
mRequests( 0 ),
mIdentifierSpecified( false ),
mIsLeftToRight( true ),
mIsTopToBottom( true )
{
QTimer::singleShot( 0, this, SLOT(init()) );
}
ComicProviderWrapper::~ComicProviderWrapper()
{
delete mPackage;
}
void ComicProviderWrapper::init()
{
const QString path = KStandardDirs::locate( "data", QLatin1String( "plasma/comics/" ) + mProvider->pluginName() + QLatin1Char( '/' ) );
if ( !path.isEmpty() ) {
mPackage = new Plasma::Package( path, ComicProviderKross::packageStructure() );
if ( mPackage->isValid() ) {
// package->filePath( "mainscript" ) returns empty if it does not exist
// We want to test extensions supported by kross with mainscript
const QString mainscript = mPackage->path() + mPackage->structure()->contentsPrefix() +
mPackage->structure()->path( "mainscript" );
QFileInfo info( mainscript );
for ( int i = 0; i < extensions().count() && !info.exists(); ++i ) {
info.setFile( mainscript + extensions().value( i ) );
}
if ( info.exists() ) {
mAction = new Kross::Action( parent(), mProvider->pluginName() );
if ( mAction ) {
mAction->addObject( this, QLatin1String( "comic" ) );
mAction->addObject( new StaticDateWrapper( this ), QLatin1String( "date" ) );
mAction->setFile( info.filePath() );
mAction->trigger();
mFunctions = mAction->functionNames();
mIdentifierSpecified = !mProvider->isCurrent();
setIdentifierToDefault();
callFunction( QLatin1String( "init" ) );
}
}
}
}
}
const QStringList& ComicProviderWrapper::extensions() const
{
if ( mExtensions.isEmpty() ) {
Kross::InterpreterInfo* info;
QStringList list;
QString wildcards;
foreach( const QString &interpretername, Kross::Manager::self().interpreters() ) {
info = Kross::Manager::self().interpreterInfo( interpretername );
wildcards = info->wildcard();
wildcards.remove( QLatin1Char( '*' ) );
mExtensions << wildcards.split( QLatin1Char( ' ' ) );
}
}
return mExtensions;
}
ComicProvider::IdentifierType ComicProviderWrapper::identifierType() const
{
ComicProvider::IdentifierType result = ComicProvider::StringIdentifier;
const QString type = mProvider->description().property( QLatin1String( "X-KDE-PlasmaComicProvider-SuffixType" ) ).toString();
if ( type == QLatin1String( "Date" ) ) {
result = ComicProvider::DateIdentifier;
} else if ( type == QLatin1String( "Number" ) ) {
result = ComicProvider::NumberIdentifier;
} else if ( type == QLatin1String( "String" ) ) {
result = ComicProvider::StringIdentifier;
}
return result;
}
QImage ComicProviderWrapper::comicImage()
{
ImageWrapper* img = qobject_cast<ImageWrapper*>( callFunction( QLatin1String( "image" ) ).value<QObject*>() );
if ( functionCalled() && img ) {
return img->image();
}
if ( mKrossImage ) {
return mKrossImage->image();
}
return QImage();
}
QVariant ComicProviderWrapper::identifierToScript( const QVariant &identifier )
{
if ( identifierType() == ComicProvider::DateIdentifier && identifier.type() != QVariant::Bool ) {
return QVariant::fromValue( qobject_cast<QObject*>( new DateWrapper( this, identifier.toDate() ) ) );
}
return identifier;
}
QVariant ComicProviderWrapper::identifierFromScript( const QVariant &identifier ) const
{
QVariant result = identifier;
if ( identifier.type() != QVariant::Bool ) {
switch ( identifierType() ) {
case DateIdentifier:
result = DateWrapper::fromVariant( identifier );
break;
case NumberIdentifier:
result = identifier.toInt();
break;
case StringIdentifier:
result = identifier.toString();
break;
}
}
return result;
}
void ComicProviderWrapper::checkIdentifier( QVariant *identifier )
{
switch ( identifierType() ) {
case DateIdentifier:
if ( !mLastIdentifier.isNull() && !identifier->isNull() &&
( !mIdentifierSpecified || identifier->toDate() > mLastIdentifier.toDate() ) ) {
*identifier = mLastIdentifier;
}
if ( !mFirstIdentifier.isNull() && !identifier->isNull() &&
identifier->toDate() < mFirstIdentifier.toDate() ) {
*identifier = mFirstIdentifier;
}
break;
case NumberIdentifier:
if ( !mLastIdentifier.isNull() && !identifier->isNull() &&
( !mIdentifierSpecified || identifier->toInt() > mLastIdentifier.toInt() ) ) {
*identifier = mLastIdentifier;
}
if ( !mFirstIdentifier.isNull() && !identifier->isNull() &&
identifier->toInt() < mFirstIdentifier.toInt() ) {
*identifier = mFirstIdentifier;
}
break;
case StringIdentifier:
if ( !mLastIdentifier.isNull() && !mLastIdentifier.toString().isEmpty() &&
!mIdentifierSpecified ) {
*identifier = mLastIdentifier;
}
break;
}
}
void ComicProviderWrapper::setIdentifierToDefault()
{
switch ( identifierType() ) {
case DateIdentifier:
mIdentifier = mProvider->requestedDate();
mLastIdentifier = QDate::currentDate();
break;
case NumberIdentifier:
mIdentifier = mProvider->requestedNumber();
mFirstIdentifier = 1;
break;
case StringIdentifier:
mIdentifier = mProvider->requestedString();
break;
}
}
bool ComicProviderWrapper::identifierSpecified() const
{
return mIdentifierSpecified;
}
bool ComicProviderWrapper::isLeftToRight() const
{
return mIsLeftToRight;
}
void ComicProviderWrapper::setLeftToRight( bool ltr )
{
mIsLeftToRight = ltr;
}
bool ComicProviderWrapper::isTopToBottom() const
{
return mIsTopToBottom;
}
void ComicProviderWrapper::setTopToBottom( bool ttb )
{
mIsTopToBottom = ttb;
}
QString ComicProviderWrapper::textCodec() const
{
return QString::fromAscii( mTextCodec );
}
void ComicProviderWrapper::setTextCodec( const QString &textCodec )
{
mTextCodec = textCodec.toAscii();
}
QString ComicProviderWrapper::comicAuthor() const
{
return mProvider->comicAuthor();
}
void ComicProviderWrapper::setComicAuthor( const QString &author )
{
mProvider->setComicAuthor( author );
}
QString ComicProviderWrapper::websiteUrl() const
{
return mWebsiteUrl;
}
void ComicProviderWrapper::setWebsiteUrl( const QString &websiteUrl )
{
mWebsiteUrl = websiteUrl;
}
QString ComicProviderWrapper::shopUrl() const
{
return mShopUrl;
}
void ComicProviderWrapper::setShopUrl( const QString &shopUrl )
{
mShopUrl = shopUrl;
}
QString ComicProviderWrapper::title() const
{
return mTitle;
}
void ComicProviderWrapper::setTitle( const QString &title )
{
mTitle = title;
}
QString ComicProviderWrapper::additionalText() const
{
return mAdditionalText;
}
void ComicProviderWrapper::setAdditionalText( const QString &additionalText )
{
mAdditionalText = additionalText;
}
QVariant ComicProviderWrapper::identifier()
{
return identifierToScript( mIdentifier );
}
void ComicProviderWrapper::setIdentifier( const QVariant &identifier )
{
mIdentifier = identifierFromScript( identifier );
checkIdentifier( &mIdentifier );
}
QVariant ComicProviderWrapper::nextIdentifier()
{
return identifierToScript( mNextIdentifier );
}
void ComicProviderWrapper::setNextIdentifier( const QVariant &nextIdentifier )
{
mNextIdentifier = identifierFromScript( nextIdentifier );
if ( mNextIdentifier == mIdentifier ) {
mNextIdentifier.clear();
kWarning() << "Next identifier is the same as the current one, clearing next identifier.";
}
}
QVariant ComicProviderWrapper::previousIdentifier()
{
return identifierToScript( mPreviousIdentifier );
}
void ComicProviderWrapper::setPreviousIdentifier( const QVariant &previousIdentifier )
{
mPreviousIdentifier = identifierFromScript( previousIdentifier );
if ( mPreviousIdentifier == mIdentifier ) {
mPreviousIdentifier.clear();
kWarning() << "Previous identifier is the same as the current one, clearing previous identifier.";
}
}
QVariant ComicProviderWrapper::firstIdentifier()
{
return identifierToScript( mFirstIdentifier );
}
void ComicProviderWrapper::setFirstIdentifier( const QVariant &firstIdentifier )
{
switch ( identifierType() ) {
case DateIdentifier:
mProvider->setFirstStripDate( DateWrapper::fromVariant( firstIdentifier ) );
break;
case NumberIdentifier:
mProvider->setFirstStripNumber( firstIdentifier.toInt() );
break;
case StringIdentifier:
break;
}
mFirstIdentifier = identifierFromScript( firstIdentifier );
checkIdentifier( &mIdentifier );
}
QVariant ComicProviderWrapper::lastIdentifier()
{
return identifierToScript( mLastIdentifier );
}
void ComicProviderWrapper::setLastIdentifier( const QVariant &lastIdentifier )
{
mLastIdentifier = identifierFromScript( lastIdentifier );
checkIdentifier( &mIdentifier );
}
QVariant ComicProviderWrapper::identifierVariant() const
{
return mIdentifier;
}
QVariant ComicProviderWrapper::firstIdentifierVariant() const
{
return mFirstIdentifier;
}
QVariant ComicProviderWrapper::lastIdentifierVariant() const
{
return mLastIdentifier;
}
QVariant ComicProviderWrapper::nextIdentifierVariant() const
{
//either handle both previousIdentifier and nextIdentifier or handle none
if ( mPreviousIdentifier.isNull() && mNextIdentifier.isNull() ) {
switch ( identifierType() ) {
case DateIdentifier:
if ( ( mLastIdentifier.isNull() && mIdentifier.toDate() < QDate::currentDate() ) ||
( !mLastIdentifier.isNull() && mIdentifier.toDate() < mLastIdentifier.toDate() ) ) {
return mIdentifier.toDate().addDays( 1 );
} else {
return false;
}
case NumberIdentifier:
if ( mLastIdentifier.isNull() || mIdentifier.toInt() < mLastIdentifier.toInt() ) {
return mIdentifier.toInt() + 1;
} else {
return false;
}
case StringIdentifier:
break;
}
//check if the nextIdentifier is correct
} else if ( !mNextIdentifier.isNull() ) {
//no nextIdentifier if mIdentifier == mLastIdentifier or if no identifier has been specified
switch ( identifierType() ) {
case DateIdentifier:
if ( ( !mLastIdentifier.isNull() && ( mIdentifier.toDate() == mLastIdentifier.toDate() ) ) ||
!mIdentifierSpecified ) {
return false;
}
break;
case NumberIdentifier:
if ( ( !mLastIdentifier.isNull() && ( mIdentifier.toInt() == mLastIdentifier.toInt() ) ) ||
!mIdentifierSpecified ) {
return false;
}
break;
case StringIdentifier:
if ( !mIdentifierSpecified ) {
return false;
}
break;
}
}
return mNextIdentifier;
}
QVariant ComicProviderWrapper::previousIdentifierVariant() const
{
//either handle both previousIdentifier and nextIdentifier or handle none
if ( mPreviousIdentifier.isNull() && mNextIdentifier.isNull() ) {
switch ( identifierType() ) {
case DateIdentifier:
if ( mFirstIdentifier.isNull() || mIdentifier.toDate() > mFirstIdentifier.toDate() ) {
return mIdentifier.toDate().addDays( -1 );
} else {
return false;
}
case NumberIdentifier:
if ( ( mFirstIdentifier.isNull() && mIdentifier.toInt() > 1 ) ||
( !mFirstIdentifier.isNull() && mIdentifier.toInt() > mFirstIdentifier.toInt() ) ) {
return mIdentifier.toInt() - 1;
} else {
return false;
}
case StringIdentifier:
break;
}
} else if ( !mPreviousIdentifier.isNull() ) {
//no previousIdentifier if mIdentifier == mFirstIdentifier
switch ( identifierType() ) {
case DateIdentifier:
if ( !mFirstIdentifier.isNull() && ( mIdentifier.toDate() == mFirstIdentifier.toDate() ) ) {
return false;
}
break;
case NumberIdentifier:
if ( !mFirstIdentifier.isNull() && ( mIdentifier.toInt() == mFirstIdentifier.toInt() ) ) {
return false;
}
break;
case StringIdentifier:
break;
}
}
return mPreviousIdentifier;
}
void ComicProviderWrapper::pageRetrieved( int id, const QByteArray &data )
{
--mRequests;
if ( id == Image ) {
mKrossImage = new ImageWrapper( this, data );
callFunction( QLatin1String( "pageRetrieved" ), QVariantList() << id <<
qVariantFromValue( qobject_cast<QObject*>( mKrossImage ) ) );
if ( mRequests < 1 ) { // Don't finish if we still have pageRequests
finished();
}
} else {
QTextCodec *codec = 0;
if ( !mTextCodec.isEmpty() ) {
codec = QTextCodec::codecForName( mTextCodec );
}
if ( !codec ) {
codec = QTextCodec::codecForHtml( data );
}
QString html = codec->toUnicode( data );
callFunction( QLatin1String( "pageRetrieved" ), QVariantList() << id << html );
}
}
void ComicProviderWrapper::pageError( int id, const QString &message )
{
--mRequests;
callFunction( QLatin1String( "pageError" ), QVariantList() << id << message );
if ( !functionCalled() ) {
emit mProvider->error( mProvider );
}
}
void ComicProviderWrapper::redirected(int id, const KUrl &newUrl)
{
--mRequests;
callFunction( QLatin1String( "redirected" ), QVariantList() << id << newUrl );
if ( mRequests < 1 ) { //Don't finish while there are still requests
finished();
}
}
void ComicProviderWrapper::finished() const
{
kDebug() << QString( QLatin1String( "Author" ) ).leftJustified( 22, QLatin1Char( '.' ) ) << comicAuthor();
kDebug() << QString( QLatin1String( "Website URL" ) ).leftJustified( 22, QLatin1Char( '.' ) ) << mWebsiteUrl;
kDebug() << QString( QLatin1String( "Shop URL" ) ).leftJustified( 22, QLatin1Char( '.' ) ) << mShopUrl;
kDebug() << QString( QLatin1String( "Title" ) ).leftJustified( 22, QLatin1Char( '.' ) ) << mTitle;
kDebug() << QString( QLatin1String( "Additional Text" ) ).leftJustified( 22, QLatin1Char( '.' ) ) << mAdditionalText;
kDebug() << QString( QLatin1String( "Identifier" ) ).leftJustified( 22, QLatin1Char( '.' ) ) << mIdentifier;
kDebug() << QString( QLatin1String( "First Identifier" ) ).leftJustified( 22, QLatin1Char( '.' ) ) << mFirstIdentifier;
kDebug() << QString( QLatin1String( "Last Identifier" ) ).leftJustified( 22, QLatin1Char( '.' ) ) << mLastIdentifier;
kDebug() << QString( QLatin1String( "Next Identifier" ) ).leftJustified( 22, QLatin1Char( '.' ) ) << mNextIdentifier;
kDebug() << QString( QLatin1String( "Previous Identifier" ) ).leftJustified( 22, QLatin1Char( '.' ) ) << mPreviousIdentifier;
emit mProvider->finished( mProvider );
}
void ComicProviderWrapper::error() const
{
emit mProvider->error( mProvider );
}
void ComicProviderWrapper::requestPage( const QString &url, int id, const QVariantMap &infos )
{
QMap<QString, QString> map;
foreach ( const QString& key, infos.keys() ) {
map[key] = infos[key].toString();
}
mProvider->requestPage( KUrl( url ), id, map );
++mRequests;
}
void ComicProviderWrapper::requestRedirectedUrl( const QString &url, int id, const QVariantMap &infos )
{
QMap<QString, QString> map;
foreach ( const QString& key, infos.keys() ) {
map[key] = infos[key].toString();
}
mProvider->requestRedirectedUrl( KUrl( url ), id, map );
++mRequests;
}
bool ComicProviderWrapper::functionCalled() const
{
return mFuncFound;
}
QVariant ComicProviderWrapper::callFunction( const QString &name, const QVariantList &args )
{
if ( mAction ) {
mFuncFound = mFunctions.contains( name );
if ( mFuncFound ) {
return mAction->callFunction( name, args );
}
}
return QVariant();
}
void ComicProviderWrapper::combine( const QVariant &image, PositionType position )
{
if (!mKrossImage) {
return;
}
QImage header;
if ( image.type() == QVariant::String ) {
const QString path( mPackage->filePath( "images", image.toString() ) );
if ( QFile::exists( path ) ) {
header = QImage( path );
} else {
return;
}
} else {
ImageWrapper* img = qobject_cast<ImageWrapper*>( image.value<QObject*>() );
if ( img ) {
header = img->image();
} else {
return;
}
}
const QImage comic = mKrossImage->image();
int height = 0;
int width = 0;
switch ( position ) {
case Top:
case Bottom:
height = header.height() + comic.height();
width = ( header.width() >= comic.width() ) ? header.width() : comic.width();
break;
case Left:
case Right:
height = ( header.height() >= comic.height() ) ? header.height() : comic.height();
width = header.width() + comic.width();
break;
}
QImage img = QImage( QSize( width, height ), QImage::Format_RGB32 );
img.fill( header.pixel( QPoint( 0, 0 ) ) );
QPainter painter( &img );
// center and draw the Images
QPoint headerPos;
QPoint comicPos;
switch ( position ) {
case Top:
headerPos = QPoint( ( ( width - header.width() ) / 2 ), 0 );
comicPos = QPoint( ( ( width - comic.width() ) / 2 ), header.height() );
break;
case Bottom:
headerPos = QPoint( ( ( width - header.width() ) / 2 ), comic.height() );
comicPos = QPoint( ( ( width - comic.width() ) / 2 ), 0 );
break;
case Left:
headerPos = QPoint( 0, ( ( height - header.height() ) / 2 ) );
comicPos = QPoint( header.width(), ( ( height - comic.height() ) / 2 ) );
break;
case Right:
headerPos = QPoint( comic.width(), ( ( height - header.height() ) / 2 ) );
comicPos = QPoint( 0, ( ( height - comic.height() ) / 2 ) );
break;
}
painter.drawImage( headerPos, header );
painter.drawImage( comicPos, comic );
mKrossImage->setImage( img );
}
QObject* ComicProviderWrapper::image()
{
return qobject_cast<QObject*>( mKrossImage );
}
#include "moc_comicproviderwrapper.cpp"

View file

@ -1,288 +0,0 @@
/*
* Copyright (C) 2008 Petri Damstén <damu@iki.fi>
* Copyright (C) 2010 Matthias Fuchs <mat69@gmx.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef COMICPROVIDERWRAPPER_H
#define COMICPROVIDERWRAPPER_H
#include "comicprovider.h"
#include <QBuffer>
#include <QImage>
#include <QImageReader>
#include <QByteArray>
namespace Kross {
class Action;
}
namespace Plasma {
class Package;
}
class ComicProviderKross;
class ImageWrapper : public QObject
{
Q_OBJECT
Q_PROPERTY( QImage image READ image WRITE setImage )
Q_PROPERTY( QByteArray rawData READ rawData WRITE setRawData )
public:
explicit ImageWrapper( QObject *parent = 0, const QByteArray &image = QByteArray() );
QImage image() const;
/**
* Sets the image, rawData is changed to the new set image
*/
void setImage( const QImage &image );
QByteArray rawData() const;
/**
* Sets the rawData, image is changed to the new rawData
*/
void setRawData( const QByteArray &rawData );
public slots:
/**
* Returns the numbers of images contained in the image
* 0 if there is just one image, > 0 if the image format supports animation (the number of frames),
* -1 if there was an error
* @since 4600
*/
int imageCount() const;
/**
* Returns an image, if it did not work an null image is returned
* For animations returns the next frame upon each call, if there are no frames left returns a null image
* @see imageCount()
* @since 4600
*/
QImage read();
private:
void resetImageReader();
private:
QImage mImage;
mutable QByteArray mRawData;
QBuffer mBuffer;
QImageReader mImageReader;
};
class DateWrapper : public QObject
{
Q_OBJECT
Q_PROPERTY( QDate date READ date WRITE setDate )
public:
explicit DateWrapper( QObject *parent = 0, const QDate &date = QDate() );
QDate date() const;
void setDate( const QDate &date );
static QDate fromVariant( const QVariant &variant );
public slots:
QObject* addDays( int ndays );
QObject* addMonths( int nmonths );
QObject* addYears( int nyears );
int day() const;
int dayOfWeek() const;
int dayOfYear() const;
int daysInMonth() const;
int daysInYear() const;
int daysTo( const QVariant d ) const;
bool isNull() const;
bool isValid() const;
int month() const;
bool setDate( int year, int month, int day );
int toJulianDay() const;
QString toString( const QString &format ) const;
QString toString( int format = 0 ) const;
int weekNumber() const;
int year() const;
private:
QDate mDate;
};
class StaticDateWrapper : public QObject
{
Q_OBJECT
Q_ENUMS( DateType )
public:
enum DateType {
TextDate = Qt::TextDate,
ISODate = Qt::ISODate,
SystemLocaleShortDate = Qt::SystemLocaleShortDate,
SystemLocaleLongDate = Qt::SystemLocaleLongDate,
DefaultLocaleShortDate = Qt::DefaultLocaleShortDate,
DefaultLocaleLongDate = Qt::DefaultLocaleLongDate
};
StaticDateWrapper( QObject *parent = 0 );
public slots:
QObject* currentDate();
QObject* fromJulianDay( int jd );
QObject* fromString( const QString & string, int format = Qt::TextDate );
QObject* fromString( const QString & string, const QString & format );
bool isLeapYear ( int year );
bool isValid ( int year, int month, int day );
QString longDayName ( int weekday );
QString longMonthName ( int month );
QString shortDayName ( int weekday );
QString shortMonthName ( int month );
};
class ComicProviderWrapper : public QObject
{
Q_OBJECT
Q_ENUMS( IdentifierType )
Q_ENUMS( RequestType )
Q_ENUMS( PositionType )
Q_ENUMS( RedirectedUrlType )
Q_PROPERTY( bool identifierSpecified READ identifierSpecified )
Q_PROPERTY( QString textCodec READ textCodec WRITE setTextCodec )
Q_PROPERTY( QString comicAuthor READ comicAuthor WRITE setComicAuthor )
Q_PROPERTY( QString websiteUrl READ websiteUrl WRITE setWebsiteUrl )
Q_PROPERTY( QString shopUrl READ shopUrl WRITE setShopUrl )
Q_PROPERTY( QString title READ title WRITE setTitle )
Q_PROPERTY( QString additionalText READ additionalText WRITE setAdditionalText )
Q_PROPERTY( QVariant identifier READ identifier WRITE setIdentifier )
Q_PROPERTY( QVariant nextIdentifier READ nextIdentifier WRITE setNextIdentifier )
Q_PROPERTY( QVariant previousIdentifier READ previousIdentifier WRITE setPreviousIdentifier )
Q_PROPERTY( QVariant firstIdentifier READ firstIdentifier WRITE setFirstIdentifier )
Q_PROPERTY( QVariant lastIdentifier READ lastIdentifier WRITE setLastIdentifier )
Q_PROPERTY( bool isLeftToRight READ isLeftToRight WRITE setLeftToRight )
Q_PROPERTY( bool isTopToBottom READ isTopToBottom WRITE setTopToBottom )
Q_PROPERTY( int apiVersion READ apiVersion )
public:
enum PositionType {
Left = 0,
Top,
Right,
Bottom
};
enum RequestType {
Page = ComicProvider::Page,
Image = ComicProvider::Image,
User = ComicProvider::User
};
enum IdentifierType {
DateIdentifier = ComicProvider::DateIdentifier,
NumberIdentifier = ComicProvider::NumberIdentifier,
StringIdentifier = ComicProvider::StringIdentifier
};
enum RedirectedUrlType {
PreviousUrl = 0,
CurrentUrl = 1,
NextUrl = 2,
FirstUrl = 3,
LastUrl = 4,
UserUrl = 10
};
ComicProviderWrapper( ComicProviderKross *parent );
~ComicProviderWrapper();
int apiVersion() const { return 4600; }
ComicProvider::IdentifierType identifierType() const;
QImage comicImage();
void pageRetrieved( int id, const QByteArray &data );
void pageError( int id, const QString &message );
void redirected( int id, const KUrl &newUrl );
bool identifierSpecified() const;
QString textCodec() const;
void setTextCodec( const QString &textCodec );
QString comicAuthor() const;
void setComicAuthor( const QString &author );
QString websiteUrl() const;
void setWebsiteUrl( const QString &websiteUrl );
QString shopUrl() const;
void setShopUrl( const QString &shopUrl );
QString title() const;
void setTitle( const QString &title );
QString additionalText() const;
void setAdditionalText( const QString &additionalText );
QVariant identifier();
void setIdentifier( const QVariant &identifier );
QVariant nextIdentifier();
void setNextIdentifier( const QVariant &nextIdentifier );
QVariant previousIdentifier();
void setPreviousIdentifier( const QVariant &previousIdentifier );
QVariant firstIdentifier();
void setFirstIdentifier( const QVariant &firstIdentifier );
QVariant lastIdentifier();
void setLastIdentifier( const QVariant &lastIdentifier );
bool isLeftToRight() const;
void setLeftToRight( bool ltr );
bool isTopToBottom() const;
void setTopToBottom( bool ttb );
QVariant identifierVariant() const;
QVariant firstIdentifierVariant() const;
QVariant lastIdentifierVariant() const;
QVariant nextIdentifierVariant() const;
QVariant previousIdentifierVariant() const;
public slots:
void finished() const;
void error() const;
void requestPage( const QString &url, int id, const QVariantMap &infos = QVariantMap() );
void requestRedirectedUrl( const QString &url, int id, const QVariantMap &infos = QVariantMap() );
void combine( const QVariant &image, PositionType position = Top );
QObject* image();
void init();
protected:
QVariant callFunction( const QString &name, const QVariantList &args = QVariantList() );
const QStringList& extensions() const;
bool functionCalled() const;
QVariant identifierToScript( const QVariant &identifier );
QVariant identifierFromScript( const QVariant &identifier ) const;
void setIdentifierToDefault();
void checkIdentifier( QVariant *identifier );
private:
Kross::Action *mAction;
ComicProviderKross *mProvider;
QStringList mFunctions;
bool mFuncFound;
ImageWrapper *mKrossImage;
static QStringList mExtensions;
Plasma::Package *mPackage;
QByteArray mTextCodec;
QString mWebsiteUrl;
QString mShopUrl;
QString mTitle;
QString mAdditionalText;
QVariant mIdentifier;
QVariant mNextIdentifier;
QVariant mPreviousIdentifier;
QVariant mFirstIdentifier;
QVariant mLastIdentifier;
int mRequests;
bool mIdentifierSpecified;
bool mIsLeftToRight;
bool mIsTopToBottom;
};
#endif

View file

@ -1,119 +0,0 @@
[Desktop Entry]
Name=Comic Strips
Name[ar]=شرائط هزلية
Name[ast]=Tires de cómic
Name[bs]=Smiješni stripovi
Name[ca]=Tires còmiques
Name[ca@valencia]=Tires còmiques
Name[cs]=Komiksové proužky
Name[da]=Tegneseriestriber
Name[de]=Comics
Name[el]=Σειρές κόμικ
Name[en_GB]=Comic Strips
Name[es]=Tiras de cómic
Name[et]=Koomiksid
Name[eu]=Komiki zerrendak
Name[fi]=Sarjakuvat
Name[fr]=Bandes dessinées
Name[ga]=Stiallchartúin
Name[gl]=Banda deseñada
Name[he]=רצועות הקומיקס
Name[hr]=Stripovi
Name[hu]=Képregények
Name[is]=Myndasögur
Name[it]=Strisce di fumetti
Name[ja]=
Name[kk]=Комикстер
Name[km]=
Name[ko]=
Name[ku]=Pirtûkên Qerfî
Name[lv]=Komiksu lentas
Name[mr]=ि
Name[nb]=Tegneserier
Name[nds]=Comics
Name[nl]=Stripverhalen
Name[nn]=Teikneseriar
Name[pa]=ਿ
Name[pl]=Komiksy
Name[pt]=Bandas Desenhadas
Name[pt_BR]=Tirinhas
Name[ro]=Benzi desenate
Name[ru]=Комиксы
Name[sk]=Komiksy
Name[sl]=Smešni stripi
Name[sr]=стрипови
Name[sr@ijekavian]=стрипови
Name[sr@ijekavianlatin]=stripovi
Name[sr@latin]=stripovi
Name[sv]=Tecknad serie
Name[th]=
Name[tr]=Çizgi Romanlar
Name[uk]=Комічна стрічка
Name[wa]=Bindes d' imådje
Name[x-test]=xxComic Stripsxx
Name[zh_CN]=
Name[zh_TW]=
Comment=Online comic strips
Comment[ar]=شرائط هزلية على الويب
Comment[ast]=Tires de cómic en rede
Comment[bs]=Smiješni stripovi na vezi
Comment[ca]=Tires còmiques en línia
Comment[ca@valencia]=Tires còmiques en línia
Comment[cs]=Online komiksové proužky
Comment[da]=Online tegneseriestriber.
Comment[de]=Online-Comics
Comment[el]=Διαδικτυακές σειρές κόμικ
Comment[en_GB]=Online comic strips
Comment[es]=Tiras de cómic en red
Comment[et]=Internetikoomiksid
Comment[fi]=Verkkosarjakuvat
Comment[fr]=Bandes dessinées « En ligne »
Comment[ga]=Stiallchartúin ar líne
Comment[gl]=Bandas deseñadas en liña
Comment[hr]=Stripovi na Internetu
Comment[hu]=Online képregények
Comment[is]=Myndasögur á netinu
Comment[it]=Strisce di fumetti in rete
Comment[ja]=
Comment[kk]=Онлайн комикстер
Comment[km]=
Comment[ko]=
Comment[lv]=Tiešsaistes komiksu lentas
Comment[mr]= ि
Comment[nb]=Tegneserier på nettet
Comment[nds]=Internet-Comics
Comment[nl]=Online stripverhalen
Comment[nn]=Teikneseriar på nettet
Comment[pa]= ਿ
Comment[pl]=Komiksy online
Comment[pt]=Bandas desenhadas 'online'
Comment[pt_BR]=Tirinhas online
Comment[ro]=Benzi desenate online
Comment[ru]=Стрипы комиксов из сети
Comment[sk]=Online komiksy
Comment[sl]=Spletni smešni stripi
Comment[sr]=Стрипови на вези
Comment[sr@ijekavian]=Стрипови на вези
Comment[sr@ijekavianlatin]=Stripovi na vezi
Comment[sr@latin]=Stripovi na vezi
Comment[sv]=Tecknade serier på nätet
Comment[th]=
Comment[tr]=Çevrimiçi çizgi romanlar
Comment[uk]=Мережеві стрічки коміксів
Comment[wa]=Bindes d' imådjes so fyis
Comment[x-test]=xxOnline comic stripsxx
Comment[zh_CN]=线
Comment[zh_TW]=
X-KDE-ServiceTypes=Plasma/DataEngine
Type=Service
Icon=face-smile-big
X-KDE-Library=plasma_engine_comic
X-KDE-PluginInfo-Author=
X-KDE-PluginInfo-Email=
X-KDE-PluginInfo-Name=comic
X-KDE-PluginInfo-Version=
X-KDE-PluginInfo-Website=
X-KDE-PluginInfo-Category=
X-KDE-PluginInfo-Depends=

View file

@ -1,123 +0,0 @@
[Desktop Entry]
Name=Comic
Name[ar]=Comic
Name[ast]=Cómic
Name[bs]=Comic
Name[ca]=Còmic
Name[ca@valencia]=Còmic
Name[cs]=Komiks
Name[da]=Tegneserie
Name[de]=Comic
Name[el]=Κόμικ
Name[en_GB]=Comic
Name[es]=Cómic
Name[et]=Koomiks
Name[eu]=Komikia
Name[fi]=Sarjakuva
Name[fr]=Bande dessinée
Name[ga]=Stiallchartún
Name[gl]=Cómic
Name[he]=קומיקס
Name[hr]=Strip
Name[hu]=Képregény
Name[is]=Comic
Name[it]=Fumetto
Name[ja]=
Name[kk]=Комикс
Name[km]=
Name[ko]=
Name[ku]=Pirtûka Qerfî
Name[lv]=Komikss
Name[mr]=ि
Name[nb]=Tegneserie
Name[nds]=Comic
Name[nl]=Stripverhaal
Name[nn]=Teikneserie
Name[pa]=ਿ
Name[pl]=Komiks
Name[pt]=Banda Desenhada
Name[pt_BR]=Tirinha
Name[ro]=Benzi desenate
Name[ru]=Комикс
Name[sk]=Komiks
Name[sl]=Strip
Name[sq]=Komike
Name[sr]=стрип
Name[sr@ijekavian]=стрип
Name[sr@ijekavianlatin]=strip
Name[sr@latin]=strip
Name[sv]=Serie
Name[th]=
Name[tr]=Çizgi Roman
Name[uk]=Комікси
Name[wa]=Binde d' imådje
Name[x-test]=xxComicxx
Name[zh_CN]=
Name[zh_TW]=
Comment=Comic Package Structure
Comment[ar]=بنية حزمة Comic
Comment[ast]=Cadarma del paquete de cómics
Comment[bs]=Struktura paketa stripova
Comment[ca]=Estructura de paquet de còmic
Comment[ca@valencia]=Estructura de paquet de còmic
Comment[cs]=Struktura komiksového balíčku
Comment[da]=Tegneseriepakkestruktur
Comment[de]=Comic-Paketstruktur
Comment[el]=Δομή πακέτου κόμικ
Comment[en_GB]=Comic Package Structure
Comment[es]=Estructura del paquete de cómics
Comment[et]=Koomiksipaketi struktuur
Comment[eu]=Komiki paketearen egitura
Comment[fi]=Sarjakuvapaketin rakenne
Comment[fr]=Structure de paquet de bandes dessinées
Comment[ga]=Struchtúr Pacáiste Comic
Comment[gl]=Estrutura de paquete cómic
Comment[he]=מבנה חבילה של הקומיקס
Comment[hr]=Struktura pakiranja stripa
Comment[hu]=Képregénycsomag-struktúra
Comment[is]=Uppbygging Comic pakka
Comment[it]=Struttura pacchetto fumetto
Comment[ja]=
Comment[kk]=Комикс десте құрылымы
Comment[km]=
Comment[ko]=
Comment[ku]=Avahiya Pakêtê Pirtûkên Qerfî
Comment[lv]=Komiksa pakotnes struktūra
Comment[mr]=ि
Comment[nb]=Pakkestruktur for tegneserie
Comment[nds]=Comic-Paketstruktuur
Comment[nl]=Stripboek-pakketstructuur
Comment[nn]=Pakkestruktur for teikneserie
Comment[pa]=ਿ
Comment[pl]=Struktura pakietu komiksu
Comment[pt]=Estrutura do Pacote de Banda Desenhada
Comment[pt_BR]=Estrutura do pacote de tirinha
Comment[ro]=Structură pachet de benzi desenate
Comment[ru]=Структура пакета комиксов
Comment[sk]=Štruktúra komiksového balíčka
Comment[sl]=Zgradba paketa s stripom
Comment[sr]=Структура пакета за стрипове
Comment[sr@ijekavian]=Структура пакета за стрипове
Comment[sr@ijekavianlatin]=Struktura paketa za stripove
Comment[sr@latin]=Struktura paketa za stripove
Comment[sv]=Seriens paketstruktur
Comment[th]=
Comment[tr]=Çizgi Roman Paket Yapısı
Comment[uk]=Структура пакунка коміксів
Comment[wa]=Sitructeure do pacaedje del binde d' imådje
Comment[x-test]=xxComic Package Structurexx
Comment[zh_CN]=
Comment[zh_TW]=
Type=Service
X-KDE-ServiceTypes=Plasma/PackageStructure
X-KDE-Library=plasma_packagestructure_comic
X-KDE-PluginInfo-Author=Petri Damstén
X-KDE-PluginInfo-Email=damu@iki.fi
X-KDE-PluginInfo-Name=comic
X-KDE-PluginInfo-Version=pre0.1
X-KDE-PluginInfo-Website=http://plasma.kde.org/
X-KDE-PluginInfo-License=GPLv2+
X-KDE-PluginInfo-EnabledByDefault=true
X-Plasma-PackageFileFilter=*.comic
X-Plasma-PackageFileMimetypes=application/zip

View file

@ -1,22 +0,0 @@
#ifndef PLASMA_COMIC_EXPORT_H
#define PLASMA_COMIC_EXPORT_H
/* needed for KDE_EXPORT macros */
#include <kdemacros.h>
#if defined _WIN32 || defined _WIN64
#ifndef PLASMA_COMIC_EXPORT
# ifdef MAKE_PLASMACOMICPROVIDERCORE_LIB
# define PLASMA_COMIC_EXPORT KDE_EXPORT
# else
# define PLASMA_COMIC_EXPORT KDE_IMPORT
# endif
#endif
#else /* UNIX*/
/* export statements for unix */
#define PLASMA_COMIC_EXPORT KDE_EXPORT
#endif
#endif

View file

@ -1,63 +0,0 @@
[Desktop Entry]
Type=ServiceType
X-KDE-ServiceType=Plasma/Comic
Comment=Plugin for Plasma Comic Engine
Comment[ar]=ملحق لمحرك Comic
Comment[ast]=Complementu pal motor de cómics de Plasma
Comment[bs]=Dodatak za plazma pogon za stripove
Comment[ca]=Connector per al motor de còmics del plasma
Comment[ca@valencia]=Connector per al motor de còmics del plasma
Comment[cs]=Modul pro Plasma komiksy
Comment[da]=Plugin til Plasmas tegneseriemotor
Comment[de]=Modul für den Plasma-Comic-Datentreiber
Comment[el]=Πρόσθετο της μηχανής κόμικ Plasma
Comment[en_GB]=Plugin for Plasma Comic Engine
Comment[es]=Complemento para el motor de cómics de Plasma
Comment[et]=Plasma koomiksite mootori plugin
Comment[eu]=Plasma komiki motorearentzako plugina
Comment[fi]=Sarjakuvatietomoottorin liitännäinen
Comment[fr]=Module externe pour le moteur Plasma de bandes dessinées
Comment[ga]=Breiseán le haghaidh inneall stiallchartún Plasma
Comment[gl]=Extensión para o motor de Cómics de Plasma
Comment[he]=פלאגין של מנוע הקומיקסים עבור Plasma
Comment[hr]=Priključak za Plasmin stripovni mehanizam
Comment[hu]=Plazma képregénykezelő-bővítmény
Comment[is]=Íforrit fyrir Comic plasmavél
Comment[it]=Estensione per il motore di fumetti di Plasma
Comment[ja]=Plasma
Comment[kk]=Plasma комикс тетігінің плагині
Comment[km]= Plasma
Comment[ko]=Plasma
Comment[ku]=Pêvek ji bo Motora Pirtûka Qerfî yê Plasma
Comment[lv]=Spraudnis Plasma komiksu dzinējam
Comment[mr]= ि िि
Comment[nb]=Programtillegg for Plasma-motor for tegneserier
Comment[nds]=Moduul för den Plasma-Datenkarn
Comment[nl]=Plug-in voor Plasma-stripboek-gegevensengine
Comment[nn]=Programtillegg for teikneseriar
Comment[pa]= ਿ
Comment[pl]=Wtyczka silnika danych komiksów
Comment[pt]='Plugin' do Motor de Banda Desenhada do Plasma
Comment[pt_BR]=Plugin para o mecanismo das tirinhas do Plasma
Comment[ro]=Modul pentru Motorul de benzi desenate Plasma
Comment[ru]=Модуль для движка Plasma Comic
Comment[sk]=Modul pre Plasma komiksy
Comment[sl]=Vstavek za pogon za smešen strip
Comment[sr]=Прикључак за Плазминог мотор стрипова
Comment[sr@ijekavian]=Прикључак за Плазминог мотор стрипова
Comment[sr@ijekavianlatin]=Priključak za Plasminog motor stripova
Comment[sr@latin]=Priključak za Plasminog motor stripova
Comment[sv]=Insticksprogram för Plasma seriegränssnitt
Comment[th]=
Comment[tr]=Plasma Çizgi Roman Motoru için Eklenti
Comment[uk]=Додаток для джерела жартів Плазми
Comment[wa]=Tchôke-divins po l' éndjin Plasma des bindes d' imådjes
Comment[x-test]=xxPlugin for Plasma Comic Enginexx
Comment[zh_CN]=Plasma
Comment[zh_TW]=Plasma
[PropertyDef::X-KDE-PlasmaComicProvider-SuffixType]
Type=QString
[PropertyDef::X-KDE-PluginInfo-Name]
Type=QString

View file

@ -1,7 +1,3 @@
find_package(KDE4 4.14.3 REQUIRED)
include(KDE4Defaults)
add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
include_directories(
${CMAKE_BINARY_DIR}
${KDE4_INCLUDE_DIR}