Yoda/src/app/browser.cpp

451 lines
9.7 KiB
C++
Raw Normal View History

#include "browser.hpp"
#include "browser/header.hpp"
2024-08-11 22:04:34 +03:00
#include "browser/main.hpp"
2024-08-05 03:15:41 +03:00
2024-08-08 12:44:27 +03:00
using namespace app;
2024-08-05 03:15:41 +03:00
2024-08-11 09:55:10 +03:00
Browser::Browser(
2024-09-09 05:06:36 +03:00
sqlite3 * db,
2024-09-08 08:15:17 +03:00
const Glib::RefPtr<Gtk::Application> & APP
2024-08-11 09:55:10 +03:00
) {
// Init database
DB::SESSION::init(
this->db = db
);
2024-09-08 02:09:54 +03:00
// Init window actions
2024-09-11 07:49:01 +03:00
const auto ACTION__UPDATE = add_action(
"update",
2024-08-16 19:45:42 +03:00
[this]
{
2024-09-11 02:34:02 +03:00
browserMain->update();
2024-08-11 09:55:10 +03:00
2024-09-11 02:34:02 +03:00
browserHeader->update(
2024-09-12 05:54:59 +03:00
browserMain->get_tab_page_title(),
browserMain->get_tab_page_description()
2024-09-05 16:40:41 +03:00
);
2024-08-16 19:45:42 +03:00
}
2024-08-14 07:11:24 +03:00
);
2024-09-11 08:00:47 +03:00
const auto ACTION__CLEAN = add_action(
"clean",
[this]
{
clean();
2024-09-11 08:00:47 +03:00
}
);
2024-09-10 03:23:29 +03:00
const auto ACTION__RESTORE = add_action(
"restore",
[this]
{
restore();
2024-09-10 03:23:29 +03:00
}
);
const auto ACTION__SAVE = add_action(
"save",
[this]
{
save();
2024-09-10 03:23:29 +03:00
}
);
2024-09-08 17:48:19 +03:00
const auto ACTION__DEBUG = add_action(
2024-09-05 16:40:41 +03:00
"debug",
2024-08-16 19:45:42 +03:00
[this]
{
2024-09-05 16:40:41 +03:00
// @TODO https://gitlab.gnome.org/GNOME/gtkmm/-/commit/5f3b82537d3daad7bda59dd01e719788070f4b6c
gtk_window_set_interactive_debugging(
true
);
2024-08-16 19:45:42 +03:00
}
2024-08-12 19:11:00 +03:00
);
2024-09-08 08:15:17 +03:00
APP->set_accel_for_action(
"win.debug",
"<Primary>i"
2024-08-12 20:24:06 +03:00
);
2024-09-08 17:48:19 +03:00
const auto ACTION__MAIN_TAB_APPEND = add_action(
2024-09-08 08:15:17 +03:00
"main_tab_append",
[this]
{
browserMain->tab_append();
}
);
APP->set_accel_for_action(
"win.main_tab_append",
"<Primary>t"
2024-08-12 20:24:06 +03:00
);
2024-09-08 17:58:40 +03:00
const auto ACTION__MAIN_TAB_CLOSE_ACTIVE = add_action(
"main_tab_close_active",
2024-09-08 08:15:17 +03:00
[this]
{
browserMain->tab_close();
}
);
ACTION__MAIN_TAB_CLOSE_ACTIVE->set_enabled(
false
);
APP->set_accel_for_action(
"win.main_tab_close_active",
"<Primary>Escape"
);
2024-09-08 08:15:17 +03:00
add_action(
"main_tab_close_left",
[this]
{
browserMain->tab_close_left();
}
)->set_enabled(
false
);
add_action(
"main_tab_close_right",
[this]
{
browserMain->tab_close_right();
}
)->set_enabled(
false
);
2024-09-08 17:58:40 +03:00
const auto ACTION__MAIN_TAB_CLOSE_ALL = add_action(
2024-09-08 08:15:17 +03:00
"main_tab_close_all",
[this]
{
browserMain->tab_close_all();
}
);
2024-09-08 17:58:40 +03:00
ACTION__MAIN_TAB_CLOSE_ALL->set_enabled(
false
);
const auto ACTION__MAIN_TAB_PAGE_NAVIGATION_RELOAD = add_action(
"main_tab_page_navigation_reload",
2024-09-08 08:18:23 +03:00
[this]
{
browserMain->tab_page_navigation_reload();
2024-09-08 08:18:23 +03:00
}
);
ACTION__MAIN_TAB_PAGE_NAVIGATION_RELOAD->set_enabled(
2024-09-08 08:18:23 +03:00
false
2024-08-12 20:24:06 +03:00
);
2024-09-08 08:18:23 +03:00
APP->set_accel_for_action(
"win.main_tab_page_navigation_reload",
2024-09-08 08:18:23 +03:00
"<Primary>r"
);
2024-09-08 08:15:17 +03:00
2024-09-08 08:18:23 +03:00
const auto ACTION__MAIN_TAB_PAGE_NAVIGATION_HISTORY_BACK = add_action(
"main_tab_page_navigation_history_back",
[this]
{
browserMain->tab_page_navigation_history_back();
}
);
2024-09-08 08:15:17 +03:00
2024-09-08 08:18:23 +03:00
ACTION__MAIN_TAB_PAGE_NAVIGATION_HISTORY_BACK->set_enabled(
false
2024-09-05 02:31:23 +03:00
);
2024-09-08 08:18:23 +03:00
APP->set_accel_for_action(
"win.main_tab_page_navigation_history_back",
"<Primary>Left"
);
2024-09-08 08:15:17 +03:00
2024-09-08 08:18:23 +03:00
const auto ACTION__MAIN_TAB_PAGE_NAVIGATION_HISTORY_FORWARD = add_action(
"main_tab_page_navigation_history_forward",
[this]
{
browserMain->tab_page_navigation_history_forward();
}
);
2024-09-08 08:15:17 +03:00
2024-09-08 08:18:23 +03:00
ACTION__MAIN_TAB_PAGE_NAVIGATION_HISTORY_FORWARD->set_enabled(
false
2024-09-05 02:31:23 +03:00
);
2024-09-08 08:18:23 +03:00
APP->set_accel_for_action(
"win.main_tab_page_navigation_history_forward",
"<Primary>Right"
);
2024-09-08 02:09:54 +03:00
const auto ACTION__QUIT = add_action(
"quit",
[this]
{
close();
}
);
APP->set_accel_for_action(
"win.quit",
"<Primary>q"
);
2024-09-08 02:09:54 +03:00
// Init widget
set_title(
_("Yoda")
);
set_default_size(
WIDTH,
HEIGHT
);
2024-09-08 08:18:23 +03:00
// Init components
2024-09-08 17:48:19 +03:00
browserHeader = Gtk::make_managed<browser::Header>(
ACTION__DEBUG,
ACTION__QUIT,
2024-09-11 08:00:47 +03:00
ACTION__CLEAN,
2024-09-10 03:23:29 +03:00
ACTION__RESTORE,
ACTION__SAVE,
2024-09-08 17:48:19 +03:00
ACTION__MAIN_TAB_APPEND,
2024-09-08 17:58:40 +03:00
ACTION__MAIN_TAB_CLOSE_ACTIVE,
ACTION__MAIN_TAB_CLOSE_ALL,
2024-09-08 17:48:19 +03:00
ACTION__MAIN_TAB_PAGE_NAVIGATION_HISTORY_BACK,
ACTION__MAIN_TAB_PAGE_NAVIGATION_HISTORY_FORWARD,
ACTION__MAIN_TAB_PAGE_NAVIGATION_RELOAD
2024-09-08 17:48:19 +03:00
);
2024-09-08 02:09:54 +03:00
2024-09-08 08:18:23 +03:00
set_titlebar(
* browserHeader
);
2024-09-08 02:09:54 +03:00
2024-09-08 03:49:08 +03:00
browserMain = Gtk::make_managed<browser::Main>(
db,
2024-09-11 07:49:01 +03:00
ACTION__UPDATE,
2024-09-08 17:58:40 +03:00
ACTION__MAIN_TAB_CLOSE_ACTIVE,
ACTION__MAIN_TAB_CLOSE_ALL,
2024-09-08 03:49:08 +03:00
ACTION__MAIN_TAB_PAGE_NAVIGATION_HISTORY_BACK,
2024-09-08 04:20:25 +03:00
ACTION__MAIN_TAB_PAGE_NAVIGATION_HISTORY_FORWARD,
ACTION__MAIN_TAB_PAGE_NAVIGATION_RELOAD
2024-09-08 03:49:08 +03:00
);
2024-09-08 02:09:54 +03:00
2024-09-08 08:18:23 +03:00
set_child(
* browserMain
);
// Connect signals
signal_realize().connect(
[this]
{
restore(); // last session from DB
}
);
signal_close_request().connect(
[this]
{
save();
2024-09-09 10:58:12 +03:00
// @TODO sqlite3_close(db);
return false;
},
true
);
}
// Actions
int Browser::restore()
{
sqlite3_stmt* statement; // @TODO move to the DB model namespace
const int PREPARE_STATUS = sqlite3_prepare_v3(
db,
R"SQL(
SELECT * FROM `app_browser__session` ORDER BY `page_number` ASC
)SQL",
-1,
SQLITE_PREPARE_NORMALIZE,
&statement,
nullptr
);
if (PREPARE_STATUS == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
// Restore widget settings
set_default_size( // @TODO actualize
sqlite3_column_int(
statement,
DB::SESSION::WIDTH
),
sqlite3_column_int(
statement,
DB::SESSION::HEIGHT
)
);
// Restore children components
browserMain->restore(
sqlite3_column_int(
statement,
DB::SESSION::ID
)
);
}
}
return sqlite3_finalize(
statement
);
}
void Browser::clean()
{
DB::SESSION::clean(
db
);
}
void Browser::save()
{
char * error; // @TODO
// Delete previous data
DB::SESSION::clean(
db
); // @TODO run on background
// Create new session
const sqlite3_int64 APP_BROWSER__SESSION__ID = DB::SESSION::add(
db,
get_width(),
get_height(),
false // @TODO full screen status
);
// Delegate save actions to children components
browserMain->save(
APP_BROWSER__SESSION__ID
);
}
// Database
int Browser::DB::SESSION::init(
sqlite3 * db
) {
char * error;
return sqlite3_exec(
db,
R"SQL(
CREATE TABLE IF NOT EXISTS `app_browser__session`
(
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
`time` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP,
`width` INTEGER NOT NULL,
`height` INTEGER NOT NULL,
`is_full_screen` INTEGER NOT NULL
)
)SQL",
nullptr,
nullptr,
&error
);
}
int Browser::DB::SESSION::clean(
sqlite3 * db
) {
char * error; // @TODO
sqlite3_stmt * statement;
const int PREPARE_STATUS = sqlite3_prepare_v3(
db,
R"SQL(
SELECT * FROM `app_browser__session`
)SQL",
-1,
SQLITE_PREPARE_NORMALIZE,
&statement,
nullptr
);
if (PREPARE_STATUS == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
const sqlite3_int64 APP_BROWSER__SESSION__ID = sqlite3_column_int64(
statement,
DB::SESSION::ID
);
// Delete record
const int EXEC_STATUS = sqlite3_exec(
db,
Glib::ustring::sprintf(
R"SQL(
DELETE FROM `app_browser__session` WHERE `id` = %d
)SQL",
APP_BROWSER__SESSION__ID
).c_str(),
nullptr,
nullptr,
&error
);
// Delegate children dependencies cleanup
if (EXEC_STATUS == SQLITE_OK)
{
browser::Main::DB::SESSION::clean(
db,
APP_BROWSER__SESSION__ID
);
}
}
}
return sqlite3_finalize(
statement
);
}
sqlite3_int64 Browser::DB::SESSION::add(
sqlite3 * db,
const int & WIDTH,
const int & HEIGHT,
const bool & IS_FULL_SCREEN
) {
char * error; // @TODO
sqlite3_exec(
db,
Glib::ustring::sprintf(
R"SQL(
INSERT INTO `app_browser__session` (
`width`,
`height`,
`is_full_screen`
) VALUES (
%d,
%d,
%d
)
)SQL",
WIDTH,
HEIGHT,
IS_FULL_SCREEN ? 1 : 0
).c_str(),
nullptr,
nullptr,
&error
);
return sqlite3_last_insert_rowid(
db
);
2024-08-16 19:45:42 +03:00
}