Skip to content

Commit 9b2fa5e

Browse files
committed
workspace: Do not depends on the library*.db order.
We make sure that default and memory DB are first added and then we list the others. This ensure that library.db (default) is present when adding the other workspace and avoid a crash due to null access. Closes #20140.
1 parent ca35370 commit 9b2fa5e

File tree

1 file changed

+31
-40
lines changed

1 file changed

+31
-40
lines changed

src/gui/workspace.c

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
This file is part of darktable,
3-
Copyright (C) 2025 darktable developers.
3+
Copyright (C) 2025-2026 darktable developers.
44
55
darktable is free software: you can redistribute it and/or modify
66
it under the terms of the GNU General Public License as published by
@@ -128,14 +128,26 @@ static void _workspace_new_db(GtkWidget *button, dt_workspace_t *session)
128128
_workspace_screen_destroy(session);
129129
}
130130

131-
static GtkBox *_insert_button(dt_workspace_t *session, const char *label)
131+
static GtkBox *_insert_button(dt_workspace_t *session,
132+
const char *label,
133+
const gboolean with_del)
132134
{
133135
GtkBox *box = GTK_BOX(dt_gui_hbox());
134136
GtkWidget *b = gtk_button_new_with_label(label);
135137
gtk_widget_set_hexpand(GTK_WIDGET(b), TRUE);
136138
dt_gui_box_add(box, b);
137139
g_signal_connect(G_OBJECT(b), "clicked",
138140
G_CALLBACK(_workspace_select_db), session);
141+
142+
if(with_del)
143+
{
144+
GtkWidget *del = dtgtk_button_new(dtgtk_cairo_paint_remove, 0, NULL);
145+
g_signal_connect(G_OBJECT(del), "clicked",
146+
G_CALLBACK(_workspace_delete_db), session);
147+
g_object_set_data(G_OBJECT(del), "db", b);
148+
dt_gui_box_add(box, del);
149+
}
150+
139151
dt_gui_dialog_add(session->db_screen, box);
140152
return box;
141153
}
@@ -170,56 +182,35 @@ gboolean dt_workspace_create(const char *datadir)
170182

171183
gtk_window_set_position(GTK_WINDOW(session->db_screen), GTK_WIN_POS_CENTER);
172184

173-
GList *dbs = dt_read_file_pattern(datadir, "library*.db");
185+
GList *dbs = dt_read_file_pattern(datadir, "library-*.db");
174186

175187
GtkWidget *l1 = gtk_label_new(_("select an existing workspace"));
176188
dt_gui_dialog_add(session->db_screen, l1);
177189

178190
const char *current_db = dt_conf_get_string("database");
179-
gboolean current_db_found = FALSE;
191+
gboolean current_db_found = strcmp("default", current_db) == 0 ? TRUE : FALSE;
180192

193+
// add default workspace
194+
GtkBox *box = _insert_button(session, _("default"), FALSE);
195+
// add a memory workspace just after default one
196+
box = _insert_button(session, _("memory"), FALSE);
197+
198+
// add now only the non default libraries
181199
for(GList *l = g_list_first(dbs); l; l = g_list_next(l))
182200
{
183201
char *name = (char *)l->data;
184-
const gboolean is_default = strcmp(name, "library.db") == 0;
185-
GtkBox *box = NULL;
186202

187-
if(is_default)
188-
{
189-
box = _insert_button(session, _("default"));
190-
}
191-
else if(g_str_has_prefix(name, "library-"))
192-
{
193-
// skip "library-" prefix
194-
char *f = name + strlen("library") + 1;
195-
// end with the dot
196-
char *e = f;
197-
while(*e != '.') e++;
198-
*e = '\0';
199-
200-
box = _insert_button(session, f);
201-
}
203+
// skip "library-" prefix
204+
char *f = name + strlen("library") + 1;
205+
// end with the dot
206+
char *e = f;
207+
while(*e != '.') e++;
208+
*e = '\0';
209+
210+
box = _insert_button(session, f, TRUE);
202211

203212
if(strcmp(name, current_db) == 0)
204213
current_db_found = TRUE;
205-
206-
if(is_default)
207-
{
208-
// add a memory workspace just after default one
209-
box = _insert_button(session, _("memory"));
210-
}
211-
else if(!is_default)
212-
{
213-
GList *bc = gtk_container_get_children(GTK_CONTAINER(box));
214-
GtkWidget *b = (GtkWidget *)g_list_first(bc)->data;
215-
g_list_free(bc);
216-
217-
GtkWidget *del = dtgtk_button_new(dtgtk_cairo_paint_remove, 0, NULL);
218-
g_signal_connect(G_OBJECT(del), "clicked",
219-
G_CALLBACK(_workspace_delete_db), session);
220-
g_object_set_data(G_OBJECT(del), "db", b);
221-
dt_gui_box_add(box, del);
222-
}
223214
}
224215

225216
g_list_free_full(dbs, g_free);
@@ -233,7 +224,7 @@ gboolean dt_workspace_create(const char *datadir)
233224

234225
GtkWidget *l2 = gtk_label_new(_("or create a new one"));
235226

236-
GtkBox *box = GTK_BOX(dt_gui_hbox());
227+
box = GTK_BOX(dt_gui_hbox());
237228
session->entry = gtk_entry_new();
238229
g_signal_connect(G_OBJECT(session->entry),
239230
"changed", G_CALLBACK(_workspace_entry_changed), session);

0 commit comments

Comments
 (0)