1. Changed license year
[apps/home/mobileprint.git] / mobileprint / smsc / lib / smsc_smart.c
1 /*
2 *  Mobileprint
3 *
4 * Copyright 2013  Samsung Electronics Co., Ltd
5
6 * Licensed under the Flora License, Version 1.1 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9
10 * http://floralicense.org/license/
11
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20 #include <Evas.h>
21
22 #include "smsc_debug.h"
23 #include "smsc_widget.h"
24
25 #include "smsc_smart.h"
26
27
28 #define _evas_smart_smsc_type "Evas_Smart_Smsc"
29
30
31 #define _evas_smart_smsc_type           "Evas_Smart_Smsc"
32 #define EVT_CHILDREN_NUMBER_CHANGED     "children,changed"
33
34
35 static const Evas_Smart_Cb_Description _smart_callbacks[] =
36 {
37    {EVT_CHILDREN_NUMBER_CHANGED, "i"},
38    {NULL, NULL}
39 };
40
41
42 struct _Evas_Smart_Smsc_Data {
43         Evas_Object_Smart_Clipped_Data base;
44         struct smsc_widget widget;
45         Evas_Object *screen_reader_rectangle;
46
47         int is_ready;
48         struct size_px widget_size;
49
50         int is_process_file;
51         char **fnames;
52         int files_count;
53         char *ppd;
54         struct paper_size_pts paper_size;
55         enum page_orientation orientation;
56         int n_up;
57         struct page_scale scale;
58         int is_grayscale;
59 };
60
61
62 typedef struct _Evas_Smart_Smsc_Data Evas_Smart_Smsc_Data;
63
64
65 #define EVAS_SMART_SMSC_DATA_GET(o, ptr) \
66         Evas_Smart_Smsc_Data *ptr = evas_object_smart_data_get(o)
67
68 #define EVAS_SMART_SMSC_DATA_GET_OR_RETURN(o, ptr)              \
69         EVAS_SMART_SMSC_DATA_GET(o, ptr);                       \
70         if (!ptr) {                                             \
71                 fprintf(stderr, "No widget data for object %p (%s)!", \
72                                 o, evas_object_type_get(o));    \
73                 fflush(stderr);                                 \
74                 abort();                                        \
75                 return;                                         \
76         }
77
78 #define EVAS_SMART_SMSC_DATA_GET_OR_RETURN_VAL(o, ptr, val)     \
79         EVAS_SMART_SMSC_DATA_GET(o, ptr);                       \
80         if (!ptr) {                                             \
81                 fprintf(stderr, "No widget data for object %p (%s)!", \
82                                 o, evas_object_type_get(o));    \
83                 fflush(stderr);                                 \
84                 abort();                                        \
85                 return val;                                     \
86         }
87
88 EVAS_SMART_SUBCLASS_NEW(_evas_smart_smsc_type, _evas_smart_smsc,
89                 Evas_Smart_Class, Evas_Smart_Class,
90                 evas_object_smart_clipped_class_get, _smart_callbacks);
91
92
93 static void _evas_smart_smsc_smart_add(Evas_Object *o)
94 {
95         SMSC_TRACE_BEGIN;
96         EVAS_SMART_DATA_ALLOC(o, Evas_Smart_Smsc_Data);
97
98         init_smsc_widget(&(priv->widget), o);
99         priv->is_ready = 0;
100         memset(&(priv->widget_size), 0, sizeof(priv->widget_size));
101
102         priv->is_process_file = 0;
103         priv->fnames = NULL;
104         priv->files_count = 0;
105         priv->ppd = NULL;
106         memset(&(priv->paper_size), 0, sizeof(priv->paper_size));
107         priv->orientation = PAGE_ORIENTATION_PORTRAIT;
108         priv->n_up = 1;
109         memset(&(priv->scale), 0, sizeof(priv->scale));
110         priv->is_grayscale = 0;
111         priv->screen_reader_rectangle = NULL;
112
113         _evas_smart_smsc_parent_sc->add(o);
114         SMSC_TRACE_END;
115 }
116
117
118 static void _evas_smart_smsc_smart_del(Evas_Object *o)
119 {
120         //EVAS_SMART_SMSC_DATA_GET(o, priv);
121
122         /* remove childrens */
123         /* TODO: destroy smsc_widget */
124
125         _evas_smart_smsc_parent_sc->del(o);
126 }
127
128
129 static void _evas_smart_smsc_smart_show(Evas_Object *o)
130 {
131         EVAS_SMART_SMSC_DATA_GET(o, priv);
132         /* show smsc_widget */
133         show_smsc_widget(&(priv->widget));
134         _evas_smart_smsc_parent_sc->show(o);
135 }
136
137
138 static void _evas_smart_smsc_smart_hide(Evas_Object *o)
139 {
140         EVAS_SMART_SMSC_DATA_GET(o, priv);
141         /* hide childrens */
142         /* TODO: save hide state for smsc_widget */
143         hide_smsc_widget(&(priv->widget));
144         _evas_smart_smsc_parent_sc->hide(o);
145 }
146
147
148 static void _evas_smart_smsc_smart_move(Evas_Object *o,
149                 Evas_Coord x, Evas_Coord y)
150 {
151         /* TODO: correct move event usage (provide picture moving animation) */
152         SMSC_TRACE_BEGIN;
153         EVAS_SMART_SMSC_DATA_GET_OR_RETURN(o, priv);
154         priv->widget.off_x = x;
155         priv->widget.off_y = y;
156         move_smsc_widget_pages(&(priv->widget));
157         evas_object_move(priv->widget.loading_animation, x, y);
158         SMSC_TRACE_END;
159 }
160
161
162 static void _evas_smart_smsc_smart_resize(Evas_Object *o,
163                 Evas_Coord w, Evas_Coord h)
164 {
165         SMSC_TRACE_BEGIN;
166         Evas_Coord ow, oh;
167         evas_object_geometry_get(o, NULL, NULL, &ow, &oh);
168         if ((ow == w) && (oh == h)) {
169                 SMSC_TRACE_END;
170                 return;
171         }
172
173         evas_object_smart_changed(o);
174         SMSC_TRACE_END;
175 }
176
177
178 void evas_smart_smsc_free_process_file_args(Evas_Smart_Smsc_Data *priv)
179 {
180         int i;
181         SMSC_RET_IF(NULL == priv, "priv is NULL");
182         if (priv->fnames != NULL)
183                 for (i = 0; i < priv->files_count; ++i)
184                         SMSC_IF_FREE_MEM(priv->fnames[i]);
185         SMSC_IF_FREE_MEM(priv->fnames);
186         priv->files_count = 0;
187         SMSC_IF_FREE_MEM(priv->ppd);
188         SMSC_IF_FREE_MEM(priv->paper_size.name);
189
190         priv->is_process_file = 0;
191 }
192
193
194 static void _evas_smart_smsc_smart_calculate(Evas_Object *o)
195 {
196         SMSC_TRACE_BEGIN;
197         Evas_Coord x, y, w, h;
198
199         EVAS_SMART_SMSC_DATA_GET_OR_RETURN(o, priv);
200         evas_object_geometry_get(o, &x, &y, &w, &h);
201         SMSC_DEBUG("Geometry: (%d, %d) : (%d, %d)",
202                         x, y, w, h);
203
204         /* change children sizes */
205
206         priv->widget_size.x = w;
207         priv->widget_size.y = h;
208         priv->is_ready = 1;
209
210         /* set widget offset */
211         priv->widget.off_x = x;
212         priv->widget.off_y = y;
213
214         /* resize rectangle for accessibility support */
215         evas_object_move(priv->screen_reader_rectangle, x, y);
216         evas_object_resize(priv->screen_reader_rectangle, w, h);
217
218         clear_smsc_widget(&(priv->widget));
219
220         /* request to preview_engine for recalculation */
221         if (priv->is_process_file)
222                 process_preview_engine_file(&(priv->widget.engine),
223                                 priv->fnames, priv->files_count,
224                                 priv->ppd, &(priv->paper_size),
225                                 &(priv->widget_size), priv->orientation,
226                                 priv->n_up, &(priv->scale), priv->is_grayscale);
227
228         SMSC_TRACE_END;
229 }
230
231
232 /* set smart interface */
233 static void _evas_smart_smsc_smart_set_user(Evas_Smart_Class *sc)
234 {
235         SMSC_TRACE_BEGIN;
236         sc->add = _evas_smart_smsc_smart_add;
237         sc->del = _evas_smart_smsc_smart_del;
238         sc->show = _evas_smart_smsc_smart_show;
239         sc->hide = _evas_smart_smsc_smart_hide;
240         sc->move = _evas_smart_smsc_smart_move;
241
242         sc->resize = _evas_smart_smsc_smart_resize;
243         sc->calculate = _evas_smart_smsc_smart_calculate;
244         SMSC_TRACE_END;
245 }
246
247
248 Evas_Object *evas_smart_smsc_add(Evas *evas)
249 {
250         Evas_Object *res;
251         SMSC_TRACE_BEGIN;
252         res = evas_object_smart_add(evas, _evas_smart_smsc_smart_class_new());
253         SMSC_TRACE_END;
254         return res;
255 }
256
257
258 int evas_smart_smsc_set_file(Evas_Object *o, char **const fnames,
259                 int files_count, const char *ppd,
260                 const struct paper_size_pts *paper_size,
261                 enum page_orientation orientation, int n_up,
262                 const struct page_scale *scale, int is_grayscale)
263 {
264         int res = 0;
265         int i;
266         SMSC_TRACE_BEGIN;
267         SMSC_RETV_IF(NULL == o || NULL == fnames || files_count <= 0
268                         || NULL == fnames[0] || NULL == ppd
269                         || NULL == paper_size || NULL == scale,
270                         -1, "Argument error");
271         EVAS_SMART_SMSC_DATA_GET_OR_RETURN_VAL(o, priv, -1);
272
273         /* save configuration for future usage */
274         evas_smart_smsc_free_process_file_args(priv);
275
276         priv->fnames = malloc(sizeof(char*) * (files_count + 1));
277         SMSC_RETV_IF(NULL == priv->fnames, -1, "Out of memory");
278         memset(priv->fnames, 0, sizeof(char*) * (files_count + 1));
279         for (i = 0; i < files_count; ++i) {
280                 priv->fnames[i] = strdup(fnames[i]);
281                 if (NULL == priv->fnames[i]) {
282                         evas_smart_smsc_free_process_file_args(priv);
283                         SMSC_RETV_IF(1, -1, "Out of memory");
284                 }
285         }
286         priv->files_count = files_count;
287         priv->ppd = strdup(ppd);
288         priv->paper_size = *paper_size;
289         priv->paper_size.name = strdup(paper_size->name);
290         priv->orientation = orientation;
291         priv->n_up = n_up;
292         priv->scale = *scale;
293         priv->is_grayscale = is_grayscale;
294
295         priv->is_process_file = 1;
296
297         if (NULL == priv->ppd || NULL == priv->paper_size.name) {
298                 evas_smart_smsc_free_process_file_args(priv);
299                 SMSC_RETV_IF(1, -1, "Out of memory");
300         }
301
302         /* request preview_engine for recalculation */
303         if (priv->is_ready) {
304                 clear_smsc_widget(&(priv->widget));
305                 res = process_preview_engine_file(&(priv->widget.engine),
306                                 priv->fnames, priv->files_count, priv->ppd,
307                                 &(priv->paper_size), &(priv->widget_size),
308                                 priv->orientation, priv->n_up, &(priv->scale),
309                                 priv->is_grayscale);
310         }
311
312         SMSC_TRACE_END;
313         return res;
314 }
315
316 //needed to get events MOUSE_IN for correct Screen Reader work
317 void smsc_mouse_in_cb(void *data, Evas *evas,
318                 Evas_Object *obj, void *event_info)
319 {
320         SMSC_TRACE_BEGIN;
321         SMSC_TRACE_END;
322 }
323
324 int evas_smart_smsc_set_layout(Evas_Object *o, Evas_Object *layout)
325 {
326         EVAS_SMART_SMSC_DATA_GET_OR_RETURN_VAL(o, priv, -1);
327         smsc_widget_set_layout(&(priv->widget), layout);
328         evas_object_event_callback_add(priv->screen_reader_rectangle, EVAS_CALLBACK_MOUSE_IN,
329                         smsc_mouse_in_cb, &(priv->widget));
330         return 0;
331 }
332
333 /* transparent rectangle to support Screen Reader */
334 int init_smsc_accessability_support(Evas_Object *o)
335 {
336         SMSC_TRACE_BEGIN;
337         SMSC_RETV_IF(NULL == o, -1, "Invalid arguments");
338         EVAS_SMART_SMSC_DATA_GET_OR_RETURN_VAL(o, priv, -1);
339         struct smsc_widget *widget = &(priv->widget);
340
341         SMSC_RETV_IF(NULL == widget || NULL == widget->parent || NULL == widget->canvas, -1,
342                         "Can't get widget of object.");
343         if (NULL == priv->screen_reader_rectangle)
344         {
345                 priv->screen_reader_rectangle = evas_object_rectangle_add(widget->canvas);
346                 SMSC_RETV_IF(NULL == priv->screen_reader_rectangle, -1,
347                         "Failed to add rectangle to smart object widget canvas");
348         }
349
350         evas_object_color_set(priv->screen_reader_rectangle, 0, 0, 0, 0);
351         evas_object_smart_member_add(priv->screen_reader_rectangle, widget->parent);
352         evas_object_move(priv->screen_reader_rectangle,
353                                                 priv->widget.off_x, priv->widget.off_y);
354         evas_object_resize(priv->screen_reader_rectangle,
355                                                 priv->widget_size.x,
356                                                 priv->widget_size.y);
357         evas_object_raise(priv->screen_reader_rectangle);
358         evas_object_show(priv->screen_reader_rectangle);
359
360         SMSC_TRACE_END;
361         return 0;
362 }
363
364 /* rectangle for screen reader creating and registering in access */
365 int set_main_view_accessability_info(Evas_Object *o,
366                                                                         Evas_Object *layout,
367                                                                         const char *access_info,
368                                                                         const char *access_type,
369                                                                         const char *access_context_info)
370 {
371         SMSC_TRACE_BEGIN;
372         EVAS_SMART_SMSC_DATA_GET_OR_RETURN_VAL(o, priv, -1);
373
374         Evas_Object *ao;
375         ao = elm_access_object_get(priv->screen_reader_rectangle);
376         if (NULL == ao) {
377                 ao = elm_access_object_register(priv->screen_reader_rectangle, layout);
378                 SMSC_RETV_IF(NULL == ao, -1, "ERROR: Failed to register smsc in access!");
379         }
380         SMSC_DEBUG("Setting main view accessibility info for screen reader: %s", access_info);
381         elm_access_info_set(ao, ELM_ACCESS_INFO, access_info);
382         elm_access_info_set(ao, ELM_ACCESS_TYPE, access_type);
383         elm_access_info_set(ao, ELM_ACCESS_CONTEXT_INFO, access_context_info);
384         SMSC_TRACE_END;
385         return 0;
386 }
387
388
389 /**
390  * @brief       Calculate current page number based on current page offset
391  * @param[in]   o       Smooth scrolling widget
392  * @return      <0      Error (argument error or not initialized)
393  *              >=0     Current page number starting from 0
394  */
395 int evas_smart_smsc_calculate_page_number(Evas_Object *o)
396 {
397         EVAS_SMART_SMSC_DATA_GET_OR_RETURN_VAL(o, priv, -1);
398         return get_smsc_position_cur_page(&(priv->widget.position));
399 }
400
401
402 /**
403  * @brief       Get pages count
404  * @param[in]   o       Smooth scrolling widget
405  * return       <=0     Error (argument error or not initialized)
406  *              >0      Pages count
407  */
408 int evas_smart_smsc_get_pages_count(Evas_Object *o)
409 {
410         EVAS_SMART_SMSC_DATA_GET_OR_RETURN_VAL(o, priv, -1);
411         SMSC_RETV_IF(!priv->widget.position.is_configured,
412                         -1, "Not initialized");
413         return priv->widget.position.pages_count;
414 }