File indexing completed on 2024-05-19 04:07:53

0001 /*
0002     SPDX-FileCopyrightText: 2009-2011 Stefan Majewsky <majewsky@gmx.net>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "components.h"
0008 #include <Pala/Slicer>
0009 #include <Pala/SlicerJob>
0010 #include <Pala/SlicerMode>
0011 
0012 #include <KPluginFactory>
0013 #include <KPluginMetaData>
0014 
0015 Palapeli::PuzzleComponent* Palapeli::CreationContextComponent::cast(Type type) const
0016 {
0017     //just a short-hand
0018     const Palapeli::PuzzleCreationContext& cc = creationContext;
0019     //metadata is in creationContext (except for piece count which needs to be
0020     //inferred from contents)
0021     if (type == Palapeli::PuzzleComponent::Metadata)
0022     {
0023         Palapeli::PuzzleMetadata metadata(cc);
0024         const Palapeli::PuzzleComponent* cmp = puzzle()->get(Contents);
0025         const Palapeli::ContentsComponent* cmp2 = dynamic_cast<const Palapeli::ContentsComponent*>(cmp);
0026         metadata.pieceCount = cmp2 ? cmp2->contents.pieces.count() : -1;
0027         return new Palapeli::MetadataComponent(metadata);
0028     }
0029     //contents can be built
0030     else if (type == Palapeli::PuzzleComponent::Contents)
0031     {
0032         //TODO: move slicer instantiation to a location that is shared between
0033         //      puzzle creator dialog and this function
0034         //find slicer
0035         const QList<KPluginMetaData> offers = KPluginMetaData::findPlugins(QStringLiteral("palapelislicers"), [cc](const KPluginMetaData &m) {
0036             return m.pluginId() == cc.slicer;
0037         });
0038         if (offers.isEmpty())
0039         {
0040             CAST_ERROR(QString::fromLatin1("Could not find slicer \"%1\".").arg(cc.slicer));
0041             return nullptr;
0042         }
0043         //initialize requested slicer plugin
0044         std::unique_ptr<Pala::Slicer> slicer;
0045         if (auto plugin = KPluginFactory::instantiatePlugin<Pala::Slicer>(offers.first(), nullptr).plugin) {
0046             slicer.reset(plugin);
0047         } else {
0048             return nullptr;
0049         }
0050         //create job
0051         Pala::SlicerJob job(cc.image, cc.slicerArgs);
0052         if (!cc.slicerMode.isEmpty())
0053         {
0054             const auto modes = slicer->modes();
0055             for (const Pala::SlicerMode* mode : modes)
0056                 if (mode->key() == cc.slicerMode)
0057                 {
0058                     job.setMode(mode);
0059                     break;
0060                 }
0061             if (!job.mode())
0062             {
0063                 CAST_ERROR(QString::fromLatin1("Could not find slicer mode \"%1\".").arg(QString::fromUtf8(cc.slicerMode)));
0064                 return nullptr;
0065             }
0066         }
0067         //do slicing
0068         if (!slicer->process(&job))
0069         {
0070             CAST_ERROR(QString::fromLatin1("Slicing failed because of undetermined problems."));
0071             return nullptr;
0072         }
0073         //assemble PuzzleContents
0074         Palapeli::PuzzleContents contents;
0075         contents.imageSize = job.image().size();
0076         contents.pieces = job.pieces();
0077         contents.pieceOffsets = job.pieceOffsets();
0078         contents.relations = job.relations();
0079         return new Palapeli::ContentsComponent(contents);
0080     }
0081     //casts for writing an archive
0082     else if (type == DirectoryStorage)
0083         return Palapeli::DirectoryStorageComponent::fromData(puzzle());
0084     else if (type == ArchiveStorage)
0085         return Palapeli::ArchiveStorageComponent::fromData(puzzle());
0086     //unknown type requested
0087     else
0088         return nullptr;
0089 }