1 /*
2  * SPDX-FileCopyrightText: 2007 Jeremy Whiting <jpwhiting@kde.org>
3  * SPDX-FileCopyrightText: 2007 Frederik Gladhorn <frederik.gladhorn@kdemail.net>
4  * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "keduvocwordtype.h"
8 
9 #include "keduvocexpression.h"
10 
11 #include <QSet>
12 
13 class KEduVocWordType::Private
14 {
15 public:
16     // bitvector of word type flags
17     KEduVocWordFlags m_flags;
18     QList<KEduVocExpression*> m_expressions;
19     // list of translations
20     QList<KEduVocTranslation*> m_translations;
21 };
22 
KEduVocWordType(const QString & name,KEduVocWordType * parent)23 KEduVocWordType::KEduVocWordType(const QString& name, KEduVocWordType *parent)
24         : KEduVocContainer(name, WordType, parent), d( new Private )
25 {}
26 
~KEduVocWordType()27 KEduVocWordType::~KEduVocWordType()
28 {
29     foreach(KEduVocTranslation* translation, d->m_translations) {
30         translation->setWordType(0);
31     }
32     delete d;
33 }
34 
entries(EnumEntriesRecursive recursive)35 QList<KEduVocExpression*> KEduVocWordType::entries(EnumEntriesRecursive recursive)
36 {
37     if (recursive == Recursive) {
38         return entriesRecursive();
39     }
40 
41     return d->m_expressions;
42 }
43 
entryCount(EnumEntriesRecursive recursive)44 int KEduVocWordType::entryCount(EnumEntriesRecursive recursive)
45 {
46     if (recursive == Recursive) {
47         return entriesRecursive().count();
48     }
49     return d->m_expressions.count();
50 }
51 
addTranslation(KEduVocTranslation * translation)52 void KEduVocWordType::addTranslation(KEduVocTranslation* translation)
53 {
54     // add to expression - if not already there because another translation of the same word is there.
55     bool found = false;
56     foreach(int i, translation->entry()->translationIndices()) {
57         if (translation->entry()->translation(i)->wordType() == this) {
58             found = true;
59             break;
60         }
61     }
62     if (!found) {
63         d->m_expressions.append(translation->entry());
64     }
65     d->m_translations.append( translation );
66     invalidateChildLessonEntries();
67 }
68 
removeTranslation(KEduVocTranslation * translation)69 void KEduVocWordType::removeTranslation(KEduVocTranslation* translation)
70 {
71     d->m_translations.removeAt( d->m_translations.indexOf(translation) );
72 
73     // no lesson found - this entry is being deleted. remove all its siblings.
74     if (!translation->entry()->lesson()) {
75         int index = d->m_expressions.indexOf(translation->entry());
76         if (index != -1) {
77             d->m_expressions.removeAt(index);
78         }
79     }
80 
81     // remove from cache if none of the translations use this word type (other than the one we are removing that should not be taken into account)
82     bool found = false;
83     foreach(int i, translation->entry()->translationIndices()) {
84         if (translation->entry()->translation(i)->wordType() && translation->entry()->translation(i)->wordType() == this && translation->entry()->translation(i) != translation) {
85             found = true;
86             break;
87         }
88     }
89     if (!found) {
90         d->m_expressions.removeAt(d->m_expressions.indexOf(translation->entry()));
91     }
92 
93     invalidateChildLessonEntries();
94 }
95 
translation(int row)96 KEduVocTranslation * KEduVocWordType::translation(int row)
97 {
98 
99     return d->m_translations.value(row);
100 }
101 
entry(int row,EnumEntriesRecursive recursive)102 KEduVocExpression * KEduVocWordType::entry(int row, EnumEntriesRecursive recursive)
103 {
104     if (recursive == Recursive) {
105         return entriesRecursive().value(row);
106     }
107     return entries().value(row);
108 }
109 
wordType() const110 KEduVocWordFlags KEduVocWordType::wordType() const
111 {
112     return d->m_flags;
113 }
114 
setWordType(KEduVocWordFlags flags)115 void KEduVocWordType::setWordType(KEduVocWordFlags flags)
116 {
117     d->m_flags = flags;
118 }
119 
childOfType(const KEduVocWordFlags & flags)120 KEduVocWordType* KEduVocWordType::childOfType(const KEduVocWordFlags& flags)
121 {
122     if(d->m_flags == flags) {
123         return this;
124     }
125     foreach(KEduVocContainer* child, childContainers()) {
126         KEduVocWordType* result = static_cast<KEduVocWordType*>(child)->childOfType(flags);
127         if(result) {
128             return result;
129         }
130     }
131     return 0;
132 }
133 
134