Skip to content

Commit b012811

Browse files
committed
add "merge tab" menu
1 parent fe76380 commit b012811

File tree

7 files changed

+92
-18
lines changed

7 files changed

+92
-18
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
- refactor of tilesource improves OME_TIFF modes
44
- fix menu state init
55
- save and restore more view settings
6+
- add "Merge column" and "Merge tab" submenus
67

78
## 9.0.9 2025/05/28
89

TODO

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
1-
- load ws with locked tab, rightclick menu on locked tab does not
2-
have tick selected
1+
- merge tab should not work when locked
32

4-
a bit tricky to fix
5-
6-
- the "new tab" icon is still broken in the windows build
3+
- scroll to view current column after tab merge
74

8-
- change "Merge into ..."
5+
- merge actions should be more robust
96

10-
split to "Merge from file ..." and "Merge column >" with a
11-
pullright listing all columns
7+
- load ws with locked tab, rightclick menu on locked tab does not
8+
have tick selected
129

13-
Same for merge in tab menu, except "Merge tab >"
10+
two tabs, lock one, menu on other also shows lock
1411

15-
Just does save/load for you
12+
a bit tricky to fix
1613

17-
how would we do a dynamic pullright menu?:n mes
14+
- the "new tab" icon is still broken in the windows build
1815

1916
# menu redesign
2017

src/gtk/workspaceviewlabel.ui

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<interface>
33

4-
<menu id="workspaceviewlabel-menu">
4+
<menu id="workspaceviewlabel_menu">
55
<section>
66
<item>
77
<attribute name='label' translatable='yes'>Rename</attribute>
@@ -15,9 +15,21 @@
1515
<attribute name='label' translatable='yes'>Duplicate</attribute>
1616
<attribute name='action'>win.tab-duplicate</attribute>
1717
</item>
18+
</section>
19+
20+
<!-- the thing at this position is replaced dynamically by
21+
workspaceviewlabel_menu() with the tab merge menu
22+
-->
23+
<section>
24+
<submenu>
25+
<attribute name='label' translatable='yes'>placeholder1</attribute>
26+
</submenu>
27+
</section>
28+
29+
<section>
1830
<item>
19-
<attribute name='label' translatable='yes'>Merge into ...</attribute>
20-
<attribute name='action'>win.tab-merge</attribute>
31+
<attribute name='label' translatable='yes'>Merge from file ...</attribute>
32+
<attribute name='action'>win.tab-merge-file</attribute>
2133
</item>
2234
<item>
2335
<attribute name='label' translatable='yes'>Save as ...</attribute>
@@ -57,7 +69,7 @@
5769

5870
<child>
5971
<object class="GtkPopoverMenu" id="right_click_menu">
60-
<property name="menu-model">workspaceviewlabel-menu</property>
72+
<property name="menu-model">workspaceviewlabel_menu</property>
6173
</object>
6274
</child>
6375

src/mainwindow.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,9 @@ static GActionEntry mainwindow_entries[] = {
594594
{ "tab-rename", mainwindow_view_action },
595595
{ "tab-select-all", mainwindow_view_action },
596596
{ "tab-duplicate", mainwindow_view_action },
597-
{ "tab-merge", mainwindow_view_action },
597+
// takes name of tab to merge as a param
598+
{ "tab-merge", mainwindow_view_action, "s" },
599+
{ "tab-merge-file", mainwindow_view_action },
598600
{ "tab-saveas", mainwindow_view_action },
599601
{ "tab-lock", action_toggle, NULL, "false", mainwindow_view_action },
600602
{ "tab-delete", mainwindow_view_action },

src/workspacegroupview.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ workspacegroupview_background_menu(GtkGestureClick *gesture,
228228
g_menu_remove(column_menu, 1);
229229
g_menu_insert_submenu(column_menu, 1, "Merge column",
230230
G_MENU_MODEL(columns));
231-
232231
}
233232
else if ((rview = workspacegroupview_pick_rowview(wsgview, x, y))) {
234233
mainwindow_set_action_view(VIEW(rview));

src/workspaceview.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,14 @@ workspaceview_merge(Workspaceview *wview)
824824
&workspaceview_merge_sub, wview);
825825
}
826826

