Advertisement
Guest User

Untitled

a guest
Jul 23rd, 2017
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.71 KB | None | 0 0
  1. #include "feedmodel.h"
  2. #include <QFile>
  3. #include <QDir>
  4. #include <QApplication>
  5.  
  6.  
  7. FeedModel::FeedModel(QObject *parent) :
  8. QAbstractItemModel(parent),
  9. myURLs( QMap<QString, int>() ),
  10. myBuffers( QMap<int, Cache>()),
  11. myURLUpdateQueue( QMultiMap<QString, Feed*>() ),
  12. myHTTP( new QHttp( this )),
  13. myCacheLocation("/home/user/.indite/"),
  14. myDesiredSize( -1 )
  15.  
  16. {
  17. QHash<int, QByteArray> roles;
  18. roles[Feed::TypeRole] = "feedType";
  19. roles[Feed::IDRole] = "feedID";
  20. roles[Feed::UserIDRole] = "feedUserID";
  21. roles[Feed::NameRole] = "feedName";
  22. roles[Feed::CreatedRole] = "feedCreated";
  23. roles[Feed::PictureRole] = "feedPicture";
  24. roles[Feed::ContentRole] = "feedContent";
  25. roles[Feed::LikeCountRole] = "likeCount";
  26. roles[Feed::LikeURLRole] = "likeURL";
  27. roles[Feed::CommentCountRole] = "commentCount";
  28. roles[Feed::CommentURLRole] = "commentURL";
  29. setRoleNames(roles);
  30.  
  31. QVector<QVariant> headers;
  32. // asetetaan oikean kokoinen data. OBS!!!! THIS NEEDS TO BE HARDCODED SINCE WE CANNOT ASK ENUM IT'S SIZE!!!!
  33. // headers.resize( Feed::LASTROLE );
  34. // foreach( QVariant header, headers )
  35. // header = QString(""); // initialize the data with empty data.
  36.  
  37. // // set the names to be displayed as headers
  38. // headers[Feed::TypeRole].setValue(QString("Feed type"));
  39. // headers[Feed::NameRole] = QString("Feed name");
  40.  
  41. myRootItem = new Feed( );
  42.  
  43. // if( !QDir().exists(myCacheLocation) )
  44. // {
  45. // QDir().mkpath(myCacheLocation);
  46. // }
  47.  
  48. /*
  49. // Settings for the model (earlier cached URLs)
  50. QSettings* settings = new QSettings( myCacheLocation + "cachedURLs.ini",
  51. QSettings::IniFormat,
  52. this);
  53. int size = settings->beginReadArray( "URLs" );
  54. // read the dependancies
  55. for( int i = 0; i < size; i++ )
  56. {
  57. settings->setArrayIndex( i );
  58. // Check the file still exists.
  59. if( QFile().exists( myCacheLocation + QString( "%1.png" ).arg(settings->value("new").toInt()) ) )
  60. {
  61. myURLs.insert( settings->value("original").toString(), settings->value("new").toInt() );
  62. qDebug() << "Reading cached url from settings" << settings->value("original").toString() << settings->value("new").toInt();
  63. }
  64. }
  65. settings->clear();
  66. */
  67. // connects
  68. connect(myHTTP, SIGNAL(requestFinished(int, bool)),this, SLOT(cachingFinished(int,bool)));
  69. }
  70.  
  71. FeedModel::~FeedModel()
  72. {
  73. /*
  74. // remember the pictures
  75. QSettings* settings = new QSettings( myCacheLocation + "cachedURLs.ini",
  76. QSettings::IniFormat,
  77. this);
  78.  
  79. settings->clear();
  80.  
  81. settings->beginWriteArray( "URLs", myURLs.size() );
  82. int j = 0;
  83. QMapIterator<QString, int> i(myURLs);
  84. while (i.hasNext()) {
  85. i.next();
  86. settings->setArrayIndex( j );
  87. j++;
  88. settings->setValue( "original", i.key() );
  89. settings->setValue( "new", i.value() );
  90. }
  91. settings->endArray();
  92. */
  93. // clear cache
  94.  
  95. QDir dir(myCacheLocation);
  96. QStringList fileListing;
  97. foreach ( QString file, dir.entryList( QDir::Files ))
  98. fileListing << QFileInfo( dir, file).absoluteFilePath();
  99.  
  100. int count = fileListing.size();
  101. for( int i=0; i<count; i++)
  102. QFile::remove( fileListing[i]);
  103. }
  104.  
  105. void FeedModel::clear()
  106. {
  107. // delete myRootItem would have been enough........
  108. delete myRootItem;
  109. myRootItem = new Feed();
  110. /*
  111. //! Sorry Meelis, this all you copied was just meaningless and it was time to let it go.
  112.  
  113. QSettings* settingstemp = new QSettings( myCacheLocation + "cachedURLs.ini",
  114. QSettings::IniFormat,
  115. this);
  116.  
  117. settingstemp->clear();
  118.  
  119. settingstemp->beginWriteArray( "URLs", myURLs.size() );
  120. int j = 0;
  121. QMapIterator<QString, int> i(myURLs);
  122. while (i.hasNext()) {
  123. i.next();
  124. settingstemp->setArrayIndex( j );
  125. j++;
  126. settingstemp->setValue( "original", i.key() );
  127. settingstemp->setValue( "new", i.value() );
  128. }
  129. settingstemp->endArray();
  130.  
  131. delete myRootItem;
  132.  
  133. QHash<int, QByteArray> roles;
  134. roles[Feed::TypeRole] = "feedType";
  135. roles[Feed::IDRole] = "feedID";
  136. roles[Feed::UserIDRole] = "feedUserID";
  137. roles[Feed::NameRole] = "feedName";
  138. roles[Feed::CreatedRole] = "feedCreated";
  139. roles[Feed::PictureRole] = "feedPicture";
  140. roles[Feed::ContentRole] = "feedContent";
  141. roles[Feed::LikeCountRole] = "likeCount";
  142. setRoleNames(roles);
  143.  
  144.  
  145. QVector<QVariant> headers;
  146. // asetetaan oikean kokoinen data. OBS!!!! THIS NEEDS TO BE HARDCODED SINCE WE CANNOT ASK ENUM IT'S SIZE!!!!
  147. headers.resize( Feed::LASTROLE );
  148. foreach( QVariant header, headers )
  149. header = QString(""); // initialize the data with empty data.
  150.  
  151. // set the names to be displayed as headers
  152. headers[Feed::TypeRole].setValue(QString("Feed type"));
  153. headers[Feed::NameRole] = QString("Feed name");
  154.  
  155. myRootItem = new Feed( headers );
  156.  
  157. if( !QDir().exists(myCacheLocation) )
  158. {
  159. QDir().mkpath(myCacheLocation);
  160. }
  161. // Settings for the model (earlier cached URLs)
  162. QSettings* settings = new QSettings( myCacheLocation + "cachedURLs.ini",
  163. QSettings::IniFormat,
  164. this);
  165. int size = settings->beginReadArray( "URLs" );
  166. // read the dependancies
  167. for( int i = 0; i < size; i++ )
  168. {
  169. settings->setArrayIndex( i );
  170. // Check the file still exists.
  171. if( QFile().exists( myCacheLocation + QString("%1.png").arg(settings->value("new").toInt()) ) )
  172. {
  173. myURLs.insert( settings->value("original").toString(), settings->value("new").toInt() );
  174. }
  175. }
  176. settings->clear();
  177. // connects
  178. connect(myHTTP, SIGNAL(requestFinished(int, bool)),this, SLOT(cachingFinished(int,bool)));
  179. */
  180. }
  181.  
  182. void FeedModel::detachService(Feed::FeedType type)
  183. {
  184. qDebug() << "Detaching" << type << "size" << rowCount();
  185. QVector<Feed*> TBD; //to be deleted
  186. for( int i = 0; i < rowCount(); i++ )
  187. {
  188. qDebug() << myRootItem->child(i)->data(Feed::TypeRole) << "vs." << type;
  189. if( myRootItem->child(i)->data(Feed::TypeRole) == type )
  190. TBD.append(myRootItem->child(i));
  191. }
  192. for( int i = 0; i < TBD.size() ; i++ )
  193. {
  194. myRootItem->getRidOfChild(TBD.at(i));
  195. qDebug() << "Detaching" << type << "size" << rowCount();
  196. }
  197. }
  198.  
  199. // Palauttaa parentin alta tietyn alkion indeksin.
  200. // Parametrit:
  201. // parent : Oletuksena invalid
  202. // column : Oletuksena 0
  203. QModelIndex FeedModel::index(int row, int column, const QModelIndex& parent ) const
  204. {
  205. // if( !hasIndex(row, column, parent) )
  206. // {
  207. // qDebug() << "MODEL: INDEX NOT VALID";
  208. // return QModelIndex();
  209. // }
  210. // qDebug() << "MODEL: INDEX";
  211.  
  212. Feed* parentItem = 0;
  213.  
  214. if( !parent.isValid() )
  215. parentItem = myRootItem;
  216. else
  217. parentItem = (Feed*) parent.internalPointer();
  218.  
  219. Feed* childItem = parentItem->child(row);
  220.  
  221. if( childItem != 0 )
  222. {
  223. return createIndex( row, 0, childItem );
  224. }
  225. else
  226. {
  227. qDebug() << "MODEL: CHILD NULL";
  228. return QModelIndex();
  229. }
  230.  
  231. }
  232.  
  233.  
  234. QModelIndex FeedModel::parent(const QModelIndex& index) const
  235. {
  236. qDebug() << "MODEL: Calling parent of root?" << (index.internalPointer() == myRootItem);
  237. if (!index.isValid())
  238. return QModelIndex();
  239.  
  240. Feed* childItem = (Feed*) index.internalPointer();
  241. Feed* parentItem = childItem->parent();
  242.  
  243. if( parentItem == myRootItem)
  244. return QModelIndex();
  245. return createIndex(parentItem->childNumber(), 0, parentItem);
  246. }
  247.  
  248. int FeedModel::columnCount(const QModelIndex &parent) const
  249. {
  250. if( parent.isValid() )
  251. return 0;
  252. //TODO kovakoodia hyi hyi
  253. //qDebug() << "MODEL: Column count called";
  254. return 1;
  255. }
  256.  
  257. int FeedModel::rowCount(const QModelIndex &parent) const
  258. {
  259. if( parent.isValid() )
  260. return 0;
  261. Feed *parentItem = myRootItem;
  262. // TODO support trees
  263. //qDebug() << "MODEL: row count called!" << parentItem->childCount();
  264. return parentItem->childCount();
  265.  
  266. }
  267.  
  268. QVariant FeedModel::data(const QModelIndex &index, int role) const
  269. {
  270. return getItem(index)->data(role);
  271. }
  272.  
  273. // this came out reeeal weird.
  274. // wonder if we eve even use this.
  275. QVariant FeedModel::headerData(int section, Qt::Orientation orientation, int role) const
  276. {
  277. qDebug() << "MODEL: header data called";
  278. if( orientation == Qt::Horizontal && role == Qt::DisplayRole )
  279. {
  280. if( section == 0 )
  281. return "Type";
  282. else if (section == 1)
  283. return "Name";
  284. }
  285. return QVariant();
  286.  
  287. }
  288.  
  289. bool FeedModel::insertColumns(int position, int columns, const QModelIndex &parent)
  290. {
  291. // you cannot insert columns yourself
  292. qDebug() << "MODEL: Inserting columns";
  293. return false;
  294. }
  295.  
  296. bool FeedModel::removeColumns(int position, int columns, const QModelIndex &parent)
  297. {
  298. // forbidden
  299. qDebug() << "MODEL: Removing colums;";
  300. return false;
  301. }
  302.  
  303. bool FeedModel::insertRows(int row, int count, const QModelIndex &parent)
  304. {
  305. // todo insert empty Feeds
  306. if( (count < 1 || row < 0 || row > rowCount(parent)) )
  307. return false;
  308.  
  309. beginInsertRows(parent, row, row+count );
  310.  
  311. for( int r = 0; r < count; ++r )
  312. getItem(parent)->insertChild( new Feed() );
  313.  
  314. endInsertRows();
  315.  
  316. return true;
  317. }
  318.  
  319. bool FeedModel::removeRows(int row, int count, const QModelIndex &parent)
  320. {
  321. if (count <= 0 || row < 0 || (row + count) > rowCount(parent))
  322. return false;
  323.  
  324. beginRemoveRows(QModelIndex(), row, row + count - 1);
  325.  
  326. for (int r = 0; r < count; ++r)
  327. getItem(parent)->removeChild(row);
  328.  
  329. endRemoveRows();
  330.  
  331. return true;
  332. }
  333.  
  334. Qt::ItemFlags FeedModel::flags(const QModelIndex &index) const
  335. {
  336. if (!index.isValid())
  337. return 0;
  338.  
  339. // let's NOT allow editing
  340. return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
  341. }
  342.  
  343.  
  344. bool FeedModel::setData(const QModelIndex &index, const QVariant &value, int role)
  345. {
  346. if (index.row() >= 0 && index.row() < myRootItem->childCount()
  347. && (role == Qt::EditRole || role == Qt::DisplayRole)) {
  348. myRootItem->child(index.row())->setData(role, value.toString());
  349. emit dataChanged(index, index);
  350. return true;
  351. }
  352. return false;
  353. }
  354.  
  355. bool FeedModel::setHeaderData(int section, Qt::Orientation orientation,
  356. const QVariant &value, int role)
  357. {
  358. qDebug() << "Setting header data";
  359. //todo headerdata is stored in root item's data
  360. return false;
  361. }
  362.  
  363. QModelIndex FeedModel::addFeed(Feed *item, const QModelIndex &parent)
  364. {
  365. int row = 0;
  366. //QModelIndex parentItem;
  367.  
  368. if( myDesiredSize == 0 )
  369. {
  370. delete item;
  371. return QModelIndex();
  372. }
  373.  
  374. if( parent == QModelIndex() )
  375. {
  376. // // Make room.. need to sort if we add MORE ITEMS than size.
  377. // if( myDesiredSize != -1 && rowCount() >= myDesiredSize )
  378. // {
  379. // sort(0, Qt::DescendingOrder);
  380. // qDebug() << "ASD" << rowCount();
  381. // Feed* oldest = myRootItem->child( rowCount()-1);
  382. // if( oldest->getStatus() == Feed::QUEUE )
  383. // {
  384. // // delete later
  385. // myRootItem->setStatus( Feed::RELEASED );
  386. // myRootItem->releaseChild( rowCount() -1 );
  387. // }
  388. // else
  389. // myRootItem->removeChild( rowCount() -1 );
  390. // }
  391. item->setParent(myRootItem);
  392. row = myRootItem->insertChild( item );
  393. //convertURL( item );
  394. }
  395. else
  396. {
  397. Feed* parentFeed = static_cast<Feed*>(parent.internalPointer());
  398. item->setParent(parentFeed);
  399. row = parentFeed->insertChild(item);
  400. qDebug() << "MODEL: Adding a comment?? row:" << row;
  401. //parentItem = createIndex(parentFeed->childNumber(), 0, parentFeed);
  402. }
  403.  
  404. }
  405.  
  406. bool FeedModel::removeFeed(const QModelIndex &index)
  407. {
  408. if( !index.isValid() )
  409. {
  410. // TODO this means one cannot remove top level items
  411. return false;
  412. }
  413. emit beginRemoveRows( createIndex(0,0, myRootItem ), index.row(), index.row() );
  414. getItem(index)->removeChild( static_cast<Feed*>(index.internalPointer()));
  415. //emit dataChanged(QModelIndex(), QModelIndex()); // TODO
  416. emit endRemoveRows();
  417. return true;
  418. }
  419.  
  420. void FeedModel::debug() const
  421. {
  422. qDebug() << "DEBUGGING";
  423. myRootItem->print();
  424. }
  425.  
  426. Feed* FeedModel::getRoot() const
  427. {
  428. return myRootItem;
  429. }
  430.  
  431. void FeedModel::resize(int size)
  432. {
  433. if( size > -1 )
  434. myDesiredSize = size;
  435. qDebug() << "Resizing:" << size << "from: " << rowCount() << "Desired size: " << myDesiredSize;
  436. while( myDesiredSize != -1 && rowCount() > myDesiredSize )
  437. {
  438. int childID = myRootItem->childCount()-1;
  439. if( myRootItem->child(childID)->getStatus() == Feed::QUEUE )
  440. {
  441. myRootItem->child(childID)->setStatus( Feed::RELEASED);
  442. myRootItem->releaseChild(childID);
  443. }
  444. else
  445. {
  446. myRootItem->removeChild(myRootItem->childCount()-1);
  447. }
  448. }
  449.  
  450. qDebug() << "Size now: " << rowCount();
  451. }
  452.  
  453. // This could actually be a function of Feed, not the model
  454. QStringList FeedModel::getComments(Feed *parentItem)
  455. {
  456. QStringList strings;
  457. if( parentItem == 0 )
  458. {
  459. // Return feeds? If so, just use myRootItem.
  460. return strings;
  461. }
  462. QString adder;
  463. // sort the comments.
  464. sort( 0, Qt::DescendingOrder, parentItem );
  465. for( int i = 0; i < parentItem->childCount(); i++ )
  466. {
  467. Feed* child = parentItem->child(i);
  468. adder = QString( "Name: %1\nCreated: %2\n%3")
  469. .arg(child->data(Feed::NameRole).toString())
  470. .arg(child->data(Feed::CreatedRole).toString())
  471. .arg(child->data(Feed::ContentRole).toString());
  472. strings.append( adder );
  473. qDebug() << "Getting comments.. got " << strings.size() << "so far";
  474. }
  475. return strings;
  476. }
  477.  
  478. //void FeedModel::convertURL( Feed* item )
  479. //{
  480. // if( item->getStatus() == Feed::RELEASED )
  481. // {
  482. // delete item;
  483. // return;
  484. // }
  485. // // get the url to be converted
  486. // QString stringURL = item->data( (int) Feed::PictureRole).toString();
  487. // // check if the new URL already exists.
  488. // if( myURLs.contains( stringURL ) )
  489. // {
  490. // if( myURLs.value( stringURL ) != -1)
  491. // {
  492. // item->setData( (int) Feed::PictureRole, myCacheLocation + QString( "%1.png" ).
  493. // arg(myURLs.value( stringURL ) ));
  494. // return;
  495. // }
  496. // myURLUpdateQueue.insertMulti(stringURL, item);
  497. // item->setStatus( Feed::QUEUE );
  498. // item->setData( (int) Feed::PictureRole,
  499. // QString("images/misc/icon_blank_profile.png") );
  500. // return;
  501.  
  502. // }
  503. // // log the original url as read, not processed
  504. // myURLs.insert( stringURL, -1 );
  505. // myURLUpdateQueue.insertMulti(stringURL, item);
  506. // item->setStatus( Feed::QUEUE );
  507.  
  508. // // create a buffer in which the
  509. // QBuffer* buffer = new QBuffer(this);
  510. // QUrl url( stringURL );
  511.  
  512. // // create a buffer into which download bytes to.
  513. // buffer->open(QIODevice::WriteOnly);
  514. // myHTTP->setHost(url.host());
  515. // Cache c =
  516. // {
  517. // stringURL,
  518. // buffer,
  519. // };
  520.  
  521. // int request=myHTTP->get (url.path(),buffer);
  522. // //qDebug() << "Starting to cache:" << request;
  523. // myBuffers.insert( request, c );
  524. // item->setData( (int) Feed::PictureRole,
  525. // QString("images/misc/icon_blank_profile.png") );
  526. // return;
  527. //}
  528.  
  529. //// TODO prepare for errors
  530. //void FeedModel::cachingFinished(int requestID, bool error)
  531. //{
  532. // if( !myBuffers.contains(requestID ))
  533. // {
  534. // //qDebug() << "Error, finished caching a non-existing image." << requestID;
  535. // return;
  536. // }
  537.  
  538. // QBuffer* buffer = myBuffers.value(requestID).Buffer;
  539. // QImage asd;
  540. // asd.loadFromData(QByteArray(buffer->data()));
  541. // asd.save( myCacheLocation + QString( "%1.png" ).arg(requestID) );
  542. // buffer->deleteLater();
  543. // myURLs.insert(myBuffers.value(requestID).ID, requestID);
  544. // updateURLs(myBuffers.value(requestID).ID);
  545. // myBuffers.remove(requestID);
  546. //}
  547.  
  548. //void FeedModel::updateURLs( QString url )
  549. //{
  550. // int newURL = myURLs.value(url);
  551. // //qDebug() << url;
  552. // QList<Feed*> queue = myURLUpdateQueue.values(url);
  553. // //qDebug() << QString( "Updating %1 URLs or %2 URLs").arg(queue.size()).arg(myURLUpdateQueue.size());
  554. // foreach( Feed* feed, queue)
  555. // {
  556. // if( feed->getStatus() == Feed::RELEASED )
  557. // {
  558. // qDebug() << feed->getStatus();
  559. // delete feed;
  560. // }
  561. // else
  562. // {
  563. // feed->setData( (int) Feed::PictureRole, myCacheLocation + QString( "%1.png" ).
  564. // arg( newURL ));
  565. // feed->setStatus( Feed::NOTINQUEUE );
  566. // }
  567. // }
  568. // myURLUpdateQueue.remove( url );
  569.  
  570. // //emit(repaintNewsfeed());
  571. //}
  572.  
  573. Feed* FeedModel::getItem( const QModelIndex& index ) const
  574. {
  575. if (index.isValid()) {
  576. Feed *item = static_cast<Feed*>(index.internalPointer());
  577. if (item == 0 )
  578. {
  579. qDebug() << "MODEL: Returning something else";
  580. return myRootItem->child(index.row());
  581. }
  582. else
  583. {
  584. return item;
  585. }
  586. }
  587. qDebug() << "MODEL: returning root item";
  588. return myRootItem;
  589. }
  590.  
  591.  
  592. // TESTING (IMPLEMENTING THESE FROM QSTRINGLISTMODEL
  593. static bool ascendingLessThan(const QPair<Feed*, int> &s1, const QPair<Feed*, int> &s2)
  594. {
  595. return s1.first->data(Feed::CreatedRole).toString() < s2.first->data(Feed::CreatedRole).toString();
  596. }
  597.  
  598. static bool descendingLessThan(const QPair<Feed*, int> &s1, const QPair<Feed*, int> &s2)
  599. {
  600. return s1.first->data(Feed::CreatedRole).toString() > s2.first->data(Feed::CreatedRole).toString();
  601. }
  602.  
  603. void FeedModel::sort(int column, Qt::SortOrder order, Feed* parentItem )
  604. {
  605. // added later on to enable comment sorting
  606. if( parentItem == 0 || parentItem == myRootItem )
  607. {
  608. parentItem = myRootItem;
  609. emit layoutAboutToBeChanged();
  610. //resize();
  611. }
  612.  
  613.  
  614. QList<QPair<Feed*, int> > list;
  615. for (int i = 0; i < parentItem->childCount(); ++i)
  616. list.append(QPair<Feed*, int>(parentItem->child(i), i));
  617.  
  618. if (order == Qt::AscendingOrder)
  619. qSort(list.begin(), list.end(), ascendingLessThan);
  620. else
  621. qSort(list.begin(), list.end(), descendingLessThan);
  622. parentItem->releaseChildren();
  623.  
  624. QVector<int> forwarding(list.count());
  625. for (int i = 0; i < list.count(); ++i) {
  626. parentItem->insertChild(list.at(i).first);
  627. forwarding[list.at(i).second] = i;
  628. }
  629. if( parentItem == myRootItem )
  630. {
  631. // QModelIndexList oldList = persistentIndexList();
  632. // QModelIndexList newList;
  633. // for (int i = 0; i < oldList.count(); ++i)
  634. // newList.append(index(forwarding.at(oldList.at(i).row()), 0));
  635. // changePersistentIndexList(oldList, newList);
  636.  
  637. emit layoutChanged();
  638. emit(repaintNewsfeed());
  639. }
  640.  
  641. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement