Merge lp:~jeremywootten/scratch/fix-ambiguous-tab-names-in-scratch into lp:~elementary-apps/scratch/scratch

Proposed by Jeremy Wootten
Status: Work in progress
Proposed branch: lp:~jeremywootten/scratch/fix-ambiguous-tab-names-in-scratch
Merge into: lp:~elementary-apps/scratch/scratch
Diff against target: 166 lines (+80/-6)
2 files modified
src/Services/Document.vala (+3/-5)
src/Widgets/DocumentView.vala (+77/-1)
To merge this branch: bzr merge lp:~jeremywootten/scratch/fix-ambiguous-tab-names-in-scratch
Reviewer Review Type Date Requested Status
Zisu Andrei (community) Needs Fixing
Review via email: mp+305375@code.launchpad.net

Description of the change

Where two tabs are opened at different folders that have the same name, label the tabs in a way that distinguishes them.

In this branch, enough of the parent path needed to distinguish them is prepended to the tab-name.

To post a comment you must log in.
Revision history for this message
Zisu Andrei (matzipan) wrote :

When I close the tab with similar name, I guess it should revert back to the original name.

review: Needs Fixing
Revision history for this message
Zisu Andrei (matzipan) wrote :

Some comments inline

review: Needs Fixing
1754. By Jeremy Wootten

Revert to normal name on close all tabs with same name

1755. By Jeremy Wootten

Address inline comments

Revision history for this message
Zisu Andrei (matzipan) wrote :

A comment inline.

And a short mention. I don't know how it would be best to handle this, but basically, while testing this, if the parent folder's name is big, say "fix-ambiguous-tab-names-in-scratch", the filename will actually end up truncated.

To deal with this, Atom, for example, append the folder name instead.

Sorry I didn't notice this earlier.

review: Needs Fixing
Revision history for this message
Jeremy Wootten (jeremywootten) wrote :

Better wait until the equivalent pantheon-files branch is merged so that a consistent approach can be used.

Unmerged revisions

1755. By Jeremy Wootten

Address inline comments

1754. By Jeremy Wootten

Revert to normal name on close all tabs with same name

1753. By Jeremy Wootten

