No issues found
1 /*
2 *
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) version 3.
7 *
8 * This program 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 GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with the program; if not, see <http://www.gnu.org/licenses/>
15 *
16 *
17 * Authors:
18 * Miguel de Icaza <miguel@ximian.com>
19 * Chris Lahey <clahey@ximian.com>
20 *
21 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <gtk/gtk.h>
30 #include "e-util/e-util.h"
31
32 #include "e-cell.h"
33
34 G_DEFINE_TYPE (ECell, e_cell, G_TYPE_OBJECT)
35
36 static ECellView *
37 ec_new_view (ECell *ecell,
38 ETableModel *table_model,
39 gpointer e_table_item_view)
40 {
41 return NULL;
42 }
43
44 static void
45 ec_realize (ECellView *e_cell)
46 {
47 }
48
49 static void
50 ec_kill_view (ECellView *ecell_view)
51 {
52 }
53
54 static void
55 ec_unrealize (ECellView *e_cell)
56 {
57 }
58
59 static void
60 ec_draw (ECellView *ecell_view,
61 cairo_t *cr,
62 gint model_col,
63 gint view_col,
64 gint row,
65 ECellFlags flags,
66 gint x1,
67 gint y1,
68 gint x2,
69 gint y2)
70 {
71 g_critical ("e-cell-draw invoked");
72 }
73
74 static gint
75 ec_event (ECellView *ecell_view,
76 GdkEvent *event,
77 gint model_col,
78 gint view_col,
79 gint row,
80 ECellFlags flags,
81 ECellActions *actions)
82 {
83 g_critical ("e-cell-event invoked");
84
85 return 0;
86 }
87
88 static gint
89 ec_height (ECellView *ecell_view,
90 gint model_col,
91 gint view_col,
92 gint row)
93 {
94 g_critical ("e-cell-height invoked");
95
96 return 0;
97 }
98
99 static void
100 ec_focus (ECellView *ecell_view,
101 gint model_col,
102 gint view_col,
103 gint row,
104 gint x1,
105 gint y1,
106 gint x2,
107 gint y2)
108 {
109 ecell_view->focus_col = view_col;
110 ecell_view->focus_row = row;
111 ecell_view->focus_x1 = x1;
112 ecell_view->focus_y1 = y1;
113 ecell_view->focus_x2 = x2;
114 ecell_view->focus_y2 = y2;
115 }
116
117 static void
118 ec_unfocus (ECellView *ecell_view)
119 {
120 ecell_view->focus_col = -1;
121 ecell_view->focus_row = -1;
122 ecell_view->focus_x1 = -1;
123 ecell_view->focus_y1 = -1;
124 ecell_view->focus_x2 = -1;
125 ecell_view->focus_y2 = -1;
126 }
127
128 static gpointer
129 ec_enter_edit (ECellView *ecell_view,
130 gint model_col,
131 gint view_col,
132 gint row)
133 {
134 return NULL;
135 }
136
137 static void
138 ec_leave_edit (ECellView *ecell_view,
139 gint model_col,
140 gint view_col,
141 gint row,
142 gpointer context)
143 {
144 }
145
146 static gpointer
147 ec_save_state (ECellView *ecell_view,
148 gint model_col,
149 gint view_col,
150 gint row,
151 gpointer context)
152 {
153 return NULL;
154 }
155
156 static void
157 ec_load_state (ECellView *ecell_view,
158 gint model_col,
159 gint view_col,
160 gint row,
161 gpointer context,
162 gpointer save_state)
163 {
164 }
165
166 static void
167 ec_free_state (ECellView *ecell_view,
168 gint model_col,
169 gint view_col,
170 gint row,
171 gpointer save_state)
172 {
173 }
174
175 static void
176 e_cell_class_init (ECellClass *class)
177 {
178 class->realize = ec_realize;
179 class->unrealize = ec_unrealize;
180 class->new_view = ec_new_view;
181 class->kill_view = ec_kill_view;
182 class->draw = ec_draw;
183 class->event = ec_event;
184 class->focus = ec_focus;
185 class->unfocus = ec_unfocus;
186 class->height = ec_height;
187 class->enter_edit = ec_enter_edit;
188 class->leave_edit = ec_leave_edit;
189 class->save_state = ec_save_state;
190 class->load_state = ec_load_state;
191 class->free_state = ec_free_state;
192 class->print = NULL;
193 class->print_height = NULL;
194 class->max_width = NULL;
195 class->max_width_by_row = NULL;
196 }
197
198 static void
199 e_cell_init (ECell *cell)
200 {
201 }
202
203 /**
204 * e_cell_event:
205 * @ecell_view: The ECellView where the event will be dispatched
206 * @event: The GdkEvent.
207 * @model_col: the column in the model
208 * @view_col: the column in the view
209 * @row: the row
210 * @flags: flags about the current state
211 * @actions: a second return value in case the cell wants to take some action
212 * (specifically grabbing & ungrabbing)
213 *
214 * Dispatches the event @event to the @ecell_view for.
215 *
216 * Returns: processing state from the GdkEvent handling.
217 */
218 gint
219 e_cell_event (ECellView *ecell_view,
220 GdkEvent *event,
221 gint model_col,
222 gint view_col,
223 gint row,
224 ECellFlags flags,
225 ECellActions *actions)
226 {
227 ECellClass *class;
228
229 class = E_CELL_GET_CLASS (ecell_view->ecell);
230
231 return class->event (
232 ecell_view, event, model_col,
233 view_col, row, flags, actions);
234 }
235
236 /**
237 * e_cell_new_view:
238 * @ecell: the Ecell that will create the new view
239 * @table_model: the table model the ecell is bound to
240 * @e_table_item_view: an ETableItem object (the CanvasItem that
241 * reprensents the view of the table)
242 *
243 * ECell renderers new to be bound to a table_model and to the actual view
244 * during their life time to actually render the data. This method is invoked
245 * by the ETableItem canvas item to instatiate a new view of the ECell.
246 *
247 * This is invoked when the ETableModel is attached to the ETableItem
248 * (a CanvasItem that can render ETableModels in the screen).
249 *
250 * Returns: a new ECellView for this @ecell on the @table_model displayed
251 * on the @e_table_item_view.
252 */
253 ECellView *
254 e_cell_new_view (ECell *ecell,
255 ETableModel *table_model,
256 gpointer e_table_item_view)
257 {
258 return E_CELL_GET_CLASS (ecell)->new_view (
259 ecell, table_model, e_table_item_view);
260 }
261
262 /**
263 * e_cell_realize:
264 * @ecell_view: The ECellView to be realized.
265 *
266 * This function is invoked to give a chance to the ECellView to allocate
267 * any resources it needs from Gdk, equivalent to the GtkWidget::realize
268 * signal.
269 */
270 void
271 e_cell_realize (ECellView *ecell_view)
272 {
273 ECellClass *class;
274
275 class = E_CELL_GET_CLASS (ecell_view->ecell);
276 g_return_if_fail (class->realize != NULL);
277
278 class->realize (ecell_view);
279 }
280
281 /**
282 * e_cell_kill_view:
283 * @ecell_view: view to be destroyed.
284 *
285 * This method it used to destroy a view of an ECell renderer
286 */
287 void
288 e_cell_kill_view (ECellView *ecell_view)
289 {
290 ECellClass *class;
291
292 class = E_CELL_GET_CLASS (ecell_view->ecell);
293 g_return_if_fail (class->kill_view != NULL);
294
295 class->kill_view (ecell_view);
296 }
297
298 /**
299 * e_cell_unrealize:
300 * @ecell_view: The ECellView to be unrealized.
301 *
302 * This function is invoked to give a chance to the ECellView to
303 * release any resources it allocated during the realize method,
304 * equivalent to the GtkWidget::unrealize signal.
305 */
306 void
307 e_cell_unrealize (ECellView *ecell_view)
308 {
309 ECellClass *class;
310
311 class = E_CELL_GET_CLASS (ecell_view->ecell);
312 g_return_if_fail (class->unrealize != NULL);
313
314 class->unrealize (ecell_view);
315 }
316
317 /**
318 * e_cell_draw:
319 * @ecell_view: the ECellView to redraw
320 * @cr: a Cairo context
321 * @model_col: the column in the model being drawn.
322 * @view_col: the column in the view being drawn (what the model maps to).
323 * @row: the row being drawn
324 * @flags: rendering flags.
325 * @x1: boudary for the rendering
326 * @y1: boudary for the rendering
327 * @x2: boudary for the rendering
328 * @y2: boudary for the rendering
329 *
330 * This instructs the ECellView to render itself into the Cairo context.
331 * The region to be drawn in given by (x1,y1)-(x2,y2).
332 *
333 * The most important flags are %E_CELL_SELECTED and %E_CELL_FOCUSED, other
334 * flags include alignments and justifications.
335 */
336 void
337 e_cell_draw (ECellView *ecell_view,
338 cairo_t *cr,
339 gint model_col,
340 gint view_col,
341 gint row,
342 ECellFlags flags,
343 gint x1,
344 gint y1,
345 gint x2,
346 gint y2)
347 {
348 ECellClass *class;
349
350 g_return_if_fail (ecell_view != NULL);
351 g_return_if_fail (row >= 0);
352 g_return_if_fail (row < e_table_model_row_count (ecell_view->e_table_model));
353
354 class = E_CELL_GET_CLASS (ecell_view->ecell);
355 g_return_if_fail (class->draw != NULL);
356
357 cairo_save (cr);
358
359 class->draw (
360 ecell_view, cr,
361 model_col, view_col,
362 row, flags, x1, y1, x2, y2);
363
364 cairo_restore (cr);
365 }
366
367 /**
368 * e_cell_print:
369 * @ecell_view: the ECellView to redraw
370 * @context: The GtkPrintContext where we output our printed data.
371 * @model_col: the column in the model being drawn.
372 * @view_col: the column in the view being drawn (what the model maps to).
373 * @row: the row being drawn
374 * @width: width
375 * @height: height
376 *
377 * FIXME:
378 */
379 void
380 e_cell_print (ECellView *ecell_view,
381 GtkPrintContext *context,
382 gint model_col,
383 gint view_col,
384 gint row,
385 gdouble width,
386 gdouble height)
387 {
388 ECellClass *class;
389
390 class = E_CELL_GET_CLASS (ecell_view->ecell);
391
392 if (class->print != NULL)
393 class->print (
394 ecell_view, context,
395 model_col, view_col,
396 row, width, height);
397 }
398
399 /**
400 * e_cell_print:
401 *
402 * FIXME:
403 */
404 gdouble
405 e_cell_print_height (ECellView *ecell_view,
406 GtkPrintContext *context,
407 gint model_col,
408 gint view_col,
409 gint row,
410 gdouble width)
411 {
412 ECellClass *class;
413
414 class = E_CELL_GET_CLASS (ecell_view->ecell);
415
416 if (class->print_height == NULL)
417 return 0.0;
418
419 return class->print_height (
420 ecell_view, context,
421 model_col, view_col,
422 row, width);
423 }
424
425 /**
426 * e_cell_height:
427 * @ecell_view: the ECellView.
428 * @model_col: the column in the model
429 * @view_col: the column in the view.
430 * @row: the row to me measured
431 *
432 * Returns: the height of the cell at @model_col, @row rendered at
433 * @view_col, @row.
434 */
435 gint
436 e_cell_height (ECellView *ecell_view,
437 gint model_col,
438 gint view_col,
439 gint row)
440 {
441 ECellClass *class;
442
443 class = E_CELL_GET_CLASS (ecell_view->ecell);
444 g_return_val_if_fail (class->height != NULL, 0);
445
446 return class->height (ecell_view, model_col, view_col, row);
447 }
448
449 /**
450 * e_cell_enter_edit:
451 * @ecell_view: the ECellView that will enter editing
452 * @model_col: the column in the model
453 * @view_col: the column in the view
454 * @row: the row
455 *
456 * Notifies the ECellView that it is about to enter editing mode for
457 * @model_col, @row rendered at @view_col, @row.
458 */
459 gpointer
460 e_cell_enter_edit (ECellView *ecell_view,
461 gint model_col,
462 gint view_col,
463 gint row)
464 {
465 ECellClass *class;
466
467 class = E_CELL_GET_CLASS (ecell_view->ecell);
468 g_return_val_if_fail (class->enter_edit != NULL, NULL);
469
470 return class->enter_edit (ecell_view, model_col, view_col, row);
471 }
472
473 /**
474 * e_cell_leave_edit:
475 * @ecell_view: the ECellView that will leave editing
476 * @model_col: the column in the model
477 * @view_col: the column in the view
478 * @row: the row
479 * @edit_context: the editing context
480 *
481 * Notifies the ECellView that editing is finished at @model_col, @row
482 * rendered at @view_col, @row.
483 */
484 void
485 e_cell_leave_edit (ECellView *ecell_view,
486 gint model_col,
487 gint view_col,
488 gint row,
489 gpointer edit_context)
490 {
491 ECellClass *class;
492
493 class = E_CELL_GET_CLASS (ecell_view->ecell);
494 g_return_if_fail (class->leave_edit != NULL);
495
496 class->leave_edit (ecell_view, model_col, view_col, row, edit_context);
497 }
498
499 /**
500 * e_cell_save_state:
501 * @ecell_view: the ECellView to save
502 * @model_col: the column in the model
503 * @view_col: the column in the view
504 * @row: the row
505 * @edit_context: the editing context
506 *
507 * Returns: The save state.
508 *
509 * Requests that the ECellView return a gpointer representing the state
510 * of the ECell. This is primarily intended for things like selection
511 * or scrolling.
512 */
513 gpointer
514 e_cell_save_state (ECellView *ecell_view,
515 gint model_col,
516 gint view_col,
517 gint row,
518 gpointer edit_context)
519 {
520 ECellClass *class;
521
522 class = E_CELL_GET_CLASS (ecell_view->ecell);
523
524 if (class->save_state == NULL)
525 return NULL;
526
527 return class->save_state (
528 ecell_view, model_col, view_col, row, edit_context);
529 }
530
531 /**
532 * e_cell_load_state:
533 * @ecell_view: the ECellView to load
534 * @model_col: the column in the model
535 * @view_col: the column in the view
536 * @row: the row
537 * @edit_context: the editing context
538 * @save_state: the save state to load from
539 *
540 * Requests that the ECellView load from the given save state.
541 */
542 void
543 e_cell_load_state (ECellView *ecell_view,
544 gint model_col,
545 gint view_col,
546 gint row,
547 gpointer edit_context,
548 gpointer save_state)
549 {
550 ECellClass *class;
551
552 class = E_CELL_GET_CLASS (ecell_view->ecell);
553
554 if (class->load_state != NULL)
555 class->load_state (
556 ecell_view, model_col, view_col,
557 row, edit_context, save_state);
558 }
559
560 /**
561 * e_cell_free_state:
562 * @ecell_view: the ECellView
563 * @model_col: the column in the model
564 * @view_col: the column in the view
565 * @row: the row
566 * @edit_context: the editing context
567 * @save_state: the save state to free
568 *
569 * Requests that the ECellView free the given save state.
570 */
571 void
572 e_cell_free_state (ECellView *ecell_view,
573 gint model_col,
574 gint view_col,
575 gint row,
576 gpointer save_state)
577 {
578 ECellClass *class;
579
580 class = E_CELL_GET_CLASS (ecell_view->ecell);
581
582 if (class->free_state != NULL)
583 class->free_state (
584 ecell_view, model_col, view_col, row, save_state);
585 }
586
587 /**
588 * e_cell_max_width:
589 * @ecell_view: the ECellView that will leave editing
590 * @model_col: the column in the model
591 * @view_col: the column in the view.
592 *
593 * Returns: the maximum width for the ECellview at @model_col which
594 * is being rendered as @view_col
595 */
596 gint
597 e_cell_max_width (ECellView *ecell_view,
598 gint model_col,
599 gint view_col)
600 {
601 ECellClass *class;
602
603 class = E_CELL_GET_CLASS (ecell_view->ecell);
604 g_return_val_if_fail (class->max_width != NULL, 0);
605
606 return class->max_width (ecell_view, model_col, view_col);
607 }
608
609 /**
610 * e_cell_max_width_by_row:
611 * @ecell_view: the ECellView that we are curious about
612 * @model_col: the column in the model
613 * @view_col: the column in the view.
614 * @row: The row in the model.
615 *
616 * Returns: the maximum width for the ECellview at @model_col which
617 * is being rendered as @view_col for the data in @row.
618 */
619 gint
620 e_cell_max_width_by_row (ECellView *ecell_view,
621 gint model_col,
622 gint view_col,
623 gint row)
624 {
625 ECellClass *class;
626
627 class = E_CELL_GET_CLASS (ecell_view->ecell);
628
629 if (class->max_width_by_row == NULL)
630 return e_cell_max_width (ecell_view, model_col, view_col);
631
632 return class->max_width_by_row (ecell_view, model_col, view_col, row);
633 }
634
635 /**
636 * e_cell_max_width_by_row_implemented:
637 * @ecell_view: the ECellView that we are curious about
638 * @model_col: the column in the model
639 * @view_col: the column in the view.
640 * @row: The row in the model.
641 *
642 * Returns: the maximum width for the ECellview at @model_col which
643 * is being rendered as @view_col for the data in @row.
644 */
645 gboolean
646 e_cell_max_width_by_row_implemented (ECellView *ecell_view)
647 {
648 ECellClass *class;
649
650 class = E_CELL_GET_CLASS (ecell_view->ecell);
651
652 return (class->max_width_by_row != NULL);
653 }
654
655 gchar *
656 e_cell_get_bg_color (ECellView *ecell_view,
657 gint row)
658 {
659 ECellClass *class;
660
661 class = E_CELL_GET_CLASS (ecell_view->ecell);
662
663 if (class->get_bg_color == NULL)
664 return NULL;
665
666 return class->get_bg_color (ecell_view, row);
667 }
668
669 void
670 e_cell_style_set (ECellView *ecell_view,
671 GtkStyle *previous_style)
672 {
673 ECellClass *class;
674
675 class = E_CELL_GET_CLASS (ecell_view->ecell);
676
677 if (class->style_set != NULL)
678 class->style_set (ecell_view, previous_style);
679 }