From c9059c12dca7444796c3f7ab6a87425ec004ca34 Mon Sep 17 00:00:00 2001 From: Emanuel Sprung Date: Thu, 26 Mar 2020 20:06:23 +0100 Subject: [PATCH] Browser: Let the user add/remove bookmarks to the bookmarks bar This patchset adds a Button to the toolbar (right next to the location field) with a star icon. The star is white if the currently visited url is not yet bookmarked and yellow if a bookmark for the url exists. After adding or removing a bookmark, the bookmark json file is synced to disk. Therefore, some new pledge/unveil's have been added. --- Applications/Browser/BookmarksBarWidget.cpp | 42 ++++++++++++++++++ Applications/Browser/BookmarksBarWidget.h | 4 ++ Applications/Browser/main.cpp | 46 +++++++++++++++++++- Base/res/icons/16x16/star-contour.png | Bin 0 -> 612 bytes Base/res/icons/16x16/star-yellow.png | Bin 0 -> 583 bytes 5 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 Base/res/icons/16x16/star-contour.png create mode 100644 Base/res/icons/16x16/star-yellow.png diff --git a/Applications/Browser/BookmarksBarWidget.cpp b/Applications/Browser/BookmarksBarWidget.cpp index f51bfe0e69..eb9b6ad1db 100644 --- a/Applications/Browser/BookmarksBarWidget.cpp +++ b/Applications/Browser/BookmarksBarWidget.cpp @@ -162,3 +162,45 @@ void BookmarksBarWidget::update_content_size() } } } + +bool BookmarksBarWidget::contains_bookmark(const String& url) +{ + for (int item_index = 0; item_index < model()->row_count(); ++item_index) { + + auto item_title = model()->data(model()->index(item_index, 0)).to_string(); + auto item_url = model()->data(model()->index(item_index, 1)).to_string(); + if (item_url == url) { + return true; + } + } + return false; +} + +bool BookmarksBarWidget::remove_bookmark(const String& url) +{ + for (int item_index = 0; item_index < model()->row_count(); ++item_index) { + + auto item_title = model()->data(model()->index(item_index, 0)).to_string(); + auto item_url = model()->data(model()->index(item_index, 1)).to_string(); + if (item_url == url) { + auto& json_model = *static_cast(model()); + json_model.remove(item_index); + return true; + } + } + + return false; +} +bool BookmarksBarWidget::add_bookmark(const String& url, const String& title) +{ + Vector values; + values.append(title); + values.append(url); + + auto& json_model = *static_cast(model()); + if (json_model.add(move(values))) { + json_model.store(); + return true; + } + return false; +} diff --git a/Applications/Browser/BookmarksBarWidget.h b/Applications/Browser/BookmarksBarWidget.h index c9135d6549..586192eea7 100644 --- a/Applications/Browser/BookmarksBarWidget.h +++ b/Applications/Browser/BookmarksBarWidget.h @@ -41,6 +41,10 @@ public: Function on_bookmark_click; Function on_bookmark_hover; + bool contains_bookmark(const String& url); + bool remove_bookmark(const String& url); + bool add_bookmark(const String& url, const String& title); + private: BookmarksBarWidget(const String&, bool enabled); diff --git a/Applications/Browser/main.cpp b/Applications/Browser/main.cpp index 441d8ddfb7..25f01f5755 100644 --- a/Applications/Browser/main.cpp +++ b/Applications/Browser/main.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -56,9 +58,11 @@ static const char* home_url = "file:///home/anon/www/welcome.html"; static const char* bookmarks_filename = "/home/anon/bookmarks.json"; +static String s_title = ""; + int main(int argc, char** argv) { - if (pledge("stdio shared_buffer accept unix cpath rpath fattr", nullptr) < 0) { + if (pledge("stdio shared_buffer accept unix cpath rpath wpath fattr", nullptr) < 0) { perror("pledge"); return 1; } @@ -68,11 +72,23 @@ int main(int argc, char** argv) // Connect to the ProtocolServer immediately so we can drop the "unix" pledge. Web::ResourceLoader::the(); - if (pledge("stdio shared_buffer accept rpath", nullptr) < 0) { + if (pledge("stdio shared_buffer accept cpath rpath wpath", nullptr) < 0) { perror("pledge"); return 1; } + if (unveil("/home", "rwc") < 0) { + perror("unveil"); + return 1; + } + + if (unveil("/res", "r") < 0) { + perror("unveil"); + return 1; + } + + unveil(nullptr, nullptr); + auto window = GUI::Window::construct(); window->set_rect(100, 100, 640, 480); @@ -135,11 +151,36 @@ int main(int argc, char** argv) html_widget.load(location_box.text()); }; + auto& bookmark_button = toolbar.add(); + bookmark_button.set_button_style(Gfx::ButtonStyle::CoolBar); + bookmark_button.set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/star-black.png")); + bookmark_button.set_size_policy(GUI::SizePolicy::Fixed, GUI::SizePolicy::Fixed); + bookmark_button.set_preferred_size(22, 22); + + auto update_bookmark_button = [&](const String& url) { + if (bookmarksbar.contains_bookmark(url)) { + bookmark_button.set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/star-yellow.png")); + } else { + bookmark_button.set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/star-contour.png")); + } + }; + + bookmark_button.on_click = [&] { + auto url = html_widget.main_frame().document()->url().to_string(); + if (bookmarksbar.contains_bookmark(url)) { + bookmarksbar.remove_bookmark(url); + } else { + bookmarksbar.add_bookmark(url, s_title); + } + update_bookmark_button(url); + }; + html_widget.on_load_start = [&](auto& url) { location_box.set_text(url.to_string()); if (should_push_loads_to_history) history.push(url); update_actions(); + update_bookmark_button(url.to_string()); }; html_widget.on_link_click = [&](auto& url) { @@ -151,6 +192,7 @@ int main(int argc, char** argv) }; html_widget.on_title_change = [&](auto& title) { + s_title = title; window->set_title(String::format("%s - Browser", title.characters())); }; diff --git a/Base/res/icons/16x16/star-contour.png b/Base/res/icons/16x16/star-contour.png new file mode 100644 index 0000000000000000000000000000000000000000..ce7fbbe99226ce5db8d19a91a3d58bd9e9003acc GIT binary patch literal 612 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7I14-?iy0W0ia?lAb#6*5 z0|SF(iEBhjaDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$QVa}?A3a?hLo9lGCvMCZ zW)wMAUq1a-#Z|L%+euCulP=7$EXv3@(5$ido0w`Olb`DeORJ6r^^L{LAI$L8Xz>x^ zNa1hvTgJh8ap4MgZ=;MUd{W*ocW%*8T>kgi_kG{@e&6e_B%xFw-of1Nxa5L8%QY3x zDlLvf4`04~S^XgT!nBzIBB^&v@9JJJm1ih#st9thjnkTX>S@uAn-d+-Wf0K^3;%TEzI-56c z+;}Z-`|7=M@0mYv{@|!#<6{XFDGyqC#rX85XTFz@nD`pa39u{;w zudJBozBS7B_U+r%P0KQ`%O0=1{QB#k(~IKP&zEfbC^KXChc!30{oQr><)8A3^78BF z(>Cijw!W;_vF`i4>T1?pR^IDbruR3kk#(3m_0aXY{qebGv)?lG`nKta&B^4GL$~?nIt;9<9*ki+Oxx(E?FOvqTKh^gNHe)&1m{pI?5rui+8 z&&kXC7ZSRa^$v5(=X*>WawU%KTcnZS_(Z2$@PXlnf?K!ZBN(RW$ zA9q}9diJffWNqHO=cxgqeS2@8UTd=d`O|ePx({8BO}-GAzx_g7;(;Ws!%s_tCyCwN z+4wH7MN`%5$qVyO<*Yvqyq+G>t?n(OU5}~ci zC)KkP&9r>Q{qOyEta+m=T&&o}-Eia^pYeUZjiqLZ`eDjXy{0WznYTBsC~e-t|MwPO zKmTRDtI*2Qpyz8BvrgJux9q_hk7xRGSkhi{v)mL8z5mzCX2%(h30CJB7Mw|QQ#UGz z2sFR;;B-%_q{XVjt04uNXCJG7`26EdTrA5p?U2;7b3M;g#T>g-|NMc`sV_S3`9-$v zwy~+X<@`8RchbfwMGG4}`xDdW--u|KI@Lgb+dcuN8T=p9GAAEQW3Qdm5^AEP>v!z- n-8gTe~DWM4fqelhX literal 0 HcmV?d00001