File indexing completed on 2024-05-12 04:06:27
0001 /* 0002 SPDX-FileCopyrightText: 2011 Stefan Majewsky <majewsky@gmx.net> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "puzzle.h" 0008 0009 #include <QFileInfo> 0010 #include <QHash> 0011 0012 //BEGIN Palapeli::PuzzleComponent 0013 0014 Palapeli::PuzzleComponent::PuzzleComponent() 0015 : m_puzzle(nullptr) 0016 { 0017 } 0018 0019 Palapeli::PuzzleComponent::~PuzzleComponent() 0020 { 0021 } 0022 0023 Palapeli::PuzzleComponent* Palapeli::PuzzleComponent::cast(Palapeli::PuzzleComponent::Type type) const 0024 { 0025 Q_UNUSED(type) 0026 return nullptr; 0027 } 0028 0029 Palapeli::Puzzle* Palapeli::PuzzleComponent::puzzle() const 0030 { 0031 return m_puzzle; 0032 } 0033 0034 //END Palapeli::PuzzleComponent 0035 //BEGIN Palapeli::Puzzle 0036 0037 //See Private::get() for the whole story. 0038 struct Component 0039 { 0040 Palapeli::PuzzleComponent *component = nullptr; 0041 0042 Component() {} 0043 explicit Component(Palapeli::PuzzleComponent* component) : component(component) {} 0044 ~Component() { delete component; } 0045 }; 0046 struct Palapeli::Puzzle::Private 0047 { 0048 Palapeli::Puzzle* q; 0049 QHash<Palapeli::PuzzleComponent::Type, Component*> m_components; 0050 Palapeli::PuzzleComponent *m_mainComponent; 0051 QString m_location; 0052 QString m_identifier; 0053 0054 Private(Palapeli::Puzzle* q, Palapeli::PuzzleComponent* mainComponent, const QString& location, const QString& identifier); 0055 const Palapeli::PuzzleComponent* get(Palapeli::PuzzleComponent::Type type); 0056 }; 0057 0058 Palapeli::Puzzle::Puzzle(Palapeli::PuzzleComponent* mainComponent, const QString& location, const QString& identifier) 0059 : d(new Private(this, mainComponent, location, identifier)) 0060 { 0061 qRegisterMetaType<Palapeli::Puzzle*>(); 0062 } 0063 0064 Palapeli::Puzzle::Private::Private(Palapeli::Puzzle* q, Palapeli::PuzzleComponent* mainComponent, const QString& location, const QString& identifier) 0065 : q(q) 0066 , m_mainComponent(mainComponent) 0067 , m_location(location) 0068 , m_identifier(identifier) 0069 { 0070 m_mainComponent->m_puzzle = q; 0071 m_components.insert(mainComponent->type(), new Component(mainComponent)); 0072 } 0073 0074 Palapeli::Puzzle::~Puzzle() 0075 { 0076 QHashIterator<Palapeli::PuzzleComponent::Type, Component*> iter(d->m_components); 0077 while (iter.hasNext()) 0078 delete iter.next().value(); 0079 delete d; 0080 } 0081 0082 const Palapeli::PuzzleComponent* Palapeli::Puzzle::component(Palapeli::PuzzleComponent::Type type) const 0083 { 0084 const Component* c = d->m_components.value(type); 0085 return c ? c->component : nullptr; 0086 } 0087 0088 const Palapeli::PuzzleComponent* Palapeli::Puzzle::get(Palapeli::PuzzleComponent::Type type) 0089 { 0090 return d->get (type); 0091 } 0092 0093 const Palapeli::PuzzleComponent* Palapeli::Puzzle::Private::get(Palapeli::PuzzleComponent::Type type) 0094 { 0095 Component* c = m_components.value(type); 0096 if (c) 0097 return c->component; 0098 0099 m_components.insert(type, c = new Component); 0100 Palapeli::PuzzleComponent* cmp = m_mainComponent->cast(type); 0101 if (cmp) 0102 cmp->m_puzzle = q; 0103 c->component = cmp; 0104 return cmp; 0105 } 0106 0107 QString Palapeli::Puzzle::identifier() const 0108 { 0109 return d->m_identifier; 0110 } 0111 0112 QString Palapeli::Puzzle::location() const 0113 { 0114 return d->m_location; 0115 } 0116 0117 void Palapeli::Puzzle::setLocation(const QString& location) 0118 { 0119 d->m_location = location; 0120 } 0121 0122 void Palapeli::Puzzle::dropComponent(Palapeli::PuzzleComponent::Type type) 0123 { 0124 //DO NEVER EVER USE THIS FUNCTION! THIS FUNCTION IS PURELY DANGEROUS. STUFF WILL BREAK. 0125 Component*& c = d->m_components[type]; 0126 delete c; 0127 c = nullptr; 0128 } 0129 0130 Q_GLOBAL_STATIC(QList<QString>, g_usedIdentifiers) 0131 0132 /*static*/ QString Palapeli::Puzzle::fsIdentifier(const QString& location) 0133 { 0134 QString puzzleName = QFileInfo(location).fileName(); 0135 const char* disallowedChars = "\\:*?\"<>|"; //Windows forbids using these chars in filenames, so we'll strip them 0136 for (const char* c = disallowedChars; *c; ++c) 0137 puzzleName.remove(QLatin1Char(*c)); 0138 const QString identifierPattern = QString::fromLatin1("__FSC_%1_%2_").arg(puzzleName); 0139 int uniquifier = 0; 0140 while (g_usedIdentifiers->contains(identifierPattern.arg(uniquifier))) 0141 ++uniquifier; 0142 const QString identifier = identifierPattern.arg(uniquifier); 0143 *g_usedIdentifiers << identifier; 0144 return identifier; 0145 } 0146 0147 //END Palapeli::Puzzle 0148 0149 #include "moc_puzzle.cpp"