ContentFilterSettingsWidget.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * Copyright (c) 2022, Maciej Zygmanowski <sppmacd@pm.me>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "ContentFilterSettingsWidget.h"
  7. #include <AK/NonnullRefPtr.h>
  8. #include <Applications/BrowserSettings/ContentFilterSettingsWidgetGML.h>
  9. #include <LibConfig/Client.h>
  10. #include <LibCore/StandardPaths.h>
  11. #include <LibGUI/CheckBox.h>
  12. #include <LibGUI/Event.h>
  13. #include <LibGUI/Forward.h>
  14. #include <LibGUI/InputBox.h>
  15. #include <LibGUI/ListView.h>
  16. #include <LibGUI/Menu.h>
  17. static constexpr bool s_default_enable_content_filtering = true;
  18. static DeprecatedString filter_list_file_path()
  19. {
  20. return DeprecatedString::formatted("{}/BrowserContentFilters.txt", Core::StandardPaths::config_directory());
  21. }
  22. ErrorOr<void> DomainListModel::load()
  23. {
  24. // FIXME: This should be somewhat shared with Browser.
  25. auto file = TRY(Core::File::open(filter_list_file_path(), Core::File::OpenMode::Read));
  26. auto content_filter_list = TRY(Core::BufferedFile::create(move(file)));
  27. auto buffer = TRY(ByteBuffer::create_uninitialized(4096));
  28. while (TRY(content_filter_list->can_read_line())) {
  29. auto line = TRY(content_filter_list->read_line(buffer));
  30. if (!line.is_empty())
  31. m_domain_list.append(line);
  32. }
  33. return {};
  34. }
  35. ErrorOr<void> DomainListModel::save()
  36. {
  37. if (!m_was_modified)
  38. return {};
  39. m_was_modified = false;
  40. StringBuilder builder;
  41. for (auto const& domain : m_domain_list)
  42. TRY(builder.try_appendff("{}\n", domain));
  43. auto file = TRY(Core::File::open(filter_list_file_path(), Core::File::OpenMode::Write));
  44. // FIXME: This should write the entire span.
  45. TRY(file->write_some(TRY(builder.to_byte_buffer()).bytes()));
  46. return {};
  47. }
  48. void DomainListModel::add_domain(DeprecatedString name)
  49. {
  50. begin_insert_rows({}, m_domain_list.size(), m_domain_list.size());
  51. m_domain_list.append(move(name));
  52. end_insert_rows();
  53. m_was_modified = true;
  54. did_update(UpdateFlag::DontInvalidateIndices);
  55. }
  56. void DomainListModel::delete_domain(size_t index)
  57. {
  58. begin_delete_rows({}, index, index);
  59. m_domain_list.remove(index);
  60. end_delete_rows();
  61. m_was_modified = true;
  62. did_update(UpdateFlag::DontInvalidateIndices);
  63. }
  64. void DomainListModel::reset_default_values()
  65. {
  66. // FIXME: This probably should not be hardcoded.
  67. m_domain_list = {
  68. "207.net",
  69. "247realmedia.com",
  70. "2o7.net",
  71. "adbrite.com",
  72. "admob.com",
  73. "adthis.com",
  74. "advertising.com",
  75. "aquantive.com",
  76. "atwola.com",
  77. "channelintelligence.com",
  78. "doubleclick.com",
  79. "doubleclick.net",
  80. "esomniture.com",
  81. "google-analytics.com",
  82. "googleadservices.com",
  83. "googlesyndication.com",
  84. "gravity.com",
  85. "hitbox.com",
  86. "intellitxt.com",
  87. "nielsen-online.com",
  88. "omniture.com",
  89. "quantcast.com",
  90. "quantserve.com",
  91. "scorecardresearch.com",
  92. };
  93. m_was_modified = true;
  94. did_update(UpdateFlag::InvalidateAllIndices);
  95. }
  96. ContentFilterSettingsWidget::ContentFilterSettingsWidget()
  97. {
  98. load_from_gml(content_filter_settings_widget_gml).release_value_but_fixme_should_propagate_errors();
  99. m_enable_content_filtering_checkbox = find_descendant_of_type_named<GUI::CheckBox>("enable_content_filtering_checkbox");
  100. m_domain_list_view = find_descendant_of_type_named<GUI::ListView>("domain_list_view");
  101. m_add_new_domain_button = find_descendant_of_type_named<GUI::Button>("add_new_domain_button");
  102. m_enable_content_filtering_checkbox->set_checked(Config::read_bool("Browser"sv, "Preferences"sv, "EnableContentFilters"sv, s_default_enable_content_filtering), GUI::AllowCallback::No);
  103. m_enable_content_filtering_checkbox->on_checked = [&](auto) { set_modified(true); };
  104. m_add_new_domain_button->on_click = [&](unsigned) {
  105. DeprecatedString text;
  106. if (GUI::InputBox::show(window(), text, "Enter domain name"sv, "Add domain to Content Filter"sv, GUI::InputType::NonemptyText) == GUI::Dialog::ExecResult::OK) {
  107. m_domain_list_model->add_domain(move(text));
  108. set_modified(true);
  109. }
  110. };
  111. m_domain_list_model = make_ref_counted<DomainListModel>();
  112. // FIXME: Propagate errors
  113. MUST(m_domain_list_model->load());
  114. m_domain_list_view->set_model(m_domain_list_model);
  115. auto delete_action = GUI::CommonActions::make_delete_action([&](GUI::Action const&) {
  116. if (!m_domain_list_view->selection().is_empty()) {
  117. m_domain_list_model->delete_domain(m_domain_list_view->selection().first().row());
  118. set_modified(true);
  119. }
  120. });
  121. m_entry_context_menu = GUI::Menu::construct();
  122. m_entry_context_menu->add_action(delete_action);
  123. m_domain_list_view->on_context_menu_request = [&](GUI::ModelIndex const& index, GUI::ContextMenuEvent const& event) {
  124. m_domain_list_view->set_cursor(index, GUI::AbstractView::SelectionUpdate::Set);
  125. m_entry_context_menu->popup(event.screen_position());
  126. };
  127. }
  128. void ContentFilterSettingsWidget::apply_settings()
  129. {
  130. // FIXME: Propagate errors
  131. MUST(m_domain_list_model->save());
  132. Config::write_bool("Browser"sv, "Preferences"sv, "EnableContentFilters"sv, m_enable_content_filtering_checkbox->is_checked());
  133. }
  134. void ContentFilterSettingsWidget::reset_default_values()
  135. {
  136. m_domain_list_model->reset_default_values();
  137. m_enable_content_filtering_checkbox->set_checked(s_default_enable_content_filtering);
  138. }