diff --git a/README.PACKAGERS b/README.PACKAGERS index 97fce50baf2de865a05eb8885c9f09918950087e..dcf4efc89f0fb1c0bad5e14287575505d13abf47 100644 --- a/README.PACKAGERS +++ b/README.PACKAGERS @@ -1 +1,6 @@ -You might want to distribute the files at $KDEDIR/share/apps/palapeli/collection/*.puzzle in a separate data package. These are the default puzzle files, which are quite big, but change only seldomly. \ No newline at end of file +You might want to distribute the files at $KDEDIR/share/apps/palapeli/collection/*.{desktop,jpg} in a separate data package. + +Changelog for packagers +----------------------- + +Version 1.0 -> 1.1: If you have previously distributed libpala-puzzlebuilder in some development package, this is the right moment to move it to the main palapeli package, because Palapeli needs this tool to build its default puzzles on first run. diff --git a/puzzles/CMakeLists.txt b/puzzles/CMakeLists.txt index 777f5c07effcee38b081a3a77c09d814e63216f5..38659c502ce5fe7cb7451dfbecfab6636ae7547a 100644 --- a/puzzles/CMakeLists.txt +++ b/puzzles/CMakeLists.txt @@ -1,9 +1,14 @@ install(FILES - castle-maintenon.puzzle - cincinnati-bridge.puzzle - citrus-fruits.puzzle - european-honey-bee.puzzle - panther-chameleon-female.puzzle + castle-maintenon.desktop + castle-maintenon.jpg + cincinnati-bridge.desktop + cincinnati-bridge.jpg + citrus-fruits.desktop + citrus-fruits.jpg + european-honey-bee.desktop + european-honey-bee.jpg + panther-chameleon-female.desktop + panther-chameleon-female.jpg DESTINATION ${DATA_INSTALL_DIR}/palapeli/collection) install(FILES diff --git a/puzzles/castle-maintenon.puzzle b/puzzles/castle-maintenon.puzzle deleted file mode 100644 index 2a2654cacf8ced74f91c47001f1664f646f83a62..0000000000000000000000000000000000000000 Binary files a/puzzles/castle-maintenon.puzzle and /dev/null differ diff --git a/puzzles/cincinnati-bridge.puzzle b/puzzles/cincinnati-bridge.puzzle deleted file mode 100644 index 85724ad6d31f821d10495317e819c44a0b6b190e..0000000000000000000000000000000000000000 Binary files a/puzzles/cincinnati-bridge.puzzle and /dev/null differ diff --git a/puzzles/citrus-fruits.puzzle b/puzzles/citrus-fruits.puzzle deleted file mode 100644 index 6cb83719a0e4a55e26df2a01a122d252ac343887..0000000000000000000000000000000000000000 Binary files a/puzzles/citrus-fruits.puzzle and /dev/null differ diff --git a/puzzles/european-honey-bee.puzzle b/puzzles/european-honey-bee.puzzle deleted file mode 100644 index 2d21b0a8328874c999b694de24446203d34ac4e5..0000000000000000000000000000000000000000 Binary files a/puzzles/european-honey-bee.puzzle and /dev/null differ diff --git a/puzzles/make-puzzles.sh b/puzzles/make-puzzles.sh deleted file mode 100644 index 0dd14232e432736c93ac4935acb703d661feff62..0000000000000000000000000000000000000000 --- a/puzzles/make-puzzles.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -for MANIFEST in *.desktop; do - TARGET=$(basename $MANIFEST .desktop).puzzle - echo "Creating $TARGET" - libpala-puzzlebuilder $MANIFEST $TARGET -done diff --git a/puzzles/panther-chameleon-female.puzzle b/puzzles/panther-chameleon-female.puzzle deleted file mode 100644 index 0bd8d300c5c230756b6a071e1ff11c2e05fbcf4f..0000000000000000000000000000000000000000 Binary files a/puzzles/panther-chameleon-female.puzzle and /dev/null differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 46e9aafe3935e9dfafdc9240ad805f5eff012216..434055d55bbc0849cb8b23f8c37dfa854c1d1be4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,6 +30,7 @@ set(palapeli_SRCS file-io/collection-list.cpp file-io/collection-view.cpp file-io/puzzle.cpp + firsttimehelper.cpp importhelper.cpp main.cpp window/collectionwidget.cpp diff --git a/src/firsttimehelper.cpp b/src/firsttimehelper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..737c6381162a7e28ed03195deb740fa38f58b766 --- /dev/null +++ b/src/firsttimehelper.cpp @@ -0,0 +1,135 @@ +/*************************************************************************** + * Copyright 2009, 2010 Stefan Majewsky + * + * 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 "firsttimehelper.h" +#include "window/mainwindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//NOTE: A local copy of Palapeli::ListCollection::readUrl, with an extension to resolve local URLs. +static KUrl resolveUrl(const KUrl& url, bool local) +{ + if (url.protocol() == "palapeli") + { + //resolve special URLs with KStandardDirs + QString path = url.path(KUrl::RemoveTrailingSlash); + if (path.startsWith('/')) + path.remove(0, 1); + return KUrl(local ? KStandardDirs::locateLocal("appdata", path) : KStandardDirs::locate("appdata", path)); + } + else + return url; +} + +Palapeli::FirstTimeHelper::FirstTimeHelper() + : m_bar(0) +{ + //open config, read puzzles + KConfig config("palapeli-collectionrc", KConfig::CascadeConfig); + KConfigGroup mainGroup(&config, "Palapeli Collection"); + const QStringList puzzleIds = mainGroup.groupList(); + foreach (const QString& puzzleId, puzzleIds) + { + KConfigGroup puzzleGroup(&mainGroup, puzzleId); + const KUrl barePuzzleUrl = puzzleGroup.readEntry("Location", KUrl()); + //generate name of corresponding .desktop file + QString desktopFileName = barePuzzleUrl.fileName(); + desktopFileName.replace(QRegExp("\\.puzzle$"), QLatin1String(".desktop")); + KUrl bareDesktopUrl(barePuzzleUrl); + bareDesktopUrl.setFileName(desktopFileName); + //if desktop file does not exist, we cannot do anything + const KUrl puzzleUrl = resolveUrl(barePuzzleUrl, false); + const KUrl desktopUrl = resolveUrl(bareDesktopUrl, false); + if (desktopUrl.isEmpty()) + continue; + //if puzzle file does not exist or is older than desktop file (e.g. because of translation update), schedule update + if (puzzleUrl.isEmpty() || (QFileInfo(puzzleUrl.path()).lastModified() < QFileInfo(desktopUrl.path()).lastModified())) + { + const KUrl localPuzzleUrl = resolveUrl(barePuzzleUrl, true); + Task task = { desktopUrl, localPuzzleUrl }; + m_tasks << task; + } + } +} + +bool Palapeli::FirstTimeHelper::isNecessary() const +{ + return !m_tasks.isEmpty(); +} + +void Palapeli::FirstTimeHelper::execute() +{ + //create a progress dialog + QWidget* widget = new QWidget; + widget->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); + connect(this, SIGNAL(done()), widget, SLOT(deleteLater())); + QGridLayout* layout = new QGridLayout; + widget->setLayout(layout); + QLabel* icon = new QLabel; + QLabel* label = new QLabel(i18nc("content of first-run wizard (which behaves more like a splashscreen in fact, i.e. no user interaction)", "Palapeli first-run and update wizardCreating default puzzles...This needs to be done only once."), widget); +// label2->setWordWrap(true); + m_bar = new QProgressBar(widget); + layout->addWidget(icon, 0, 0, 2, 1); + layout->addWidget(label, 0, 1); + layout->addWidget(m_bar, 1, 1); + const int iconSize = layout->sizeHint().height() - layout->contentsMargins().top() - layout->contentsMargins().bottom(); + icon->setPixmap(KIcon("palapeli").pixmap(iconSize)); + icon->setFixedSize(QSize(iconSize, iconSize)); + m_bar->setMinimum(0); + m_bar->setMaximum(m_tasks.count() + 1); //do not let the bar reach 100% while it is visible + m_bar->setValue(0); + widget->show(); + QTimer::singleShot(0, this, SLOT(next())); +} + +void Palapeli::FirstTimeHelper::next() +{ + if (m_tasks.isEmpty()) + { + //done + emit done(); + (new Palapeli::MainWindow(KCmdLineArgs::parsedArgs()))->show(); + deleteLater(); + return; + } + m_bar->setValue(m_bar->value() + 1); + //create next puzzle + Task task = m_tasks.takeFirst(); + QProcess* process = new QProcess; + QFileInfo desktopFile(task.desktopUrl.path()); + process->setWorkingDirectory(desktopFile.dir().absolutePath()); + QStringList args; + args << desktopFile.fileName() << task.puzzleUrl.path(); + process->start("libpala-puzzlebuilder", args); + connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(next())); +} + +#include "firsttimehelper.moc" diff --git a/src/firsttimehelper.h b/src/firsttimehelper.h new file mode 100644 index 0000000000000000000000000000000000000000..bfdd5cb8ab0856e3477af0f25d823da738983cd4 --- /dev/null +++ b/src/firsttimehelper.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright 2009, 2010 Stefan Majewsky + * + * 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 PALAPELI_FIRSTTIMEHELPER_H +#define PALAPELI_FIRSTTIMEHELPER_H + +#include +class QProgressBar; +#include + +namespace Palapeli +{ + ///This whole class is a hack, which I only implement at all because feature freeze is just 5.5 hours from now. + ///It checks the standard collection, and if some puzzles have not yet been built, it calls libpala-puzzlebuilder to build them. + ///TODO: Of course, the right way would be to implement this feature directly in the collection, but this will have to wait until Palapeli 1.2 because of aforementioned feature freeze. + class FirstTimeHelper : public QObject + { + Q_OBJECT + public: + FirstTimeHelper(); + bool isNecessary() const; + public Q_SLOTS: + void execute(); + private Q_SLOTS: + void next(); + Q_SIGNALS: + void done(); + private: + struct Task + { + KUrl desktopUrl, puzzleUrl; + }; + QList m_tasks; + QProgressBar* m_bar; + }; +} + +#endif // PALAPELI_FIRSTTIMEHELPER_H diff --git a/src/main.cpp b/src/main.cpp index 0a7e8ca4510219171830023f8c7dfb93ea6097aa..ba5903672ebfdff1f39f378c5a52ae01946d1fed 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright 2009 Stefan Majewsky + * Copyright 2009, 2010 Stefan Majewsky * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public @@ -16,10 +16,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ***************************************************************************/ +#include "firsttimehelper.h" #include "importhelper.h" #include "window/mainwindow.h" #include +#include #include #include #include @@ -48,7 +50,16 @@ int main(int argc, char** argv) //perform import request new Palapeli::ImportHelper(args); else + { //no import request, show main window - (new Palapeli::MainWindow(args))->show(); + Palapeli::FirstTimeHelper* helper = new Palapeli::FirstTimeHelper; + if (helper->isNecessary()) + QTimer::singleShot(0, helper, SLOT(execute())); + else + { + delete helper; + (new Palapeli::MainWindow(args))->show(); + } + } return app.exec(); }