293 lines
12 KiB
Vala
293 lines
12 KiB
Vala
|
/*
|
||
|
Copyright (C) 2009-2014 Christian Dywan <christian@twotoasts.de>
|
||
|
Copyright (C) 2009-2012 Alexander Butenko <a.butenka@gmail.com>
|
||
|
|
||
|
This library is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU Lesser General Public
|
||
|
License as published by the Free Software Foundation; either
|
||
|
version 2.1 of the License, or (at your option) any later version.
|
||
|
|
||
|
See the file COPYING for the full license text.
|
||
|
*/
|
||
|
|
||
|
namespace Adblock {
|
||
|
|
||
|
|
||
|
public class StatusIcon : Midori.ContextAction {
|
||
|
Config config;
|
||
|
SubscriptionManager manager;
|
||
|
public State state;
|
||
|
public bool debug_element_toggled;
|
||
|
|
||
|
public StatusIcon (Adblock.Config config, SubscriptionManager manager) {
|
||
|
GLib.Object (name: "AdblockStatusMenu");
|
||
|
|
||
|
this.config = config;
|
||
|
this.manager = manager;
|
||
|
this.debug_element_toggled = false;
|
||
|
|
||
|
var item = new Midori.ContextAction ("Preferences",
|
||
|
_("Preferences"), null, Gtk.STOCK_PREFERENCES);
|
||
|
item.activate.connect (() => {
|
||
|
manager.add_subscription (null);
|
||
|
});
|
||
|
add (item);
|
||
|
|
||
|
add (null);
|
||
|
|
||
|
var checkitem = new Gtk.ToggleAction ("Disable", _("Disable"), null, null);
|
||
|
checkitem.set_active (!config.enabled);
|
||
|
checkitem.toggled.connect (() => {
|
||
|
config.enabled = !checkitem.active;
|
||
|
set_state (config.enabled ? Adblock.State.ENABLED : Adblock.State.DISABLED);
|
||
|
});
|
||
|
add (checkitem);
|
||
|
|
||
|
var hideritem = new Gtk.ToggleAction ("HiddenElements",
|
||
|
_("Display hidden elements"), null, null);
|
||
|
hideritem.set_active (debug_element_toggled);
|
||
|
hideritem.toggled.connect (() => {
|
||
|
this.debug_element_toggled = hideritem.active;
|
||
|
});
|
||
|
add (hideritem);
|
||
|
set_status (config.enabled ? "enabled" : "disabled");
|
||
|
}
|
||
|
|
||
|
void set_status (string status) {
|
||
|
gicon = new GLib.ThemedIcon ("adblock-%s".printf (status));
|
||
|
}
|
||
|
|
||
|
public void set_state (Adblock.State state) {
|
||
|
this.state = state;
|
||
|
|
||
|
if (this.state == State.BLOCKED) {
|
||
|
set_status ("blocked");
|
||
|
tooltip = _("Blocking");
|
||
|
} else if (this.state == State.ENABLED) {
|
||
|
set_status ("enabled");
|
||
|
tooltip = _("Enabled");
|
||
|
} else if (this.state == State.DISABLED) {
|
||
|
set_status ("disabled");
|
||
|
tooltip = _("Disabled");
|
||
|
} else
|
||
|
assert_not_reached ();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public class SubscriptionManager {
|
||
|
Gtk.TreeView treeview;
|
||
|
Gtk.ListStore liststore;
|
||
|
Adblock.Config config;
|
||
|
public Gtk.Label description_label;
|
||
|
string description;
|
||
|
|
||
|
public SubscriptionManager (Config config) {
|
||
|
this.config = config;
|
||
|
this.liststore = new Gtk.ListStore (1, typeof (Subscription));
|
||
|
this.description_label = new Gtk.Label (null);
|
||
|
this.description = _("Type the address of a preconfigured filter list in the text entry and hit Enter.\n");
|
||
|
this.description += _("You can find more lists by visiting following sites:\n %s, %s\n".printf (
|
||
|
"<a href=\"http://adblockplus.org/en/subscriptions\">adblockplus.org/en/subscriptions</a>",
|
||
|
"<a href=\"http://easylist.adblockplus.org/\">easylist.adblockplus.org</a>"
|
||
|
));
|
||
|
}
|
||
|
|
||
|
public void add_subscription (string? uri) {
|
||
|
var dialog = new Gtk.Dialog.with_buttons (_("Configure Advertisement filters"),
|
||
|
null,
|
||
|
#if !HAVE_GTK3
|
||
|
Gtk.DialogFlags.NO_SEPARATOR |
|
||
|
#endif
|
||
|
Gtk.DialogFlags.DESTROY_WITH_PARENT,
|
||
|
Gtk.STOCK_HELP, Gtk.ResponseType.HELP,
|
||
|
Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE);
|
||
|
#if HAVE_GTK3
|
||
|
dialog.get_widget_for_response (Gtk.ResponseType.HELP).get_style_context ().add_class ("help_button");
|
||
|
#endif
|
||
|
dialog.set_icon_name (Gtk.STOCK_PROPERTIES);
|
||
|
dialog.set_response_sensitive (Gtk.ResponseType.HELP, false);
|
||
|
|
||
|
var hbox = new Gtk.HBox (false, 0);
|
||
|
(dialog.get_content_area () as Gtk.Box).pack_start (hbox, true, true, 12);
|
||
|
var vbox = new Gtk.VBox (false, 0);
|
||
|
hbox.pack_start (vbox, true, true, 4);
|
||
|
this.description_label.set_markup (this.description);
|
||
|
this.description_label.set_line_wrap (true);
|
||
|
vbox.pack_start (this.description_label, false, false, 4);
|
||
|
|
||
|
var entry = new Gtk.Entry ();
|
||
|
if (uri != null)
|
||
|
entry.set_text (uri);
|
||
|
vbox.pack_start (entry, false, false, 4);
|
||
|
|
||
|
liststore = new Gtk.ListStore (1, typeof (Subscription));
|
||
|
treeview = new Gtk.TreeView.with_model (liststore);
|
||
|
treeview.set_headers_visible (false);
|
||
|
var column = new Gtk.TreeViewColumn ();
|
||
|
var renderer_toggle = new Gtk.CellRendererToggle ();
|
||
|
column.pack_start (renderer_toggle, false);
|
||
|
column.set_cell_data_func (renderer_toggle, (column, renderer, model, iter) => {
|
||
|
Subscription sub;
|
||
|
liststore.get (iter, 0, out sub);
|
||
|
renderer.set ("active", sub.active,
|
||
|
"sensitive", sub.mutable);
|
||
|
});
|
||
|
renderer_toggle.toggled.connect ((path) => {
|
||
|
Gtk.TreeIter iter;
|
||
|
if (liststore.get_iter_from_string (out iter, path)) {
|
||
|
Subscription sub;
|
||
|
liststore.get (iter, 0, out sub);
|
||
|
sub.active = !sub.active;
|
||
|
}
|
||
|
});
|
||
|
treeview.append_column (column);
|
||
|
|
||
|
column = new Gtk.TreeViewColumn ();
|
||
|
var renderer_text = new Gtk.CellRendererText ();
|
||
|
column.pack_start (renderer_text, false);
|
||
|
renderer_text.set ("editable", true);
|
||
|
// TODO: renderer_text.edited.connect
|
||
|
column.set_cell_data_func (renderer_text, (column, renderer, model, iter) => {
|
||
|
Subscription sub;
|
||
|
liststore.get (iter, 0, out sub);
|
||
|
string status = "";
|
||
|
foreach (unowned Feature feature in sub) {
|
||
|
var updater = feature as Adblock.Updater;
|
||
|
if (updater != null) {
|
||
|
if (updater.last_updated != null)
|
||
|
status = updater.last_updated.format (_("Last update: %x %X"));
|
||
|
}
|
||
|
}
|
||
|
if (!sub.valid)
|
||
|
status = _("File incomplete - broken download?");
|
||
|
renderer.set ("markup", (Markup.printf_escaped ("<b>%s</b>\n%s",
|
||
|
sub.title ?? sub.uri, status)));
|
||
|
});
|
||
|
treeview.append_column (column);
|
||
|
|
||
|
column = new Gtk.TreeViewColumn ();
|
||
|
Gtk.CellRendererPixbuf renderer_button = new Gtk.CellRendererPixbuf ();
|
||
|
column.pack_start (renderer_button, false);
|
||
|
column.set_cell_data_func (renderer_button, on_render_button);
|
||
|
treeview.append_column (column);
|
||
|
|
||
|
var scrolled = new Gtk.ScrolledWindow (null, null);
|
||
|
scrolled.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
|
||
|
scrolled.add (treeview);
|
||
|
vbox.pack_start (scrolled);
|
||
|
int height;
|
||
|
treeview.create_pango_layout ("a\nb").get_pixel_size (null, out height);
|
||
|
scrolled.set_size_request (-1, height * 5);
|
||
|
|
||
|
foreach (unowned Subscription sub in config)
|
||
|
liststore.insert_with_values (null, 0, 0, sub);
|
||
|
treeview.button_release_event.connect (button_released);
|
||
|
|
||
|
entry.activate.connect (() => {
|
||
|
string? parsed_uri = Adblock.parse_subscription_uri (entry.text);
|
||
|
if (parsed_uri != null) {
|
||
|
var sub = new Subscription (parsed_uri);
|
||
|
if (config.add (sub)) {
|
||
|
liststore.insert_with_values (null, 0, 0, sub);
|
||
|
try {
|
||
|
sub.parse ();
|
||
|
} catch (GLib.Error error) {
|
||
|
warning ("Error parsing %s: %s", sub.uri, error.message);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
entry.text = "";
|
||
|
});
|
||
|
|
||
|
dialog.get_content_area ().show_all ();
|
||
|
|
||
|
dialog.response.connect ((response)=>{ dialog.destroy (); });
|
||
|
dialog.show ();
|
||
|
}
|
||
|
|
||
|
void on_render_button (Gtk.CellLayout column, Gtk.CellRenderer renderer,
|
||
|
Gtk.TreeModel model, Gtk.TreeIter iter) {
|
||
|
|
||
|
Subscription sub;
|
||
|
liststore.get (iter, 0, out sub);
|
||
|
|
||
|
renderer.set ("stock-id", sub.mutable ? Gtk.STOCK_DELETE : null,
|
||
|
"stock-size", Gtk.IconSize.MENU);
|
||
|
}
|
||
|
|
||
|
public bool button_released (Gdk.EventButton event) {
|
||
|
Gtk.TreePath? path;
|
||
|
Gtk.TreeViewColumn column;
|
||
|
if (treeview.get_path_at_pos ((int)event.x, (int)event.y, out path, out column, null, null)) {
|
||
|
if (path != null) {
|
||
|
if (column == treeview.get_column (2)) {
|
||
|
Gtk.TreeIter iter;
|
||
|
if (liststore.get_iter (out iter, path)) {
|
||
|
Subscription sub;
|
||
|
liststore.get (iter, 0, out sub);
|
||
|
if (sub.mutable) {
|
||
|
config.remove (sub);
|
||
|
liststore.remove (iter);
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class CustomRulesEditor {
|
||
|
Gtk.Dialog dialog;
|
||
|
Subscription custom;
|
||
|
public string? rule { get; set; }
|
||
|
|
||
|
public CustomRulesEditor (Subscription custom) {
|
||
|
this.custom = custom;
|
||
|
}
|
||
|
|
||
|
public void set_uri (string uri) {
|
||
|
this.rule = uri;
|
||
|
}
|
||
|
|
||
|
public void show () {
|
||
|
this.dialog = new Gtk.Dialog.with_buttons (_("Edit rule"),
|
||
|
null,
|
||
|
#if !HAVE_GTK3
|
||
|
Gtk.DialogFlags.NO_SEPARATOR |
|
||
|
#endif
|
||
|
Gtk.DialogFlags.DESTROY_WITH_PARENT,
|
||
|
Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
|
||
|
Gtk.STOCK_ADD, Gtk.ResponseType.ACCEPT);
|
||
|
dialog.set_icon_name (Gtk.STOCK_ADD);
|
||
|
dialog.resizable = false;
|
||
|
|
||
|
var hbox = new Gtk.HBox (false, 8);
|
||
|
var sizegroup = new Gtk.SizeGroup (Gtk.SizeGroupMode.HORIZONTAL);
|
||
|
hbox.border_width = 5;
|
||
|
var label = new Gtk.Label.with_mnemonic (_("_Rule:"));
|
||
|
sizegroup.add_widget (label);
|
||
|
hbox.pack_start (label, false, false, 0);
|
||
|
(dialog.get_content_area () as Gtk.Box).pack_start (hbox, false, true, 0);
|
||
|
|
||
|
var entry = new Gtk.Entry ();
|
||
|
sizegroup.add_widget (entry);
|
||
|
entry.activates_default = true;
|
||
|
entry.set_text (this.rule);
|
||
|
hbox.pack_start (entry, true, true, 0);
|
||
|
|
||
|
dialog.get_content_area ().show_all ();
|
||
|
|
||
|
dialog.set_default_response (Gtk.ResponseType.ACCEPT);
|
||
|
if (dialog.run () != Gtk.ResponseType.ACCEPT)
|
||
|
return;
|
||
|
|
||
|
this.rule = entry.get_text ();
|
||
|
this.dialog.destroy ();
|
||
|
custom.add_rule (this.rule);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|