root/gui/graph_view.c @ a5d878cdc4363738db31c771dace7c14c4c75d3b

Revision a5d878cdc4363738db31c771dace7c14c4c75d3b, 11.6 KB (checked in by Nikita Zlobin <cook60020tmp@…>, 2 years ago)

gladish: Move help text from code to separate text file

  • Property mode set to 100644
Line 
1/* -*- Mode: C ; c-basic-offset: 2 -*- */
2/*
3 * LADI Session Handler (ladish)
4 *
5 * Copyright (C) 2009, 2010 Nedko Arnaudov <nedko@arnaudov.name>
6 *
7 **************************************************************************
8 * This file contains implementation of the graph view object
9 **************************************************************************
10 *
11 * LADI Session Handler is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * LADI Session Handler is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
23 * or write to the Free Software Foundation, Inc.,
24 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
25 */
26
27#include "common.h"
28#include "graph_view.h"
29#include "gtk_builder.h"
30#include "world_tree.h"
31#include "menu.h"
32#include "../proxies/room_proxy.h"
33#include "../common/catdup.h"
34#include "../common/file.h"
35
36struct graph_view
37{
38  struct list_head siblings;
39  char * view_name;
40  char * project_name;
41  char * full_name;
42  graph_canvas_handle graph_canvas;
43  graph_proxy_handle graph;
44  GtkWidget * canvas_widget;
45  ladish_app_supervisor_proxy_handle app_supervisor;
46  ladish_room_proxy_handle room;
47};
48
49struct list_head g_views;
50
51GtkScrolledWindow * g_main_scrolledwin;
52static struct graph_view * g_current_view;
53GtkWidget * g_view_label;
54
55const char * g_view_label_text = NULL;
56
57void view_init(void)
58{
59  g_view_label_text = read_file_contents(DATA_DIR "/help/default.txt");
60
61  g_main_scrolledwin = GTK_SCROLLED_WINDOW(get_gtk_builder_widget("main_scrolledwin"));
62  INIT_LIST_HEAD(&g_views);
63
64  g_view_label = gtk_label_new(g_view_label_text);
65  g_object_ref(g_view_label);
66  gtk_widget_show(g_view_label);
67
68  g_current_view = NULL;
69  gtk_scrolled_window_add_with_viewport(g_main_scrolledwin, g_view_label);
70}
71
72void announce_view_name_change(struct graph_view * view_ptr)
73{
74  world_tree_name_changed((graph_view_handle)view_ptr);
75
76  if (g_current_view == view_ptr)
77  {
78    set_main_window_title((graph_view_handle)view_ptr);
79  }
80}
81
82static void detach_canvas(struct graph_view * view_ptr)
83{
84  GtkWidget * child;
85
86  child = gtk_bin_get_child(GTK_BIN(g_main_scrolledwin));
87  if (child == view_ptr->canvas_widget)
88  {
89    gtk_container_remove(GTK_CONTAINER(g_main_scrolledwin), view_ptr->canvas_widget);
90    g_current_view = NULL;
91    gtk_widget_show(g_view_label);
92    gtk_scrolled_window_add_with_viewport(g_main_scrolledwin, g_view_label);
93  }
94}
95
96#define view_ptr ((struct graph_view *)context)
97
98static void app_added(void * context, uint64_t id, const char * name, bool running, bool terminal, uint8_t level)
99{
100  //log_info("app added. id=%"PRIu64", name='%s', %srunning, %s, level %u", id, name, running ? "" : "not ", terminal ? "terminal" : "shell", (unsigned int)level);
101  world_tree_add_app(context, id, name, running, terminal, level);
102}
103
104static void app_state_changed(void * context, uint64_t id, const char * name, bool running, bool terminal, uint8_t level)
105{
106  //log_info("app state changed. id=%"PRIu64", name='%s', %srunning, %s, level %u", id, name, running ? "" : "not ", terminal ? "terminal" : "shell", (unsigned int)level);
107  world_tree_app_state_changed(context, id, name, running, terminal, level);
108}
109
110static void app_removed(void * context, uint64_t id)
111{
112  //log_info("app removed. id=%"PRIu64, id);
113  world_tree_remove_app(context, id);
114}
115
116static void project_properties_changed(void * context, const char * project_dir, const char * project_name)
117{
118  bool empty;
119  char * project_name_buffer;
120  char * full_name_buffer;
121
122  log_info("Room '%s' project properties changed. name='%s', dir='%s'", view_ptr->view_name, project_name, project_dir);
123
124  empty = strlen(project_name) == 0;
125
126  if (!empty)
127  {
128    project_name_buffer = strdup(project_name);
129    if (project_name_buffer == NULL)
130    {
131      return;
132    }
133
134    full_name_buffer = catdup4(view_ptr->view_name, " (", project_name, ")");
135    if (full_name_buffer == NULL)
136    {
137      free(project_name_buffer);
138      return;
139    }
140
141    if (view_ptr->full_name != NULL && view_ptr->full_name != view_ptr->view_name)
142    {
143      free(view_ptr->full_name);
144    }
145
146    if (view_ptr->project_name != NULL)
147    {
148      free(view_ptr->project_name);
149    }
150
151    view_ptr->full_name = full_name_buffer;
152    view_ptr->project_name = project_name_buffer;
153  }
154  else
155  {
156    if (view_ptr->full_name != NULL && view_ptr->full_name != view_ptr->view_name)
157    {
158      free(view_ptr->full_name);
159    }
160
161    if (view_ptr->project_name != NULL)
162    {
163      free(view_ptr->project_name);
164    }
165
166    view_ptr->full_name = view_ptr->view_name;
167    view_ptr->project_name = NULL;
168  }
169
170  announce_view_name_change(view_ptr);
171}
172
173#undef view_ptr
174
175static void fill_canvas_menu(GtkMenu * menu)
176{
177  fill_view_popup_menu(menu, (graph_view_handle)g_current_view);
178}
179
180bool
181create_view(
182  const char * name,
183  const char * service,
184  const char * object,
185  bool graph_dict_supported,
186  bool app_supervisor_supported,
187  bool force_activate,
188  graph_view_handle * handle_ptr)
189{
190  struct graph_view * view_ptr;
191
192  view_ptr = malloc(sizeof(struct graph_view));
193  if (view_ptr == NULL)
194  {
195    log_error("malloc() failed for struct graph_view");
196    goto fail;
197  }
198
199  view_ptr->view_name = strdup(name);
200  if (view_ptr->view_name == NULL)
201  {
202    log_error("strdup() failed for \"%s\"", name);
203    goto free_view;
204  }
205
206  view_ptr->app_supervisor = NULL;
207  view_ptr->room = NULL;
208  view_ptr->full_name = view_ptr->view_name;
209  view_ptr->project_name = NULL;
210
211  if (!graph_proxy_create(service, object, graph_dict_supported, &view_ptr->graph))
212  {
213    goto free_name;
214  }
215
216  if (!graph_canvas_create(1600 * 2, 1200 * 2, fill_canvas_menu, &view_ptr->graph_canvas))
217  {
218    goto destroy_graph;
219  }
220
221  if (!graph_canvas_attach(view_ptr->graph_canvas, view_ptr->graph))
222  {
223    goto destroy_graph_canvas;
224  }
225
226  view_ptr->canvas_widget = canvas_get_widget(graph_canvas_get_canvas(view_ptr->graph_canvas));
227
228  list_add_tail(&view_ptr->siblings, &g_views);
229
230  gtk_widget_show(view_ptr->canvas_widget);
231
232  world_tree_add((graph_view_handle)view_ptr, force_activate);
233
234  if (app_supervisor_supported)
235  {
236    if (!ladish_app_supervisor_proxy_create(service, object, view_ptr, app_added, app_state_changed, app_removed, &view_ptr->app_supervisor))
237    {
238      goto remove_from_world_tree;
239    }
240  }
241
242  if (strcmp(object, STUDIO_OBJECT_PATH) != 0 && strcmp(object, JACKDBUS_OBJECT_PATH) != 0) /* TODO: this is a quite lame way to detect room views */
243  {
244    if (!ladish_room_proxy_create(service, object, view_ptr, project_properties_changed, &view_ptr->room))
245    {
246      goto free_app_supervisor;
247    }
248  }
249
250  if (!graph_proxy_activate(view_ptr->graph))
251  {
252    goto free_room_proxy;
253  }
254
255  *handle_ptr = (graph_view_handle)view_ptr;
256
257  return true;
258
259free_room_proxy:
260  if (view_ptr->room != NULL)
261  {
262    ladish_room_proxy_destroy(view_ptr->room);
263  }
264free_app_supervisor:
265  if (view_ptr->app_supervisor != NULL)
266  {
267    ladish_app_supervisor_proxy_destroy(view_ptr->app_supervisor);
268  }
269remove_from_world_tree:
270  list_del(&view_ptr->siblings);
271  if (!list_empty(&g_views))
272  {
273    world_tree_activate((graph_view_handle)list_entry(g_views.next, struct graph_view, siblings));
274  }
275  else
276  {
277    set_main_window_title(NULL);
278  }
279
280  detach_canvas(view_ptr);
281
282  world_tree_remove((graph_view_handle)view_ptr);
283destroy_graph_canvas:
284  graph_canvas_destroy(view_ptr->graph_canvas);
285destroy_graph:
286  graph_proxy_destroy(view_ptr->graph);
287free_name:
288  if (view_ptr->full_name != NULL && view_ptr->full_name != view_ptr->view_name)
289  {
290    free(view_ptr->full_name);
291  }
292  if (view_ptr->project_name != NULL)
293  {
294    free(view_ptr->project_name);
295  }
296  free(view_ptr->view_name);
297free_view:
298  free(view_ptr);
299fail:
300  return false;
301}
302
303static void attach_canvas(struct graph_view * view_ptr)
304{
305  GtkWidget * child;
306
307  child = gtk_bin_get_child(GTK_BIN(g_main_scrolledwin));
308
309  if (child == view_ptr->canvas_widget)
310  {
311    return;
312  }
313
314  if (child != NULL)
315  {
316    gtk_container_remove(GTK_CONTAINER(g_main_scrolledwin), child);
317  }
318
319  g_current_view = view_ptr;
320  gtk_container_add(GTK_CONTAINER(g_main_scrolledwin), view_ptr->canvas_widget);
321
322  //_main_scrolledwin->property_hadjustment().get_value()->set_step_increment(10);
323  //_main_scrolledwin->property_vadjustment().get_value()->set_step_increment(10);
324}
325
326#define view_ptr ((struct graph_view *)view)
327
328void destroy_view(graph_view_handle view)
329{
330  list_del(&view_ptr->siblings);
331  if (!list_empty(&g_views))
332  {
333    world_tree_activate((graph_view_handle)list_entry(g_views.next, struct graph_view, siblings));
334  }
335  else
336  {
337    set_main_window_title(NULL);
338  }
339
340  detach_canvas(view_ptr);
341
342  world_tree_remove(view);
343
344  graph_canvas_detach(view_ptr->graph_canvas);
345  graph_canvas_destroy(view_ptr->graph_canvas);
346  graph_proxy_destroy(view_ptr->graph);
347
348  if (view_ptr->app_supervisor != NULL)
349  {
350    ladish_app_supervisor_proxy_destroy(view_ptr->app_supervisor);
351  }
352
353  if (view_ptr->room != NULL)
354  {
355    ladish_room_proxy_destroy(view_ptr->room);
356  }
357
358  if (view_ptr->full_name != NULL && view_ptr->full_name != view_ptr->view_name)
359  {
360    free(view_ptr->full_name);
361  }
362  if (view_ptr->project_name != NULL)
363  {
364    free(view_ptr->project_name);
365  }
366  free(view_ptr->view_name);
367
368  free(view_ptr);
369}
370
371void activate_view(graph_view_handle view)
372{
373  attach_canvas(view_ptr);
374  set_main_window_title(view);
375  menu_view_activated(is_room_view(view));
376}
377
378const char * get_view_name(graph_view_handle view)
379{
380  return view_ptr->full_name;
381}
382
383const char * get_view_opath(graph_view_handle view)
384{
385  return graph_proxy_get_object(view_ptr->graph);
386}
387
388bool set_view_name(graph_view_handle view, const char * name)
389{
390  char * view_name_buffer;
391  char * full_name_buffer;
392
393  view_name_buffer = strdup(name);
394  if (view_name_buffer == NULL)
395  {
396    log_error("strdup() failed for \"%s\"", name);
397    return false;
398  }
399
400  if (view_ptr->project_name != NULL)
401  {
402    full_name_buffer = catdup4(view_name_buffer, " (", view_ptr->project_name, ")");
403    if (full_name_buffer == NULL)
404    {
405      free(view_name_buffer);
406      return false;
407    }
408  }
409  else
410  {
411    full_name_buffer = view_name_buffer;
412  }
413
414  if (view_ptr->full_name != NULL && view_ptr->full_name != view_ptr->view_name)
415  {
416    free(view_ptr->full_name);
417  }
418
419  free(view_ptr->view_name);
420
421  view_ptr->view_name = view_name_buffer;
422  view_ptr->full_name = full_name_buffer;
423
424  announce_view_name_change(view_ptr);
425
426  return true;
427}
428
429canvas_handle get_current_canvas(void)
430{
431  if (g_current_view == NULL)
432  {
433    return NULL;
434  }
435
436  return graph_canvas_get_canvas(g_current_view->graph_canvas);
437}
438
439const char * get_current_view_room_name(void)
440{
441  if (g_current_view == NULL || !is_room_view((graph_view_handle)g_current_view))
442  {
443    return NULL;
444  }
445
446  return g_current_view->view_name;
447}
448
449graph_view_handle get_current_view(void)
450{
451  return (graph_view_handle)g_current_view;
452}
453
454bool is_room_view(graph_view_handle view)
455{
456  return view_ptr->room != NULL;
457}
458
459bool app_run_custom(graph_view_handle view, const char * command, const char * name, bool run_in_terminal, uint8_t level)
460{
461  return ladish_app_supervisor_proxy_run_custom(view_ptr->app_supervisor, command, name, run_in_terminal, level);
462}
463
464ladish_app_supervisor_proxy_handle graph_view_get_app_supervisor(graph_view_handle view)
465{
466  return view_ptr->app_supervisor;
467}
468
469ladish_room_proxy_handle graph_view_get_room(graph_view_handle view)
470{
471  return view_ptr->room;
472}
Note: See TracBrowser for help on using the browser.