filemodel.cpp 6.84 KB
Newer Older
1
/*
2
 * Copyright (C) 2014-2018 CZ.NIC
3 4 5 6 7 8 9 10
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 13 14 15 16 17 18 19 20 21 22 23
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations including
 * the two.
 */

24
#include <QQmlEngine> /* qmlRegisterType */
25
#include <QSqlRecord>
26
#include <QStringBuilder>
27

28
#include "src/files.h" /* TODO -- Do something with it. */
29 30
#include "src/models/filemodel.h"

31 32 33 34 35 36
FileListModel::Entry::Entry(const Entry &other)
    : m_fileId(other.m_fileId),
    m_fileName(other.m_fileName),
    m_data(other.m_data),
    m_fileSize(other.m_fileSize),
    m_filePath(other.m_filePath)
37 38 39
{
}

40
FileListModel::Entry::Entry(const int fileId, const QString &fileName,
41
    const QByteArray &data, qint64 fileSize, const QString &filePath)
42
    : m_fileId(fileId),
43
    m_fileName(fileName),
44 45
    m_data(data),
    m_fileSize(fileSize),
Martin Straka's avatar
Martin Straka committed
46
    m_filePath(filePath)
47 48 49
{
}

50
int FileListModel::Entry::fileId(void) const
51 52 53 54
{
	return m_fileId;
}

55
const QString &FileListModel::Entry::fileName(void) const
56
{
57
	return m_fileName;
58 59
}

60
void FileListModel::Entry::setFileName(const QString &fileName)
61
{
62
	m_fileName = fileName;
63 64
}

65 66 67 68 69 70 71 72
/*!
 * @brief Creates human readable size description string.
 *
 * @param[in] dataSize Size in bytes.
 * @return String containing units.
 */
static
QString approximateDataSize(qint64 dataSize)
73
{
74
	if (dataSize >= 1024) {
75 76
		qint64 kBytes = dataSize >> 10; /* dataSize / 1024 */
		/* (dataSize % 1024) >= 512 -> increase dicision by 1 */
Karel Slaný's avatar
Karel Slaný committed
77
		kBytes += (dataSize & 0x0200) ? 1 : 0; /* round((float)(dataSize / 1024)) */
78
		return QStringLiteral("~") % QString::number(kBytes) % QStringLiteral(" kB");
79 80 81
	} else {
		return QStringLiteral("~") % QString::number(dataSize) % QStringLiteral(" B");
	}
82 83
}

84
QString FileListModel::Entry::fileSizeStr(void) const
85
{
86 87 88 89 90
	if (m_fileSize >= 0) {
		return approximateDataSize(m_fileSize);
	} else {
		return QString();
	}
91 92
}

93
const QByteArray &FileListModel::Entry::binaryContent(void) const
94
{
95
	return m_data;
96 97
}

98
void FileListModel::Entry::setBinaryContent(const QByteArray &data)
99
{
100
	m_data = data;
101 102
}

103
qint64 FileListModel::Entry::fileSize(void) const
104
{
105
	return m_fileSize;
106 107
}

108
void FileListModel::Entry::setFileSize(qint64 fileSize)
109
{
110
	m_fileSize = fileSize;
111 112
}

113
const QString &FileListModel::Entry::filePath(void) const
Martin Straka's avatar
Martin Straka committed
114 115 116 117 118 119 120 121 122
{
	return m_filePath;
}

void FileListModel::Entry::setFilePath(const QString &filePath)
{
	m_filePath = filePath;
}

123 124 125
void FileListModel::declareQML(void)
{
	qmlRegisterType<FileListModel>("cz.nic.mobileDatovka.models", 1, 0, "FileListModel");
126
	qRegisterMetaType<FileListModel>();
127 128
}

129
FileListModel::FileListModel(QObject *parent)
130 131 132 133 134 135 136 137
    : QAbstractListModel(parent),
    m_files()
{
}

FileListModel::FileListModel(const FileListModel &model, QObject *parent)
    : QAbstractListModel(parent),
    m_files(model.m_files)
138 139 140 141 142
{
}

int FileListModel::rowCount(const QModelIndex &parent) const
{
Martin Straka's avatar
Martin Straka committed
143
	return !parent.isValid() ? m_files.size() : 0;
144 145 146 147 148 149 150 151
}

QHash<int, QByteArray> FileListModel::roleNames(void) const
{
	static QHash<int, QByteArray> roles;
	if (roles.isEmpty()) {
		roles[ROLE_FILE_ID] = "rFileId";
		roles[ROLE_FILE_NAME] = "rFileName";
152
		roles[ROLE_FILE_SIZE_STR] = "rFileSizeStr";
153
		roles[ROLE_BINARY_DATA] = "rBinaryContent";
154
		roles[ROLE_FILE_SIZE_BYTES] = "rFileSizeBytes";
Martin Straka's avatar
Martin Straka committed
155
		roles[ROLE_FILE_PATH] = "rFilePath";
156 157 158 159 160 161 162 163 164 165
	}
	return roles;
}

