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 }