From 49ec6ee23d6aaed80e22c7a88caef6a8d9af672c Mon Sep 17 00:00:00 2001 From: yggverse Date: Wed, 24 Jul 2024 20:16:41 +0300 Subject: [PATCH] implement bookmarks browser --- .../Bookmark/Container/Navbar/Button.php | 20 +++ .../Bookmark/Container/Navbar/Entry.php | 20 +++ src/Entity/Browser/Bookmark.php | 68 ++++++++ src/Entity/Browser/Bookmark/Container.php | 65 ++++++++ .../Browser/Bookmark/Container/Content.php | 111 +++++++++++++ .../Bookmark/Container/Content/Table.php | 148 ++++++++++++++++++ .../Bookmark/Container/Content/Table/Data.php | 65 ++++++++ .../Bookmark/Container/Content/Viewport.php | 31 ++++ .../Browser/Bookmark/Container/Navbar.php | 99 ++++++++++++ .../Bookmark/Container/Navbar/Delete.php | 39 +++++ .../Bookmark/Container/Navbar/Filter.php | 45 ++++++ .../Bookmark/Container/Navbar/Open.php | 34 ++++ src/Entity/Browser/Bookmark/Header.php | 35 +++++ src/Entity/Browser/Menu.php | 10 ++ src/Entity/Browser/Menu/Bookmark.php | 49 ++++++ src/Entity/Browser/Menu/History.php | 2 +- 16 files changed, 840 insertions(+), 1 deletion(-) create mode 100644 src/Abstract/Entity/Browser/Bookmark/Container/Navbar/Button.php create mode 100644 src/Abstract/Entity/Browser/Bookmark/Container/Navbar/Entry.php create mode 100644 src/Entity/Browser/Bookmark.php create mode 100644 src/Entity/Browser/Bookmark/Container.php create mode 100644 src/Entity/Browser/Bookmark/Container/Content.php create mode 100644 src/Entity/Browser/Bookmark/Container/Content/Table.php create mode 100644 src/Entity/Browser/Bookmark/Container/Content/Table/Data.php create mode 100644 src/Entity/Browser/Bookmark/Container/Content/Viewport.php create mode 100644 src/Entity/Browser/Bookmark/Container/Navbar.php create mode 100644 src/Entity/Browser/Bookmark/Container/Navbar/Delete.php create mode 100644 src/Entity/Browser/Bookmark/Container/Navbar/Filter.php create mode 100644 src/Entity/Browser/Bookmark/Container/Navbar/Open.php create mode 100644 src/Entity/Browser/Bookmark/Header.php create mode 100644 src/Entity/Browser/Menu/Bookmark.php diff --git a/src/Abstract/Entity/Browser/Bookmark/Container/Navbar/Button.php b/src/Abstract/Entity/Browser/Bookmark/Container/Navbar/Button.php new file mode 100644 index 00000000..748a97e5 --- /dev/null +++ b/src/Abstract/Entity/Browser/Bookmark/Container/Navbar/Button.php @@ -0,0 +1,20 @@ +navbar = $navbar; + } +} diff --git a/src/Abstract/Entity/Browser/Bookmark/Container/Navbar/Entry.php b/src/Abstract/Entity/Browser/Bookmark/Container/Navbar/Entry.php new file mode 100644 index 00000000..d0af6c9c --- /dev/null +++ b/src/Abstract/Entity/Browser/Bookmark/Container/Navbar/Entry.php @@ -0,0 +1,20 @@ +navbar = $navbar; + } +} diff --git a/src/Entity/Browser/Bookmark.php b/src/Entity/Browser/Bookmark.php new file mode 100644 index 00000000..47f352ef --- /dev/null +++ b/src/Entity/Browser/Bookmark.php @@ -0,0 +1,68 @@ +browser = $browser; + + // Init window + $this->gtk = new GtkWindow; + + $this->gtk->set_size_request( + $this::WIDTH, + $this::HEIGHT + ); + + if ($this::MAXIMIZE) + { + $this->gtk->maximize(); + } + + // Init header + $this->header = new Bookmark\Header( + $this + ); + + $this->gtk->set_titlebar( + $this->header->gtk + ); + + // Init container + $this->container = new Bookmark\Container( + $this + ); + + $this->gtk->add( + $this->container->gtk + ); + + // Render + $this->gtk->show(); + } +} \ No newline at end of file diff --git a/src/Entity/Browser/Bookmark/Container.php b/src/Entity/Browser/Bookmark/Container.php new file mode 100644 index 00000000..866284a5 --- /dev/null +++ b/src/Entity/Browser/Bookmark/Container.php @@ -0,0 +1,65 @@ +bookmark = $bookmark; + + // Init container + $this->gtk = new GtkBox( + GtkOrientation::VERTICAL + ); + + // Init navbar + $this->navbar = new Container\Navbar( + $this + ); + + $this->gtk->add( + $this->navbar->gtk + ); + + // Init content + $this->content = new Container\Content( + $this + ); + + $this->gtk->pack_start( + $this->content->gtk, + true, + true, + 0 + ); + + // Render + $this->gtk->show(); + } + + public function refresh() + { + $this->navbar->refresh(); + $this->content->refresh(); + } +} \ No newline at end of file diff --git a/src/Entity/Browser/Bookmark/Container/Content.php b/src/Entity/Browser/Bookmark/Container/Content.php new file mode 100644 index 00000000..e00bec29 --- /dev/null +++ b/src/Entity/Browser/Bookmark/Container/Content.php @@ -0,0 +1,111 @@ +container = $container; + + // Init container + $this->gtk = new GtkScrolledWindow; + + $this->gtk->set_margin_start( + $this::MARGIN + ); + + $this->gtk->set_margin_end( + $this::MARGIN + ); + + $this->gtk->set_margin_bottom( + $this::MARGIN + ); + + // Init bookmark records table + $this->table = new Content\Table( + $this + ); + + // Init viewport to integrate scrolled window features + $this->viewport = new Content\Viewport( + $this + ); + + $this->viewport->gtk->add( + $this->table->gtk + ); + + $this->gtk->add( + $this->viewport->gtk + ); + + // Render + $this->gtk->show(); + + // Do initial search + $this->search(); + } + + // Do records search in database + public function search( + string $filter = '' + ): void + { + $this->table->data->clear(); + + if ($records = $this->container->bookmark->browser->database->findBookmark($filter)) + { + foreach ($records as $record) + { + $this->table->data->append( + $record->id, + $record->time, + $record->request, + $record->title + ); + } + } + + else + { + $this->container->navbar->open->gtk->set_sensitive( + false + ); + + $this->container->navbar->delete->gtk->set_sensitive( + false + ); + } + } + + // Refresh rows using current filter value in the navbar + public function refresh(): void + { + $this->search( + $this->container->navbar->filter->getValue() + ); + } +} \ No newline at end of file diff --git a/src/Entity/Browser/Bookmark/Container/Content/Table.php b/src/Entity/Browser/Bookmark/Container/Content/Table.php new file mode 100644 index 00000000..f7a9c83d --- /dev/null +++ b/src/Entity/Browser/Bookmark/Container/Content/Table.php @@ -0,0 +1,148 @@ +content = $content; + + // Init tree view + $this->gtk = new GtkTreeView; + + $this->gtk->append_column( + new GtkTreeViewColumn( + $this::TIME, + new GtkCellRendererText(), + 'text', + 1 + ) + ); + + $this->gtk->append_column( + new GtkTreeViewColumn( + $this::REQUEST, + new GtkCellRendererText(), + 'text', + 2 + ) + ); + + $this->gtk->append_column( + new GtkTreeViewColumn( + $this::TITLE, + new GtkCellRendererText(), + 'text', + 3 + ) + ); + + // Init data model + $this->data = new Table\Data( + $this + ); + + $this->gtk->set_model( + $this->data->gtk + ); + + // Render + $this->gtk->show(); + + // Init events + $this->gtk->connect( + 'row-activated', + function() + { + // Focus on browser + // $this->content->container->bookmark->browser->gtk->present(); + + $this->content->container->bookmark->browser->container->tab->append( + $this->getSelectedRequest() + ); + } + ); + + $this->gtk->connect( + 'cursor-changed', + function() + { + $this->content->container->navbar->open->gtk->set_sensitive( + boolval( + $this->getSelectedId() + ) + ); + + $this->content->container->navbar->delete->gtk->set_sensitive( + boolval( + $this->getSelectedId() + ) + ); + } + ); + } + + public function getSelectedId(): ?int + { + if ($id = $this->_getSelected(0)) + { + return $id; + } + + return null; + } + + public function getSelectedRequest(): ?string + { + if ($request = $this->_getSelected(2)) + { + return $request; + } + + return null; + } + + private function _getSelected( + int $column + ): null|int|string + { + list( + $list, + $row + ) = $this->gtk->get_selection()->get_selected(); + + if ($list && $row) + { + if ($value = $list->get_value($row, $column)) + { + return $value; + } + } + + return null; + } +} \ No newline at end of file diff --git a/src/Entity/Browser/Bookmark/Container/Content/Table/Data.php b/src/Entity/Browser/Bookmark/Container/Content/Table/Data.php new file mode 100644 index 00000000..082cd861 --- /dev/null +++ b/src/Entity/Browser/Bookmark/Container/Content/Table/Data.php @@ -0,0 +1,65 @@ +table = $table; + + // Init tree view + $this->gtk = new GtkListStore( + GObject::TYPE_INT, + GObject::TYPE_STRING, + GObject::TYPE_STRING, + GObject::TYPE_STRING + ); + } + + // Append new row + public function append( + int $id, + int $time, + string $request, + ?string $title + ): void + { + $this->gtk->append( + [ + $id, + date( + $this::TIME, + $time + ), + $request, + strval( + $title + ) + ] + ); + } + + // Remove rows from list + public function clear(): void + { + $this->gtk->clear(); + } +} \ No newline at end of file diff --git a/src/Entity/Browser/Bookmark/Container/Content/Viewport.php b/src/Entity/Browser/Bookmark/Container/Content/Viewport.php new file mode 100644 index 00000000..070f8915 --- /dev/null +++ b/src/Entity/Browser/Bookmark/Container/Content/Viewport.php @@ -0,0 +1,31 @@ +content = $content; + + // Init viewport + $this->gtk = new GtkViewport; + + // Render + $this->gtk->show(); + } +} \ No newline at end of file diff --git a/src/Entity/Browser/Bookmark/Container/Navbar.php b/src/Entity/Browser/Bookmark/Container/Navbar.php new file mode 100644 index 00000000..b0d32cbb --- /dev/null +++ b/src/Entity/Browser/Bookmark/Container/Navbar.php @@ -0,0 +1,99 @@ +container = $container; + + // Init container + $this->gtk = new GtkBox( + GtkOrientation::HORIZONTAL + ); + + $this->gtk->set_margin_top( + $this::MARGIN + ); + + $this->gtk->set_margin_bottom( + $this::MARGIN + ); + + $this->gtk->set_margin_start( + $this::MARGIN + ); + + $this->gtk->set_margin_end( + $this::MARGIN + ); + + $this->gtk->set_spacing( + $this::SPACING + ); + + // Init open button + $this->open = new Navbar\Open( + $this + ); + + $this->gtk->add( + $this->open->gtk + ); + + // Init delete button + $this->delete = new Navbar\Delete( + $this + ); + + $this->gtk->add( + $this->delete->gtk + ); + + // Init filter entry + $this->filter = new Navbar\Filter( + $this + ); + + $this->gtk->pack_start( + $this->filter->gtk, + true, + true, + 0 + ); + + // Render + $this->gtk->show(); + } + + public function refresh(): void + { + $this->delete->refresh(); + $this->open->refresh(); + } +} \ No newline at end of file diff --git a/src/Entity/Browser/Bookmark/Container/Navbar/Delete.php b/src/Entity/Browser/Bookmark/Container/Navbar/Delete.php new file mode 100644 index 00000000..305f4b99 --- /dev/null +++ b/src/Entity/Browser/Bookmark/Container/Navbar/Delete.php @@ -0,0 +1,39 @@ +navbar->container->content->table->getSelectedId()) + { + $this->navbar->container->bookmark->browser->database->deleteBookmark( + $id + ); + } + + $this->navbar->container->refresh(); + } + + public function refresh(): void + { + $this->gtk->set_sensitive( + boolval( + $this->navbar->container->content->table->getSelectedId() + ) + ); + } +} diff --git a/src/Entity/Browser/Bookmark/Container/Navbar/Filter.php b/src/Entity/Browser/Bookmark/Container/Navbar/Filter.php new file mode 100644 index 00000000..7329715c --- /dev/null +++ b/src/Entity/Browser/Bookmark/Container/Navbar/Filter.php @@ -0,0 +1,45 @@ +navbar->container->content->search( + $entry->get_text() + ); + } + + protected function _onKeyRelease( + GtkEntry $entry, + GdkEvent $event + ): void + { + $this->navbar->container->content->search( + $entry->get_text() + ); + } + + protected function _onChanged( + GtkEntry $entry + ): void + {} + + protected function _onFocusOut( + GtkEntry $entry, + GdkEvent $event + ): void + {} +} \ No newline at end of file diff --git a/src/Entity/Browser/Bookmark/Container/Navbar/Open.php b/src/Entity/Browser/Bookmark/Container/Navbar/Open.php new file mode 100644 index 00000000..148dc3ac --- /dev/null +++ b/src/Entity/Browser/Bookmark/Container/Navbar/Open.php @@ -0,0 +1,34 @@ +navbar->container->bookmark->browser->container->tab->append( + $this->navbar->container->content->table->getSelectedRequest() + ); + } + + public function refresh(): void + { + $this->gtk->set_sensitive( + boolval( + $this->navbar->container->content->table->getSelectedId() + ) + ); + } +} diff --git a/src/Entity/Browser/Bookmark/Header.php b/src/Entity/Browser/Bookmark/Header.php new file mode 100644 index 00000000..48b14212 --- /dev/null +++ b/src/Entity/Browser/Bookmark/Header.php @@ -0,0 +1,35 @@ +gtk = new GtkHeaderBar; + + $this->gtk->set_show_close_button( + $this::ACTIONS + ); + + $this->gtk->set_title( + _($this::TITLE) + ); + + $this->gtk->set_subtitle( + _($this::SUBTITLE) + ); + + $this->gtk->show(); + } +} \ No newline at end of file diff --git a/src/Entity/Browser/Menu.php b/src/Entity/Browser/Menu.php index fb729aa1..35d3caf4 100644 --- a/src/Entity/Browser/Menu.php +++ b/src/Entity/Browser/Menu.php @@ -19,6 +19,7 @@ class Menu // Requirements public Menu\File $file; public Menu\Tab $tab; + public Menu\Bookmark $bookmark; public Menu\History $history; public Menu\Quit $quit; @@ -49,6 +50,15 @@ class Menu $this->tab->gtk ); + // Init bookmark menu item + $this->bookmark = new Menu\Bookmark( + $this + ); + + $this->gtk->append( + $this->bookmark->gtk + ); + // Init history menu item $this->history = new Menu\History( $this diff --git a/src/Entity/Browser/Menu/Bookmark.php b/src/Entity/Browser/Menu/Bookmark.php new file mode 100644 index 00000000..39a15c1d --- /dev/null +++ b/src/Entity/Browser/Menu/Bookmark.php @@ -0,0 +1,49 @@ +menu = $menu; + + // Init menu item + $this->gtk = GtkMenuItem::new_with_label( + $this::LABEL + ); + + // Render + $this->gtk->show(); + + // Int events + $this->gtk->connect( + 'activate', + function() + { + new Window( + $this->menu->browser + ); + } + ); + } +} \ No newline at end of file diff --git a/src/Entity/Browser/Menu/History.php b/src/Entity/Browser/Menu/History.php index 956ce396..8609adc9 100644 --- a/src/Entity/Browser/Menu/History.php +++ b/src/Entity/Browser/Menu/History.php @@ -40,7 +40,7 @@ class History 'activate', function() { - $history = new Window( + new Window( $this->menu->browser ); }