Distinguish ambiguous tab names

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/Services/Document.vala'
2--- src/Services/Document.vala 2016-04-28 00:27:27 +0000
3+++ src/Services/Document.vala 2016-10-11 16:25:29 +0000
4@@ -44,6 +44,7 @@
5 public signal void doc_opened ();
6 public signal void doc_saved ();
7 public signal void doc_closed ();
8+ public signal void file_changed ();
9
10 // Widgets
11 public Scratch.Widgets.SourceView source_view;
12@@ -61,6 +62,7 @@
13 set {
14 source_file.set_location (value);
15 file_changed ();
16+ after_file_changed ();
17 }
18 }
19
20@@ -357,9 +359,6 @@
21 // Change syntax highlight
22 this.source_view.change_syntax_highlight_from_file (this.file);
23
24- // Change label
25- this.label = get_basename ();
26-
27 return true;
28 }
29
30@@ -426,7 +425,6 @@
31 box.pack_start (scroll, true, true, 0);
32 #endif
33 this.page = box;
34- this.label = get_basename ();
35 }
36
37 // Get file uri
38@@ -730,7 +728,7 @@
39 return this.file.query_exists ();
40 }
41
42- private void file_changed () {
43+ private void after_file_changed () {
44 if (mount != null) {
45 mount.unmounted.disconnect (unmounted_cb);
46 mount = null;
47
48=== modified file 'src/Widgets/DocumentView.vala'
49--- src/Widgets/DocumentView.vala 2015-11-09 21:25:02 +0000
50+++ src/Widgets/DocumentView.vala 2016-10-11 16:25:29 +0000
51@@ -217,7 +217,7 @@
52 }
53
54 private void on_doc_added (Granite.Widgets.Tab tab) {
55- var doc = tab as Services.Document;
56+ var doc = (Services.Document) tab;
57 doc.main_actions = window.main_actions;
58
59 this.docs.append (doc);
60@@ -225,6 +225,9 @@
61 doc.source_view.drag_data_received.connect (this.drag_received);
62 doc.source_view.drag_motion.connect (this.drag_motion);
63
64+ doc.label = check_for_tab_with_same_name (doc);
65+ doc.file_changed.connect (after_doc_file_changed);
66+
67 }
68
69 private void on_doc_removed (Granite.Widgets.Tab tab) {
70@@ -234,10 +237,15 @@
71 doc.source_view.focus_in_event.disconnect (this.on_focus_in_event);
72 doc.source_view.drag_data_received.disconnect (this.drag_received);
73 doc.source_view.drag_motion.disconnect (this.drag_motion);
74+ doc.file_changed.disconnect (after_doc_file_changed);
75
76 // Check if the view is empty
77 if (this.is_empty ()) {
78 empty ();
79+ } else {
80+ foreach (Services.Document d in docs) {
81+ after_doc_file_changed (d);
82+ }
83 }
84 }
85
86@@ -268,6 +276,10 @@
87 doc.focus ();
88 }
89
90+ private void after_doc_file_changed (Services.Document doc) {
91+ doc.label = check_for_tab_with_same_name (doc);
92+ }
93+
94 private bool on_focus_in_event () {
95 var doc = get_current_document ();
96 if (doc == null) {
97@@ -293,5 +305,69 @@
98 Gtk.drag_finish (ctx, true, false, time);
99 }
100 }
101+
102+ private string check_for_tab_with_same_name (Services.Document doc) {
103+ string name = doc.file.get_basename ();
104+ string new_name = name;
105+ string? path = doc.file.get_uri ();
106+
107+ foreach (Granite.Widgets.Tab tab in notebook.tabs) {
108+ var content = (Services.Document)(tab);
109+ if (content != doc) {
110+ string? content_path = content.file.get_uri ();
111+ string title = content.file.get_basename ();
112+ if (title == name && content_path != path) {
113+ if (title == tab.label) {
114+ Idle.add_full (GLib.Priority.LOW, () => {
115+ content.label = check_for_tab_with_same_name (content);
116+ return false;
117+ }); /* Trigger relabelling of conflicting tab (but not before this function finishes) */
118+ }
119+ new_name = append_parent (name, path, content_path); /*Also relabel this tab */
120+ }
121+ }
122+ }
123+
124+ return new_name;
125+ }
126+
127+ private string append_parent (string name, string path, string conflict_path) {
128+ string prefix = "";
129+ string conflict_prefix = "";
130+ string temp_path = path;
131+ string temp_conflict_path = conflict_path;
132+
133+ /* Add parent directories until path and conflict path differ */
134+ while (prefix == conflict_prefix) {
135+ var parent_path = get_parent_path_from_path (temp_path);
136+ var parent_conflict_path = get_parent_path_from_path (temp_conflict_path);
137+ prefix = Path.get_basename (parent_path) + Path.DIR_SEPARATOR_S + prefix;
138+ conflict_prefix = Path.get_basename (parent_conflict_path) + Path.DIR_SEPARATOR_S + conflict_prefix;
139+ temp_path = parent_path;
140+ temp_conflict_path = parent_conflict_path;
141+ }
142+
143+ return prefix + name;
144+ }
145+
146+ /*** Simplified version of PF.FileUtils function, with fewer checks ***/
147+ private string get_parent_path_from_path (string path) {
148+ if (path.length < 2) {
149+ return Path.DIR_SEPARATOR_S;
150+ }
151+
152+ StringBuilder sb = new StringBuilder (path);
153+ if (path.has_suffix (Path.DIR_SEPARATOR_S)) {
154+ sb.erase (sb.str.length - 1,-1);
155+ }
156+
157+ int last_separator = sb.str.last_index_of (Path.DIR_SEPARATOR_S);
158+ if (last_separator < 0) {
159+ last_separator = 0;
160+ }
161+
162+ sb.erase (last_separator, -1);
163+ return sb.str + Path.DIR_SEPARATOR_S;
164+ }
165 }
166 }

Subscribers

People subscribed via source and target branches