827+
static void *
828+
workspaceview_find_workspace(Workspace *ws, void *a)
829+
{
830+
const char *name = (const char *) a;
831+
832+
return g_str_equal(IOBJECT(ws)->name, name) ? ws : NULL;
833+
}
834+
827835
static void
828836
workspaceview_action(GSimpleAction *action, GVariant *parameter, View *view)
829837
{
@@ -849,7 +857,36 @@ workspaceview_action(GSimpleAction *action, GVariant *parameter, View *view)
849857
}
850858
else if (g_str_equal(name, "tab-duplicate"))
851859
workspace_duplicate(ws);
852-
else if (g_str_equal(name, "tab-merge"))
860+
else if (g_str_equal(name, "tab-merge") &&
861+
parameter) {
862+
Workspacegroup *wsg = workspace_get_workspacegroup(ws);
863+
Workspace *from = workspacegroup_map(wsg,
864+
workspaceview_find_workspace,
865+
(void *) g_variant_get_string(parameter, NULL), NULL);
866+
char filename[VIPS_PATH_MAX];
867+
868+
if (!temp_name(filename, IOBJECT(from)->name, "ws")) {
869+
workspace_set_show_error(ws, TRUE);
870+
return;
871+
}
872+
873+
icontainer_current(ICONTAINER(wsg), ICONTAINER(ws));
874+
if (!workspacegroup_save_current(wsg, filename)) {
875+
workspace_set_show_error(ws, TRUE);
876+
return;
877+
}
878+
879+
if (!workspace_merge_file(ws, filename)) {
880+
workspace_set_show_error(ws, TRUE);
881+
return;
882+
}
883+
884+
unlinkf("%s", filename);
885+
886+
workspace_deselect_all(ws);
887+
symbol_recalculate_all();
888+
}
889+
else if (g_str_equal(name, "tab-merge-file"))
853890
workspaceview_merge(wview);
854891
else if (g_str_equal(name, "tab-saveas"))
855892
workspaceview_saveas(wview);

src/workspaceviewlabel.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ struct _Workspaceviewlabel {
4949
GtkWidget *lock;
5050
GtkWidget *error;
5151
GtkWidget *right_click_menu;
52+
GMenu *workspaceviewlabel_menu;
5253

5354
/* State.
5455
*/
@@ -137,10 +138,34 @@ workspaceviewlabel_init(Workspaceviewlabel *wviewlabel)
137138
gtk_widget_init_template(GTK_WIDGET(wviewlabel));
138139
}
139140

141+
static void *
142+
workspaceviewlabel_add_tab_item(Workspace *ws, void *user_data)
143+
{
144+
GMenu *tabs = G_MENU(user_data);
145+
146+
GMenuItem *item = g_menu_item_new(IOBJECT(ws)->name, NULL);
147+
GVariant *target = g_variant_new_string(IOBJECT(ws)->name);
148+
g_menu_item_set_action_and_target_value(item, "win.tab-merge", target);
149+
g_menu_append_item(tabs, item);
150+
151+
return NULL;
152+
}
153+
140154
static void
141155
workspaceviewlabel_menu(GtkGestureClick *gesture,
142156
guint n_press, double x, double y, Workspaceviewlabel *wviewlabel)
143157
{
158+
Workspaceview *wview = wviewlabel->wview;
159+
Workspace *ws = WORKSPACE(VOBJECT(wview)->iobject);
160+
Workspacegroup *wsg = workspace_get_workspacegroup(ws);
161+
162+
// generate the dynamic tab submenu
163+
GMenu *tabs = g_menu_new();
164+
workspacegroup_map(wsg, workspaceviewlabel_add_tab_item, tabs, NULL);
165+
GMenu *tab_menu = wviewlabel->workspaceviewlabel_menu;
166+
g_menu_remove(tab_menu, 1);
167+
g_menu_insert_submenu(tab_menu, 1, "Merge tab", G_MENU_MODEL(tabs));
168+
144169
mainwindow_set_action_view(VIEW(wviewlabel->wview));
145170

146171
gtk_popover_set_pointing_to(GTK_POPOVER(wviewlabel->right_click_menu),
@@ -213,6 +238,7 @@ workspaceviewlabel_class_init(WorkspaceviewlabelClass *class)
213238
BIND_VARIABLE(Workspaceviewlabel, lock);
214239
BIND_VARIABLE(Workspaceviewlabel, error);
215240
BIND_VARIABLE(Workspaceviewlabel, right_click_menu);
241+
BIND_VARIABLE(Workspaceviewlabel, workspaceviewlabel_menu);
216242

217243
BIND_CALLBACK(workspaceviewlabel_menu);
218244
BIND_CALLBACK(workspaceviewlabel_pressed);

0 commit comments

Comments
 (0)