From 924b7e0e60022ecfff4e94e9ecf473c84666c253 Mon Sep 17 00:00:00 2001 From: Sebastian Neuser Date: Sat, 7 Nov 2015 19:52:25 +0100 Subject: [PATCH 1/4] shortcuts.c: Fix code comments --- zathura/shortcuts.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zathura/shortcuts.c b/zathura/shortcuts.c index 1cb3d02..17b4414 100644 --- a/zathura/shortcuts.c +++ b/zathura/shortcuts.c @@ -1308,7 +1308,7 @@ sc_toggle_presentation(girara_session_t* session, girara_argument_t* render_all(zathura); refresh_view(zathura); - /* setm ode */ + /* set mode */ girara_mode_set(session, zathura->modes.normal); } else if (old_mode == zathura->modes.normal) { /* backup pages per row */ @@ -1336,7 +1336,7 @@ sc_toggle_presentation(girara_session_t* session, girara_argument_t* gtk_window_fullscreen(GTK_WINDOW(session->gtk.window)); refresh_view(zathura); - /* setm ode */ + /* set mode */ girara_mode_set(session, zathura->modes.presentation); } From 7e2a18f7a8d0f5e0b9e81886cf4f76387bee093e Mon Sep 17 00:00:00 2001 From: Sebastian Neuser Date: Sat, 7 Nov 2015 19:55:25 +0100 Subject: [PATCH 2/4] Change type of first-page-column to char* / TEXT --- zathura/config.c | 2 +- zathura/database-plain.c | 4 +- zathura/database-sqlite.c | 94 ++++++++++++++++++++++++++++++++++----- zathura/database.h | 2 +- zathura/shortcuts.c | 7 +-- zathura/zathura.c | 14 +++--- 6 files changed, 99 insertions(+), 24 deletions(-) diff --git a/zathura/config.c b/zathura/config.c index d807f6c..626f495 100644 --- a/zathura/config.c +++ b/zathura/config.c @@ -149,7 +149,7 @@ config_load_default(zathura_t* zathura) int_value = 1; girara_setting_add(gsession, "pages-per-row", &int_value, INT, false, _("Number of pages per row"), cb_page_layout_value_changed, NULL); int_value = 1; - girara_setting_add(gsession, "first-page-column", &int_value, INT, false, _("Column of the first page"), cb_page_layout_value_changed, NULL); + girara_setting_add(gsession, "first-page-column", "1:2", STRING, false, _("Column of the first page"), cb_page_layout_value_changed, NULL); float_value = 40; girara_setting_add(gsession, "scroll-step", &float_value, FLOAT, false, _("Scroll step"), NULL, NULL); float_value = 40; diff --git a/zathura/database-plain.c b/zathura/database-plain.c index 3f4133d..e64feda 100644 --- a/zathura/database-plain.c +++ b/zathura/database-plain.c @@ -559,7 +559,7 @@ plain_set_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t* g_key_file_set_double (priv->history, name, KEY_SCALE, file_info->scale); 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); + g_key_file_set_string(priv->history, name, KEY_FIRST_PAGE_COLUMN, file_info->first_page_column_list); 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); g_key_file_set_integer(priv->history, name, KEY_TIME, time(NULL)); @@ -600,7 +600,7 @@ plain_get_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t* file_info->pages_per_row = g_key_file_get_integer(priv->history, name, KEY_PAGES_PER_ROW, NULL); } 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); + file_info->first_page_column_list = g_key_file_get_string(priv->history, name, KEY_FIRST_PAGE_COLUMN, NULL); } 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); diff --git a/zathura/database-sqlite.c b/zathura/database-sqlite.c index 176f3dc..c1808ee 100644 --- a/zathura/database-sqlite.c +++ b/zathura/database-sqlite.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "database-sqlite.h" #include "utils.h" @@ -17,6 +18,7 @@ G_DEFINE_TYPE_WITH_CODE(ZathuraSQLDatabase, zathura_sqldatabase, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(GIRARA_TYPE_INPUT_HISTORY_IO, io_interface_init)) static bool check_column(sqlite3* session, const char* table, const char* col, bool* result); +static bool check_column_type(sqlite3* session, const char* table, const char* col, const char* type, bool* result); static void sqlite_finalize(GObject* object); static bool sqlite_add_bookmark(zathura_database_t* db, const char* file, zathura_bookmark_t* bookmark); static bool sqlite_remove_bookmark(zathura_database_t* db, const char* file, const char* id); @@ -148,7 +150,7 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path) "scale FLOAT," "rotation INTEGER," "pages_per_row INTEGER," - "first_page_column INTEGER," + "first_page_column TEXT," "position_x FLOAT," "position_y FLOAT," "time TIMESTAMP" @@ -176,9 +178,9 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path) /* update fileinfo table (part 2) */ static const char SQL_FILEINFO_ALTER2[] = - "ALTER TABLE fileinfo ADD COLUMN first_page_column INTEGER;"; + "ALTER TABLE fileinfo ADD COLUMN first_page_column TEXT;"; - /* update fileinfo table (part 2) */ + /* update fileinfo table (part 3) */ static const char SQL_FILEINFO_ALTER3[] = "ALTER TABLE fileinfo ADD COLUMN time TIMESTAMP;"; @@ -242,6 +244,37 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path) } } + /* check existing tables for correct column types */ + ret1 = check_column_type(session, "fileinfo", "first_page_column", "TEXT", &res1); + + if (ret1 == true && res1 == false) { + girara_debug("old database table layout detected; updating ..."); + + /* prepare transaction */ + char tx_begin[] = "BEGIN TRANSACTION;" + "ALTER TABLE fileinfo RENAME TO tmp;"; + char tx_end[] = "INSERT INTO fileinfo SELECT * FROM tmp;" + "DROP TABLE tmp;" + "COMMIT;"; + + /* calculate requred buffer size */ + size_t tx_buffer_size = strlen(tx_begin); + tx_buffer_size += strlen(SQL_FILEINFO_INIT); + tx_buffer_size += strlen(tx_end); + ++tx_buffer_size; + + /* assemble transaction */ + char transaction[tx_buffer_size]; + bzero(transaction, tx_buffer_size); + strcat(transaction, tx_begin); + strcat(transaction, SQL_FILEINFO_INIT); + strcat(transaction, tx_end); + + if (sqlite3_exec(session, transaction, NULL, 0, NULL) != SQLITE_OK) { + girara_warning("failed to update database table layout"); + } + } + priv->session = session; } @@ -318,6 +351,42 @@ check_column(sqlite3* session, const char* table, const char* col, bool* res) return true; } +static bool +check_column_type(sqlite3* session, const char* table, const char* col, const char* type, bool* res) +{ + /* we can't actually bind the argument with sqlite3_bind_text because + * sqlite3_prepare_v2 fails with "PRAGMA table_info(?);" */ + char* query = sqlite3_mprintf("PRAGMA table_info(%Q);", table); + if (query == NULL) { + return false; + } + + sqlite3_stmt* stmt = prepare_statement(session, query); + if (stmt == NULL) { + return false; + } + + *res = false; + + while (sqlite3_step(stmt) == SQLITE_ROW) { + if (strcmp((const char*) sqlite3_column_text(stmt, 1), col) == 0) { + if (strcmp((const char*) sqlite3_column_text(stmt, 2), type) == 0) { + *res = true; + break; + } + } + } + + if (*res == false) { + girara_debug("column %s in table %s has wrong type", col, table); + } + + sqlite3_finalize(stmt); + sqlite3_free(query); + + return true; +} + static bool sqlite_add_bookmark(zathura_database_t* db, const char* file, zathura_bookmark_t* bookmark) @@ -587,7 +656,8 @@ sqlite_set_fileinfo(zathura_database_t* db, const char* file, sqlite3_bind_double(stmt, 4, file_info->scale) != SQLITE_OK || sqlite3_bind_int(stmt, 5, file_info->rotation) != SQLITE_OK || sqlite3_bind_int(stmt, 6, file_info->pages_per_row) != SQLITE_OK || - sqlite3_bind_int(stmt, 7, file_info->first_page_column) != SQLITE_OK || + sqlite3_bind_text(stmt, 7, file_info->first_page_column_list, -1, NULL) + != SQLITE_OK || sqlite3_bind_double(stmt, 8, file_info->position_x) != SQLITE_OK || sqlite3_bind_double(stmt, 9, file_info->position_y) != SQLITE_OK) { sqlite3_finalize(stmt); @@ -631,14 +701,14 @@ sqlite_get_fileinfo(zathura_database_t* db, const char* file, return false; } - file_info->current_page = sqlite3_column_int(stmt, 0); - file_info->page_offset = sqlite3_column_int(stmt, 1); - file_info->scale = sqlite3_column_double(stmt, 2); - file_info->rotation = sqlite3_column_int(stmt, 3); - file_info->pages_per_row = sqlite3_column_int(stmt, 4); - file_info->first_page_column = sqlite3_column_int(stmt, 5); - file_info->position_x = sqlite3_column_double(stmt, 6); - file_info->position_y = sqlite3_column_double(stmt, 7); + file_info->current_page = sqlite3_column_int(stmt, 0); + file_info->page_offset = sqlite3_column_int(stmt, 1); + file_info->scale = sqlite3_column_double(stmt, 2); + file_info->rotation = sqlite3_column_int(stmt, 3); + file_info->pages_per_row = sqlite3_column_int(stmt, 4); + file_info->first_page_column_list = g_strdup((const char*) sqlite3_column_text(stmt, 5)); + file_info->position_x = sqlite3_column_double(stmt, 6); + file_info->position_y = sqlite3_column_double(stmt, 7); sqlite3_finalize(stmt); diff --git a/zathura/database.h b/zathura/database.h index 3d46132..8a5140b 100644 --- a/zathura/database.h +++ b/zathura/database.h @@ -15,7 +15,7 @@ typedef struct zathura_fileinfo_s { double scale; unsigned int rotation; unsigned int pages_per_row; - unsigned int first_page_column; + char* first_page_column_list; double position_x; double position_y; } zathura_fileinfo_t; diff --git a/zathura/shortcuts.c b/zathura/shortcuts.c index 17b4414..693235e 100644 --- a/zathura/shortcuts.c +++ b/zathura/shortcuts.c @@ -1286,7 +1286,7 @@ sc_toggle_presentation(girara_session_t* session, girara_argument_t* } static int pages_per_row = 1; - static int first_page_column = 1; + static char* first_page_column_list = "1:2"; static double zoom = 1.0; const girara_mode_t old_mode = girara_mode_get(session); @@ -1295,7 +1295,7 @@ sc_toggle_presentation(girara_session_t* session, girara_argument_t* girara_setting_set(session, "pages-per-row", &pages_per_row); /* reset first page column */ - girara_setting_set(session, "first-page-column", &first_page_column); + girara_setting_set(session, "first-page-column", first_page_column_list); /* show status bar */ gtk_widget_show(GTK_WIDGET(session->gtk.statusbar)); @@ -1315,7 +1315,8 @@ sc_toggle_presentation(girara_session_t* session, girara_argument_t* girara_setting_get(session, "pages-per-row", &pages_per_row); /* backup first page column */ - girara_setting_get(session, "first-page-column", &first_page_column); + g_free(first_page_column_list); + girara_setting_get(session, "first-page-column", &first_page_column_list); /* set single view */ int int_value = 1; diff --git a/zathura/zathura.c b/zathura/zathura.c index 26fc95d..ce42f33 100644 --- a/zathura/zathura.c +++ b/zathura/zathura.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -651,13 +652,14 @@ document_open(zathura_t* zathura, const char* path, const char* password, } /* read history file */ + char first_page_column_list_default[] = "1:2"; zathura_fileinfo_t file_info = { .current_page = 0, .page_offset = 0, .scale = 1, .rotation = 0, .pages_per_row = 0, - .first_page_column = 0, + .first_page_column_list = first_page_column_list_default, .position_x = 0, .position_y = 0 }; @@ -856,6 +858,7 @@ document_open(zathura_t* zathura, const char* path, const char* password, /* view mode */ unsigned int pages_per_row = 1; unsigned int first_page_column = 1; + char* first_page_column_list = first_page_column_list_default; unsigned int page_padding = 1; girara_setting_get(zathura->ui.session, "page-padding", &page_padding); @@ -866,8 +869,9 @@ document_open(zathura_t* zathura, const char* path, const char* password, girara_setting_get(zathura->ui.session, "pages-per-row", &pages_per_row); } - if (file_info.first_page_column > 0) { - first_page_column = file_info.first_page_column; + /* read first_page_column list */ + if (strcmp(file_info.first_page_column_list, "")) { + first_page_column_list = file_info.first_page_column_list; } else { girara_setting_get(zathura->ui.session, "first-page-column", &first_page_column); } @@ -1072,14 +1076,14 @@ document_close(zathura_t* zathura, bool keep_monitor) /* store file information */ const char* path = zathura_document_get_path(zathura->document); - zathura_fileinfo_t file_info = { 0, 0, 1, 0, 1, 1, 0, 0 }; + zathura_fileinfo_t file_info = { 0, 0, 1, 0, 1, "1:2", 0, 0 }; file_info.current_page = zathura_document_get_current_page_number(zathura->document); file_info.page_offset = zathura_document_get_page_offset(zathura->document); file_info.scale = zathura_document_get_scale(zathura->document); file_info.rotation = zathura_document_get_rotation(zathura->document); girara_setting_get(zathura->ui.session, "pages-per-row", &(file_info.pages_per_row)); - girara_setting_get(zathura->ui.session, "first-page-column", &(file_info.first_page_column)); + girara_setting_get(zathura->ui.session, "first-page-column", &(file_info.first_page_column_list)); /* get position */ file_info.position_x = zathura_document_get_position_x(zathura->document); From a9aa7e4ad29b749bd5f140794f6193224101b726 Mon Sep 17 00:00:00 2001 From: Sebastian Neuser Date: Sat, 7 Nov 2015 20:12:01 +0100 Subject: [PATCH 3/4] Implement first page column list --- zathura/callbacks.c | 9 +++++++-- zathura/utils.c | 30 ++++++++++++++++++++++++++++++ zathura/utils.h | 13 +++++++++++++ zathura/zathura.c | 12 +++++++++--- 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/zathura/callbacks.c b/zathura/callbacks.c index dd6070c..0ee3b0b 100644 --- a/zathura/callbacks.c +++ b/zathura/callbacks.c @@ -243,8 +243,13 @@ cb_page_layout_value_changed(girara_session_t* session, const char* name, girara unsigned int pages_per_row = 1; girara_setting_get(session, "pages-per-row", &pages_per_row); - unsigned int first_page_column = 1; - girara_setting_get(session, "first-page-column", &first_page_column); + /* get list of first_page_column settings */ + char* first_page_column_list = NULL; + girara_setting_get(session, "first-page-column", &first_page_column_list); + + /* find value for first_page_column */ + unsigned int first_page_column = find_first_page_column(first_page_column_list, pages_per_row); + g_free(first_page_column_list); unsigned int page_padding = 1; girara_setting_get(zathura->ui.session, "page-padding", &page_padding); diff --git a/zathura/utils.c b/zathura/utils.c index a995eb7..370958e 100644 --- a/zathura/utils.c +++ b/zathura/utils.c @@ -253,3 +253,33 @@ get_selection(zathura_t* zathura) return selection; } + +unsigned int +find_first_page_column(const char* first_page_column_list, + const unsigned int pages_per_row) +{ + /* sanity checks */ + unsigned int first_page_column = 1; + g_return_val_if_fail(first_page_column_list != NULL, first_page_column); + g_return_val_if_fail(strcmp(first_page_column_list, ""), first_page_column); + g_return_val_if_fail(pages_per_row > 0, first_page_column); + + /* split settings list */ + char** settings = g_strsplit(first_page_column_list, ":", pages_per_row+1); + + size_t settings_size = 0; + while (settings[settings_size] != NULL) { + ++settings_size; + } + + /* read setting value corresponding to the specified pages per row */ + unsigned int index = pages_per_row - 1; + if (settings_size > index && strcmp(settings[index], "")) { + first_page_column = atoi(settings[index]); + } + + /* free buffers */ + g_strfreev(settings); + + return first_page_column; +} diff --git a/zathura/utils.h b/zathura/utils.h index 141468f..a1902f0 100644 --- a/zathura/utils.h +++ b/zathura/utils.h @@ -107,4 +107,17 @@ GdkAtom* get_selection(zathura_t* zathura); double zathura_correct_scale_value(girara_session_t* session, const double scale); + +/** + * Extracts the column the first page should be rendered in from the specified + * list of settings corresponding to the specified pages per row + * + * @param[in] first_page_column_list The settings list + * @param[in] pages_per_row The current pages per row + * + * @return The column the first page should be rendered in + */ +unsigned int find_first_page_column(const char* first_page_column_list, + const unsigned int pages_per_row); + #endif // UTILS_H diff --git a/zathura/zathura.c b/zathura/zathura.c index ce42f33..385c98b 100644 --- a/zathura/zathura.c +++ b/zathura/zathura.c @@ -857,7 +857,6 @@ document_open(zathura_t* zathura, const char* path, const char* password, /* view mode */ unsigned int pages_per_row = 1; - unsigned int first_page_column = 1; char* first_page_column_list = first_page_column_list_default; unsigned int page_padding = 1; @@ -873,11 +872,15 @@ document_open(zathura_t* zathura, const char* path, const char* password, if (strcmp(file_info.first_page_column_list, "")) { first_page_column_list = file_info.first_page_column_list; } else { - girara_setting_get(zathura->ui.session, "first-page-column", &first_page_column); + girara_setting_get(zathura->ui.session, "first-page-column", &first_page_column_list); } + /* find value for first_page_column */ + unsigned int first_page_column = find_first_page_column(first_page_column_list, pages_per_row); + girara_setting_set(zathura->ui.session, "pages-per-row", &pages_per_row); - girara_setting_set(zathura->ui.session, "first-page-column", &first_page_column); + girara_setting_set(zathura->ui.session, "first-page-column", first_page_column_list); + g_free(first_page_column_list); page_widget_set_mode(zathura, page_padding, pages_per_row, first_page_column); zathura_document_set_page_layout(zathura->document, page_padding, pages_per_row, first_page_column); @@ -1097,6 +1100,9 @@ document_close(zathura_t* zathura, bool keep_monitor) zathura_db_save_jumplist(zathura->database, path, zathura->jumplist.list); } + /* free buffers */ + g_free(file_info.first_page_column_list); + girara_list_iterator_free(zathura->jumplist.cur); zathura->jumplist.cur = NULL; girara_list_free(zathura->jumplist.list); From bab767fb2c79b8610c0e8c4b4b5ddc0ba1554b99 Mon Sep 17 00:00:00 2001 From: Sebastian Neuser Date: Sat, 7 Nov 2015 19:49:56 +0100 Subject: [PATCH 4/4] Update documentation on first-page-column --- doc/man/zathurarc.5.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/man/zathurarc.5.rst b/doc/man/zathurarc.5.rst index 9bb3cc1..45a9bbb 100644 --- a/doc/man/zathurarc.5.rst +++ b/doc/man/zathurarc.5.rst @@ -731,9 +731,12 @@ Defines the number of pages that are rendered next to each other in a row. first-page-column ^^^^^^^^^^^^^^^^^ Defines the column in which the first page will be displayed. +This setting is stored separately for every value of pages-per-row according to +the following pattern <1 page per row>:[<2 pages per row>[: ...]]. Per default, +the first column is set to 2 for double-page layout. -* Value type: Integer -* Default value: 1 +* Value type: String +* Default value: 1:2 recolor ^^^^^^^