on c7cb640 help sign in
unity8/plugins/Utils/windowstatestorage.cpp
156 lines 5.1 kB history raw
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
17#include "windowstatestorage.h"
19#include <QtConcurrent>
20#include <QDebug>
21#include <QFutureSynchronizer>
22#include <QSqlQuery>
23#include <QSqlError>
24#include <QSqlResult>
25#include <QRect>
27QMutex WindowStateStorage::s_mutex;
29WindowStateStorage::WindowStateStorage(QObject *parent):
30 QObject(parent)
32 QString dbPath = QDir::homePath() + "/.cache/unity8/";
33 m_db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"));
34 QDir dir;
35 dir.mkpath(dbPath);
36 m_db.setDatabaseName(dbPath + "windowstatestorage.sqlite");
37 initdb();
40WindowStateStorage::~WindowStateStorage()
42 QFutureSynchronizer<void> futureSync;
43 for (int i = 0; i < m_asyncQueries.count(); ++i) {
44 futureSync.addFuture(m_asyncQueries[i]);
45 }
46 futureSync.waitForFinished();
47 m_db.close();
50void WindowStateStorage::saveState(const QString &windowId, WindowStateStorage::WindowState state)
52 const QString queryString = QStringLiteral("INSERT OR REPLACE INTO state (windowId, state) values ('%1', '%2');")
53 .arg(windowId)
54 .arg((int)state);
56 saveValue(queryString);
59WindowStateStorage::WindowState WindowStateStorage::getState(const QString &windowId, WindowStateStorage::WindowState defaultValue) const
61 const QString queryString = QStringLiteral("SELECT * FROM state WHERE windowId = '%1';")
62 .arg(windowId);
64 QSqlQuery query = getValue(queryString);
66 if (!query.first()) {
67 return defaultValue;
68 }
69 return (WindowState)query.value(QStringLiteral("state")).toInt();
72void WindowStateStorage::saveGeometry(const QString &windowId, const QRect rect)
74 const QString queryString = QStringLiteral("INSERT OR REPLACE INTO geometry (windowId, x, y, width, height) values ('%1', '%2', '%3', '%4', '%5');")
75 .arg(windowId)
76 .arg(rect.x())
77 .arg(rect.y())
78 .arg(rect.width())
79 .arg(rect.height());
81 saveValue(queryString);
84void WindowStateStorage::executeAsyncQuery(const QString &queryString)
86 QMutexLocker l(&s_mutex);
87 QSqlQuery query;
89 bool ok = query.exec(queryString);
90 if (!ok) {
91 qWarning() << "Error executing query" << queryString
92 << "Driver error:" << query.lastError().driverText()
93 << "Database error:" << query.lastError().databaseText();
94 }
97QRect WindowStateStorage::getGeometry(const QString &windowId, const QRect defaultValue) const
99 QString queryString = QStringLiteral("SELECT * FROM geometry WHERE windowId = '%1';")
100 .arg(windowId);
102 QSqlQuery query = getValue(queryString);
104 if (!query.first()) {
105 return defaultValue;
106 }
107 return QRect(query.value(QStringLiteral("x")).toInt(), query.value(QStringLiteral("y")).toInt(), query.value(QStringLiteral("width")).toInt(), query.value(QStringLiteral("height")).toInt());
110void WindowStateStorage::initdb()
112 m_db.open();
113 if (!m_db.open()) {
114 qWarning() << "Error opening state database:" << m_db.lastError().driverText() << m_db.lastError().databaseText();
115 return;
116 }
118 if (!m_db.tables().contains(QStringLiteral("geometry"))) {
119 QSqlQuery query;
120 query.exec(QStringLiteral("CREATE TABLE geometry(windowId TEXT UNIQUE, x INTEGER, y INTEGER, width INTEGER, height INTEGER);"));
121 }
123 if (!m_db.tables().contains(QStringLiteral("state"))) {
124 QSqlQuery query;
125 query.exec(QStringLiteral("CREATE TABLE state(windowId TEXT UNIQUE, state INTEGER);"));
126 }
129void WindowStateStorage::saveValue(const QString &queryString)
131 QMutexLocker mutexLocker(&s_mutex);
133 QFuture<void> future = QtConcurrent::run(executeAsyncQuery, queryString);
134 m_asyncQueries.append(future);
136 QFutureWatcher<void> *futureWatcher = new QFutureWatcher<void>();
137 futureWatcher->setFuture(future);
138 connect(futureWatcher, &QFutureWatcher<void>::finished,
139 this,
140 [=](){ m_asyncQueries.removeAll(futureWatcher->future());
141 futureWatcher->deleteLater(); });
144QSqlQuery WindowStateStorage::getValue(const QString &queryString) const
146 QMutexLocker l(&s_mutex);
147 QSqlQuery query;
149 bool ok = query.exec(queryString);
150 if (!ok) {
151 qWarning() << "Error retrieving database query:" << queryString
152 << "Driver error:" << query.lastError().driverText()
153 << "Database error:" << query.lastError().databaseText();
154 }
155 return query;