同步操作将从 陈炳煌/sqlitebrowser 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
#include <QImage>#include "RemoteModel.h"#include "RemoteDatabase.h"using json = nlohmann::json;RemoteModelItem::RemoteModelItem(RemoteModelItem* parent) :m_parent(parent),m_fetchedDirectoryList(false){}RemoteModelItem::~RemoteModelItem(){qDeleteAll(m_children);}QVariant RemoteModelItem::value(RemoteModelColumns column) const{return m_values[column];}void RemoteModelItem::setValue(RemoteModelColumns column, QVariant value){m_values[column] = value;}void RemoteModelItem::appendChild(RemoteModelItem *item){m_children.push_back(item);}RemoteModelItem* RemoteModelItem::child(int row) const{return m_children[static_cast<size_t>(row)];}RemoteModelItem* RemoteModelItem::parent() const{return m_parent;}int RemoteModelItem::childCount() const{return static_cast<int>(m_children.size());}int RemoteModelItem::row() const{if(m_parent){auto f = std::find( m_parent->m_children.begin(), m_parent->m_children.end(), const_cast<RemoteModelItem*>(this));if(f == m_parent->m_children.end())return -1;elsereturn static_cast<int>(std::distance(m_parent->m_children.begin(), f));}return 0;}bool RemoteModelItem::fetchedDirectoryList() const{return m_fetchedDirectoryList;}void RemoteModelItem::setFetchedDirectoryList(bool fetched){m_fetchedDirectoryList = fetched;}std::vector<RemoteModelItem*> RemoteModelItem::loadArray(const json& array, RemoteModelItem* parent){std::vector<RemoteModelItem*> items;// Loop through all directory itemsfor(const auto& elem : array){// Create a new model item with the specified parentRemoteModelItem* item = new RemoteModelItem(parent);// Save all relevant values. If one of the values isn't set in the JSON document, an empty string// will be storeditem->setValue(RemoteModelColumnName, QString::fromStdString(elem["name"]));item->setValue(RemoteModelColumnType, QString::fromStdString(elem["type"]));item->setValue(RemoteModelColumnUrl, QString::fromStdString(elem["url"]));item->setValue(RemoteModelColumnLastModified, QString::fromStdString(elem["last_modified"]));if(elem.contains("commit_id"))item->setValue(RemoteModelColumnCommitId, QString::fromStdString(elem["commit_id"]));if(elem.contains("size"))item->setValue(RemoteModelColumnSize, QString::number(static_cast<int>(elem["size"])));items.push_back(item);}return items;}RemoteModel::RemoteModel(QObject* parent, RemoteDatabase& remote) :QAbstractItemModel(parent),rootItem(new RemoteModelItem()),remoteDatabase(remote){// Initialise list of column namesheaderList << tr("Name") << tr("Commit") << tr("Last modified") << tr("Size");// Set up signalsconnect(&remoteDatabase, &RemoteDatabase::gotDirList, this, &RemoteModel::parseDirectoryListing);}RemoteModel::~RemoteModel(){delete rootItem;}void RemoteModel::setNewRootDir(const QString& url, const QString& cert){// Get user name from client certcurrentUserName = remoteDatabase.getInfoFromClientCert(cert, RemoteDatabase::CertInfoUser);// Save settingscurrentRootDirectory = url;currentClientCert = cert;// Fetch root directory and put the reply data under the root itemremoteDatabase.fetch(currentRootDirectory, RemoteDatabase::RequestTypeDirectory, currentClientCert, QModelIndex());}void RemoteModel::parseDirectoryListing(const QString& text, const QVariant& userdata){// Load new JSON root document assuming it's an arrayjson array = json::parse(text.toStdString(), nullptr, false);if(array.is_discarded() || !array.is_array())return;// Get model index to store the new data underQModelIndex parent = userdata.toModelIndex();RemoteModelItem* parentItem = const_cast<RemoteModelItem*>(modelIndexToItem(parent));// An invalid model index indicates that this is a new root item. This means the old one needs to be entirely deleted first.if(!parent.isValid()){// Clear root itembeginResetModel();delete rootItem;rootItem = new RemoteModelItem();endResetModel();// Set parent model index and parent item to the new valuesparent = QModelIndex();parentItem = rootItem;}// Insert databeginInsertRows(parent, 0, static_cast<int>(array.size()));std::vector<RemoteModelItem*> items = RemoteModelItem::loadArray(array, parentItem);for(RemoteModelItem* item : items)parentItem->appendChild(item);endInsertRows();// Emit directory listing parsed signalemit directoryListingParsed(parent);}QModelIndex RemoteModel::index(int row, int column, const QModelIndex& parent) const{if(!hasIndex(row, column, parent))return QModelIndex();const RemoteModelItem* parentItem = modelIndexToItem(parent);RemoteModelItem* childItem = parentItem->child(row);if(childItem)return createIndex(row, column, childItem);elsereturn QModelIndex();}QModelIndex RemoteModel::parent(const QModelIndex& index) const{if(!index.isValid())return QModelIndex();const RemoteModelItem* childItem = modelIndexToItem(index);RemoteModelItem* parentItem = childItem->parent();if(parentItem == rootItem)return QModelIndex();return createIndex(parentItem->row(), 0, parentItem);}QVariant RemoteModel::data(const QModelIndex& index, int role) const{// Don't return data for invalid indicesif(!index.isValid())return QVariant();// Type of itemconst RemoteModelItem* item = modelIndexToItem(index);QString type = item->value(RemoteModelColumnType).toString();// Decoration role? Only for first column!if(role == Qt::DecorationRole && index.column() == 0){// Use different icons depending on item typeif(type == "folder" && index.parent() == QModelIndex() && item->value(RemoteModelColumnName) == currentUserName)return QImage(":/icons/folder_user");else if(type == "folder")return QImage(":/icons/folder");else if(type == "database")return QImage(":/icons/database");} else if(role == Qt::DisplayRole) {// Display role?// Return different value depending on columnswitch(index.column()){case 0:{return item->value(RemoteModelColumnName);}case 1:{if(type == "folder")return QVariant();return item->value(RemoteModelColumnCommitId);}case 2:{return item->value(RemoteModelColumnLastModified);}case 3:{// Folders don't have a sizeif(type == "folder")return QVariant();// Convert size to human readable formatfloat size = item->value(RemoteModelColumnSize).toFloat();QStringList list;list << "KiB" << "MiB" << "GiB" << "TiB";QStringListIterator it(list);QString unit(tr("bytes"));while(size >= 1024.0f && it.hasNext()){unit = it.next();size /= 1024.0f;}return QString().setNum(size, 'f', 2).remove(".00") + QString(" ") + unit;}}}return QVariant();}QVariant RemoteModel::headerData(int section, Qt::Orientation orientation, int role) const{// Call default implementation for vertical headers and for non-display rolesif(role != Qt::DisplayRole || orientation != Qt::Horizontal)return QAbstractItemModel::headerData(section, orientation, role);// Return header string depending on columnreturn headerList.at(section);}int RemoteModel::rowCount(const QModelIndex& parent) const{if(parent.column() > 0)return 0;const RemoteModelItem* parentItem = modelIndexToItem(parent);return parentItem->childCount();}int RemoteModel::columnCount(const QModelIndex& /*parent*/) const{return headerList.size();}bool RemoteModel::hasChildren(const QModelIndex& parent) const{if(!parent.isValid())return true;// If the item actually has children or is of type "folder" (and may have no children yet), we say that it actually has childrenconst RemoteModelItem* item = modelIndexToItem(parent);return item->childCount() || item->value(RemoteModelColumnType) == "folder";}bool RemoteModel::canFetchMore(const QModelIndex& parent) const{if(!parent.isValid())return false;// If the item is of type "folder" and we haven't tried fetching a directory listing yet, we indicate that there might be more data to loadconst RemoteModelItem* item = modelIndexToItem(parent);return item->value(RemoteModelColumnType) == "folder" && !item->fetchedDirectoryList();}void RemoteModel::fetchMore(const QModelIndex& parent){// Can we even fetch more data?if(!canFetchMore(parent))return;// Get parent itemRemoteModelItem* item = static_cast<RemoteModelItem*>(parent.internalPointer());// Fetch item URLitem->setFetchedDirectoryList(true);remoteDatabase.fetch(item->value(RemoteModelColumnUrl).toString(), RemoteDatabase::RequestTypeDirectory, currentClientCert, parent);}const QString& RemoteModel::currentClientCertificate() const{return currentClientCert;}const RemoteModelItem* RemoteModel::modelIndexToItem(const QModelIndex& idx) const{if(!idx.isValid())return rootItem;elsereturn static_cast<const RemoteModelItem*>(idx.internalPointer());}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。