Changeset View
Changeset View
Standalone View
Standalone View
src/project/projectmodel.cpp
Show All 21 Lines | 1 | /* **************************************************************************** | |||
---|---|---|---|---|---|
22 | 22 | | |||
23 | You should have received a copy of the GNU General Public License | 23 | You should have received a copy of the GNU General Public License | ||
24 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 24 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
25 | 25 | | |||
26 | **************************************************************************** */ | 26 | **************************************************************************** */ | ||
27 | 27 | | |||
28 | #include "projectmodel.h" | 28 | #include "projectmodel.h" | ||
29 | 29 | | |||
30 | #include "lokalize_debug.h" | | |||
31 | | ||||
32 | #include "project.h" | | |||
33 | #include "metadata/poextractor.h" | | |||
34 | #include "metadata/xliffextractor.h" | | |||
35 | | ||||
36 | #include <QIcon> | 30 | #include <QIcon> | ||
37 | #include <QTime> | 31 | #include <QTime> | ||
38 | #include <QFile> | 32 | #include <QFile> | ||
39 | #include <QDir> | 33 | #include <QDir> | ||
40 | #include <QtAlgorithms> | 34 | #include <QtAlgorithms> | ||
41 | #include <QTimer> | 35 | #include <QTimer> | ||
42 | #include <QThreadPool> | 36 | #include <QThreadPool> | ||
43 | #include <QSqlDatabase> | | |||
44 | #include <QSqlQuery> | | |||
45 | #include <QSqlError> | | |||
46 | #include <QStandardPaths> | | |||
47 | 37 | | |||
48 | #include <klocalizedstring.h> | 38 | #include <KLocalizedString> | ||
39 | #include <KDirLister> | ||||
40 | | ||||
41 | #include "lokalize_debug.h" | ||||
42 | #include "project.h" | ||||
43 | #include "updatestatsjob.h" | ||||
49 | 44 | | |||
50 | static int nodeCounter = 0; | 45 | static int nodeCounter = 0; | ||
51 | 46 | | |||
52 | ProjectModel::ProjectModel(QObject *parent) | 47 | ProjectModel::ProjectModel(QObject *parent) | ||
53 | : QAbstractItemModel(parent) | 48 | : QAbstractItemModel(parent) | ||
54 | , m_poModel(this) | 49 | , m_poModel(this) | ||
55 | , m_potModel(this) | 50 | , m_potModel(this) | ||
56 | , m_rootNode(NULL, -1, -1, -1) | 51 | , m_rootNode(NULL, -1, -1, -1) | ||
▲ Show 20 Lines • Show All 1199 Lines • ▼ Show 20 Line(s) | 1249 | { | |||
1256 | metaDataStatus = info.invalid_file ? Status::InvalidFile : Status::HasStats; | 1251 | metaDataStatus = info.invalid_file ? Status::InvalidFile : Status::HasStats; | ||
1257 | } | 1252 | } | ||
1258 | 1253 | | |||
1259 | void ProjectModel::ProjectNode::resetMetaData() | 1254 | void ProjectModel::ProjectNode::resetMetaData() | ||
1260 | { | 1255 | { | ||
1261 | metaDataStatus = Status::NoStats; | 1256 | metaDataStatus = Status::NoStats; | ||
1262 | metaData = FileMetaData(); | 1257 | metaData = FileMetaData(); | ||
1263 | } | 1258 | } | ||
1264 | | ||||
1265 | | ||||
1266 | //BEGIN UpdateStatsJob | | |||
1267 | //these are run in separate thread | | |||
1268 | UpdateStatsJob::UpdateStatsJob(const QList<KFileItem> &files, QObject*) | | |||
1269 | : QRunnable() | | |||
1270 | , m_files(files) | | |||
1271 | , m_status(0) | | |||
1272 | { | | |||
1273 | setAutoDelete(false); | | |||
1274 | } | | |||
1275 | | ||||
1276 | UpdateStatsJob::~UpdateStatsJob() | | |||
1277 | { | | |||
1278 | } | | |||
1279 | | ||||
1280 | //#define NOMETAINFOCACHE | | |||
1281 | #ifndef NOMETAINFOCACHE | | |||
1282 | static void initDataBase(QSqlDatabase& db) | | |||
1283 | { | | |||
1284 | QSqlQuery queryMain(db); | | |||
1285 | queryMain.exec(QStringLiteral("PRAGMA encoding = \"UTF-8\"")); | | |||
1286 | queryMain.exec(QStringLiteral( | | |||
1287 | "CREATE TABLE IF NOT EXISTS metadata (" | | |||
1288 | "filepath INTEGER PRIMARY KEY ON CONFLICT REPLACE, "// AUTOINCREMENT," | | |||
1289 | //"filepath TEXT UNIQUE ON CONFLICT REPLACE, " | | |||
1290 | "metadata BLOB, "//XLIFF markup info, see catalog/catalogstring.h catalog/xliff/* | | |||
1291 | "changedate INTEGER" | | |||
1292 | ")")); | | |||
1293 | | ||||
1294 | //queryMain.exec("CREATE INDEX IF NOT EXISTS filepath_index ON metainfo ("filepath)"); | | |||
1295 | } | | |||
1296 | #endif | | |||
1297 | | ||||
1298 | static FileMetaData cachedMetaData(const KFileItem& file) | | |||
1299 | { | | |||
1300 | if (file.isNull() || file.isDir()) | | |||
1301 | return FileMetaData(); | | |||
1302 | #ifdef NOMETAINFOCACHE | | |||
1303 | return FileMetaData::extract(file.localPath()); | | |||
1304 | #else | | |||
1305 | QString dbName = QStringLiteral("metainfocache"); | | |||
1306 | if (!QSqlDatabase::contains(dbName)) { | | |||
1307 | QSqlDatabase db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), dbName); | | |||
1308 | db.setDatabaseName(QStandardPaths::writableLocation(QStandardPaths::DataLocation) % QLatin1Char('/') % dbName % QLatin1String(".sqlite")); | | |||
1309 | if (Q_UNLIKELY(!db.open())) | | |||
1310 | return FileMetaData::extract(file.localPath()); | | |||
1311 | initDataBase(db); | | |||
1312 | } | | |||
1313 | QSqlDatabase db = QSqlDatabase::database(dbName); | | |||
1314 | if (!db.isOpen()) | | |||
1315 | return FileMetaData::extract(file.localPath()); | | |||
1316 | | ||||
1317 | QByteArray result; | | |||
1318 | | ||||
1319 | QSqlQuery queryCache(db); | | |||
1320 | queryCache.prepare(QStringLiteral("SELECT * from metadata where filepath=?")); | | |||
1321 | queryCache.bindValue(0, qHash(file.localPath())); | | |||
1322 | queryCache.exec(); | | |||
1323 | //not using file.time(KFileItem::ModificationTime) because it gives wrong result for files that have just been saved in editor | | |||
1324 | if (queryCache.next() && QFileInfo(file.localPath()).lastModified() == queryCache.value(2).toDateTime()) { | | |||
1325 | result = queryCache.value(1).toByteArray(); | | |||
1326 | QDataStream stream(&result, QIODevice::ReadOnly); | | |||
1327 | | ||||
1328 | FileMetaData info; | | |||
1329 | stream >> info; | | |||
1330 | Q_ASSERT(info.translated == FileMetaData::extract(file.localPath()).translated); | | |||
1331 | return info; | | |||
1332 | } | | |||
1333 | | ||||
1334 | FileMetaData m = FileMetaData::extract(file.localPath()); | | |||
1335 | | ||||
1336 | QDataStream stream(&result, QIODevice::WriteOnly); | | |||
1337 | //this is synced with ProjectModel::ProjectNode::setFileStats | | |||
1338 | stream << m; | | |||
1339 | | ||||
1340 | QSqlQuery query(db); | | |||
1341 | | ||||
1342 | query.prepare(QStringLiteral("INSERT INTO metadata (filepath, metadata, changedate) " | | |||
1343 | "VALUES (?, ?, ?)")); | | |||
1344 | query.bindValue(0, qHash(file.localPath())); | | |||
1345 | query.bindValue(1, result); | | |||
1346 | query.bindValue(2, QFileInfo(file.localPath()).lastModified()); | | |||
1347 | if (Q_UNLIKELY(!query.exec())) | | |||
1348 | qCWarning(LOKALIZE_LOG) << "metainfo cache acquiring error: " << query.lastError().text(); | | |||
1349 | | ||||
1350 | return m; | | |||
1351 | #endif | | |||
1352 | } | | |||
1353 | | ||||
1354 | void UpdateStatsJob::run() | | |||
1355 | { | | |||
1356 | #ifndef NOMETAINFOCACHE | | |||
1357 | QString dbName = QStringLiteral("metainfocache"); | | |||
1358 | bool ok = QSqlDatabase::contains(dbName); | | |||
1359 | if (ok) { | | |||
1360 | QSqlDatabase db = QSqlDatabase::database(dbName); | | |||
1361 | QSqlQuery queryBegin(QStringLiteral("BEGIN"), db); | | |||
1362 | } | | |||
1363 | #endif | | |||
1364 | m_info.reserve(m_files.count()); | | |||
1365 | for (int pos = 0; pos < m_files.count(); pos++) { | | |||
1366 | if (m_status != 0) | | |||
1367 | break; | | |||
1368 | | ||||
1369 | m_info.append(cachedMetaData(m_files.at(pos))); | | |||
1370 | } | | |||
1371 | #ifndef NOMETAINFOCACHE | | |||
1372 | if (ok) { | | |||
1373 | QSqlDatabase db = QSqlDatabase::database(dbName); | | |||
1374 | { | | |||
1375 | //braces are needed to avoid resource leak on close | | |||
1376 | QSqlQuery queryEnd(QStringLiteral("END"), db); | | |||
1377 | } | | |||
1378 | db.close(); | | |||
1379 | db.open(); | | |||
1380 | } | | |||
1381 | #endif | | |||
1382 | emit done(this); | | |||
1383 | } | | |||
1384 | | ||||
1385 | void UpdateStatsJob::setStatus(int status) | | |||
1386 | { | | |||
1387 | m_status = status; | | |||
1388 | } | | |||
1389 | //END UpdateStatsJob | | |||
1390 | |