Line data Source code
1 : /* File: gui_sketch_object_creator.c; Copyright and License: see below */
2 :
3 : #include "sketch/gui_sketch_object_creator.h"
4 : #include "geometry/geometry_rectangle.h"
5 : #include "ctrl_multi_step_changer.h"
6 : #include "entity/data_table.h"
7 : #include "entity/data_id.h"
8 : #include "u8/u8_trace.h"
9 : #include "u8/u8_log.h"
10 : #include <stdint.h>
11 : #include <stdbool.h>
12 :
13 0 : void gui_sketch_object_creator_init ( gui_sketch_object_creator_t *this_,
14 : ctrl_controller_t *controller,
15 : data_database_reader_t *db_reader,
16 : gui_simple_message_to_user_t *message_to_user )
17 : {
18 0 : U8_TRACE_BEGIN();
19 :
20 0 : (*this_).db_reader = db_reader;
21 0 : (*this_).controller = controller;
22 0 : gui_sketch_defaults_init ( &((*this_).defaults ) );
23 0 : data_rules_init ( &((*this_).data_rules ) );
24 0 : (*this_).message_to_user = message_to_user;
25 :
26 0 : U8_TRACE_END();
27 0 : }
28 :
29 0 : void gui_sketch_object_creator_destroy ( gui_sketch_object_creator_t *this_ )
30 : {
31 0 : U8_TRACE_BEGIN();
32 :
33 0 : (*this_).message_to_user = NULL;
34 0 : data_rules_destroy ( &((*this_).data_rules) );
35 0 : gui_sketch_defaults_destroy ( &((*this_).defaults) );
36 0 : (*this_).db_reader = NULL;
37 0 : (*this_).controller = NULL;
38 :
39 0 : U8_TRACE_END();
40 0 : }
41 :
42 0 : u8_error_t gui_sketch_object_creator_create_classifier ( gui_sketch_object_creator_t *this_,
43 : data_row_t diagram_id,
44 : int32_t x_order,
45 : int32_t y_order,
46 : data_row_t *out_diagramelement_id,
47 : data_row_t *out_classifier_id )
48 : {
49 0 : U8_TRACE_BEGIN();
50 0 : assert ( NULL != out_classifier_id );
51 0 : assert ( NULL != out_diagramelement_id );
52 0 : assert ( DATA_ROW_VOID != diagram_id );
53 :
54 : u8_error_t c_result;
55 :
56 : /* get type of diagram */
57 0 : data_diagram_type_t diag_type = DATA_DIAGRAM_TYPE_LIST;
58 : {
59 : const u8_error_t diag_err
60 0 : = data_database_reader_get_diagram_by_id( (*this_).db_reader,
61 : diagram_id,
62 : &((*this_).private_temp_diagram)
63 : );
64 0 : if ( U8_ERROR_NONE == diag_err )
65 : {
66 0 : diag_type = data_diagram_get_diagram_type( &((*this_).private_temp_diagram) );
67 0 : data_diagram_destroy ( &((*this_).private_temp_diagram) );
68 : }
69 : else
70 : {
71 0 : U8_LOG_ERROR_INT( "gui_sketch_object_creator_create_classifier cannot find diagram:", diagram_id );
72 : }
73 : }
74 :
75 : /* determine type of new classifier */
76 : data_classifier_type_t type_of_new_classifier;
77 0 : type_of_new_classifier = gui_sketch_defaults_get_classifier_type( &((*this_).defaults), diag_type );
78 :
79 : /* define classifier */
80 : const u8_error_t d_err
81 0 : = data_classifier_init_new ( &((*this_).private_temp_classifier),
82 : type_of_new_classifier,
83 : "", /* stereotype */
84 : "New Element", /* name */
85 : "", /* description */
86 : x_order,
87 : y_order,
88 : y_order /* y_order used also as list_order */
89 : );
90 0 : if ( d_err != U8_ERROR_NONE )
91 : {
92 0 : U8_LOG_ERROR_HEX("data_classifier_init_new failed in gui_sketch_object_creator_create_classifier:",d_err);
93 : }
94 :
95 : /* create classifier, adapt name if necessary: */
96 : {
97 : ctrl_multi_step_changer_t multi_stepper;
98 0 : ctrl_multi_step_changer_init( &multi_stepper, (*this_).controller, (*this_).db_reader );
99 : u8_error_t out_info;
100 0 : c_result = ctrl_multi_step_changer_create_classifier( &multi_stepper,
101 : &((*this_).private_temp_classifier),
102 : &out_info
103 : );
104 0 : *out_classifier_id = data_classifier_get_row( &((*this_).private_temp_classifier) );
105 0 : ctrl_multi_step_changer_destroy( &multi_stepper );
106 : }
107 :
108 0 : if ( U8_ERROR_NONE == c_result )
109 : {
110 : /* get diagram controller */
111 0 : ctrl_diagram_controller_t *const diagram_control = ctrl_controller_get_diagram_control_ptr( (*this_).controller );
112 :
113 : data_diagramelement_t new_diagele;
114 0 : data_diagramelement_init_new ( &new_diagele,
115 : diagram_id,
116 : *out_classifier_id,
117 : DATA_DIAGRAMELEMENT_FLAG_NONE,
118 : DATA_ROW_VOID
119 : );
120 :
121 : data_id_t created_lifeline;
122 0 : c_result = ctrl_diagram_controller_create_diagramelement ( diagram_control,
123 : &new_diagele,
124 : CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND,
125 : out_diagramelement_id,
126 : &created_lifeline
127 : );
128 : (void) created_lifeline; /* information not needed here */
129 :
130 : /* cleanup */
131 0 : data_diagramelement_destroy ( &new_diagele );
132 : }
133 0 : else if ( U8_ERROR_READ_ONLY_DB == c_result )
134 : {
135 : /* notify read-only warning to user */
136 0 : gui_simple_message_to_user_show_message( (*this_).message_to_user,
137 : GUI_SIMPLE_MESSAGE_TYPE_WARNING,
138 : GUI_SIMPLE_MESSAGE_CONTENT_DB_IS_READ_ONLY
139 : );
140 : }
141 :
142 : /* cleanup */
143 0 : data_classifier_destroy ( &((*this_).private_temp_classifier) );
144 :
145 0 : U8_TRACE_END_ERR( c_result );
146 0 : return c_result;
147 : }
148 :
149 0 : u8_error_t gui_sketch_object_creator_create_classifier_as_child ( gui_sketch_object_creator_t *this_,
150 : data_row_t diagram_id,
151 : data_row_t parent_classifier_id,
152 : int32_t x_order,
153 : int32_t y_order,
154 : data_row_t *out_diagramelement_id,
155 : data_row_t *out_classifier_id,
156 : data_row_t *out_relationship_id )
157 : {
158 0 : U8_TRACE_BEGIN();
159 0 : assert ( NULL != out_classifier_id );
160 0 : assert ( NULL != out_diagramelement_id );
161 0 : assert ( NULL != out_relationship_id );
162 0 : assert ( DATA_ROW_VOID != parent_classifier_id );
163 0 : assert ( DATA_ROW_VOID != diagram_id );
164 :
165 : u8_error_t c_result;
166 :
167 0 : c_result = gui_sketch_object_creator_create_classifier( this_,
168 : diagram_id,
169 : x_order,
170 : y_order,
171 : out_diagramelement_id,
172 : out_classifier_id
173 : );
174 :
175 0 : if ( U8_ERROR_NONE == c_result )
176 : {
177 : /* get classifier controller */
178 : ctrl_classifier_controller_t *classifier_control;
179 0 : classifier_control = ctrl_controller_get_classifier_control_ptr ( (*this_).controller );
180 :
181 : /* define relationship */
182 : const u8_error_t d_err
183 0 : = data_relationship_init_new( &((*this_).private_temp_relationship),
184 : parent_classifier_id,
185 : DATA_ROW_VOID,
186 : *out_classifier_id,
187 : DATA_ROW_VOID,
188 : DATA_RELATIONSHIP_TYPE_UML_CONTAINMENT,
189 : "", /* =stereotype */
190 : "", /* =name */
191 : "", /* =description */
192 : y_order /* =list_order */
193 : );
194 0 : if ( d_err != U8_ERROR_NONE )
195 : {
196 0 : U8_LOG_ERROR_HEX("data_relationship_init failed in gui_sketch_object_creator_create_classifier_as_child:",d_err);
197 : }
198 :
199 : /* create relationship */
200 0 : c_result = ctrl_classifier_controller_create_relationship( classifier_control,
201 0 : &((*this_).private_temp_relationship),
202 : CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND,
203 : out_relationship_id
204 : );
205 :
206 : /* cleanup */
207 0 : data_relationship_destroy( &((*this_).private_temp_relationship) );
208 : }
209 :
210 0 : U8_TRACE_END_ERR( c_result );
211 0 : return c_result;
212 : }
213 :
214 0 : u8_error_t gui_sketch_object_creator_create_diagram ( gui_sketch_object_creator_t *this_,
215 : data_row_t parent_diagram_id,
216 : int32_t list_order,
217 : data_row_t *out_diagram_id )
218 : {
219 0 : U8_TRACE_BEGIN();
220 0 : assert ( NULL != out_diagram_id );
221 :
222 : u8_error_t c_result;
223 :
224 : ctrl_diagram_controller_t *diag_control;
225 0 : diag_control = ctrl_controller_get_diagram_control_ptr ( (*this_).controller );
226 :
227 : /* create the diagram */
228 : const u8_error_t d_err
229 0 : = data_diagram_init_new( &((*this_).private_temp_diagram),
230 : parent_diagram_id,
231 : DATA_DIAGRAM_TYPE_UML_COMPONENT_DIAGRAM,
232 : "",
233 : "New Diagram",
234 : "",
235 : list_order,
236 : DATA_DIAGRAM_FLAG_NONE
237 : );
238 0 : if ( d_err != U8_ERROR_NONE )
239 : {
240 0 : U8_LOG_ERROR_HEX("data_diagram_init_new failed in gui_sketch_object_creator_create_diagram:",d_err);
241 : }
242 :
243 0 : c_result = ctrl_diagram_controller_create_diagram( diag_control,
244 0 : &((*this_).private_temp_diagram),
245 : CTRL_UNDO_REDO_ACTION_BOUNDARY_START_NEW,
246 : out_diagram_id
247 : );
248 0 : if ( U8_ERROR_READ_ONLY_DB == c_result )
249 : {
250 : /* notify read-only warning to user */
251 0 : gui_simple_message_to_user_show_message( (*this_).message_to_user,
252 : GUI_SIMPLE_MESSAGE_TYPE_WARNING,
253 : GUI_SIMPLE_MESSAGE_CONTENT_DB_IS_READ_ONLY
254 : );
255 : }
256 :
257 : /* cleanup */
258 0 : if ( d_err == U8_ERROR_NONE )
259 : {
260 0 : data_diagram_destroy ( &((*this_).private_temp_diagram) );
261 : }
262 :
263 0 : U8_TRACE_END_ERR( c_result );
264 0 : return c_result;
265 : }
266 :
267 0 : u8_error_t gui_sketch_object_creator_create_relationship ( gui_sketch_object_creator_t *this_,
268 : data_diagram_type_t diag_type,
269 : data_row_t from_classifier_id,
270 : data_row_t from_feature_id,
271 : data_row_t to_classifier_id,
272 : data_row_t to_feature_id,
273 : int32_t list_order,
274 : data_row_t *out_relationship_id )
275 : {
276 0 : U8_TRACE_BEGIN();
277 0 : assert ( NULL != out_relationship_id );
278 0 : assert ( DATA_ROW_VOID != from_classifier_id );
279 0 : assert ( DATA_ROW_VOID != to_classifier_id );
280 :
281 : u8_error_t c_result;
282 :
283 : /* get classifier controller */
284 : ctrl_classifier_controller_t *classifier_control;
285 0 : classifier_control = ctrl_controller_get_classifier_control_ptr( (*this_).controller );
286 :
287 : /* propose a type for the relationship */
288 0 : data_relationship_type_t new_rel_type = DATA_RELATIONSHIP_TYPE_UML_DEPENDENCY;
289 : {
290 : /* get type of from_classifier */
291 0 : data_classifier_type_t from_class_type = DATA_CLASSIFIER_TYPE_CLASS;
292 : {
293 : const u8_error_t clsfy_err
294 0 : = data_database_reader_get_classifier_by_id( (*this_).db_reader,
295 : from_classifier_id,
296 : &((*this_).private_temp_classifier)
297 : );
298 0 : if ( U8_ERROR_NONE == clsfy_err )
299 : {
300 0 : from_class_type = data_classifier_get_main_type( &((*this_).private_temp_classifier) );
301 0 : data_classifier_destroy ( &((*this_).private_temp_classifier) );
302 : }
303 : else
304 : {
305 0 : U8_LOG_ERROR_INT( "gui_sketch_object_creator_create_relationship cannot find classifier:", from_classifier_id );
306 : }
307 : }
308 :
309 : /* get type of from_feature */
310 0 : data_feature_type_t from_feature_type = DATA_FEATURE_TYPE_VOID;
311 0 : if ( from_feature_id != DATA_ROW_VOID )
312 : {
313 : const u8_error_t feat_err
314 0 : = data_database_reader_get_feature_by_id( (*this_).db_reader,
315 : from_feature_id,
316 : &((*this_).private_temp_feature)
317 : );
318 0 : if ( U8_ERROR_NONE == feat_err )
319 : {
320 0 : from_feature_type = data_feature_get_main_type( &((*this_).private_temp_feature) );
321 0 : data_feature_destroy ( &((*this_).private_temp_feature) );
322 : }
323 : else
324 : {
325 0 : U8_LOG_ERROR_INT( "gui_sketch_object_creator_create_relationship cannot find feature:", from_feature_id );
326 : }
327 : }
328 0 : new_rel_type = gui_sketch_defaults_get_relationship_type( &((*this_).defaults), from_class_type, from_feature_type );
329 : }
330 :
331 : /* define relationship struct */
332 : const u8_error_t d_err
333 0 : = data_relationship_init_new( &((*this_).private_temp_relationship),
334 : from_classifier_id,
335 : from_feature_id,
336 : to_classifier_id,
337 : to_feature_id,
338 : new_rel_type,
339 : "", /* =stereotype */
340 : "", /* =name */
341 : "", /* =description */
342 : list_order
343 : );
344 0 : if ( d_err != U8_ERROR_NONE )
345 : {
346 0 : U8_LOG_ERROR_HEX("data_relationship_init failed in gui_sketch_object_creator_create_relationship:",d_err);
347 : }
348 :
349 : /* check preconditions */
350 0 : const bool is_scenario = data_rules_diagram_is_scenario ( &((*this_).data_rules), diag_type )
351 0 : && (( from_feature_id != DATA_ROW_VOID )||( to_feature_id != DATA_ROW_VOID ));
352 0 : const bool diagram_ok = is_scenario
353 0 : ? data_rules_diagram_shows_scenario_relationships ( &((*this_).data_rules), diag_type )
354 0 : : data_rules_diagram_shows_uncond_relationships ( &((*this_).data_rules), diag_type );
355 :
356 0 : if ( diagram_ok ) {
357 : /* create relationship */
358 0 : c_result = ctrl_classifier_controller_create_relationship( classifier_control,
359 0 : &((*this_).private_temp_relationship),
360 : CTRL_UNDO_REDO_ACTION_BOUNDARY_START_NEW,
361 : out_relationship_id
362 : );
363 0 : if ( U8_ERROR_READ_ONLY_DB == c_result )
364 : {
365 : /* notify read-only warning to user */
366 0 : gui_simple_message_to_user_show_message( (*this_).message_to_user,
367 : GUI_SIMPLE_MESSAGE_TYPE_WARNING,
368 : GUI_SIMPLE_MESSAGE_CONTENT_DB_IS_READ_ONLY
369 : );
370 : }
371 : }
372 : else
373 : {
374 : /* notify error to user */
375 0 : gui_simple_message_to_user_show_message( (*this_).message_to_user,
376 : GUI_SIMPLE_MESSAGE_TYPE_ERROR,
377 : GUI_SIMPLE_MESSAGE_CONTENT_NO_RELATIONSHIPS
378 : );
379 0 : c_result = U8_ERROR_DIAGRAM_HIDES_RELATIONSHIPS;
380 : }
381 :
382 : /* cleanup */
383 0 : data_relationship_destroy( &((*this_).private_temp_relationship) );
384 :
385 0 : U8_TRACE_END_ERR( c_result );
386 0 : return c_result;
387 : }
388 :
389 0 : u8_error_t gui_sketch_object_creator_create_feature ( gui_sketch_object_creator_t *this_,
390 : data_diagram_type_t diag_type,
391 : data_row_t parent_classifier_id,
392 : int32_t std_list_order,
393 : int32_t port_list_order,
394 : data_row_t *out_feature_id )
395 : {
396 0 : U8_TRACE_BEGIN();
397 0 : assert ( NULL != out_feature_id );
398 0 : assert ( DATA_ROW_VOID != parent_classifier_id );
399 :
400 : u8_error_t c_result;
401 :
402 : /* get classifier controller */
403 : ctrl_classifier_controller_t *classifier_control;
404 0 : classifier_control = ctrl_controller_get_classifier_control_ptr( (*this_).controller );
405 :
406 : /* get type of parent classifier */
407 0 : data_classifier_type_t parent_class_type = DATA_CLASSIFIER_TYPE_CLASS;
408 : {
409 : const u8_error_t clsfy_err
410 0 : = data_database_reader_get_classifier_by_id( (*this_).db_reader,
411 : parent_classifier_id,
412 : &((*this_).private_temp_classifier)
413 : );
414 0 : if ( U8_ERROR_NONE == clsfy_err )
415 : {
416 0 : parent_class_type = data_classifier_get_main_type( &((*this_).private_temp_classifier) );
417 0 : data_classifier_destroy( &((*this_).private_temp_classifier) );
418 : }
419 : else
420 : {
421 0 : U8_LOG_ERROR_INT( "gui_sketch_object_creator_create_feature cannot find classifier:", parent_classifier_id );
422 : }
423 : }
424 :
425 : /* propose a type for the feature */
426 : data_feature_type_t new_feature_type;
427 0 : new_feature_type = gui_sketch_defaults_get_feature_type( &((*this_).defaults), parent_class_type );
428 :
429 : /* select the right list_order */
430 : int32_t list_order;
431 0 : if ( ( DATA_FEATURE_TYPE_PROVIDED_INTERFACE == new_feature_type )
432 0 : || ( DATA_FEATURE_TYPE_REQUIRED_INTERFACE == new_feature_type )
433 0 : || ( DATA_FEATURE_TYPE_PORT == new_feature_type )
434 0 : || ( DATA_FEATURE_TYPE_IN_PORT_PIN == new_feature_type )
435 0 : || ( DATA_FEATURE_TYPE_OUT_PORT_PIN == new_feature_type )
436 0 : || ( DATA_FEATURE_TYPE_ENTRY == new_feature_type )
437 0 : || ( DATA_FEATURE_TYPE_EXIT == new_feature_type ) )
438 : {
439 0 : list_order = port_list_order;
440 : }
441 : else /* DATA_FEATURE_TYPE_PROPERTY or DATA_FEATURE_TYPE_OPERATION or DATA_FEATURE_TYPE_TAGGED_VALUE */
442 : {
443 0 : list_order = std_list_order;
444 : }
445 :
446 : /* define feature struct */
447 : const u8_error_t data_err
448 0 : = data_feature_init_new( &((*this_).private_temp_feature),
449 : new_feature_type,
450 : parent_classifier_id,
451 : "New Feature", /* name */
452 : "", /* type/value */
453 : "",
454 : list_order
455 : );
456 0 : if ( data_err != U8_ERROR_NONE )
457 : {
458 0 : U8_LOG_ERROR_HEX("data_feature_init failed in gui_sketch_object_creator_create_feature:",data_err);
459 : }
460 :
461 : /* check preconditions */
462 0 : const bool is_scenario = data_rules_feature_is_scenario_cond ( &((*this_).data_rules), new_feature_type );
463 0 : assert ( ! is_scenario ); /* lifelines should not be created by this function */
464 0 : const bool diagram_ok = is_scenario
465 0 : ? data_rules_diagram_shows_scenario_features ( &((*this_).data_rules), diag_type )
466 0 : : data_rules_diagram_shows_uncond_features ( &((*this_).data_rules), diag_type );
467 :
468 0 : if ( diagram_ok )
469 : {
470 : /* create feature */
471 0 : c_result = ctrl_classifier_controller_create_feature( classifier_control,
472 0 : &((*this_).private_temp_feature),
473 : CTRL_UNDO_REDO_ACTION_BOUNDARY_START_NEW,
474 : out_feature_id
475 : );
476 0 : if ( U8_ERROR_READ_ONLY_DB == c_result )
477 : {
478 : /* notify read-only warning to user */
479 0 : gui_simple_message_to_user_show_message( (*this_).message_to_user,
480 : GUI_SIMPLE_MESSAGE_TYPE_WARNING,
481 : GUI_SIMPLE_MESSAGE_CONTENT_DB_IS_READ_ONLY
482 : );
483 : }
484 : }
485 : else
486 : {
487 : /* notify error to user */
488 0 : gui_simple_message_to_user_show_message( (*this_).message_to_user,
489 : GUI_SIMPLE_MESSAGE_TYPE_ERROR,
490 : GUI_SIMPLE_MESSAGE_CONTENT_NO_FEATURES
491 : );
492 0 : c_result = U8_ERROR_DIAGRAM_HIDES_FEATURES;
493 : }
494 :
495 : /* cleanup */
496 0 : data_feature_destroy( &((*this_).private_temp_feature) );
497 :
498 0 : U8_TRACE_END_ERR( c_result );
499 0 : return c_result;
500 : }
501 :
502 :
503 : /*
504 : Copyright 2017-2026 Andreas Warnke
505 :
506 : Licensed under the Apache License, Version 2.0 (the "License");
507 : you may not use this file except in compliance with the License.
508 : You may obtain a copy of the License at
509 :
510 : http://www.apache.org/licenses/LICENSE-2.0
511 :
512 : Unless required by applicable law or agreed to in writing, software
513 : distributed under the License is distributed on an "AS IS" BASIS,
514 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
515 : See the License for the specific language governing permissions and
516 : limitations under the License.
517 : */
|