Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "feedmodel.h"
- #include <QFile>
- #include <QDir>
- #include <QApplication>
- FeedModel::FeedModel(QObject *parent) :
- QAbstractItemModel(parent),
- myURLs( QMap<QString, int>() ),
- myBuffers( QMap<int, Cache>()),
- myURLUpdateQueue( QMultiMap<QString, Feed*>() ),
- myHTTP( new QHttp( this )),
- myCacheLocation("/home/user/.indite/"),
- myDesiredSize( -1 )
- {
- QHash<int, QByteArray> roles;
- roles[Feed::TypeRole] = "feedType";
- roles[Feed::IDRole] = "feedID";
- roles[Feed::UserIDRole] = "feedUserID";
- roles[Feed::NameRole] = "feedName";
- roles[Feed::CreatedRole] = "feedCreated";
- roles[Feed::PictureRole] = "feedPicture";
- roles[Feed::ContentRole] = "feedContent";
- roles[Feed::LikeCountRole] = "likeCount";
- roles[Feed::LikeURLRole] = "likeURL";
- roles[Feed::CommentCountRole] = "commentCount";
- roles[Feed::CommentURLRole] = "commentURL";
- setRoleNames(roles);
- QVector<QVariant> headers;
- // asetetaan oikean kokoinen data. OBS!!!! THIS NEEDS TO BE HARDCODED SINCE WE CANNOT ASK ENUM IT'S SIZE!!!!
- // headers.resize( Feed::LASTROLE );
- // foreach( QVariant header, headers )
- // header = QString(""); // initialize the data with empty data.
- // // set the names to be displayed as headers
- // headers[Feed::TypeRole].setValue(QString("Feed type"));
- // headers[Feed::NameRole] = QString("Feed name");
- myRootItem = new Feed( );
- // if( !QDir().exists(myCacheLocation) )
- // {
- // QDir().mkpath(myCacheLocation);
- // }
- /*
- // Settings for the model (earlier cached URLs)
- QSettings* settings = new QSettings( myCacheLocation + "cachedURLs.ini",
- QSettings::IniFormat,
- this);
- int size = settings->beginReadArray( "URLs" );
- // read the dependancies
- for( int i = 0; i < size; i++ )
- {
- settings->setArrayIndex( i );
- // Check the file still exists.
- if( QFile().exists( myCacheLocation + QString( "%1.png" ).arg(settings->value("new").toInt()) ) )
- {
- myURLs.insert( settings->value("original").toString(), settings->value("new").toInt() );
- qDebug() << "Reading cached url from settings" << settings->value("original").toString() << settings->value("new").toInt();
- }
- }
- settings->clear();
- */
- // connects
- connect(myHTTP, SIGNAL(requestFinished(int, bool)),this, SLOT(cachingFinished(int,bool)));
- }
- FeedModel::~FeedModel()
- {
- /*
- // remember the pictures
- QSettings* settings = new QSettings( myCacheLocation + "cachedURLs.ini",
- QSettings::IniFormat,
- this);
- settings->clear();
- settings->beginWriteArray( "URLs", myURLs.size() );
- int j = 0;
- QMapIterator<QString, int> i(myURLs);
- while (i.hasNext()) {
- i.next();
- settings->setArrayIndex( j );
- j++;
- settings->setValue( "original", i.key() );
- settings->setValue( "new", i.value() );
- }
- settings->endArray();
- */
- // clear cache
- QDir dir(myCacheLocation);
- QStringList fileListing;
- foreach ( QString file, dir.entryList( QDir::Files ))
- fileListing << QFileInfo( dir, file).absoluteFilePath();
- int count = fileListing.size();
- for( int i=0; i<count; i++)
- QFile::remove( fileListing[i]);
- }
- void FeedModel::clear()
- {
- // delete myRootItem would have been enough........
- delete myRootItem;
- myRootItem = new Feed();
- /*
- //! Sorry Meelis, this all you copied was just meaningless and it was time to let it go.
- QSettings* settingstemp = new QSettings( myCacheLocation + "cachedURLs.ini",
- QSettings::IniFormat,
- this);
- settingstemp->clear();
- settingstemp->beginWriteArray( "URLs", myURLs.size() );
- int j = 0;
- QMapIterator<QString, int> i(myURLs);
- while (i.hasNext()) {
- i.next();
- settingstemp->setArrayIndex( j );
- j++;
- settingstemp->setValue( "original", i.key() );
- settingstemp->setValue( "new", i.value() );
- }
- settingstemp->endArray();
- delete myRootItem;
- QHash<int, QByteArray> roles;
- roles[Feed::TypeRole] = "feedType";
- roles[Feed::IDRole] = "feedID";
- roles[Feed::UserIDRole] = "feedUserID";
- roles[Feed::NameRole] = "feedName";
- roles[Feed::CreatedRole] = "feedCreated";
- roles[Feed::PictureRole] = "feedPicture";
- roles[Feed::ContentRole] = "feedContent";
- roles[Feed::LikeCountRole] = "likeCount";
- setRoleNames(roles);
- QVector<QVariant> headers;
- // asetetaan oikean kokoinen data. OBS!!!! THIS NEEDS TO BE HARDCODED SINCE WE CANNOT ASK ENUM IT'S SIZE!!!!
- headers.resize( Feed::LASTROLE );
- foreach( QVariant header, headers )
- header = QString(""); // initialize the data with empty data.
- // set the names to be displayed as headers
- headers[Feed::TypeRole].setValue(QString("Feed type"));
- headers[Feed::NameRole] = QString("Feed name");
- myRootItem = new Feed( headers );
- if( !QDir().exists(myCacheLocation) )
- {
- QDir().mkpath(myCacheLocation);
- }
- // Settings for the model (earlier cached URLs)
- QSettings* settings = new QSettings( myCacheLocation + "cachedURLs.ini",
- QSettings::IniFormat,
- this);
- int size = settings->beginReadArray( "URLs" );
- // read the dependancies
- for( int i = 0; i < size; i++ )
- {
- settings->setArrayIndex( i );
- // Check the file still exists.
- if( QFile().exists( myCacheLocation + QString("%1.png").arg(settings->value("new").toInt()) ) )
- {
- myURLs.insert( settings->value("original").toString(), settings->value("new").toInt() );
- }
- }
- settings->clear();
- // connects
- connect(myHTTP, SIGNAL(requestFinished(int, bool)),this, SLOT(cachingFinished(int,bool)));
- */
- }
- void FeedModel::detachService(Feed::FeedType type)
- {
- qDebug() << "Detaching" << type << "size" << rowCount();
- QVector<Feed*> TBD; //to be deleted
- for( int i = 0; i < rowCount(); i++ )
- {
- qDebug() << myRootItem->child(i)->data(Feed::TypeRole) << "vs." << type;
- if( myRootItem->child(i)->data(Feed::TypeRole) == type )
- TBD.append(myRootItem->child(i));
- }
- for( int i = 0; i < TBD.size() ; i++ )
- {
- myRootItem->getRidOfChild(TBD.at(i));
- qDebug() << "Detaching" << type << "size" << rowCount();
- }
- }
- // Palauttaa parentin alta tietyn alkion indeksin.
- // Parametrit:
- // parent : Oletuksena invalid
- // column : Oletuksena 0
- QModelIndex FeedModel::index(int row, int column, const QModelIndex& parent ) const
- {
- // if( !hasIndex(row, column, parent) )
- // {
- // qDebug() << "MODEL: INDEX NOT VALID";
- // return QModelIndex();
- // }
- // qDebug() << "MODEL: INDEX";
- Feed* parentItem = 0;
- if( !parent.isValid() )
- parentItem = myRootItem;
- else
- parentItem = (Feed*) parent.internalPointer();
- Feed* childItem = parentItem->child(row);
- if( childItem != 0 )
- {
- return createIndex( row, 0, childItem );
- }
- else
- {
- qDebug() << "MODEL: CHILD NULL";
- return QModelIndex();
- }
- }
- QModelIndex FeedModel::parent(const QModelIndex& index) const
- {
- qDebug() << "MODEL: Calling parent of root?" << (index.internalPointer() == myRootItem);
- if (!index.isValid())
- return QModelIndex();
- Feed* childItem = (Feed*) index.internalPointer();
- Feed* parentItem = childItem->parent();
- if( parentItem == myRootItem)
- return QModelIndex();
- return createIndex(parentItem->childNumber(), 0, parentItem);
- }
- int FeedModel::columnCount(const QModelIndex &parent) const
- {
- if( parent.isValid() )
- return 0;
- //TODO kovakoodia hyi hyi
- //qDebug() << "MODEL: Column count called";
- return 1;
- }
- int FeedModel::rowCount(const QModelIndex &parent) const
- {
- if( parent.isValid() )
- return 0;
- Feed *parentItem = myRootItem;
- // TODO support trees
- //qDebug() << "MODEL: row count called!" << parentItem->childCount();
- return parentItem->childCount();
- }
- QVariant FeedModel::data(const QModelIndex &index, int role) const
- {
- return getItem(index)->data(role);
- }
- // this came out reeeal weird.
- // wonder if we eve even use this.
- QVariant FeedModel::headerData(int section, Qt::Orientation orientation, int role) const
- {
- qDebug() << "MODEL: header data called";
- if( orientation == Qt::Horizontal && role == Qt::DisplayRole )
- {
- if( section == 0 )
- return "Type";
- else if (section == 1)
- return "Name";
- }
- return QVariant();
- }
- bool FeedModel::insertColumns(int position, int columns, const QModelIndex &parent)
- {
- // you cannot insert columns yourself
- qDebug() << "MODEL: Inserting columns";
- return false;
- }
- bool FeedModel::removeColumns(int position, int columns, const QModelIndex &parent)
- {
- // forbidden
- qDebug() << "MODEL: Removing colums;";
- return false;
- }
- bool FeedModel::insertRows(int row, int count, const QModelIndex &parent)
- {
- // todo insert empty Feeds
- if( (count < 1 || row < 0 || row > rowCount(parent)) )
- return false;
- beginInsertRows(parent, row, row+count );
- for( int r = 0; r < count; ++r )
- getItem(parent)->insertChild( new Feed() );
- endInsertRows();
- return true;
- }
- bool FeedModel::removeRows(int row, int count, const QModelIndex &parent)
- {
- if (count <= 0 || row < 0 || (row + count) > rowCount(parent))
- return false;
- beginRemoveRows(QModelIndex(), row, row + count - 1);
- for (int r = 0; r < count; ++r)
- getItem(parent)->removeChild(row);
- endRemoveRows();
- return true;
- }
- Qt::ItemFlags FeedModel::flags(const QModelIndex &index) const
- {
- if (!index.isValid())
- return 0;
- // let's NOT allow editing
- return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
- }
- bool FeedModel::setData(const QModelIndex &index, const QVariant &value, int role)
- {
- if (index.row() >= 0 && index.row() < myRootItem->childCount()
- && (role == Qt::EditRole || role == Qt::DisplayRole)) {
- myRootItem->child(index.row())->setData(role, value.toString());
- emit dataChanged(index, index);
- return true;
- }
- return false;
- }
- bool FeedModel::setHeaderData(int section, Qt::Orientation orientation,
- const QVariant &value, int role)
- {
- qDebug() << "Setting header data";
- //todo headerdata is stored in root item's data
- return false;
- }
- QModelIndex FeedModel::addFeed(Feed *item, const QModelIndex &parent)
- {
- int row = 0;
- //QModelIndex parentItem;
- if( myDesiredSize == 0 )
- {
- delete item;
- return QModelIndex();
- }
- if( parent == QModelIndex() )
- {
- // // Make room.. need to sort if we add MORE ITEMS than size.
- // if( myDesiredSize != -1 && rowCount() >= myDesiredSize )
- // {
- // sort(0, Qt::DescendingOrder);
- // qDebug() << "ASD" << rowCount();
- // Feed* oldest = myRootItem->child( rowCount()-1);
- // if( oldest->getStatus() == Feed::QUEUE )
- // {
- // // delete later
- // myRootItem->setStatus( Feed::RELEASED );
- // myRootItem->releaseChild( rowCount() -1 );
- // }
- // else
- // myRootItem->removeChild( rowCount() -1 );
- // }
- item->setParent(myRootItem);
- row = myRootItem->insertChild( item );
- //convertURL( item );
- }
- else
- {
- Feed* parentFeed = static_cast<Feed*>(parent.internalPointer());
- item->setParent(parentFeed);
- row = parentFeed->insertChild(item);
- qDebug() << "MODEL: Adding a comment?? row:" << row;
- //parentItem = createIndex(parentFeed->childNumber(), 0, parentFeed);
- }
- }
- bool FeedModel::removeFeed(const QModelIndex &index)
- {
- if( !index.isValid() )
- {
- // TODO this means one cannot remove top level items
- return false;
- }
- emit beginRemoveRows( createIndex(0,0, myRootItem ), index.row(), index.row() );
- getItem(index)->removeChild( static_cast<Feed*>(index.internalPointer()));
- //emit dataChanged(QModelIndex(), QModelIndex()); // TODO
- emit endRemoveRows();
- return true;
- }
- void FeedModel::debug() const
- {
- qDebug() << "DEBUGGING";
- myRootItem->print();
- }
- Feed* FeedModel::getRoot() const
- {
- return myRootItem;
- }
- void FeedModel::resize(int size)
- {
- if( size > -1 )
- myDesiredSize = size;
- qDebug() << "Resizing:" << size << "from: " << rowCount() << "Desired size: " << myDesiredSize;
- while( myDesiredSize != -1 && rowCount() > myDesiredSize )
- {
- int childID = myRootItem->childCount()-1;
- if( myRootItem->child(childID)->getStatus() == Feed::QUEUE )
- {
- myRootItem->child(childID)->setStatus( Feed::RELEASED);
- myRootItem->releaseChild(childID);
- }
- else
- {
- myRootItem->removeChild(myRootItem->childCount()-1);
- }
- }
- qDebug() << "Size now: " << rowCount();
- }
- // This could actually be a function of Feed, not the model
- QStringList FeedModel::getComments(Feed *parentItem)
- {
- QStringList strings;
- if( parentItem == 0 )
- {
- // Return feeds? If so, just use myRootItem.
- return strings;
- }
- QString adder;
- // sort the comments.
- sort( 0, Qt::DescendingOrder, parentItem );
- for( int i = 0; i < parentItem->childCount(); i++ )
- {
- Feed* child = parentItem->child(i);
- adder = QString( "Name: %1\nCreated: %2\n%3")
- .arg(child->data(Feed::NameRole).toString())
- .arg(child->data(Feed::CreatedRole).toString())
- .arg(child->data(Feed::ContentRole).toString());
- strings.append( adder );
- qDebug() << "Getting comments.. got " << strings.size() << "so far";
- }
- return strings;
- }
- //void FeedModel::convertURL( Feed* item )
- //{
- // if( item->getStatus() == Feed::RELEASED )
- // {
- // delete item;
- // return;
- // }
- // // get the url to be converted
- // QString stringURL = item->data( (int) Feed::PictureRole).toString();
- // // check if the new URL already exists.
- // if( myURLs.contains( stringURL ) )
- // {
- // if( myURLs.value( stringURL ) != -1)
- // {
- // item->setData( (int) Feed::PictureRole, myCacheLocation + QString( "%1.png" ).
- // arg(myURLs.value( stringURL ) ));
- // return;
- // }
- // myURLUpdateQueue.insertMulti(stringURL, item);
- // item->setStatus( Feed::QUEUE );
- // item->setData( (int) Feed::PictureRole,
- // QString("images/misc/icon_blank_profile.png") );
- // return;
- // }
- // // log the original url as read, not processed
- // myURLs.insert( stringURL, -1 );
- // myURLUpdateQueue.insertMulti(stringURL, item);
- // item->setStatus( Feed::QUEUE );
- // // create a buffer in which the
- // QBuffer* buffer = new QBuffer(this);
- // QUrl url( stringURL );
- // // create a buffer into which download bytes to.
- // buffer->open(QIODevice::WriteOnly);
- // myHTTP->setHost(url.host());
- // Cache c =
- // {
- // stringURL,
- // buffer,
- // };
- // int request=myHTTP->get (url.path(),buffer);
- // //qDebug() << "Starting to cache:" << request;
- // myBuffers.insert( request, c );
- // item->setData( (int) Feed::PictureRole,
- // QString("images/misc/icon_blank_profile.png") );
- // return;
- //}
- //// TODO prepare for errors
- //void FeedModel::cachingFinished(int requestID, bool error)
- //{
- // if( !myBuffers.contains(requestID ))
- // {
- // //qDebug() << "Error, finished caching a non-existing image." << requestID;
- // return;
- // }
- // QBuffer* buffer = myBuffers.value(requestID).Buffer;
- // QImage asd;
- // asd.loadFromData(QByteArray(buffer->data()));
- // asd.save( myCacheLocation + QString( "%1.png" ).arg(requestID) );
- // buffer->deleteLater();
- // myURLs.insert(myBuffers.value(requestID).ID, requestID);
- // updateURLs(myBuffers.value(requestID).ID);
- // myBuffers.remove(requestID);
- //}
- //void FeedModel::updateURLs( QString url )
- //{
- // int newURL = myURLs.value(url);
- // //qDebug() << url;
- // QList<Feed*> queue = myURLUpdateQueue.values(url);
- // //qDebug() << QString( "Updating %1 URLs or %2 URLs").arg(queue.size()).arg(myURLUpdateQueue.size());
- // foreach( Feed* feed, queue)
- // {
- // if( feed->getStatus() == Feed::RELEASED )
- // {
- // qDebug() << feed->getStatus();
- // delete feed;
- // }
- // else
- // {
- // feed->setData( (int) Feed::PictureRole, myCacheLocation + QString( "%1.png" ).
- // arg( newURL ));
- // feed->setStatus( Feed::NOTINQUEUE );
- // }
- // }
- // myURLUpdateQueue.remove( url );
- // //emit(repaintNewsfeed());
- //}
- Feed* FeedModel::getItem( const QModelIndex& index ) const
- {
- if (index.isValid()) {
- Feed *item = static_cast<Feed*>(index.internalPointer());
- if (item == 0 )
- {
- qDebug() << "MODEL: Returning something else";
- return myRootItem->child(index.row());
- }
- else
- {
- return item;
- }
- }
- qDebug() << "MODEL: returning root item";
- return myRootItem;
- }
- // TESTING (IMPLEMENTING THESE FROM QSTRINGLISTMODEL
- static bool ascendingLessThan(const QPair<Feed*, int> &s1, const QPair<Feed*, int> &s2)
- {
- return s1.first->data(Feed::CreatedRole).toString() < s2.first->data(Feed::CreatedRole).toString();
- }
- static bool descendingLessThan(const QPair<Feed*, int> &s1, const QPair<Feed*, int> &s2)
- {
- return s1.first->data(Feed::CreatedRole).toString() > s2.first->data(Feed::CreatedRole).toString();
- }
- void FeedModel::sort(int column, Qt::SortOrder order, Feed* parentItem )
- {
- // added later on to enable comment sorting
- if( parentItem == 0 || parentItem == myRootItem )
- {
- parentItem = myRootItem;
- emit layoutAboutToBeChanged();
- //resize();
- }
- QList<QPair<Feed*, int> > list;
- for (int i = 0; i < parentItem->childCount(); ++i)
- list.append(QPair<Feed*, int>(parentItem->child(i), i));
- if (order == Qt::AscendingOrder)
- qSort(list.begin(), list.end(), ascendingLessThan);
- else
- qSort(list.begin(), list.end(), descendingLessThan);
- parentItem->releaseChildren();
- QVector<int> forwarding(list.count());
- for (int i = 0; i < list.count(); ++i) {
- parentItem->insertChild(list.at(i).first);
- forwarding[list.at(i).second] = i;
- }
- if( parentItem == myRootItem )
- {
- // QModelIndexList oldList = persistentIndexList();
- // QModelIndexList newList;
- // for (int i = 0; i < oldList.count(); ++i)
- // newList.append(index(forwarding.at(oldList.at(i).row()), 0));
- // changePersistentIndexList(oldList, newList);
- emit layoutChanged();
- emit(repaintNewsfeed());
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement