Skip to content

Commit

Permalink
UI: ProgramsWindow: Add sorting.
Browse files Browse the repository at this point in the history
  • Loading branch information
tnodir committed Jan 8, 2020
1 parent eda332e commit afac18e
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 65 deletions.
34 changes: 12 additions & 22 deletions src/ui/3rdparty/sqlite/sqlitedb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,28 +115,18 @@ QVariant SqliteDb::executeEx(const char *sql,
QVariantList list;

SqliteStmt stmt;
bool success = true;

if (stmt.prepare(db(), sql)) {
// Bind variables
if (!vars.isEmpty()) {
int index = 0;
for (const QVariant &v : vars) {
success = stmt.bindVar(++index, v);
if (!success) break;
}
}

if (success) {
const auto stepRes = stmt.step();
success = (stepRes != SqliteStmt::StepError);

// Get result
if (stepRes == SqliteStmt::StepRow) {
for (int i = 0; i < resultCount; ++i) {
const QVariant v = stmt.columnVar(i);
list.append(v);
}
bool success = false;

if (stmt.prepare(db(), sql)
&& stmt.bindVars(vars)) {
const auto stepRes = stmt.step();
success = (stepRes != SqliteStmt::StepError);

// Get result
if (stepRes == SqliteStmt::StepRow) {
for (int i = 0; i < resultCount; ++i) {
const QVariant v = stmt.columnVar(i);
list.append(v);
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/ui/3rdparty/sqlite/sqlitestmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,15 @@ bool SqliteStmt::bindVar(int index, const QVariant &v)
}
}

bool SqliteStmt::bindVars(const QVariantList &vars, int index)
{
for (const QVariant &v : vars) {
if (!bindVar(index++, v))
return false;
}
return true;
}

bool SqliteStmt::clearBindings()
{
m_bindObjects.clear();
Expand Down
1 change: 1 addition & 0 deletions src/ui/3rdparty/sqlite/sqlitestmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class SqliteStmt
bool bindDateTime(int index, const QDateTime &dateTime);
bool bindBlob(int index, const QByteArray &data);
bool bindVar(int index, const QVariant &v);
bool bindVars(const QVariantList &vars, int index = 1);

bool clearBindings();
bool reset();
Expand Down
31 changes: 8 additions & 23 deletions src/ui/conf/confmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,22 +122,6 @@ const char * const sqlUpdateTask =
" WHERE task_id = ?1;"
;

const char * const sqlSelectAppCount =
"SELECT count(*) FROM app;"
;

const char * const sqlSelectAppByIndex =
"SELECT t.app_id,"
" g.order_index as group_index,"
" t.path, t.use_group_perm, t.blocked,"
" (alert.app_id IS NOT NULL) as alerted,"
" t.end_time"
" FROM app t"
" JOIN app_group g ON g.app_group_id = t.app_group_id"
" LEFT JOIN app_alert alert ON alert.app_id = t.app_id"
" LIMIT 1 OFFSET ?1;"
;

const char * const sqlSelectApps =
"SELECT g.order_index as group_index,"
" t.path, t.use_group_perm, t.blocked,"
Expand Down Expand Up @@ -325,26 +309,26 @@ bool ConfManager::saveTasks(const QList<TaskInfo *> &taskInfos)
return ok;
}

int ConfManager::appCount()
int ConfManager::appCount(const QString &sql)
{
SqliteStmt stmt;
if (!stmt.prepare(m_sqliteDb->db(), sqlSelectAppCount)
if (!stmt.prepare(m_sqliteDb->db(), sql.toLatin1())
|| stmt.step() != SqliteStmt::StepRow)
return 0;

return stmt.columnInt(0);
}

bool ConfManager::getAppByIndex(bool &useGroupPerm, bool &blocked, bool &alerted,
qint64 &appId, int &groupIndex,
QString &appPath, QDateTime &endTime, int row)
qint64 &appId, int &groupIndex, QString &appPath,
QDateTime &endTime, QDateTime &creatTime,
const QString &sql, const QVariantList &vars)
{
SqliteStmt stmt;
if (!stmt.prepare(m_sqliteDb->db(), sqlSelectAppByIndex))
if (!stmt.prepare(m_sqliteDb->db(), sql.toLatin1())
|| !stmt.bindVars(vars))
return false;

stmt.bindInt(1, row);

if (stmt.step() != SqliteStmt::StepRow)
return false;

Expand All @@ -355,6 +339,7 @@ bool ConfManager::getAppByIndex(bool &useGroupPerm, bool &blocked, bool &alerted
blocked = stmt.columnBool(4);
alerted = stmt.columnBool(5);
endTime = stmt.columnDateTime(6);
creatTime = stmt.columnDateTime(7);

return true;
}
Expand Down
7 changes: 4 additions & 3 deletions src/ui/conf/confmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ class ConfManager : public QObject
bool loadTasks(const QList<TaskInfo *> &taskInfos);
bool saveTasks(const QList<TaskInfo *> &taskInfos);

int appCount();
int appCount(const QString &sql);
bool getAppByIndex(bool &useGroupPerm, bool &blocked, bool &alerted,
qint64 &appId, int &groupIndex,
QString &appPath, QDateTime &endTime, int row);
qint64 &appId, int &groupIndex, QString &appPath,
QDateTime &endTime, QDateTime &creatTime,
const QString &sql, const QVariantList &vars);
qint64 appGroupIdByIndex(int index = 0);
QStringList appGroupNames();

Expand Down
18 changes: 15 additions & 3 deletions src/ui/form/prog/programswindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

namespace {

#define APPS_HEADER_VERSION 1

const ValuesList appBlockInHourValues = {
3, 1, 6, 12, 24, 24 * 7, 24 * 30
};
Expand Down Expand Up @@ -81,10 +83,14 @@ void ProgramsWindow::onSaveWindowState()
{
auto header = m_appListView->horizontalHeader();
settings()->setProgAppsHeader(header->saveState());
settings()->setProgAppsHeaderVersion(APPS_HEADER_VERSION);
}

void ProgramsWindow::onRestoreWindowState()
{
if (settings()->progAppsHeaderVersion() != APPS_HEADER_VERSION)
return;

auto header = m_appListView->horizontalHeader();
header->restoreState(settings()->progAppsHeader());
}
Expand Down Expand Up @@ -224,7 +230,6 @@ void ProgramsWindow::setupAppEditForm()
auto pathLayout = new QHBoxLayout();

m_editPath = new QLineEdit();
m_editPath->setClearButtonEnabled(true);

m_btSelectFile = ControlUtil::createLinkButton(":/images/folder_explore.png");

Expand Down Expand Up @@ -366,6 +371,7 @@ void ProgramsWindow::setupTableApps()
m_appListView->setSelectionMode(QAbstractItemView::SingleSelection);
m_appListView->setSelectionBehavior(QAbstractItemView::SelectItems);

m_appListView->setSortingEnabled(true);
m_appListView->setModel(appListModel());

connect(m_appListView, &TableView::doubleClicked, m_btEditApp, &QPushButton::click);
Expand All @@ -376,14 +382,19 @@ void ProgramsWindow::setupTableAppsHeader()
auto header = m_appListView->horizontalHeader();

header->setSectionResizeMode(0, QHeaderView::Interactive);
header->setSectionResizeMode(1, QHeaderView::Stretch);
header->setSectionResizeMode(1, QHeaderView::Interactive);
header->setSectionResizeMode(2, QHeaderView::Fixed);
header->setSectionResizeMode(3, QHeaderView::Interactive);
header->setSectionResizeMode(4, QHeaderView::Stretch);
header->setSectionResizeMode(5, QHeaderView::Stretch);

header->resizeSection(0, 500);
header->resizeSection(2, 20);
header->resizeSection(3, 80);

header->setSectionsClickable(true);
header->setSortIndicatorShown(true);
header->setSortIndicator(5, Qt::DescendingOrder);
}

void ProgramsWindow::setupAppInfoRow()
Expand Down Expand Up @@ -472,6 +483,7 @@ void ProgramsWindow::updateAppEditForm(bool editCurrentApp)

m_editPath->setText(appRow.appPath);
m_editPath->setReadOnly(editCurrentApp);
m_editPath->setClearButtonEnabled(!editCurrentApp);
m_btSelectFile->setEnabled(!editCurrentApp);
m_comboAppGroup->setCurrentIndex(appRow.groupIndex);
m_cbUseGroupPerm->setChecked(appRow.useGroupPerm);
Expand All @@ -498,7 +510,7 @@ void ProgramsWindow::deleteCurrentApp()
const int appIndex = appListCurrentIndex();
if (appIndex >= 0) {
const auto appRow = appListModel()->appRow(appIndex);
appListModel()->deleteApp(appRow.appId, appRow.appPath);
appListModel()->deleteApp(appRow.appId, appRow.appPath, appIndex);
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/ui/fortsettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ class FortSettings : public QObject
bool progWindowMaximized() const { return iniBool("progWindow/maximized"); }
void setProgWindowMaximized(bool on) { setIniValue("progWindow/maximized", on); }

bool progAppsSortDesc() const { return iniBool("progWindow/appsSortDesc"); }
void setProgSortDesc(bool v) { setIniValue("progWindow/appsSortDesc", v); }

int progAppsSortColumn() const { return iniInt("progWindow/appsSortColumn"); }
void setProgSortColumn(int v) { setIniValue("progWindow/appsSortColumn", v); }

int progAppsHeaderVersion() const { return iniInt("progWindow/appsHeaderVersion"); }
void setProgAppsHeaderVersion(int v) { setIniValue("progWindow/appsHeaderVersion", v); }

QByteArray progAppsHeader() const { return iniByteArray("progWindow/appsHeader"); }
void setProgAppsHeader(const QByteArray &v) { setIniValue("progWindow/appsHeader", v); }

Expand Down
88 changes: 75 additions & 13 deletions src/ui/log/model/applistmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,28 +57,33 @@ int AppListModel::rowCount(const QModelIndex &parent) const
Q_UNUSED(parent)

if (m_appCount < 0) {
m_appCount = confManager()->appCount();
m_appCount = confManager()->appCount(sqlCount());
}

return m_appCount;
}

int AppListModel::columnCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : 5;
return parent.isValid() ? 0 : 6;
}

QVariant AppListModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (orientation == Qt::Horizontal
&& role == Qt::DisplayRole) {
switch (section) {
case 0: return tr("Program");
case 1: return tr("Group");
case 2: return tr("Gr.");
case 3: return tr("State");
case 4: return tr("End Time");
if (orientation == Qt::Horizontal) {
switch (role) {
case Qt::DisplayRole: {
switch (section) {
case 0: return tr("Program");
case 1: return tr("Group");
case 2: return tr("Gr.");
case 3: return tr("State");
case 4: return tr("End Time");
case 5: return tr("Creation Time");
}
break;
}
}
}
return QVariant();
Expand Down Expand Up @@ -111,6 +116,7 @@ QVariant AppListModel::data(const QModelIndex &index, int role) const
case 3: return appStateToString(m_rowCache.state);
case 4: return m_rowCache.endTime.isValid()
? m_rowCache.endTime : QVariant();
case 5: return m_rowCache.creatTime;
}

break;
Expand Down Expand Up @@ -174,6 +180,16 @@ QVariant AppListModel::data(const QModelIndex &index, int role) const
return QVariant();
}

void AppListModel::sort(int column, Qt::SortOrder order)
{
if (m_sortColumn != column || m_sortOrder != order) {
m_sortColumn = column;
m_sortOrder = order;

reset();
}
}

QString AppListModel::appPathByRow(int row) const
{
updateRowCache(row);
Expand Down Expand Up @@ -216,11 +232,13 @@ bool AppListModel::updateApp(qint64 appId, const QString &appPath,
return false;
}

void AppListModel::deleteApp(qint64 appId, const QString &appPath)
void AppListModel::deleteApp(qint64 appId, const QString &appPath, int row)
{
if (confManager()->updateDriverDeleteApp(appPath)
&& confManager()->deleteApp(appId)) {
reset();
beginRemoveRows(QModelIndex(), row, row);
invalidateRowCache();
endRemoveRows();
}
}

Expand Down Expand Up @@ -252,12 +270,56 @@ void AppListModel::updateRowCache(int row) const

if (m_confManager->getAppByIndex(m_rowCache.useGroupPerm, blocked, alerted,
m_rowCache.appId, m_rowCache.groupIndex,
m_rowCache.appPath, m_rowCache.endTime, row)) {
m_rowCache.appPath, m_rowCache.endTime,
m_rowCache.creatTime, sql(), {row})) {
m_rowCache.state = alerted ? AppAlert : (blocked ? AppBlock : AppAllow);
m_rowCache.row = row;
}
}

QString AppListModel::sqlCount() const
{
return "SELECT count(*) FROM (" + sqlBase() + ");";
}

QString AppListModel::sql() const
{
return sqlBase() + sqlOrder() + " LIMIT 1 OFFSET ?1;"
;
}

QString AppListModel::sqlBase() const
{
return
"SELECT t.app_id,"
" g.order_index as group_index,"
" t.path, t.use_group_perm, t.blocked,"
" (alert.app_id IS NOT NULL) as alerted,"
" t.end_time, t.creat_time"
" FROM app t"
" JOIN app_group g ON g.app_group_id = t.app_group_id"
" LEFT JOIN app_alert alert ON alert.app_id = t.app_id"
;
}

QString AppListModel::sqlOrder() const
{
QString columnsStr = "1";
switch (m_sortColumn) {
case 0: columnsStr = "3"; break; // Program
case 1: columnsStr = "2"; break; // Group
case 2: columnsStr = "4"; break; // Gr.
case 3: columnsStr = "5, 6"; break; // State
case 4: columnsStr = "7"; break; // End Time
case 5: columnsStr = "1"; break; // Creation Time
}

const QString orderStr = (m_sortOrder == Qt::AscendingOrder)
? "ASC" : "DESC";

return QString(" ORDER BY %1 %2").arg(columnsStr, orderStr);
}

void AppListModel::updateAppGroupNames()
{
m_appGroupNames = confManager()->appGroupNames();
Expand Down
Loading

0 comments on commit afac18e

Please sign in to comment.