use babel for all the shell scripts
[hkl.git] / gui / hkl-gui.c
blob00a52a32897a89f4e3be95b6ad3554cb7295f212
1 /* This file is part of the hkl library.
3 * The hkl library is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * The hkl library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with the hkl library. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright (C) 2003-2014 Synchrotron SOLEIL
17 * L'Orme des Merisiers Saint-Aubin
18 * BP 48 91192 GIF-sur-YVETTE CEDEX
20 * Authors: Picca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <float.h>
26 #include <math.h>
27 #include <stdio.h>
29 #include <glib.h>
30 #include <glib-object.h>
31 #include <gtk/gtk.h>
32 #include <gdk/gdk.h>
34 #include "hkl.h"
35 #include "hkl-gui.h"
36 #include "hkl-gui-macros.h"
37 #if HKL3D
38 # include <gtk/gtkgl.h>
39 # include "hkl-gui-3d.h"
40 #endif
41 #include "hkl-gui-pseudoaxes.h"
43 #define HKL_GUI_TYPE_WINDOW (hkl_gui_window_get_type ())
44 #define HKL_GUI_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), HKL_GUI_TYPE_WINDOW, HklGuiWindow))
45 #define HKL_GUI_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), HKL_GUI_TYPE_WINDOW, HklGuiWindowClass))
46 #define HKL_GUI_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HKL_GUI_TYPE_WINDOW))
47 #define HKL_GUI_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), HKL_GUI_TYPE_WINDOW))
48 #define HKL_GUI_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), HKL_GUI_TYPE_WINDOW, HklGuiWindowClass))
50 #define EMBED_BREAKPOINT asm volatile ("int3;")
52 G_DEFINE_TYPE (HklGuiWindow, hkl_gui_window, G_TYPE_OBJECT);
54 typedef enum {
55 REFLECTION_COL_INDEX = 0,
56 REFLECTION_COL_H,
57 REFLECTION_COL_K,
58 REFLECTION_COL_L,
59 REFLECTION_COL_FLAG,
60 REFLECTION_COL_REFLECTION,
61 REFLECTION_COL_N_COLUMNS
62 } ReflectionCol;
64 typedef enum {
65 AXIS_COL_AXIS = 0,
66 AXIS_COL_NAME,
67 AXIS_COL_READ,
68 AXIS_COL_WRITE,
69 AXIS_COL_MIN,
70 AXIS_COL_MAX,
71 AXIS_COL_N_COLUMNS
72 } AxisCol;
74 typedef enum {
75 PSEUDO_AXIS_COL_IDX = 0,
76 PSEUDO_AXIS_COL_ENGINE,
77 PSEUDO_AXIS_COL_NAME,
78 PSEUDO_AXIS_COL_READ,
79 PSEUDO_AXIS_COL_WRITE,
80 PSEUDO_AXIS_COL_N_COLUMNS
81 } PseudoAxisCol;
83 typedef enum {
84 PARAMETER_COL_PARAMETER = 0,
85 PARAMETER_COL_NAME,
86 PARAMETER_COL_VALUE,
87 PARAMETER_COL_N_COLUMNS
88 } ParameterCol;
90 typedef enum {
91 SAMPLE_COL_SAMPLE = 0,
92 SAMPLE_COL_NAME,
93 SAMPLE_COL_A,
94 SAMPLE_COL_B,
95 SAMPLE_COL_C,
96 SAMPLE_COL_ALPHA,
97 SAMPLE_COL_BETA,
98 SAMPLE_COL_GAMMA,
99 SAMPLE_COL_N_COLUMNS
100 } SampleCol;
102 typedef enum {
103 SOLUTION_COL_INDEX = 0,
104 SOLUTION_COL_HKL_GEOMETRY_LIST_ITEM,
105 SOLUTION_COL_N_COLUMNS
106 } SolutionCol;
108 typedef enum {
109 DIFFRACTOMETER_COL_NAME = 0,
110 DIFFRACTOMETER_COL_FACTORY,
111 DIFFRACTOMETER_COL_DIFFRACTOMETER,
112 DIFFRACTOMETER_COL_N_COLUMNS
113 } DiffractometerCol;
115 /******************/
116 /* Diffractometer */
117 /******************/
119 struct diffractometer_t {
120 HklFactory *factory;
121 HklGeometry *geometry;
122 HklDetector *detector;
123 HklEngineList *engines;
124 HklGeometryList *solutions;
128 static struct diffractometer_t *
129 create_diffractometer(HklFactory *factory)
131 struct diffractometer_t *self;
133 self = malloc(sizeof(*self));
135 self->factory = factory;
136 self->geometry = hkl_factory_create_new_geometry (factory);
137 self->engines = hkl_factory_create_new_engine_list (factory);
138 self->detector = hkl_detector_factory_new (HKL_DETECTOR_TYPE_0D);
139 self->solutions = NULL;
141 return self;
144 static void
145 delete_diffractometer(struct diffractometer_t *self)
147 hkl_geometry_free(self->geometry);
148 hkl_engine_list_free(self->engines);
149 hkl_detector_free(self->detector);
150 if(self->solutions)
151 hkl_geometry_list_free(self->solutions);
155 static void
156 dump_diffractometer(struct diffractometer_t *self)
158 /* hkl_geometry_fprintf(stderr, self->geometry); */
159 /* hkl_engine_list_fprintf(stderr, self->engines); */
160 /* hkl_detector_fprintf(stderr, self->detector); */
163 static void
164 diffractometer_set_sample(struct diffractometer_t *self,
165 HklSample *sample)
167 hkl_engine_list_init(self->engines,
168 self->geometry,
169 self->detector,
170 sample);
171 hkl_engine_list_get(self->engines);
174 static void
175 diffractometer_set_wavelength(struct diffractometer_t *self,
176 double wavelength)
178 if(hkl_geometry_wavelength_set(self->geometry,
179 wavelength, HKL_UNIT_USER, NULL))
180 hkl_engine_list_get(self->engines);
183 static gboolean
184 diffractometer_set_solutions(struct diffractometer_t *self, HklGeometryList *solutions)
186 if(solutions){
187 if(self->solutions)
188 hkl_geometry_list_free(self->solutions);
189 self->solutions = solutions;
192 return NULL != solutions;
195 static gboolean
196 diffractometer_pseudo_axes_values_set(struct diffractometer_t *self,
197 HklEngine *engine, gdouble values[], guint n_values,
198 GError **error)
200 HklGeometryList *solutions;
203 solutions = hkl_engine_pseudo_axes_values_set(engine, values, n_values, HKL_UNIT_USER, error);
205 return diffractometer_set_solutions(self, solutions);
208 static void
209 diffractometer_set_solution(struct diffractometer_t *self,
210 const HklGeometryListItem *item)
212 hkl_engine_list_select_solution(self->engines, item);
216 /****************/
217 /* HklGuiWindow */
218 /****************/
220 struct _HklGuiWindowPrivate {
221 GtkBuilder* builder;
222 GtkLabel* label_UB11;
223 GtkLabel* label_UB12;
224 GtkLabel* label_UB13;
225 GtkLabel* label_UB21;
226 GtkLabel* label_UB22;
227 GtkLabel* label_UB23;
228 GtkLabel* label_UB31;
229 GtkLabel* label_UB32;
230 GtkLabel* label_UB33;
231 GtkButton* button2;
232 GtkSpinButton* spinbutton_a;
233 GtkSpinButton* spinbutton_b;
234 GtkSpinButton* spinbutton_c;
235 GtkSpinButton* spinbutton_alpha;
236 GtkSpinButton* spinbutton_beta;
237 GtkSpinButton* spinbutton_gamma;
238 GtkSpinButton* spinbutton_a_min;
239 GtkSpinButton* spinbutton_b_min;
240 GtkSpinButton* spinbutton_c_min;
241 GtkSpinButton* spinbutton_alpha_min;
242 GtkSpinButton* spinbutton_beta_min;
243 GtkSpinButton* spinbutton_gamma_min;
244 GtkSpinButton* spinbutton_a_max;
245 GtkSpinButton* spinbutton_b_max;
246 GtkSpinButton* spinbutton_c_max;
247 GtkSpinButton* spinbutton_alpha_max;
248 GtkSpinButton* spinbutton_beta_max;
249 GtkSpinButton* spinbutton_gamma_max;
250 GtkSpinButton* spinbutton_lambda;
251 GtkSpinButton* spinbutton_a_star;
252 GtkSpinButton* spinbutton_b_star;
253 GtkSpinButton* spinbutton_c_star;
254 GtkSpinButton* spinbutton_alpha_star;
255 GtkSpinButton* spinbutton_beta_star;
256 GtkSpinButton* spinbutton_gamma_star;
257 GtkSpinButton* spinbutton_ux;
258 GtkSpinButton* spinbutton_uy;
259 GtkSpinButton* spinbutton_uz;
260 GtkSpinButton* spinbutton_U11;
261 GtkSpinButton* spinbutton_U12;
262 GtkSpinButton* spinbutton_U13;
263 GtkSpinButton* spinbutton_U21;
264 GtkSpinButton* spinbutton_U22;
265 GtkSpinButton* spinbutton_U23;
266 GtkSpinButton* spinbutton_U31;
267 GtkSpinButton* spinbutton_U32;
268 GtkSpinButton* spinbutton_U33;
269 GtkCheckButton* checkbutton_a;
270 GtkCheckButton* checkbutton_b;
271 GtkCheckButton* checkbutton_c;
272 GtkCheckButton* checkbutton_alpha;
273 GtkCheckButton* checkbutton_beta;
274 GtkCheckButton* checkbutton_gamma;
275 GtkCheckButton* checkbutton_ux;
276 GtkCheckButton* checkbutton_uy;
277 GtkCheckButton* checkbutton_uz;
278 GtkTreeView* treeview_reflections;
279 GtkTreeView* treeview_crystals;
280 GtkTreeView* treeview_axes;
281 GtkTreeView* treeview_pseudo_axes;
282 GtkTreeView* treeview_solutions;
283 GtkToolButton* toolbutton_add_reflection;
284 GtkToolButton* toolbutton_goto_reflection;
285 GtkToolButton* toolbutton_del_reflection;
286 GtkToolButton* toolbutton_setUB;
287 GtkToolButton* toolbutton_computeUB;
288 GtkToolButton* toolbutton_add_crystal;
289 GtkToolButton* toolbutton_copy_crystal;
290 GtkToolButton* toolbutton_del_crystal;
291 GtkToolButton* toolbutton_affiner;
292 GtkStatusbar* statusbar;
293 GtkImageMenuItem* menuitem5;
294 GtkVBox* box_info_bar; /* fake for the infor bar */
295 GtkVBox* vbox7;
296 GtkVBox* vbox2;
297 GtkDialog* dialog1;
298 GtkButton* button1;
299 GtkComboBox* combobox1;
300 GtkListStore* liststore_diffractometer;
301 GtkListStore* liststore_axis;
302 GtkListStore* liststore_pseudo_axes;
303 GtkListStore* liststore_solutions;
304 GtkListStore* liststore_reflections;
305 GtkListStore* liststore_crystals;
307 GtkInfoBar *info_bar;
308 GtkLabel *info_message;
310 darray(HklGuiEngine *) pseudo_frames;
312 #if HKL3D
313 HklGui3D *frame3d;
314 #endif
315 struct diffractometer_t *diffractometer; /* unowned */
316 HklSample *sample; /* unowned */
317 HklLattice *reciprocal;
320 #define HKL_GUI_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), HKL_GUI_TYPE_WINDOW, HklGuiWindowPrivate))
322 static gboolean
323 finalize_liststore_diffractometer(GtkTreeModel *model,
324 GtkTreePath *path,
325 GtkTreeIter *iter,
326 gpointer data)
328 struct diffractometer_t *diffractometer;
330 gtk_tree_model_get(model, iter,
331 DIFFRACTOMETER_COL_DIFFRACTOMETER, &diffractometer,
332 -1);
333 delete_diffractometer(diffractometer);
334 return FALSE;
337 static gboolean
338 finalize_liststore_samples(GtkTreeModel *model,
339 GtkTreePath *path,
340 GtkTreeIter *iter,
341 gpointer data)
343 HklSample *sample = NULL;
345 gtk_tree_model_get(model, iter,
346 SAMPLE_COL_SAMPLE, &sample,
347 -1);
348 hkl_sample_free(sample);
349 return FALSE;
352 static void
353 finalize (GObject* object)
355 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(object);
357 g_object_unref(priv->builder);
359 darray_free(priv->pseudo_frames);
361 gtk_tree_model_foreach(GTK_TREE_MODEL(priv->liststore_diffractometer),
362 finalize_liststore_diffractometer,
363 NULL);
365 gtk_tree_model_foreach(GTK_TREE_MODEL(priv->liststore_crystals),
366 finalize_liststore_samples,
367 NULL);
369 G_OBJECT_CLASS (hkl_gui_window_parent_class)->finalize (object);
372 HklGuiWindow* hkl_gui_window_new (void)
374 return g_object_new (HKL_GUI_TYPE_WINDOW, NULL);
377 static void
378 hkl_gui_window_get_widgets_and_objects_from_ui (HklGuiWindow* self)
380 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
381 GtkBuilder* builder;
383 g_return_if_fail (self != NULL);
385 priv->builder = builder = gtk_builder_new ();
386 get_ui(builder, "ghkl.ui");
388 get_object(builder, GTK_LIST_STORE, priv, liststore_diffractometer);
389 get_object(builder, GTK_LIST_STORE, priv, liststore_axis);
390 get_object(builder, GTK_LIST_STORE, priv, liststore_pseudo_axes);
391 get_object(builder, GTK_LIST_STORE, priv, liststore_reflections);
392 get_object(builder, GTK_LIST_STORE, priv, liststore_crystals);
394 get_object(builder, GTK_LABEL, priv, label_UB11);
395 get_object(builder, GTK_LABEL, priv, label_UB12);
396 get_object(builder, GTK_LABEL, priv, label_UB13);
397 get_object(builder, GTK_LABEL, priv, label_UB21);
398 get_object(builder, GTK_LABEL, priv, label_UB22);
399 get_object(builder, GTK_LABEL, priv, label_UB23);
400 get_object(builder, GTK_LABEL, priv, label_UB31);
401 get_object(builder, GTK_LABEL, priv, label_UB32);
402 get_object(builder, GTK_LABEL, priv, label_UB33);
404 get_object(builder, GTK_BUTTON, priv, button2);
406 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_a);
407 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_a_min);
408 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_a_max);
409 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_a_star);
411 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_b);
412 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_b_min);
413 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_b_max);
414 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_b_star);
416 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_c);
417 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_c_min);
418 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_c_max);
419 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_c_star);
421 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_alpha);
422 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_alpha_min);
423 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_alpha_max);
424 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_alpha_star);
426 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_beta);
427 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_beta_min);
428 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_beta_max);
429 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_beta_star);
431 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_gamma);
432 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_gamma_min);
433 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_gamma_max);
434 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_gamma_star);
436 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_lambda);
438 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_ux);
439 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_uy);
440 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_uz);
442 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U11);
443 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U12);
444 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U13);
445 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U21);
446 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U22);
447 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U23);
448 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U31);
449 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U32);
450 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U33);
453 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_a);
454 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_b);
455 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_c);
456 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_alpha);
457 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_beta);
458 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_gamma);
459 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_ux);
460 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_uy);
461 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_uz);
464 get_object(builder, GTK_TREE_VIEW, priv, treeview_reflections);
465 get_object(builder, GTK_TREE_VIEW, priv, treeview_crystals);
466 get_object(builder, GTK_TREE_VIEW, priv, treeview_axes);
467 get_object(builder, GTK_TREE_VIEW, priv, treeview_pseudo_axes);
468 get_object(builder, GTK_TREE_VIEW, priv, treeview_solutions);
470 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_add_reflection);
471 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_goto_reflection);
472 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_del_reflection);
473 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_setUB);
474 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_computeUB);
475 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_add_crystal);
476 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_copy_crystal);
477 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_del_crystal);
478 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_affiner);
480 get_object(builder, GTK_STATUSBAR, priv, statusbar);
482 get_object(builder, GTK_IMAGE_MENU_ITEM, priv, menuitem5);
484 get_object(builder, GTK_VBOX, priv, vbox7);
485 get_object(builder, GTK_VBOX, priv, vbox2);
486 get_object(builder, GTK_VBOX, priv, box_info_bar);
488 get_object(builder, GTK_DIALOG, priv, dialog1);
490 get_object(builder, GTK_COMBO_BOX, priv, combobox1);
492 gtk_builder_connect_signals (builder, self);
495 static void
496 update_pseudo_axes_frames (HklGuiWindow* self)
498 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
499 HklGuiEngine **engine;
501 g_return_if_fail (self != NULL);
503 darray_foreach(engine, priv->pseudo_frames){
504 hkl_gui_engine_update(*engine);
508 static void
509 raise_error(HklGuiWindow *self, GError **error)
511 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
513 g_return_if_fail (error != NULL);
515 /* show an error message */
516 gtk_label_set_text (GTK_LABEL (priv->info_message),
517 (*error)->message);
518 gtk_info_bar_set_message_type (priv->info_bar,
519 GTK_MESSAGE_ERROR);
520 gtk_widget_show (GTK_WIDGET(priv->info_bar));
522 g_clear_error(error);
525 static void
526 clear_error(HklGuiWindow *self, GError **error)
528 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
530 g_return_if_fail (self != NULL);
532 gtk_widget_hide(GTK_WIDGET(priv->info_bar));
535 static gboolean
536 _update_axis (GtkTreeModel *model, GtkTreePath *path,
537 GtkTreeIter *iter, gpointer data)
539 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(data);
540 const char *name;
541 const HklParameter *axis;
542 gdouble value, min, max;
544 gtk_tree_model_get (model, iter,
545 AXIS_COL_NAME, &name,
546 -1);
548 axis = hkl_geometry_axis_get(priv->diffractometer->geometry, name, NULL);
549 hkl_parameter_min_max_get(axis, &min, &max, HKL_UNIT_USER);
550 value = hkl_parameter_value_get(axis, HKL_UNIT_USER);
552 gtk_list_store_set(GTK_LIST_STORE(model), iter,
553 AXIS_COL_READ, value,
554 AXIS_COL_WRITE, value,
555 AXIS_COL_MIN, min,
556 AXIS_COL_MAX, max,
557 -1);
558 return FALSE;
561 static void
562 update_axes (HklGuiWindow* self)
564 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
566 g_return_if_fail (self != NULL);
568 gtk_tree_model_foreach(GTK_TREE_MODEL(priv->liststore_axis),
569 _update_axis,
570 self);
573 static gboolean
574 _update_pseudo_axes (GtkTreeModel *model, GtkTreePath *path,
575 GtkTreeIter *iter, gpointer data)
577 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(data);
578 const char *name;
579 const HklEngine *engine;
580 const HklParameter *pseudo_axis;
581 gdouble value, min, max;
583 gtk_tree_model_get (model, iter,
584 PSEUDO_AXIS_COL_ENGINE, &engine,
585 PSEUDO_AXIS_COL_NAME, &name,
586 -1);
588 pseudo_axis = hkl_engine_pseudo_axis_get(engine, name, NULL);
589 hkl_parameter_min_max_get(pseudo_axis, &min, &max, HKL_UNIT_USER);
590 value = hkl_parameter_value_get(pseudo_axis, HKL_UNIT_USER);
592 gtk_list_store_set(GTK_LIST_STORE(model), iter,
593 PSEUDO_AXIS_COL_READ, value,
594 PSEUDO_AXIS_COL_WRITE, value,
595 -1);
596 return FALSE;
599 static void
600 update_pseudo_axes (HklGuiWindow* self)
602 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
604 g_return_if_fail (self != NULL);
606 gtk_tree_model_foreach(GTK_TREE_MODEL(priv->liststore_pseudo_axes),
607 _update_pseudo_axes,
608 self);
611 static void
612 update_solutions (HklGuiWindow* self)
614 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
615 GtkTreeIter iter = {0};
617 g_return_if_fail (self != NULL);
618 g_return_if_fail (priv->diffractometer->solutions != NULL);
620 const HklGeometryListItem *item;
621 gtk_list_store_clear(priv->liststore_solutions);
623 gint n_values = gtk_tree_model_get_n_columns (GTK_TREE_MODEL(priv->liststore_solutions));
624 GValue *values = g_new0(GValue, n_values);
625 gint *columns = g_new0(gint, n_values);
626 gint i;
628 /* prepare the GValue before using them */
629 g_value_init(&values[SOLUTION_COL_INDEX], G_TYPE_INT);
630 g_value_init(&values[SOLUTION_COL_HKL_GEOMETRY_LIST_ITEM], G_TYPE_POINTER);
631 for(i=SOLUTION_COL_N_COLUMNS; i<n_values; ++i)
632 g_value_init(&values[i], G_TYPE_DOUBLE);
634 i=0;
635 HKL_GEOMETRY_LIST_FOREACH(item, priv->diffractometer->solutions){
636 const HklGeometry *geometry = hkl_geometry_list_item_geometry_get(item);
637 unsigned int n_v = darray_size(*hkl_geometry_axes_names_get(geometry));
638 double v[n_v];
640 hkl_geometry_axes_values_get(geometry, v, n_v, HKL_UNIT_USER);
642 g_value_set_int(&values[SOLUTION_COL_INDEX], i);
643 g_value_set_pointer(&values[SOLUTION_COL_HKL_GEOMETRY_LIST_ITEM], (gpointer)item);
644 columns[SOLUTION_COL_INDEX] = SOLUTION_COL_INDEX;
645 columns[SOLUTION_COL_HKL_GEOMETRY_LIST_ITEM] = SOLUTION_COL_HKL_GEOMETRY_LIST_ITEM;
647 for(unsigned int j=0; j<n_v; ++j){
648 g_value_set_double(&values[SOLUTION_COL_N_COLUMNS + j], v[j]);
649 columns[SOLUTION_COL_N_COLUMNS + j] = SOLUTION_COL_N_COLUMNS + j;
651 gtk_list_store_insert_with_valuesv(priv->liststore_solutions,
652 &iter, i,
653 columns, values, n_values);
654 i++;
656 g_free(columns);
657 g_free(values);
660 static void
661 update_source (HklGuiWindow* self)
663 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
665 g_return_if_fail (self != NULL);
667 gtk_spin_button_set_value (priv->spinbutton_lambda,
668 hkl_geometry_wavelength_get(priv->diffractometer->geometry,
669 HKL_UNIT_USER));
672 static void
673 update_reflections (HklGuiWindow *self)
675 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
677 gtk_list_store_clear (priv->liststore_reflections);
679 if(priv->sample){
680 HklSampleReflection* reflection;
681 guint index = 0;
683 HKL_SAMPLE_REFLECTIONS_FOREACH(reflection, priv->sample){
684 GtkTreeIter iter = {0};
685 gdouble h, k, l;
686 gboolean flag;
688 hkl_sample_reflection_hkl_get(reflection, &h, &k, &l);
689 flag = hkl_sample_reflection_flag_get(reflection);
691 gtk_list_store_append (priv->liststore_reflections, &iter);
693 gtk_list_store_set (priv->liststore_reflections,
694 &iter,
695 REFLECTION_COL_INDEX, index++,
696 REFLECTION_COL_H, h,
697 REFLECTION_COL_K, k,
698 REFLECTION_COL_L, l,
699 REFLECTION_COL_FLAG, flag,
700 REFLECTION_COL_REFLECTION, reflection,
701 -1);
706 static void
707 update_3d(HklGuiWindow *self)
709 #ifdef HKL3D
710 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
712 if(priv->frame3d){
713 hkl_gui_3d_is_colliding(priv->frame3d);
714 hkl_gui_3d_invalidate(priv->frame3d);
716 #endif
719 static void
720 pseudo_axes_frame_changed_cb (HklGuiEngine *gui_engine, HklGuiWindow *self)
722 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
723 HklEngine *engine;
724 GtkListStore *liststore;
725 guint n_values;
726 GtkTreeIter iter = {0};
727 gboolean valid;
728 GError *error = NULL;
730 g_object_get(gui_engine,
731 "engine", &engine,
732 "liststore", &liststore,
733 NULL);
735 n_values = darray_size(*hkl_engine_pseudo_axes_names_get(engine));
736 gdouble values[n_values];
738 /* extract all the values from the listore */
739 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(liststore), &iter);
740 while(valid){
741 guint it_idx;
742 gdouble it_value;
744 gtk_tree_model_get (GTK_TREE_MODEL(liststore), &iter,
745 PSEUDO_COL_IDX, &it_idx,
746 PSEUDO_COL_VALUE, &it_value,
747 -1);
749 values[it_idx] = it_value;
751 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(liststore), &iter);
754 if(diffractometer_pseudo_axes_values_set(priv->diffractometer, engine,
755 values, n_values, &error)){
756 update_axes (self);
757 update_pseudo_axes (self);
758 update_pseudo_axes_frames (self);
759 update_solutions (self);
760 update_3d(self);
761 }else
762 raise_error(self, &error);
764 g_object_unref(liststore);
768 static void
769 set_up_pseudo_axes_frames (HklGuiWindow* self)
771 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
772 HklGuiEngine **pseudo;
773 GtkVBox* vbox2;
774 HklEngine **engine;
775 darray_engine *engines;
777 g_return_if_fail (self != NULL);
779 darray_foreach (pseudo, priv->pseudo_frames){
780 gtk_container_remove(GTK_CONTAINER(priv->vbox2),
781 GTK_WIDGET (hkl_gui_engine_get_frame (*pseudo)));
782 g_object_unref(*pseudo);
784 darray_size (priv->pseudo_frames) = 0;
786 engines = hkl_engine_list_engines_get (priv->diffractometer->engines);
787 darray_foreach (engine, *engines){
788 HklGuiEngine *pseudo;
790 pseudo = hkl_gui_engine_new (*engine);
791 darray_append(priv->pseudo_frames, pseudo);
792 gtk_container_add (GTK_CONTAINER (priv->vbox2),
793 GTK_WIDGET (hkl_gui_engine_get_frame(pseudo)));
795 g_signal_connect_object (pseudo,
796 "changed",
797 G_CALLBACK(pseudo_axes_frame_changed_cb),
798 self, 0);
801 gtk_widget_show_all (GTK_WIDGET (priv->vbox2));
805 static void
806 set_up_diffractometer_model (HklGuiWindow* self)
808 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
809 unsigned int i, n;
810 HklFactory **factories;
812 g_return_if_fail (self != NULL);
814 factories = hkl_factory_get_all(&n);
815 for(i=0; i<n; ++i){
816 GtkTreeIter iter = {0};
818 gtk_list_store_append (priv->liststore_diffractometer, &iter);
819 gtk_list_store_set (priv->liststore_diffractometer, &iter,
820 DIFFRACTOMETER_COL_NAME, hkl_factory_name_get(factories[i]),
821 DIFFRACTOMETER_COL_FACTORY, factories[i],
822 DIFFRACTOMETER_COL_DIFFRACTOMETER, NULL,
823 -1);
827 static void
828 set_up_tree_view_axes (HklGuiWindow* self)
830 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
831 const darray_string *axes;
832 const char **axis;
833 GtkCellRenderer* renderer = NULL;
834 GtkTreeViewColumn* column = NULL;
835 GList* columns;
836 GtkTreeIter iter = {0};
838 gtk_list_store_clear (priv->liststore_axis);
840 axes = hkl_geometry_axes_names_get(priv->diffractometer->geometry);
841 darray_foreach (axis, *axes){
842 gtk_list_store_append (priv->liststore_axis, &iter);
843 gtk_list_store_set (priv->liststore_axis, &iter,
844 AXIS_COL_NAME, *axis,
845 -1);
848 update_axes (self);
851 static void
852 set_up_tree_view_pseudo_axes (HklGuiWindow* self)
854 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
855 HklParameter **parameter;
856 HklEngine **engine;
857 const darray_engine *engines;
859 gtk_list_store_clear(priv->liststore_pseudo_axes);
861 engines = hkl_engine_list_engines_get(priv->diffractometer->engines);
862 darray_foreach(engine, *engines){
863 const darray_string *pseudo_axes = hkl_engine_pseudo_axes_names_get(*engine);
864 GtkTreeIter iter = {0};
865 guint idx;
867 for(idx=0; idx<darray_size(*pseudo_axes); ++idx){
868 gtk_list_store_append (priv->liststore_pseudo_axes, &iter);
869 gtk_list_store_set (priv->liststore_pseudo_axes, &iter,
870 PSEUDO_AXIS_COL_IDX, idx,
871 PSEUDO_AXIS_COL_ENGINE, *engine,
872 PSEUDO_AXIS_COL_NAME, darray_item(*pseudo_axes, idx),
873 -1);
877 update_pseudo_axes (self);
880 static void
881 _delete_column(gpointer data,
882 gpointer user_data)
884 gtk_tree_view_remove_column (GTK_TREE_VIEW(user_data),
885 GTK_TREE_VIEW_COLUMN(data));
888 static void
889 set_up_tree_view_solutions (HklGuiWindow* self)
891 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
892 const darray_string *axes;
893 int i;
894 GtkCellRenderer* renderer = NULL;
895 GtkTreeViewColumn* column = NULL;
896 GList* columns;
897 GType* types;
898 gint n_columns;
900 axes = hkl_geometry_axes_names_get(priv->diffractometer->geometry);
902 n_columns = SOLUTION_COL_N_COLUMNS + darray_size(*axes);
904 /* prepare types for the liststore */
905 types = g_new0 (GType, n_columns);
907 /* first remove all the columns */
908 columns = gtk_tree_view_get_columns (priv->treeview_solutions);
909 g_list_foreach(columns, _delete_column, priv->treeview_solutions);
910 g_list_free(columns);
912 /* now add the index column */
913 renderer = gtk_cell_renderer_text_new ();
914 column = gtk_tree_view_column_new_with_attributes ("index",
915 renderer, "text",
916 SOLUTION_COL_INDEX, NULL);
918 gtk_tree_view_append_column (priv->treeview_solutions, column);
920 types[0] = G_TYPE_INT;
921 types[1] = G_TYPE_POINTER;
923 /* add the axes column */
924 for(i=SOLUTION_COL_N_COLUMNS; i<n_columns; ++i){
925 const char *axis;
927 axis = darray_item(*axes, i - SOLUTION_COL_N_COLUMNS);
928 renderer = gtk_cell_renderer_text_new ();
929 column = gtk_tree_view_column_new_with_attributes (axis,
930 renderer, "text",
931 i, NULL);
933 gtk_tree_view_append_column (priv->treeview_solutions, column);
934 types[i] = G_TYPE_DOUBLE;
937 if (priv->liststore_solutions)
938 g_object_unref(priv->liststore_solutions);
939 priv->liststore_solutions = gtk_list_store_newv (n_columns, types);
940 g_free (types);
942 gtk_tree_view_set_model (priv->treeview_solutions,
943 GTK_TREE_MODEL(priv->liststore_solutions));
945 update_solutions (self);
948 void
949 set_up_info_bar(HklGuiWindow *self)
951 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
952 GtkWidget *content_area;
954 g_return_if_fail (self != NULL);
956 /* set up info bar until we can use glade for this purpose or
957 * switch to gtk3 */
958 if (priv->info_bar)
959 return;
961 priv->info_bar = GTK_INFO_BAR(gtk_info_bar_new ());
962 gtk_widget_set_no_show_all (GTK_WIDGET(priv->info_bar), TRUE);
964 priv->info_message = GTK_LABEL(gtk_label_new (""));
965 gtk_widget_show (GTK_WIDGET(priv->info_message));
967 content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (priv->info_bar));
968 gtk_container_add (GTK_CONTAINER (content_area),
969 GTK_WIDGET(priv->info_message));
970 gtk_info_bar_add_button (priv->info_bar,
971 GTK_STOCK_OK, GTK_RESPONSE_OK);
972 g_signal_connect (priv->info_bar, "response",
973 G_CALLBACK (gtk_widget_hide), NULL);
975 gtk_box_pack_start(GTK_BOX(priv->box_info_bar),
976 GTK_WIDGET(priv->info_bar),
977 TRUE, TRUE, 0);
980 static void
981 set_up_lambda(HklGuiWindow *self)
983 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
985 g_object_set(G_OBJECT(priv->spinbutton_lambda),
986 "sensitive", TRUE,
987 NULL);
989 gtk_spin_button_set_value(priv->spinbutton_lambda,
990 hkl_geometry_wavelength_get(priv->diffractometer->geometry,
991 HKL_UNIT_USER));
994 static void
995 set_up_3D (HklGuiWindow* self)
997 #if HKL3D
999 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1000 const char *filename = NULL;
1001 const char *name = hkl_factory_name_get(priv->diffractometer->factory);
1003 if(!strcmp("K6C", name))
1004 filename = "../data/diffabs.yaml";
1005 else if (!strcmp("K4CV", name))
1006 filename = "../data/cristal4C.yaml";
1008 if(priv->frame3d){
1009 gtk_widget_destroy(GTK_WIDGET(hkl_gui_3d_frame_get(priv->frame3d)));
1010 g_object_unref(priv->frame3d);
1011 priv->frame3d = NULL;
1014 if (filename){
1015 priv->frame3d = hkl_gui_3d_new(filename, priv->diffractometer->geometry);
1017 gtk_box_pack_start (GTK_BOX(priv->vbox7),
1018 GTK_WIDGET(hkl_gui_3d_frame_get(priv->frame3d)),
1019 TRUE, TRUE, (guint) 0);
1021 gtk_widget_show_all (GTK_WIDGET(priv->vbox7));
1023 #endif
1026 /* select diffractometer */
1027 void
1028 hkl_gui_window_combobox1_changed_cb(GtkComboBox *combobox, gpointer *user_data)
1030 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1031 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1032 HklFactory *factory;
1033 struct diffractometer_t *dif = NULL;
1035 GtkTreeIter iter = {0};
1037 if(gtk_combo_box_get_active_iter (combobox, &iter)){
1038 gtk_tree_model_get(GTK_TREE_MODEL(priv->liststore_diffractometer),
1039 &iter,
1040 DIFFRACTOMETER_COL_FACTORY, &factory,
1041 DIFFRACTOMETER_COL_DIFFRACTOMETER, &dif,
1042 -1);
1044 if (!dif){
1045 dif = create_diffractometer(factory);
1046 gtk_list_store_set(priv->liststore_diffractometer,
1047 &iter,
1048 DIFFRACTOMETER_COL_DIFFRACTOMETER, dif,
1049 -1);
1052 if(dif != priv->diffractometer){
1053 priv->diffractometer = dif;
1055 diffractometer_set_sample(dif, priv->sample);
1057 set_up_lambda(self);
1058 set_up_pseudo_axes_frames(self);
1059 set_up_tree_view_axes(self);
1060 set_up_tree_view_pseudo_axes(self);
1061 set_up_tree_view_solutions(self);
1062 set_up_info_bar(self);
1063 set_up_3D(self);
1068 /* axis read cb */
1069 void
1070 hkl_gui_window_cellrendererspin1_edited_cb(GtkCellRendererText *renderer,
1071 gchar *path,
1072 gchar *new_text,
1073 gpointer user_data)
1075 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1076 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1077 GtkTreeIter iter = {0};
1078 gdouble value = 0.0;
1079 const char *axis;
1080 HklParameter *parameter;
1082 g_return_if_fail (renderer != NULL);
1083 g_return_if_fail (path != NULL);
1084 g_return_if_fail (new_text != NULL);
1085 g_return_if_fail (user_data != NULL);
1087 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(priv->liststore_axis),
1088 &iter,
1089 path);
1090 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_axis), &iter,
1091 AXIS_COL_NAME, &axis,
1092 -1);
1094 value = atof(new_text); /* TODO need to check for the right conversion */
1096 /* set the axis value */
1097 parameter = hkl_parameter_new_copy(hkl_geometry_axis_get(priv->diffractometer->geometry,
1098 axis, NULL));
1099 hkl_parameter_value_set (parameter, value, HKL_UNIT_USER, NULL);
1100 hkl_geometry_axis_set(priv->diffractometer->geometry,
1101 axis, parameter, NULL);
1102 hkl_parameter_free(parameter);
1104 hkl_engine_list_get(priv->diffractometer->engines);
1106 /* ok so set the model with the new value */
1107 gtk_list_store_set (priv->liststore_axis, &iter,
1108 AXIS_COL_READ, value,
1109 AXIS_COL_WRITE, value,
1110 -1);
1112 update_pseudo_axes (self);
1113 update_pseudo_axes_frames (self);
1114 update_3d(self);
1117 /* axis min cb */
1118 void
1119 hkl_gui_window_cellrendererspin3_edited_cb(GtkCellRendererText *renderer,
1120 gchar *path,
1121 gchar *new_text,
1122 gpointer user_data)
1124 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1125 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1126 GtkTreeIter iter = {0};
1127 gdouble value = 0.0;
1128 const char *axis;
1129 HklParameter* parameter = NULL;
1130 gdouble shit, max;
1132 g_return_if_fail (renderer != NULL);
1133 g_return_if_fail (path != NULL);
1134 g_return_if_fail (new_text != NULL);
1135 g_return_if_fail (user_data != NULL);
1137 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(priv->liststore_axis),
1138 &iter,
1139 path);
1140 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_axis), &iter,
1141 AXIS_COL_NAME, &axis,
1142 -1);
1144 value = atof(new_text); /* TODO need to check for the right conversion */
1146 parameter = hkl_parameter_new_copy(hkl_geometry_axis_get(priv->diffractometer->geometry,
1147 axis, NULL));
1148 hkl_parameter_min_max_get (parameter, &shit, &max, HKL_UNIT_USER);
1149 hkl_parameter_min_max_set (parameter, value, max, HKL_UNIT_USER, NULL); /* TODO error */
1150 hkl_geometry_axis_set(priv->diffractometer->geometry,
1151 axis, parameter, NULL);
1152 hkl_parameter_free(parameter);
1154 gtk_list_store_set (priv->liststore_axis, &iter,
1155 AXIS_COL_MIN, value,
1156 -1);
1158 update_pseudo_axes (self);
1162 /* axis max cb */
1163 void
1164 hkl_gui_window_cellrendererspin4_edited_cb(GtkCellRendererText *renderer,
1165 gchar *path,
1166 gchar *new_text,
1167 gpointer user_data)
1169 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1170 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1171 GtkTreeIter iter = {0};
1172 gdouble value = 0.0;
1173 const char *axis;
1174 HklParameter* parameter = NULL;
1175 gdouble shit, min;
1177 g_return_if_fail (renderer != NULL);
1178 g_return_if_fail (path != NULL);
1179 g_return_if_fail (new_text != NULL);
1180 g_return_if_fail (user_data != NULL);
1182 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(priv->liststore_axis),
1183 &iter,
1184 path);
1185 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_axis), &iter,
1186 AXIS_COL_NAME, &axis,
1187 -1);
1189 value = atof(new_text); /* TODO need to check for the right conversion */
1192 parameter = hkl_parameter_new_copy(hkl_geometry_axis_get(priv->diffractometer->geometry,
1193 axis, NULL));
1194 hkl_parameter_min_max_get (parameter, &min, &shit, HKL_UNIT_USER);
1195 hkl_parameter_min_max_set (parameter, min, value, HKL_UNIT_USER, NULL);
1196 hkl_geometry_axis_set(priv->diffractometer->geometry,
1197 axis, parameter, NULL);
1198 hkl_parameter_free(parameter);
1201 gtk_list_store_set (priv->liststore_axis, &iter,
1202 AXIS_COL_MAX, value,
1203 -1);
1205 update_pseudo_axes (self);
1209 /* pseudo axis write */
1210 void
1211 hkl_gui_window_cellrenderertext5_edited_cb(GtkCellRendererText *renderer,
1212 gchar *path,
1213 gchar *new_text,
1214 gpointer user_data)
1216 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1217 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1218 GtkTreeIter iter = {0};
1219 gdouble value = 0.0;
1220 gdouble old_value;
1221 unsigned int idx;
1222 HklEngine *engine = NULL;
1223 gboolean valid;
1224 GtkTreeIter it = {0};
1225 guint n_values;
1226 GError *error = NULL;
1228 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(priv->liststore_pseudo_axes),
1229 &iter,
1230 path);
1231 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_pseudo_axes), &iter,
1232 PSEUDO_AXIS_COL_IDX, &idx,
1233 PSEUDO_AXIS_COL_ENGINE, &engine,
1234 PSEUDO_AXIS_COL_WRITE, &old_value,
1235 -1);
1237 n_values = darray_size(*hkl_engine_pseudo_axes_names_get(engine));
1238 gdouble values[n_values];
1240 /* extract all the values from the listore */
1242 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(priv->liststore_pseudo_axes), &it);
1243 while(valid){
1244 guint it_idx;
1245 HklEngine *it_engine;
1246 gdouble it_value;
1248 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_pseudo_axes), &it,
1249 PSEUDO_AXIS_COL_IDX, &it_idx,
1250 PSEUDO_AXIS_COL_ENGINE, &it_engine,
1251 PSEUDO_AXIS_COL_WRITE, &it_value,
1252 -1);
1254 if(engine == it_engine)
1255 values[it_idx] = it_value;
1257 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(priv->liststore_pseudo_axes), &it);
1260 /* replace with the new value */
1261 value = atof(new_text); /* TODO need to check for the right conversion */
1262 values[idx] = value;
1264 if(diffractometer_pseudo_axes_values_set(priv->diffractometer, engine,
1265 values, n_values, &error)){
1266 gtk_list_store_set (priv->liststore_pseudo_axes,
1267 &iter,
1268 PSEUDO_AXIS_COL_WRITE, value,
1269 -1);
1271 update_axes (self);
1272 update_pseudo_axes (self);
1273 update_pseudo_axes_frames (self);
1274 update_solutions (self);
1275 update_3d(self);
1276 }else
1277 raise_error(self, &error);
1281 void
1282 hkl_gui_window_treeview_solutions_cursor_changed_cb (GtkTreeView *tree_view,
1283 gpointer user_data)
1285 HklGuiWindow* self = HKL_GUI_WINDOW(user_data);
1286 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1288 GtkTreePath* path = NULL;
1289 GtkTreeViewColumn* focus_column = NULL;
1290 GtkTreeIter iter = {0};
1291 const HklGeometryListItem *solution;
1293 gtk_tree_view_get_cursor (tree_view, &path, &focus_column);
1294 gtk_tree_model_get_iter (GTK_TREE_MODEL(priv->liststore_solutions), &iter, path);
1295 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_solutions), &iter,
1296 SOLUTION_COL_HKL_GEOMETRY_LIST_ITEM, &solution,
1297 -1);
1299 diffractometer_set_solution(priv->diffractometer, solution);
1301 update_axes (self);
1302 update_pseudo_axes (self);
1303 update_pseudo_axes_frames (self);
1304 update_3d(self);
1306 gtk_tree_path_free (path);
1309 /* reflection h k l */
1310 #define HKL_GUI_WINDOW_CELLRENDERERTEXT_HKL_EDITED_CB(_number, _hkl, _HKL) \
1311 void \
1312 hkl_gui_window_cellrenderertext ## _number ## _edited_cb(GtkCellRendererText* _sender, const gchar* path, \
1313 const gchar* new_text, gpointer user_data) \
1315 HklGuiWindow *self = HKL_GUI_WINDOW(user_data); \
1316 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data); \
1318 g_return_if_fail (self != NULL); \
1319 g_return_if_fail (path != NULL); \
1320 g_return_if_fail (new_text != NULL); \
1322 if (priv->sample){ \
1323 gdouble h = 0.0; \
1324 gdouble k = 0.0; \
1325 gdouble l = 0.0; \
1326 HklSampleReflection* reflection = NULL; \
1327 GtkTreeIter iter = {0}; \
1328 GError *error = NULL; \
1330 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(priv->liststore_reflections), \
1331 &iter, path); \
1332 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_reflections), \
1333 &iter, \
1334 REFLECTION_COL_REFLECTION, &reflection, \
1335 -1); \
1337 hkl_sample_reflection_hkl_get (reflection, &h, &k, &l); \
1338 _hkl = atof(new_text); \
1339 if(!hkl_sample_reflection_hkl_set (reflection, h, k, l, NULL)) \
1340 raise_error(self, &error); \
1341 else \
1342 gtk_list_store_set (priv->liststore_reflections, \
1343 &iter, \
1344 REFLECTION_COL_ ## _HKL, _hkl, \
1345 -1); \
1349 HKL_GUI_WINDOW_CELLRENDERERTEXT_HKL_EDITED_CB(7, h, H);
1350 HKL_GUI_WINDOW_CELLRENDERERTEXT_HKL_EDITED_CB(8, k, K);
1351 HKL_GUI_WINDOW_CELLRENDERERTEXT_HKL_EDITED_CB(9, l, L);
1354 /* reflection flag */
1355 void
1356 hkl_gui_window_cellrenderertoggle1_toggled_cb (GtkCellRendererToggle* renderer, const gchar* path,
1357 gpointer self)
1359 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1361 g_return_if_fail (self != NULL);
1362 g_return_if_fail (path != NULL);
1364 if (priv->sample){
1365 gboolean flag;
1366 HklSampleReflection* reflection = NULL;
1367 GtkTreeIter iter = {0};
1369 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(priv->liststore_reflections),
1370 &iter, path);
1371 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_reflections),
1372 &iter,
1373 REFLECTION_COL_REFLECTION, &reflection,
1374 -1);
1376 flag = gtk_cell_renderer_toggle_get_active(renderer);
1377 hkl_sample_reflection_flag_set (reflection, flag);
1378 gtk_list_store_set (priv->liststore_reflections,
1379 &iter,
1380 REFLECTION_COL_FLAG, flag,
1381 -1);
1385 gboolean
1386 hkl_gui_window_treeview_reflections_key_press_event_cb (GtkWidget* _sender, GdkEventKey* event,
1387 gpointer self)
1389 return TRUE;
1392 void
1393 hkl_gui_window_toolbutton_add_reflection_clicked_cb(GtkToolButton* _sender,
1394 gpointer self)
1396 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1398 if (priv->diffractometer == NULL){
1399 gtk_statusbar_push (priv->statusbar, 0,
1400 "Please select a diffractometer before adding reflections");
1401 return;
1404 if (priv->sample) {
1405 HklSampleReflection *reflection = NULL;
1406 GtkTreeIter iter = {0};
1407 gboolean flag;
1408 gint n_rows;
1409 GError *error = NULL;
1411 reflection = hkl_sample_reflection_new(priv->diffractometer->geometry,
1412 priv->diffractometer->detector,
1413 0, 0, 0, &error);
1414 if(!reflection)
1415 raise_error(self, &error);
1416 else{
1417 hkl_sample_add_reflection(priv->sample, reflection);
1418 flag = hkl_sample_reflection_flag_get(reflection);
1420 n_rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(priv->liststore_reflections),
1421 NULL);
1422 gtk_list_store_insert_with_values (priv->liststore_reflections,
1423 &iter, -1,
1424 REFLECTION_COL_INDEX, n_rows,
1425 REFLECTION_COL_H, 0.,
1426 REFLECTION_COL_K, 0.,
1427 REFLECTION_COL_L, 0.,
1428 REFLECTION_COL_FLAG, flag,
1429 REFLECTION_COL_REFLECTION, reflection,
1430 -1);
1435 void
1436 hkl_gui_window_toolbutton_goto_reflection_clicked_cb (GtkToolButton* _sender, gpointer user_data)
1438 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1439 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1441 g_return_if_fail (self != NULL);
1443 if (priv->sample) {
1444 GtkTreeSelection* selection = NULL;
1445 guint nb_rows = 0U;
1447 selection = gtk_tree_view_get_selection (priv->treeview_reflections);
1448 nb_rows = gtk_tree_selection_count_selected_rows (selection);
1450 if (nb_rows == 1) {
1451 HklSampleReflection *reflection;
1452 GtkTreeIter iter = {0};
1453 GtkTreeModel* model = NULL;
1454 GtkTreePath *treepath;
1455 GList* list;
1457 model = GTK_TREE_MODEL(priv->liststore_reflections);
1459 list = gtk_tree_selection_get_selected_rows (selection,
1460 &model);
1462 treepath = g_list_nth_data(list, 0);
1464 gtk_tree_model_get_iter (GTK_TREE_MODEL(priv->liststore_reflections),
1465 &iter, treepath);
1467 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_reflections),
1468 &iter,
1469 REFLECTION_COL_REFLECTION, &reflection,
1470 -1);
1472 hkl_geometry_set (priv->diffractometer->geometry,
1473 hkl_sample_reflection_geometry_get(reflection));
1475 update_source (self);
1476 update_axes (self);
1477 update_pseudo_axes (self);
1478 update_3d(self);
1480 g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
1481 } else
1482 if (nb_rows > 1)
1483 gtk_statusbar_push (priv->statusbar, 0,
1484 "Please select only one reflection.");
1485 else
1486 gtk_statusbar_push (priv->statusbar, 0,
1487 "Please select at least one reflection.");
1491 static void
1492 _del_reflection(gpointer data, gpointer user_data)
1494 HklSampleReflection *reflection;
1495 GtkTreeIter iter = {0};
1496 GtkTreePath *treepath = data;
1497 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1499 gtk_tree_model_get_iter (GTK_TREE_MODEL(priv->liststore_reflections),
1500 &iter, treepath);
1502 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_reflections),
1503 &iter,
1504 REFLECTION_COL_REFLECTION, &reflection,
1505 -1);
1506 hkl_sample_del_reflection(priv->sample, reflection);
1509 void
1510 hkl_gui_window_toolbutton_del_reflection_clicked_cb (GtkToolButton* _sender, gpointer user_data)
1512 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1513 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1514 HklSample* sample = NULL;
1516 g_return_if_fail (self != NULL);
1518 if (priv->sample) {
1519 GtkTreeSelection* selection = NULL;
1520 guint nb_rows = 0U;
1522 selection = gtk_tree_view_get_selection (priv->treeview_reflections);
1523 nb_rows = gtk_tree_selection_count_selected_rows (selection);
1524 if (nb_rows > 0) {
1525 GtkTreeModel* model = NULL;
1526 GList* list;
1527 guint* indexes;
1528 gint i;
1529 GtkMessageDialog* dialog;
1531 model = GTK_TREE_MODEL(priv->liststore_reflections);
1532 list = gtk_tree_selection_get_selected_rows (selection, &model);
1535 dialog = GTK_MESSAGE_DIALOG(
1536 gtk_message_dialog_new (NULL,
1537 GTK_DIALOG_DESTROY_WITH_PARENT,
1538 GTK_MESSAGE_WARNING,
1539 GTK_BUTTONS_YES_NO,
1540 "Are you sure that you want to delete reflections"));
1542 switch (gtk_dialog_run (GTK_DIALOG(dialog))) {
1543 case GTK_RESPONSE_YES:
1545 g_list_foreach(list, _del_reflection, self);
1546 update_reflections (self);
1547 break;
1549 default:
1550 break;
1552 gtk_widget_destroy (GTK_WIDGET(dialog));
1553 g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
1554 } else {
1555 gtk_statusbar_push (priv->statusbar, 0,
1556 "Please select at least one reflection.");
1561 static void
1562 set_up_tree_view_reflections(HklGuiWindow *self)
1564 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1565 GtkTreeSelection* selection = NULL;
1567 selection = gtk_tree_view_get_selection (priv->treeview_reflections);
1568 gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
1571 /* crystal name */
1572 void
1573 hkl_gui_window_cellrenderertext10_edited_cb(GtkCellRendererText* _sender, const gchar* path,
1574 const gchar* new_text, gpointer user_data)
1576 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1578 GtkTreeModel* model = NULL;
1579 GtkTreeIter iter = {0};
1580 HklSample* sample = NULL;
1581 gchar* name = NULL;
1583 g_return_if_fail (user_data != NULL);
1584 g_return_if_fail (path != NULL);
1585 g_return_if_fail (new_text != NULL);
1587 model = GTK_TREE_MODEL(priv->liststore_crystals);
1589 gtk_tree_model_get_iter_from_string (model, &iter, path);
1591 gtk_tree_model_get (model, &iter,
1592 SAMPLE_COL_SAMPLE, &sample,
1593 -1);
1595 hkl_sample_name_set (sample, new_text);
1597 gtk_list_store_set(priv->liststore_crystals, &iter,
1598 SAMPLE_COL_NAME, new_text,
1599 -1);
1602 #define set_lattice(lattice, parameter) do{ \
1603 const HklParameter *p; \
1604 gdouble min, max, value; \
1605 gboolean fit; \
1606 p = hkl_lattice_## parameter ##_get((lattice)); \
1607 value = hkl_parameter_value_get(p, HKL_UNIT_USER); \
1608 hkl_parameter_min_max_get(p, &min, &max, HKL_UNIT_USER); \
1609 fit = hkl_parameter_fit_get(p); \
1610 gtk_spin_button_set_value(priv->spinbutton_## parameter, value); \
1611 gtk_spin_button_set_value(priv->spinbutton_## parameter ##_min, min); \
1612 gtk_spin_button_set_value(priv->spinbutton_## parameter ##_max, max); \
1613 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(priv->checkbutton_ ## parameter), fit); \
1614 }while(0)
1616 static void
1617 update_lattice (HklGuiWindow* self)
1619 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1621 g_return_if_fail (self != NULL);
1623 if (priv->sample != NULL) {
1624 const HklLattice *lattice;
1625 lattice = hkl_sample_lattice_get(priv->sample);
1626 set_lattice(lattice, a);
1627 set_lattice(lattice, b);
1628 set_lattice(lattice, c);
1629 set_lattice(lattice, alpha);
1630 set_lattice(lattice, beta);
1631 set_lattice(lattice, gamma);
1635 #define set_reciprocal_lattice(lattice, parameter) do{ \
1636 const HklParameter *p; \
1637 gdouble value; \
1638 p = hkl_lattice_## parameter ##_get((lattice)); \
1639 value = hkl_parameter_value_get(p, HKL_UNIT_USER); \
1640 gtk_spin_button_set_value(priv->spinbutton_## parameter ##_star, value); \
1641 }while(0)
1643 static void
1644 update_reciprocal_lattice (HklGuiWindow* self)
1646 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1648 g_return_if_fail (self != NULL);
1650 if (priv->sample != NULL) {
1651 hkl_lattice_reciprocal (hkl_sample_lattice_get(priv->sample),
1652 priv->reciprocal);
1654 set_reciprocal_lattice(priv->reciprocal, a);
1655 set_reciprocal_lattice(priv->reciprocal, b);
1656 set_reciprocal_lattice(priv->reciprocal, c);
1657 set_reciprocal_lattice(priv->reciprocal, alpha);
1658 set_reciprocal_lattice(priv->reciprocal, beta);
1659 set_reciprocal_lattice(priv->reciprocal, gamma);
1663 #define set_ux_uy_uz(sample, parameter) do { \
1664 const HklParameter *p; \
1665 p = hkl_sample_## parameter ##_get((sample)); \
1666 gboolean fit = hkl_parameter_fit_get(p); \
1667 gtk_spin_button_set_value(priv->spinbutton_## parameter, \
1668 hkl_parameter_value_get(p, HKL_UNIT_USER)); \
1669 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(priv->checkbutton_## parameter), fit); \
1670 }while(0)
1672 static void
1673 update_ux_uy_uz (HklGuiWindow* self)
1675 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1677 g_return_if_fail (self != NULL);
1679 if (priv->sample != NULL) {
1680 set_ux_uy_uz(priv->sample, ux);
1681 set_ux_uy_uz(priv->sample, uy);
1682 set_ux_uy_uz(priv->sample, uz);
1686 #define set_UB(i, j) do{ \
1687 gtk_label_set_markup(priv->label_UB ## i ## j, \
1688 g_ascii_formatd(text, \
1689 G_ASCII_DTOSTR_BUF_SIZE, \
1690 "<tt> %+.4f </tt>", \
1691 hkl_matrix_get(UB, i - 1, j - 1))); \
1692 }while(0)
1694 static void
1695 update_UB (HklGuiWindow* self)
1697 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1699 g_return_if_fail (self != NULL);
1701 if (priv->sample != NULL) {
1702 const HklMatrix *UB = hkl_sample_UB_get (priv->sample);
1703 gchar *text = g_new0 (gchar, G_ASCII_DTOSTR_BUF_SIZE);
1705 set_UB(1, 1);
1706 set_UB(1, 2);
1707 set_UB(1, 3);
1708 set_UB(2, 1);
1709 set_UB(2, 2);
1710 set_UB(2, 3);
1711 set_UB(3, 1);
1712 set_UB(3, 2);
1713 set_UB(3, 3);
1715 g_free(text);
1719 void
1720 hkl_gui_window_treeview_crystals_cursor_changed_cb (GtkTreeView* _sender, gpointer user_data)
1722 GtkTreePath* path = NULL;
1723 GtkTreeViewColumn* column = NULL;
1724 GtkTreeIter iter = {0};
1726 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1727 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1728 HklSample *sample;
1730 g_return_if_fail (user_data != NULL);
1732 gtk_tree_view_get_cursor (priv->treeview_crystals, &path, &column);
1733 if(path){
1734 if (gtk_tree_model_get_iter (GTK_TREE_MODEL(priv->liststore_crystals),
1735 &iter, path) == TRUE){
1736 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_crystals),
1737 &iter,
1738 SAMPLE_COL_SAMPLE, &sample,
1739 -1);
1741 if(sample && sample != priv->sample){
1742 priv->sample = sample;
1744 update_reflections(self);
1745 update_lattice(self);
1746 update_reciprocal_lattice (self);
1747 update_ux_uy_uz (self);
1748 update_UB (self);
1750 if(priv->diffractometer){
1751 diffractometer_set_sample(priv->diffractometer,
1752 priv->sample);
1754 update_pseudo_axes (self);
1755 update_pseudo_axes_frames (self);
1756 update_solutions(self);
1760 gtk_tree_path_free (path);
1766 static GtkTreeIter
1767 _add_sample(HklGuiWindow *self, HklSample *sample)
1769 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1770 GtkTreeIter iter = {0};
1771 const HklLattice *lattice;
1772 gdouble a, b, c, alpha, beta, gamma;
1774 g_return_val_if_fail (self != NULL, iter);
1776 lattice = hkl_sample_lattice_get(sample);
1777 a = hkl_parameter_value_get(hkl_lattice_a_get(lattice), HKL_UNIT_USER);
1778 b = hkl_parameter_value_get(hkl_lattice_b_get(lattice), HKL_UNIT_USER);
1779 c = hkl_parameter_value_get(hkl_lattice_c_get(lattice), HKL_UNIT_USER);
1780 alpha = hkl_parameter_value_get(hkl_lattice_alpha_get(lattice),
1781 HKL_UNIT_USER);
1782 beta = hkl_parameter_value_get(hkl_lattice_beta_get(lattice),
1783 HKL_UNIT_USER);
1784 gamma = hkl_parameter_value_get(hkl_lattice_gamma_get(lattice),
1785 HKL_UNIT_USER);
1787 gtk_list_store_insert_with_values(priv->liststore_crystals,
1788 &iter, -1,
1789 SAMPLE_COL_SAMPLE, sample,
1790 SAMPLE_COL_NAME, hkl_sample_name_get(sample),
1791 SAMPLE_COL_A, a,
1792 SAMPLE_COL_B, b,
1793 SAMPLE_COL_C, c,
1794 SAMPLE_COL_ALPHA, alpha,
1795 SAMPLE_COL_BETA, beta,
1796 SAMPLE_COL_GAMMA, gamma,
1797 -1);
1798 return iter;
1801 static void
1802 set_up_tree_view_crystals (HklGuiWindow* self)
1804 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1805 GtkTreeIter iter = {0};
1806 GtkTreePath *path = NULL;
1808 g_return_if_fail (self != NULL);
1810 iter = _add_sample(self, hkl_sample_new("default"));
1812 path = gtk_tree_model_get_path(GTK_TREE_MODEL(priv->liststore_crystals),
1813 &iter);
1815 gtk_tree_view_set_cursor(priv->treeview_crystals, path, NULL, FALSE);
1817 gtk_tree_path_free(path);
1820 static void
1821 _add_sample_and_edit_name(HklGuiWindow *self, HklSample *sample)
1823 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1824 GtkTreeIter iter = {0};
1825 GtkTreePath* path = NULL;
1826 GtkTreeViewColumn* column = NULL;
1828 iter = _add_sample(self, sample);
1830 path = gtk_tree_model_get_path(GTK_TREE_MODEL(priv->liststore_crystals),
1831 &iter);
1832 column = gtk_tree_view_get_column (priv->treeview_crystals, 0);
1833 gtk_tree_view_set_cursor (priv->treeview_crystals, path, column, TRUE);
1835 gtk_tree_path_free(path);
1838 void
1839 hkl_gui_window_toolbutton_add_crystal_clicked_cb (GtkToolButton* _sender, gpointer user_data)
1841 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1842 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1843 HklSample *sample;
1845 g_return_if_fail (user_data != NULL);
1847 sample = hkl_sample_new ("new");
1848 if(sample)
1849 _add_sample_and_edit_name(self, sample);
1852 void
1853 hkl_gui_window_toolbutton_copy_crystal_clicked_cb (GtkToolButton* _sender, gpointer user_data)
1855 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1856 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1857 HklSample *copy = NULL;
1859 g_return_if_fail (self != NULL);
1861 if(priv->sample) {
1862 copy = hkl_sample_new_copy(priv->sample);
1863 if (copy)
1864 _add_sample_and_edit_name(self, copy);
1865 }else
1866 gtk_statusbar_push (priv->statusbar, (guint) 0, "Please select a crystal to copy.");
1869 void
1870 hkl_gui_window_toolbutton_del_crystal_clicked_cb (GtkToolButton* _sender, gpointer user_data)
1872 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1873 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1875 g_return_if_fail (user_data != NULL);
1877 if (priv->sample != NULL) {
1878 guint n_rows;
1880 n_rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(priv->liststore_crystals),
1881 NULL );
1882 if (n_rows == 1)
1883 return;
1884 else {
1885 GtkTreeIter iter = {0};
1886 GtkTreePath *path = NULL;
1887 GtkTreeViewColumn *column = NULL;
1889 gtk_tree_view_get_cursor(priv->treeview_crystals,
1890 &path, &column);
1891 if (path){
1892 if (gtk_tree_model_get_iter (GTK_TREE_MODEL(priv->liststore_crystals),
1893 &iter, path) == TRUE) {
1894 gtk_tree_path_free(path);
1896 hkl_sample_free(priv->sample);
1897 if (gtk_list_store_remove(priv->liststore_crystals,
1898 &iter) == TRUE){
1899 path = gtk_tree_model_get_path(GTK_TREE_MODEL(priv->liststore_crystals),
1900 &iter);
1901 gtk_tree_view_set_cursor(priv->treeview_crystals,
1902 path, NULL, FALSE);
1910 #define get_lattice_parameter(lattice, parameter, _error) do{ \
1911 HklParameter *p = hkl_parameter_new_copy(hkl_lattice_## parameter ##_get(lattice)); \
1912 if(!hkl_parameter_min_max_set(p, \
1913 gtk_spin_button_get_value(priv->spinbutton_## parameter ##_min), \
1914 gtk_spin_button_get_value(priv->spinbutton_## parameter ##_max), \
1915 HKL_UNIT_USER, _error)){ \
1916 raise_error(self, _error); \
1917 hkl_parameter_free(p); \
1918 return; \
1919 }else{ \
1920 hkl_parameter_fit_set(p, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->checkbutton_## parameter))); \
1921 if(!hkl_lattice_ ## parameter ## _set(lattice, p, _error)){ \
1922 raise_error(self, _error); \
1923 hkl_parameter_free(p); \
1924 return; \
1927 hkl_parameter_free(p); \
1928 } while(0)
1930 #define get_ux_uy_uz(sample, parameter, _error) do { \
1931 HklParameter *p; \
1932 p = hkl_parameter_new_copy(hkl_sample_## parameter ##_get(sample)); \
1933 if(!hkl_parameter_value_set(p, \
1934 gtk_spin_button_get_value (priv->spinbutton_## parameter), \
1935 HKL_UNIT_USER, _error)){ \
1936 raise_error(self, _error); \
1937 hkl_parameter_free(p); \
1938 return; \
1939 }else{ \
1940 hkl_parameter_fit_set(p, \
1941 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->checkbutton_## parameter))); \
1942 if(!hkl_sample_ ## parameter ## _set(sample, p, _error)){ \
1943 raise_error(self, _error); \
1944 hkl_parameter_free(p); \
1945 return; \
1948 hkl_parameter_free(p); \
1949 }while(0)
1952 static gboolean
1953 _update_crystal_model(GtkTreeModel *model,
1954 GtkTreePath *path,
1955 GtkTreeIter *iter,
1956 gpointer data)
1958 HklGuiWindow *self = HKL_GUI_WINDOW(data);
1959 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(data);
1960 HklSample *sample = NULL;
1962 gtk_tree_model_get(model, iter,
1963 SAMPLE_COL_SAMPLE, &sample,
1964 -1);
1965 if(priv->sample == sample){
1966 const HklLattice *lattice;
1967 gdouble a, b, c, alpha, beta, gamma;
1969 lattice = hkl_sample_lattice_get(sample);
1970 a = hkl_parameter_value_get(hkl_lattice_a_get(lattice),
1971 HKL_UNIT_USER);
1972 b = hkl_parameter_value_get(hkl_lattice_b_get(lattice),
1973 HKL_UNIT_USER);
1974 c = hkl_parameter_value_get(hkl_lattice_c_get(lattice),
1975 HKL_UNIT_USER);
1976 alpha = hkl_parameter_value_get(hkl_lattice_alpha_get(lattice),
1977 HKL_UNIT_USER);
1978 beta = hkl_parameter_value_get(hkl_lattice_beta_get(lattice),
1979 HKL_UNIT_USER);
1980 gamma = hkl_parameter_value_get(hkl_lattice_gamma_get(lattice),
1981 HKL_UNIT_USER);
1983 gtk_list_store_set(priv->liststore_crystals,
1984 iter,
1985 SAMPLE_COL_NAME, hkl_sample_name_get(sample),
1986 SAMPLE_COL_A, a,
1987 SAMPLE_COL_B, b,
1988 SAMPLE_COL_C, c,
1989 SAMPLE_COL_ALPHA, alpha,
1990 SAMPLE_COL_BETA, beta,
1991 SAMPLE_COL_GAMMA, gamma,
1992 -1);
1993 return TRUE;
1995 return FALSE;
1998 static void
1999 update_crystal_model(HklGuiWindow *self)
2001 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
2003 gtk_tree_model_foreach(GTK_TREE_MODEL(priv->liststore_crystals),
2004 _update_crystal_model,
2005 self);
2008 /* apply crystal parameters */
2009 void
2010 hkl_gui_window_button2_clicked_cb (GtkButton* _sender, gpointer user_data)
2012 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2013 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2015 g_return_if_fail (self != NULL);
2017 if (priv->sample != NULL) {
2018 gdouble a, b, c, alpha, beta, gamma;
2019 gdouble ux, uy, uz;
2020 HklLattice *lattice;
2021 HklParameter *p;
2022 GError *error = NULL;
2024 fprintf(stderr, "%s\n", __func__);
2025 /* lattice parameters */
2026 a = gtk_spin_button_get_value (priv->spinbutton_a);
2027 b = gtk_spin_button_get_value (priv->spinbutton_b);
2028 c = gtk_spin_button_get_value (priv->spinbutton_c);
2029 alpha = gtk_spin_button_get_value (priv->spinbutton_alpha);
2030 beta = gtk_spin_button_get_value (priv->spinbutton_beta);
2031 gamma = gtk_spin_button_get_value (priv->spinbutton_gamma);
2033 lattice = hkl_lattice_new(a, b, c,
2034 alpha * HKL_DEGTORAD,
2035 beta * HKL_DEGTORAD,
2036 gamma * HKL_DEGTORAD, &error);
2037 if(!lattice)
2038 raise_error(self, &error);
2039 else{
2041 get_lattice_parameter(lattice, a, &error);
2042 get_lattice_parameter(lattice, b, &error);
2043 get_lattice_parameter(lattice, c, &error);
2044 get_lattice_parameter(lattice, alpha, &error);
2045 get_lattice_parameter(lattice, beta, &error);
2046 get_lattice_parameter(lattice, gamma, &error);
2048 hkl_sample_lattice_set(priv->sample, lattice);
2050 hkl_lattice_free(lattice);
2052 /* UB */
2053 get_ux_uy_uz(priv->sample, ux, &error);
2054 get_ux_uy_uz(priv->sample, uy, &error);
2055 get_ux_uy_uz(priv->sample, uz, &error);
2057 if(priv->diffractometer)
2058 diffractometer_set_sample(priv->diffractometer,
2059 priv->sample);
2061 update_crystal_model (self);
2062 update_reciprocal_lattice (self);
2063 update_UB (self);
2064 update_pseudo_axes (self);
2065 update_pseudo_axes_frames (self);
2070 void
2071 hkl_gui_window_spinbutton_lambda_value_changed_cb (GtkSpinButton* _sender, gpointer user_data)
2073 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2074 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2076 diffractometer_set_wavelength(priv->diffractometer,
2077 gtk_spin_button_get_value(_sender));
2078 update_pseudo_axes (self);
2079 update_pseudo_axes_frames (self);
2082 void
2083 hkl_gui_window_spinbutton_ux_value_changed_cb (GtkSpinButton *_senser, gpointer user_data)
2085 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2086 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2087 GError *error = NULL;
2089 get_ux_uy_uz(priv->sample, ux, &error);
2091 if(priv->diffractometer)
2092 diffractometer_set_sample(priv->diffractometer,
2093 priv->sample);
2095 update_UB (self);
2096 update_pseudo_axes (self);
2097 update_pseudo_axes_frames (self);
2100 void
2101 hkl_gui_window_spinbutton_uy_value_changed_cb (GtkSpinButton *_senser, gpointer user_data)
2103 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2104 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2105 GError *error = NULL;
2107 get_ux_uy_uz(priv->sample, uy, &error);
2109 if(priv->diffractometer)
2110 diffractometer_set_sample(priv->diffractometer,
2111 priv->sample);
2113 update_UB (self);
2114 update_pseudo_axes (self);
2115 update_pseudo_axes_frames (self);
2118 void
2119 hkl_gui_window_spinbutton_uz_value_changed_cb (GtkSpinButton *_senser, gpointer user_data)
2121 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2122 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2123 GError *error = NULL;
2125 get_ux_uy_uz(priv->sample, uz, &error);
2127 if(priv->diffractometer)
2128 diffractometer_set_sample(priv->diffractometer,
2129 priv->sample);
2131 update_UB (self);
2132 update_pseudo_axes (self);
2133 update_pseudo_axes_frames (self);
2136 void
2137 hkl_gui_window_toolbutton_setUB_clicked_cb(GtkToolButton* _sender, gpointer user_data)
2139 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2140 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2142 HklMatrix *UB;
2143 GError *error = NULL;
2145 UB = hkl_matrix_new_full(gtk_spin_button_get_value(priv->spinbutton_U11),
2146 gtk_spin_button_get_value(priv->spinbutton_U12),
2147 gtk_spin_button_get_value(priv->spinbutton_U13),
2148 gtk_spin_button_get_value(priv->spinbutton_U21),
2149 gtk_spin_button_get_value(priv->spinbutton_U22),
2150 gtk_spin_button_get_value(priv->spinbutton_U23),
2151 gtk_spin_button_get_value(priv->spinbutton_U31),
2152 gtk_spin_button_get_value(priv->spinbutton_U32),
2153 gtk_spin_button_get_value(priv->spinbutton_U33));
2155 if(!hkl_sample_UB_set (priv->sample, UB, &error))
2156 raise_error(self, &error);
2157 else{
2158 if(priv->diffractometer){
2159 diffractometer_set_sample(priv->diffractometer,
2160 priv->sample);
2162 update_lattice (self);
2163 update_crystal_model (self);
2164 update_reciprocal_lattice (self);
2165 update_UB (self);
2166 update_ux_uy_uz (self);
2167 update_pseudo_axes (self);
2168 update_pseudo_axes_frames (self);
2172 hkl_matrix_free(UB);
2175 void
2176 hkl_gui_window_toolbutton_computeUB_clicked_cb (GtkToolButton* _sender, gpointer user_data)
2178 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2179 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2180 GtkTreeSelection* selection = NULL;
2181 guint nb_rows = 0U;
2183 selection = gtk_tree_view_get_selection (priv->treeview_reflections);
2184 nb_rows = gtk_tree_selection_count_selected_rows (selection);
2185 if (nb_rows > 1) {
2186 GtkTreeModel* model = NULL;
2187 GList* list;
2188 GtkTreeIter iter = {0};
2189 GtkTreePath *path;
2190 HklSampleReflection *ref1, *ref2;
2191 GError *error = NULL;
2193 model = GTK_TREE_MODEL(priv->liststore_reflections);
2194 list = gtk_tree_selection_get_selected_rows (selection, &model);
2196 /* get the first reflection */
2197 path = g_list_nth_data(list, 0);
2198 gtk_tree_model_get_iter (GTK_TREE_MODEL(priv->liststore_reflections),
2199 &iter,
2200 path);
2201 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_reflections), &iter,
2202 REFLECTION_COL_REFLECTION, &ref1,
2203 -1);
2205 /* get the second one */
2206 path = g_list_nth_data(list, 1);
2207 gtk_tree_model_get_iter (GTK_TREE_MODEL(priv->liststore_reflections),
2208 &iter,
2209 path);
2210 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_reflections), &iter,
2211 REFLECTION_COL_REFLECTION, &ref2,
2212 -1);
2214 if(!hkl_sample_compute_UB_busing_levy(priv->sample,
2215 ref1, ref2, &error)){
2216 raise_error(self, &error);
2217 }else{
2218 if(priv->diffractometer)
2219 diffractometer_set_sample(priv->diffractometer,
2220 priv->sample);
2222 update_UB (self);
2223 update_ux_uy_uz (self);
2224 update_pseudo_axes (self);
2225 update_pseudo_axes_frames (self);
2227 g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
2228 } else {
2229 gtk_statusbar_push (priv->statusbar, 0,
2230 "Please select at least two reflection.");
2234 void
2235 hkl_gui_window_toolbutton_affiner_clicked_cb (GtkToolButton* _sender, gpointer user_data)
2237 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2238 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2239 GError *error = NULL;
2241 if(!hkl_sample_affine (priv->sample, &error)){
2242 raise_error(self, &error);
2243 }else{
2244 if(priv->diffractometer)
2245 diffractometer_set_sample(priv->diffractometer,
2246 priv->sample);
2248 update_lattice (self);
2249 update_crystal_model (self);
2250 update_reciprocal_lattice (self);
2251 update_UB (self);
2252 update_ux_uy_uz (self);
2253 update_pseudo_axes (self);
2254 update_pseudo_axes_frames (self);
2258 #define TOGGLE_LATTICE_CB(_parameter) \
2259 void hkl_gui_window_checkbutton_ ## _parameter ## _toggled_cb(GtkCheckButton *checkbutton, \
2260 gpointer user_data) \
2262 HklGuiWindow *self = HKL_GUI_WINDOW(user_data); \
2263 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data); \
2264 HklLattice *lattice; \
2265 HklParameter *p; \
2266 GError *error = NULL; \
2267 lattice = hkl_lattice_new_copy(hkl_sample_lattice_get(priv->sample)); \
2268 p = hkl_parameter_new_copy(hkl_lattice_## _parameter ##_get(lattice)); \
2269 hkl_parameter_fit_set(p, \
2270 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbutton))); \
2271 if(!hkl_lattice_## _parameter ##_set(lattice, p, &error)){ \
2272 raise_error(self, &error); \
2273 }else{ \
2274 hkl_sample_lattice_set(priv->sample, lattice); \
2276 hkl_parameter_free(p); \
2277 hkl_lattice_free(lattice); \
2280 TOGGLE_LATTICE_CB(a);
2281 TOGGLE_LATTICE_CB(b);
2282 TOGGLE_LATTICE_CB(c);
2283 TOGGLE_LATTICE_CB(alpha);
2284 TOGGLE_LATTICE_CB(beta);
2285 TOGGLE_LATTICE_CB(gamma);
2287 #define TOGGLE_UX_UY_UZ(_parameter) \
2288 void hkl_gui_window_checkbutton_ ## _parameter ## _toggled_cb(GtkCheckButton *checkbutton, \
2289 gpointer user_data) \
2291 HklGuiWindow *self = HKL_GUI_WINDOW(user_data); \
2292 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data); \
2293 HklParameter *p; \
2294 GError *error = NULL; \
2295 p = hkl_parameter_new_copy(hkl_sample_ ## _parameter ## _get(priv->sample)); \
2296 hkl_parameter_fit_set(p, \
2297 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbutton))); \
2298 if(!hkl_sample_ ## _parameter ## _set(priv->sample, p, &error)){ \
2299 raise_error(self, &error); \
2301 hkl_parameter_free(p); \
2304 TOGGLE_UX_UY_UZ(ux);
2305 TOGGLE_UX_UY_UZ(uy);
2306 TOGGLE_UX_UY_UZ(uz);
2310 static gboolean _hkl_gui_window_on_tree_view_crystals_key_press_event_gtk_widget_key_press_event (GtkWidget* _sender, GdkEventKey* event, gpointer self) {
2311 gboolean result;
2312 result = hkl_gui_window_on_tree_view_crystals_key_press_event (event, self);
2314 return result;
2318 static gboolean hkl_gui_window_on_tree_view_crystals_key_press_event (GdkEventKey* event, HklGuiWindow* self) {
2319 gboolean result = FALSE;
2321 g_return_val_if_fail (self != NULL, FALSE);
2323 g_return_val_if_fail (event != NULL, FALSE);
2325 result = TRUE;
2327 return result;
2333 static void
2334 hkl_gui_window_class_init (HklGuiWindowClass *class)
2336 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
2338 g_type_class_add_private (class, sizeof (HklGuiWindowPrivate));
2340 /* virtual method */
2341 gobject_class->finalize = finalize;
2345 static void hkl_gui_window_init (HklGuiWindow * self)
2347 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
2349 priv->diffractometer = NULL;
2350 priv->sample = NULL;
2352 darray_init(priv->pseudo_frames);
2354 priv->reciprocal = hkl_lattice_new_default ();
2356 hkl_gui_window_get_widgets_and_objects_from_ui (self);
2358 set_up_diffractometer_model (self);
2360 set_up_tree_view_crystals (self);
2362 set_up_tree_view_reflections(self);
2365 int main (int argc, char ** argv)
2367 gtk_init (&argc, &argv);
2368 #ifdef HKL3D
2369 gtk_gl_init(&argc, &argv);
2370 #endif
2371 hkl_gui_window_new ();
2373 gtk_main ();
2375 return 0;