File indexing completed on 2023-05-30 10:45:26
0001 /* 0002 SPDX-FileCopyrightText: 2006-2010 Peter Hedlund <peter.hedlund@kdemail.net> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "kwqtablemodel.h" 0007 0008 #include <KLocalizedString> 0009 0010 #include "prefs.h" 0011 #include "documentsettings.h" 0012 #include "keduvocexpression.h" 0013 0014 KWQTableModel::KWQTableModel(QObject * parent) : QAbstractTableModel(parent) 0015 { 0016 m_doc = 0; 0017 m_decorationCache = new KImageCache(QStringLiteral("kwordquiz"), 10485760); 0018 } 0019 0020 KWQTableModel::~KWQTableModel() 0021 { 0022 delete m_decorationCache; 0023 } 0024 0025 int KWQTableModel::rowCount(const QModelIndex & parent) const 0026 { 0027 if (parent.isValid()) 0028 return 0; 0029 return m_doc->lesson()->entryCount(KEduVocLesson::Recursive); 0030 } 0031 0032 int KWQTableModel::columnCount(const QModelIndex & parent) const 0033 { 0034 if (parent.isValid()) 0035 return 0; 0036 return 2; 0037 } 0038 0039 QVariant KWQTableModel::data(const QModelIndex & index, int role) const 0040 { 0041 if (!index.isValid()) 0042 return QVariant(); 0043 0044 QPixmap ip; 0045 QString image; 0046 0047 switch (role) { 0048 case Qt::FontRole: 0049 return QVariant(Prefs::editorFont()); 0050 0051 case Qt::DisplayRole: 0052 return m_doc->lesson()->entries(KEduVocLesson::Recursive).value(index.row())->translation(index.column())->text(); 0053 0054 case Qt::DecorationRole: 0055 image = m_doc->lesson()->entries(KEduVocLesson::Recursive).value(index.row())->translation(index.column())->imageUrl().toLocalFile(); 0056 if (!image.isEmpty()) { 0057 if (!m_decorationCache->findPixmap(image, &ip)) { 0058 ip = QPixmap(image).scaled(QSize(22, 22), Qt::KeepAspectRatio); 0059 m_decorationCache->insertPixmap(image, ip); 0060 } 0061 } 0062 return ip; 0063 0064 case KWQTableModel::ImageRole: 0065 return m_doc->lesson()->entries(KEduVocLesson::Recursive).value(index.row())->translation(index.column())->imageUrl().toLocalFile(); 0066 0067 case KWQTableModel::SoundRole: 0068 return m_doc->lesson()->entries(KEduVocLesson::Recursive).value(index.row())->translation(index.column())->soundUrl().toLocalFile(); 0069 0070 default: 0071 return QVariant(); 0072 } 0073 } 0074 0075 QVariant KWQTableModel::headerData(int section, Qt::Orientation orientation, int role) const 0076 { 0077 if (orientation == Qt::Horizontal) 0078 { 0079 if (section < 0 || section > 1) 0080 return QVariant(); 0081 0082 if (role == Qt::DisplayRole) { 0083 return m_doc->identifier(section).name(); 0084 } 0085 0086 if (role == Qt::SizeHintRole) { 0087 DocumentSettings documentSettings(m_doc->url().url()); 0088 documentSettings.read(); 0089 return QSize(documentSettings.sizeHintColumn(section), 25); 0090 } 0091 0092 if (role == KWQTableModel::KeyboardLayoutRole) { 0093 DocumentSettings documentSettings(m_doc->url().url()); 0094 documentSettings.read(); 0095 return documentSettings.keyboardLayoutColumn(section); 0096 } 0097 0098 return QVariant(); 0099 } 0100 else 0101 return QAbstractTableModel::headerData(section, orientation, role); 0102 } 0103 0104 Qt::ItemFlags KWQTableModel::flags(const QModelIndex & index) const 0105 { 0106 if (!index.isValid()) 0107 return Qt::ItemIsEnabled; 0108 0109 return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; 0110 } 0111 0112 bool KWQTableModel::setData(const QModelIndex & index, const QVariant & value, int role) 0113 { 0114 if (!index.isValid()) 0115 return false; 0116 0117 switch (role) { 0118 case Qt::EditRole: 0119 m_doc->lesson()->entries(KEduVocLesson::Recursive).value(index.row())->setTranslation(index.column(), value.toString()); 0120 break; 0121 0122 case KWQTableModel::ImageRole: 0123 m_doc->lesson()->entries(KEduVocLesson::Recursive).value(index.row())->translation(index.column())->setImageUrl(value.toUrl()); 0124 break; 0125 0126 case KWQTableModel::SoundRole: 0127 m_doc->lesson()->entries(KEduVocLesson::Recursive).value(index.row())->translation(index.column())->setSoundUrl(value.toUrl()); 0128 break; 0129 } 0130 0131 Q_EMIT dataChanged(index, index); 0132 return true; 0133 } 0134 0135 bool KWQTableModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant & value, int role) 0136 { 0137 if (orientation == Qt::Horizontal) { 0138 if (section < 0 || section > 1) 0139 return false; 0140 0141 if (role == Qt::EditRole) { 0142 m_doc->identifier(section).setName(value.toString()); 0143 } 0144 0145 if (role == Qt::SizeHintRole) { 0146 DocumentSettings documentSettings(m_doc->url().url()); 0147 documentSettings.setSizeHintColumn(section, qvariant_cast<QSize>(value).width()); 0148 documentSettings.save(); 0149 } 0150 0151 if (role == KWQTableModel::KeyboardLayoutRole) { 0152 DocumentSettings documentSettings(m_doc->url().url()); 0153 documentSettings.setKeyboardLayoutColumn(section, value.toString()); 0154 documentSettings.save(); 0155 } 0156 0157 Q_EMIT headerDataChanged(orientation, section, section); 0158 return true; 0159 } 0160 return false; 0161 } 0162 0163 0164 bool KWQTableModel::insertRows(int row, int count, const QModelIndex & parent) 0165 { 0166 Q_UNUSED(parent); 0167 if (count < 1 || row < 0 || row > m_doc->lesson()->entryCount(KEduVocLesson::Recursive)) 0168 return false; 0169 0170 KEduVocLesson * cl = currentLesson(row); 0171 0172 beginInsertRows(QModelIndex(), row, row + count - 1); 0173 0174 for (int i = row; i < row + count; i++) 0175 cl->insertEntry(i, new KEduVocExpression); //m_doc->lesson()->insertEntry(i, new KEduVocExpression); 0176 0177 endInsertRows(); 0178 m_doc->setModified(true); 0179 return true; 0180 } 0181 0182 bool KWQTableModel::removeRows(int row, int count, const QModelIndex & parent) 0183 { 0184 Q_UNUSED(parent); 0185 if (count < 1 || row < 0 || row + count > m_doc->lesson()->entryCount(KEduVocLesson::Recursive) || count >= m_doc->lesson()->entryCount(KEduVocLesson::Recursive)) 0186 return false; 0187 0188 int bottomRow = row + count -1; 0189 beginRemoveRows(QModelIndex(), row, row + count - 1); 0190 0191 for (int i = bottomRow; i >= row; i--) { 0192 KEduVocExpression* entry = m_doc->lesson()->entries(KEduVocLesson::Recursive).value(i); 0193 entry->lesson()->removeEntry(entry); 0194 delete entry; 0195 } 0196 0197 endRemoveRows(); 0198 m_doc->setModified(true); 0199 return true; 0200 } 0201 0202 void KWQTableModel::setDocument(KEduVocDocument * doc) 0203 { 0204 beginResetModel(); 0205 m_doc = doc; 0206 endResetModel(); 0207 } 0208 0209 bool KWQTableModel::isEmpty() 0210 { 0211 if (m_doc->url().fileName() == i18n("Untitled")){ 0212 int rc = rowCount(QModelIndex()); 0213 for (int i = 0; i < rc; i++) 0214 if (!data(index(i, 0), Qt::DisplayRole).toString().isEmpty() || !data(index(i, 1), Qt::DisplayRole).toString().isEmpty()) 0215 return false; 0216 0217 return true; 0218 } 0219 else 0220 return false; 0221 } 0222 0223 0224 bool KWQTableModel::checkBlanksSyntax(const QString & text) const 0225 { 0226 if (!Prefs::enableBlanks()) 0227 return true; 0228 0229 bool result = false; 0230 int openCount = 0; 0231 int closeCount = 0; 0232 QVector<int> openPos(0); 0233 QVector<int> closePos(0); 0234 0235 for (int i = 0; i< text.length(); ++i) 0236 { 0237 if (text[i] == delim_start) 0238 { 0239 openCount++; 0240 openPos.resize(openCount); 0241 openPos[openCount - 1] = i; 0242 } 0243 0244 if (text[i] == delim_end) 0245 { 0246 closeCount++; 0247 closePos.resize(closeCount); 0248 closePos[closeCount - 1] = i; 0249 } 0250 } 0251 0252 if (openCount == 0 && closeCount == 0) 0253 return true; 0254 0255 if (openCount > 0 && closeCount > 0) 0256 if (openPos.size() == closePos.size()) 0257 for (int i = 0; i < openPos.size(); ++i) 0258 result = (openPos[i] < closePos[i]); 0259 0260 return result; 0261 } 0262 0263 bool KWQTableModel::checkSyntax() const 0264 { 0265 int errorCount = 0; 0266 0267 for (int r = 0; r < rowCount(QModelIndex()); ++r) 0268 { 0269 QString s = data(index(r, 0, QModelIndex()), Qt::DisplayRole).toString(); 0270 if (s.length() > 0) 0271 for (int i = 0; i <= s.length(); ++i) 0272 if (s[i] == delim_start || s[i] == delim_end) 0273 if (!checkBlanksSyntax(s)) 0274 errorCount++; 0275 s = data(index(r, 1, QModelIndex()), Qt::DisplayRole).toString(); 0276 if (s.length() > 0) 0277 for (int i = 0; i <= s.length(); ++i) 0278 if (s[i] == delim_start || s[i] == delim_end) 0279 if (!checkBlanksSyntax(s)) 0280 errorCount++; 0281 } 0282 0283 return (errorCount == 0); 0284 } 0285 0286 KEduVocLesson * KWQTableModel::currentLesson(int row) 0287 { 0288 int i = 0; 0289 QList<KEduVocContainer *> lessons = m_doc->lesson()->childContainers(); 0290 foreach(KEduVocContainer * c, lessons) { 0291 if (c->containerType() == KEduVocLesson::Lesson) { 0292 i += c->entryCount(); 0293 if (i >= row) 0294 return static_cast<KEduVocLesson *>(c); 0295 } 0296 } 0297 return m_doc->lesson(); 0298 }