00001 #include <QStringList>
00002 #include <QDomDocument>
00003 #include <QDebug>
00004 #include <QFile>
00005 #include "costpositionmodel.h"
00006
00007 CostPositionModel::CostPositionModel(QObject *parent, bool empty) : QAbstractItemModel(parent)
00008 {
00009 qDebug()<<"Improvement needed: CostPositionModel -- better way for getting the CostPositionItem* from the pointer in the data-methode";
00010
00011 QList<QVariant> rootData;
00012 rootData << tr("Kostenpositionen");
00013 rootItem = new CostPositionItem(rootData);
00014
00015 if(!empty)
00016 {
00017 readCategories();
00018 }
00019 }
00020
00021 CostPositionModel::~CostPositionModel()
00022 {
00023 delete rootItem;
00024 }
00025
00026 int CostPositionModel::columnCount(const QModelIndex &parent) const
00027 {
00028 if(parent.isValid())
00029 {
00030 return static_cast<CostPositionItem*>(parent.internalPointer())->columnCount();
00031 }
00032 else
00033 {
00034 return rootItem->columnCount();
00035 }
00036 }
00037
00038 QVariant CostPositionModel::data(const QModelIndex &index, int role) const
00039 {
00040 if(!index.isValid())
00041 {
00042 return QVariant();
00043 }
00044
00045 if(role != Qt::DisplayRole && role != 32)
00046 {
00047 return QVariant();
00048 }
00049 else if(role == 32)
00050 {
00051 CostPositionItem *item = getCostPositionItem(index.data(Qt::DisplayRole).toString(), index.parent().data(Qt::DisplayRole).toString());
00052 return item->itemInfo();
00053 }
00054 else
00055 {
00056 CostPositionItem *item = static_cast<CostPositionItem*>(index.internalPointer());
00057 return item->data(index.column());
00058 }
00059 }
00060
00061 CostPositionItem* CostPositionModel::getCostPositionItem(QString name, QString secName) const
00062 {
00063 CostPositionItem* root = rootItem;
00064 for(int i = 0; i != root->childCount(); i++)
00065 {
00066 CostPositionItem *category = root->child(i);
00067 if(category->data(0).toString() == secName)
00068 {
00069 for(int j=0; j!=category->childCount(); j++)
00070 {
00071 CostPositionItem *item = category->child(j);
00072 if(item->data(0).toString() == name)
00073 {
00074 return item;
00075 }
00076 }
00077 }
00078 }
00079 return new CostPositionItem(QVariantList());
00080 }
00081
00082 Qt::ItemFlags CostPositionModel::flags(const QModelIndex &index) const
00083 {
00084 if(!index.isValid())
00085 {
00086 return 0;
00087 }
00088
00089 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
00090 }
00091
00092 QVariant CostPositionModel::headerData(int section, Qt::Orientation orientation, int role) const
00093 {
00094 if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
00095 {
00096 return rootItem->data(section);
00097 }
00098
00099 return QVariant();
00100 }
00101
00102 QModelIndex CostPositionModel::index(int row, int column, const QModelIndex &parent) const
00103 {
00104 if(!hasIndex(row, column, parent))
00105 {
00106 return QModelIndex();
00107 }
00108
00109 CostPositionItem *parentItem;
00110
00111 if(!parent.isValid())
00112 {
00113 parentItem = rootItem;
00114 }
00115 else
00116 {
00117 parentItem = static_cast<CostPositionItem*>(parent.internalPointer());
00118 }
00119
00120 CostPositionItem *childItem = parentItem->child(row);
00121 if(childItem)
00122 {
00123 return createIndex(row, column, childItem);
00124 }
00125 else
00126 {
00127 return QModelIndex();
00128 }
00129 }
00130
00131 QModelIndex CostPositionModel::parent(const QModelIndex &index) const
00132 {
00133 if(!index.isValid())
00134 {
00135 return QModelIndex();
00136 }
00137
00138 CostPositionItem *childItem = static_cast<CostPositionItem*>(index.internalPointer());
00139 CostPositionItem *parentItem = childItem->parent();
00140
00141 if(parentItem == rootItem)
00142 {
00143 return QModelIndex();
00144 }
00145
00146 return createIndex(parentItem->row(), 0, parentItem);
00147 }
00148
00149 int CostPositionModel::rowCount(const QModelIndex &parent) const
00150 {
00151 CostPositionItem *parentItem;
00152 if(parent.column() > 0)
00153 return 0;
00154
00155 if(!parent.isValid())
00156 {
00157 parentItem = rootItem;
00158 }
00159 else
00160 {
00161 parentItem = static_cast<CostPositionItem*>(parent.internalPointer());
00162 }
00163 return parentItem->childCount();
00164 }
00165
00166 void CostPositionModel::addCategory(uint sectionid, QString name, bool editable)
00167 {
00168 QMap<QString, QVariant> d;
00169 QVariantList c;
00170
00171 d.insert("sectionId", sectionid);
00172 d.insert("editable", editable);
00173
00174 c<<name;
00175 c<<d;
00176
00177 rootItem->appendChild(new CostPositionItem(c, rootItem));
00178 reset();
00179 }
00180
00181 void CostPositionModel::addCostPosition(QString desc, QString lang, int action, int costtype, QString secName, bool editable)
00182 {
00183 if(existsCategory(secName))
00184 {
00185 if(!existsPositionInCategory(desc, getSectionId(secName)))
00186 {
00187 addPosition(desc, lang, action, costtype, getSectionId(secName), editable);
00188 }
00189 }
00190 else
00191 {
00192 int count = rootItem->childItems.count();
00193 addCategory(count++, secName, editable);
00194 addPosition(desc, lang, action, costtype, getSectionId(secName), editable);
00195 }
00196 }
00197
00198 void CostPositionModel::addPosition(QString desc, QString lang, int action, int costtype, int sectionid, bool editable)
00199 {
00200 for(int i=0; i < rootItem->childCount();i++)
00201 {
00202 CostPositionItem *cate = rootItem->child(i);
00203 if(cate->data(1).toMap().value("sectionId").toInt() == sectionid)
00204 {
00205 QMap<QString, QVariant> data;
00206 QVariantList columnData;
00207
00208 data.insert("language", lang);
00209 data.insert("action", action);
00210 data.insert("costtype", costtype);
00211 data.insert("sectionId", sectionid);
00212 data.insert("editable", editable);
00213
00214 columnData<<desc;
00215 columnData<<data;
00216
00217 rootItem->childItems.value(i)->appendChild(new CostPositionItem(columnData, rootItem->childItems.value(i)));
00218 reset();
00219 }
00220 }
00221 }
00222
00223 int CostPositionModel::getSectionId(QString cat)
00224 {
00225 int id = -1;
00226 for(int i=0; i!=rootItem->childCount(); i++)
00227 {
00228 CostPositionItem *cate = rootItem->child(i);
00229 if(cate->data(0).toString() == cat)
00230 {
00231 id = cate->data(1).toMap().value("sectionId").toInt();
00232 }
00233 }
00234 return id;
00235 }
00236
00237 int CostPositionModel::getSectionIdFromPosition(QString positionName)
00238 {
00239 for(int i=0; i < rootItem->childCount(); i++)
00240 {
00241 CostPositionItem *cat= rootItem->child(i);
00242 for(int j=0; j < cat->childCount(); j++)
00243 {
00244 CostPositionItem *item = cat->child(j);
00245 if(item->data(0).toString() == positionName)
00246 {
00247 return item->data(1).toMap().value("section-id").toInt();
00248 }
00249 }
00250 }
00251 return -1;
00252 }
00253
00254 QString CostPositionModel::getCategoryNameFromSectionId(int sectionId)
00255 {
00256 CostPositionItem *root = rootItem;
00257 QString name;
00258 for(int i=0; i!=root->childCount(); i++)
00259 {
00260 CostPositionItem *cat = root->child(i);
00261 if(cat->data(1).toMap().value("sectionId").toInt() == sectionId)
00262 {
00263 name = cat->data(0).toString();
00264 }
00265 }
00266 return name;
00267 }
00268
00269 bool CostPositionModel::existsCategory(QString name)
00270 {
00271 bool exist = false;
00272 for(int i=0; i!=rootItem->childCount(); i++)
00273 {
00274 CostPositionItem *cate = rootItem->child(i);
00275 if(cate->data(0).toString() == name)
00276 {
00277 exist = true;
00278 }
00279 }
00280 return exist;
00281 }
00282
00283 bool CostPositionModel::existsPositionInCategory(QString posName, int sectionid)
00284 {
00285 bool exist = false;
00286 for(int i=0; i!=rootItem->childCount(); i++)
00287 {
00288 CostPositionItem *cate = rootItem->child(i);
00289 if(cate->data(1).toMap().value("id").toInt() == sectionid)
00290 {
00291 for(int j=0; j!=cate->childCount(); j++)
00292 {
00293 CostPositionItem *pos = cate->child(j);
00294 if(pos->data(0).toString() == posName)
00295 {
00296 exist = true;
00297 }
00298 }
00299
00300 }
00301 }
00302 return exist;
00303 }
00304
00305 bool CostPositionModel::isCategoryEditable(int sectionId)
00306 {
00307 for(int i=0; i < rootItem->childCount(); i++)
00308 {
00309 CostPositionItem *cat = rootItem->child(i);
00310 if(cat->data(1).toMap().value("sectionId").toInt() == sectionId)
00311 {
00312 if(cat->data(1).toMap().value("editable").toBool() == true)
00313 {
00314 return true;
00315 }
00316 }
00317 }
00318 return false;
00319 }
00320
00321 bool CostPositionModel::isPositionEditable(QString positionName, int sectionId)
00322 {
00323 for(int i=0; i < rootItem->childCount(); i++)
00324 {
00325 CostPositionItem *cat = rootItem->child(i);
00326 qDebug()<<getSectionIdFromPosition(positionName);
00327 if(cat->data(1).toMap().value("sectionId").toInt() == sectionId)
00328 {
00329 for(int j=0; j < cat->childCount(); j++)
00330 {
00331 CostPositionItem *item = cat->child(j);
00332 if(item->data(0).toString() == positionName)
00333 {
00334 if(item->data(1).toMap().value("editable").toBool() == true)
00335 {
00336 return true;
00337 }
00338 }
00339 }
00340 }
00341 }
00342 return false;
00343 }
00344
00345 void CostPositionModel::deletePosition(QString positionname, int sectionId)
00346 {
00347 for(int i=0; i!=rootItem->childCount(); i++)
00348 {
00349 CostPositionItem *cat = rootItem->child(i);
00350 if(cat->data(1).toMap().value("sectionId").toInt() == sectionId)
00351 {
00352 for(int j=0; j!=cat->childCount(); j++)
00353 {
00354 CostPositionItem *item = cat->child(j);
00355 if(item->data(0).toString() == positionname)
00356 {
00357 cat->removeChild(item);
00358 reset();
00359 return;
00360 }
00361 }
00362 }
00363 }
00364 }
00365
00366 void CostPositionModel::deleteCategory(int sectionid)
00367 {
00368 for(int i=0; i!=rootItem->childCount(); i++)
00369 {
00370 CostPositionItem *cat = rootItem->child(i);
00371 if(cat->data(1).toMap().value("sectionId").toInt() == sectionid)
00372 {
00373 qDebug()<<i<<" "<<rootItem->childItems.size();
00374 rootItem->removeChild(cat);
00375 reset();
00376 return;
00377 }
00378 }
00379 }
00380
00381 void CostPositionModel::editCategory(QString oldCat, QString newCat)
00382 {
00383 for(int i=0; i < rootItem->childCount(); i++)
00384 {
00385 CostPositionItem *cat = rootItem->child(i);
00386 if(cat->data(0).toString() == oldCat)
00387 {
00388
00389
00390 QMap<QString, QVariant> d;
00391 QVariantList c;
00392
00393 d.insert("sectionId", cat->data(1).toMap().value("sectionId"));
00394 d.insert("editable", cat->data(1).toMap().value("editable"));
00395
00396 c<<newCat;
00397 c<<d;
00398 CostPositionItem *cate = new CostPositionItem(c, rootItem);
00399
00400
00401 rootItem->childItems.replace(i, cate);
00402
00403 addOtherPositions(cate->data(1).toMap().value("sectionId").toInt(), cat);
00404
00405
00406 reset();
00407 return;
00408 }
00409 }
00410 }
00411
00412 void CostPositionModel::addOtherPositions(int sectionId, CostPositionItem *&oldCat)
00413 {
00414
00415
00416 for(int i=0; i!=rootItem->childCount(); i++)
00417 {
00418 CostPositionItem *cate = rootItem->child(i);
00419 if(cate->data(1).toMap().value("sectionId").toInt() == sectionId)
00420 {
00421 for(int j=0; j!= oldCat->childCount(); j++)
00422 {
00423 CostPositionItem *item = oldCat->child(j);
00424 QMap<QString, QVariant> d;
00425 QVariantList c;
00426
00427 d.insert("sectionId", item->data(1).toMap().value("sectionId"));
00428 d.insert("editable", item->data(1).toMap().value("editable"));
00429 d.insert("action", item->data(1).toMap().value("action"));
00430 d.insert("costtype", item->data(1).toMap().value("costtype"));
00431 d.insert("language", item->data(1).toMap().value("language"));
00432
00433 c<<item->data(0).toString();
00434 c<<d;
00435
00436 CostPositionItem *position = new CostPositionItem(c, cate);
00437 cate->appendChild(position);
00438 reset();
00439 }
00440 }
00441 }
00442 }
00443
00444 void CostPositionModel::editPosition(QMap<QString, QVariant> *changes)
00445 {
00446 if(changes->value("newCategoryName").toString() != changes->value("oldCategoryName").toString())
00447 {
00448 if(!existsCategory(changes->value("newCategory").toString()))
00449 {
00450 addCategory(rootItem->childCount(), changes->value("newCategoryName").toString(), true);
00451 }
00452 CostPositionItem *item = getCostPositionItem(changes->value("oldPositionName").toString(), changes->value("oldCategoryName").toString());
00453
00454 QVariantList list = item->itemInfo();
00455 CostPositionItem *temp = new CostPositionItem(list, rootItem->child(rootItem->childCount()-1));
00456
00457 rootItem->child(rootItem->childCount()-1)->appendChild(temp);
00458 rootItem->child(getSectionId(changes->value("oldCategoryName").toString()))->removeChild(item);
00459
00460 }
00461 if(changes->value("newPositionName").toString() != changes->value("oldPositionName").toString() || changes->value("newAction").toInt() != changes->value("oldAction").toInt() || changes->value("newCosttype").toInt() != changes->value("oldCosttype").toInt())
00462 {
00463 CostPositionItem *item = getCostPositionItem(changes->value("oldPositionName").toString(), changes->value("newCategoryName").toString());
00464 rootItem->child(getSectionId(changes->value("newCategoryName").toString()))->removeChild(item);
00465 addPosition(changes->value("newPositionName").toString(), "de", changes->value("newAction").toInt(), changes->value("newCosttype").toInt(), getSectionId(changes->value("newCategoryName").toString()), true);
00466 }
00467 reset();
00468 }
00469
00470
00471 void CostPositionModel::readCategories()
00472 {
00473 QFile file(":/data/costpositions");
00474 QDomDocument doc("Allevo");
00475 if(!file.open(QIODevice::ReadOnly))
00476 {
00477 emit costTypePositionsNotReadable();
00478 return;
00479 }
00480 if(!doc.setContent(&file))
00481 {
00482 emit costTypePositionsNotReadable();
00483 file.close();
00484 return;
00485 }
00486 file.close();
00487
00488
00489 clearPositions();
00490
00491
00492 emit clearCostPositions(false);
00493
00494 QStringList documentinfo = QStringList();
00495 QStringList h = QStringList();
00496 QDomElement root = doc.documentElement();
00497 QDomNode node;
00498 node = root.firstChild();
00499 while(!node.isNull())
00500 {
00501 if(node.isElement() && node.nodeName() == "section")
00502 {
00503 QDomElement e = node.toElement();
00504 addCategory(e.attribute("id").toInt(), e.attribute("desc"), (e.attribute("editable")=="true")?true:false);
00505
00506 QDomElement info = node.toElement();
00507 QDomNode n = info.firstChild();
00508 while(!n.isNull())
00509 {
00510 if(n.isElement())
00511 {
00512 if(n.nodeName() == "category")
00513 {
00514 QDomElement element = n.toElement();
00515 QDomElement e2 = node.toElement();
00516
00517
00518 addCostPosition(element.attribute("name"), element.attribute("lang"), element.attribute("action").toInt(), element.attribute("costtype").toInt(), e.attribute("desc"), (element.attribute("editable")=="true")?true:false);
00519 }
00520 n = n.nextSibling();
00521 }
00522 }
00523 node = node.nextSibling();
00524 }
00525 }
00526 }
00527
00528 QDomElement CostPositionModel::dataNode()
00529 {
00530 QDomDocument doc;
00531 QDomElement categories = doc.createElement("categories");
00532 bool found = false;
00533
00534 CostPositionItem *root = rootItem;
00535 for(int i = 0; i != root->childCount(); i++)
00536 {
00537 CostPositionItem *category = root->child(i);
00538 QDomElement section = doc.createElement("section");
00539 section.setAttribute("name", category->data(0).toString());
00540 section.setAttribute("lang", "de");
00541 section.setAttribute("sectionId", category->data(1).toMap().value("sectionId").toString());
00542 section.setAttribute("editable", category->data(1).toMap().value("editable").toString());
00543 categories.appendChild(section);
00544 for(int j = 0; j != category->childCount(); j++)
00545 {
00546 CostPositionItem *item = category->child(j);
00547 if(item->data(1).toMap().value("editable").toBool())
00548 {
00549 found = true;
00550 QDomElement position = doc.createElement("position");
00551 position.setAttribute("positionName", item->data(0).toString());
00552 position.setAttribute("action", item->data(1).toMap().value("action").toString());
00553 position.setAttribute("costtype", item->data(1).toMap().value("costtype").toString());
00554 position.setAttribute("lang", item->data(1).toMap().value("language").toString());
00555 position.setAttribute("editable", item->data(1).toMap().value("editable").toString());
00556 section.appendChild(position);
00557 }
00558 }
00559 if(!found)
00560 {
00561 categories.removeChild(section);
00562 }
00563 else
00564 {
00565 found = false;
00566 }
00567 }
00568 return categories;
00569 }
00570
00571 void CostPositionModel::clearPositions()
00572 {
00573 int counter = 0;
00574 while(rootItem->childCount() > 0)
00575 {
00576 CostPositionItem *item = rootItem->child(counter);
00577 item->removeChilds();
00578
00579 rootItem->removeChild(item);
00580 }
00581 }
00582
00583 CostPositionItem::CostPositionItem(const QVariantList &data, CostPositionItem *parent)
00584 {
00585 parentItem = parent;
00586 itemData = data;
00587 }
00588
00589 CostPositionItem::~CostPositionItem()
00590 {
00591 qDeleteAll(childItems);
00592 }
00593
00594 void CostPositionItem::appendChild(CostPositionItem *item)
00595 {
00596 childItems.append(item);
00597 }
00598
00599 void CostPositionItem::removeChild(CostPositionItem *item)
00600 {
00601 childItems.removeAll(item);
00602 }
00603
00604 void CostPositionItem::removeChilds()
00605 {
00606 childItems.clear();
00607 }
00608
00609 CostPositionItem *CostPositionItem::child(int row)
00610 {
00611 return childItems.value(row);
00612 }
00613
00614 int CostPositionItem::childCount() const
00615 {
00616 return childItems.count();
00617 }
00618
00619 int CostPositionItem::columnCount() const
00620 {
00621 return itemData.count();
00622 }
00623
00624 QVariant CostPositionItem::data(int column) const
00625 {
00626 return itemData.value(column);
00627 }
00628
00629 QVariantList CostPositionItem::itemInfo() const
00630 {
00631 return itemData;
00632 }
00633
00634 QMap<QString, QVariant> CostPositionItem::itemInformation()
00635 {
00636 return itemData.value(0).value<QMap<QString, QVariant> >();
00637 }
00638
00639 CostPositionItem *CostPositionItem::parent()
00640 {
00641 return parentItem;
00642 }
00643
00644 int CostPositionItem::row() const
00645 {
00646 if(parentItem)
00647 {
00648 return parentItem->childItems.indexOf(const_cast<CostPositionItem*>(this));
00649 }
00650 return 0;
00651 }