Browse Source

implement browser, main widget db session

CPP-GTK4
yggverse 1 week ago
parent
commit
c13cc44a59
  1. 213
      src/app/browser.cpp
  2. 68
      src/app/browser.hpp
  3. 189
      src/app/browser/main.cpp
  4. 70
      src/app/browser/main.hpp
  5. 58
      src/app/browser/main/tab.cpp
  6. 14
      src/app/browser/main/tab.hpp

213
src/app/browser.cpp

@ -8,6 +8,11 @@ Browser::Browser(
sqlite3 * db, sqlite3 * db,
const Glib::RefPtr<Gtk::Application> & APP const Glib::RefPtr<Gtk::Application> & APP
) { ) {
// Init database
DB::SESSION::init(
this->db = db
);
// Init window actions // Init window actions
const auto ACTION__UPDATE = add_action( const auto ACTION__UPDATE = add_action(
"update", "update",
@ -26,7 +31,7 @@ Browser::Browser(
"clean", "clean",
[this] [this]
{ {
browserMain->clean(); clean();
} }
); );
@ -34,7 +39,7 @@ Browser::Browser(
"restore", "restore",
[this] [this]
{ {
browserMain->restore(); restore();
} }
); );
@ -42,7 +47,7 @@ Browser::Browser(
"save", "save",
[this] [this]
{ {
browserMain->save(); save();
} }
); );
@ -232,10 +237,17 @@ Browser::Browser(
); );
// Connect signals // Connect signals
signal_realize().connect(
[this]
{
restore(); // last session from DB
}
);
signal_close_request().connect( signal_close_request().connect(
[this] [this]
{ {
browserMain->save(); save();
// @TODO sqlite3_close(db); // @TODO sqlite3_close(db);
@ -244,3 +256,196 @@ Browser::Browser(
true 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
);
}

68
src/app/browser.hpp

@ -24,20 +24,76 @@ namespace app
class Browser : public Gtk::ApplicationWindow class Browser : public Gtk::ApplicationWindow
{ {
// Components public:
app::browser::Header * browserHeader;
app::browser::Main * browserMain; /*
* Tab class database
*
* Allowed parental access to enums and relationship methods
*/
struct DB
{
// APP_BROWSER_MAIN_TAB__*
struct SESSION
{
enum
{
ID,
TIME,
WIDTH,
HEIGHT,
IS_FULL_SCREEN
}; // table fields index
static int init(
sqlite3 * db
); // return sqlite3_exec status code
static int clean(
sqlite3 * db
); // return sqlite3_finalize status code
static sqlite3_int64 add(
sqlite3 * db,
const int & WIDTH,
const int & HEIGHT,
const bool & IS_FULL_SCREEN
); // return sqlite3_last_insert_rowid
};
};
/*
* Internal members
*/
private:
// Defaults // Database
const int WIDTH = 640; sqlite3 * db;
const int HEIGHT = 480;
// Components
app::browser::Header * browserHeader;
app::browser::Main * browserMain;
// Defaults
const int WIDTH = 640;
const int HEIGHT = 480;
/*
* Browser class API
*/
public: public:
Browser( Browser(
sqlite3 * db, sqlite3 * db,
const Glib::RefPtr<Gtk::Application> & APP const Glib::RefPtr<Gtk::Application> & APP
); );
// Actions
int restore(); // return sqlite3_finalize status code
void clean();
void save();
}; };
} }

189
src/app/browser/main.cpp

@ -12,6 +12,11 @@ Main::Main(
const Glib::RefPtr<Gio::SimpleAction> & ACTION__MAIN_TAB_PAGE_NAVIGATION_HISTORY_FORWARD, const Glib::RefPtr<Gio::SimpleAction> & ACTION__MAIN_TAB_PAGE_NAVIGATION_HISTORY_FORWARD,
const Glib::RefPtr<Gio::SimpleAction> & ACTION__MAIN_TAB_PAGE_NAVIGATION_RELOAD const Glib::RefPtr<Gio::SimpleAction> & ACTION__MAIN_TAB_PAGE_NAVIGATION_RELOAD
) { ) {
// Init database
DB::SESSION::init(
this->db = db
);
// Init widget // Init widget
set_orientation( set_orientation(
Gtk::Orientation::VERTICAL Gtk::Orientation::VERTICAL
@ -40,19 +45,73 @@ Main::Main(
// Actions // Actions
/// Session /// Session
void Main::clean() void Main::clean(
{ const sqlite3_int64 & APP_BROWSER__SESSION__ID
mainTab->clean(); ) {
DB::SESSION::clean(
db,
APP_BROWSER__SESSION__ID
);
mainTab->close_all();
}; };
void Main::restore() int Main::restore(
{ const sqlite3_int64 & APP_BROWSER__SESSION__ID
mainTab->restore(); ) {
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__session`
WHERE `app_browser__session_id` = %d
)SQL",
APP_BROWSER__SESSION__ID
).c_str(),
-1,
SQLITE_PREPARE_NORMALIZE,
&statement,
nullptr
);
if (PREPARE_STATUS == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
mainTab->restore(
DB::SESSION::ID
);
}
}
return sqlite3_finalize(
statement
);
}; };
void Main::save() void Main::save(
{ const sqlite3_int64 & APP_BROWSER__SESSION__ID
mainTab->save(); ) {
char * error; // @TODO
// Delete previous data
DB::SESSION::clean(
db,
APP_BROWSER__SESSION__ID
); // @TODO run on background
// Create new session
const sqlite3_int64 APP_BROWSER_MAIN__SESSION__ID = DB::SESSION::add(
db,
APP_BROWSER__SESSION__ID
);
// Delegate save actions to children components
mainTab->save(
APP_BROWSER_MAIN__SESSION__ID
);
}; };
/// Tab actions /// Tab actions
@ -131,3 +190,115 @@ Glib::ustring Main::get_tab_page_description()
mainTab->get_current_page() mainTab->get_current_page()
); );
}; };
// Database
int Main::DB::SESSION::init(
sqlite3 * db
) {
char * error;
return sqlite3_exec(
db,
R"SQL(
CREATE TABLE IF NOT EXISTS `app_browser_main__session`
(
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
`time` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP,
`app_browser__session__id` INTEGER NOT NULL
)
)SQL",
nullptr,
nullptr,
&error
);
}
int Main::DB::SESSION::clean(
sqlite3 * db,
const sqlite3_int64 & APP_BROWSER__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__session`
WHERE `app_browser__session__id` = %d
)SQL",
APP_BROWSER__SESSION__ID
).c_str(),
-1,
SQLITE_PREPARE_NORMALIZE,
&statement,
nullptr
);
if (PREPARE_STATUS == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
const sqlite3_int64 APP_BROWSER_MAIN__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_main__session` WHERE `id` = %d
)SQL",
APP_BROWSER_MAIN__SESSION__ID
).c_str(),
nullptr,
nullptr,
&error
);
// Delegate children dependencies cleanup
if (EXEC_STATUS == SQLITE_OK)
{
main::Tab::DB::SESSION::clean(
db,
APP_BROWSER_MAIN__SESSION__ID
);
}
}
}
return sqlite3_finalize(
statement
);
}
sqlite3_int64 Main::DB::SESSION::add(
sqlite3 * db,
const sqlite3_int64 & APP_BROWSER__SESSION__ID
) {
char * error; // @TODO
sqlite3_exec(
db,
Glib::ustring::sprintf(
R"SQL(
INSERT INTO `app_browser_main__session` (
`app_browser_main__session__id`
) VALUES (
%d
)
)SQL",
APP_BROWSER__SESSION__ID
).c_str(),
nullptr,
nullptr,
&error
);
return sqlite3_last_insert_rowid(
db
);
}

70
src/app/browser/main.hpp

@ -18,12 +18,58 @@ namespace app::browser
class Main : public Gtk::Box class Main : public Gtk::Box
{ {
// Components public:
main::Tab * mainTab;
/*
* Tab class database
*
* Allowed parental access to enums and relationship methods
*/
struct DB
{
// APP_BROWSER_MAIN__*
struct SESSION
{
enum
{
ID,
TIME
}; // table fields index
static int init(
sqlite3 * db
); // return sqlite3_exec status code
static int clean(
sqlite3 * db,
const sqlite3_int64 & APP_BROWSER__SESSION__ID
); // return sqlite3_finalize status code
static sqlite3_int64 add(
sqlite3 * db,
const sqlite3_int64 & APP_BROWSER__SESSION__ID
); // return sqlite3_last_insert_rowid
};
};
/*
* Internal members
*/
private:
// Database
sqlite3 * db;
// Defaults // Components
const bool HOMOGENEOUS = true; main::Tab * mainTab;
// Defaults
const bool HOMOGENEOUS = true;
/*
* Main class API
*/
public: public:
Main( Main(
@ -37,10 +83,6 @@ namespace app::browser
); );
// Actions // Actions
void clean();
void restore();
void save();
void tab_append(); void tab_append();
void tab_close_all(); void tab_close_all();
@ -52,6 +94,18 @@ namespace app::browser
void tab_page_navigation_history_back(); void tab_page_navigation_history_back();
void tab_page_navigation_history_forward(); void tab_page_navigation_history_forward();
int restore(
const sqlite3_int64 & APP_BROWSER__SESSION__ID
); // return sqlite3_finalize status code
void clean(
const sqlite3_int64 & APP_BROWSER__SESSION__ID
);
void save(
const sqlite3_int64 & APP_BROWSER__SESSION__ID
);
void update(); void update();
// Getters // Getters

58
src/app/browser/main/tab.cpp

@ -31,14 +31,6 @@ Tab::Tab(
SCROLLABLE SCROLLABLE
); );
// Init events
signal_realize().connect(
[this]
{
restore(); // last session from DB
}
);
signal_switch_page().connect( signal_switch_page().connect(
[this](Gtk::Widget*, guint) [this](Gtk::Widget*, guint)
{ {
@ -48,15 +40,20 @@ Tab::Tab(
); );
} }
int Tab::restore() int Tab::restore(
{ const sqlite3_int64 & APP_BROWSER_MAIN__SESSION__ID
) {
sqlite3_stmt* statement; // @TODO move to the DB model namespace sqlite3_stmt* statement; // @TODO move to the DB model namespace
const int PREPARE_STATUS = sqlite3_prepare_v3( const int PREPARE_STATUS = sqlite3_prepare_v3(
db, db,
R"SQL( Glib::ustring::sprintf(
SELECT * FROM `app_browser_main_tab__session` ORDER BY `page_number` ASC R"SQL(
)SQL", SELECT * FROM `app_browser_main_tab__session`
WHERE `app_browser_main__session_id` = %d ORDER BY `page_number` ASC
)SQL",
APP_BROWSER_MAIN__SESSION__ID
).c_str(),
-1, -1,
SQLITE_PREPARE_NORMALIZE, SQLITE_PREPARE_NORMALIZE,
&statement, &statement,
@ -103,22 +100,15 @@ int Tab::restore()
); );
} }
void Tab::clean() // @TODO menu action? void Tab::save(
{ const sqlite3_int64 & APP_BROWSER_MAIN__SESSION__ID
DB::SESSION::clean( ) {
db
);
close_all();
}
void Tab::save()
{
char * error; // @TODO char * error; // @TODO
// Delete previous data // Delete previous data
DB::SESSION::clean( DB::SESSION::clean(
db db,
APP_BROWSER_MAIN__SESSION__ID
); // @TODO run on background ); // @TODO run on background
// Save current tab session // Save current tab session
@ -127,6 +117,7 @@ void Tab::save()
// Create new session // Create new session
const sqlite3_int64 APP_BROWSER_MAIN_TAB__SESSION__ID = DB::SESSION::add( const sqlite3_int64 APP_BROWSER_MAIN_TAB__SESSION__ID = DB::SESSION::add(
db, db,
APP_BROWSER_MAIN__SESSION__ID,
page_number, page_number,
page_number == get_current_page() ? 1 : 0 page_number == get_current_page() ? 1 : 0
); );
@ -377,16 +368,21 @@ int Tab::DB::SESSION::init(
} }
int Tab::DB::SESSION::clean( int Tab::DB::SESSION::clean(
sqlite3 * db sqlite3 * db,
const sqlite3_int64 & APP_BROWSER_MAIN__SESSION__ID
) { ) {
char * error; // @TODO char * error; // @TODO
sqlite3_stmt * statement; sqlite3_stmt * statement;
const int PREPARE_STATUS = sqlite3_prepare_v3( const int PREPARE_STATUS = sqlite3_prepare_v3(
db, db,
R"SQL( Glib::ustring::sprintf(
SELECT * FROM `app_browser_main_tab__session` R"SQL(
)SQL", SELECT * FROM `app_browser_main_tab__session`
WHERE `app_browser_main_tab__session_id` = %d
)SQL",
APP_BROWSER_MAIN__SESSION__ID
).c_str(),
-1, -1,
SQLITE_PREPARE_NORMALIZE, SQLITE_PREPARE_NORMALIZE,
&statement, &statement,
@ -439,6 +435,7 @@ int Tab::DB::SESSION::clean(
sqlite3_int64 Tab::DB::SESSION::add( sqlite3_int64 Tab::DB::SESSION::add(
sqlite3 * db, sqlite3 * db,
const sqlite3_int64 & APP_BROWSER_MAIN__SESSION__ID,
const int & PAGE_NUMBER, const int & PAGE_NUMBER,
const bool & IS_CURRENT const bool & IS_CURRENT
) { ) {
@ -449,13 +446,16 @@ sqlite3_int64 Tab::DB::SESSION::add(
Glib::ustring::sprintf( Glib::ustring::sprintf(
R"SQL( R"SQL(
INSERT INTO `app_browser_main_tab__session` ( INSERT INTO `app_browser_main_tab__session` (
`app_browser_main__session_id`,
`page_number`, `page_number`,
`is_current` `is_current`
) VALUES ( ) VALUES (
%d,
%d, %d,
%d %d
) )
)SQL", )SQL",
APP_BROWSER_MAIN__SESSION__ID,
PAGE_NUMBER, PAGE_NUMBER,
IS_CURRENT IS_CURRENT
).c_str(), ).c_str(),

14
src/app/browser/main/tab.hpp

@ -43,11 +43,13 @@ namespace app::browser::main
); // return sqlite3_exec status code ); // return sqlite3_exec status code
static int clean( static int clean(
sqlite3 * db sqlite3 * db,
const sqlite3_int64 & APP_BROWSER_MAIN__SESSION__ID
); // return sqlite3_finalize status code ); // return sqlite3_finalize status code
static sqlite3_int64 add( static sqlite3_int64 add(
sqlite3 * db, sqlite3 * db,
const sqlite3_int64 & APP_BROWSER_MAIN__SESSION__ID,
const int & PAGE_NUMBER, const int & PAGE_NUMBER,
const bool & IS_CURRENT const bool & IS_CURRENT
); // return sqlite3_last_insert_rowid ); // return sqlite3_last_insert_rowid
@ -121,11 +123,13 @@ namespace app::browser::main
const int & PAGE_NUMBER const int & PAGE_NUMBER
); );
int restore(); // return sqlite3_finalize status code int restore(
const sqlite3_int64 & APP_BROWSER_MAIN__SESSION__ID
); // return sqlite3_finalize status code
void clean(); void save(
const sqlite3_int64 & APP_BROWSER_MAIN__SESSION__ID
void save(); );
// Getters // Getters
Glib::ustring get_page_title( Glib::ustring get_page_title(

Loading…
Cancel
Save