mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2024-12-29 12:55:59 +01:00
Make the jumplist persistent on a per-file basis
This patch implements two new ZathuraDatabaseInterface functions, save_jumplist and load_jumplist, for both the plain and sqlite backends (along with some cleanups). Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
This commit is contained in:
parent
87a7f2310f
commit
99b32ae109
7 changed files with 416 additions and 78 deletions
14
config.c
14
config.c
|
@ -27,10 +27,18 @@ cb_jumplist_change(girara_session_t* session, const char* name,
|
||||||
g_return_if_fail(session->global.data != NULL);
|
g_return_if_fail(session->global.data != NULL);
|
||||||
g_return_if_fail(name != NULL);
|
g_return_if_fail(name != NULL);
|
||||||
zathura_t* zathura = session->global.data;
|
zathura_t* zathura = session->global.data;
|
||||||
if (g_strcmp0(name, "jumplist-size") == 0) {
|
|
||||||
int* max_size = (int*) value;
|
if (g_strcmp0(name, "jumplist-size") != 0) {
|
||||||
zathura->jumplist.max_size = *max_size;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*(int *)value < 0) {
|
||||||
|
zathura->jumplist.max_size = 0;
|
||||||
|
} else {
|
||||||
|
zathura->jumplist.max_size = *(int *)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
zathura_jumplist_trim(zathura);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#define KEY_FIRST_PAGE_COLUMN "first-page-column"
|
#define KEY_FIRST_PAGE_COLUMN "first-page-column"
|
||||||
#define KEY_POSITION_X "position-x"
|
#define KEY_POSITION_X "position-x"
|
||||||
#define KEY_POSITION_Y "position-y"
|
#define KEY_POSITION_Y "position-y"
|
||||||
|
#define KEY_JUMPLIST "jumplist"
|
||||||
|
|
||||||
#ifdef __GNU__
|
#ifdef __GNU__
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
|
@ -47,18 +48,14 @@ G_DEFINE_TYPE_WITH_CODE(ZathuraPlainDatabase, zathura_plaindatabase, G_TYPE_OBJE
|
||||||
G_IMPLEMENT_INTERFACE(GIRARA_TYPE_INPUT_HISTORY_IO, io_interface_init))
|
G_IMPLEMENT_INTERFACE(GIRARA_TYPE_INPUT_HISTORY_IO, io_interface_init))
|
||||||
|
|
||||||
static void plain_finalize(GObject* object);
|
static void plain_finalize(GObject* object);
|
||||||
static bool plain_add_bookmark(zathura_database_t* db, const char* file,
|
static bool plain_add_bookmark(zathura_database_t* db, const char* file, zathura_bookmark_t* bookmark);
|
||||||
zathura_bookmark_t* bookmark);
|
static bool plain_remove_bookmark(zathura_database_t* db, const char* file, const char* id);
|
||||||
static bool plain_remove_bookmark(zathura_database_t* db, const char* file,
|
static girara_list_t* plain_load_bookmarks(zathura_database_t* db, const char* file);
|
||||||
const char* id);
|
static girara_list_t* plain_load_jumplist(zathura_database_t* db, const char* file);
|
||||||
static girara_list_t* plain_load_bookmarks(zathura_database_t* db,
|
static bool plain_save_jumplist(zathura_database_t* db, const char* file, girara_list_t* jumplist);
|
||||||
const char* file);
|
static bool plain_set_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t* file_info);
|
||||||
static bool plain_set_fileinfo(zathura_database_t* db, const char* file,
|
static bool plain_get_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t* file_info);
|
||||||
zathura_fileinfo_t* file_info);
|
static void plain_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec);
|
||||||
static bool plain_get_fileinfo(zathura_database_t* db, const char* file,
|
|
||||||
zathura_fileinfo_t* file_info);
|
|
||||||
static void plain_set_property(GObject* object, guint prop_id,
|
|
||||||
const GValue* value, GParamSpec* pspec);
|
|
||||||
static void plain_io_append(GiraraInputHistoryIO* db, const char*);
|
static void plain_io_append(GiraraInputHistoryIO* db, const char*);
|
||||||
static girara_list_t* plain_io_read(GiraraInputHistoryIO* db);
|
static girara_list_t* plain_io_read(GiraraInputHistoryIO* db);
|
||||||
|
|
||||||
|
@ -66,8 +63,7 @@ static girara_list_t* plain_io_read(GiraraInputHistoryIO* db);
|
||||||
static bool zathura_db_check_file(const char* path);
|
static bool zathura_db_check_file(const char* path);
|
||||||
static GKeyFile* zathura_db_read_key_file_from_file(const char* path);
|
static GKeyFile* zathura_db_read_key_file_from_file(const char* path);
|
||||||
static void zathura_db_write_key_file_to_file(const char* file, GKeyFile* key_file);
|
static void zathura_db_write_key_file_to_file(const char* file, GKeyFile* key_file);
|
||||||
static void cb_zathura_db_watch_file(GFileMonitor* monitor, GFile* file, GFile*
|
static void cb_zathura_db_watch_file(GFileMonitor* monitor, GFile* file, GFile* other_file, GFileMonitorEvent event, zathura_database_t* database);
|
||||||
other_file, GFileMonitorEvent event, zathura_database_t* database);
|
|
||||||
|
|
||||||
typedef struct zathura_plaindatabase_private_s {
|
typedef struct zathura_plaindatabase_private_s {
|
||||||
char* bookmark_path;
|
char* bookmark_path;
|
||||||
|
@ -110,6 +106,8 @@ zathura_database_interface_init(ZathuraDatabaseInterface* iface)
|
||||||
iface->add_bookmark = plain_add_bookmark;
|
iface->add_bookmark = plain_add_bookmark;
|
||||||
iface->remove_bookmark = plain_remove_bookmark;
|
iface->remove_bookmark = plain_remove_bookmark;
|
||||||
iface->load_bookmarks = plain_load_bookmarks;
|
iface->load_bookmarks = plain_load_bookmarks;
|
||||||
|
iface->load_jumplist = plain_load_jumplist;
|
||||||
|
iface->save_jumplist = plain_save_jumplist;
|
||||||
iface->set_fileinfo = plain_set_fileinfo;
|
iface->set_fileinfo = plain_set_fileinfo;
|
||||||
iface->get_fileinfo = plain_get_fileinfo;
|
iface->get_fileinfo = plain_get_fileinfo;
|
||||||
}
|
}
|
||||||
|
@ -427,6 +425,73 @@ plain_load_bookmarks(zathura_database_t* db, const char* file)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static girara_list_t*
|
||||||
|
get_jumplist_from_str(const char* str)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(str != NULL, NULL);
|
||||||
|
|
||||||
|
if (*str == 0) {
|
||||||
|
return girara_list_new2(g_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
girara_list_t* result = girara_list_new2(g_free);
|
||||||
|
char* copy = g_strdup(str);
|
||||||
|
char* token = strtok(copy, " ");
|
||||||
|
|
||||||
|
while (token != NULL) {
|
||||||
|
zathura_jump_t* jump = g_malloc0(sizeof(zathura_jump_t));
|
||||||
|
|
||||||
|
jump->page = strtoul(token, NULL, 0);
|
||||||
|
token = strtok(NULL, " ");
|
||||||
|
jump->x = strtod(token, NULL);
|
||||||
|
token = strtok(NULL, " ");
|
||||||
|
jump->y = strtod(token, NULL);
|
||||||
|
girara_list_append(result, jump);
|
||||||
|
token = strtok(NULL, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(copy);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static girara_list_t*
|
||||||
|
plain_load_jumplist(zathura_database_t* db, const char* file)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(db != NULL && file != NULL, NULL);
|
||||||
|
|
||||||
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db);
|
||||||
|
char* str_value = g_key_file_get_string(priv->history, file, KEY_JUMPLIST, NULL);
|
||||||
|
|
||||||
|
if (str_value == NULL) {
|
||||||
|
return girara_list_new2(g_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_jumplist_from_str(str_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
plain_save_jumplist(zathura_database_t* db, const char* file, girara_list_t* jumplist)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(db != NULL && file != NULL && jumplist != NULL, false);
|
||||||
|
|
||||||
|
GString* str_val = g_string_new(NULL);
|
||||||
|
|
||||||
|
GIRARA_LIST_FOREACH(jumplist, zathura_jump_t*, iter, jump)
|
||||||
|
g_string_append(str_val, g_strdup_printf("%d ", jump->page));
|
||||||
|
g_string_append(str_val, g_strdup_printf("%.20f ", jump->x));
|
||||||
|
g_string_append(str_val, g_strdup_printf("%.20f ", jump->y));
|
||||||
|
GIRARA_LIST_FOREACH_END(jumplist, zathura_jump_t*, iter, jump);
|
||||||
|
|
||||||
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db);
|
||||||
|
|
||||||
|
g_key_file_set_string(priv->history, file, KEY_JUMPLIST, str_val->str);
|
||||||
|
zathura_db_write_key_file_to_file(priv->history_path, priv->history);
|
||||||
|
g_string_free(str_val, TRUE);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
plain_set_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t*
|
plain_set_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t*
|
||||||
file_info)
|
file_info)
|
||||||
|
@ -441,7 +506,7 @@ plain_set_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t*
|
||||||
g_key_file_set_integer(priv->history, name, KEY_PAGE, file_info->current_page);
|
g_key_file_set_integer(priv->history, name, KEY_PAGE, file_info->current_page);
|
||||||
g_key_file_set_integer(priv->history, name, KEY_OFFSET, file_info->page_offset);
|
g_key_file_set_integer(priv->history, name, KEY_OFFSET, file_info->page_offset);
|
||||||
|
|
||||||
char* tmp = g_strdup_printf("%f", file_info->scale);
|
char* tmp = g_strdup_printf("%.20f", file_info->scale);
|
||||||
g_key_file_set_string (priv->history, name, KEY_SCALE, tmp);
|
g_key_file_set_string (priv->history, name, KEY_SCALE, tmp);
|
||||||
g_free(tmp);
|
g_free(tmp);
|
||||||
|
|
||||||
|
@ -449,11 +514,11 @@ plain_set_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t*
|
||||||
g_key_file_set_integer(priv->history, name, KEY_PAGES_PER_ROW, file_info->pages_per_row);
|
g_key_file_set_integer(priv->history, name, KEY_PAGES_PER_ROW, file_info->pages_per_row);
|
||||||
g_key_file_set_integer(priv->history, name, KEY_FIRST_PAGE_COLUMN, file_info->first_page_column);
|
g_key_file_set_integer(priv->history, name, KEY_FIRST_PAGE_COLUMN, file_info->first_page_column);
|
||||||
|
|
||||||
tmp = g_strdup_printf("%f", file_info->position_x);
|
tmp = g_strdup_printf("%.20f", file_info->position_x);
|
||||||
g_key_file_set_string(priv->history, name, KEY_POSITION_X, tmp);
|
g_key_file_set_string(priv->history, name, KEY_POSITION_X, tmp);
|
||||||
g_free(tmp);
|
g_free(tmp);
|
||||||
|
|
||||||
tmp = g_strdup_printf("%f", file_info->position_y);
|
tmp = g_strdup_printf("%.20f", file_info->position_y);
|
||||||
g_key_file_set_string(priv->history, name, KEY_POSITION_Y, tmp);
|
g_key_file_set_string(priv->history, name, KEY_POSITION_Y, tmp);
|
||||||
g_free(tmp);
|
g_free(tmp);
|
||||||
|
|
||||||
|
|
|
@ -17,18 +17,14 @@ G_DEFINE_TYPE_WITH_CODE(ZathuraSQLDatabase, zathura_sqldatabase, G_TYPE_OBJECT,
|
||||||
|
|
||||||
static bool check_column(sqlite3* session, const char* table, const char* col, bool* result);
|
static bool check_column(sqlite3* session, const char* table, const char* col, bool* result);
|
||||||
static void sqlite_finalize(GObject* object);
|
static void sqlite_finalize(GObject* object);
|
||||||
static bool sqlite_add_bookmark(zathura_database_t* db, const char* file,
|
static bool sqlite_add_bookmark(zathura_database_t* db, const char* file, zathura_bookmark_t* bookmark);
|
||||||
zathura_bookmark_t* bookmark);
|
static bool sqlite_remove_bookmark(zathura_database_t* db, const char* file, const char* id);
|
||||||
static bool sqlite_remove_bookmark(zathura_database_t* db, const char* file,
|
static girara_list_t* sqlite_load_bookmarks(zathura_database_t* db, const char* file);
|
||||||
const char* id);
|
static girara_list_t* sqlite_load_jumplist(zathura_database_t* db, const char* file);
|
||||||
static girara_list_t* sqlite_load_bookmarks(zathura_database_t* db,
|
static bool sqlite_save_jumplist(zathura_database_t* db, const char* file, girara_list_t* jumplist);
|
||||||
const char* file);
|
static bool sqlite_set_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t* file_info);
|
||||||
static bool sqlite_set_fileinfo(zathura_database_t* db, const char* file,
|
static bool sqlite_get_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t* file_info);
|
||||||
zathura_fileinfo_t* file_info);
|
static void sqlite_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec);
|
||||||
static bool sqlite_get_fileinfo(zathura_database_t* db, const char* file,
|
|
||||||
zathura_fileinfo_t* file_info);
|
|
||||||
static void sqlite_set_property(GObject* object, guint prop_id,
|
|
||||||
const GValue* value, GParamSpec* pspec);
|
|
||||||
static void sqlite_io_append(GiraraInputHistoryIO* db, const char*);
|
static void sqlite_io_append(GiraraInputHistoryIO* db, const char*);
|
||||||
static girara_list_t* sqlite_io_read(GiraraInputHistoryIO* db);
|
static girara_list_t* sqlite_io_read(GiraraInputHistoryIO* db);
|
||||||
|
|
||||||
|
@ -51,6 +47,8 @@ zathura_database_interface_init(ZathuraDatabaseInterface* iface)
|
||||||
iface->add_bookmark = sqlite_add_bookmark;
|
iface->add_bookmark = sqlite_add_bookmark;
|
||||||
iface->remove_bookmark = sqlite_remove_bookmark;
|
iface->remove_bookmark = sqlite_remove_bookmark;
|
||||||
iface->load_bookmarks = sqlite_load_bookmarks;
|
iface->load_bookmarks = sqlite_load_bookmarks;
|
||||||
|
iface->load_jumplist = sqlite_load_jumplist;
|
||||||
|
iface->save_jumplist = sqlite_save_jumplist;
|
||||||
iface->set_fileinfo = sqlite_set_fileinfo;
|
iface->set_fileinfo = sqlite_set_fileinfo;
|
||||||
iface->get_fileinfo = sqlite_get_fileinfo;
|
iface->get_fileinfo = sqlite_get_fileinfo;
|
||||||
}
|
}
|
||||||
|
@ -128,6 +126,15 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path)
|
||||||
"vadj_ratio FLOAT,"
|
"vadj_ratio FLOAT,"
|
||||||
"PRIMARY KEY(file, id));";
|
"PRIMARY KEY(file, id));";
|
||||||
|
|
||||||
|
static const char SQL_JUMPLIST_INIT[] =
|
||||||
|
"CREATE TABLE IF NOT EXISTS jumplist ("
|
||||||
|
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
||||||
|
"file TEXT,"
|
||||||
|
"page INTEGER,"
|
||||||
|
"hadj_ratio FLOAT,"
|
||||||
|
"vadj_ratio FLOAT"
|
||||||
|
");";
|
||||||
|
|
||||||
/* create fileinfo table */
|
/* create fileinfo table */
|
||||||
static const char SQL_FILEINFO_INIT[] =
|
static const char SQL_FILEINFO_INIT[] =
|
||||||
"CREATE TABLE IF NOT EXISTS fileinfo ("
|
"CREATE TABLE IF NOT EXISTS fileinfo ("
|
||||||
|
@ -177,6 +184,12 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sqlite3_exec(session, SQL_JUMPLIST_INIT, NULL, 0, NULL) != SQLITE_OK) {
|
||||||
|
girara_error("Failed to initialize database: %s\n", path);
|
||||||
|
sqlite3_close(session);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (sqlite3_exec(session, SQL_FILEINFO_INIT, NULL, 0, NULL) != SQLITE_OK) {
|
if (sqlite3_exec(session, SQL_FILEINFO_INIT, NULL, 0, NULL) != SQLITE_OK) {
|
||||||
girara_error("Failed to initialize database: %s\n", path);
|
girara_error("Failed to initialize database: %s\n", path);
|
||||||
sqlite3_close(session);
|
sqlite3_close(session);
|
||||||
|
@ -397,6 +410,139 @@ sqlite_load_bookmarks(zathura_database_t* db, const char* file)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
sqlite_save_jumplist(zathura_database_t* db, const char* file, girara_list_t* jumplist)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(db != NULL && file != NULL && jumplist != NULL, false);
|
||||||
|
|
||||||
|
zathura_sqldatabase_private_t* priv = ZATHURA_SQLDATABASE_GET_PRIVATE(db);
|
||||||
|
static const char SQL_INSERT_JUMP[] = "INSERT INTO jumplist (file, page, hadj_ratio, vadj_ratio) VALUES (?, ?, ?, ?);";
|
||||||
|
static const char SQL_REMOVE_JUMPLIST[] = "DELETE FROM jumplist WHERE file = ?;";
|
||||||
|
sqlite3_stmt* stmt = NULL;
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
if (sqlite3_exec(priv->session, "BEGIN;", NULL, 0, NULL) != SQLITE_OK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt = prepare_statement(priv->session, SQL_REMOVE_JUMPLIST);
|
||||||
|
|
||||||
|
if (stmt == NULL) {
|
||||||
|
sqlite3_exec(priv->session, "ROLLBACK;", NULL, 0, NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sqlite3_bind_text(stmt, 1, file, -1, NULL) != SQLITE_OK) {
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
sqlite3_exec(priv->session, "ROLLBACK;", NULL, 0, NULL);
|
||||||
|
girara_error("Failed to bind arguments.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = sqlite3_step(stmt);
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
|
if (res != SQLITE_DONE) {
|
||||||
|
sqlite3_exec(priv->session, "ROLLBACK;", NULL, 0, NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (girara_list_size(jumplist) == 0) {
|
||||||
|
sqlite3_exec(priv->session, "COMMIT;", NULL, 0, NULL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
girara_list_iterator_t* cur = girara_list_iterator(jumplist);
|
||||||
|
bool status = true;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
zathura_jump_t* jump = girara_list_iterator_data(cur);
|
||||||
|
|
||||||
|
stmt = prepare_statement(priv->session, SQL_INSERT_JUMP);
|
||||||
|
|
||||||
|
if (stmt == NULL) {
|
||||||
|
status = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sqlite3_bind_text(stmt, 1, file, -1, NULL) != SQLITE_OK ||
|
||||||
|
sqlite3_bind_int(stmt, 2, jump->page) != SQLITE_OK ||
|
||||||
|
sqlite3_bind_double(stmt, 3, jump->x) != SQLITE_OK ||
|
||||||
|
sqlite3_bind_double(stmt, 4, jump->y) != SQLITE_OK) {
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
girara_error("Failed to bind arguments.");
|
||||||
|
status = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = sqlite3_step(stmt);
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
|
if (res != SQLITE_DONE) {
|
||||||
|
status = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (girara_list_iterator_has_next(cur) == true) {
|
||||||
|
girara_list_iterator_next(cur);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == false) {
|
||||||
|
sqlite3_exec(priv->session, "ROLLBACK;", NULL, 0, NULL);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
sqlite3_exec(priv->session, "COMMIT;", NULL, 0, NULL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static girara_list_t*
|
||||||
|
sqlite_load_jumplist(zathura_database_t* db, const char* file)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(db != NULL && file != NULL, NULL);
|
||||||
|
|
||||||
|
zathura_sqldatabase_private_t* priv = ZATHURA_SQLDATABASE_GET_PRIVATE(db);
|
||||||
|
static const char SQL_GET_JUMPLIST[] = "SELECT page, hadj_ratio, vadj_ratio FROM jumplist WHERE file = ? ORDER BY id ASC;";
|
||||||
|
sqlite3_stmt* stmt = prepare_statement(priv->session, SQL_GET_JUMPLIST);
|
||||||
|
|
||||||
|
if (stmt == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sqlite3_bind_text(stmt, 1, file, -1, NULL) != SQLITE_OK) {
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
girara_error("Failed to bind arguments.");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
girara_list_t* jumplist = girara_list_new2(g_free);
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
while ((res = sqlite3_step(stmt)) == SQLITE_ROW) {
|
||||||
|
zathura_jump_t* jump = g_malloc0(sizeof(zathura_jump_t));
|
||||||
|
|
||||||
|
jump->page = sqlite3_column_int(stmt, 0);
|
||||||
|
jump->x = sqlite3_column_double(stmt, 1);
|
||||||
|
jump->y = sqlite3_column_double(stmt, 2);
|
||||||
|
girara_list_append(jumplist, jump);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
|
if (res != SQLITE_DONE) {
|
||||||
|
girara_list_free(jumplist);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return jumplist;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
sqlite_set_fileinfo(zathura_database_t* db, const char* file,
|
sqlite_set_fileinfo(zathura_database_t* db, const char* file,
|
||||||
zathura_fileinfo_t* file_info)
|
zathura_fileinfo_t* file_info)
|
||||||
|
|
16
database.c
16
database.c
|
@ -35,6 +35,22 @@ zathura_db_load_bookmarks(zathura_database_t* db, const char* file)
|
||||||
return ZATHURA_DATABASE_GET_INTERFACE(db)->load_bookmarks(db, file);
|
return ZATHURA_DATABASE_GET_INTERFACE(db)->load_bookmarks(db, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
girara_list_t*
|
||||||
|
zathura_db_load_jumplist(zathura_database_t* db, const char* file)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(ZATHURA_IS_DATABASE(db) && file != NULL, NULL);
|
||||||
|
|
||||||
|
return ZATHURA_DATABASE_GET_INTERFACE(db)->load_jumplist(db, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
zathura_db_save_jumplist(zathura_database_t* db, const char* file, girara_list_t* jumplist)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(ZATHURA_IS_DATABASE(db) && file != NULL && jumplist != NULL, NULL);
|
||||||
|
|
||||||
|
return ZATHURA_DATABASE_GET_INTERFACE(db)->save_jumplist(db, file, jumplist);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
zathura_db_set_fileinfo(zathura_database_t* db, const char* file,
|
zathura_db_set_fileinfo(zathura_database_t* db, const char* file,
|
||||||
zathura_fileinfo_t* file_info)
|
zathura_fileinfo_t* file_info)
|
||||||
|
|
35
database.h
35
database.h
|
@ -43,6 +43,10 @@ struct _ZathuraDatabaseInterface
|
||||||
|
|
||||||
girara_list_t* (*load_bookmarks)(ZathuraDatabase* db, const char* file);
|
girara_list_t* (*load_bookmarks)(ZathuraDatabase* db, const char* file);
|
||||||
|
|
||||||
|
girara_list_t* (*load_jumplist)(ZathuraDatabase* db, const char* file);
|
||||||
|
|
||||||
|
bool (*save_jumplist)(ZathuraDatabase* db, const char* file, girara_list_t* jumplist);
|
||||||
|
|
||||||
bool (*set_fileinfo)(ZathuraDatabase* db, const char* file, zathura_fileinfo_t* file_info);
|
bool (*set_fileinfo)(ZathuraDatabase* db, const char* file, zathura_fileinfo_t* file_info);
|
||||||
|
|
||||||
bool (*get_fileinfo)(ZathuraDatabase* db, const char* file, zathura_fileinfo_t* file_info);
|
bool (*get_fileinfo)(ZathuraDatabase* db, const char* file, zathura_fileinfo_t* file_info);
|
||||||
|
@ -54,7 +58,7 @@ GType zathura_database_get_type(void);
|
||||||
* Add or update bookmark in the database.
|
* Add or update bookmark in the database.
|
||||||
*
|
*
|
||||||
* @param db The database instance
|
* @param db The database instance
|
||||||
* @param file The file to which the bookmark belongs to.
|
* @param file The file to which the bookmark belongs.
|
||||||
* @param bookmark The bookmark instance.
|
* @param bookmark The bookmark instance.
|
||||||
* @return true on success, false otherwise
|
* @return true on success, false otherwise
|
||||||
*/
|
*/
|
||||||
|
@ -62,10 +66,10 @@ bool zathura_db_add_bookmark(zathura_database_t* db, const char* file,
|
||||||
zathura_bookmark_t* bookmark);
|
zathura_bookmark_t* bookmark);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add or update bookmark in the database.
|
* Remove a bookmark from the database.
|
||||||
*
|
*
|
||||||
* @param db The database instance
|
* @param db The database instance
|
||||||
* @param file The file to which the bookmark belongs to.
|
* @param file The file to which the bookmark belongs.
|
||||||
* @param id The id of the bookmark
|
* @param id The id of the bookmark
|
||||||
* @return true on success, false otherwise
|
* @return true on success, false otherwise
|
||||||
*/
|
*/
|
||||||
|
@ -82,11 +86,32 @@ bool zathura_db_remove_bookmark(zathura_database_t* db, const char* file, const
|
||||||
girara_list_t* zathura_db_load_bookmarks(zathura_database_t* db, const char*
|
girara_list_t* zathura_db_load_bookmarks(zathura_database_t* db, const char*
|
||||||
file);
|
file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the jumplist belonging to the specified file from the database.
|
||||||
|
*
|
||||||
|
* @param db The database instance.
|
||||||
|
* @param file The file to which the jumplist belongs.
|
||||||
|
*
|
||||||
|
* return A linked list constituting the jumplist of the specified file.
|
||||||
|
*/
|
||||||
|
girara_list_t* zathura_db_load_jumplist(ZathuraDatabase* db, const char* file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the jumplist belonging to the specified file to the database.
|
||||||
|
*
|
||||||
|
* @param db The database instance.
|
||||||
|
* @param file The file to which the jumplist belongs.
|
||||||
|
* @param jumplist The jumplist to be saved
|
||||||
|
*
|
||||||
|
* return true on success, false otherwise.
|
||||||
|
*/
|
||||||
|
bool zathura_db_save_jumplist(ZathuraDatabase* db, const char* file, girara_list_t* jumplist);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set file info (last site, ...) in the database.
|
* Set file info (last site, ...) in the database.
|
||||||
*
|
*
|
||||||
* @param db The database instance
|
* @param db The database instance
|
||||||
* @param file The file to which the file info belongs to.
|
* @param file The file to which the file info belongs.
|
||||||
* @param file_info The file info
|
* @param file_info The file info
|
||||||
* @return true on success, false otherwise.
|
* @return true on success, false otherwise.
|
||||||
*/
|
*/
|
||||||
|
@ -96,7 +121,7 @@ bool zathura_db_set_fileinfo(zathura_database_t* db, const char* file,
|
||||||
/* Get file info (last site, ...) from the database.
|
/* Get file info (last site, ...) from the database.
|
||||||
*
|
*
|
||||||
* @param db The database instance
|
* @param db The database instance
|
||||||
* @param file The file to which the file info belongs to.
|
* @param file The file to which the file info belongs.
|
||||||
* @param file_info The file info
|
* @param file_info The file info
|
||||||
* @return true on success, false otherwise.
|
* @return true on success, false otherwise.
|
||||||
*/
|
*/
|
||||||
|
|
95
zathura.c
95
zathura.c
|
@ -273,10 +273,11 @@ zathura_init(zathura_t* zathura)
|
||||||
|
|
||||||
/* jumplist */
|
/* jumplist */
|
||||||
|
|
||||||
zathura->jumplist.max_size = 20;
|
int jumplist_size = 20;
|
||||||
girara_setting_get(zathura->ui.session, "jumplist-size", &(zathura->jumplist.max_size));
|
girara_setting_get(zathura->ui.session, "jumplist-size", &jumplist_size);
|
||||||
|
|
||||||
zathura->jumplist.list = girara_list_new2(g_free);
|
zathura->jumplist.max_size = jumplist_size < 0 ? 0 : jumplist_size;
|
||||||
|
zathura->jumplist.list = NULL;
|
||||||
zathura->jumplist.size = 0;
|
zathura->jumplist.size = 0;
|
||||||
zathura->jumplist.cur = NULL;
|
zathura->jumplist.cur = NULL;
|
||||||
|
|
||||||
|
@ -770,6 +771,11 @@ document_open(zathura_t* zathura, const char* path, const char* password,
|
||||||
/* bookmarks */
|
/* bookmarks */
|
||||||
zathura_bookmarks_load(zathura, file_path);
|
zathura_bookmarks_load(zathura, file_path);
|
||||||
|
|
||||||
|
/* jumplist */
|
||||||
|
if (zathura_jumplist_load(zathura, file_path) == false) {
|
||||||
|
zathura->jumplist.list = girara_list_new2(g_free);
|
||||||
|
}
|
||||||
|
|
||||||
/* update title */
|
/* update title */
|
||||||
basename_only = false;
|
basename_only = false;
|
||||||
girara_setting_get(zathura->ui.session, "window-title-basename", &basename_only);
|
girara_setting_get(zathura->ui.session, "window-title-basename", &basename_only);
|
||||||
|
@ -930,6 +936,14 @@ document_close(zathura_t* zathura, bool keep_monitor)
|
||||||
/* save file info */
|
/* save file info */
|
||||||
zathura_db_set_fileinfo(zathura->database, path, &file_info);
|
zathura_db_set_fileinfo(zathura->database, path, &file_info);
|
||||||
|
|
||||||
|
/* save jumplist */
|
||||||
|
zathura_db_save_jumplist(zathura->database, path, zathura->jumplist.list);
|
||||||
|
girara_list_iterator_free(zathura->jumplist.cur);
|
||||||
|
zathura->jumplist.cur = NULL;
|
||||||
|
girara_list_free(zathura->jumplist.list);
|
||||||
|
zathura->jumplist.list = NULL;
|
||||||
|
zathura->jumplist.size = 0;
|
||||||
|
|
||||||
/* release render thread */
|
/* release render thread */
|
||||||
render_free(zathura->sync.render_thread);
|
render_free(zathura->sync.render_thread);
|
||||||
zathura->sync.render_thread = NULL;
|
zathura->sync.render_thread = NULL;
|
||||||
|
@ -1224,27 +1238,43 @@ zathura_jumplist_reset_current(zathura_t* zathura)
|
||||||
static void
|
static void
|
||||||
zathura_jumplist_append_jump(zathura_t* zathura)
|
zathura_jumplist_append_jump(zathura_t* zathura)
|
||||||
{
|
{
|
||||||
|
g_return_if_fail(zathura != NULL && zathura->jumplist.list != NULL);
|
||||||
|
|
||||||
zathura_jump_t *jump = g_malloc(sizeof(zathura_jump_t));
|
zathura_jump_t *jump = g_malloc(sizeof(zathura_jump_t));
|
||||||
if (jump != NULL) {
|
|
||||||
jump->page = 0;
|
jump->page = 0;
|
||||||
jump->x = 0;
|
jump->x = 0.0;
|
||||||
jump->y = 0;
|
jump->y = 0.0;
|
||||||
|
|
||||||
/* trim from beginning until max_size */
|
|
||||||
girara_list_iterator_t *it = girara_list_iterator(zathura->jumplist.list);
|
|
||||||
while (zathura->jumplist.size >= zathura->jumplist.max_size && girara_list_iterator_is_valid(it)) {
|
|
||||||
girara_list_iterator_remove(it);
|
|
||||||
zathura->jumplist.size = zathura->jumplist.size - 1;
|
|
||||||
}
|
|
||||||
g_free(it);
|
|
||||||
|
|
||||||
girara_list_append(zathura->jumplist.list, jump);
|
girara_list_append(zathura->jumplist.list, jump);
|
||||||
|
|
||||||
if (zathura->jumplist.size == 0) {
|
if (zathura->jumplist.size == 0) {
|
||||||
zathura->jumplist.cur = girara_list_iterator(zathura->jumplist.list);
|
zathura->jumplist.cur = girara_list_iterator(zathura->jumplist.list);
|
||||||
}
|
}
|
||||||
|
|
||||||
zathura->jumplist.size = zathura->jumplist.size + 1;
|
++zathura->jumplist.size;
|
||||||
|
zathura_jumplist_trim(zathura);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zathura_jumplist_trim(zathura_t* zathura)
|
||||||
|
{
|
||||||
|
g_return_if_fail(zathura != NULL && zathura->jumplist.list != NULL && zathura->jumplist.size != 0);
|
||||||
|
|
||||||
|
girara_list_iterator_t* cur = girara_list_iterator(zathura->jumplist.list);
|
||||||
|
|
||||||
|
while (zathura->jumplist.size > zathura->jumplist.max_size) {
|
||||||
|
if (girara_list_iterator_data(cur) == girara_list_iterator_data(zathura->jumplist.cur)) {
|
||||||
|
girara_list_iterator_free(zathura->jumplist.cur);
|
||||||
|
zathura->jumplist.cur = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
girara_list_iterator_remove(cur);
|
||||||
|
--zathura->jumplist.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zathura->jumplist.size == 0) {
|
||||||
|
girara_list_iterator_free(cur);
|
||||||
|
} else if (zathura->jumplist.cur == NULL) {
|
||||||
|
zathura->jumplist.cur = cur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1258,19 +1288,50 @@ zathura_jumplist_add(zathura_t* zathura)
|
||||||
double x = zathura_adjustment_get_ratio(gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)));
|
double x = zathura_adjustment_get_ratio(gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)));
|
||||||
double y = zathura_adjustment_get_ratio(gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)));
|
double y = zathura_adjustment_get_ratio(gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)));
|
||||||
|
|
||||||
|
if (zathura->jumplist.size != 0) {
|
||||||
zathura_jumplist_reset_current(zathura);
|
zathura_jumplist_reset_current(zathura);
|
||||||
|
|
||||||
zathura_jump_t* cur = zathura_jumplist_current(zathura);
|
zathura_jump_t* cur = zathura_jumplist_current(zathura);
|
||||||
|
|
||||||
if (cur && cur->page == pagenum && cur->x == x && cur->y == y) {
|
if (cur != NULL) {
|
||||||
|
if (cur->page == pagenum && cur->x == x && cur->y == y) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
zathura_jumplist_append_jump(zathura);
|
zathura_jumplist_append_jump(zathura);
|
||||||
zathura_jumplist_reset_current(zathura);
|
zathura_jumplist_reset_current(zathura);
|
||||||
zathura_jumplist_save(zathura);
|
zathura_jumplist_save(zathura);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
zathura_jumplist_load(zathura_t* zathura, const char* file)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(zathura != NULL && zathura->database != NULL && file != NULL, false);
|
||||||
|
|
||||||
|
zathura->jumplist.list = zathura_db_load_jumplist(zathura->database, file);
|
||||||
|
|
||||||
|
if (zathura->jumplist.list == NULL) {
|
||||||
|
girara_error("Failed to load the jumplist from the database");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
zathura->jumplist.size = girara_list_size(zathura->jumplist.list);
|
||||||
|
|
||||||
|
if (zathura->jumplist.size != 0) {
|
||||||
|
zathura->jumplist.cur = girara_list_iterator(zathura->jumplist.list);
|
||||||
|
zathura_jumplist_reset_current(zathura);
|
||||||
|
zathura_jumplist_trim(zathura);
|
||||||
|
girara_debug("Loaded the jumplist from the database");
|
||||||
|
} else {
|
||||||
|
girara_debug("No jumplist for this file in the database yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zathura_jumplist_save(zathura_t* zathura)
|
zathura_jumplist_save(zathura_t* zathura)
|
||||||
{
|
{
|
||||||
|
|
17
zathura.h
17
zathura.h
|
@ -387,6 +387,23 @@ void zathura_jumplist_backward(zathura_t* zathura);
|
||||||
*/
|
*/
|
||||||
void zathura_jumplist_add(zathura_t* zathura);
|
void zathura_jumplist_add(zathura_t* zathura);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trim entries from the beginning of the jumplist to maintain it's maximum size constraint.
|
||||||
|
*
|
||||||
|
* @param zathura The zathura session
|
||||||
|
*/
|
||||||
|
void zathura_jumplist_trim(zathura_t* zathura);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the jumplist of the specified file
|
||||||
|
*
|
||||||
|
* @param zathura The zathura session
|
||||||
|
* @param file The file whose jumplist is to be loaded
|
||||||
|
*
|
||||||
|
* return A linked list of zathura_jump_t structures constituting the jumplist of the specified file, or NULL.
|
||||||
|
*/
|
||||||
|
bool zathura_jumplist_load(zathura_t* zathura, const char* file);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a page to the page cache
|
* Add a page to the page cache
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue