mirror of
https://github.com/YGGverse/Yoda.git
synced 2026-03-31 16:45:27 +00:00
implement navigation history session save
This commit is contained in:
parent
ab21f58adb
commit
a9d00188f4
4 changed files with 328 additions and 35 deletions
|
|
@ -52,6 +52,7 @@ Navigation::Navigation(
|
||||||
);
|
);
|
||||||
|
|
||||||
navigationHistory = Gtk::make_managed<navigation::History>(
|
navigationHistory = Gtk::make_managed<navigation::History>(
|
||||||
|
db,
|
||||||
ACTION__NAVIGATION_HISTORY_BACK,
|
ACTION__NAVIGATION_HISTORY_BACK,
|
||||||
ACTION__NAVIGATION_HISTORY_FORWARD
|
ACTION__NAVIGATION_HISTORY_FORWARD
|
||||||
);
|
);
|
||||||
|
|
@ -135,6 +136,13 @@ int Navigation::restore(
|
||||||
while (sqlite3_step(statement) == SQLITE_ROW)
|
while (sqlite3_step(statement) == SQLITE_ROW)
|
||||||
{
|
{
|
||||||
// Restore children components
|
// Restore children components
|
||||||
|
navigationHistory->restore(
|
||||||
|
sqlite3_column_int64(
|
||||||
|
statement,
|
||||||
|
DB::SESSION::ID
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
navigationRequest->restore(
|
navigationRequest->restore(
|
||||||
sqlite3_column_int64(
|
sqlite3_column_int64(
|
||||||
statement,
|
statement,
|
||||||
|
|
@ -149,13 +157,33 @@ int Navigation::restore(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Navigation::save(
|
void Navigation::save(
|
||||||
const sqlite3_int64 & APP_BROWSER_MAIN_TAB_PAGE__SESSION__ID
|
const sqlite3_int64 & APP_BROWSER_MAIN_TAB_PAGE__SESSION__ID
|
||||||
) {
|
) {
|
||||||
return navigationRequest->save(
|
// Delete previous session
|
||||||
|
DB::SESSION::clean(
|
||||||
|
db,
|
||||||
|
APP_BROWSER_MAIN_TAB_PAGE__SESSION__ID
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create new record
|
||||||
|
const sqlite3_int64 APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID = DB::SESSION::add(
|
||||||
|
db,
|
||||||
|
APP_BROWSER_MAIN_TAB_PAGE__SESSION__ID
|
||||||
|
);
|
||||||
|
|
||||||
|
// Delegate save action to children components
|
||||||
|
navigationHistory->save(
|
||||||
DB::SESSION::add(
|
DB::SESSION::add(
|
||||||
db,
|
db,
|
||||||
APP_BROWSER_MAIN_TAB_PAGE__SESSION__ID
|
APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
navigationRequest->save(
|
||||||
|
DB::SESSION::add(
|
||||||
|
db,
|
||||||
|
APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -275,7 +303,8 @@ int Navigation::DB::SESSION::clean(
|
||||||
db,
|
db,
|
||||||
Glib::ustring::sprintf(
|
Glib::ustring::sprintf(
|
||||||
R"SQL(
|
R"SQL(
|
||||||
SELECT * FROM `app_browser_main_tab_page_navigation__session` WHERE `app_browser_main_tab_page__session__id` = %d
|
SELECT * FROM `app_browser_main_tab_page_navigation__session`
|
||||||
|
WHERE `app_browser_main_tab_page__session__id` = %d
|
||||||
)SQL",
|
)SQL",
|
||||||
APP_BROWSER_MAIN_TAB_PAGE__SESSION__ID
|
APP_BROWSER_MAIN_TAB_PAGE__SESSION__ID
|
||||||
).c_str(),
|
).c_str(),
|
||||||
|
|
|
||||||
|
|
@ -94,11 +94,11 @@ namespace app::browser::main::tab::page
|
||||||
);
|
);
|
||||||
|
|
||||||
int restore(
|
int restore(
|
||||||
const sqlite3_int64 & APP_BROWSER_MAIN_TAB__SESSION__ID
|
const sqlite3_int64 & APP_BROWSER_MAIN_TAB_PAGE__SESSION__ID
|
||||||
); // return sqlite3_finalize status code
|
); // return sqlite3_finalize status code
|
||||||
|
|
||||||
int save(
|
void save(
|
||||||
const sqlite3_int64 & APP_BROWSER_MAIN_TAB__SESSION__ID
|
const sqlite3_int64 & APP_BROWSER_MAIN_TAB_PAGE__SESSION__ID
|
||||||
);
|
);
|
||||||
|
|
||||||
void history_add(
|
void history_add(
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,16 @@
|
||||||
using namespace app::browser::main::tab::page::navigation;
|
using namespace app::browser::main::tab::page::navigation;
|
||||||
|
|
||||||
History::History(
|
History::History(
|
||||||
|
sqlite3 * db,
|
||||||
const Glib::RefPtr<Gio::SimpleAction> & ACTION__HISTORY_BACK,
|
const Glib::RefPtr<Gio::SimpleAction> & ACTION__HISTORY_BACK,
|
||||||
const Glib::RefPtr<Gio::SimpleAction> & ACTION__HISTORY_FORWARD
|
const Glib::RefPtr<Gio::SimpleAction> & ACTION__HISTORY_FORWARD
|
||||||
) {
|
) {
|
||||||
|
// Init database
|
||||||
|
DB::SESSION::init(
|
||||||
|
this->db = db
|
||||||
|
);
|
||||||
|
|
||||||
|
// Init widget
|
||||||
add_css_class(
|
add_css_class(
|
||||||
"linked" // merge children elements
|
"linked" // merge children elements
|
||||||
);
|
);
|
||||||
|
|
@ -30,6 +37,106 @@ History::History(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
|
void History::add(
|
||||||
|
const Glib::ustring & REQUEST,
|
||||||
|
const bool & UPDATE_MEMORY_INDEX
|
||||||
|
) {
|
||||||
|
memory.push_back(
|
||||||
|
{
|
||||||
|
REQUEST,
|
||||||
|
std::time(
|
||||||
|
nullptr
|
||||||
|
)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (UPDATE_MEMORY_INDEX)
|
||||||
|
{
|
||||||
|
index = memory.size() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int History::restore(
|
||||||
|
const sqlite3_int64 & APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID
|
||||||
|
) {
|
||||||
|
sqlite3_stmt* statement; // @TODO move to the DB model namespace
|
||||||
|
|
||||||
|
const int PREPARE_STATUS = sqlite3_prepare_v3(
|
||||||
|
db,
|
||||||
|
Glib::ustring::sprintf(
|
||||||
|
R"SQL(
|
||||||
|
SELECT * FROM `app_browser_main_tab_page_navigation_history__session`
|
||||||
|
WHERE `app_browser_main_tab_page_navigation__session__id` = %d
|
||||||
|
ORDER BY `id` DESC LIMIT 1
|
||||||
|
)SQL",
|
||||||
|
APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID
|
||||||
|
).c_str(),
|
||||||
|
-1,
|
||||||
|
SQLITE_PREPARE_NORMALIZE,
|
||||||
|
&statement,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
if (PREPARE_STATUS == SQLITE_OK)
|
||||||
|
{
|
||||||
|
// Use latest record as order
|
||||||
|
while (sqlite3_step(statement) == SQLITE_ROW)
|
||||||
|
{
|
||||||
|
// Cleanup
|
||||||
|
memory.clear();
|
||||||
|
|
||||||
|
// Restore
|
||||||
|
memory.push_back(
|
||||||
|
{
|
||||||
|
reinterpret_cast<const char*>(
|
||||||
|
sqlite3_column_text(
|
||||||
|
statement,
|
||||||
|
DB::SESSION::REQUEST
|
||||||
|
)
|
||||||
|
),
|
||||||
|
sqlite3_column_int(
|
||||||
|
statement,
|
||||||
|
DB::SESSION::TIME
|
||||||
|
)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (sqlite3_column_int(statement, DB::SESSION::IS_CURRENT) == 1)
|
||||||
|
{
|
||||||
|
index = memory.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore children components here (on available)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sqlite3_finalize(
|
||||||
|
statement
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void History::save(
|
||||||
|
const sqlite3_int64 & APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID
|
||||||
|
) {
|
||||||
|
// Delete previous records for session
|
||||||
|
DB::SESSION::clean(
|
||||||
|
db,
|
||||||
|
APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add new records
|
||||||
|
for (const auto & VALUE : memory)
|
||||||
|
{
|
||||||
|
DB::SESSION::add(
|
||||||
|
db,
|
||||||
|
APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID,
|
||||||
|
VALUE.time,
|
||||||
|
VALUE.request,
|
||||||
|
-1 == index // @TODO
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void History::update()
|
void History::update()
|
||||||
{
|
{
|
||||||
Memory match;
|
Memory match;
|
||||||
|
|
@ -49,26 +156,6 @@ void History::update()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::add(
|
|
||||||
const Glib::ustring & REQUEST,
|
|
||||||
const bool & UPDATE_MEMORY_INDEX
|
|
||||||
) {
|
|
||||||
memory.push_back(
|
|
||||||
{
|
|
||||||
REQUEST,
|
|
||||||
std::time(
|
|
||||||
nullptr
|
|
||||||
),
|
|
||||||
true
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (UPDATE_MEMORY_INDEX)
|
|
||||||
{
|
|
||||||
index = memory.size() - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool History::try_back(
|
bool History::try_back(
|
||||||
Memory & match,
|
Memory & match,
|
||||||
const bool & UPDATE_MEMORY_INDEX
|
const bool & UPDATE_MEMORY_INDEX
|
||||||
|
|
@ -115,4 +202,123 @@ bool History::try_forward(
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Database model
|
||||||
|
int History::DB::SESSION::init(
|
||||||
|
sqlite3 * db
|
||||||
|
) {
|
||||||
|
char * error;
|
||||||
|
|
||||||
|
return sqlite3_exec(
|
||||||
|
db,
|
||||||
|
R"SQL(
|
||||||
|
CREATE TABLE IF NOT EXISTS `app_browser_main_tab_page_navigation_history__session`
|
||||||
|
(
|
||||||
|
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `app_browser_main_tab_page_navigation__session__id` INTEGER NOT NULL,
|
||||||
|
`time` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`request` VARCHAR (1024) NOT NULL,
|
||||||
|
`is_current` INTEGER NOT NULL
|
||||||
|
)
|
||||||
|
)SQL",
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
int History::DB::SESSION::clean(
|
||||||
|
sqlite3 * db,
|
||||||
|
const sqlite3_int64 & APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID
|
||||||
|
) {
|
||||||
|
char * error; // @TODO
|
||||||
|
sqlite3_stmt * statement;
|
||||||
|
|
||||||
|
const int PREPARE_STATUS = sqlite3_prepare_v3(
|
||||||
|
db,
|
||||||
|
Glib::ustring::sprintf(
|
||||||
|
R"SQL(
|
||||||
|
SELECT * FROM `app_browser_main_tab_page_navigation_history__session`
|
||||||
|
WHERE `app_browser_main_tab_page_navigation__session__id` = %d
|
||||||
|
)SQL",
|
||||||
|
APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID
|
||||||
|
).c_str(),
|
||||||
|
-1,
|
||||||
|
SQLITE_PREPARE_NORMALIZE,
|
||||||
|
&statement,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
if (PREPARE_STATUS == SQLITE_OK)
|
||||||
|
{
|
||||||
|
while (sqlite3_step(statement) == SQLITE_ROW)
|
||||||
|
{
|
||||||
|
// Delete record
|
||||||
|
const int EXEC_STATUS = sqlite3_exec(
|
||||||
|
db,
|
||||||
|
Glib::ustring::sprintf(
|
||||||
|
R"SQL(
|
||||||
|
DELETE FROM `app_browser_main_tab_page_navigation_history__session` WHERE `id` = %d
|
||||||
|
)SQL",
|
||||||
|
sqlite3_column_int64(
|
||||||
|
statement,
|
||||||
|
DB::SESSION::ID
|
||||||
|
)
|
||||||
|
).c_str(),
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
|
||||||
|
// Delegate children dependencies cleanup
|
||||||
|
if (EXEC_STATUS == SQLITE_OK)
|
||||||
|
{
|
||||||
|
// nothing here.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sqlite3_finalize(
|
||||||
|
statement
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_int64 History::DB::SESSION::add(
|
||||||
|
sqlite3 * db,
|
||||||
|
const sqlite3_int64 & APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID,
|
||||||
|
const int & TIME,
|
||||||
|
const Glib::ustring & REQUEST,
|
||||||
|
const bool & IS_CURRENT
|
||||||
|
) {
|
||||||
|
char * error; // @TODO
|
||||||
|
|
||||||
|
sqlite3_exec(
|
||||||
|
db,
|
||||||
|
Glib::ustring::sprintf(
|
||||||
|
R"SQL(
|
||||||
|
INSERT INTO `app_browser_main_tab_page_navigation_history__session` (
|
||||||
|
`app_browser_main_tab_page_navigation__session__id`,
|
||||||
|
`time`,
|
||||||
|
`request`,
|
||||||
|
`is_current`
|
||||||
|
) VALUES (
|
||||||
|
'%d',
|
||||||
|
'%d',
|
||||||
|
'%s',
|
||||||
|
'%d'
|
||||||
|
)
|
||||||
|
)SQL",
|
||||||
|
APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID,
|
||||||
|
TIME,
|
||||||
|
REQUEST,
|
||||||
|
IS_CURRENT
|
||||||
|
).c_str(),
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
|
||||||
|
return sqlite3_last_insert_rowid(
|
||||||
|
db
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include <glibmm/ustring.h>
|
#include <glibmm/ustring.h>
|
||||||
#include <gtkmm/box.h>
|
#include <gtkmm/box.h>
|
||||||
#include <gtkmm/object.h>
|
#include <gtkmm/object.h>
|
||||||
|
#include <sqlite3.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace app::browser::main::tab::page::navigation
|
namespace app::browser::main::tab::page::navigation
|
||||||
|
|
@ -20,26 +21,77 @@ namespace app::browser::main::tab::page::navigation
|
||||||
|
|
||||||
class History : public Gtk::Box
|
class History : public Gtk::Box
|
||||||
{
|
{
|
||||||
// Components
|
private:
|
||||||
history::Back * historyBack;
|
/*
|
||||||
history::Forward * historyForward;
|
* History class database
|
||||||
|
*
|
||||||
|
* Allowed parental access to enums and relationship methods
|
||||||
|
*/
|
||||||
|
struct DB
|
||||||
|
{
|
||||||
|
// APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION_REQUEST__*
|
||||||
|
struct SESSION
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ID,
|
||||||
|
APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID,
|
||||||
|
TIME,
|
||||||
|
REQUEST,
|
||||||
|
IS_CURRENT
|
||||||
|
}; // table fields index
|
||||||
|
|
||||||
int index = -1;
|
static int init(
|
||||||
|
sqlite3 * db
|
||||||
|
); // return sqlite3_exec status code
|
||||||
|
|
||||||
|
static int clean(
|
||||||
|
sqlite3 * db,
|
||||||
|
const sqlite3_int64 & APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID
|
||||||
|
); // return sqlite3_finalize status code
|
||||||
|
|
||||||
|
static sqlite3_int64 add(
|
||||||
|
sqlite3 * db,
|
||||||
|
const sqlite3_int64 & APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID,
|
||||||
|
const int & TIME,
|
||||||
|
const Glib::ustring & REQUEST,
|
||||||
|
const bool & IS_CURRENT
|
||||||
|
); // return sqlite3_last_insert_rowid
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal members
|
||||||
|
*/
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Database
|
||||||
|
sqlite3 * db;
|
||||||
|
|
||||||
|
// Components
|
||||||
|
history::Back * historyBack;
|
||||||
|
history::Forward * historyForward;
|
||||||
|
|
||||||
|
// Extras
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* History class API
|
||||||
|
*/
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Extras
|
// Extras
|
||||||
struct Memory
|
struct Memory
|
||||||
{
|
{
|
||||||
Glib::ustring request;
|
Glib::ustring request;
|
||||||
std::time_t time; // event unix time
|
std::time_t time; // event unix time
|
||||||
bool permanent; // save in database (on application close) @TODO
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Define navigation history storage
|
// Define navigation history storage
|
||||||
std::vector<Memory> memory;
|
std::vector<Memory> memory;
|
||||||
|
|
||||||
History(
|
History(
|
||||||
|
sqlite3 * db,
|
||||||
const Glib::RefPtr<Gio::SimpleAction> & ACTION__HISTORY_BACK,
|
const Glib::RefPtr<Gio::SimpleAction> & ACTION__HISTORY_BACK,
|
||||||
const Glib::RefPtr<Gio::SimpleAction> & ACTION__HISTORY_FORWARD
|
const Glib::RefPtr<Gio::SimpleAction> & ACTION__HISTORY_FORWARD
|
||||||
);
|
);
|
||||||
|
|
@ -50,9 +102,15 @@ namespace app::browser::main::tab::page::navigation
|
||||||
const bool & UPDATE_MEMORY_INDEX
|
const bool & UPDATE_MEMORY_INDEX
|
||||||
);
|
);
|
||||||
|
|
||||||
void update();
|
int restore(
|
||||||
|
const sqlite3_int64 & APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID
|
||||||
|
); // return sqlite3_finalize status code
|
||||||
|
|
||||||
void save(); // @TODO save history to the permanent storage
|
void save(
|
||||||
|
const sqlite3_int64 & APP_BROWSER_MAIN_TAB_PAGE_NAVIGATION__SESSION__ID
|
||||||
|
);
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
bool try_back(
|
bool try_back(
|
||||||
Memory & match,
|
Memory & match,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue