File indexing completed on 2024-05-05 05:40:25
0001 /*************************************************************************** 0002 * Copyright (C) 2021 by Renaud Guezennec * 0003 * http://www.rolisteam.org/contact * 0004 * * 0005 * This software is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 #include "data/campaigneditor.h" 0021 0022 #include "data/campaign.h" 0023 #include "data/character.h" 0024 #include "data/media.h" 0025 #include "data/rolisteamtheme.h" 0026 #include "utils/iohelper.h" 0027 #include "model/characterstatemodel.h" 0028 #include "model/nonplayablecharactermodel.h" 0029 #include "worker/fileserializer.h" 0030 #include "worker/iohelper.h" 0031 #include "worker/modelhelper.h" 0032 #include "worker/utilshelper.h" 0033 0034 #include <QFuture> 0035 #include <QFutureWatcher> 0036 #include <QtConcurrent> 0037 0038 namespace campaign 0039 { 0040 namespace 0041 { 0042 void readCampaignInfo(const CampaignInfo& info, Campaign* manager) 0043 { 0044 if(!info.status || !manager) 0045 return; 0046 ModelHelper::fetchDiceModel(info.dices, manager->diceAliases()); 0047 ModelHelper::fetchCharacterStateModel(info.states, manager->stateModel()); 0048 ModelHelper::fetchNpcModel(info.npcs, manager->npcModel(), manager->rootDirectory()); 0049 auto assets= info.asset; 0050 ModelHelper::fetchMedia(assets[Core::JsonKey::JSON_MEDIAS].toArray(), manager); 0051 manager->setName(assets[Core::JsonKey::JSON_NAME].toString()); 0052 manager->setCurrentChapter(assets[Core::JsonKey::JSON_CURRENT_CHAPTER].toString()); 0053 manager->setCurrentTheme(IOHelper::jsonToTheme(info.theme)); 0054 0055 auto const& states= manager->stateModel()->statesList(); 0056 auto list= new QList<CharacterState*>(); 0057 std::transform(std::begin(states), std::end(states), std::back_inserter(*list), 0058 [](const std::unique_ptr<CharacterState>& item) { return item.get(); }); 0059 Character::setListOfCharacterState(list); 0060 } 0061 } // namespace 0062 CampaignEditor::CampaignEditor(QObject* parent) : QObject(parent), m_campaign(new Campaign) 0063 { 0064 connect(m_campaign.get(), &Campaign::mediaAdded, this, &CampaignEditor::importedFile); 0065 } 0066 0067 Campaign* CampaignEditor::campaign() const 0068 { 0069 return m_campaign.get(); 0070 } 0071 0072 bool CampaignEditor::open(const QString& from) 0073 { 0074 m_campaign->setRootDirectory(from); 0075 helper::utils::setContinuation<CampaignInfo>( 0076 QtConcurrent::run([from]() { return campaign::FileSerializer::readCampaignDirectory(from); }), m_campaign.get(), 0077 [this](const CampaignInfo& info) 0078 { 0079 readCampaignInfo(info, m_campaign.get()); 0080 emit campaignLoaded(info.missingFiles, info.unmanagedFiles); 0081 }); 0082 return true; 0083 } 0084 0085 bool CampaignEditor::mergeAudioFile(const QString& source, const QString& dest) 0086 { 0087 return IOHelper::mergePlayList(source, dest); 0088 } 0089 0090 /*bool CampaignEditor::copyArrayModelAndFile(const QString& source, const QString& srcDir, const QString& dest, 0091 const QString& destDir) 0092 { 0093 return IOHelper::copyArrayModelAndFile(source, srcDir, dest, destDir); 0094 }*/ 0095 0096 bool CampaignEditor::copyMedia(const QString& source, const QString& dest, Core::MediaType type) 0097 { 0098 auto listFile= IOHelper::mediaList(source, type); 0099 if(listFile.isEmpty()) 0100 return false; 0101 for(auto const& file : listFile) 0102 { 0103 addMedia(QUuid::createUuid().toString(QUuid::WithoutBraces), QString("%1/%2").arg(dest, file), 0104 utils::IOHelper::loadFile(QString("%1/%2").arg(source, file))); 0105 } 0106 return true; 0107 } 0108 0109 bool CampaignEditor::copyTheme(const QString& source, const QString& dest) 0110 { 0111 auto res= utils::IOHelper::copyFile(source, dest); 0112 return !res.isEmpty(); 0113 } 0114 0115 bool CampaignEditor::mergeJsonArrayFile(const QString& source, const QString& dest) 0116 { 0117 bool ok; 0118 auto srcArray= IOHelper::loadJsonFileIntoArray(source, ok); 0119 if(!ok) 0120 return false; 0121 auto destArray= IOHelper::loadJsonFileIntoArray(dest, ok); 0122 0123 if(!ok) 0124 { 0125 utils::IOHelper::copyFile(source, dest); 0126 return true; 0127 } 0128 0129 destArray.append(srcArray); 0130 IOHelper::writeJsonArrayIntoFile(dest, destArray); 0131 return true; 0132 } 0133 0134 bool CampaignEditor::loadDiceAlias(const QString& source) 0135 { 0136 if(!m_campaign) 0137 return false; 0138 0139 bool ok; 0140 ModelHelper::fetchDiceModel(IOHelper::loadJsonFileIntoArray(source, ok), m_campaign->diceAliases()); 0141 return ok; 0142 } 0143 0144 bool CampaignEditor::loadStates(const QString& source, const QString& srcDir, const QString& dest, 0145 const QString& destDir) 0146 { 0147 if(!m_campaign) 0148 return false; 0149 0150 bool ok; 0151 ModelHelper::fetchCharacterStateModel(IOHelper::loadJsonFileIntoArray(source, ok), m_campaign->stateModel()); 0152 auto const& list= m_campaign->stateModel()->statesList(); 0153 0154 std::for_each(std::begin(list), std::end(list), 0155 [srcDir, destDir](const std::unique_ptr<CharacterState>& state) 0156 { 0157 auto path= state->imagePath(); 0158 if(path.isEmpty()) 0159 return; 0160 utils::IOHelper::copyFile(QString("%1/%2").arg(srcDir, path), 0161 QString("%1/%2").arg(destDir, path)); 0162 }); 0163 // todo manage images from states 0164 return ok; 0165 } 0166 0167 bool CampaignEditor::loadNpcData(const QString& source, const QString& srcDir, const QString& dest, 0168 const QString& destDir) 0169 { 0170 if(!m_campaign) 0171 return false; 0172 0173 bool ok; 0174 ModelHelper::fetchNpcModel(IOHelper::loadJsonFileIntoArray(source, ok), m_campaign->npcModel(), srcDir); 0175 auto const& list= m_campaign->npcModel()->npcList(); 0176 0177 std::for_each(std::begin(list), std::end(list), 0178 [srcDir, destDir](const std::unique_ptr<NonPlayableCharacter>& npc) 0179 { 0180 auto path= npc->avatarPath(); 0181 if(path.isEmpty()) 0182 return; 0183 utils::IOHelper::copyFile(QString("%1/%2").arg(srcDir, path), 0184 QString("%1/%2").arg(destDir, path)); 0185 }); 0186 // todo manage images from states 0187 return ok; 0188 } 0189 0190 bool CampaignEditor::removeMedia(const QString& src) 0191 { 0192 // remove from campaign 0193 auto media= m_campaign->mediaFromPath(src); 0194 0195 if(!media) 0196 return false; 0197 0198 m_campaign->removeMedia(media->id()); 0199 0200 // remove file on disk 0201 return removeFile(src); 0202 } 0203 0204 bool CampaignEditor::removeFile(const QString& src) 0205 { 0206 return utils::IOHelper::removeFile(src); 0207 } 0208 0209 QString CampaignEditor::saveAvatar(const QString& id, const QByteArray& array) 0210 { 0211 auto dest= QString("%1/avatar_%2.png").arg(m_campaign->directory(campaign::Campaign::Place::NPC_ROOT), id); 0212 utils::IOHelper::writeFile(dest, array); 0213 return dest; 0214 } 0215 0216 /*QString CampaignEditor::addFileIntoCharacters(const QString& src) 0217 { 0218 // TODO create command 0219 // IOHelper::copyFile(); 0220 // IOHelper::writeFile(src, array, true); 0221 } 0222 0223 bool CampaignEditor::removeFileFromCharacters(const QString& path) 0224 { 0225 // IOHelper::removeFile(path); 0226 }*/ 0227 0228 bool CampaignEditor::addMedia(const QString& id, const QString& dest, const QByteArray& array) 0229 { 0230 QFileInfo file(dest); 0231 std::unique_ptr<Media> media(new Media(id, file.baseName(), dest, FileSerializer::typeFromExtention(dest))); 0232 m_campaign->addMedia(std::move(media)); 0233 utils::IOHelper::writeFile(dest, array, true); 0234 return true; 0235 } 0236 0237 QString CampaignEditor::mediaFullPathWithExtension(const QString& file, Core::ContentType type) const 0238 { 0239 return mediaFullPath(campaign::FileSerializer::addExtention(file, type)); 0240 } 0241 0242 QString CampaignEditor::mediaFullPath(const QString& file) const 0243 { 0244 return QString("%1/%2").arg(m_campaign->directory(campaign::Campaign::Place::MEDIA_ROOT), file); 0245 } 0246 0247 void CampaignEditor::doCommand(QUndoCommand* command) 0248 { 0249 emit performCommand(command); 0250 } 0251 0252 QString campaign::CampaignEditor::campaignDir() const 0253 { 0254 return m_campaign->rootDirectory(); 0255 } 0256 0257 QString CampaignEditor::currentDir() const 0258 { 0259 return m_campaign->currentChapter(); 0260 } 0261 } // namespace campaign