00001 #include "exercisemodel.h"
00002 #include "../Data/dataproject.h"
00003
00004 ExerciseModel::ExerciseModel(bool exercise, DataProject *project, QAbstractItemModel *parent) : QAbstractItemModel(parent)
00005 {
00006 isTeacher = false;
00007 isPrintDialog = false;
00008 maxChapterId = 0;
00009
00010 p_project = project;
00011 QVariantList rootData;
00012 if(exercise)
00013 {
00014 rootData << "Übungen";
00015 }
00016 else
00017 {
00018 rootData << "Aufgaben";
00019 }
00020
00021 rootItem = new ExerciseItem(rootData);
00022 if(project)
00023 {
00024 QList<DataChapter *> chapters = project->getChapters();
00025 for(int i = 0; i < chapters.count(); i++)
00026 {
00027 addChapter(chapters.value(i)->name(), chapters.value(i)->id());
00028 QList<DataExercise *> exercises = chapters.value(i)->exercises();
00029 for(int j = 0; j < exercises.count(); j++)
00030 {
00031 addExercise(chapters.value(i)->name(), exercises.value(j)->name(), exercises.value(j)->id(), exercises.value(j)->status());
00032 }
00033 }
00034 }
00035 }
00036
00037 Qt::ItemFlags ExerciseModel::flags(const QModelIndex &index) const
00038 {
00039 if(!index.isValid())
00040 {
00041 return 0;
00042 }
00043
00044 Qt::ItemFlags flags;
00045 if(isTeacher)
00046 {
00047 flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
00048 }
00049 else
00050 {
00051 flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
00052 }
00053
00054 if(isPrintDialog)
00055 {
00056 flags = flags | Qt::ItemIsUserCheckable;
00057 }
00058
00059 return flags;
00060 }
00061
00062 QVariant ExerciseModel::headerData(int section, Qt::Orientation orientation, int role) const
00063 {
00064 if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
00065 {
00066 return rootItem->data(section);
00067 }
00068
00069 return QVariant();
00070
00071 }
00072
00073 QModelIndex ExerciseModel::index(int row, int column, const QModelIndex &parent) const
00074 {
00075 if(!hasIndex(row, column, parent))
00076 {
00077 return QModelIndex();
00078 }
00079
00080 ExerciseItem *parentItem;
00081
00082 if(!parent.isValid())
00083 {
00084 parentItem = rootItem;
00085 }
00086 else
00087 {
00088 parentItem = static_cast<ExerciseItem *>(parent.internalPointer());
00089 }
00090 ExerciseItem *childItem = parentItem->child(row);
00091 if(childItem)
00092 {
00093 return createIndex(row, column, childItem);
00094 }
00095 else
00096 {
00097 return QModelIndex();
00098 }
00099 }
00100
00101 QModelIndex ExerciseModel::parent(const QModelIndex &index) const
00102 {
00103 if(!index.isValid())
00104 {
00105 return QModelIndex();
00106 }
00107
00108 ExerciseItem *childItem = static_cast<ExerciseItem*>(index.internalPointer());
00109 ExerciseItem *parentItem = childItem->parent();
00110
00111 if(parentItem == rootItem)
00112 {
00113 return QModelIndex();
00114 }
00115
00116
00117
00118 if(!parentItem)
00119 {
00120 qDebug() << "ExerciseModel::parent(): I'm missing my parentItem (NULL ptr)! anyone feeling responsible?";
00121 return QModelIndex();
00122 }
00123
00124 return createIndex(parentItem->row(), 0, parentItem);
00125 }
00126
00127 int ExerciseModel::rowCount(const QModelIndex &parent) const
00128 {
00129 ExerciseItem *parentItem = NULL;
00130 if(parent.column() > 0)
00131 {
00132 return 0;
00133 }
00134
00135 if(!parent.isValid())
00136 {
00137 parentItem = rootItem;
00138 }
00139 else
00140 {
00141 parentItem = static_cast<ExerciseItem *>(parent.internalPointer());
00142 }
00143 return parentItem->childCount();
00144 }
00145
00146 int ExerciseModel::columnCount(const QModelIndex &parent) const
00147 {
00148 if(parent.isValid())
00149 {
00150 return static_cast<ExerciseItem *>(parent.internalPointer())->columnCount();
00151 }
00152 else
00153 {
00154 return rootItem->columnCount();
00155 }
00156 }
00157
00158 QVariant ExerciseModel::data(const QModelIndex &index, int role) const
00159 {
00160 if(!index.isValid())
00161 {
00162 return QVariant();
00163 }
00164
00165 if(role == Qt::DisplayRole)
00166 {
00167 ExerciseItem *item = static_cast<ExerciseItem*>(index.internalPointer());
00168 return item->data(index.column());
00169 }
00170 else if(role == Qt::DecorationRole)
00171 {
00172 if(!isTeacher)
00173 {
00174 ExerciseItem *item = static_cast<ExerciseItem*>(index.internalPointer());
00175 if(!this->index(0,0, index).isValid())
00176 {
00177 if(item->data(1).toMap().value("state").toUInt() == Correct)
00178 {
00179 return QIcon(":misc/Apply");
00180 }
00181 else if(item->data(1).toMap().value("state").toUInt() == Wrong)
00182 {
00183 return QIcon(":project/DeleteDocument");
00184 }
00185 else if(item->data(1).toMap().value("state").toUInt() == NotCompleted)
00186 {
00187 return QIcon(":help/WhatsThis");
00188 }
00189 }
00190 }
00191 }
00192 else if(role == Qt::CheckStateRole)
00193 {
00194 if(isPrintDialog)
00195 {
00196 ExerciseItem *item = static_cast<ExerciseItem*>(index.internalPointer());
00197 return item->isChecked();
00198 }
00199 }
00200 else if(role == 32)
00201 {
00202 ExerciseItem *item = static_cast<ExerciseItem*>(index.internalPointer());
00203 return item->itemInfo();
00204 }
00205 else
00206 {
00207 return QVariant();
00208 }
00209 return QVariant();
00210 }
00211
00212 bool ExerciseModel::setData(const QModelIndex &index, const QVariant &value, int role)
00213 {
00214 bool result = false;
00215 if(role == Qt::EditRole)
00216 {
00217 if(!index.parent().isValid())
00218 {
00219 ExerciseItem *item = static_cast<ExerciseItem *>(index.internalPointer());
00220 if(!existsChapter(value.toString()))
00221 {
00222 if((p_project->chapter(index.data(0).toString())) != NULL)
00223 {
00224 p_project->chapter(index.data(0).toString())->setChapterName(value.toString());
00225 }
00226 replaceChapterName(item, value.toString());
00227 }
00228 else
00229 {
00230 if(item->data(0).toString() != value.toString())
00231 {
00232 emit printError("Sie können diesen Namen nicht benutzen, da er schon existiert!");
00233 removeChapter(item->data(1).toMap().value("chapterId").toUInt(), item->data(0).toString());
00234 }
00235 }
00236 result = true;
00237 }
00238 else
00239 {
00240 ExerciseItem *child = static_cast<ExerciseItem *>(index.internalPointer());
00241 if(!existsExercise(chapterName(child->data(1).toMap().value("chapterId").toUInt()), value.toString()))
00242 {
00243 DataChapter *chap = p_project->chapter(index.parent().data(0).toString());
00244 if(chap->exercise(index.data(0).toString()) != NULL)
00245 {
00246 chap->exercise(index.data(0).toString())->setExerciseName(value.toString());
00247 }
00248 replaceExerciseName(child, value.toString());
00249 }
00250 else
00251 {
00252 if(child->data(0).toString() != value.toString())
00253 {
00254 removeExercise(chapterById(child->data(1).toMap().value("chapterId").toUInt()), child->data(0).toString());
00255 emit printError("Sie können diesen Namen nicht benutzen, da er schon existiert!");
00256 }
00257 }
00258 result = true;
00259 }
00260 }
00261 else if(role == Qt::CheckStateRole)
00262 {
00263 if(isPrintDialog)
00264 {
00265 ExerciseItem *item = static_cast<ExerciseItem *>(index.internalPointer());
00266 Qt::CheckState checked = static_cast<Qt::CheckState>(value.toInt());
00267 if(item->parent() == rootItem)
00268 {
00269
00270 for(int i = 0; i < item->childCount(); i++)
00271 {
00272 item->child(i)->setCheckState(static_cast<Qt::CheckState>(value.toInt()));
00273 }
00274 }
00275 item->setCheckState(checked);
00276
00277 result = true;
00278 }
00279 }
00280
00281 emit dataChanged(index, index);
00282
00283
00284 return result;
00285 }
00286
00287 void ExerciseModel::addChapter(QString chapterName, uint chapterId)
00288 {
00289 if(!existsChapter(chapterName))
00290 {
00291 if((p_project->chapter(chapterName)) == NULL)
00292 {
00293 DataChapter *dChapter = new DataChapter();
00294 dChapter->setChapterName(chapterName);
00295 dChapter->setId(chapterId);
00296 p_project->addChapter(dChapter);
00297 }
00298 QVariantList list;
00299 QMap<QString, QVariant> data;
00300
00301 data.insert("chapterId", chapterId);
00302 list<<chapterName;
00303 list<<data;
00304 ExerciseItem *chapter = new ExerciseItem(list, rootItem);
00305 rootItem->addChild(chapter);
00306 maxChapterId++;
00307 }
00308 reset();
00309 emit resetView();
00310 }
00311
00312 void ExerciseModel::addExercise(QString chapterName, QString exerciseName, uint exerciseId, DataExerciseStatus status)
00313 {
00314 if(!existsExercise(chapterName, exerciseName))
00315 {
00316 DataChapter *chap = p_project->chapter(chapterName);
00317 if((chap->exercise(exerciseName)) == NULL)
00318 {
00319 DataExercise *exercise = new DataExercise();
00320 exercise->setExerciseName(exerciseName);
00321 exercise->setExerciseId(exerciseId);
00322 exercise->setStatus(status);
00323 chap->addExercise(exercise);
00324 }
00325
00326 ExerciseItem *item = chapterByName(chapterName);
00327 QVariantList list;
00328 QMap<QString, QVariant> data;
00329 data.insert("exerciseId", exerciseId);
00330 data.insert("chapterId", chapterID(chapterName));
00331 data.insert("state", status);
00332 list<<exerciseName;
00333 list<<data;
00334 ExerciseItem *exercise = new ExerciseItem(list, item);
00335 item->addChild(exercise);
00336 item->incrementExerciseIdByOne();
00337 }
00338 reset();
00339 emit resetView();
00340 }
00341
00342 void ExerciseModel::addOtherExercises(uint chapterId, ExerciseItem *oldExercise)
00343 {
00344 for(int i=0; i!=rootItem->childCount(); i++)
00345 {
00346 ExerciseItem *chapter = rootItem->child(i);
00347 if(chapter->data(1).toMap().value("chapterId").toUInt() == QVariant(chapterId).toUInt())
00348 {
00349 for(int j=0; j!= oldExercise->childCount(); j++)
00350 {
00351 ExerciseItem *item = oldExercise->child(j);
00352 QMap<QString, QVariant> d;
00353 QVariantList c;
00354
00355 d.insert("exerciseId", item->data(1).toMap().value("exerciseId"));
00356 d.insert("chapterId", item->data(1).toMap().value("chapterId"));
00357 d.insert("state", item->data(1).toMap().value("state"));
00358
00359 c<<item->data(0).toString();
00360 c<<d;
00361
00362 ExerciseItem *exercise = new ExerciseItem(c, chapter);
00363 chapter->addChild(exercise);
00364 emit resetView();
00365 }
00366 }
00367 }
00368 }
00369
00370 uint ExerciseModel::maxExerciseIdByChapterId(uint chapterId)
00371 {
00372 ExerciseItem *chapter = chapterById(chapterId);
00373 return chapter->maxExerciseID();
00374 }
00375
00376 uint ExerciseModel::maxExerciseIdByChapterName(QString chapterName)
00377 {
00378 ExerciseItem *chapter = chapterByName(chapterName);
00379 return chapter->maxExerciseID();
00380 }
00381
00382 void ExerciseModel::replaceChapterName(ExerciseItem *oldChapter, QString newChapterName)
00383 {
00384 for(int i = 0; i < rootItem->childCount(); i++)
00385 {
00386 if(rootItem->child(i)->data(0).toString() == oldChapter->data(0).toString())
00387 {
00388 QVariantList list;
00389 QMap<QString, QVariant> data;
00390 data.insert("chapterId", oldChapter->data(1).toMap().value("chapterId").toUInt());
00391 list<<newChapterName;
00392 list<<data;
00393 ExerciseItem *item = new ExerciseItem(list, rootItem);
00394 rootItem->childItems.replace(i, item);
00395 addOtherExercises(item->data(1).toMap().value("chapterId").toUInt(), oldChapter);
00396 }
00397 }
00398 }
00399
00400 void ExerciseModel::replaceExerciseName(ExerciseItem *oldExercise, QString newExerciseName)
00401 {
00402 ExerciseItem *chapterItem = chapterById(oldExercise->data(1).toMap().value("chapterId").toUInt());
00403 for(int i = 0; i < chapterItem->childCount(); i++)
00404 {
00405 ExerciseItem * exerciseItem = chapterItem->child(i);
00406 if(exerciseItem->data(0).toString() == oldExercise->data(0).toString())
00407 {
00408 QVariantList list;
00409 QMap<QString, QVariant> data;
00410 data.insert("chapterId", oldExercise->data(1).toMap().value("chapterId").toString());
00411 data.insert("exerciseId", oldExercise->data(1).toMap().value("exerciseId").toUInt());
00412 data.insert("state", oldExercise->data(1).toMap().value("state").toInt());
00413 list<<newExerciseName;
00414 list<<data;
00415 ExerciseItem *item = new ExerciseItem(list, chapterItem);
00416 chapterItem->childItems.replace(i, item);
00417 }
00418 }
00419 }
00420
00421 void ExerciseModel::editState(QString exerciseName, int exerciseId, DataExerciseStatus state)
00422 {
00423 for(int i = 0; i != rootItem->childCount(); i++)
00424 {
00425 ExerciseItem *item = rootItem->child(i);
00426 if(this->existsExercise(item->data(0).toString(), exerciseName))
00427 {
00428 QVariantList list;
00429 QMap<QString, QVariant> data;
00430 data.insert("chapterId", item->data(1).toMap().value("chapterId").toUInt());
00431 data.insert("exerciseId", exerciseId);
00432 data.insert("state", state);
00433 list<<exerciseName;
00434 list<<data;
00435 ExerciseItem *ex = new ExerciseItem(list, item);
00436 item->childItems.replace(exerciseId, ex);
00437 emit setSelection(item->data(1).toMap().value("chapterId").toUInt(), exerciseId);
00438 }
00439 }
00440 emit resetView();
00441 }
00442
00443 void ExerciseModel::removeChapterByName(QString chapterName)
00444 {
00445 ExerciseItem *chapter = chapterByName(chapterName);
00446 rootItem->removeChild(chapter);
00447 reset();
00448 emit resetView();
00449 }
00450
00451 void ExerciseModel::removeExerciseByName(QString chapterName, QString exerciseName, uint chapterId)
00452 {
00453 if(chapterId == 0)
00454 {
00455 ExerciseItem *chapter = chapterByName(chapterName);
00456 removeExercise(chapter, exerciseName);
00457 }
00458 else
00459 {
00460 ExerciseItem *chapter = chapterById(chapterId);
00461 removeExercise(chapter, exerciseName);
00462 }
00463 reset();
00464 emit resetView();
00465 }
00466
00467 void ExerciseModel::removeChapter(int chapterID, QString chapterName)
00468 {
00469 for(int i = 0; i < rootItem->childCount(); i++)
00470 {
00471 ExerciseItem *chapter = rootItem->child(i);
00472 if(chapter->data(1).toMap().value("chapterId").toInt() == chapterID && chapter->data(0).toString() == chapterName)
00473 {
00474 rootItem->removeChild(chapter);
00475 }
00476 }
00477 reset();
00478 emit resetView();
00479 }
00480
00481 void ExerciseModel::removeExercise(ExerciseItem *chapter, QString exerciseName)
00482 {
00483 for(int i = 0; i < chapter->childCount(); i++)
00484 {
00485 ExerciseItem *child = chapter->child(i);
00486 if(child->data(0).toString() == exerciseName)
00487 {
00488 chapter->removeChild(child);
00489 }
00490 }
00491 reset();
00492 emit resetView();
00493 }
00494
00495 ExerciseItem* ExerciseModel::chapterById(uint chapterId)
00496 {
00497 for(int i = 0; i < rootItem->childCount(); i++)
00498 {
00499 ExerciseItem *chapter = rootItem->child(i);
00500 if(chapter->data(1).toMap().value("chapterId").toUInt() == chapterId)
00501 {
00502 return chapter;
00503 }
00504 }
00505 return 0;
00506 }
00507
00508 ExerciseItem* ExerciseModel::chapterByName(QString chapterName)
00509 {
00510 for(int i = 0; i < rootItem->childCount(); i++)
00511 {
00512 ExerciseItem *chapter = rootItem->child(i);
00513 if(chapter->data(0).toString() == chapterName)
00514 {
00515 return chapter;
00516 }
00517 }
00518 return 0;
00519 }
00520
00521 int ExerciseModel::chapterID(QString chapterName)
00522 {
00523 int id = -1;
00524 for(int i = 0; i < rootItem->childCount(); i++)
00525 {
00526 ExerciseItem *chapter = rootItem->child(i);
00527 if(chapter->data(0).toString() == chapterName)
00528 {
00529 id = chapter->data(1).toMap().value("chapterId").toInt();
00530 }
00531 }
00532 return id;
00533 }
00534
00535 QString ExerciseModel::chapterName(uint chapterId)
00536 {
00537 return chapterById(chapterId)->data(0).toString();
00538 }
00539
00540 bool ExerciseModel::existsChapter(QString chapterName)
00541 {
00542 bool found = false;
00543 for(int i = 0; i < rootItem->childCount(); i++)
00544 {
00545 ExerciseItem *chapter = rootItem->child(i);
00546 if(chapter->data(0).toString() == chapterName)
00547 {
00548 found = true;
00549 }
00550 }
00551 return found;
00552 }
00553
00554 bool ExerciseModel::existsExercise(QString chapterName, QString exerciseName)
00555 {
00556 bool found = false;
00557 ExerciseItem *chapter = chapterByName(chapterName);
00558 for(int i = 0; i < chapter->childCount(); i++)
00559 {
00560 ExerciseItem *exercise = chapter->child(i);
00561 if(exercise->data(0).toString() == exerciseName)
00562 {
00563 found = true;
00564 }
00565 }
00566 return found;
00567 }
00568
00569 ExerciseItem::ExerciseItem(const QVariantList &data, ExerciseItem *parent)
00570 {
00571 infos = data;
00572 parentItem = parent;
00573 maxExerciseId = 0;
00574 checkState = Qt::Unchecked;
00575 }
00576
00577 ExerciseItem* ExerciseItem::parent()
00578 {
00579 return parentItem;
00580 }
00581
00582 ExerciseItem *ExerciseModel::getExercise(QString chapterName, QString exerciseName) const
00583 {
00584 ExerciseItem *result = NULL;
00585
00586 for(int i=0; i < rootItem->childCount(); i++)
00587 {
00588 ExerciseItem *chapterItem = rootItem->child(i);
00589 if(chapterItem->data(0).toString() == chapterName)
00590 {
00591 for(int j=0; j < chapterItem->childCount(); j++)
00592 {
00593 ExerciseItem *exerciseItem = chapterItem->child(j);
00594 if(exerciseItem->data(0).toString() == exerciseName)
00595 {
00596 result = exerciseItem;
00597 }
00598 }
00599 }
00600 }
00601 return result;
00602 }
00603
00604 void ExerciseModel::drawTreeOnDebugOutput()
00605 {
00606 qDebug()<<"The ExerciseSelectionViewTree";
00607 qDebug()<<"INFORMATION";
00608 qDebug()<<"Chapter --> chapterName, chapterId";
00609 qDebug()<<"Exercise --> exerciseName, exerciseId, state, chapterId";
00610 ExerciseItem *root = rootItem;
00611 for(int i = 0; i < root->childCount(); i++)
00612 {
00613 ExerciseItem *chapter = root->child(i);
00614 qDebug()<<chapter->data(0).toString()<<" "<<chapter->data(1).toMap().value("chapterId").toUInt();
00615 for(int j = 0; j < chapter->childCount(); j++)
00616 {
00617 ExerciseItem *exercise = chapter->child(j);
00618 qDebug()<<" "<<exercise->data(0).toString()<<" "<<exercise->data(1).toMap().value("exerciseId").toUInt()<<" "<<exercise->data(1).toMap().value("state").toUInt()<<" "<<exercise->data(1).toMap().value("chapterId").toUInt();
00619 }
00620 }
00621 }
00622
00623 ExerciseItem *ExerciseModel::getItemByName(QString name) const
00624 {
00625 ExerciseItem *result = NULL;
00626
00627 for(int i=0; i < rootItem->childCount(); i++)
00628 {
00629 ExerciseItem *chapterItem = rootItem->child(i);
00630 if(chapterItem->data(0).toString() == name)
00631 {
00632 result = chapterItem;
00633 break;
00634 }
00635 else
00636 {
00637 for(int j = 0; j < chapterItem->childCount(); j++)
00638 {
00639 ExerciseItem *exerciseItem = chapterItem->child(j);
00640 if(exerciseItem->data(0).toString() == name)
00641 {
00642 result = exerciseItem;
00643 break;
00644 }
00645 }
00646 }
00647 }
00648
00649 return result;
00650 }
00651
00652
00653 int ExerciseItem::childCount() const
00654 {
00655 return this->childItems.count();
00656 }
00657
00658 int ExerciseItem::columnCount() const
00659 {
00660 return this->infos.count();
00661 }
00662
00663 ExerciseItem *ExerciseItem::child(int row)
00664 {
00665 return this->childItems.value(row);
00666 }
00667
00668 QVariant ExerciseItem::data(int column) const
00669 {
00670 return infos.value(column);
00671 }
00672
00673 bool ExerciseItem::setData(QVariant value, int column) const
00674 {
00675 bool result = false;
00676
00677 if(column < this->infos.size())
00678 {
00679
00680
00681
00682
00683 infos.value(column)=value;
00684 result=true;
00685 }
00686 return result;
00687 }
00688
00689 int ExerciseItem::row() const
00690 {
00691 if(parentItem)
00692 {
00693 return parentItem->childItems.indexOf(const_cast<ExerciseItem*>(this));
00694 }
00695 return 0;
00696 }
00697
00698 void ExerciseItem::addChild(ExerciseItem *item)
00699 {
00700 childItems.append(item);
00701 }
00702
00703 void ExerciseItem::removeChild(ExerciseItem *item)
00704 {
00705 childItems.removeAll(item);
00706 }
00707
00708 int ExerciseItem::positionOfExerciseById(uint exerciseId)
00709 {
00710 for(int i = 0; i < childCount(); i++)
00711 {
00712 ExerciseItem *item = child(i);
00713 if(item->data(1).toMap().value("exerciseId").toUInt() == exerciseId)
00714 {
00715 return i;
00716 }
00717 }
00718 return 0;
00719 }