2011-10-11 15:59:36 +02:00
|
|
|
/* See LICENSE file for license and copyright information */
|
|
|
|
|
2011-11-21 16:40:26 +01:00
|
|
|
#define _POSIX_SOURCE
|
2013-03-17 16:19:10 +01:00
|
|
|
#define _XOPEN_SOURCE 500
|
2011-11-21 16:40:26 +01:00
|
|
|
|
2011-10-11 22:39:55 +02:00
|
|
|
#include <glib.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2011-10-14 01:04:06 +02:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
2011-10-11 22:39:55 +02:00
|
|
|
#include <unistd.h>
|
2011-10-23 17:01:15 +02:00
|
|
|
#include <girara/utils.h>
|
|
|
|
#include <girara/datastructures.h>
|
2013-03-17 16:19:10 +01:00
|
|
|
#include <girara/input-history.h>
|
2011-10-11 15:59:36 +02:00
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
#include "database-plain.h"
|
2014-01-10 15:49:22 +01:00
|
|
|
#include "utils.h"
|
2011-10-11 15:59:36 +02:00
|
|
|
|
2013-06-21 14:30:04 +02:00
|
|
|
#define BOOKMARKS "bookmarks"
|
|
|
|
#define HISTORY "history"
|
|
|
|
#define INPUT_HISTORY "input-history"
|
|
|
|
|
|
|
|
#define KEY_PAGE "page"
|
|
|
|
#define KEY_OFFSET "offset"
|
|
|
|
#define KEY_SCALE "scale"
|
|
|
|
#define KEY_ROTATE "rotate"
|
|
|
|
#define KEY_PAGES_PER_ROW "pages-per-row"
|
|
|
|
#define KEY_FIRST_PAGE_COLUMN "first-page-column"
|
|
|
|
#define KEY_POSITION_X "position-x"
|
|
|
|
#define KEY_POSITION_Y "position-y"
|
|
|
|
#define KEY_JUMPLIST "jumplist"
|
2011-10-11 22:39:55 +02:00
|
|
|
|
2012-03-27 00:24:58 +02:00
|
|
|
#ifdef __GNU__
|
|
|
|
#include <sys/file.h>
|
|
|
|
#define file_lock_set(fd, cmd) flock(fd, cmd)
|
|
|
|
#else
|
2011-10-14 01:04:06 +02:00
|
|
|
#define file_lock_set(fd, cmd) \
|
|
|
|
{ \
|
|
|
|
struct flock lock = { .l_type = cmd, .l_start = 0, .l_whence = SEEK_SET, .l_len = 0}; \
|
2012-03-27 11:56:42 +02:00
|
|
|
fcntl(fd, F_SETLK, lock); \
|
2011-10-14 01:04:06 +02:00
|
|
|
}
|
2012-03-27 00:24:58 +02:00
|
|
|
#endif
|
2011-10-14 01:04:06 +02:00
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
static void zathura_database_interface_init(ZathuraDatabaseInterface* iface);
|
2013-03-17 16:19:10 +01:00
|
|
|
static void io_interface_init(GiraraInputHistoryIOInterface* iface);
|
2012-03-04 15:56:54 +01:00
|
|
|
|
|
|
|
G_DEFINE_TYPE_WITH_CODE(ZathuraPlainDatabase, zathura_plaindatabase, G_TYPE_OBJECT,
|
2013-03-17 16:19:10 +01:00
|
|
|
G_IMPLEMENT_INTERFACE(ZATHURA_TYPE_DATABASE, zathura_database_interface_init)
|
|
|
|
G_IMPLEMENT_INTERFACE(GIRARA_TYPE_INPUT_HISTORY_IO, io_interface_init))
|
2012-03-04 15:56:54 +01:00
|
|
|
|
2013-06-21 14:30:04 +02:00
|
|
|
static void plain_finalize(GObject* object);
|
|
|
|
static bool plain_add_bookmark(zathura_database_t* db, const char* file, zathura_bookmark_t* bookmark);
|
|
|
|
static bool plain_remove_bookmark(zathura_database_t* db, const char* file, const char* id);
|
|
|
|
static girara_list_t* plain_load_bookmarks(zathura_database_t* db, const char* file);
|
|
|
|
static girara_list_t* plain_load_jumplist(zathura_database_t* db, const char* file);
|
|
|
|
static bool plain_save_jumplist(zathura_database_t* db, const char* file, girara_list_t* jumplist);
|
|
|
|
static bool plain_set_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t* file_info);
|
|
|
|
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*);
|
2013-03-17 16:19:10 +01:00
|
|
|
static girara_list_t* plain_io_read(GiraraInputHistoryIO* db);
|
2012-03-04 15:56:54 +01:00
|
|
|
|
2011-10-11 22:39:55 +02:00
|
|
|
/* forward declaration */
|
2013-06-21 14:30:04 +02:00
|
|
|
static bool zathura_db_check_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 cb_zathura_db_watch_file(GFileMonitor* monitor, GFile* file, GFile* other_file, GFileMonitorEvent event, zathura_database_t* database);
|
2011-10-11 22:39:55 +02:00
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
typedef struct zathura_plaindatabase_private_s {
|
2011-10-11 22:39:55 +02:00
|
|
|
char* bookmark_path;
|
2011-10-12 12:32:31 +02:00
|
|
|
GKeyFile* bookmarks;
|
2011-10-11 22:39:55 +02:00
|
|
|
GFileMonitor* bookmark_monitor;
|
|
|
|
|
|
|
|
char* history_path;
|
2011-10-12 12:43:36 +02:00
|
|
|
GKeyFile* history;
|
2011-10-11 22:39:55 +02:00
|
|
|
GFileMonitor* history_monitor;
|
2013-03-17 16:19:10 +01:00
|
|
|
|
|
|
|
char* input_history_path;
|
2012-03-04 15:56:54 +01:00
|
|
|
} zathura_plaindatabase_private_t;
|
|
|
|
|
|
|
|
#define ZATHURA_PLAINDATABASE_GET_PRIVATE(obj) \
|
|
|
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), ZATHURA_TYPE_PLAINDATABASE, zathura_plaindatabase_private_t))
|
|
|
|
|
2012-10-09 01:12:18 +02:00
|
|
|
enum {
|
2012-03-04 15:56:54 +01:00
|
|
|
PROP_0,
|
|
|
|
PROP_PATH
|
2011-10-11 15:59:36 +02:00
|
|
|
};
|
|
|
|
|
2012-03-14 13:36:51 +01:00
|
|
|
static char*
|
|
|
|
prepare_filename(const char* file)
|
|
|
|
{
|
|
|
|
if (file == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strchr(file, '[') == NULL && strchr(file, ']') == NULL) {
|
|
|
|
return g_strdup(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
return g_base64_encode((const guchar*) file, strlen(file));
|
|
|
|
}
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
static void
|
|
|
|
zathura_database_interface_init(ZathuraDatabaseInterface* iface)
|
|
|
|
{
|
|
|
|
/* initialize interface */
|
2012-03-09 08:04:54 +01:00
|
|
|
iface->add_bookmark = plain_add_bookmark;
|
2012-03-04 15:56:54 +01:00
|
|
|
iface->remove_bookmark = plain_remove_bookmark;
|
2012-03-09 08:04:54 +01:00
|
|
|
iface->load_bookmarks = plain_load_bookmarks;
|
2013-06-21 14:30:04 +02:00
|
|
|
iface->load_jumplist = plain_load_jumplist;
|
|
|
|
iface->save_jumplist = plain_save_jumplist;
|
2012-03-09 08:04:54 +01:00
|
|
|
iface->set_fileinfo = plain_set_fileinfo;
|
|
|
|
iface->get_fileinfo = plain_get_fileinfo;
|
2012-03-04 15:56:54 +01:00
|
|
|
}
|
|
|
|
|
2013-03-17 16:19:10 +01:00
|
|
|
static void
|
|
|
|
io_interface_init(GiraraInputHistoryIOInterface* iface)
|
|
|
|
{
|
|
|
|
/* initialize interface */
|
|
|
|
iface->append = plain_io_append;
|
|
|
|
iface->read = plain_io_read;
|
|
|
|
}
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
static void
|
|
|
|
zathura_plaindatabase_class_init(ZathuraPlainDatabaseClass* class)
|
|
|
|
{
|
|
|
|
/* add private members */
|
|
|
|
g_type_class_add_private(class, sizeof(zathura_plaindatabase_private_t));
|
|
|
|
|
|
|
|
/* override methods */
|
|
|
|
GObjectClass* object_class = G_OBJECT_CLASS(class);
|
2012-03-09 08:04:54 +01:00
|
|
|
object_class->finalize = plain_finalize;
|
2012-03-04 15:56:54 +01:00
|
|
|
object_class->set_property = plain_set_property;
|
|
|
|
|
|
|
|
g_object_class_install_property(object_class, PROP_PATH,
|
2013-03-25 02:58:37 +01:00
|
|
|
g_param_spec_string("path", "path", "path to directory where the bookmarks and history are locates",
|
|
|
|
NULL, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
2012-03-04 15:56:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
zathura_plaindatabase_init(ZathuraPlainDatabase* db)
|
|
|
|
{
|
|
|
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db);
|
2012-03-09 08:04:54 +01:00
|
|
|
|
2013-03-17 16:19:10 +01:00
|
|
|
priv->bookmark_path = NULL;
|
|
|
|
priv->bookmark_monitor = NULL;
|
|
|
|
priv->bookmarks = NULL;
|
|
|
|
priv->history_path = NULL;
|
|
|
|
priv->history_monitor = NULL;
|
|
|
|
priv->history = NULL;
|
|
|
|
priv->input_history_path = NULL;
|
2012-03-04 15:56:54 +01:00
|
|
|
}
|
|
|
|
|
2011-10-11 15:59:36 +02:00
|
|
|
zathura_database_t*
|
2012-03-04 15:56:54 +01:00
|
|
|
zathura_plaindatabase_new(const char* path)
|
2011-10-11 15:59:36 +02:00
|
|
|
{
|
2012-03-04 15:56:54 +01:00
|
|
|
g_return_val_if_fail(path != NULL && strlen(path) != 0, NULL);
|
2011-10-11 22:39:55 +02:00
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
zathura_database_t* db = g_object_new(ZATHURA_TYPE_PLAINDATABASE, "path", path, NULL);
|
|
|
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db);
|
|
|
|
if (priv->bookmark_path == NULL) {
|
|
|
|
g_object_unref(db);
|
|
|
|
return NULL;
|
2011-10-11 22:39:55 +02:00
|
|
|
}
|
2012-03-09 08:04:54 +01:00
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
return db;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
plain_db_init(ZathuraPlainDatabase* db, const char* dir)
|
|
|
|
{
|
|
|
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db);
|
2011-10-11 22:39:55 +02:00
|
|
|
|
|
|
|
/* bookmarks */
|
2012-03-04 15:56:54 +01:00
|
|
|
priv->bookmark_path = g_build_filename(dir, BOOKMARKS, NULL);
|
|
|
|
if (zathura_db_check_file(priv->bookmark_path) == false) {
|
2011-10-11 22:39:55 +02:00
|
|
|
goto error_free;
|
|
|
|
}
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
GFile* bookmark_file = g_file_new_for_path(priv->bookmark_path);
|
2011-10-11 22:39:55 +02:00
|
|
|
if (bookmark_file != NULL) {
|
2012-03-04 15:56:54 +01:00
|
|
|
priv->bookmark_monitor = g_file_monitor(bookmark_file, G_FILE_MONITOR_NONE, NULL, NULL);
|
2011-10-11 22:39:55 +02:00
|
|
|
} else {
|
|
|
|
goto error_free;
|
|
|
|
}
|
2012-03-09 08:04:54 +01:00
|
|
|
|
2011-10-11 22:39:55 +02:00
|
|
|
g_object_unref(bookmark_file);
|
|
|
|
|
2011-10-11 23:43:30 +02:00
|
|
|
g_signal_connect(
|
2012-10-09 01:12:18 +02:00
|
|
|
G_OBJECT(priv->bookmark_monitor),
|
|
|
|
"changed",
|
|
|
|
G_CALLBACK(cb_zathura_db_watch_file),
|
|
|
|
db
|
2011-10-11 23:43:30 +02:00
|
|
|
);
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
priv->bookmarks = zathura_db_read_key_file_from_file(priv->bookmark_path);
|
|
|
|
if (priv->bookmarks == NULL) {
|
2011-10-12 12:32:31 +02:00
|
|
|
goto error_free;
|
|
|
|
}
|
|
|
|
|
2011-10-11 22:39:55 +02:00
|
|
|
/* history */
|
2012-03-04 15:56:54 +01:00
|
|
|
priv->history_path = g_build_filename(dir, HISTORY, NULL);
|
|
|
|
if (zathura_db_check_file(priv->history_path) == false) {
|
2011-10-11 22:39:55 +02:00
|
|
|
goto error_free;
|
|
|
|
}
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
GFile* history_file = g_file_new_for_path(priv->history_path);
|
2011-10-11 22:39:55 +02:00
|
|
|
if (history_file != NULL) {
|
2012-03-04 15:56:54 +01:00
|
|
|
priv->history_monitor = g_file_monitor(history_file, G_FILE_MONITOR_NONE, NULL, NULL);
|
2011-10-11 22:39:55 +02:00
|
|
|
} else {
|
|
|
|
goto error_free;
|
|
|
|
}
|
2012-03-09 08:04:54 +01:00
|
|
|
|
2011-10-11 22:39:55 +02:00
|
|
|
g_object_unref(history_file);
|
|
|
|
|
2011-10-11 23:43:30 +02:00
|
|
|
g_signal_connect(
|
2012-10-09 01:12:18 +02:00
|
|
|
G_OBJECT(priv->history_monitor),
|
|
|
|
"changed",
|
|
|
|
G_CALLBACK(cb_zathura_db_watch_file),
|
|
|
|
db
|
2011-10-11 23:43:30 +02:00
|
|
|
);
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
priv->history = zathura_db_read_key_file_from_file(priv->history_path);
|
|
|
|
if (priv->history == NULL) {
|
2011-10-11 22:39:55 +02:00
|
|
|
goto error_free;
|
|
|
|
}
|
2012-03-09 08:04:54 +01:00
|
|
|
|
2013-03-17 16:19:10 +01:00
|
|
|
/* input history */
|
|
|
|
priv->input_history_path = g_build_filename(dir, INPUT_HISTORY, NULL);
|
|
|
|
if (zathura_db_check_file(priv->input_history_path) == false) {
|
|
|
|
goto error_free;
|
|
|
|
}
|
|
|
|
|
2012-03-04 15:59:08 +01:00
|
|
|
return;
|
2011-10-11 22:39:55 +02:00
|
|
|
|
|
|
|
error_free:
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
/* bookmarks */
|
|
|
|
g_free(priv->bookmark_path);
|
|
|
|
priv->bookmark_path = NULL;
|
|
|
|
|
|
|
|
if (priv->bookmark_monitor != NULL) {
|
|
|
|
g_object_unref(priv->bookmark_monitor);
|
|
|
|
priv->bookmark_monitor = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (priv->bookmarks != NULL) {
|
|
|
|
g_key_file_free(priv->bookmarks);
|
|
|
|
priv->bookmarks = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* history */
|
|
|
|
g_free(priv->history_path);
|
|
|
|
priv->history_path = NULL;
|
2011-10-11 22:39:55 +02:00
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
if (priv->history_monitor != NULL) {
|
|
|
|
g_object_unref(priv->history_monitor);
|
|
|
|
priv->history_monitor = NULL;
|
|
|
|
}
|
2011-10-11 22:39:55 +02:00
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
if (priv->history != NULL) {
|
|
|
|
g_key_file_free(priv->history);
|
|
|
|
priv->history = NULL;
|
|
|
|
}
|
2013-03-17 16:19:10 +01:00
|
|
|
|
|
|
|
/* input history */
|
|
|
|
g_free(priv->input_history_path);
|
|
|
|
priv->input_history_path = NULL;
|
2011-10-11 15:59:36 +02:00
|
|
|
}
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
static void
|
|
|
|
plain_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec)
|
2011-10-11 15:59:36 +02:00
|
|
|
{
|
2012-03-04 15:56:54 +01:00
|
|
|
ZathuraPlainDatabase* db = ZATHURA_PLAINDATABASE(object);
|
|
|
|
|
|
|
|
switch (prop_id) {
|
|
|
|
case PROP_PATH:
|
|
|
|
plain_db_init(db, g_value_get_string(value));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
2011-10-11 22:39:55 +02:00
|
|
|
}
|
2012-03-04 15:56:54 +01:00
|
|
|
}
|
2011-10-11 22:39:55 +02:00
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
static void
|
|
|
|
plain_finalize(GObject* object)
|
|
|
|
{
|
|
|
|
ZathuraPlainDatabase* db = ZATHURA_PLAINDATABASE(object);
|
|
|
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db);
|
2012-03-09 08:04:54 +01:00
|
|
|
|
2011-10-11 22:39:55 +02:00
|
|
|
/* bookmarks */
|
2012-03-04 15:56:54 +01:00
|
|
|
g_free(priv->bookmark_path);
|
2011-10-11 22:39:55 +02:00
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
if (priv->bookmark_monitor != NULL) {
|
|
|
|
g_object_unref(priv->bookmark_monitor);
|
2011-10-11 22:39:55 +02:00
|
|
|
}
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
if (priv->bookmarks != NULL) {
|
|
|
|
g_key_file_free(priv->bookmarks);
|
2011-10-12 12:32:31 +02:00
|
|
|
}
|
2011-10-11 22:39:55 +02:00
|
|
|
|
|
|
|
/* history */
|
2012-03-04 15:56:54 +01:00
|
|
|
g_free(priv->history_path);
|
2011-10-11 22:39:55 +02:00
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
if (priv->history_monitor != NULL) {
|
|
|
|
g_object_unref(priv->history_monitor);
|
2011-10-11 22:39:55 +02:00
|
|
|
}
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
if (priv->history != NULL) {
|
|
|
|
g_key_file_free(priv->history);
|
|
|
|
}
|
|
|
|
|
2013-03-17 16:19:10 +01:00
|
|
|
/* input history */
|
|
|
|
g_free(priv->input_history_path);
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
G_OBJECT_CLASS(zathura_plaindatabase_parent_class)->finalize(object);
|
2011-10-11 15:59:36 +02:00
|
|
|
}
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
static bool
|
|
|
|
plain_add_bookmark(zathura_database_t* db, const char* file,
|
2012-10-09 01:12:18 +02:00
|
|
|
zathura_bookmark_t* bookmark)
|
2011-10-11 15:59:36 +02:00
|
|
|
{
|
2012-03-04 15:56:54 +01:00
|
|
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db);
|
2012-03-09 08:04:54 +01:00
|
|
|
if (priv->bookmarks == NULL || priv->bookmark_path == NULL ||
|
2012-03-04 15:56:54 +01:00
|
|
|
bookmark->id == NULL) {
|
2011-10-11 22:39:55 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-03-14 13:36:51 +01:00
|
|
|
char* name = prepare_filename(file);
|
2014-01-10 15:49:22 +01:00
|
|
|
char* val_list[] = {
|
|
|
|
g_strdup_printf("%d", bookmark->page),
|
2014-01-19 17:09:33 +01:00
|
|
|
g_try_malloc0(G_ASCII_DTOSTR_BUF_SIZE),
|
|
|
|
g_try_malloc0(G_ASCII_DTOSTR_BUF_SIZE)
|
2014-01-10 15:49:22 +01:00
|
|
|
};
|
2014-01-19 17:09:33 +01:00
|
|
|
if (name == NULL || val_list[1] == NULL || val_list[2] == NULL) {
|
|
|
|
g_free(name);
|
|
|
|
for (unsigned int i = 0; i < LENGTH(val_list); ++i) {
|
|
|
|
g_free(val_list[i]);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
Bookmark the exact position, not just the page number (along with a number of fixes).
This patch adds some enhancements/fixes to the bookmarking feature of Zathura:
- Bookmark the exact vertical and horizontal adjustments values, along with
the page number. This is done in a backward-compatible way for both the
plain and sqlite database backends, so that bookmarks that was taken
previously (bookmarking only the page number) will still work as expected
and won't be lost.
- Fix the issue of not being able to remove bookmarks from the plain
database; removing a bookmark in plain_remove_bookmark using
g_key_file_remove_key corrupts the bookmarks file. This is due to not
truncating the entire bookmarks file in zathura_db_write_key_file_to_file
prior to overriding it with a new one not containing the removed line.
This is why, I guess, plain_remove_bookmark hadn't been implemented as
expected using g_key_file_remove_key, because apparently, someone thought
that the problem is caused by this API.
- Fix not being able to update existing bookmarks persistently; updating a
bookmark works only during the current session, but after the file is
closed and reopened, the updated bookmark still has it's old value. This
is due to changing only the bookmark structure in memory; the proper way
to do it, is to call zathura_db_remove_bookmark on the old bookmark, then
follow that by a call to zathura_db_add_bookmark on a bookmark structure
containing the new position and the same old ID.
- Make zathura_bookmark_add updates the bookmark if it already exists,
rather than doing this externally in cmd_bookmark_create. This allows us
to have all the relevant girara_notify messages in cmd_bookmark_create.
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-21 06:12:12 +02:00
|
|
|
|
2014-01-19 17:09:33 +01:00
|
|
|
g_ascii_dtostr(val_list[1], G_ASCII_DTOSTR_BUF_SIZE, bookmark->x);
|
|
|
|
g_ascii_dtostr(val_list[2], G_ASCII_DTOSTR_BUF_SIZE, bookmark->y);
|
2014-01-19 16:47:08 +01:00
|
|
|
|
2014-01-10 15:49:22 +01:00
|
|
|
g_key_file_set_string_list(priv->bookmarks, name, bookmark->id, (const char**)val_list, LENGTH(val_list));
|
Bookmark the exact position, not just the page number (along with a number of fixes).
This patch adds some enhancements/fixes to the bookmarking feature of Zathura:
- Bookmark the exact vertical and horizontal adjustments values, along with
the page number. This is done in a backward-compatible way for both the
plain and sqlite database backends, so that bookmarks that was taken
previously (bookmarking only the page number) will still work as expected
and won't be lost.
- Fix the issue of not being able to remove bookmarks from the plain
database; removing a bookmark in plain_remove_bookmark using
g_key_file_remove_key corrupts the bookmarks file. This is due to not
truncating the entire bookmarks file in zathura_db_write_key_file_to_file
prior to overriding it with a new one not containing the removed line.
This is why, I guess, plain_remove_bookmark hadn't been implemented as
expected using g_key_file_remove_key, because apparently, someone thought
that the problem is caused by this API.
- Fix not being able to update existing bookmarks persistently; updating a
bookmark works only during the current session, but after the file is
closed and reopened, the updated bookmark still has it's old value. This
is due to changing only the bookmark structure in memory; the proper way
to do it, is to call zathura_db_remove_bookmark on the old bookmark, then
follow that by a call to zathura_db_add_bookmark on a bookmark structure
containing the new position and the same old ID.
- Make zathura_bookmark_add updates the bookmark if it already exists,
rather than doing this externally in cmd_bookmark_create. This allows us
to have all the relevant girara_notify messages in cmd_bookmark_create.
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-21 06:12:12 +02:00
|
|
|
|
2014-01-10 15:49:22 +01:00
|
|
|
for (unsigned int i = 0; i < LENGTH(val_list); ++i) {
|
Bookmark the exact position, not just the page number (along with a number of fixes).
This patch adds some enhancements/fixes to the bookmarking feature of Zathura:
- Bookmark the exact vertical and horizontal adjustments values, along with
the page number. This is done in a backward-compatible way for both the
plain and sqlite database backends, so that bookmarks that was taken
previously (bookmarking only the page number) will still work as expected
and won't be lost.
- Fix the issue of not being able to remove bookmarks from the plain
database; removing a bookmark in plain_remove_bookmark using
g_key_file_remove_key corrupts the bookmarks file. This is due to not
truncating the entire bookmarks file in zathura_db_write_key_file_to_file
prior to overriding it with a new one not containing the removed line.
This is why, I guess, plain_remove_bookmark hadn't been implemented as
expected using g_key_file_remove_key, because apparently, someone thought
that the problem is caused by this API.
- Fix not being able to update existing bookmarks persistently; updating a
bookmark works only during the current session, but after the file is
closed and reopened, the updated bookmark still has it's old value. This
is due to changing only the bookmark structure in memory; the proper way
to do it, is to call zathura_db_remove_bookmark on the old bookmark, then
follow that by a call to zathura_db_add_bookmark on a bookmark structure
containing the new position and the same old ID.
- Make zathura_bookmark_add updates the bookmark if it already exists,
rather than doing this externally in cmd_bookmark_create. This allows us
to have all the relevant girara_notify messages in cmd_bookmark_create.
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-21 06:12:12 +02:00
|
|
|
g_free(val_list[i]);
|
|
|
|
}
|
2012-03-14 13:36:51 +01:00
|
|
|
g_free(name);
|
2011-10-12 12:32:31 +02:00
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
zathura_db_write_key_file_to_file(priv->bookmark_path, priv->bookmarks);
|
2011-10-12 12:32:31 +02:00
|
|
|
|
|
|
|
return true;
|
2011-10-11 15:59:36 +02:00
|
|
|
}
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
static bool
|
Bookmark the exact position, not just the page number (along with a number of fixes).
This patch adds some enhancements/fixes to the bookmarking feature of Zathura:
- Bookmark the exact vertical and horizontal adjustments values, along with
the page number. This is done in a backward-compatible way for both the
plain and sqlite database backends, so that bookmarks that was taken
previously (bookmarking only the page number) will still work as expected
and won't be lost.
- Fix the issue of not being able to remove bookmarks from the plain
database; removing a bookmark in plain_remove_bookmark using
g_key_file_remove_key corrupts the bookmarks file. This is due to not
truncating the entire bookmarks file in zathura_db_write_key_file_to_file
prior to overriding it with a new one not containing the removed line.
This is why, I guess, plain_remove_bookmark hadn't been implemented as
expected using g_key_file_remove_key, because apparently, someone thought
that the problem is caused by this API.
- Fix not being able to update existing bookmarks persistently; updating a
bookmark works only during the current session, but after the file is
closed and reopened, the updated bookmark still has it's old value. This
is due to changing only the bookmark structure in memory; the proper way
to do it, is to call zathura_db_remove_bookmark on the old bookmark, then
follow that by a call to zathura_db_add_bookmark on a bookmark structure
containing the new position and the same old ID.
- Make zathura_bookmark_add updates the bookmark if it already exists,
rather than doing this externally in cmd_bookmark_create. This allows us
to have all the relevant girara_notify messages in cmd_bookmark_create.
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-21 06:12:12 +02:00
|
|
|
plain_remove_bookmark(zathura_database_t* db, const char* file, const char* id)
|
2011-10-11 15:59:36 +02:00
|
|
|
{
|
2012-03-04 15:56:54 +01:00
|
|
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db);
|
|
|
|
if (priv->bookmarks == NULL || priv->bookmark_path == NULL) {
|
2011-10-11 22:39:55 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-03-14 13:36:51 +01:00
|
|
|
char* name = prepare_filename(file);
|
|
|
|
if (g_key_file_has_group(priv->bookmarks, name) == TRUE) {
|
Bookmark the exact position, not just the page number (along with a number of fixes).
This patch adds some enhancements/fixes to the bookmarking feature of Zathura:
- Bookmark the exact vertical and horizontal adjustments values, along with
the page number. This is done in a backward-compatible way for both the
plain and sqlite database backends, so that bookmarks that was taken
previously (bookmarking only the page number) will still work as expected
and won't be lost.
- Fix the issue of not being able to remove bookmarks from the plain
database; removing a bookmark in plain_remove_bookmark using
g_key_file_remove_key corrupts the bookmarks file. This is due to not
truncating the entire bookmarks file in zathura_db_write_key_file_to_file
prior to overriding it with a new one not containing the removed line.
This is why, I guess, plain_remove_bookmark hadn't been implemented as
expected using g_key_file_remove_key, because apparently, someone thought
that the problem is caused by this API.
- Fix not being able to update existing bookmarks persistently; updating a
bookmark works only during the current session, but after the file is
closed and reopened, the updated bookmark still has it's old value. This
is due to changing only the bookmark structure in memory; the proper way
to do it, is to call zathura_db_remove_bookmark on the old bookmark, then
follow that by a call to zathura_db_add_bookmark on a bookmark structure
containing the new position and the same old ID.
- Make zathura_bookmark_add updates the bookmark if it already exists,
rather than doing this externally in cmd_bookmark_create. This allows us
to have all the relevant girara_notify messages in cmd_bookmark_create.
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-21 06:12:12 +02:00
|
|
|
if (g_key_file_remove_key(priv->bookmarks, name, id, NULL) == TRUE) {
|
2011-10-12 12:32:31 +02:00
|
|
|
|
Bookmark the exact position, not just the page number (along with a number of fixes).
This patch adds some enhancements/fixes to the bookmarking feature of Zathura:
- Bookmark the exact vertical and horizontal adjustments values, along with
the page number. This is done in a backward-compatible way for both the
plain and sqlite database backends, so that bookmarks that was taken
previously (bookmarking only the page number) will still work as expected
and won't be lost.
- Fix the issue of not being able to remove bookmarks from the plain
database; removing a bookmark in plain_remove_bookmark using
g_key_file_remove_key corrupts the bookmarks file. This is due to not
truncating the entire bookmarks file in zathura_db_write_key_file_to_file
prior to overriding it with a new one not containing the removed line.
This is why, I guess, plain_remove_bookmark hadn't been implemented as
expected using g_key_file_remove_key, because apparently, someone thought
that the problem is caused by this API.
- Fix not being able to update existing bookmarks persistently; updating a
bookmark works only during the current session, but after the file is
closed and reopened, the updated bookmark still has it's old value. This
is due to changing only the bookmark structure in memory; the proper way
to do it, is to call zathura_db_remove_bookmark on the old bookmark, then
follow that by a call to zathura_db_add_bookmark on a bookmark structure
containing the new position and the same old ID.
- Make zathura_bookmark_add updates the bookmark if it already exists,
rather than doing this externally in cmd_bookmark_create. This allows us
to have all the relevant girara_notify messages in cmd_bookmark_create.
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-21 06:12:12 +02:00
|
|
|
zathura_db_write_key_file_to_file(priv->bookmark_path, priv->bookmarks);
|
|
|
|
g_free(name);
|
2011-10-12 12:32:31 +02:00
|
|
|
|
Bookmark the exact position, not just the page number (along with a number of fixes).
This patch adds some enhancements/fixes to the bookmarking feature of Zathura:
- Bookmark the exact vertical and horizontal adjustments values, along with
the page number. This is done in a backward-compatible way for both the
plain and sqlite database backends, so that bookmarks that was taken
previously (bookmarking only the page number) will still work as expected
and won't be lost.
- Fix the issue of not being able to remove bookmarks from the plain
database; removing a bookmark in plain_remove_bookmark using
g_key_file_remove_key corrupts the bookmarks file. This is due to not
truncating the entire bookmarks file in zathura_db_write_key_file_to_file
prior to overriding it with a new one not containing the removed line.
This is why, I guess, plain_remove_bookmark hadn't been implemented as
expected using g_key_file_remove_key, because apparently, someone thought
that the problem is caused by this API.
- Fix not being able to update existing bookmarks persistently; updating a
bookmark works only during the current session, but after the file is
closed and reopened, the updated bookmark still has it's old value. This
is due to changing only the bookmark structure in memory; the proper way
to do it, is to call zathura_db_remove_bookmark on the old bookmark, then
follow that by a call to zathura_db_add_bookmark on a bookmark structure
containing the new position and the same old ID.
- Make zathura_bookmark_add updates the bookmark if it already exists,
rather than doing this externally in cmd_bookmark_create. This allows us
to have all the relevant girara_notify messages in cmd_bookmark_create.
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-21 06:12:12 +02:00
|
|
|
return true;
|
|
|
|
}
|
2011-10-12 12:32:31 +02:00
|
|
|
}
|
2012-03-14 13:36:51 +01:00
|
|
|
g_free(name);
|
2011-10-12 12:32:31 +02:00
|
|
|
|
2011-10-11 15:59:36 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
static girara_list_t*
|
|
|
|
plain_load_bookmarks(zathura_database_t* db, const char* file)
|
2011-10-11 15:59:36 +02:00
|
|
|
{
|
2012-03-04 15:56:54 +01:00
|
|
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db);
|
|
|
|
if (priv->bookmarks == NULL) {
|
2011-10-11 22:39:55 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-03-14 13:36:51 +01:00
|
|
|
char* name = prepare_filename(file);
|
|
|
|
if (g_key_file_has_group(priv->bookmarks, name) == FALSE) {
|
|
|
|
g_free(name);
|
2011-10-12 12:32:31 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-03-09 08:04:54 +01:00
|
|
|
girara_list_t* result = girara_sorted_list_new2((girara_compare_function_t)
|
2012-10-09 01:12:18 +02:00
|
|
|
zathura_bookmarks_compare, (girara_free_function_t)
|
|
|
|
zathura_bookmark_free);
|
2011-10-12 12:32:31 +02:00
|
|
|
|
Bookmark the exact position, not just the page number (along with a number of fixes).
This patch adds some enhancements/fixes to the bookmarking feature of Zathura:
- Bookmark the exact vertical and horizontal adjustments values, along with
the page number. This is done in a backward-compatible way for both the
plain and sqlite database backends, so that bookmarks that was taken
previously (bookmarking only the page number) will still work as expected
and won't be lost.
- Fix the issue of not being able to remove bookmarks from the plain
database; removing a bookmark in plain_remove_bookmark using
g_key_file_remove_key corrupts the bookmarks file. This is due to not
truncating the entire bookmarks file in zathura_db_write_key_file_to_file
prior to overriding it with a new one not containing the removed line.
This is why, I guess, plain_remove_bookmark hadn't been implemented as
expected using g_key_file_remove_key, because apparently, someone thought
that the problem is caused by this API.
- Fix not being able to update existing bookmarks persistently; updating a
bookmark works only during the current session, but after the file is
closed and reopened, the updated bookmark still has it's old value. This
is due to changing only the bookmark structure in memory; the proper way
to do it, is to call zathura_db_remove_bookmark on the old bookmark, then
follow that by a call to zathura_db_add_bookmark on a bookmark structure
containing the new position and the same old ID.
- Make zathura_bookmark_add updates the bookmark if it already exists,
rather than doing this externally in cmd_bookmark_create. This allows us
to have all the relevant girara_notify messages in cmd_bookmark_create.
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-21 06:12:12 +02:00
|
|
|
gsize num_keys;
|
|
|
|
char** keys = g_key_file_get_keys(priv->bookmarks, name, &num_keys, NULL);
|
2011-10-12 12:32:31 +02:00
|
|
|
if (keys == NULL) {
|
|
|
|
girara_list_free(result);
|
2012-03-14 13:36:51 +01:00
|
|
|
g_free(name);
|
2011-10-12 12:32:31 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
Bookmark the exact position, not just the page number (along with a number of fixes).
This patch adds some enhancements/fixes to the bookmarking feature of Zathura:
- Bookmark the exact vertical and horizontal adjustments values, along with
the page number. This is done in a backward-compatible way for both the
plain and sqlite database backends, so that bookmarks that was taken
previously (bookmarking only the page number) will still work as expected
and won't be lost.
- Fix the issue of not being able to remove bookmarks from the plain
database; removing a bookmark in plain_remove_bookmark using
g_key_file_remove_key corrupts the bookmarks file. This is due to not
truncating the entire bookmarks file in zathura_db_write_key_file_to_file
prior to overriding it with a new one not containing the removed line.
This is why, I guess, plain_remove_bookmark hadn't been implemented as
expected using g_key_file_remove_key, because apparently, someone thought
that the problem is caused by this API.
- Fix not being able to update existing bookmarks persistently; updating a
bookmark works only during the current session, but after the file is
closed and reopened, the updated bookmark still has it's old value. This
is due to changing only the bookmark structure in memory; the proper way
to do it, is to call zathura_db_remove_bookmark on the old bookmark, then
follow that by a call to zathura_db_add_bookmark on a bookmark structure
containing the new position and the same old ID.
- Make zathura_bookmark_add updates the bookmark if it already exists,
rather than doing this externally in cmd_bookmark_create. This allows us
to have all the relevant girara_notify messages in cmd_bookmark_create.
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-21 06:12:12 +02:00
|
|
|
gsize num_vals = 0;
|
|
|
|
|
|
|
|
for (gsize i = 0; i < num_keys; i++) {
|
2014-01-19 16:47:08 +01:00
|
|
|
zathura_bookmark_t* bookmark = g_try_malloc0(sizeof(zathura_bookmark_t));
|
|
|
|
if (bookmark == NULL) {
|
|
|
|
continue;
|
|
|
|
}
|
2011-10-12 12:32:31 +02:00
|
|
|
|
2013-10-31 16:43:44 +01:00
|
|
|
bookmark->id = g_strdup(keys[i]);
|
2014-01-19 17:09:33 +01:00
|
|
|
char** val_list = g_key_file_get_string_list(priv->bookmarks, name, keys[i],
|
|
|
|
&num_vals, NULL);
|
|
|
|
|
|
|
|
if (num_vals != 1 && num_vals != 3) {
|
|
|
|
girara_error("Unexpected number of values.");
|
|
|
|
g_free(bookmark);
|
|
|
|
g_strfreev(val_list);
|
|
|
|
continue;
|
|
|
|
}
|
Bookmark the exact position, not just the page number (along with a number of fixes).
This patch adds some enhancements/fixes to the bookmarking feature of Zathura:
- Bookmark the exact vertical and horizontal adjustments values, along with
the page number. This is done in a backward-compatible way for both the
plain and sqlite database backends, so that bookmarks that was taken
previously (bookmarking only the page number) will still work as expected
and won't be lost.
- Fix the issue of not being able to remove bookmarks from the plain
database; removing a bookmark in plain_remove_bookmark using
g_key_file_remove_key corrupts the bookmarks file. This is due to not
truncating the entire bookmarks file in zathura_db_write_key_file_to_file
prior to overriding it with a new one not containing the removed line.
This is why, I guess, plain_remove_bookmark hadn't been implemented as
expected using g_key_file_remove_key, because apparently, someone thought
that the problem is caused by this API.
- Fix not being able to update existing bookmarks persistently; updating a
bookmark works only during the current session, but after the file is
closed and reopened, the updated bookmark still has it's old value. This
is due to changing only the bookmark structure in memory; the proper way
to do it, is to call zathura_db_remove_bookmark on the old bookmark, then
follow that by a call to zathura_db_add_bookmark on a bookmark structure
containing the new position and the same old ID.
- Make zathura_bookmark_add updates the bookmark if it already exists,
rather than doing this externally in cmd_bookmark_create. This allows us
to have all the relevant girara_notify messages in cmd_bookmark_create.
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-21 06:12:12 +02:00
|
|
|
|
|
|
|
bookmark->page = atoi(val_list[0]);
|
|
|
|
|
|
|
|
if (num_vals == 3) {
|
|
|
|
bookmark->x = g_ascii_strtod(val_list[1], NULL);
|
|
|
|
bookmark->y = g_ascii_strtod(val_list[2], NULL);
|
|
|
|
} else if (num_vals == 1) {
|
|
|
|
bookmark->x = DBL_MIN;
|
|
|
|
bookmark->y = DBL_MIN;
|
|
|
|
}
|
2011-10-12 12:32:31 +02:00
|
|
|
|
|
|
|
girara_list_append(result, bookmark);
|
Bookmark the exact position, not just the page number (along with a number of fixes).
This patch adds some enhancements/fixes to the bookmarking feature of Zathura:
- Bookmark the exact vertical and horizontal adjustments values, along with
the page number. This is done in a backward-compatible way for both the
plain and sqlite database backends, so that bookmarks that was taken
previously (bookmarking only the page number) will still work as expected
and won't be lost.
- Fix the issue of not being able to remove bookmarks from the plain
database; removing a bookmark in plain_remove_bookmark using
g_key_file_remove_key corrupts the bookmarks file. This is due to not
truncating the entire bookmarks file in zathura_db_write_key_file_to_file
prior to overriding it with a new one not containing the removed line.
This is why, I guess, plain_remove_bookmark hadn't been implemented as
expected using g_key_file_remove_key, because apparently, someone thought
that the problem is caused by this API.
- Fix not being able to update existing bookmarks persistently; updating a
bookmark works only during the current session, but after the file is
closed and reopened, the updated bookmark still has it's old value. This
is due to changing only the bookmark structure in memory; the proper way
to do it, is to call zathura_db_remove_bookmark on the old bookmark, then
follow that by a call to zathura_db_add_bookmark on a bookmark structure
containing the new position and the same old ID.
- Make zathura_bookmark_add updates the bookmark if it already exists,
rather than doing this externally in cmd_bookmark_create. This allows us
to have all the relevant girara_notify messages in cmd_bookmark_create.
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-21 06:12:12 +02:00
|
|
|
g_strfreev(val_list);
|
2011-10-12 12:32:31 +02:00
|
|
|
}
|
|
|
|
|
2012-03-14 13:36:51 +01:00
|
|
|
g_free(name);
|
2012-03-04 01:12:53 +01:00
|
|
|
g_strfreev(keys);
|
|
|
|
|
2011-10-12 12:32:31 +02:00
|
|
|
return result;
|
2011-10-11 15:59:36 +02:00
|
|
|
}
|
|
|
|
|
2013-06-21 14:30:04 +02:00
|
|
|
static girara_list_t*
|
|
|
|
get_jumplist_from_str(const char* str)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail(str != NULL, NULL);
|
|
|
|
|
2014-01-10 15:49:22 +01:00
|
|
|
if (*str == '\0') {
|
2013-06-21 14:30:04 +02:00
|
|
|
return girara_list_new2(g_free);
|
|
|
|
}
|
|
|
|
|
|
|
|
girara_list_t* result = girara_list_new2(g_free);
|
|
|
|
char* copy = g_strdup(str);
|
2014-01-10 16:07:03 +01:00
|
|
|
char* saveptr = NULL;
|
|
|
|
char* token = strtok_r(copy, " ", &saveptr);
|
2013-06-21 14:30:04 +02:00
|
|
|
|
|
|
|
while (token != NULL) {
|
2014-01-19 16:47:08 +01:00
|
|
|
zathura_jump_t* jump = g_try_malloc0(sizeof(zathura_jump_t));
|
|
|
|
if (jump == NULL) {
|
|
|
|
continue;
|
|
|
|
}
|
2013-06-21 14:30:04 +02:00
|
|
|
|
|
|
|
jump->page = strtoul(token, NULL, 0);
|
2014-01-10 16:07:03 +01:00
|
|
|
token = strtok_r(NULL, " ", &saveptr);
|
|
|
|
if (token == NULL) {
|
|
|
|
girara_warning("Could not parse jumplist information.");
|
|
|
|
g_free(jump);
|
|
|
|
break;
|
|
|
|
}
|
2014-01-10 15:49:22 +01:00
|
|
|
jump->x = g_ascii_strtod(token, NULL);
|
2014-01-10 16:11:43 +01:00
|
|
|
|
2014-01-10 16:07:03 +01:00
|
|
|
token = strtok_r(NULL, " ", &saveptr);
|
2014-01-10 16:11:43 +01:00
|
|
|
if (token == NULL) {
|
|
|
|
girara_warning("Could not parse jumplist information.");
|
|
|
|
g_free(jump);
|
|
|
|
break;
|
|
|
|
}
|
2014-01-10 15:49:22 +01:00
|
|
|
jump->y = g_ascii_strtod(token, NULL);
|
2014-01-10 16:11:43 +01:00
|
|
|
|
2013-06-21 14:30:04 +02:00
|
|
|
girara_list_append(result, jump);
|
2014-01-10 16:07:03 +01:00
|
|
|
token = strtok_r(NULL, " ", &saveptr);
|
2013-06-21 14:30:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
2014-01-10 15:49:22 +01:00
|
|
|
char buffer[G_ASCII_DTOSTR_BUF_SIZE] = { '\0' };
|
|
|
|
|
|
|
|
g_string_append_printf(str_val, "%d ", jump->page);
|
|
|
|
g_string_append(str_val, g_ascii_dtostr(buffer, G_ASCII_DTOSTR_BUF_SIZE, jump->x));
|
|
|
|
g_string_append_c(str_val, ' ');
|
|
|
|
g_string_append(str_val, g_ascii_dtostr(buffer, G_ASCII_DTOSTR_BUF_SIZE, jump->y));
|
|
|
|
g_string_append_c(str_val, ' ');
|
2013-06-21 14:30:04 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
static bool
|
2012-04-20 21:15:03 +02:00
|
|
|
plain_set_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t*
|
2012-10-09 01:12:18 +02:00
|
|
|
file_info)
|
2011-10-11 15:59:36 +02:00
|
|
|
{
|
2012-03-04 15:56:54 +01:00
|
|
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db);
|
2012-04-20 21:15:03 +02:00
|
|
|
if (priv->history == NULL || file_info == NULL || file == NULL) {
|
2011-10-11 23:18:21 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-03-14 13:36:51 +01:00
|
|
|
char* name = prepare_filename(file);
|
2011-10-11 23:18:21 +02:00
|
|
|
|
2014-01-10 15:49:22 +01:00
|
|
|
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_double (priv->history, name, KEY_SCALE, file_info->scale);
|
2012-06-27 22:34:16 +02:00
|
|
|
g_key_file_set_integer(priv->history, name, KEY_ROTATE, file_info->rotation);
|
|
|
|
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);
|
2014-01-10 15:49:22 +01:00
|
|
|
g_key_file_set_double (priv->history, name, KEY_POSITION_X, file_info->position_x);
|
|
|
|
g_key_file_set_double (priv->history, name, KEY_POSITION_Y, file_info->position_y);
|
2011-10-11 23:18:21 +02:00
|
|
|
|
2012-04-20 23:35:48 +02:00
|
|
|
g_free(name);
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
zathura_db_write_key_file_to_file(priv->history_path, priv->history);
|
2011-10-11 23:18:21 +02:00
|
|
|
|
2011-10-12 11:45:00 +02:00
|
|
|
return true;
|
2011-10-11 15:59:36 +02:00
|
|
|
}
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
static bool
|
2012-04-20 21:15:03 +02:00
|
|
|
plain_get_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t*
|
2012-10-09 01:12:18 +02:00
|
|
|
file_info)
|
2011-10-11 15:59:36 +02:00
|
|
|
{
|
2012-04-20 21:15:03 +02:00
|
|
|
if (db == NULL || file == NULL || file_info == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db);
|
|
|
|
if (priv->history == NULL) {
|
2011-10-11 22:39:55 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-03-14 13:36:51 +01:00
|
|
|
char* name = prepare_filename(file);
|
|
|
|
if (g_key_file_has_group(priv->history, name) == FALSE) {
|
2012-05-08 17:02:18 +02:00
|
|
|
g_free(name);
|
2011-10-12 12:43:36 +02:00
|
|
|
return false;
|
2011-10-11 23:18:21 +02:00
|
|
|
}
|
|
|
|
|
2012-06-27 22:34:16 +02:00
|
|
|
file_info->current_page = g_key_file_get_integer(priv->history, name, KEY_PAGE, NULL);
|
|
|
|
file_info->page_offset = g_key_file_get_integer(priv->history, name, KEY_OFFSET, NULL);
|
2014-01-10 15:49:22 +01:00
|
|
|
file_info->scale = g_key_file_get_double (priv->history, name, KEY_SCALE, NULL);
|
2012-06-27 22:34:16 +02:00
|
|
|
file_info->rotation = g_key_file_get_integer(priv->history, name, KEY_ROTATE, NULL);
|
2011-10-12 12:43:36 +02:00
|
|
|
|
2014-01-10 15:49:22 +01:00
|
|
|
/* the following flags got introduced at a later point */
|
|
|
|
if (g_key_file_has_key(priv->history, name, KEY_PAGES_PER_ROW, NULL) == TRUE) {
|
|
|
|
file_info->pages_per_row = g_key_file_get_integer(priv->history, name, KEY_PAGES_PER_ROW, NULL);
|
2012-04-21 17:09:38 +02:00
|
|
|
}
|
2014-01-10 15:49:22 +01:00
|
|
|
if (g_key_file_has_key(priv->history, name, KEY_FIRST_PAGE_COLUMN, NULL) == TRUE) {
|
|
|
|
file_info->first_page_column = g_key_file_get_integer(priv->history, name, KEY_FIRST_PAGE_COLUMN, NULL);
|
2012-04-21 17:09:38 +02:00
|
|
|
}
|
2014-01-10 15:49:22 +01:00
|
|
|
if (g_key_file_has_key(priv->history, name, KEY_POSITION_X, NULL) == TRUE) {
|
|
|
|
file_info->position_x = g_key_file_get_double(priv->history, name, KEY_POSITION_X, NULL);
|
|
|
|
}
|
|
|
|
if (g_key_file_has_key(priv->history, name, KEY_POSITION_Y, NULL) == TRUE) {
|
|
|
|
file_info->position_y = g_key_file_get_double(priv->history, name, KEY_POSITION_Y, NULL);
|
2012-04-21 17:09:38 +02:00
|
|
|
}
|
2012-04-20 23:35:48 +02:00
|
|
|
|
2012-03-14 13:36:51 +01:00
|
|
|
g_free(name);
|
2012-03-04 01:02:14 +01:00
|
|
|
|
2011-10-12 12:43:36 +02:00
|
|
|
return true;
|
2011-10-11 15:59:36 +02:00
|
|
|
}
|
2011-10-11 22:39:55 +02:00
|
|
|
|
|
|
|
static bool
|
|
|
|
zathura_db_check_file(const char* path)
|
|
|
|
{
|
|
|
|
if (path == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_file_test(path, G_FILE_TEST_EXISTS) == false) {
|
|
|
|
FILE* file = fopen(path, "w");
|
|
|
|
if (file != NULL) {
|
|
|
|
fclose(file);
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else if (g_file_test(path, G_FILE_TEST_IS_REGULAR) == false) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-10-12 12:32:31 +02:00
|
|
|
static GKeyFile*
|
2011-10-16 20:28:58 +02:00
|
|
|
zathura_db_read_key_file_from_file(const char* path)
|
2011-10-11 22:39:55 +02:00
|
|
|
{
|
|
|
|
if (path == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-10-14 01:24:42 +02:00
|
|
|
/* open file */
|
2012-03-27 00:24:58 +02:00
|
|
|
FILE* file = fopen(path, "rw");
|
2011-11-21 16:40:26 +01:00
|
|
|
if (file == NULL) {
|
2011-10-14 01:24:42 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-10-12 12:32:31 +02:00
|
|
|
GKeyFile* key_file = g_key_file_new();
|
|
|
|
if (key_file == NULL) {
|
2011-11-21 16:40:26 +01:00
|
|
|
fclose(file);
|
2011-10-14 01:24:42 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* read config file */
|
2011-11-21 16:40:26 +01:00
|
|
|
file_lock_set(fileno(file), F_WRLCK);
|
|
|
|
char* content = girara_file_read2(file);
|
|
|
|
file_lock_set(fileno(file), F_UNLCK);
|
|
|
|
fclose(file);
|
2011-10-14 01:24:42 +02:00
|
|
|
if (content == NULL) {
|
2011-11-21 16:40:26 +01:00
|
|
|
g_key_file_free(key_file);
|
2011-10-11 23:18:21 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
2011-10-14 01:24:42 +02:00
|
|
|
|
|
|
|
/* parse config file */
|
2011-10-16 20:28:58 +02:00
|
|
|
size_t contentlen = strlen(content);
|
|
|
|
if (contentlen == 0) {
|
|
|
|
static const char dummy_content[] = "# nothing";
|
|
|
|
static const size_t dummy_len = sizeof(dummy_content) - 1;
|
|
|
|
|
|
|
|
free(content);
|
|
|
|
content = malloc(sizeof(char) * (dummy_len + 1));
|
2011-10-17 09:37:22 +02:00
|
|
|
content = memcpy(content, dummy_content, dummy_len + 1);
|
2011-10-16 20:28:58 +02:00
|
|
|
contentlen = dummy_len;
|
|
|
|
}
|
|
|
|
|
2011-10-12 12:32:31 +02:00
|
|
|
GError* error = NULL;
|
2011-10-16 20:28:58 +02:00
|
|
|
if (g_key_file_load_from_data(key_file, content, contentlen,
|
2012-10-09 01:12:18 +02:00
|
|
|
G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error) ==
|
2011-10-12 12:32:31 +02:00
|
|
|
FALSE) {
|
2012-10-09 01:12:18 +02:00
|
|
|
if (error->code != 1) { /* ignore empty file */
|
2011-10-14 01:24:42 +02:00
|
|
|
free(content);
|
2011-10-12 12:32:31 +02:00
|
|
|
g_key_file_free(key_file);
|
|
|
|
g_error_free(error);
|
2011-10-14 01:24:42 +02:00
|
|
|
return NULL;
|
2011-10-12 12:32:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
g_error_free(error);
|
|
|
|
}
|
|
|
|
|
2011-10-14 01:24:42 +02:00
|
|
|
free(content);
|
|
|
|
|
2011-10-12 12:32:31 +02:00
|
|
|
return key_file;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-10-12 12:43:36 +02:00
|
|
|
zathura_db_write_key_file_to_file(const char* file, GKeyFile* key_file)
|
2011-10-12 12:32:31 +02:00
|
|
|
{
|
2011-10-12 12:43:36 +02:00
|
|
|
if (file == NULL || key_file == NULL) {
|
2011-10-12 12:32:31 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-10-12 12:43:36 +02:00
|
|
|
gchar* content = g_key_file_to_data(key_file, NULL, NULL);
|
2011-10-12 12:32:31 +02:00
|
|
|
if (content == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-10-14 01:04:06 +02:00
|
|
|
/* open file */
|
Bookmark the exact position, not just the page number (along with a number of fixes).
This patch adds some enhancements/fixes to the bookmarking feature of Zathura:
- Bookmark the exact vertical and horizontal adjustments values, along with
the page number. This is done in a backward-compatible way for both the
plain and sqlite database backends, so that bookmarks that was taken
previously (bookmarking only the page number) will still work as expected
and won't be lost.
- Fix the issue of not being able to remove bookmarks from the plain
database; removing a bookmark in plain_remove_bookmark using
g_key_file_remove_key corrupts the bookmarks file. This is due to not
truncating the entire bookmarks file in zathura_db_write_key_file_to_file
prior to overriding it with a new one not containing the removed line.
This is why, I guess, plain_remove_bookmark hadn't been implemented as
expected using g_key_file_remove_key, because apparently, someone thought
that the problem is caused by this API.
- Fix not being able to update existing bookmarks persistently; updating a
bookmark works only during the current session, but after the file is
closed and reopened, the updated bookmark still has it's old value. This
is due to changing only the bookmark structure in memory; the proper way
to do it, is to call zathura_db_remove_bookmark on the old bookmark, then
follow that by a call to zathura_db_add_bookmark on a bookmark structure
containing the new position and the same old ID.
- Make zathura_bookmark_add updates the bookmark if it already exists,
rather than doing this externally in cmd_bookmark_create. This allows us
to have all the relevant girara_notify messages in cmd_bookmark_create.
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-21 06:12:12 +02:00
|
|
|
int fd = open(file, O_RDWR | O_TRUNC);
|
2011-10-14 01:04:06 +02:00
|
|
|
if (fd == -1) {
|
2011-10-12 12:32:31 +02:00
|
|
|
g_free(content);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-10-14 01:04:06 +02:00
|
|
|
file_lock_set(fd, F_WRLCK);
|
2011-11-21 16:40:26 +01:00
|
|
|
if (write(fd, content, strlen(content)) == 0) {
|
|
|
|
girara_error("Failed to write to %s", file);
|
|
|
|
}
|
2011-10-14 01:04:06 +02:00
|
|
|
file_lock_set(fd, F_UNLCK);
|
|
|
|
|
|
|
|
close(fd);
|
|
|
|
|
2011-10-12 12:32:31 +02:00
|
|
|
g_free(content);
|
2011-10-11 22:39:55 +02:00
|
|
|
}
|
|
|
|
|
2011-10-11 23:43:30 +02:00
|
|
|
static void
|
|
|
|
cb_zathura_db_watch_file(GFileMonitor* UNUSED(monitor), GFile* file, GFile* UNUSED(other_file),
|
2012-10-09 01:12:18 +02:00
|
|
|
GFileMonitorEvent event, zathura_database_t* database)
|
2011-10-11 23:43:30 +02:00
|
|
|
{
|
|
|
|
if (event != G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT || database == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* path = g_file_get_path(file);
|
|
|
|
if (path == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(database);
|
|
|
|
if (priv->bookmark_path && strcmp(priv->bookmark_path, path) == 0) {
|
2012-03-05 20:46:00 +01:00
|
|
|
if (priv->bookmarks != NULL) {
|
|
|
|
g_key_file_free(priv->bookmarks);
|
|
|
|
}
|
2012-03-09 08:04:54 +01:00
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
priv->bookmarks = zathura_db_read_key_file_from_file(priv->bookmark_path);
|
|
|
|
} else if (priv->history_path && strcmp(priv->history_path, path) == 0) {
|
2012-03-05 20:46:00 +01:00
|
|
|
if (priv->history != NULL) {
|
|
|
|
g_key_file_free(priv->history);
|
|
|
|
}
|
2012-03-09 08:04:54 +01:00
|
|
|
|
2012-03-04 15:56:54 +01:00
|
|
|
priv->history = zathura_db_read_key_file_from_file(priv->history_path);
|
2011-10-11 23:43:30 +02:00
|
|
|
}
|
2012-04-01 22:57:34 +02:00
|
|
|
|
|
|
|
g_free(path);
|
2011-10-11 23:43:30 +02:00
|
|
|
}
|
2013-03-17 16:19:10 +01:00
|
|
|
|
|
|
|
static girara_list_t*
|
|
|
|
plain_io_read(GiraraInputHistoryIO* db)
|
|
|
|
{
|
|
|
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db);
|
|
|
|
|
|
|
|
/* open file */
|
|
|
|
FILE* file = fopen(priv->input_history_path, "r");
|
|
|
|
if (file == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* read input history file */
|
|
|
|
file_lock_set(fileno(file), F_RDLCK);
|
|
|
|
char* content = girara_file_read2(file);
|
|
|
|
file_lock_set(fileno(file), F_UNLCK);
|
|
|
|
fclose(file);
|
|
|
|
|
|
|
|
girara_list_t* res = girara_list_new2(g_free);
|
|
|
|
char** tmp = g_strsplit(content, "\n", 0);
|
|
|
|
for (size_t i = 0; tmp[i] != NULL; ++i) {
|
2013-06-08 01:35:10 +02:00
|
|
|
if (strlen(tmp[i]) == 0 || strchr(":/?", tmp[i][0]) == NULL) {
|
2013-03-17 16:19:10 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
girara_list_append(res, g_strdup(tmp[i]));
|
|
|
|
}
|
|
|
|
g_strfreev(tmp);
|
|
|
|
free(content);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
static void
|
|
|
|
plain_io_append(GiraraInputHistoryIO* db, const char* input)
|
|
|
|
{
|
|
|
|
zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db);
|
|
|
|
|
|
|
|
/* open file */
|
|
|
|
FILE* file = fopen(priv->input_history_path, "r+");
|
|
|
|
if (file == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* read input history file */
|
|
|
|
file_lock_set(fileno(file), F_WRLCK);
|
|
|
|
char* content = girara_file_read2(file);
|
|
|
|
|
|
|
|
rewind(file);
|
|
|
|
if (ftruncate(fileno(file), 0) != 0) {
|
|
|
|
free(content);
|
|
|
|
file_lock_set(fileno(file), F_UNLCK);
|
|
|
|
fclose(file);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
char** tmp = g_strsplit(content, "\n", 0);
|
|
|
|
free(content);
|
|
|
|
|
|
|
|
/* write input history file */
|
|
|
|
for (size_t i = 0; tmp[i] != NULL; ++i) {
|
2013-06-08 01:35:10 +02:00
|
|
|
if (strlen(tmp[i]) == 0 || strchr(":/?", tmp[i][0]) == NULL || strcmp(tmp[i], input) == 0) {
|
2013-03-17 16:19:10 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
fprintf(file, "%s\n", tmp[i]);
|
|
|
|
}
|
|
|
|
g_strfreev(tmp);
|
|
|
|
fprintf(file, "%s\n", input);
|
|
|
|
|
|
|
|
file_lock_set(fileno(file), F_UNLCK);
|
|
|
|
fclose(file);
|
|
|
|
}
|