Warning, file /education/libkeduvocdocument/keduvocdocument/keduvoccontainer.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * SPDX-FileCopyrightText: 2007 Jeremy Whiting <jpwhiting@kde.org> 0003 * SPDX-FileCopyrightText: 2007 Frederik Gladhorn <frederik.gladhorn@kdemail.net> 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "keduvoccontainer.h" 0008 0009 #include "keduvocdocument.h" 0010 #include "keduvocexpression.h" 0011 0012 #include <QDebug> 0013 0014 /** private class to store information about a lesson */ 0015 class KEduVocContainer::Private 0016 { 0017 public: 0018 ~Private(); 0019 0020 // properties for this lesson 0021 QString m_name; 0022 bool m_inPractice; 0023 0024 // The containing document. This is only set for the top lesson, so to 0025 // get to the document, you need to follow the parent pointer to the top 0026 // container. 0027 KEduVocDocument *m_document; 0028 0029 // other lessons in the tree 0030 KEduVocContainer *m_parentContainer; 0031 QList<KEduVocContainer *> m_childContainers; 0032 0033 EnumContainerType m_type; 0034 0035 QList<KEduVocExpression *> m_childLessonEntries; 0036 bool m_childLessonEntriesValid; 0037 0038 /// Image url 0039 QUrl m_imageUrl; 0040 }; 0041 0042 KEduVocContainer::Private::~Private() 0043 { 0044 qDeleteAll(m_childContainers); 0045 } 0046 0047 // This is a private constructor only used by KEduVocDocument when creating 0048 // the top level lesson. 0049 KEduVocContainer::KEduVocContainer(const QString &name, EnumContainerType type, KEduVocDocument *document) 0050 : d(new Private) 0051 { 0052 d->m_parentContainer = nullptr; 0053 d->m_name = name; 0054 d->m_inPractice = true; 0055 d->m_type = type; 0056 d->m_childLessonEntriesValid = false; 0057 0058 d->m_document = document; 0059 } 0060 0061 KEduVocContainer::KEduVocContainer(const QString &name, EnumContainerType type, KEduVocContainer *parent) 0062 : d(new Private) 0063 { 0064 d->m_parentContainer = parent; 0065 d->m_name = name; 0066 d->m_inPractice = true; 0067 d->m_type = type; 0068 d->m_childLessonEntriesValid = false; 0069 0070 d->m_document = nullptr; 0071 } 0072 0073 KEduVocContainer::KEduVocContainer(const KEduVocContainer &other) 0074 : d(new Private) 0075 { 0076 d->m_name = other.d->m_name; 0077 d->m_inPractice = other.d->m_inPractice; 0078 d->m_type = other.d->m_type; 0079 d->m_parentContainer = other.d->m_parentContainer; 0080 d->m_childLessonEntriesValid = false; 0081 } 0082 0083 KEduVocContainer::~KEduVocContainer() 0084 { 0085 delete d; 0086 } 0087 0088 KEduVocDocument *KEduVocContainer::document() const 0089 { 0090 KEduVocContainer *cont = (KEduVocContainer *)this; 0091 while (cont->d->m_parentContainer) { 0092 cont = cont->d->m_parentContainer; 0093 } 0094 0095 Q_ASSERT(cont->d->m_document); 0096 return cont->d->m_document; 0097 } 0098 0099 void KEduVocContainer::appendChildContainer(KEduVocContainer *child) 0100 { 0101 d->m_childContainers.append(child); 0102 child->d->m_parentContainer = this; 0103 0104 invalidateChildLessonEntries(); 0105 } 0106 0107 KEduVocContainer *KEduVocContainer::childContainer(int row) 0108 { 0109 return d->m_childContainers.value(row); 0110 } 0111 0112 KEduVocContainer *KEduVocContainer::childContainer(const QString &name) 0113 { 0114 if (d->m_name == name) { 0115 return this; 0116 } 0117 0118 foreach (KEduVocContainer *container, d->m_childContainers) { 0119 KEduVocContainer *found = container->childContainer(name); 0120 if (found) { 0121 return found; 0122 } 0123 } 0124 return nullptr; 0125 } 0126 0127 void KEduVocContainer::deleteChildContainer(int row) 0128 { 0129 qDebug() << "Delete of container - check entry deletion!"; 0130 delete d->m_childContainers.takeAt(row); 0131 0132 invalidateChildLessonEntries(); 0133 } 0134 0135 void KEduVocContainer::removeChildContainer(int row) 0136 { 0137 d->m_childContainers.removeAt(row); 0138 invalidateChildLessonEntries(); 0139 } 0140 0141 int KEduVocContainer::childContainerCount() const 0142 { 0143 return d->m_childContainers.count(); 0144 } 0145 0146 int KEduVocContainer::row() const 0147 { 0148 if (d->m_parentContainer) { 0149 return d->m_parentContainer->d->m_childContainers.indexOf(const_cast<KEduVocContainer *>(this)); 0150 } 0151 return 0; 0152 } 0153 0154 KEduVocContainer &KEduVocContainer::operator=(const KEduVocContainer &other) 0155 { 0156 d->m_name = other.d->m_name; 0157 d->m_inPractice = other.d->m_inPractice; 0158 return *this; 0159 } 0160 0161 bool KEduVocContainer::operator==(const KEduVocContainer &other) const 0162 { 0163 return d->m_name == other.d->m_name && d->m_inPractice == other.d->m_inPractice 0164 /// @todo make this return something useful 0165 ; 0166 } 0167 0168 void KEduVocContainer::setName(const QString &name) 0169 { 0170 d->m_name = name; 0171 } 0172 0173 QString KEduVocContainer::name() 0174 { 0175 return d->m_name; 0176 } 0177 0178 bool KEduVocContainer::inPractice() 0179 { 0180 return d->m_inPractice; 0181 } 0182 0183 void KEduVocContainer::setInPractice(bool inPractice) 0184 { 0185 d->m_inPractice = inPractice; 0186 } 0187 0188 void KEduVocContainer::removeTranslation(int translation) 0189 { 0190 foreach (KEduVocContainer *childContainer, d->m_childContainers) { 0191 childContainer->removeTranslation(translation); 0192 } 0193 0194 foreach (KEduVocExpression *entry, entries()) { 0195 entry->removeTranslation(translation); 0196 } 0197 } 0198 0199 QList<KEduVocExpression *> KEduVocContainer::entriesRecursive() 0200 { 0201 if (!d->m_childLessonEntriesValid) { 0202 updateChildLessonEntries(); 0203 } 0204 return d->m_childLessonEntries; 0205 } 0206 0207 QList<KEduVocContainer *> KEduVocContainer::childContainers() 0208 { 0209 return d->m_childContainers; 0210 } 0211 0212 KEduVocContainer *KEduVocContainer::parent() 0213 { 0214 return d->m_parentContainer; 0215 } 0216 0217 void KEduVocContainer::setContainerType(KEduVocContainer::EnumContainerType type) 0218 { 0219 d->m_type = type; 0220 } 0221 0222 KEduVocContainer::EnumContainerType KEduVocContainer::containerType() 0223 { 0224 return d->m_type; 0225 } 0226 0227 QUrl KEduVocContainer::imageUrl() 0228 { 0229 return d->m_imageUrl; 0230 } 0231 0232 void KEduVocContainer::setImageUrl(const QUrl &url) 0233 { 0234 d->m_imageUrl = url; 0235 } 0236 0237 void KEduVocContainer::insertChildContainer(int row, KEduVocContainer *child) 0238 { 0239 d->m_childContainers.insert(row, child); 0240 child->d->m_parentContainer = this; 0241 0242 invalidateChildLessonEntries(); 0243 } 0244 0245 void KEduVocContainer::updateChildLessonEntries() 0246 { 0247 QList<KEduVocExpression *> entriesRecursive = entries(); 0248 0249 foreach (KEduVocContainer *childContainer, d->m_childContainers) 0250 foreach (KEduVocExpression *expr, childContainer->entries(Recursive)) 0251 entriesRecursive.append(expr); 0252 0253 d->m_childLessonEntries = entriesRecursive; 0254 d->m_childLessonEntriesValid = true; 0255 } 0256 0257 void KEduVocContainer::invalidateChildLessonEntries() 0258 { 0259 d->m_childLessonEntriesValid = false; 0260 // propagate to parent 0261 if (d->m_parentContainer) { 0262 d->m_parentContainer->invalidateChildLessonEntries(); 0263 } 0264 } 0265 0266 double KEduVocContainer::averageGrade(int translation, EnumEntriesRecursive recursive) 0267 { 0268 int sum = 0, presum = 0, count = 0; 0269 foreach (KEduVocExpression *entry, entries(recursive)) { 0270 KEduVocTranslation &trans(*entry->translation(translation)); 0271 if (!trans.isEmpty()) { 0272 ++count; 0273 sum += trans.grade(); 0274 presum += trans.preGrade(); 0275 } 0276 } 0277 // make that a percentage 0278 // There are KV_MAX_GRADE grades from 0 -> 100 % 0279 // There are KV_MAX_GRADE preGrades within the first grade. 0280 if (count == 0) { 0281 return 100.0; 0282 } 0283 return ((sum * 100.0 / KV_MAX_GRADE) + (presum * 100.0 / (KV_MAX_GRADE * KV_MAX_GRADE))) / count; 0284 } 0285 0286 int KEduVocContainer::expressionsOfGrade(int translation, grade_t grade, EnumEntriesRecursive recursive) 0287 { 0288 int sum = 0; 0289 foreach (KEduVocExpression *entry, entries(recursive)) { 0290 if (entry->translation(translation)->grade() == grade) { 0291 sum++; 0292 } 0293 } 0294 return sum; 0295 } 0296 0297 void KEduVocContainer::resetGrades(int translation, EnumEntriesRecursive recursive) 0298 { 0299 foreach (KEduVocExpression *entry, entries(recursive)) { 0300 entry->resetGrades(translation); 0301 } 0302 0303 document()->setModified(true); 0304 }