QVariant FileListModel::data(const QModelIndex &index, int role) const
{
	if ((index.row() < 0) || (index.row() >= m_files.size())) {
		return QVariant();
	}

166
	const Entry &file(m_files[index.row()]);
167 168 169 170 171 172

	switch (role) {
	case ROLE_FILE_ID:
		return file.fileId();
		break;
	case ROLE_FILE_NAME:
173
		return file.fileName();
174
		break;
175 176
	case ROLE_FILE_SIZE_STR:
		return file.fileSizeStr();
177
		break;
178 179
	case ROLE_BINARY_DATA:
		return file.binaryContent();
180
		break;
181
	case ROLE_FILE_SIZE_BYTES:
182
		return file.fileSize();
183
		break;
Martin Straka's avatar
Martin Straka committed
184 185 186
	case ROLE_FILE_PATH:
		return file.filePath();
		break;
187
	default:
188
		/* Do nothing. */
189 190 191 192 193 194
		break;
	}

	return QVariant();
}

Martin Straka's avatar
Martin Straka committed
195 196 197 198 199 200 201 202 203 204 205
QList<FileListModel::Entry> FileListModel::allEntries(void) const
{
	QList<FileListModel::Entry> entries;

	foreach (const FileListModel::Entry &file, m_files) {
		entries.append(file);
	}

	return entries;
}

206
QString FileListModel::filePathFromRow(int row) const
Martin Straka's avatar
Martin Straka committed
207
{
208 209
	if (Q_UNLIKELY((row < 0) || (row >= m_files.size()))) {
		Q_ASSERT(0);
Martin Straka's avatar
Martin Straka committed
210 211 212 213 214 215
		return QString();
	}

	return m_files[row].filePath();
}

216
qint64 FileListModel::dataSizeSum(void) const
217
{
218 219 220
	qint64 sum = 0;
	foreach (const Entry &entry, m_files) {
		sum += entry.fileSize();
221
	}
222
	return sum;
223 224
}

225 226
Qt::ItemFlags FileListModel::flags(const QModelIndex &index) const
{
227
	return QAbstractListModel::flags(index);
228 229 230 231
}

void FileListModel::setQuery(QSqlQuery &query)
{
232
	if (query.record().count() != 3) {
233 234 235 236 237 238 239 240 241
		return;
	}

	beginResetModel();

	m_files.clear();

	query.first();
	while (query.isActive() && query.isValid()) {
242
		m_files.append(Entry(query.value(0).toInt(),
243 244
		    query.value(1).toString(), QByteArray(),
		    query.value(2).toLongLong(), QString()));
245 246 247 248 249 250
		query.next();
	}

	endResetModel();
}

251
void FileListModel::appendFileEntry(const Entry &entry)
252
{
253 254
	beginInsertRows(QModelIndex(), rowCount(), rowCount());
	m_files.append(entry);
Martin Straka's avatar
Martin Straka committed
255 256
	endInsertRows();
}
257

Martin Straka's avatar
Martin Straka committed
258
void FileListModel::appendFileFromPath(int fileId, const QString &fileName,
259
    const QString &filePath, qint64 fileSizeBytes)
Martin Straka's avatar
Martin Straka committed
260 261
{
	beginInsertRows(QModelIndex(), rowCount(), rowCount());
262 263
	m_files.append(FileListModel::Entry(fileId, fileName, QByteArray(),
	    fileSizeBytes, filePath));
264
	endInsertRows();
265 266
}

267 268 269 270 271 272
void FileListModel::clearAll(void)
{
	beginResetModel();
	m_files.clear();
	endResetModel();
}
273

274
FileListModel *FileListModel::fromVariant(const QVariant &modelVariant)
275
{
276
	if (!modelVariant.canConvert<QObject *>()) {
277 278
		return Q_NULLPTR;
	}
279
	QObject *obj = qvariant_cast<QObject *>(modelVariant);
280 281 282
	return qobject_cast<FileListModel *>(obj);
}

283
bool FileListModel::setFromDb(const QString &userName, const QString &msgIdStr)
284 285 286 287 288 289 290
{
	bool ok = false;
	qint64 msgId = msgIdStr.toLongLong(&ok);
	if (!ok || (msgId < 0)) {
		return false;
	}

291
	return Files::setAttachmentModel(*this, userName, msgId);
292
}
Martin Straka's avatar
Martin Straka committed
293 294 295 296 297 298 299 300 301 302 303

void FileListModel::removeItem(int row)
{
	if ((row < 0) || (row >= m_files.size())) {
		return;
	}

	beginRemoveRows(QModelIndex(), row, row);
	m_files.removeAt(row);
	endRemoveRows();
}