Guest User

model of "classeurs" QTreeView

a guest
Feb 24th, 2015
201
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. #include "classeurs_model.h"
  3. #include "classeurs_treeview.h"
  4. #include "classeur.h"
  5. #include <QSqlQuery>
  6. #include <QSqlRecord>
  7. #include <QMessageBox>
  8.  
  9. Classeurs_Model::Classeurs_Model(QObject *parent):
  10. QAbstractItemModel(parent) {
  11.  
  12. // user_controler *db;
  13. // db->getInstance();
  14. // db->initdb();
  15. db_coordonates.col_FK = "";
  16. db_coordonates.fields << "nom" << "comment"
  17. << "tree_id" << "tree_id_parent"
  18. << "id";
  19. db_coordonates.id_FK = 0;
  20. db_coordonates.table = "Classeurs";
  21. db_coordonates.linker_table = "ClasseurRef";
  22. QVector<QVariant> headers;
  23. headers << tr("Classeurs") << tr("Description") << tr("id") << tr("id parent") << "ID";
  24. root_classeur = new Classeur(headers);
  25. // for(int i(0); i < headers.count(); i++)
  26. // setHeaderData(i, Qt::Horizontal, headers[i]);
  27. }
  28.  
  29. Classeurs_Model::~Classeurs_Model() {
  30.  
  31. }
  32.  
  33. QModelIndex Classeurs_Model::parent(const QModelIndex &index) const {
  34. if(!index.isValid())
  35. return QModelIndex();
  36. Classeur *childClasseur = getClasseur(index);
  37. Classeur *parentClasseur = childClasseur->parent();
  38. if(parentClasseur == root_classeur)
  39. return QModelIndex();
  40. return createIndex(parentClasseur->childNumber(), 0, parentClasseur);
  41. }
  42.  
  43. QModelIndex Classeurs_Model::index(int row,
  44. int column,
  45. const QModelIndex &parent) const {
  46. if (parent.isValid() && parent.column() != 0)
  47. return QModelIndex();
  48.  
  49. Classeur *parentClasseur = getClasseur(parent);
  50. Classeur *childClasseur = parentClasseur->child(row);
  51. if (childClasseur)
  52. return createIndex(row, column, childClasseur);
  53. else
  54. return QModelIndex();
  55.  
  56. }
  57.  
  58. QModelIndex Classeurs_Model::indexOf(Classeur *classeur) {
  59. return createIndex(0,0,classeur->parent());
  60. }
  61.  
  62. Qt::ItemFlags Classeurs_Model::flags(const QModelIndex &index) const {
  63. if(!index.isValid())
  64. return 0;
  65. return Qt::ItemIsEditable |
  66. Qt::ItemIsEnabled |
  67. Qt::ItemIsSelectable |
  68. QAbstractItemModel::flags(index);
  69. }
  70.  
  71. QVariant Classeurs_Model::data(const QModelIndex &index,
  72. int role) const {
  73. if(index.isValid() &&
  74. (role == Qt::DisplayRole ||
  75. role == Qt::EditRole)) {
  76. Classeur *classeur = getClasseur(index);
  77. return classeur->data(index.column()); }
  78. return QVariant();
  79. }
  80.  
  81. bool Classeurs_Model::setData(const QModelIndex &index,
  82. const QVariant &value,
  83. int role) {
  84. if (role != Qt::EditRole)
  85. return false;
  86. Classeur *classeur = getClasseur(index);
  87. bool result = classeur->setData(index.column(), value);
  88. if (result) {
  89. QVector<int> role; role << Qt::EditRole;
  90. emit dataChanged(index, index, role); }
  91. return result;
  92. }
  93.  
  94. int Classeurs_Model::columnCount(const QModelIndex &parent) const {
  95. return 4;
  96. }
  97.  
  98. int Classeurs_Model::rowCount(const QModelIndex &parent) const {
  99. Classeur *parentClasseur = getClasseur(parent);
  100. return parentClasseur->childCount();
  101. }
  102.  
  103. QVariant Classeurs_Model::headerData(int section,
  104. Qt::Orientation orientation,
  105. int role) const {
  106. if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
  107. return root_classeur->data(section);
  108. return QVariant();
  109. }
  110.  
  111. bool Classeurs_Model::setHeaderData(int section,
  112. Qt::Orientation orientation,
  113. const QVariant &value,
  114. int role) {
  115. if (role != Qt::EditRole || orientation != Qt::Horizontal)
  116. return false;
  117. bool result = root_classeur->setData(section, value);
  118. if (result)
  119. emit headerDataChanged(orientation, section, section);
  120. return result;
  121. }
  122.  
  123. bool Classeurs_Model::insertRows(int position,
  124. int rows,
  125. const QModelIndex &parent) {
  126. Classeur *parentClasseur = getClasseur(parent);
  127. bool success;
  128. beginInsertRows(parent, position, position + rows - 1);
  129. success = parentClasseur->insertChildren(position, rows);
  130. endInsertRows();
  131. return success;
  132. }
  133.  
  134. bool Classeurs_Model::insertClasseur(const QVector<QVariant> &datas,
  135. int position,
  136. const QModelIndex &parent) {
  137. bool success, result;
  138. Classeur *parentClasseur = getClasseur(parent);
  139. beginInsertRows(parent, position, position);
  140. success = parentClasseur->insertChildren(position, 1);
  141. endInsertRows();
  142. if(success) {
  143. for(int column(0); column < 4; ++column) {
  144. if(column != 2) {
  145. result = parentClasseur->child(position)
  146. ->setData(column, datas[column]);
  147. if (!result)
  148. return false; } } }
  149. if (success && result) {
  150. QVector<QVariant> db_datas = datas;
  151. db_datas[2] = parentClasseur->child(position)->getID_tree();
  152. QVector<QVariant> part3;
  153. part3 << db_datas[0] << db_datas[1];
  154. QHash<int, QVector<QVariant> > part2;
  155. part2.insert(db_datas[2].toInt(), part3);
  156. db_Classeurs.insert(db_datas[3].toInt(), part2);
  157. return true; }
  158. return false;
  159. }
  160.  
  161. bool Classeurs_Model::removeClasseur(const QModelIndex &index) {
  162. bool success, result;
  163. Classeur *parentClasseur = getClasseur(index.parent());
  164. Classeur *classeur = getClasseur(index);
  165. while(classeur->hasChildren()) {
  166. QModelIndex child = this->index(0,0,index);
  167. removeClasseur(child); }
  168. int id_parent = classeur->getID_tree_parent();
  169. int id = classeur->getID_tree();
  170. int id_classeur = classeur->getID_classeur();
  171. QVariant name = classeur->getName();
  172. QVariant comment = classeur->getComment();
  173. QHash<int, QVector<QVariant> > level2;
  174. QVector<QVariant> level3;
  175. level3 << name << comment;
  176. if(id_classeur != 0) {
  177. if(!deleteIntoDB(id_classeur))
  178. return false;
  179. level3 << id_classeur; }
  180. level2.insert(id, level3);
  181. db_Classeurs.remove(id_parent, level2);
  182. beginRemoveRows(index.parent(), index.row(), index.row());
  183. success = parentClasseur->removeChildren(index.row(), 1);
  184. endRemoveRows();
  185. if(success) {
  186. cleanDatasRange(); // redefine datas to be clear and well organized
  187. return true; }
  188. return false;
  189. }
  190.  
  191. bool Classeurs_Model::removeRows(int position,
  192. int rows,
  193. const QModelIndex &parent) {
  194. Classeur *parentClasseur = getClasseur(parent);
  195. bool success = true;
  196. beginRemoveRows(parent, position, position + rows - 1);
  197. success = parentClasseur->removeChildren(position, rows);
  198. endRemoveRows();
  199. return success;
  200. }
  201. //int Classeurs_Model::totalRowCount(const QModelIndex &parent) const {
  202. //}
  203.  
  204. void Classeurs_Model::setModel(const QString &colFK,
  205. const int &idFK,
  206. const QStringList &order_list,
  207. const QStringList &fields,
  208. const QString &table,
  209. const QString &fTable,
  210. const order &type) {
  211.  
  212. QString field_list;
  213. db_coordonates.col_FK = colFK;
  214. db_coordonates.id_FK = idFK;
  215. if(fields[0] != "")
  216. db_coordonates.fields = fields;
  217. db_coordonates.table = table;
  218. db_coordonates.linker_table = fTable;
  219. foreach(QString field, db_coordonates.fields)
  220. field_list += (!field_list.isEmpty()) ?
  221. QString(", c.%1").arg(field) :
  222. QString(" c.%1").arg(field);
  223. query_str = QString("SELECT %1 FROM \"%2\" c, \"%3\" r "
  224. "WHERE c.id = r.id_classeur "
  225. "AND r.%4 = %5 ;")
  226. .arg(field_list).arg(table)
  227. .arg(fTable).arg(colFK).arg(idFK);
  228. QString list_order;
  229. foreach(QVariant field, order_list)
  230. list_order += (!list_order.isEmpty()) ?
  231. QString("ORDER BY (%1").arg(field.toString()) :
  232. QString(", %2").arg(field.toString());
  233. list_order += ") ";
  234. switch (type) {
  235. case ASC: list_order += "ASC "; break;
  236. case DESC: list_order += "DESC"; break; }
  237. query_str.insert(-1, list_order);
  238. extractDatas();
  239. }
  240.  
  241.  
  242. void Classeurs_Model::setCol_FK(const QString &name) {
  243. db_coordonates.col_FK = name;
  244. }
  245.  
  246. void Classeurs_Model::setTable(const QString &name) {
  247. db_coordonates.table = name;
  248. }
  249.  
  250. void Classeurs_Model::setLinkerTable(const QString &name) {
  251. db_coordonates.table = name;
  252. }
  253.  
  254. void Classeurs_Model::setFieldsNames(const QVector<QString> &fields) {
  255. db_coordonates.fields.clear();
  256. foreach(QString field, fields)
  257. db_coordonates.fields << field;
  258. }
  259.  
  260. bool Classeurs_Model::extractDatas() {
  261. QSqlQuery query;
  262. if (!query_str.isEmpty()) {
  263. query.prepare(query_str);
  264. query.exec();
  265. int c_name = query.record().indexOf(db_coordonates.fields[0]);
  266. int c_comment = query.record().indexOf(db_coordonates.fields[1]);
  267. int c_id = query.record().indexOf(db_coordonates.fields[2]);
  268. int c_id_parent = query.record().indexOf(db_coordonates.fields[3]);
  269. int c_id_DB = query.record().indexOf(db_coordonates.fields[4]);
  270. db_Classeurs.clear();
  271. while(query.next()) {
  272. QVector<QVariant> values;
  273. values << query.value(c_name)
  274. << query.value(c_comment)
  275. << query.value(c_id_DB);
  276. QHash<int, QVector<QVariant>> level2;
  277. level2.insert(query.value(c_id).toInt(), values);
  278. db_Classeurs.insert(query.value(c_id_parent).toInt(), level2); }
  279. find_Childs(0, root_classeur); }
  280. }
  281.  
  282. void Classeurs_Model::find_Childs(int id_parent,
  283. Classeur *parent) {
  284. QList<QHash<int, QVector<QVariant>>>
  285. cols_id = db_Classeurs.values(id_parent);
  286. for(int c_id(0); c_id < cols_id.size(); ++ c_id) {
  287. QHash<int, QVector<QVariant>> col_id = cols_id[c_id];
  288. foreach(int id, col_id.keys()) {
  289. QVector<QVariant> row;
  290. row.clear();
  291. row << col_id.value(id)[0] << col_id.value(id)[1]
  292. << QVariant(id) << QVariant(id_parent)
  293. << col_id.value(id)[2];
  294. // QModelIndex idx = this->indexOf(parent);
  295. // beginInsertRows(idx, parent->childCount(), parent->childCount());
  296. parent->insertChildren(parent->childCount(), 1);
  297. // endInsertRows();
  298. for (int column = 0; column < 5; ++column)
  299. parent->child(parent->childCount() - 1)->setData(column, row[column]);
  300. if(!db_Classeurs.values(id).isEmpty())
  301. find_Childs(id, parent->child(parent->childCount() - 1)); } }
  302. }
  303.  
  304. bool Classeurs_Model::recordDatasToDB(int id_FK) {
  305. db_coordonates.id_FK = id_FK;
  306. bool success(false);
  307. int new_ID;
  308. foreach(int id_parent, db_Classeurs.keys()) {
  309. QList<QHash<int, QVector<QVariant>>>
  310. parent_values = db_Classeurs.values(id_parent);
  311. for(int c_idP(0); c_idP < parent_values.size(); ++c_idP) {
  312. QHash<int, QVector<QVariant>> parent_value = parent_values[c_idP];
  313. foreach(int id, parent_value.keys()) {
  314. QVector<QVariant> datas;
  315. datas << parent_value[id][0]
  316. << parent_value[id][1]
  317. << QVariant(id)
  318. << QVariant(id_parent);
  319. if(parent_value[id][2].isValid()) {
  320. datas << parent_value[id][2];
  321. success = updateDB(datas); }
  322. else
  323. success = insertIntoDB(datas); } } }
  324. if(success)
  325. if(root_classeur->hasChildren())
  326. success = recordFiles(root_classeur);
  327. return success;
  328. }
  329.  
  330. bool Classeurs_Model::recordFiles(Classeur *parent) {
  331. bool success(false);
  332. int rec_id_classeur(0);
  333. if(parent->hasChildren()) {
  334. foreach(Classeur *classeur, parent->childs()) {
  335. rec_id_classeur = classeur->getID_classeur();
  336. Files_Model *current_files_model = classeur->getFiles_model();
  337. // success = this->recordFilesFromModel(current_files_model,
  338. // current_files_model->index(0,0),
  339. // rec_id_classeur);
  340. if(success && classeur->hasChildren())
  341. success = recordFiles(classeur); } }
  342. return success;
  343. }
  344.  
  345. bool recordFilesFromModel(Files_Model *files_model,
  346. QModelIndex parent,
  347. int id_classeur) {
  348. QSqlQuery query;
  349. for(int i(0); i < files_model->rowCount(parent); i++) {
  350. QModelIndex Files_index = files_model->index(i, 0, parent);
  351. QRegExp tri(".*(\\.\\w*$)"); // sépare l'extention finale
  352. QString full_name = files_model->index(i, 4, parent).data().toString();
  353. QString name = files_model->index(i, 1, parent).data().toString(); //(nom entier)
  354. QString extname = full_name;
  355. extname.replace(tri, "\\1");
  356. QString directory;
  357. QString str_url = "file:" + full_name;
  358. QUrl url(str_url);
  359. QFileInfo file_url = url.toLocalFile();
  360. if(file_url.isDir()) {
  361. directory = file_url.absoluteFilePath();
  362. name = "";
  363. extname =""; }
  364. else
  365. directory = file_url.absolutePath();
  366. QString comment = files_model->index(i, 3, parent).data().toString();
  367. //**** Search if File exist allready find id *****
  368. int rec_id_file(0);
  369. query.prepare("SELECT id FROM \"Files\" "
  370. "WHERE name = :name "
  371. "AND directory = :directory ;" );
  372. query.bindValue(":name", name);
  373. query.bindValue(":directory", directory);
  374. if(!query.exec())
  375. return false;
  376. while(query.next())
  377. rec_id_file = query.value(0).toInt();
  378. if (rec_id_file == 0 ) { // if not exist
  379. //**** INSERT DATA SQL TABLE "Files" if not exist *************
  380. query.prepare("INSERT INTO \"Files\" "
  381. " ( name, extname, directory, comment) "
  382. "VALUES (:name, :extname, :directory, :comment) "
  383. "RETURNING id ;");
  384. query.bindValue(":name", name);
  385. query.bindValue(":directory", directory);
  386. query.bindValue(":extname", extname);
  387. query.bindValue(":comment", comment);
  388. if(!query.exec())
  389. return false;
  390. while(query.next())
  391. rec_id_file = query.value(0).toInt(); }
  392. //**** INSERT Link: Classeur<->Files in "FileRef" ***********
  393. query.prepare("INSERT INTO \"FileRef\" "
  394. " ( id_classeur, id_file) "
  395. "VALUES (:id_classeur, :id_file) ;");
  396. query.bindValue(":id_classeur", id_classeur);
  397. query.bindValue(":id_file", rec_id_file);
  398. if(!query.exec())
  399. return false;
  400. if(files_model->hasChildren(Files_index))
  401. if(!recordFilesFromModel(files_model, Files_index, id_classeur))
  402. qDebug() << QObject::tr("Erreur")
  403. << QObject::tr("Erreur lors de la recherche de fichiers"); }
  404. query.finish();
  405. query.clear();
  406. return true;
  407. }
  408.  
  409. bool Classeurs_Model::deleteIntoDB(int id_classeur) {
  410. QSqlDatabase::database().transaction();
  411. QSqlQuery query;
  412. query.prepare(QString("DELETE FROM \"%1\" "
  413. "WHERE id = :id_classeur ;")
  414. .arg(db_coordonates.table));
  415. query.bindValue(":id_classeur",id_classeur);
  416. if(!query.exec())
  417. return false;
  418. QSqlDatabase::database().commit();
  419. query.clear();
  420. return true;
  421. }
  422.  
  423. bool Classeurs_Model::insertIntoDB(const QVector<QVariant> &fields) {
  424. QSqlQuery query;
  425. query.prepare(QString("INSERT INTO \"%1\" "
  426. " ( %2, %3, %4, %5) "
  427. "VALUES ( :name, :comment, :tree_id, :tree_id_p) "
  428. "RETURNING id ;").arg(db_coordonates.table)
  429. .arg(db_coordonates.table)
  430. .arg(db_coordonates.fields[0])
  431. .arg(db_coordonates.fields[1])
  432. .arg(db_coordonates.fields[2])
  433. .arg(db_coordonates.fields[3]));
  434. query.bindValue(":name", fields[0].toString());
  435. query.bindValue(":comment", fields[1].toString());
  436. query.bindValue(":tree_id", fields[2].toInt());
  437. query.bindValue(":tree_id_p", fields[3].toInt());
  438. if(!query.exec())
  439. return false;
  440. int new_ID;
  441. while(query.next())
  442. new_ID = query.value(0).toInt();
  443. // insert le nouvel ID dans db_Classeurs pour l'enregistrement des fichiers et leur lien
  444. int c_id = fields[2].toInt();
  445. int c_id_parent = fields[3].toInt();
  446. // QMultiHash<int, QHash<int, QVector<QVariant>>>::iterator
  447. // i = db_Classeurs.find(c_id_parent);
  448. // while (i != db_Classeurs.end() && i.key() == c_id_parent) {
  449. // if( i.value().contains(c_id) )
  450. // *i[c_id] << QVariant(new_ID);
  451. // ++i;
  452. //}
  453. query.clear();
  454. query.prepare(QString("INSERT INTO \":%1\" "
  455. " ( id_classeur, %2) "
  456. "VALUES (:id_classeur, :id_FK) ;")
  457. .arg(db_coordonates.linker_table)
  458. .arg(db_coordonates.col_FK));
  459. query.bindValue(":id_classeur", new_ID);
  460. query.bindValue(":id_FK", db_coordonates.id_FK);
  461. if(!query.exec())
  462. return false;
  463. query.clear();
  464. return true;
  465. }
  466.  
  467. bool Classeurs_Model::updateDB(const QVector<QVariant> &fields) {
  468. QSqlQuery query;
  469. query.prepare(QString("UPDATE \"%1\" "
  470. "SET %2 = :nom, %3 = :comment, "
  471. "%4 = :tree_id, %5 = :tree_id_parent "
  472. "WHERE id = :id_classeur")
  473. .arg(db_coordonates.table)
  474. .arg(db_coordonates.fields[0])
  475. .arg(db_coordonates.fields[1])
  476. .arg(db_coordonates.fields[2])
  477. .arg(db_coordonates.fields[3]));
  478. query.bindValue(":nom", fields[0]);
  479. query.bindValue(":comment", fields[1]);
  480. query.bindValue(":tree_id", fields[2]);
  481. query.bindValue("tree_id_parent", fields[3]);
  482. query.bindValue("id_classeur", fields[4]);
  483. if(!query.exec())
  484. return false;
  485. query.clear();
  486. return true;
  487. }
  488.  
  489. void Classeurs_Model::cleanDatasRange() { // datas arrived delete by one
  490. QMap<int, QVector<QVariant>> datas; // format data
  491. foreach(int id_parent, db_Classeurs.keys()) {
  492. QList<QHash<int, QVector<QVariant>>>
  493. parent_values = db_Classeurs.values(id_parent);
  494. for(int c_idP(0); c_idP < parent_values.size(); ++c_idP) {
  495. QHash<int, QVector<QVariant>> parent_value = parent_values[c_idP];
  496. foreach(int id, parent_value.keys()) {
  497. QVector<QVariant> content;
  498. content << QVariant(id_parent)
  499. << parent_value[id][0]
  500. << parent_value[id][1];
  501. datas.insert(id, content); } } }
  502. QMap<int, QVector<QVariant>>::iterator id; // remove break count
  503. bool finish(false);
  504. while(!finish) {
  505. int i(0);
  506. for(id = datas.begin(); id != datas.end(); ++id) {
  507. i++;
  508. if(id.key() != i) { // if a break inside the count
  509. datas.insert(i, id.value());
  510. datas.remove(id.key());
  511. finish = false;
  512. break; }
  513. finish = true; } }
  514. db_Classeurs.clear();
  515. foreach(int id, datas.keys()) { // rewrite db
  516. QHash<int, QVector<QVariant>> level2;
  517. QVector<QVariant> level3;
  518. level3 << datas[id][1] // nom
  519. << datas[id][2]; // comment
  520. if(datas[id].count() == 4)
  521. level3 << datas[id][3]; // id_classeur (if exist)
  522. level2.insert(id, level3);
  523. db_Classeurs.insert(datas[id][0].toInt(), level2); }
  524. }
  525.  
  526. Files_Model* Classeurs_Model::getCurrent_Files_model(QModelIndex &index) const {
  527. if(!index.isValid())
  528. return NULL;
  529. Classeur *classeur = reinterpret_cast<Classeur*>(index.internalPointer());
  530. return classeur->getFiles_model();
  531. }
  532.  
  533. Classeur* Classeurs_Model::getClasseur(const QModelIndex &index) const {
  534. if(!index.isValid())
  535. return root_classeur;
  536. Classeur *classeur = reinterpret_cast<Classeur*>(index.internalPointer());
  537. return classeur;
  538. }
  539.  
  540. Classeur* Classeurs_Model::getRootClasseur() {
  541. return root_classeur;
  542. }
  543.  
  544. QModelIndex Classeurs_Model::getRootIndex() {
  545. return this->indexOf(root_classeur);
  546. }
RAW Paste Data