Commit a5d5ea20 authored by Wolfgang Steitz's avatar Wolfgang Steitz Committed by Jim Nelson

Use icon names, not GLib.ThemedIcons, in sidebar: Bug #719284

Geary went this way a while back, this moves the technique into
Shotwell.
parent e2198219
......@@ -5,7 +5,7 @@
*/
public class Camera.Branch : Sidebar.Branch {
internal static Icon? cameras_icon = null;
internal static string? cameras_icon = null;
private Gee.HashMap<DiscoveredCamera, Camera.SidebarEntry> camera_map = new Gee.HashMap<
DiscoveredCamera, Camera.SidebarEntry>();
......@@ -23,7 +23,7 @@ public class Camera.Branch : Sidebar.Branch {
}
internal static void init() {
cameras_icon = new GLib.ThemedIcon(Resources.ICON_CAMERAS);
cameras_icon = Resources.ICON_CAMERAS;
}
internal static void terminate() {
......@@ -101,7 +101,7 @@ public class Camera.SidebarEntry : Sidebar.SimplePageEntry {
return camera.display_name ?? _("Camera");
}
public override Icon? get_sidebar_icon() {
public override string? get_sidebar_icon() {
return camera.icon ?? Camera.Branch.cameras_icon;
}
......
......@@ -8,9 +8,9 @@ public class DiscoveredCamera {
public GPhoto.Camera gcamera;
public string uri;
public string display_name;
public GLib.Icon? icon;
public string? icon;
public DiscoveredCamera(GPhoto.Camera gcamera, string uri, string display_name, GLib.Icon? icon) {
public DiscoveredCamera(GPhoto.Camera gcamera, string uri, string display_name, string? icon) {
this.gcamera = gcamera;
this.uri = uri;
this.display_name = display_name;
......@@ -221,10 +221,10 @@ public class CameraTable {
return null;
}
private GLib.Icon? get_icon_for_uuid(string uuid) {
private string? get_icon_for_uuid(string uuid) {
foreach (Volume volume in volume_monitor.get_volumes()) {
if (volume.get_identifier(VolumeIdentifier.UUID) == uuid) {
return volume.get_icon();
return volume.get_icon().to_string();
}
}
return null;
......@@ -323,7 +323,7 @@ public class CameraTable {
foreach (string port in detected_map.keys) {
string name = detected_map.get(port);
string display_name = null;
GLib.Icon? icon = null;
string? icon = null;
string uri = get_port_uri(port);
if (camera_map.has_key(uri)) {
......
......@@ -691,7 +691,7 @@ public class ImportPage : CheckerboardPage {
private string camera_name;
private VolumeMonitor volume_monitor = null;
private ImportPage? local_ref = null;
private GLib.Icon? icon;
private string? icon;
private ImportPageSearchViewFilter search_filter = new ImportPageSearchViewFilter();
private HideImportedViewFilter hide_imported_filter = new HideImportedViewFilter();
private CameraViewTracker tracker;
......@@ -707,7 +707,7 @@ public class ImportPage : CheckerboardPage {
LIBRARY_ERROR
}
public ImportPage(GPhoto.Camera camera, string uri, string? display_name = null, GLib.Icon? icon = null) {
public ImportPage(GPhoto.Camera camera, string uri, string? display_name = null, string? icon = null) {
base(_("Camera"));
this.camera = camera;
this.uri = uri;
......
......@@ -5,11 +5,10 @@
*/
public class Events.Branch : Sidebar.Branch {
internal static Icon open_icon;
internal static Icon closed_icon;
internal static Icon events_icon;
internal static Icon single_event_icon;
internal static Icon no_event_icon;
internal static string icon = Resources.ICON_FOLDER_CLOSED;
internal static string events_icon = Resources.ICON_EVENTS;
internal static string single_event_icon = Resources.ICON_ONE_EVENT;
internal static string no_event_icon = Resources.ICON_NO_EVENT;
// NOTE: Because the comparators must be static methods (due to CompareFunc's stupid impl.)
// and there's an assumption that only one Events.Branch is ever created, this is a static
......@@ -49,21 +48,10 @@ public class Events.Branch : Sidebar.Branch {
}
internal static void init() {
open_icon = new ThemedIcon(Resources.ICON_FOLDER_OPEN);
closed_icon = new ThemedIcon(Resources.ICON_FOLDER_CLOSED);
events_icon = new ThemedIcon(Resources.ICON_EVENTS);
single_event_icon = new ThemedIcon(Resources.ICON_ONE_EVENT);
no_event_icon = new ThemedIcon(Resources.ICON_NO_EVENT);
sort_ascending = Config.Facade.get_instance().get_events_sort_ascending();
}
internal static void terminate() {
open_icon = null;
closed_icon = null;
events_icon = null;
single_event_icon = null;
no_event_icon = null;
}
public Events.MasterDirectoryEntry get_master_entry() {
......@@ -372,16 +360,8 @@ public abstract class Events.DirectoryEntry : Sidebar.SimplePageEntry, Sidebar.E
public DirectoryEntry() {
}
public override Icon? get_sidebar_icon() {
return null;
}
public virtual Icon? get_sidebar_open_icon() {
return Events.Branch.open_icon;
}
public virtual Icon? get_sidebar_closed_icon() {
return Events.Branch.closed_icon;
public override string? get_sidebar_icon() {
return Events.Branch.icon;
}
public bool expand_on_select() {
......@@ -397,15 +377,7 @@ public class Events.MasterDirectoryEntry : Events.DirectoryEntry {
return MasterEventsDirectoryPage.NAME;
}
public override Icon? get_sidebar_icon() {
return Events.Branch.events_icon;
}
public override Icon? get_sidebar_open_icon() {
return Events.Branch.events_icon;
}
public override Icon? get_sidebar_closed_icon() {
public override string? get_sidebar_icon() {
return Events.Branch.events_icon;
}
......@@ -492,7 +464,7 @@ public class Events.EventEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntr
return event.get_name();
}
public override Icon? get_sidebar_icon() {
public override string? get_sidebar_icon() {
return Events.Branch.single_event_icon;
}
......@@ -531,7 +503,7 @@ public class Events.NoEventEntry : Sidebar.SimplePageEntry {
return NoEventPage.NAME;
}
public override Icon? get_sidebar_icon() {
public override string? get_sidebar_icon() {
return Events.Branch.no_event_icon;
}
......
......@@ -138,7 +138,7 @@ public class Folders.Branch : Sidebar.Branch {
private class Folders.Root : Sidebar.Grouping {
public Root() {
base (_("Folders"), Folders.opened_icon, Folders.closed_icon);
base (_("Folders"), Folders.icon);
}
}
......@@ -172,22 +172,14 @@ public class Folders.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.ExpandableE
return dir.get_basename();
}
public override Icon? get_sidebar_icon() {
return count == 0 ? closed_icon : have_photos_icon;
public override string? get_sidebar_icon() {
return count == 0 ? icon : have_photos_icon;
}
public override string to_string() {
return dir.get_path();
}
public Icon? get_sidebar_open_icon() {
return count == 0 ? opened_icon : have_photos_icon;
}
public Icon? get_sidebar_closed_icon() {
return count == 0 ? closed_icon : have_photos_icon;
}
public bool expand_on_select() {
return true;
}
......
......@@ -15,19 +15,16 @@
namespace Folders {
static Icon? opened_icon = null;
static Icon? closed_icon = null;
static Icon? have_photos_icon = null;
static string? icon = null;
static string? have_photos_icon = null;
public void init() throws Error {
opened_icon = new ThemedIcon(Resources.ICON_FOLDER_OPEN);
closed_icon = new ThemedIcon(Resources.ICON_FOLDER_CLOSED);
have_photos_icon = new ThemedIcon(Resources.ICON_FOLDER_DOCUMENTS);
icon = Resources.ICON_FOLDER_CLOSED;
have_photos_icon = Resources.ICON_FOLDER_DOCUMENTS;
}
public void terminate() {
opened_icon = null;
closed_icon = null;
icon = null;
have_photos_icon = null;
}
......
......@@ -15,7 +15,6 @@ public class Library.Branch : Sidebar.RootOnlyBranch {
}
public class Library.SidebarEntry : Sidebar.SimplePageEntry {
private Icon icon = new ThemedIcon(Resources.ICON_PHOTOS);
public SidebarEntry() {
}
......@@ -24,8 +23,8 @@ public class Library.SidebarEntry : Sidebar.SimplePageEntry {
return Library.MainPage.NAME;
}
public override Icon? get_sidebar_icon() {
return icon;
public override string? get_sidebar_icon() {
return Resources.ICON_PHOTOS;
}
protected override Page create_page() {
......
......@@ -40,8 +40,8 @@ public class Library.FlaggedSidebarEntry : Sidebar.SimplePageEntry, Sidebar.Inte
return FlaggedPage.NAME;
}
public override Icon? get_sidebar_icon() {
return new ThemedIcon(Resources.ICON_FLAGGED_PAGE);
public override string? get_sidebar_icon() {
return Resources.ICON_FLAGGED_PAGE;
}
protected override Page create_page() {
......
......@@ -63,8 +63,8 @@ public class Library.ImportQueueSidebarEntry : Sidebar.SimplePageEntry {
return ImportQueuePage.NAME;
}
public override Icon? get_sidebar_icon() {
return new ThemedIcon(Resources.ICON_IMPORTING);
public override string? get_sidebar_icon() {
return Resources.ICON_IMPORTING;
}
protected override Page create_page() {
......
......@@ -36,8 +36,8 @@ public class Library.LastImportSidebarEntry : Sidebar.SimplePageEntry {
return LastImportPage.NAME;
}
public override Icon? get_sidebar_icon() {
return new ThemedIcon(Resources.ICON_LAST_IMPORT);
public override string? get_sidebar_icon() {
return Resources.ICON_LAST_IMPORT;
}
protected override Page create_page() {
......
......@@ -40,8 +40,8 @@ public class Library.OfflineSidebarEntry : Sidebar.SimplePageEntry {
return OfflinePage.NAME;
}
public override Icon? get_sidebar_icon() {
return new ThemedIcon(Resources.ICON_MISSING_FILES);
public override string? get_sidebar_icon() {
return Resources.ICON_MISSING_FILES;
}
protected override Page create_page() {
......
......@@ -11,8 +11,6 @@ public class Library.TrashBranch : Sidebar.RootOnlyBranch {
}
public class Library.TrashSidebarEntry : Sidebar.SimplePageEntry, Sidebar.InternalDropTargetEntry {
private static Icon? full_icon = null;
private static Icon? empty_icon = null;
public TrashSidebarEntry() {
foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all())
......@@ -25,30 +23,26 @@ public class Library.TrashSidebarEntry : Sidebar.SimplePageEntry, Sidebar.Intern
}
internal static void init() {
full_icon = new ThemedIcon(Resources.ICON_TRASH_FULL);
empty_icon = new ThemedIcon(Resources.ICON_TRASH_EMPTY);
}
internal static void terminate() {
full_icon = null;
empty_icon = null;
}
public override string get_sidebar_name() {
return TrashPage.NAME;
}
public override Icon? get_sidebar_icon() {
public override string? get_sidebar_icon() {
return get_current_icon();
}
private static Icon get_current_icon() {
private static string get_current_icon() {
foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all()) {
if (media_sources.get_trashcan_count() > 0)
return full_icon;
return Resources.ICON_TRASH_FULL;
}
return empty_icon;
return Resources.ICON_TRASH_EMPTY;
}
public bool internal_drop_received(Gee.List<MediaSource> media) {
......
......@@ -65,7 +65,7 @@ public class Searches.Grouping : Sidebar.Grouping, Sidebar.Contextable {
private Gtk.Menu? context_menu = null;
public Grouping() {
base (_("Saved Searches"), new ThemedIcon(Gtk.Stock.FIND));
base (_("Saved Searches"), "find");
setup_context_menu();
}
......@@ -104,7 +104,7 @@ public class Searches.Grouping : Sidebar.Grouping, Sidebar.Contextable {
public class Searches.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntry,
Sidebar.DestroyableEntry {
private static Icon single_search_icon;
private static string single_search_icon = "find";
private SavedSearch search;
......@@ -113,11 +113,9 @@ public class Searches.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.Renameable
}
internal static void init() {
single_search_icon = new ThemedIcon(Gtk.Stock.FIND);
}
internal static void terminate() {
single_search_icon = null;
}
public SavedSearch for_saved_search() {
......@@ -128,7 +126,7 @@ public class Searches.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.Renameable
return search.get_name();
}
public override Icon? get_sidebar_icon() {
public override string? get_sidebar_icon() {
return single_search_icon;
}
......
......@@ -7,13 +7,13 @@
public interface Sidebar.Entry : Object {
public signal void sidebar_tooltip_changed(string? tooltip);
public signal void sidebar_icon_changed(Icon? icon);
public signal void sidebar_icon_changed(string? icon);
public abstract string get_sidebar_name();
public abstract string? get_sidebar_tooltip();
public abstract Icon? get_sidebar_icon();
public abstract string? get_sidebar_icon();
public abstract string to_string();
......@@ -25,11 +25,7 @@ public interface Sidebar.Entry : Object {
}
public interface Sidebar.ExpandableEntry : Sidebar.Entry {
public signal void sidebar_open_closed_icons_changed(Icon? open, Icon? closed);
public abstract Icon? get_sidebar_open_icon();
public abstract Icon? get_sidebar_closed_icon();
public signal void sidebar_open_closed_icons_changed(string? open, string? closed);
public abstract bool expand_on_select();
}
......
......@@ -49,9 +49,7 @@ public class Sidebar.Tree : Gtk.TreeView {
NAME,
TOOLTIP,
WRAPPER,
PIXBUF,
CLOSED_PIXBUF,
OPEN_PIXBUF,
ICON,
N_COLUMNS
}
......@@ -59,17 +57,13 @@ public class Sidebar.Tree : Gtk.TreeView {
typeof (string), // NAME
typeof (string?), // TOOLTIP
typeof (EntryWrapper), // WRAPPER
typeof (Gdk.Pixbuf?), // PIXBUF
typeof (Gdk.Pixbuf?), // CLOSED_PIXBUF
typeof (Gdk.Pixbuf?) // OPEN_PIXBUF
typeof (string?) // ICON
);
private Gtk.UIManager ui = new Gtk.UIManager();
private Gtk.IconTheme icon_theme;
private Gtk.CellRendererText text_renderer;
private unowned ExternalDropHandler drop_handler;
private Gtk.Entry? text_entry = null;
private Gee.HashMap<string, Gdk.Pixbuf> icon_cache = new Gee.HashMap<string, Gdk.Pixbuf>();
private Gee.HashMap<Sidebar.Entry, EntryWrapper> entry_map =
new Gee.HashMap<Sidebar.Entry, EntryWrapper>();
private Gee.HashMap<Sidebar.Branch, int> branches = new Gee.HashMap<Sidebar.Branch, int>();
......@@ -102,9 +96,7 @@ public class Sidebar.Tree : Gtk.TreeView {
text_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED);
Gtk.CellRendererPixbuf icon_renderer = new Gtk.CellRendererPixbuf();
text_column.pack_start(icon_renderer, false);
text_column.add_attribute(icon_renderer, "pixbuf", Columns.PIXBUF);
text_column.add_attribute(icon_renderer, "pixbuf_expander_closed", Columns.CLOSED_PIXBUF);
text_column.add_attribute(icon_renderer, "pixbuf_expander_open", Columns.OPEN_PIXBUF);
text_column.add_attribute(icon_renderer, "icon_name", Columns.ICON);
text_renderer = new Gtk.CellRendererText();
text_renderer.editing_canceled.connect(on_editing_canceled);
text_renderer.editing_started.connect(on_editing_started);
......@@ -145,9 +137,6 @@ public class Sidebar.Tree : Gtk.TreeView {
popup_menu.connect(on_context_menu_keypress);
icon_theme = Resources.get_icon_theme_engine();
icon_theme.changed.connect(on_theme_change);
setup_default_context_menu();
drag_begin.connect(on_drag_begin);
......@@ -158,7 +147,6 @@ public class Sidebar.Tree : Gtk.TreeView {
~Tree() {
text_renderer.editing_canceled.disconnect(on_editing_canceled);
text_renderer.editing_started.disconnect(on_editing_started);
icon_theme.changed.disconnect(on_theme_change);
}
private void on_drag_begin(Gdk.DragContext ctx) {
......@@ -462,11 +450,7 @@ public class Sidebar.Tree : Gtk.TreeView {
Sidebar.RenameableEntry? renameable = entry as Sidebar.RenameableEntry;
if (renameable != null)
renameable.sidebar_name_changed.connect(on_sidebar_name_changed);
Sidebar.ExpandableEntry? expandable = entry as Sidebar.ExpandableEntry;
if (expandable != null)
expandable.sidebar_open_closed_icons_changed.connect(on_sidebar_open_closed_icons_changed);
entry.grafted(this);
}
......@@ -571,10 +555,6 @@ public class Sidebar.Tree : Gtk.TreeView {
if (renameable != null)
renameable.sidebar_name_changed.disconnect(on_sidebar_name_changed);
Sidebar.ExpandableEntry? expandable = entry as Sidebar.ExpandableEntry;
if (expandable != null)
expandable.sidebar_open_closed_icons_changed.disconnect(on_sidebar_open_closed_icons_changed);
bool removed = entry_map.unset(entry);
assert(removed);
}
......@@ -703,11 +683,11 @@ public class Sidebar.Tree : Gtk.TreeView {
store.set(wrapper.get_iter(), Columns.TOOLTIP, guarded_markup_escape_text(tooltip));
}
private void on_sidebar_icon_changed(Sidebar.Entry entry, Icon? icon) {
private void on_sidebar_icon_changed(Sidebar.Entry entry, string? icon) {
EntryWrapper? wrapper = get_wrapper(entry);
assert(wrapper != null);
store.set(wrapper.get_iter(), Columns.PIXBUF, fetch_icon_pixbuf(icon));
store.set(wrapper.get_iter(), Columns.ICON, icon);
}
private void on_sidebar_page_created(Sidebar.PageRepresentative entry, Page page) {
......@@ -718,15 +698,6 @@ public class Sidebar.Tree : Gtk.TreeView {
destroying_page(entry, page);
}
private void on_sidebar_open_closed_icons_changed(Sidebar.ExpandableEntry entry, Icon? open,
Icon? closed) {
EntryWrapper? wrapper = get_wrapper(entry);
assert(wrapper != null);
store.set(wrapper.get_iter(), Columns.OPEN_PIXBUF, fetch_icon_pixbuf(open));
store.set(wrapper.get_iter(), Columns.CLOSED_PIXBUF, fetch_icon_pixbuf(closed));
}
private void on_sidebar_name_changed(Sidebar.RenameableEntry entry, string name) {
EntryWrapper? wrapper = get_wrapper(entry);
assert(wrapper != null);
......@@ -734,57 +705,13 @@ public class Sidebar.Tree : Gtk.TreeView {
store.set(wrapper.get_iter(), Columns.NAME, guarded_markup_escape_text(name));
}
private Gdk.Pixbuf? fetch_icon_pixbuf(GLib.Icon? gicon) {
if (gicon == null)
return null;
try {
Gdk.Pixbuf? icon = icon_cache.get(gicon.to_string());
if (icon != null)
return icon;
Gtk.IconInfo? info = icon_theme.lookup_by_gicon(gicon, ICON_SIZE, 0);
if (info == null)
return null;
icon = info.load_icon();
if (icon == null)
return null;
icon_cache.set(gicon.to_string(), icon);
return icon;
} catch (Error err) {
warning("Unable to load icon %s: %s", gicon.to_string(), err.message);
return null;
}
}
private void load_entry_icons(Gtk.TreeIter iter) {
EntryWrapper? wrapper = get_wrapper_at_iter(iter);
if (wrapper == null)
return;
Icon? icon = wrapper.entry.get_sidebar_icon();
Icon? open = null;
Icon? closed = null;
Sidebar.ExpandableEntry? expandable = wrapper.entry as Sidebar.ExpandableEntry;
if (expandable != null) {
open = expandable.get_sidebar_open_icon();
closed = expandable.get_sidebar_closed_icon();
}
if (open == null)
open = icon;
if (closed == null)
closed = icon;
store.set(iter, Columns.PIXBUF, fetch_icon_pixbuf(icon));
store.set(iter, Columns.OPEN_PIXBUF, fetch_icon_pixbuf(open));
store.set(iter, Columns.CLOSED_PIXBUF, fetch_icon_pixbuf(closed));
string? icon = wrapper.entry.get_sidebar_icon();
store.set(iter, Columns.ICON, icon);
}
private void load_branch_icons(Gtk.TreeIter iter) {
......@@ -798,15 +725,6 @@ public class Sidebar.Tree : Gtk.TreeView {
}
}
private void on_theme_change() {
Gtk.TreeIter iter;
if (store.get_iter_first(out iter)) {
do {
load_branch_icons(iter);
} while (store.iter_next(ref iter));
}
}
private bool on_selection(Gtk.TreeSelection selection, Gtk.TreeModel model, Gtk.TreePath path,
bool path_currently_selected) {
// only allow selection if a page is selectable
......
......@@ -7,13 +7,11 @@
// A simple grouping Entry that is only expandable
public class Sidebar.Grouping : Object, Sidebar.Entry, Sidebar.ExpandableEntry {
private string name;
private Icon? open_icon;
private Icon? closed_icon;
private string? icon;
public Grouping(string name, Icon? open_icon, Icon? closed_icon = null) {
public Grouping(string name, string? icon) {
this.name = name;
this.open_icon = open_icon;
this.closed_icon = closed_icon ?? open_icon;
this.icon = icon;
}
public string get_sidebar_name() {
......@@ -24,16 +22,8 @@ public class Sidebar.Grouping : Object, Sidebar.Entry, Sidebar.ExpandableEntry {
return name;
}
public Icon? get_sidebar_icon() {
return null;
}
public Icon? get_sidebar_open_icon() {
return open_icon;
}
public Icon? get_sidebar_closed_icon() {
return closed_icon;
public string? get_sidebar_icon() {
return icon;
}
public string to_string() {
......@@ -61,7 +51,7 @@ public abstract class Sidebar.SimplePageEntry : Object, Sidebar.Entry, Sidebar.S
return get_sidebar_name();
}
public abstract Icon? get_sidebar_icon();
public abstract string? get_sidebar_icon();
public virtual string to_string() {
return get_sidebar_name();
......
......@@ -124,7 +124,7 @@ public class Tags.Grouping : Sidebar.Grouping, Sidebar.InternalDropTargetEntry,
private Gtk.Menu? context_menu = null;
public Grouping() {
base (_("Tags"), new ThemedIcon(Resources.ICON_TAGS));
base (_("Tags"), Resources.ICON_TAGS);
setup_context_menu();
}
......@@ -199,7 +199,7 @@ public class Tags.Grouping : Sidebar.Grouping, Sidebar.InternalDropTargetEntry,
public class Tags.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntry,
Sidebar.DestroyableEntry, Sidebar.InternalDropTargetEntry, Sidebar.ExpandableEntry,
Sidebar.InternalDragSourceEntry {
private static Icon single_tag_icon;
private string single_tag_icon = Resources.ICON_ONE_TAG;
private Tag tag;
......@@ -208,11 +208,9 @@ public class Tags.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntr
}
internal static void init() {
single_tag_icon = new ThemedIcon(Resources.ICON_ONE_TAG);
}
internal static void terminate() {
single_tag_icon = null;
}
public Tag for_tag() {
......@@ -223,7 +221,7 @@ public class Tags.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntr
return tag.get_user_visible_name();
}
public override Icon? get_sidebar_icon() {
public override string? get_sidebar_icon() {
return single_tag_icon;
}
......@@ -290,14 +288,6 @@ public class Tags.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntr
return false;
}
public Icon? get_sidebar_open_icon() {
return single_tag_icon;
}
public Icon? get_sidebar_closed_icon() {
return single_tag_icon;
}
public bool expand_on_select() {
return false;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment