[shotwell] use text-only section headers in sidebar (#718349)
- From: Wolfgang Steitz <wsteitz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [shotwell] use text-only section headers in sidebar (#718349)
- Date: Tue, 17 Mar 2015 21:19:00 +0000 (UTC)
commit d2fe363e32cf77d1c74b8046669d92beb6eb91d2
Author: Wolfgang Steitz <wsteitz gmail com>
Date: Tue Mar 17 22:14:58 2015 +0100
use text-only section headers in sidebar (#718349)
po/POTFILES.in | 10 +-
src/camera/Branch.vala | 8 +-
src/events/Branch.vala | 25 +++-
src/events/EventsDirectoryPage.vala | 2 +-
src/folders/Branch.vala | 4 +-
src/library/Branch.vala | 108 ++++++++++-
...FlaggedBranch.vala => FlaggedSidebarEntry.vala} | 43 ++---
...eueBranch.vala => ImportQueueSidebarEntry.vala} | 56 ++----
...portBranch.vala => LastImportSidebarEntry.vala} | 27 +--
src/library/LibraryWindow.vala | 35 +---
...OfflineBranch.vala => OfflineSidebarEntry.vala} | 18 +--
.../{TrashBranch.vala => TrashSidebarEntry.vala} | 6 -
src/library/mk/library.mk | 10 +-
src/searches/Branch.vala | 12 +-
src/sidebar/Entry.vala | 9 +
src/sidebar/Tree.vala | 193 ++++++++++++++++----
src/sidebar/common.vala | 39 ++++-
src/tags/Branch.vala | 16 ++-
18 files changed, 423 insertions(+), 198 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0f3a05e..84c6d92 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -157,17 +157,17 @@ src/folders/Branch.vala
src/folders/Folders.vala
src/folders/Page.vala
src/library/Branch.vala
-src/library/FlaggedBranch.vala
+src/library/FlaggedSidebarEntry.vala
src/library/FlaggedPage.vala
-src/library/ImportQueueBranch.vala
+src/library/ImportQueueSidebarEntry.vala
src/library/ImportQueuePage.vala
-src/library/LastImportBranch.vala
+src/library/LastImportSidebarEntry.vala
src/library/LastImportPage.vala
src/library/Library.vala
src/library/LibraryWindow.vala
-src/library/OfflineBranch.vala
+src/library/OfflineSidebarEntry.vala
src/library/OfflinePage.vala
-src/library/TrashBranch.vala
+src/library/TrashSidebarEntry.vala
src/library/TrashPage.vala
src/main.vala
src/photos/BmpSupport.vala
diff --git a/src/camera/Branch.vala b/src/camera/Branch.vala
index 43e787a..83f3f56 100644
--- a/src/camera/Branch.vala
+++ b/src/camera/Branch.vala
@@ -11,7 +11,7 @@ public class Camera.Branch : Sidebar.Branch {
DiscoveredCamera, Camera.SidebarEntry>();
public Branch() {
- base (new Camera.Grouping(),
+ base (new Camera.Header(),
Sidebar.Branch.Options.HIDE_IF_EMPTY | Sidebar.Branch.Options.AUTO_OPEN_ON_NEW_CHILD,
camera_comparator);
@@ -80,9 +80,9 @@ public class Camera.Branch : Sidebar.Branch {
}
}
-public class Camera.Grouping : Sidebar.Grouping {
- public Grouping() {
- base (_("Cameras"), Camera.Branch.cameras_icon);
+public class Camera.Header : Sidebar.Header {
+ public Header() {
+ base (_("Cameras"));
}
}
diff --git a/src/events/Branch.vala b/src/events/Branch.vala
index 114f85b..1093411 100644
--- a/src/events/Branch.vala
+++ b/src/events/Branch.vala
@@ -19,11 +19,14 @@ public class Events.Branch : Sidebar.Branch {
Event, Events.EventEntry>();
private Events.UndatedDirectoryEntry undated_entry = new Events.UndatedDirectoryEntry();
private Events.NoEventEntry no_event_entry = new Events.NoEventEntry();
+ private Events.MasterDirectoryEntry all_events_entry = new Events.MasterDirectoryEntry();
public Branch() {
- base (new Events.MasterDirectoryEntry(), Sidebar.Branch.Options.STARTUP_EXPAND_TO_FIRST_CHILD,
+ base (new Sidebar.Header(_("Events")), Sidebar.Branch.Options.STARTUP_EXPAND_TO_FIRST_CHILD,
event_year_comparator);
+ graft(get_root(), all_events_entry);
+
// seed the branch
foreach (DataObject object in Event.global.get_all())
add_event((Event) object);
@@ -54,8 +57,12 @@ public class Events.Branch : Sidebar.Branch {
internal static void terminate() {
}
+ public bool is_user_renameable() {
+ return true;
+ }
+
public Events.MasterDirectoryEntry get_master_entry() {
- return (Events.MasterDirectoryEntry) get_root();
+ return all_events_entry;
}
private static int event_year_comparator(Sidebar.Entry a, Sidebar.Entry b) {
@@ -79,6 +86,12 @@ public class Events.Branch : Sidebar.Branch {
else if (b is Events.NoEventEntry)
return -1;
+ // The All events entry should always appear on top
+ if (a is Events.MasterDirectoryEntry)
+ return -1;
+ else if (b is Events.MasterDirectoryEntry)
+ return 1;
+
if (!sort_ascending) {
Sidebar.Entry swap = a;
a = b;
@@ -300,7 +313,8 @@ public class Events.Branch : Sidebar.Branch {
int event_year = event_tm.year + 1900;
return find_first_child(get_root(), (entry) => {
- if ((entry is Events.UndatedDirectoryEntry) || (entry is Events.NoEventEntry))
+ if ((entry is Events.UndatedDirectoryEntry) || (entry is Events.NoEventEntry) ||
+ entry is Events.MasterDirectoryEntry)
return false;
else
return ((Events.YearDirectoryEntry) entry).get_year() == event_year;
@@ -472,6 +486,10 @@ public class Events.EventEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntr
return new EventPage(event);
}
+ public bool is_user_renameable() {
+ return true;
+ }
+
public void rename(string new_name) {
string? prepped = Event.prep_event_name(new_name);
if (prepped != null)
@@ -495,6 +513,7 @@ public class Events.EventEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntr
}
}
+
public class Events.NoEventEntry : Sidebar.SimplePageEntry {
public NoEventEntry() {
}
diff --git a/src/events/EventsDirectoryPage.vala b/src/events/EventsDirectoryPage.vala
index b624ab5..99601a0 100644
--- a/src/events/EventsDirectoryPage.vala
+++ b/src/events/EventsDirectoryPage.vala
@@ -227,7 +227,7 @@ public abstract class EventsDirectoryPage : CheckerboardPage {
}
public class MasterEventsDirectoryPage : EventsDirectoryPage {
- public const string NAME = _("Events");
+ public const string NAME = _("All Events");
public MasterEventsDirectoryPage() {
base (NAME, new EventDirectoryManager(), (Gee.Collection<Event>) Event.global.get_all());
diff --git a/src/folders/Branch.vala b/src/folders/Branch.vala
index 3271d26..0904e5c 100644
--- a/src/folders/Branch.vala
+++ b/src/folders/Branch.vala
@@ -136,9 +136,9 @@ public class Folders.Branch : Sidebar.Branch {
}
}
-private class Folders.Root : Sidebar.Grouping {
+private class Folders.Root : Sidebar.Header {
public Root() {
- base (_("Folders"), Folders.icon);
+ base (_("Folders"));
}
}
diff --git a/src/library/Branch.vala b/src/library/Branch.vala
index 425deff..0e875d2 100644
--- a/src/library/Branch.vala
+++ b/src/library/Branch.vala
@@ -4,23 +4,97 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
-public class Library.Branch : Sidebar.RootOnlyBranch {
+public class Library.Branch : Sidebar.Branch {
+ private const string POSITION_DATA = "x-photos-entry-position";
+
+ public Library.PhotosEntry photos_entry { get; private set; }
+ public Library.FlaggedSidebarEntry flagged_entry { get; private set; }
+ public Library.LastImportSidebarEntry last_imported_entry { get; private set; }
+ public Library.ImportQueueSidebarEntry import_queue_entry { get; private set; }
+ public Library.OfflineSidebarEntry offline_entry { get; private set; }
+ public Library.TrashSidebarEntry trash_entry { get; private set; }
+
+ // This lists the order of the library items in the sidebar. To re-order, simply move
+ // the item in this list to a new position. These numbers should *not* persist anywhere
+ // outside the app.
+ private enum EntryPosition {
+ PHOTOS,
+ FLAGGED,
+ LAST_IMPORTED,
+ IMPORT_QUEUE,
+ OFFLINE,
+ TRASH
+ }
+
public Branch() {
- base (new Library.SidebarEntry());
+ base(new Sidebar.Header(_("Library")),
+ Sidebar.Branch.Options.STARTUP_OPEN_GROUPING, comparator);
+
+ photos_entry = new Library.PhotosEntry();
+ trash_entry = new Library.TrashSidebarEntry();
+ last_imported_entry = new Library.LastImportSidebarEntry();
+ flagged_entry = new Library.FlaggedSidebarEntry();
+ offline_entry = new Library.OfflineSidebarEntry();
+ import_queue_entry = new Library.ImportQueueSidebarEntry();
+
+ insert(photos_entry, EntryPosition.PHOTOS);
+ insert(trash_entry, EntryPosition.TRASH);
+
+ flagged_entry.visibility_changed.connect(on_flagged_visibility_changed);
+ on_flagged_visibility_changed();
+
+ last_imported_entry.visibility_changed.connect(on_last_imported_visibility_changed);
+ on_last_imported_visibility_changed();
+
+ import_queue_entry.visibility_changed.connect(on_import_queue_visibility_changed);
+ on_import_queue_visibility_changed();
+
+ offline_entry.visibility_changed.connect(on_offline_visibility_changed);
+ on_offline_visibility_changed();
}
- public Library.MainPage get_main_page() {
- return (Library.MainPage) ((Library.SidebarEntry) get_root()).get_page();
+ private void insert(Sidebar.Entry entry, int position) {
+ entry.set_data<int>(POSITION_DATA, position);
+ graft(get_root(), entry);
+ }
+
+ private void on_flagged_visibility_changed() {
+ update_entry_visibility(flagged_entry, EntryPosition.FLAGGED);
+ }
+
+ private void on_last_imported_visibility_changed() {
+ update_entry_visibility(last_imported_entry, EntryPosition.LAST_IMPORTED);
+ }
+
+ private void on_import_queue_visibility_changed() {
+ update_entry_visibility(import_queue_entry, EntryPosition.IMPORT_QUEUE);
+ }
+
+ private void on_offline_visibility_changed() {
+ update_entry_visibility(offline_entry, EntryPosition.OFFLINE);
+ }
+
+ private void update_entry_visibility(Library.HideablePageEntry entry, int position) {
+ if (entry.visible) {
+ if (!has_entry(entry))
+ insert(entry, position);
+ } else if (has_entry(entry)) {
+ prune(entry);
+ }
+ }
+
+ private static int comparator(Sidebar.Entry a, Sidebar.Entry b) {
+ return a.get_data<int>(POSITION_DATA) - b.get_data<int>(POSITION_DATA);
}
}
-public class Library.SidebarEntry : Sidebar.SimplePageEntry {
+public class Library.PhotosEntry : Sidebar.SimplePageEntry {
- public SidebarEntry() {
+ public PhotosEntry() {
}
public override string get_sidebar_name() {
- return Library.MainPage.NAME;
+ return _("Photos");
}
public override string? get_sidebar_icon() {
@@ -32,6 +106,26 @@ public class Library.SidebarEntry : Sidebar.SimplePageEntry {
}
}
+public abstract class Library.HideablePageEntry : Sidebar.SimplePageEntry {
+ // container branch should listen to this signal
+ public signal void visibility_changed(bool visible);
+
+ private bool show_entry = false;
+ public bool visible {
+ get { return show_entry; }
+ set {
+ if (value == show_entry)
+ return;
+
+ show_entry = value;
+ visibility_changed(value);
+ }
+ }
+
+ public HideablePageEntry() {
+ }
+}
+
public class Library.MainPage : CollectionPage {
public const string NAME = _("Library");
diff --git a/src/library/FlaggedBranch.vala b/src/library/FlaggedSidebarEntry.vala
similarity index 79%
rename from src/library/FlaggedBranch.vala
rename to src/library/FlaggedSidebarEntry.vala
index 70f24d5..240aaf3 100644
--- a/src/library/FlaggedBranch.vala
+++ b/src/library/FlaggedSidebarEntry.vala
@@ -4,38 +4,19 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
-public class Library.FlaggedBranch : Sidebar.RootOnlyBranch {
- public FlaggedBranch() {
- base (new Library.FlaggedSidebarEntry());
-
+public class Library.FlaggedSidebarEntry : Library.HideablePageEntry, Sidebar.InternalDropTargetEntry {
+ public FlaggedSidebarEntry() {
foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all())
media_sources.flagged_contents_altered.connect(on_flagged_contents_altered);
- set_show_branch(get_total_flagged() != 0);
+ visible = (get_total_flagged() != 0);
}
- ~FlaggedBranch() {
+ ~FlaggedSidebarEntry() {
foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all())
media_sources.flagged_contents_altered.disconnect(on_flagged_contents_altered);
- }
-
- private void on_flagged_contents_altered() {
- set_show_branch(get_total_flagged() != 0);
- }
-
- private int get_total_flagged() {
- int total = 0;
- foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all())
- total += media_sources.get_flagged().size;
-
- return total;
- }
-}
-
-public class Library.FlaggedSidebarEntry : Sidebar.SimplePageEntry, Sidebar.InternalDropTargetEntry {
- public FlaggedSidebarEntry() {
- }
-
+ }
+
public override string get_sidebar_name() {
return FlaggedPage.NAME;
}
@@ -57,5 +38,17 @@ public class Library.FlaggedSidebarEntry : Sidebar.SimplePageEntry, Sidebar.Inte
public bool internal_drop_received_arbitrary(Gtk.SelectionData data) {
return false;
}
+
+ private void on_flagged_contents_altered() {
+ visible = (get_total_flagged() != 0);
+ }
+
+ private int get_total_flagged() {
+ int total = 0;
+ foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all())
+ total += media_sources.get_flagged().size;
+
+ return total;
+ }
}
diff --git a/src/library/ImportQueueBranch.vala b/src/library/ImportQueueSidebarEntry.vala
similarity index 61%
rename from src/library/ImportQueueBranch.vala
rename to src/library/ImportQueueSidebarEntry.vala
index b26f1fd..5d34ce2 100644
--- a/src/library/ImportQueueBranch.vala
+++ b/src/library/ImportQueueSidebarEntry.vala
@@ -4,35 +4,34 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
-public class Library.ImportQueueBranch : Sidebar.RootOnlyBranch {
- private Library.ImportQueueSidebarEntry entry;
-
- public ImportQueueBranch() {
- // can't pass to base() an object that was allocated in declaration; see
- // https://bugzilla.gnome.org/show_bug.cgi?id=646286
- base (new Library.ImportQueueSidebarEntry());
-
- entry = (Library.ImportQueueSidebarEntry) get_root();
-
+public class Library.ImportQueueSidebarEntry : Library.HideablePageEntry {
+ public ImportQueueSidebarEntry() {
// only attach signals to the page when it's created
- entry.page_created.connect(on_page_created);
- entry.destroying_page.connect(on_destroying_page);
+ page_created.connect(on_page_created);
+ destroying_page.connect(on_destroying_page);
// don't use entry.get_page() or get_queue_page() because (a) we don't want to
// create the page during initialization, and (b) we know there's no import activity
// at this moment
- set_show_branch(false);
+ visible = false;
}
- ~ImportQueueBranch() {
- entry.page_created.disconnect(on_page_created);
- entry.destroying_page.disconnect(on_destroying_page);
+ public override string get_sidebar_name() {
+ return ImportQueuePage.NAME;
}
- public ImportQueuePage get_queue_page() {
- return (ImportQueuePage) entry.get_page();
+ public override string? get_sidebar_icon() {
+ return Resources.ICON_IMPORTING;
}
+ protected override Page create_page() {
+ return new ImportQueuePage();
+ }
+
+ private ImportQueuePage get_queue_page() {
+ return get_page() as ImportQueuePage;
+ }
+
private void on_page_created() {
get_queue_page().batch_added.connect(on_batch_added_or_removed);
get_queue_page().batch_removed.connect(on_batch_added_or_removed);
@@ -44,31 +43,14 @@ public class Library.ImportQueueBranch : Sidebar.RootOnlyBranch {
}
private void on_batch_added_or_removed() {
- set_show_branch(get_queue_page().get_batch_count() > 0);
+ visible = (get_queue_page().get_batch_count() > 0);
}
public void enqueue_and_schedule(BatchImport batch_import, bool allow_user_cancel) {
// want to display the branch before passing to the page because this might result in the
// page being created, and want it all hooked up in the tree prior to creating the page
- set_show_branch(true);
+ visible = true;
get_queue_page().enqueue_and_schedule(batch_import, allow_user_cancel);
}
}
-public class Library.ImportQueueSidebarEntry : Sidebar.SimplePageEntry {
- public ImportQueueSidebarEntry() {
- }
-
- public override string get_sidebar_name() {
- return ImportQueuePage.NAME;
- }
-
- public override string? get_sidebar_icon() {
- return Resources.ICON_IMPORTING;
- }
-
- protected override Page create_page() {
- return new ImportQueuePage();
- }
-}
-
diff --git a/src/library/LastImportBranch.vala b/src/library/LastImportSidebarEntry.vala
similarity index 62%
rename from src/library/LastImportBranch.vala
rename to src/library/LastImportSidebarEntry.vala
index 52e682e..3414130 100644
--- a/src/library/LastImportBranch.vala
+++ b/src/library/LastImportSidebarEntry.vala
@@ -4,34 +4,19 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
-public class Library.LastImportBranch : Sidebar.RootOnlyBranch {
- public LastImportBranch() {
- base (new Library.LastImportSidebarEntry());
-
+public class Library.LastImportSidebarEntry : Library.HideablePageEntry {
+ public LastImportSidebarEntry() {
foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all())
media_sources.import_roll_altered.connect(on_import_rolls_altered);
- set_show_branch(MediaCollectionRegistry.get_instance().get_last_import_id() != null);
+ visible = (MediaCollectionRegistry.get_instance().get_last_import_id() != null);
}
- ~LastImportBranch() {
+ ~LastImportSidebarEntry() {
foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all())
media_sources.import_roll_altered.disconnect(on_import_rolls_altered);
}
- public Library.LastImportSidebarEntry get_main_entry() {
- return (Library.LastImportSidebarEntry) get_root();
- }
-
- private void on_import_rolls_altered() {
- set_show_branch(MediaCollectionRegistry.get_instance().get_last_import_id() != null);
- }
-}
-
-public class Library.LastImportSidebarEntry : Sidebar.SimplePageEntry {
- public LastImportSidebarEntry() {
- }
-
public override string get_sidebar_name() {
return LastImportPage.NAME;
}
@@ -43,5 +28,9 @@ public class Library.LastImportSidebarEntry : Sidebar.SimplePageEntry {
protected override Page create_page() {
return new LastImportPage();
}
+
+ private void on_import_rolls_altered() {
+ visible = (MediaCollectionRegistry.get_instance().get_last_import_id() != null);
+ }
}
diff --git a/src/library/LibraryWindow.vala b/src/library/LibraryWindow.vala
index 5ff41c9..a756436 100644
--- a/src/library/LibraryWindow.vala
+++ b/src/library/LibraryWindow.vala
@@ -42,16 +42,11 @@ public class LibraryWindow : AppWindow {
// outside the app.
private enum SidebarRootPosition {
LIBRARY,
- FLAGGED,
- LAST_IMPORTED,
CAMERAS,
- IMPORT_QUEUE,
SAVED_SEARCH,
EVENTS,
FOLDERS,
- TAGS,
- TRASH,
- OFFLINE
+ TAGS
}
public enum TargetType {
@@ -114,12 +109,7 @@ public class LibraryWindow : AppWindow {
private Library.Branch library_branch = new Library.Branch();
private Tags.Branch tags_branch = new Tags.Branch();
private Folders.Branch folders_branch = new Folders.Branch();
- private Library.TrashBranch trash_branch = new Library.TrashBranch();
private Events.Branch events_branch = new Events.Branch();
- private Library.OfflineBranch offline_branch = new Library.OfflineBranch();
- private Library.FlaggedBranch flagged_branch = new Library.FlaggedBranch();
- private Library.LastImportBranch last_import_branch = new Library.LastImportBranch();
- private Library.ImportQueueBranch import_queue_branch = new Library.ImportQueueBranch();
private Camera.Branch camera_branch = new Camera.Branch();
private Searches.Branch saved_search_branch = new Searches.Branch();
private bool page_switching_enabled = true;
@@ -172,12 +162,7 @@ public class LibraryWindow : AppWindow {
sidebar_tree.graft(library_branch, SidebarRootPosition.LIBRARY);
sidebar_tree.graft(tags_branch, SidebarRootPosition.TAGS);
sidebar_tree.graft(folders_branch, SidebarRootPosition.FOLDERS);
- sidebar_tree.graft(trash_branch, SidebarRootPosition.TRASH);
sidebar_tree.graft(events_branch, SidebarRootPosition.EVENTS);
- sidebar_tree.graft(offline_branch, SidebarRootPosition.OFFLINE);
- sidebar_tree.graft(flagged_branch, SidebarRootPosition.FLAGGED);
- sidebar_tree.graft(last_import_branch, SidebarRootPosition.LAST_IMPORTED);
- sidebar_tree.graft(import_queue_branch, SidebarRootPosition.IMPORT_QUEUE);
sidebar_tree.graft(camera_branch, SidebarRootPosition.CAMERAS);
sidebar_tree.graft(saved_search_branch, SidebarRootPosition.SAVED_SEARCH);
@@ -207,7 +192,7 @@ public class LibraryWindow : AppWindow {
menubar.no_show_all = true;
// create the main layout & start at the Library page
- create_layout(library_branch.get_main_page());
+ create_layout(library_branch.photos_entry.get_page());
// settings that should persist between sessions
load_configuration();
@@ -882,7 +867,7 @@ public class LibraryWindow : AppWindow {
}
public void enqueue_batch_import(BatchImport batch_import, bool allow_user_cancel) {
- import_queue_branch.enqueue_and_schedule(batch_import, allow_user_cancel);
+ library_branch.import_queue_entry.enqueue_and_schedule(batch_import, allow_user_cancel);
}
private void import_reporter(ImportManifest manifest) {
@@ -1028,7 +1013,7 @@ public class LibraryWindow : AppWindow {
}
public void switch_to_library_page() {
- switch_to_page(library_branch.get_main_page());
+ switch_to_page(library_branch.photos_entry.get_page());
}
public void switch_to_event(Event event) {
@@ -1065,7 +1050,7 @@ public class LibraryWindow : AppWindow {
}
public void switch_to_import_queue_page() {
- switch_to_page(import_queue_branch.get_queue_page());
+ switch_to_page(library_branch.import_queue_entry.get_page());
}
private void on_camera_added(DiscoveredCamera camera) {
@@ -1440,7 +1425,7 @@ public class LibraryWindow : AppWindow {
private void on_destroying_page(Sidebar.PageRepresentative entry, Page page) {
// if page is the current page, switch to fallback before destroying
if (page == get_current_page())
- switch_to_page(library_branch.get_main_page());
+ switch_to_page(library_branch.photos_entry.get_page());
remove_from_notebook(page);
@@ -1458,9 +1443,11 @@ public class LibraryWindow : AppWindow {
// if the currently selected item is removed, want to jump to fallback page (which
// depends on the item that was selected)
+ Library.LastImportSidebarEntry last_import_entry = library_branch.last_imported_entry;
+
// Importing... -> Last Import (if available)
- if (selectable is Library.ImportQueueSidebarEntry && last_import_branch.get_show_branch()) {
- switch_to_page(last_import_branch.get_main_entry().get_page());
+ if (selectable is Library.ImportQueueSidebarEntry && last_import_entry.visible) {
+ switch_to_page(last_import_entry.get_page());
return;
}
@@ -1480,7 +1467,7 @@ public class LibraryWindow : AppWindow {
}
// basic all-around default: jump to the Library page
- switch_to_page(library_branch.get_main_page());
+ switch_to_page(library_branch.photos_entry.get_page());
}
private void subscribe_for_basic_information(Page page) {
diff --git a/src/library/OfflineBranch.vala b/src/library/OfflineSidebarEntry.vala
similarity index 78%
rename from src/library/OfflineBranch.vala
rename to src/library/OfflineSidebarEntry.vala
index ab2ea90..34c09a0 100644
--- a/src/library/OfflineBranch.vala
+++ b/src/library/OfflineSidebarEntry.vala
@@ -4,23 +4,22 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
-public class Library.OfflineBranch : Sidebar.RootOnlyBranch {
- public OfflineBranch() {
- base (new Library.OfflineSidebarEntry());
+public class Library.OfflineSidebarEntry : Library.HideablePageEntry {
+ public OfflineSidebarEntry() {
foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all())
media_sources.offline_contents_altered.connect(on_offline_contents_altered);
- set_show_branch(get_total_offline() != 0);
+ visible = (get_total_offline() != 0);
}
-
- ~OfflineBranch() {
+
+ ~OfflineSidebarEntry() {
foreach (MediaSourceCollection media_sources in MediaCollectionRegistry.get_instance().get_all())
media_sources.trashcan_contents_altered.disconnect(on_offline_contents_altered);
}
private void on_offline_contents_altered() {
- set_show_branch(get_total_offline() != 0);
+ visible = (get_total_offline() != 0);
}
private int get_total_offline() {
@@ -30,11 +29,6 @@ public class Library.OfflineBranch : Sidebar.RootOnlyBranch {
return total;
}
-}
-
-public class Library.OfflineSidebarEntry : Sidebar.SimplePageEntry {
- public OfflineSidebarEntry() {
- }
public override string get_sidebar_name() {
return OfflinePage.NAME;
diff --git a/src/library/TrashBranch.vala b/src/library/TrashSidebarEntry.vala
similarity index 92%
rename from src/library/TrashBranch.vala
rename to src/library/TrashSidebarEntry.vala
index 5710211..69412b7 100644
--- a/src/library/TrashBranch.vala
+++ b/src/library/TrashSidebarEntry.vala
@@ -4,12 +4,6 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
-public class Library.TrashBranch : Sidebar.RootOnlyBranch {
- public TrashBranch() {
- base (new Library.TrashSidebarEntry());
- }
-}
-
public class Library.TrashSidebarEntry : Sidebar.SimplePageEntry, Sidebar.InternalDropTargetEntry {
public TrashSidebarEntry() {
diff --git a/src/library/mk/library.mk b/src/library/mk/library.mk
index b4ab790..dc6201f 100644
--- a/src/library/mk/library.mk
+++ b/src/library/mk/library.mk
@@ -13,11 +13,11 @@ UNIT_DIR := library
UNIT_FILES := \
LibraryWindow.vala \
Branch.vala \
- TrashBranch.vala \
- OfflineBranch.vala \
- FlaggedBranch.vala \
- LastImportBranch.vala \
- ImportQueueBranch.vala \
+ TrashSidebarEntry.vala \
+ OfflineSidebarEntry.vala \
+ FlaggedSidebarEntry.vala \
+ LastImportSidebarEntry.vala \
+ ImportQueueSidebarEntry.vala \
FlaggedPage.vala \
ImportQueuePage.vala \
LastImportPage.vala \
diff --git a/src/searches/Branch.vala b/src/searches/Branch.vala
index e4b1968..00a9ea7 100644
--- a/src/searches/Branch.vala
+++ b/src/searches/Branch.vala
@@ -9,7 +9,7 @@ public class Searches.Branch : Sidebar.Branch {
new Gee.HashMap<SavedSearch, Searches.SidebarEntry>();
public Branch() {
- base (new Searches.Grouping(),
+ base (new Searches.Header(),
Sidebar.Branch.Options.HIDE_IF_EMPTY
| Sidebar.Branch.Options.AUTO_OPEN_ON_NEW_CHILD
| Sidebar.Branch.Options.STARTUP_EXPAND_TO_FIRST_CHILD,
@@ -60,12 +60,12 @@ public class Searches.Branch : Sidebar.Branch {
}
}
-public class Searches.Grouping : Sidebar.Grouping, Sidebar.Contextable {
+public class Searches.Header : Sidebar.Header, Sidebar.Contextable {
private Gtk.UIManager ui = new Gtk.UIManager();
private Gtk.Menu? context_menu = null;
- public Grouping() {
- base (_("Saved Searches"), "find");
+ public Header() {
+ base (_("Saved Searches"));
setup_context_menu();
}
@@ -134,6 +134,10 @@ public class Searches.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.Renameable
return new SavedSearchPage(search);
}
+ public bool is_user_renameable() {
+ return true;
+ }
+
public void rename(string new_name) {
if (!SavedSearchTable.get_instance().exists(new_name))
AppWindow.get_command_manager().execute(new RenameSavedSearchCommand(search, new_name));
diff --git a/src/sidebar/Entry.vala b/src/sidebar/Entry.vala
index 090c524..5a84f74 100644
--- a/src/sidebar/Entry.vala
+++ b/src/sidebar/Entry.vala
@@ -47,6 +47,15 @@ public interface Sidebar.RenameableEntry : Sidebar.Entry {
public signal void sidebar_name_changed(string name);
public abstract void rename(string new_name);
+
+ // Return true to allow the user to rename the sidebar entry in the UI.
+ public abstract bool is_user_renameable();
+}
+
+public interface Sidebar.EmphasizableEntry : Sidebar.Entry {
+ public signal void is_emphasized_changed(bool emphasized);
+
+ public abstract bool is_emphasized();
}
public interface Sidebar.DestroyableEntry : Sidebar.Entry {
diff --git a/src/sidebar/Tree.vala b/src/sidebar/Tree.vala
index e2d1879..a020b18 100644
--- a/src/sidebar/Tree.vala
+++ b/src/sidebar/Tree.vala
@@ -37,8 +37,7 @@ public class Sidebar.Tree : Gtk.TreeView {
private class RootWrapper : EntryWrapper {
public int root_position;
- public RootWrapper(Gtk.TreeModel model, Sidebar.Entry entry, Gtk.TreePath path, int root_position)
- requires (root_position >= 0) {
+ public RootWrapper(Gtk.TreeModel model, Sidebar.Entry entry, Gtk.TreePath path, int root_position) {
base (model, entry, path);
this.root_position = root_position;
@@ -71,8 +70,11 @@ public class Sidebar.Tree : Gtk.TreeView {
private bool mask_entry_selected_signal = false;
private weak EntryWrapper? selected_wrapper = null;
private Gtk.Menu? default_context_menu = null;
+ private bool expander_called_manually = false;
+ private int expander_special_count = 0;
private bool is_internal_drag_in_progress = false;
private Sidebar.Entry? internal_drag_source_entry = null;
+ private Gtk.TreeRowReference? old_path_ref = null;
public signal void entry_selected(Sidebar.SelectableEntry selectable);
@@ -99,6 +101,7 @@ public class Sidebar.Tree : Gtk.TreeView {
icon_renderer.follow_state = true;
text_column.pack_start(icon_renderer, false);
text_column.add_attribute(icon_renderer, "icon_name", Columns.ICON);
+ text_column.set_cell_data_func(icon_renderer, icon_renderer_function);
text_renderer = new Gtk.CellRendererText();
text_renderer.ellipsize = Pango.EllipsizeMode.END;
text_renderer.editing_canceled.connect(on_editing_canceled);
@@ -126,6 +129,9 @@ public class Sidebar.Tree : Gtk.TreeView {
selection.set_mode(Gtk.SelectionMode.BROWSE);
selection.set_select_function(on_selection);
+ test_expand_row.connect(on_toggle_row);
+ test_collapse_row.connect(on_toggle_row);
+
// It Would Be Nice if the target entries and actions were gleaned by querying each
// Sidebar.Entry as it was added, but that's a tad too complicated for our needs
// currently
@@ -152,6 +158,14 @@ public class Sidebar.Tree : Gtk.TreeView {
text_renderer.editing_started.disconnect(on_editing_started);
}
+ public void icon_renderer_function(Gtk.CellLayout layout, Gtk.CellRenderer renderer, Gtk.TreeModel
model, Gtk.TreeIter iter) {
+ EntryWrapper? wrapper = get_wrapper_at_iter(iter);
+ if (wrapper == null) {
+ return;
+ }
+ renderer.visible = !(wrapper.entry is Sidebar.Header);
+ }
+
private void on_drag_begin(Gdk.DragContext ctx) {
is_internal_drag_in_progress = true;
}
@@ -261,41 +275,72 @@ public class Sidebar.Tree : Gtk.TreeView {
public bool is_selected(Sidebar.Entry entry) {
EntryWrapper? wrapper = get_wrapper(entry);
- return (wrapper != null) ? get_selection().path_is_selected(wrapper.get_path()) : false;
+ // Even though get_selection() does not report its return type as nullable, it can be null
+ // if the window has been destroyed.
+ Gtk.TreeSelection selection = get_selection();
+ if (selection == null)
+ return false;
+
+ return (wrapper != null) ? selection.path_is_selected(wrapper.get_path()) : false;
}
public bool is_any_selected() {
return get_selection().count_selected_rows() != 0;
}
-
+
private Gtk.TreePath? get_selected_path() {
Gtk.TreeModel model;
- GLib.List<Gtk.TreePath> rows = get_selection().get_selected_rows(out model);
+ Gtk.TreeSelection? selection = get_selection();
+ if (selection == null){
+ return null;
+ }
+ GLib.List<Gtk.TreePath> rows = selection.get_selected_rows(out model);
assert(rows.length() == 0 || rows.length() == 1);
-
+
return rows.length() != 0 ? rows.nth_data(0) : null;
}
+
+ private string get_name_for_entry(Sidebar.Entry entry) {
+ string name = guarded_markup_escape_text(entry.get_sidebar_name());
+
+ Sidebar.EmphasizableEntry? emphasizable_entry = entry as Sidebar.EmphasizableEntry;
+ if (emphasizable_entry != null && emphasizable_entry.is_emphasized())
+ name = "<b>%s</b>".printf(name);
+
+ return name;
+ }
+
+ public virtual bool accept_cursor_changed() {
+ return true;
+ }
public override void cursor_changed() {
Gtk.TreePath? path = get_selected_path();
if (path == null) {
if (base.cursor_changed != null)
base.cursor_changed();
-
return;
}
EntryWrapper? wrapper = get_wrapper_at_path(path);
-
- selected_wrapper = wrapper;
- if (editing_disabled == 0 && wrapper != null)
- text_renderer.editable = wrapper.entry is Sidebar.RenameableEntry;
-
- if (wrapper != null && !mask_entry_selected_signal) {
- Sidebar.SelectableEntry? selectable = wrapper.entry as Sidebar.SelectableEntry;
- if (selectable != null)
- entry_selected(selectable);
+ if (selected_wrapper != wrapper) {
+ EntryWrapper old_wrapper = selected_wrapper;
+ selected_wrapper = wrapper;
+
+ if (editing_disabled == 0 && wrapper != null && wrapper.entry is Sidebar.RenameableEntry)
+ text_renderer.editable = ((Sidebar.RenameableEntry) wrapper.entry).is_user_renameable();
+
+ if (wrapper != null && !mask_entry_selected_signal) {
+ Sidebar.SelectableEntry? selectable = wrapper.entry as Sidebar.SelectableEntry;
+ if (selectable != null) {
+ if (accept_cursor_changed()) {
+ entry_selected(selectable);
+ } else {
+ place_cursor(old_wrapper.entry, true);
+ }
+ }
+ }
}
if (base.cursor_changed != null)
@@ -311,11 +356,14 @@ public class Sidebar.Tree : Gtk.TreeView {
Gtk.TreePath? path = get_selected_path();
if (path != null && editing_disabled > 0 && --editing_disabled == 0) {
EntryWrapper? wrapper = get_wrapper_at_path(path);
- text_renderer.editable = (wrapper != null && (wrapper.entry is Sidebar.RenameableEntry));
+ if (wrapper != null && (wrapper.entry is Sidebar.RenameableEntry))
+ text_renderer.editable = ((Sidebar.RenameableEntry) wrapper.entry).
+ is_user_renameable();
}
}
public void toggle_branch_expansion(Gtk.TreePath path, bool expand_all) {
+ expander_called_manually = true;
if (is_row_expanded(path))
collapse_row(path);
else
@@ -323,6 +371,7 @@ public class Sidebar.Tree : Gtk.TreeView {
}
public bool expand_to_entry(Sidebar.Entry entry) {
+ expander_called_manually = true;
EntryWrapper? wrapper = get_wrapper(entry);
if (wrapper == null)
return false;
@@ -333,6 +382,7 @@ public class Sidebar.Tree : Gtk.TreeView {
}
public void expand_to_first_child(Sidebar.Entry entry) {
+ expander_called_manually = true;
EntryWrapper? wrapper = get_wrapper(entry);
if (wrapper == null)
return;
@@ -436,7 +486,7 @@ public class Sidebar.Tree : Gtk.TreeView {
assert(!entry_map.has_key(entry));
entry_map.set(entry, wrapper);
- store.set(assoc_iter, Columns.NAME, guarded_markup_escape_text(entry.get_sidebar_name()));
+ store.set(assoc_iter, Columns.NAME, get_name_for_entry(entry));
store.set(assoc_iter, Columns.TOOLTIP, guarded_markup_escape_text(entry.get_sidebar_tooltip()));
store.set(assoc_iter, Columns.WRAPPER, wrapper);
load_entry_icons(assoc_iter);
@@ -449,6 +499,10 @@ public class Sidebar.Tree : Gtk.TreeView {
pageable.page_created.connect(on_sidebar_page_created);
pageable.destroying_page.connect(on_sidebar_destroying_page);
}
+
+ Sidebar.EmphasizableEntry? emphasizable = entry as Sidebar.EmphasizableEntry;
+ if (emphasizable != null)
+ emphasizable.is_emphasized_changed.connect(on_is_emphasized_changed);
Sidebar.RenameableEntry? renameable = entry as Sidebar.RenameableEntry;
if (renameable != null)
@@ -466,7 +520,7 @@ public class Sidebar.Tree : Gtk.TreeView {
EntryWrapper new_wrapper = new EntryWrapper(store, entry, store.get_path(new_iter));
entry_map.set(entry, new_wrapper);
- store.set(new_iter, Columns.NAME, guarded_markup_escape_text(entry.get_sidebar_name()));
+ store.set(new_iter, Columns.NAME, get_name_for_entry(entry));
store.set(new_iter, Columns.TOOLTIP, guarded_markup_escape_text(entry.get_sidebar_tooltip()));
store.set(new_iter, Columns.WRAPPER, new_wrapper);
load_entry_icons(new_iter);
@@ -558,6 +612,10 @@ public class Sidebar.Tree : Gtk.TreeView {
if (renameable != null)
renameable.sidebar_name_changed.disconnect(on_sidebar_name_changed);
+ Sidebar.EmphasizableEntry? emphasizable = entry as Sidebar.EmphasizableEntry;
+ if (emphasizable != null)
+ emphasizable.is_emphasized_changed.disconnect(on_is_emphasized_changed);
+
bool removed = entry_map.unset(entry);
assert(removed);
}
@@ -692,20 +750,28 @@ public class Sidebar.Tree : Gtk.TreeView {
store.set(wrapper.get_iter(), Columns.ICON, icon);
}
+
+ private void rename_entry(Sidebar.Entry entry) {
+ EntryWrapper? wrapper = get_wrapper(entry);
+ assert(wrapper != null);
+
+ store.set(wrapper.get_iter(), Columns.NAME, get_name_for_entry(entry));
+ }
+
+ private void on_sidebar_name_changed(Sidebar.Entry entry, string name) {
+ rename_entry(entry);
+ }
private void on_sidebar_page_created(Sidebar.PageRepresentative entry, Page page) {
page_created(entry, page);
}
- private void on_sidebar_destroying_page(Sidebar.PageRepresentative entry, Page page) {
- destroying_page(entry, page);
+ private void on_is_emphasized_changed(Sidebar.EmphasizableEntry entry, bool is_emphasized) {
+ rename_entry(entry);
}
- private void on_sidebar_name_changed(Sidebar.RenameableEntry entry, string name) {
- EntryWrapper? wrapper = get_wrapper(entry);
- assert(wrapper != null);
-
- store.set(wrapper.get_iter(), Columns.NAME, guarded_markup_escape_text(name));
+ private void on_sidebar_destroying_page(Sidebar.PageRepresentative entry, Page page) {
+ destroying_page(entry, page);
}
private void load_entry_icons(Gtk.TreeIter iter) {
@@ -799,6 +865,42 @@ public class Sidebar.Tree : Gtk.TreeView {
return true;
}
+ public bool on_toggle_row(Gtk.TreeIter iter, Gtk.TreePath path) {
+ // Determine whether to allow the row to toggle
+ EntryWrapper? wrapper = get_wrapper_at_iter(iter);
+ if (wrapper == null) {
+ return false; // don't affect things
+ }
+
+ // Most of the time, only allow manual toggles
+ bool should_allow_toggle = expander_called_manually;
+
+ // Cancel out the manual flag
+ expander_called_manually = false;
+
+ // If we are an expanded parent entry with content
+ if (is_row_expanded(path) && store.iter_has_child(iter) && wrapper.entry is Sidebar.SelectableEntry)
{
+ // We are taking a special action
+ expander_special_count++;
+ if (expander_special_count == 1) {
+ // Workaround that prevents arrows from double-toggling
+ return true;
+ } else {
+ // Toggle only if non-manual, as opposed to the usual behavior
+ should_allow_toggle = !should_allow_toggle;
+ }
+ } else {
+ // Reset the special behavior count
+ expander_special_count = 0;
+ }
+
+ if (should_allow_toggle) {
+ return false;
+ }
+ // Prevent branch expansion toggle
+ return true;
+ }
+
public override bool button_press_event(Gdk.EventButton event) {
Gtk.TreePath? path = get_path_from_event(event);
@@ -813,19 +915,29 @@ public class Sidebar.Tree : Gtk.TreeView {
popup_context_menu(path, event);
else
popup_default_context_menu(event);
- } else if (event.button == 1 && event.type == Gdk.EventType.2BUTTON_PRESS) {
- // double left click
- if (path != null) {
+ } else if (event.button == 1 && event.type == Gdk.EventType.BUTTON_PRESS) {
+ if (path == null) {
+ old_path_ref = null;
+ return base.button_press_event(event);
+ }
+
+ EntryWrapper? wrapper = get_wrapper_at_path(path);
+
+ if (wrapper == null) {
+ old_path_ref = null;
+ return base.button_press_event(event);
+ }
+
+ // Enable single click to toggle tree entries (bug 4985)
+ if (wrapper.entry is Sidebar.ExpandableEntry
+ || wrapper.entry is Sidebar.InternalDropTargetEntry) {
+ // all labels are InternalDropTargetEntries
toggle_branch_expansion(path, false);
-
- if (can_rename_path(path))
- return false;
}
- } else if (event.button == 1 && event.type == Gdk.EventType.BUTTON_PRESS) {
+
// Is this a click on an already-highlighted tree item?
- Gtk.TreePath? cursor_path = null;
- get_cursor(out cursor_path, null);
- if ((cursor_path != null) && (cursor_path.compare(path) == 0)) {
+ if ((old_path_ref != null) && (old_path_ref.get_path() != null)
+ && (old_path_ref.get_path().compare(path) == 0)) {
// yes, don't allow single-click editing, but
// pass the event on for dragging.
text_renderer.editable = false;
@@ -834,9 +946,13 @@ public class Sidebar.Tree : Gtk.TreeView {
// Got click on different tree item, make sure it is editable
// if it needs to be.
- if (path != null && get_wrapper_at_path(path).entry is Sidebar.RenameableEntry) {
+ if (wrapper.entry is Sidebar.RenameableEntry &&
+ ((Sidebar.RenameableEntry) wrapper.entry).is_user_renameable()) {
text_renderer.editable = true;
}
+
+ // Remember what tree item is highlighted for next time.
+ old_path_ref = new Gtk.TreeRowReference(store, path);
}
return base.button_press_event(event);
@@ -1026,6 +1142,9 @@ public class Sidebar.Tree : Gtk.TreeView {
if (renameable == null)
return false;
+ if (wrapper.entry is Sidebar.Header)
+ return false;
+
get_selection().select_path(path);
return true;
diff --git a/src/sidebar/common.vala b/src/sidebar/common.vala
index d698069..0f1bc05 100644
--- a/src/sidebar/common.vala
+++ b/src/sidebar/common.vala
@@ -5,13 +5,26 @@
*/
// A simple grouping Entry that is only expandable
-public class Sidebar.Grouping : Object, Sidebar.Entry, Sidebar.ExpandableEntry {
+public class Sidebar.Grouping : Object, Sidebar.Entry, Sidebar.ExpandableEntry,
+ Sidebar.RenameableEntry {
+
private string name;
+ private string? tooltip;
private string? icon;
- public Grouping(string name, string? icon) {
+ public Grouping(string name, string? icon, string? tooltip = null) {
this.name = name;
this.icon = icon;
+ this.tooltip = tooltip;
+ }
+
+ public void rename(string name) {
+ this.name = name;
+ sidebar_name_changed(name);
+ }
+
+ public bool is_user_renameable() {
+ return false;
}
public string get_sidebar_name() {
@@ -19,7 +32,7 @@ public class Sidebar.Grouping : Object, Sidebar.Entry, Sidebar.ExpandableEntry {
}
public string? get_sidebar_tooltip() {
- return name;
+ return tooltip;
}
public string? get_sidebar_icon() {
@@ -97,6 +110,26 @@ public class Sidebar.RootOnlyBranch : Sidebar.Branch {
}
}
+/**
+ * A header is an entry that is visually distinguished from its children. Bug 6397 recommends
+ * headers to appear bolded and without any icons. To prevent the icons from rendering, we set the
+ * icons to null in the base class @see Sidebar.Grouping. But we also go a step further by
+ * using a custom cell_data_function (@see Sidebar.Tree::icon_renderer_function) which ensures that
+ * header icons won't be rendered. This approach avoids the blank icon spacing issues.
+ */
+public class Sidebar.Header : Sidebar.Grouping, Sidebar.EmphasizableEntry {
+ private bool emphasized;
+
+ public Header(string name, bool emphasized = true) {
+ base(name, null);
+ this.emphasized = emphasized;
+ }
+
+ public bool is_emphasized() {
+ return emphasized;
+ }
+}
+
public interface Sidebar.Contextable : Object {
// Return null if the context menu should not be invoked for this event
public abstract Gtk.Menu? get_sidebar_context_menu(Gdk.EventButton? event);
diff --git a/src/tags/Branch.vala b/src/tags/Branch.vala
index 8ea1293..e68b2b1 100644
--- a/src/tags/Branch.vala
+++ b/src/tags/Branch.vala
@@ -8,7 +8,7 @@ public class Tags.Branch : Sidebar.Branch {
private Gee.HashMap<Tag, Tags.SidebarEntry> entry_map = new Gee.HashMap<Tag, Tags.SidebarEntry>();
public Branch() {
- base (new Tags.Grouping(),
+ base (new Tags.Header(),
Sidebar.Branch.Options.HIDE_IF_EMPTY
| Sidebar.Branch.Options.AUTO_OPEN_ON_NEW_CHILD
| Sidebar.Branch.Options.STARTUP_OPEN_GROUPING,
@@ -31,6 +31,10 @@ public class Tags.Branch : Sidebar.Branch {
return entry_map.get(tag);
}
+ public bool is_user_renameable() {
+ return true;
+ }
+
private static int comparator(Sidebar.Entry a, Sidebar.Entry b) {
if (a == b)
return 0;
@@ -118,13 +122,13 @@ public class Tags.Branch : Sidebar.Branch {
}
}
-public class Tags.Grouping : Sidebar.Grouping, Sidebar.InternalDropTargetEntry,
+public class Tags.Header : Sidebar.Header, Sidebar.InternalDropTargetEntry,
Sidebar.InternalDragSourceEntry, Sidebar.Contextable {
private Gtk.UIManager ui = new Gtk.UIManager();
private Gtk.Menu? context_menu = null;
- public Grouping() {
- base (_("Tags"), Resources.ICON_TAGS);
+ public Header() {
+ base (_("Tags"));
setup_context_menu();
}
@@ -229,6 +233,10 @@ public class Tags.SidebarEntry : Sidebar.SimplePageEntry, Sidebar.RenameableEntr
return new TagPage(tag);
}
+ public bool is_user_renameable() {
+ return true;
+ }
+
public void rename(string new_name) {
string? prepped = Tag.prep_tag_name(new_name);
if (prepped == null)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]