#include "tab.hpp" #include "tab/label.hpp" #include "tab/page.hpp" using namespace app::browser::main; Tab::Tab( sqlite3 * db, const Glib::RefPtr & ACTION__REFRESH, const Glib::RefPtr & ACTION__TAB_CLOSE_ACTIVE, const Glib::RefPtr & ACTION__MAIN_TAB_CLOSE_ALL, const Glib::RefPtr & ACTION__TAB_PAGE_NAVIGATION_HISTORY_BACK, const Glib::RefPtr & ACTION__TAB_PAGE_NAVIGATION_HISTORY_FORWARD, const Glib::RefPtr & ACTION__TAB_PAGE_NAVIGATION_UPDATE ) { // Init database this->db = db; char * error; ::sqlite3_exec( db, R"SQL( CREATE TABLE IF NOT EXISTS `app_browser_main_tab` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `time` INTEGER NOT NULL, `number` INTEGER NOT NULL, `current` INTEGER NOT NULL, `request` VARCHAR(1024) ) )SQL", nullptr, nullptr, &error ); // Init actions action__refresh = ACTION__REFRESH; action__tab_close_active = ACTION__TAB_CLOSE_ACTIVE; action__tab_close_all = ACTION__MAIN_TAB_CLOSE_ALL; action__tab_page_navigation_history_back = ACTION__TAB_PAGE_NAVIGATION_HISTORY_BACK; action__tab_page_navigation_history_forward = ACTION__TAB_PAGE_NAVIGATION_HISTORY_FORWARD; action__tab_page_navigation_update = ACTION__TAB_PAGE_NAVIGATION_UPDATE; // Init widget set_scrollable( SCROLLABLE ); // Init events signal_realize().connect( [this] { // Restore session from DB sqlite3_stmt* statement; const int PREPARE = ::sqlite3_prepare_v3( this->db, R"SQL( SELECT * FROM `app_browser_main_tab` ORDER BY `number` ASC )SQL", -1, SQLITE_PREPARE_NORMALIZE, &statement, nullptr ); if (PREPARE == SQLITE_OK) { while (::sqlite3_step(statement) == SQLITE_ROW) { const int PAGE_NUMBER = append(); get_tabPage( PAGE_NUMBER )->set_navbar_request_text( reinterpret_cast( ::sqlite3_column_text( statement, DB::APP_BROWSER_MAIN_TAB::REQUEST ) ) ); if (::sqlite3_column_int(statement, DB::APP_BROWSER_MAIN_TAB::CURRENT) == 1) { set_current_page( PAGE_NUMBER ); } } } sqlite3_finalize( statement ); } ); signal_switch_page().connect( [this](Gtk::Widget*, guint) { // Refresh window elements, e.g. tab label to header bar action__refresh->activate(); } ); } void Tab::save() { char * error; // @TODO // Delete previous tab session ::sqlite3_exec( db, R"SQL( DELETE FROM `app_browser_main_tab` )SQL", nullptr, nullptr, &error ); // Save current tab session for (int page_number = 0; page_number < get_n_pages(); page_number++) { auto tabPage = get_tabPage( page_number ); ::sqlite3_exec( db, Glib::ustring::sprintf( R"SQL( INSERT INTO `app_browser_main_tab` ( `time`, `number`, `current`, `request` ) VALUES ( CURRENT_TIMESTAMP, '%d', '%d', '%s' ) )SQL", page_number, page_number == get_current_page() ? 1 : 0, tabPage->get_navigation_request_text() ).c_str(), nullptr, nullptr, &error ); } } void Tab::shutdown() { save(); // @TODO shutdown children components } // Actions void Tab::refresh( const int & PAGE_NUMBER ) { const auto TAB_PAGE = get_tabPage( PAGE_NUMBER ); get_tabLabel( PAGE_NUMBER )->set_label( TAB_PAGE->get_title() ); TAB_PAGE->refresh( TAB_PAGE->get_title(), TAB_PAGE->get_subtitle(), 0 // @TODO ); action__tab_close_active->set_enabled( get_n_pages() > 0 ); action__tab_close_all->set_enabled( get_n_pages() > 0 ); } int Tab::append() { const auto TAB_PAGE = new tab::Page( action__refresh, action__tab_page_navigation_history_back, action__tab_page_navigation_history_forward, action__tab_page_navigation_update ); const auto TAB_LABEL = new tab::Label( action__tab_close_active ); const int PAGE_NUMBER = append_page( * TAB_PAGE, * TAB_LABEL ); set_tab_reorderable( * TAB_PAGE, REORDERABLE ); refresh( PAGE_NUMBER ); return PAGE_NUMBER; }; void Tab::close( const int & PAGE_NUMBER ) { remove_page( PAGE_NUMBER ); // @TODO cleanup memory ot use managed children widgets // @TODO fix GtkGizmo reported min height, but sizes must be >= 0 } void Tab::close_left() {} // @TODO void Tab::close_right() {} // @TODO void Tab::close_all() { while (0 <= get_current_page()) { close( -1 // last ); } } void Tab::page_navigation_update( const int & PAGE_NUMBER, const bool & ADD_HISTORY ) { get_tabPage( PAGE_NUMBER )->navigation_update( ADD_HISTORY ); } void Tab::page_navigation_history_back( const int & PAGE_NUMBER ) { get_tabPage( PAGE_NUMBER )->navigation_history_back(); } void Tab::page_navigation_history_forward( const int & PAGE_NUMBER ) { get_tabPage( PAGE_NUMBER )->navigation_history_forward(); } // Getters Glib::ustring Tab::get_page_title( const int & PAGE_NUMBER ) { return get_tabPage( PAGE_NUMBER )->get_title(); }; Glib::ustring Tab::get_page_subtitle( const int & PAGE_NUMBER ) { return get_tabPage( PAGE_NUMBER )->get_subtitle(); }; // Private helpers tab::Label * Tab::get_tabLabel( const int & PAGE_NUMBER ) { // Get page pointer to find label widget const auto PAGE = get_nth_page( PAGE_NUMBER ); if (PAGE == nullptr) { throw _("Page not found!"); // @TODO } // Get label widget by page pointer const auto LABEL = get_tab_label( * PAGE ); if (LABEL == nullptr) { throw _("Label not found!"); // @TODO } // Downcast const auto TAB_LABEL = dynamic_cast( LABEL ); if (TAB_LABEL == nullptr) { throw _("Tab label not found!"); // @TODO } return TAB_LABEL; } tab::Page * Tab::get_tabPage( const int & PAGE_NUMBER ) { // Get page widget const auto PAGE = get_nth_page( PAGE_NUMBER ); if (PAGE == nullptr) { throw _("Page not found!"); // @TODO } // Downcast const auto TAB_PAGE = dynamic_cast( PAGE ); if (TAB_PAGE == nullptr) { throw _("Tab page not found!"); // @TODO } return TAB_PAGE; }