1 /*
2 * Copyright (C) 2002-2012 Edscott Wilson Garcia
3 * EMail: edscott@users.sf.net
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program;
18 */
19
20 //////////////////////////////////////////////////////////////////////7
21
22 #define RFM_PRIMARY_LAYOUT_C
23
24 #ifdef HAVE_CONFIG_H
25 # include <config.h>
26 #endif
27
28 #include "rfm.h"
29 #include "rfm_modules.h"
30
31 static GtkAllocation rfm_allocation;
rfm_get_allocation(void)32 GtkAllocation *rfm_get_allocation(void){return &rfm_allocation;}
rfm_set_allocation(void)33 void rfm_set_allocation(void){
34 rfm_global_t *rfm_global_p = rfm_global();
35 gtk_widget_get_allocation (rfm_global_p->window,&rfm_allocation);
36 // nested in hpane...
37 GtkWidget *hpane = g_object_get_data(G_OBJECT(rfm_global_p->window), "hpane");
38 if (hpane){
39 NOOP(stderr, "signal_on_size_paper(): we are nested in an hpane...%d\n",
40 gtk_paned_get_position (GTK_PANED(hpane)));
41 rfm_allocation.width -= gtk_paned_get_position (GTK_PANED(hpane));
42 }
43 //memcpy(&rfm_allocation, &allocation, sizeof(GtkAllocation));
44 return;
45 }
46
47 static const gchar *font_sizes_v[] = {
48 "6",
49 "8",
50 "9",
51 "10",
52 "11",
53 "12",
54 "14",
55 "18",
56 "20",
57 "22",
58 "24",
59 NULL
60 };
61
62 static const gchar *icon_sizes_v[] = {
63 "Normal",
64 "Details",
65 "Compact",
66 "Big",
67 "Huge",
68 NULL
69 };
70
71 #include "primary-layout.i"
72
rfm_get_icon_sizes(void)73 const gchar **rfm_get_icon_sizes(void){return icon_sizes_v;}
rfm_get_font_sizes(void)74 const gchar **rfm_get_font_sizes(void){return font_sizes_v;}
75
76 #define LAYOUT_ICON_SIZE (0x01)
77 #define LAYOUT_VPANE_ALLOCATION (0x01<<1)
78 #define LAYOUT_CELLWIDTH (0x01<<2)
79 #define LAYOUT_CELLHEIGHT (0x01<<3)
80 #define LAYOUT_ROOT_PARAMETERS (0x01<<4)
81 #define LAYOUT_ROOT_CONFIGURED (0x01<<5)
82
83 void
rfm_layout_population_grid_row(view_t * view_p,population_t * population_p,gint element)84 rfm_layout_population_grid_row (view_t * view_p, population_t *population_p, gint element){
85 gint grid_rows = GRID_ROWS(view_p);
86 gint grid_columns = GRID_COLUMNS(view_p);
87 if (view_p->flags.type == ICONVIEW_TYPE) {
88 if(grid_columns) {
89 population_p->row = element / grid_columns;
90 population_p->column = element % grid_columns;
91 } else {
92 population_p->row = 0;
93 population_p->column = element;
94 }
95 } else { // transposed matrix for desktop
96 if(grid_rows) {
97 population_p->row = element % grid_rows;
98 population_p->column = element / grid_rows;
99 } else {
100 population_p->row = element;
101 population_p->column = 0;
102 }
103 }
104 }
105
rfm_layout_get_name_width(view_t * view_p)106 gint rfm_layout_get_name_width(view_t *view_p){
107 if (!view_p) return FALSE;
108 view_layout_t *view_layout_p = &(view_p->view_layout);
109 return view_layout_p->name_width;
110 }
111
rfm_layout_get_text_height(view_t * view_p)112 gint rfm_layout_get_text_height(view_t *view_p){
113 if (!view_p) return FALSE;
114 view_layout_t *view_layout_p = &(view_p->view_layout);
115 return view_layout_p->text_height;
116 }
117
rfm_layout_set_root_width(view_t * view_p,gint value)118 gint rfm_layout_set_root_width(view_t *view_p, gint value){
119 if (!view_p) return FALSE;
120 view_layout_t *view_layout_p = &(view_p->view_layout);
121 return view_layout_p->root_w = value;
122 }
123
rfm_layout_set_root_height(view_t * view_p,gint value)124 gint rfm_layout_set_root_height(view_t *view_p, gint value){
125 if (!view_p) return FALSE;
126 view_layout_t *view_layout_p = &(view_p->view_layout);
127 return view_layout_p->root_h = value;
128 }
129
rfm_layout_get_root_width(view_t * view_p)130 gint rfm_layout_get_root_width(view_t *view_p){
131 if (!view_p) return FALSE;
132 view_layout_t *view_layout_p = &(view_p->view_layout);
133 return view_layout_p->root_w;
134 }
135
rfm_layout_get_root_height(view_t * view_p)136 gint rfm_layout_get_root_height(view_t *view_p){
137 if (!view_p) return FALSE;
138 view_layout_t *view_layout_p = &(view_p->view_layout);
139 return view_layout_p->root_h;
140 }
141
rfm_layout_get_root_depth(view_t * view_p)142 gint rfm_layout_get_root_depth(view_t *view_p){
143 if (!view_p) return FALSE;
144 view_layout_t *view_layout_p = &(view_p->view_layout);
145 return view_layout_p->root_d;
146 }
147
rfm_layout_get_max_elements(view_t * view_p)148 gint rfm_layout_get_max_elements(view_t *view_p){
149 if (!view_p) return FALSE;
150 view_layout_t *view_layout_p = &(view_p->view_layout);
151 return view_layout_p->max_elements;
152 }
153
rfm_layout_set_margin_top(view_t * view_p,gint value)154 gint rfm_layout_set_margin_top(view_t *view_p, gint value){
155 if (!view_p) return FALSE;
156 view_layout_t *view_layout_p = &(view_p->view_layout);
157 return view_layout_p->margin_top = value;
158 }
159
rfm_layout_set_margin_bottom(view_t * view_p,gint value)160 gint rfm_layout_set_margin_bottom(view_t *view_p, gint value){
161 if (!view_p) return FALSE;
162 view_layout_t *view_layout_p = &(view_p->view_layout);
163 return view_layout_p->margin_bottom = value;
164 }
165
rfm_layout_set_margin_right(view_t * view_p,gint value)166 gint rfm_layout_set_margin_right(view_t *view_p, gint value){
167 if (!view_p) return FALSE;
168 view_layout_t *view_layout_p = &(view_p->view_layout);
169 return view_layout_p->margin_right = value;
170 }
171
rfm_layout_set_margin_left(view_t * view_p,gint value)172 gint rfm_layout_set_margin_left(view_t *view_p, gint value){
173 if (!view_p) return FALSE;
174 view_layout_t *view_layout_p = &(view_p->view_layout);
175 return view_layout_p->margin_left = value;
176 }
177
178
rfm_layout_get_margin_top(view_t * view_p)179 gint rfm_layout_get_margin_top(view_t *view_p){
180 if (!view_p) return FALSE;
181 view_layout_t *view_layout_p = &(view_p->view_layout);
182 return view_layout_p->margin_top;
183 }
184
rfm_layout_get_margin_bottom(view_t * view_p)185 gint rfm_layout_get_margin_bottom(view_t *view_p){
186 if (!view_p) return FALSE;
187 view_layout_t *view_layout_p = &(view_p->view_layout);
188 return view_layout_p->margin_bottom;
189 }
190
rfm_layout_get_margin_right(view_t * view_p)191 gint rfm_layout_get_margin_right(view_t *view_p){
192 if (!view_p) return FALSE;
193 view_layout_t *view_layout_p = &(view_p->view_layout);
194 return view_layout_p->margin_right;
195 }
196
rfm_layout_get_margin_left(view_t * view_p)197 gint rfm_layout_get_margin_left(view_t *view_p){
198 if (!view_p) return FALSE;
199 view_layout_t *view_layout_p = &(view_p->view_layout);
200 return view_layout_p->margin_left;
201 }
202
203
rfm_layout_is_setup(view_t * view_p)204 gboolean rfm_layout_is_setup(view_t *view_p){
205 if (!view_p) {
206 DBG("rfm_layout_is_setup(): !view_p\n");
207 return FALSE;
208 }
209 view_layout_t *view_layout_p = &(view_p->view_layout);
210 if (!(view_layout_p->tripwire & LAYOUT_ICON_SIZE)) {
211 DBG("rfm_layout_is_setup(): LAYOUT_ICON_SIZE\n");
212 return FALSE;
213 }
214 GtkWidget *vpane = g_object_get_data(G_OBJECT(view_p->widgets.paper), "vpane");
215 if (vpane && !(view_layout_p->tripwire & LAYOUT_VPANE_ALLOCATION)) {
216 DBG("rfm_layout_is_setup(): LAYOUT_VPANE_ALLOCATION\n");
217 return FALSE;
218 }
219 if (!(view_layout_p->tripwire & LAYOUT_CELLWIDTH)) {
220 TRACE("rfm_layout_is_setup(): LAYOUT_CELLWIDTH\n");
221 return FALSE;
222 }
223 if (!(view_layout_p->tripwire & LAYOUT_CELLHEIGHT)) {
224 DBG("rfm_layout_is_setup(): LAYOUT_CELLHEIGHT\n");
225 return FALSE;
226 }
227 if (!(view_layout_p->tripwire & LAYOUT_ROOT_PARAMETERS)) {
228 DBG("rfm_layout_is_setup(): LAYOUT_ROOT_PARAMETERS\n");
229 return FALSE;
230 }
231 if (!(view_layout_p->tripwire & LAYOUT_ROOT_CONFIGURED)) {
232 DBG("rfm_layout_is_setup(): LAYOUT_ROOT_CONFIGURED\n");
233 return FALSE;
234 }
235 return TRUE;
236 }
237
238
rfm_layout_get_grid_rows(view_t * view_p)239 gint rfm_layout_get_grid_rows(view_t *view_p){
240 if (!view_p) g_error("rfm_layout_get_grid_rows: !view_p\n");
241 view_layout_t *view_layout_p = &(view_p->view_layout);
242 if (!(view_layout_p->tripwire & LAYOUT_ROOT_CONFIGURED))
243 g_error("rfm_layout_get_grid_rows: view_layout_p item LAYOUT_ROOT_CONFIGURED is not set\n");
244 return view_layout_p->grid_rows;
245 }
246
rfm_layout_get_grid_columns(view_t * view_p)247 gint rfm_layout_get_grid_columns(view_t *view_p){
248 if (!view_p) g_error("rfm_layout_get_grid_colums: !view_p\n");
249 view_layout_t *view_layout_p = &(view_p->view_layout);
250 if (!(view_layout_p->tripwire & LAYOUT_ROOT_CONFIGURED))
251 g_error("rfm_layout_get_grid_colums: view_layout_p item LAYOUT_ROOT_CONFIGURED is not set\n");
252 return view_layout_p->grid_columns;
253 }
254
layout_set_root_parameters(void * data)255 static void *layout_set_root_parameters(void *data){
256 view_t *view_p = data;
257 gint width;
258 gint height;
259 gint depth;
260 rfm_global_t *rfm_global_p = rfm_global();
261 rfm_get_drawable_geometry (rfm_global_p->root_Xwindow, NULL, NULL,
262 &width, &height, &depth);
263 view_layout_t *view_layout_p = &(view_p->view_layout);
264 view_layout_p->root_w = width;
265 view_layout_p->root_h = height;
266 view_layout_p->root_d = depth;
267 return NULL;
268 }
269
rfm_layout_set_root_parameters(view_t * view_p)270 void rfm_layout_set_root_parameters(view_t *view_p){
271 if (!view_p) g_error("rfm_layout_set_root_parameters: !view_p\n");
272 view_layout_t *view_layout_p = &(view_p->view_layout);
273 //rfm_global_t *rfm_global_p = rfm_global();
274 if (rfm_get_gtk_thread() != g_thread_self()){
275 rfm_context_function(layout_set_root_parameters, view_p);
276 } else {
277 layout_set_root_parameters(view_p);
278 }
279 view_layout_p->tripwire |= LAYOUT_ROOT_PARAMETERS;
280 return;
281 }
282
rfm_layout_get_root_parameters(view_t * view_p,gint * width,gint * height,gint * depth)283 void rfm_layout_get_root_parameters(view_t *view_p, gint *width, gint *height, gint *depth){
284 if (!view_p) g_error("rfm_layout_get_root_parameters: !view_p\n");
285 view_layout_t *view_layout_p = &(view_p->view_layout);
286 if (!(view_layout_p->tripwire & LAYOUT_ROOT_PARAMETERS))
287 g_error("rfm_layout_get_root_parameters: view_layout_p item LAYOUT_ROOT_PARAMETERS is not set\n");
288 if (width) *width = view_layout_p->root_w;
289 if (height) *height = view_layout_p->root_h;
290 if (depth) *depth = view_layout_p->root_d;
291 return;
292 }
293
rfm_layout_get_icon_size(view_t * view_p)294 gint rfm_layout_get_icon_size(view_t *view_p){
295 if (!view_p) g_error("rfm_layout_get_cellheight: !view_p\n");
296 view_layout_t *view_layout_p = &(view_p->view_layout);
297 if (!(view_layout_p->tripwire & LAYOUT_ICON_SIZE))
298 g_error("rfm_layout_get_icon_size: view_layout_p item LAYOUT_ICON_SIZE is not set\n");
299 if (view_layout_p->icon_size) return view_layout_p->icon_size;
300 return TINY_ICON_SIZE;
301 }
302
rfm_layout_get_icon_size_id(view_t * view_p)303 gint rfm_layout_get_icon_size_id(view_t *view_p){
304 if (!view_p) g_error("rfm_layout_get_cellheight: !view_p\n");
305 view_layout_t *view_layout_p = &(view_p->view_layout);
306 if (!(view_layout_p->tripwire & LAYOUT_ICON_SIZE))
307 g_error("rfm_layout_get_icon_size: view_layout_p item LAYOUT_ICON_SIZE is not set\n");
308 return view_layout_p->icon_size;
309 }
310
rfm_layout_is_details_size(view_t * view_p)311 gboolean rfm_layout_is_details_size(view_t *view_p){
312 if (!view_p) g_error("rfm_layout_get_cellheight: !view_p\n");
313 view_layout_t *view_layout_p = &(view_p->view_layout);
314 if (!(view_layout_p->tripwire & LAYOUT_ICON_SIZE))
315 g_error("rfm_layout_get_icon_size: view_layout_p item LAYOUT_ICON_SIZE is not set\n");
316 if (view_layout_p->icon_size) return FALSE;
317 return TRUE;
318 }
319
rfm_layout_get_cellheight(view_t * view_p)320 gint rfm_layout_get_cellheight(view_t *view_p){
321 if (!view_p) g_error("rfm_layout_get_cellheight: !view_p\n");
322 view_layout_t *view_layout_p = &(view_p->view_layout);
323 if (!(view_layout_p->tripwire & LAYOUT_CELLHEIGHT))
324 g_error("rfm_layout_get_cellheight: view_layout_p item LAYOUT_CELLHEIGHT is not set\n");
325 return view_layout_p->cellheight;
326 }
327
rfm_layout_get_cellwidth(view_t * view_p)328 gint rfm_layout_get_cellwidth(view_t *view_p){
329 if (!view_p) g_error("rfm_layout_get_cellwidth: !view_p\n");
330 view_layout_t *view_layout_p = &(view_p->view_layout);
331 if (!(view_layout_p->tripwire & LAYOUT_CELLWIDTH))
332 g_error("rfm_layout_get_cellwidth: view_layout_p item LAYOUT_CELLWIDTH is not set\n");
333 return view_layout_p->cellwidth;
334 }
335
336 static void *
get_drawable_geometry_f(void * data)337 get_drawable_geometry_f(void *data){
338 void **arg = data;
339 Drawable drawable = GPOINTER_TO_INT(arg[0]);
340 gint *x = (gint *)arg[1];
341 gint *y = (gint *)arg[2];
342 gint *w = (gint *)arg[3];
343 gint *h = (gint *)arg[4];
344 gint *d = (gint *)arg[5];
345
346 rfm_global_t *rfm_global_p = rfm_global();
347 if (rfm_get_gtk_thread() != g_thread_self()){
348 g_error("rfm_get_drawable_geometry is a main thread function\n");
349 }
350 gint x_return, y_return;
351 guint w_return, h_return, d_return, border_return;
352 Window root_return;
353 Display *display;
354 if (rfm_global_p) display = rfm_global_p->Xdisplay;
355 else display = gdk_x11_display_get_xdisplay(gdk_display_get_default());
356
357 XGetGeometry(display, drawable, &root_return,
358 &x_return, &y_return,
359 &w_return, &h_return,
360 &border_return,
361 &d_return);
362 if (x) *x = x_return;
363 if (y) *y = y_return;
364 if (w) *w = w_return;
365 if (h) *h = h_return;
366 if (d) *d = d_return;
367 return NULL;
368 }
369
rfm_get_drawable_geometry(Drawable drawable,gint * x,gint * y,gint * w,gint * h,gint * d)370 void rfm_get_drawable_geometry(Drawable drawable,
371 gint *x, gint *y, gint *w, gint *h, gint *d){
372 void *arg[]={
373 GINT_TO_POINTER(drawable),
374 (void *) x,
375 (void *) y,
376 (void *) w,
377 (void *) h,
378 (void *) d,
379 NULL
380 };
381 rfm_context_function(get_drawable_geometry_f, arg);
382 return;
383
384 }
385 #if 0
386 void rfm_get_drawable_geometry(Drawable drawable,
387 gint *x, gint *y, gint *w, gint *h, gint *d){
388 rfm_global_t *rfm_global_p = rfm_global();
389 if (rfm_get_gtk_thread() != g_thread_self()){
390 g_error("rfm_get_drawable_geometry is a main thread function\n");
391 }
392 gint x_return, y_return;
393 guint w_return, h_return, d_return, border_return;
394 Window root_return;
395 Display *display;
396 if (rfm_global_p) display = rfm_global_p->Xdisplay;
397 else display = gdk_x11_display_get_xdisplay(gdk_display_get_default());
398
399 XGetGeometry(display, drawable, &root_return,
400 &x_return, &y_return,
401 &w_return, &h_return,
402 &border_return,
403 &d_return);
404 if (x) *x = x_return;
405 if (y) *y = y_return;
406 if (w) *w = w_return;
407 if (h) *h = h_return;
408 if (d) *d = d_return;
409 return;
410 }
411 #endif
412
413 gint
rfm_get_default_size(void)414 rfm_get_default_size(void){
415 gint default_size = -1;
416 const gchar *rfm_default_icon_size = getenv("RFM_DEFAULT_ICON_SIZE");
417 if (rfm_default_icon_size && strlen(rfm_default_icon_size) != 0){
418 const gchar **p=icon_sizes_v;
419 for (; p && *p; p++){
420 if (strcmp(*p, rfm_default_icon_size)==0){
421 // Gotcha. If value is not valid, it will be ignored.
422 if (strcmp(*p, "Normal")==0) {
423 default_size = SMALL_ICON_SIZE;
424 } else
425 if (strcmp(*p, "Compact")==0) {
426 default_size = TINY_ICON_SIZE;
427 } else
428 if (strcmp(*p, "Details")==0) {
429 default_size = LIST_ICON_SIZE;
430 } else
431 if (strcmp(*p, "Big")==0) {
432 default_size = MEDIUM_ICON_SIZE;
433 } else
434 if (strcmp(*p, "Huge")==0) {
435 default_size = BIG_ICON_SIZE;
436 }
437 }
438 }
439 }
440 // Fallback condition
441 if (default_size == -1) {
442 NOOP("cannot determine default icon size\n");
443 return SMALL_ICON_SIZE;
444 }
445 return default_size;
446 }
447
448 static
449 view_preferences_t *
get_view_preferences_path(gint type,const gchar * path)450 get_view_preferences_path (gint type, const gchar * path) {
451 NOOP ("rodent_get_view_preferences()\n");
452 DBHashTable *preferences=NULL;
453 const gchar *key;
454 GString *gs;
455 gchar *f;
456 if (type==ICONVIEW_TYPE) {
457 f = g_build_filename (GRID_PREFERENCES_FILE, NULL);
458 } else {
459 f = g_build_filename (DESK_PREFERENCES_FILE, NULL);
460 }
461
462 TRACE("opening %s...\n",f);
463 FILE *f_p = fopen(f,"r");
464 if (f_p){
465 fclose(f_p);
466 preferences = dbh_new (f, NULL, DBH_READ_ONLY|DBH_PARALLEL_SAFE|DBH_THREAD_SAFE);
467 }
468
469 TRACE("open %s.\n",f);
470
471 if(!preferences) {
472 NOOP ("Preferences table does not yet exist: %s\n", f);
473 g_free (f);
474 return NULL;
475 }
476 dbh_set_parallel_lock_timeout(preferences, 3);
477 dbh_mutex_lock(preferences);
478
479 if(path){
480 key = path;
481 } else {
482 key = "RODENT_ROOT";
483 }
484 NOOP ("looking for preferences with key=%s\n", key);
485
486 gs = g_string_new (key);
487 sprintf ((char *)DBH_KEY (preferences), "%10u", g_string_hash (gs));
488 g_string_free (gs, TRUE);
489
490 view_preferences_t *view_preferences_p=NULL;
491 if(dbh_load (preferences)) {
492 view_preferences_p=
493 (view_preferences_t *)malloc(sizeof(view_preferences_t));
494 if (!view_preferences_p) g_error("malloc: %s\n", strerror(errno));
495 memcpy (view_preferences_p, DBH_DATA (preferences),
496 sizeof (view_preferences_t));
497
498 NOOP ("got preferences with key=%s (preferences=0x%x, sort_column%d)\n",
499 key, view_preferences_p->preferences, view_preferences_p->sortcolumn);
500 }
501 dbh_mutex_unlock(preferences);
502 dbh_close (preferences);
503 g_free (f);
504 return view_preferences_p;
505 }
506
507
508 view_preferences_t *
rfm_get_view_preferences(gint type,record_entry_t * target_en)509 rfm_get_view_preferences (gint type, record_entry_t *target_en) {
510
511 const gchar *key=NULL;
512 if (target_en) {
513 if (target_en->module){
514 key=(const gchar *)rfm_void(PLUGIN_DIR, target_en->module,
515 "module_preferences_key");
516 }
517 if (!key) key=target_en->path;
518
519 } else {
520 key="RODENT_ROOT";
521 }
522 view_preferences_t *view_preferences_p = get_view_preferences_path (type, key);
523 return view_preferences_p;
524 }
525
526
527 void
rfm_save_view_preferences(view_t * view_p,record_entry_t * target_en)528 rfm_save_view_preferences (view_t * view_p, record_entry_t *target_en) {
529 view_preferences_t iconview_preferences;
530 DBHashTable *preferences=NULL;
531 GString *gs;
532 gchar *f;
533 const gchar *key=NULL;
534 if(!view_p)
535 return;
536
537 NOOP("rfm_save_view_preferences: %s\n", key);
538
539 if(!target_en){
540 key = "RODENT_ROOT";
541 } else if (target_en->module) {
542 key=(const gchar *)rfm_void(PLUGIN_DIR, target_en->module, "module_preferences_key");
543 NOOP("getting preferences key from module: %s\n", key);
544 }
545 if (!key){
546 if (target_en->path==NULL){
547 key = "RODENT_ROOT";
548 } else {
549 key = target_en->path;
550 }
551 }
552
553 if (view_p->flags.type==ICONVIEW_TYPE) {
554 f = g_build_filename (GRID_PREFERENCES_FILE, NULL);
555 } else {
556 f = g_build_filename (DESK_PREFERENCES_FILE, NULL);
557 }
558 gchar *tmp_f=NULL;
559
560
561 TRACE("opening %s...\n",f);
562 FILE *f_p = fopen(f,"r");
563 if (f_p){
564 fclose(f_p);
565 preferences = dbh_new (f, NULL, DBH_PARALLEL_SAFE|DBH_THREAD_SAFE);
566 }
567 if(!preferences) {
568 NOOP ("creating file: %s", f);
569 tmp_f =g_strdup_printf("%s-%d", f, (gint)getpid());
570 unsigned char keylength=11;
571 gchar *directory = g_path_get_dirname(f);
572 if (!g_file_test(directory, G_FILE_TEST_IS_DIR)){
573 g_mkdir_with_parents(directory, 0700);
574 }
575 g_free(directory);
576 preferences = dbh_new (f, &keylength, DBH_PARALLEL_SAFE|DBH_THREAD_SAFE|DBH_CREATE);
577 }
578 TRACE("open %s.\n",f);
579 if(!preferences) {
580 DBG ("cannot open file: %s\n", f);
581 g_free (f);
582 g_free (tmp_f);
583 return;
584 }
585 dbh_set_parallel_lock_timeout(preferences, 3);
586 dbh_mutex_lock(preferences);
587
588 gs = g_string_new (key);
589 sprintf ((char *)DBH_KEY (preferences), "%10u", g_string_hash (gs));
590 g_string_free (gs, TRUE);
591
592 view_layout_t *view_layout_p = &(view_p->view_layout);
593
594 iconview_preferences.preferences = view_p->flags.preferences;
595 iconview_preferences.sortcolumn = view_p->flags.sortcolumn;
596 iconview_preferences.icon_size = view_layout_p->icon_size;
597 NOOP("saving iconsize = %d\n", iconview_preferences.icon_size);
598
599 memcpy (DBH_DATA (preferences), &iconview_preferences, sizeof (view_preferences_t));
600 dbh_set_recordsize (preferences, sizeof (view_preferences_t));
601
602 if(!dbh_update (preferences)) {
603 DBG ("!dbh_update(preferences)\n");
604 }
605 dbh_mutex_unlock(preferences);
606 dbh_close (preferences);
607 if (tmp_f){
608 if (rename(tmp_f, f) < 0){
609 DBG("rename(%s, %s) failed: %s\n",
610 tmp_f, f, strerror(errno));
611 }
612 }
613 NOOP ("saved preferences with key=%s iconsize=%d \n",
614 key, ICON_SIZE(view_p));
615 g_free (f);
616 g_free (tmp_f);
617 return;
618 }
619
620
621 void
rfm_set_view_preferences(view_t * view_p,view_preferences_t * view_preferences_p)622 rfm_set_view_preferences (view_t *view_p, view_preferences_t *view_preferences_p) {
623 if(!view_preferences_p){
624 // No user defined preferences for the "path". We shall now
625 // fall back to the default settings.
626 NOOP( "default settings\n");
627 if (view_p->en && IS_LOCAL_TYPE(view_p->en->type)){
628 view_p->flags.preferences = DEFAULT_VIEW_PREFERENCES;
629 } else {
630 view_p->flags.preferences = DEFAULT_REMOTE_PREFERENCES;
631 }
632
633 view_p->flags.sortcolumn = DEFAULT_SORT_COLUMN;
634 rfm_layout_set_icon_size(view_p, rfm_get_default_size());
635 return;
636 }
637
638 // We were successful in retrieving user preferences for the "path".
639 view_p->flags.preferences = view_preferences_p->preferences;
640 view_p->flags.sortcolumn = view_preferences_p->sortcolumn;
641 rfm_layout_set_icon_size(view_p, view_preferences_p->icon_size);
642 if (view_p->en) {
643 if(view_p->flags.preferences & __SHOW_HIDDEN){
644 NOOP( "rfm_set_view_preferences: shows hidden...\n");
645 SET_SHOWS_HIDDEN (view_p->en->type);
646 } else {
647 NOOP( "rfm_set_view_preferences: does *not* show hidden...\n");
648 UNSET_SHOWS_HIDDEN (view_p->en->type);
649 }
650 if(view_p->flags.preferences & __SHOW_IMAGES){
651 SET_SHOWS_IMAGES (view_p->en->type);
652 } else {
653 UNSET_SHOWS_IMAGES (view_p->en->type);
654 }
655 SET_USER_PREFERENCES(view_p->flags.preferences);
656 }
657
658 return;
659 }
660
661 static void *
get_pango_layout_height(void * data)662 get_pango_layout_height(void *data)
663 {
664 if (rfm_get_gtk_thread() != g_thread_self()){
665 DBG("get_pango_layout_height is a main thread function main=0x%x self=0x%x\n",GPOINTER_TO_INT(rfm_get_gtk_thread()), GPOINTER_TO_INT(g_thread_self()));
666 }
667 view_t *view_p = data;
668 if (!view_p->widgets.paper) g_error("view_p->widgets.paper is NULL\n");
669 PangoLayout *layout;
670 PangoRectangle logical_rect;
671 const gchar *tag = "RIDE A BIKE TODAY";
672 layout = gtk_widget_create_pango_layout (view_p->widgets.paper, tag);
673 layout_set_variable_font(layout);
674 pango_layout_get_pixel_extents (layout, NULL, &(logical_rect));
675 gint height = logical_rect.height;
676 g_object_unref (layout);
677 return GINT_TO_POINTER(height);
678 }
679
680 static void *
set_paper_size(gpointer data)681 set_paper_size(gpointer data){
682 if (rfm_get_gtk_thread() != g_thread_self()){
683 g_error("set_paper_size is a main thread function\n");
684 }
685 view_t *view_p = data;
686 view_layout_t *view_layout_p = &(view_p->view_layout);
687 NOOP(stderr, "******** set_paper_size: %d, %d\n",
688 view_layout_p->paperX, view_layout_p->paperY);
689 gtk_widget_set_size_request (view_p->widgets.paper, view_layout_p->paperX, view_layout_p->paperY);
690 g_object_set_data(G_OBJECT(view_p->widgets.paper), "paperX",
691 GINT_TO_POINTER(view_layout_p->paperX));
692 g_object_set_data(G_OBJECT(view_p->widgets.paper), "paperY",
693 GINT_TO_POINTER(view_layout_p->paperY));
694 return NULL;
695 }
696
697
698 static void *
context_sync(gpointer data)699 context_sync(gpointer data){
700 if (rfm_get_gtk_thread() != g_thread_self()){
701 g_error("context_sync is a main thread function\n");
702 }
703 gdk_display_sync (gdk_display_get_default ());
704 while (gtk_events_pending()) gtk_main_iteration();
705 if (data) return data;
706 return NULL;
707 }
708
709
710 static void *
do_layout_f(void * data)711 do_layout_f(void *data){
712 void **arg = data;
713 view_t *view_p = arg[0];
714 population_t *population_p = arg[1];
715 if (population_p->layout == NULL) rfm_do_layout (view_p, population_p);
716 return NULL;
717 }
718
719 //
720 void
rfm_layout_pango_layout_setup(view_t * view_p)721 rfm_layout_pango_layout_setup(view_t *view_p){
722 view_layout_t *view_layout_p = &(view_p->view_layout);
723 if (view_layout_p->icon_size > TINY_ICON_SIZE) return;
724
725 // Get longest label:
726
727 population_t **pp = view_p->population_pp;
728 gint max_length = 0;
729 population_t *population_p = NULL;
730 for (; pp && *pp; pp++){
731 gchar *label = g_strdup((*pp)->label);
732 if (label && strlen(label)>max_length) {
733 max_length = strlen(label);
734 population_p = *pp;
735 }
736 g_free(label);
737 }
738 if (population_p) {
739 void *arg[]={view_p, population_p};
740 rfm_context_function(do_layout_f, arg);
741 view_layout_p->name_width = population_p->logical_rect.width;
742 GdkRectangle rect;
743 rfm_layout_get_vpane_allocation(view_p, &rect);
744 view_layout_p->details_width = rect.width - view_layout_p->name_width;
745 }
746
747 NOOP(stderr, "+++ rfm_layout_details_setup : name width=%d, detail width=%d\n",
748 view_layout_p->name_width,view_layout_p->details_width);
749 }
750
751
752 void
rfm_layout_get_vpane_allocation(view_t * view_p,GdkRectangle * rect)753 rfm_layout_get_vpane_allocation(view_t *view_p, GdkRectangle *rect){
754 if (!view_p){
755 memset(rect, 0, sizeof(GdkRectangle));
756 DBG("rfm_layout_get_vpane_allocation(): view_p cannot be null.\n");
757 return;
758 }
759 view_layout_t *view_layout_p = &(view_p->view_layout);
760 if (view_p->flags.type == DESKVIEW_TYPE){
761 rect->x = rect->y = 0;
762 rect->width = view_layout_p->window_width;
763 rect->height = view_layout_p->window_height;
764 return;
765 }
766 if (!(view_layout_p->tripwire & LAYOUT_VPANE_ALLOCATION)){
767 g_error("rfm_layout_get_vpane_allocation: LAYOUT_VPANE_ALLOCATION is not set\n");
768 }
769 if (!view_p || !rect) g_error("!view_p || !rect\n");
770 memcpy(rect, &(view_layout_p->vpane_allocation), sizeof(GdkRectangle));
771 return;
772 }
773 void
rfm_layout_set_vpane_allocation(view_t * view_p)774 rfm_layout_set_vpane_allocation(view_t *view_p){
775 if (rfm_get_gtk_thread() != g_thread_self())
776 g_error("rfm_layout_set_vpane_allocation is a main thread function\n");
777 view_layout_t *view_layout_p = &(view_p->view_layout);
778 if (view_p->flags.type == DESKVIEW_TYPE) {
779 view_layout_p->vpane_allocation.width = view_layout_p->window_width;
780 view_layout_p->vpane_allocation.height = view_layout_p->window_height;
781 return;
782 }
783 GtkWidget *vpane = g_object_get_data(G_OBJECT(view_p->widgets.paper), "vpane");
784 if (!vpane){
785 // deskview should not have entered this function.
786 g_error("rfm_layout_set_vpane_allocation: vpane==NULL\n");
787 }
788 gtk_widget_get_allocation (vpane, &(view_layout_p->vpane_allocation));
789 view_layout_p->tripwire |= LAYOUT_VPANE_ALLOCATION;
790 }
791
792 // This function sets the iconsize scale in gridview windows to the
793 // size saved for the particular directory in the view.
794 void *
rfm_layout_set_icon_size_scale(void * data)795 rfm_layout_set_icon_size_scale(void * data){
796 view_t *view_p = data;
797 GtkWidget *size_scale = g_object_get_data(G_OBJECT(view_p->widgets.paper), "size_scale");
798 if (size_scale == NULL){
799 return NULL;
800 }
801 gtk_range_set_value (GTK_RANGE(size_scale), view_p->view_layout.icon_size);
802 g_object_set_data(G_OBJECT(size_scale), "oldvalue", GINT_TO_POINTER(view_p->view_layout.icon_size));
803
804 gint sizeid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(size_scale), "sizeid"));
805 if (!sizeid)
806 g_object_set_data(G_OBJECT(size_scale), "sizeid", GINT_TO_POINTER(1+ICON_SIZE_ID(view_p)));
807 else if (sizeid-1 != ICON_SIZE_ID(view_p)) {
808 gchar *t=NULL;
809 switch (ICON_SIZE_ID(view_p)){
810 case BIG_ICON_SIZE: t = g_strdup_printf(_("Huge (%sx%s)"), "96", "96"); break;
811 case MEDIUM_ICON_SIZE: t = g_strdup_printf(_("Large (%sx%s)"), "72", "72"); break;
812 case SMALL_ICON_SIZE: t = g_strdup_printf(_("Medium (%sx%s)"), "48", "48"); break;
813 case TINY_ICON_SIZE: t = g_strdup_printf(_("Small (%sx%s)"), "24", "24"); break;
814 case LIST_ICON_SIZE: t = g_strdup(_("List View")); break;
815 }
816 rfm_diagnostics(&(view_p->widgets), "rodent",_("Icon size:")," ", t, "\n", NULL);
817 g_free(t);
818 g_object_set_data(G_OBJECT(size_scale), "sizeid", GINT_TO_POINTER(1+ICON_SIZE_ID(view_p)));
819 }
820
821 return NULL;
822 }
823
824
825 void
rfm_layout_set_icon_size(view_t * view_p,gint size)826 rfm_layout_set_icon_size(view_t *view_p, gint size){
827 NOOP(stderr, "--- icon size set to %d\n", size);
828 switch (size){
829 case BIG_ICON_SIZE:
830 case MEDIUM_ICON_SIZE:
831 case SMALL_ICON_SIZE:
832 case TINY_ICON_SIZE:
833 case LIST_ICON_SIZE:
834 break;
835 default:
836 g_error("rfm_layout_set_icon_size: incorrect size (%d)\n", size);
837 }
838 view_layout_t *view_layout_p = &(view_p->view_layout);
839 view_layout_p->tripwire |= LAYOUT_ICON_SIZE;
840 view_layout_p->icon_size = size;
841
842 }
843
844 void
rfm_layout_set_icon_size_full(view_t * view_p,gint size)845 rfm_layout_set_icon_size_full(view_t *view_p, gint size){
846 if (!view_p) g_error("rfm_layout_set_icon_size_full: !view_p\n");
847 view_layout_t *view_layout_p = &(view_p->view_layout);
848 if (!view_layout_p->max_elements) g_error("rfm_layout_set_icon_size_full: !view_layout_p->max_elements\n");
849
850 rfm_layout_set_icon_size(view_p, size);
851 // this should be set already... rfm_layout_set_vpane_allocation(view_p);
852 rfm_layout_configure(view_p, view_layout_p->max_elements);
853 }
854
855 static void
layout_reset_columns(view_t * view_p)856 layout_reset_columns(view_t *view_p){
857 view_layout_t *view_layout_p = &(view_p->view_layout);
858
859 // Set the column width (required for cellwidth)
860 if (view_layout_p->icon_size >= SMALL_ICON_SIZE) {
861 view_layout_p->column_width = view_layout_p->icon_size * 2;
862 } else if (view_layout_p->icon_size >= TINY_ICON_SIZE) {
863 view_layout_p->column_width = SMALL_ICON_SIZE * 4;
864 } else {
865 if (view_p->flags.type == DESKVIEW_TYPE) {
866 view_layout_p->column_width = rfm_allocation.width -
867 view_layout_p->margin_right - view_layout_p->margin_left;
868 } else {
869 view_layout_p->column_width = view_layout_p->vpane_allocation.width;
870 }
871 }
872 // Set the text_height (required for cellheight)
873 if (rfm_get_gtk_thread() == g_thread_self()){
874 view_layout_p->text_height = GPOINTER_TO_INT(get_pango_layout_height(view_p));
875 } else {
876 view_layout_p->text_height = GPOINTER_TO_INT(rfm_context_function(get_pango_layout_height, view_p));
877 }
878
879 // Now set cellwidth and cell height
880
881 view_layout_p->cellwidth = view_layout_p->column_width;
882 if (view_layout_p->icon_size >= SMALL_ICON_SIZE){
883 view_layout_p->cellheight = view_layout_p->icon_size + (2*(view_layout_p->text_height + TEXTSPACING));
884 } else {
885 // icon_size may be zero for details, so use the hardcode value, TINY_ICON_SIZE.
886 view_layout_p->cellheight = TINY_ICON_SIZE + TEXTSPACING;
887 }
888 view_layout_p->tripwire |= (LAYOUT_CELLWIDTH|LAYOUT_CELLHEIGHT);
889
890 // Width is equal to window width, minus margin.
891 // Margin is (CELLWIDTH(view_p) / 2.
892 gint width = rfm_allocation.width - (view_layout_p->cellwidth / 2);
893
894 // Now get number of grid rows and columns to fit view_layout_p->max_elements.
895 GtkWidget *vpane = g_object_get_data(G_OBJECT(view_p->widgets.paper), "vpane");
896 if (vpane == NULL) { // transposed...
897 gint height = rfm_allocation.height -
898 view_layout_p->margin_bottom - view_layout_p->margin_top;
899 width = rfm_allocation.width -
900 view_layout_p->margin_right - view_layout_p->margin_left;
901
902
903 view_layout_p->grid_rows = ((double)height / view_layout_p->cellheight) + 0.5;
904 view_layout_p->grid_columns = ((double)width / view_layout_p->cellwidth) + 0.5;
905 if (view_layout_p->grid_rows * view_layout_p->grid_columns < view_layout_p->max_elements) {
906 view_layout_p->max_elements = view_layout_p->grid_rows * view_layout_p->grid_columns;
907 }
908 } else {// (iconview)
909
910
911 view_layout_p->grid_columns = ((double)width / view_layout_p->cellwidth) + 0.5;
912 view_layout_p->grid_rows = (view_layout_p->max_elements) / view_layout_p->grid_columns;
913 if(view_layout_p->max_elements % view_layout_p->grid_columns)
914 view_layout_p->grid_rows++;
915
916 // Correct for number of rows in case the paper must also fill empty space.
917
918 gint items=(view_layout_p->cellwidth==0 || view_layout_p->cellheight==0)?-1:
919 view_layout_p->vpane_allocation.width *
920 view_layout_p->vpane_allocation.height /
921 view_layout_p->cellwidth/ view_layout_p->cellheight;
922 NOOP(stderr, "init_grid (%d):items=%d pane allocation:w=%d h=%d \n",
923 view_layout_p->max_elements, items,
924 view_layout_p->vpane_allocation.width,
925 view_layout_p->vpane_allocation.height);
926 gint total_rows = items;
927
928 if (view_layout_p->grid_columns > 0) {
929 gint rows = total_rows / view_layout_p->grid_columns;
930 if (total_rows % view_layout_p->grid_columns != 0){
931 // remainder...
932 rows++;
933 }
934 total_rows = rows;
935 } else total_rows = -1;
936 if (view_layout_p->max_elements <= items - view_layout_p->grid_columns) {
937 // hacky correction for when population does not fill paper completely
938 total_rows = -1;
939 }
940
941 if (total_rows > 0 && total_rows > view_layout_p->grid_rows) {
942 view_layout_p->grid_rows = total_rows;
943 NOOP( "changing rows to %d (items = %d)\n", total_rows, items);
944 }
945 }
946 NOOP (stderr, "layout_reset_columns: rfm_allocation.width=%d rfm_allocation.height=%d\n",rfm_allocation.width,rfm_allocation.height);
947 NOOP (stderr, "layout_reset_columns: view_layout_p->max_elements=%d cellwidth=%d cellheight=%d\n",
948 view_layout_p->max_elements, view_layout_p->cellwidth, view_layout_p->cellheight);
949 NOOP (stderr, "layout_reset_columns: columns=%d rows=%d\n",
950 view_layout_p->grid_columns, view_layout_p->grid_rows);
951 view_layout_p->grid_area = view_layout_p->grid_rows * view_layout_p->grid_columns;
952 }
953
954 static void
layout_configure(view_t * view_p,gint pathc)955 layout_configure(view_t *view_p, gint pathc){
956 if (!view_p) g_error("layout_configure: !view_p\n");
957 rfm_global_t *rfm_global_p = rfm_global();
958 if(!rfm_global_p) g_error ("layout_configure: rfm_global_p==NULL\n");
959 if(!rfm_global_p->window) g_error ("layout_configure: rfm_global_p->window==NULL\n");
960
961 if (pathc == 0){
962 DBG("init_grid: pathc==0, skipping...\n");
963 return;
964 }
965 if(!rfm_global_p->window) g_error ("layout_configure: rfm_global_p->window==NULL\n");
966 view_layout_t *view_layout_p = &(view_p->view_layout);
967
968 if (!(view_layout_p->tripwire & LAYOUT_ICON_SIZE))
969 g_error("view_layout_p item LAYOUT_ICON_SIZE is not set\n");
970 GtkWidget *vpane = g_object_get_data(G_OBJECT(view_p->widgets.paper), "vpane");
971 if (vpane && !(view_layout_p->tripwire & LAYOUT_VPANE_ALLOCATION))
972 g_error("view_layout_p item LAYOUT_VPANE_ALLOCATION is not set\n");
973
974 NOOP(stderr, "layout_configure(): pathc=%d\n", pathc);
975 view_layout_p->max_elements = pathc;
976 layout_reset_columns(view_p);
977
978 if (view_layout_p->icon_size < TINY_ICON_SIZE){
979 view_layout_p->paperX = 192; // hack : 192 is maximum cellwidth
980 //view_layout_p->name_width + view_layout_p->details_width;
981 } else
982 {
983 view_layout_p->paperX = view_layout_p->cellwidth;
984 }
985
986 view_layout_p->paperY = view_layout_p->grid_rows * view_layout_p->cellheight;
987 view_layout_p->tripwire |= LAYOUT_ROOT_CONFIGURED;
988 rfm_layout_set_window_size(view_p, rfm_allocation.width, rfm_allocation.height);
989
990 return;
991 }
992
rfm_layout_set_window_size(view_t * view_p,gint width,gint height)993 gboolean rfm_layout_set_window_size(view_t *view_p, gint width, gint height){
994 if (!view_p) g_error("rfm_layout_set_window_size: !view_p\n");
995 view_layout_t *view_layout_p = &(view_p->view_layout);
996 if (width == view_layout_p->window_width && height == view_layout_p->window_height){
997 return FALSE;
998 }
999 view_layout_p->window_width = width;
1000 view_layout_p->window_height = height;
1001 return TRUE;
1002 }
1003
1004 void
rfm_layout_configure(view_t * view_p,gint pathc)1005 rfm_layout_configure(view_t *view_p, gint pathc){
1006 NOOP(stderr, "+++rfm_layout_configure\n");
1007 // (configure view layout)
1008 layout_configure(view_p, pathc);
1009
1010 // check paper size
1011 view_layout_t *view_layout_p = &(view_p->view_layout);
1012 #if 10
1013 gboolean setup_not_ok =
1014 !view_layout_p->paperX || !view_layout_p->paperY ||
1015 view_layout_p->paperX !=
1016 GPOINTER_TO_INT(g_object_get_data(G_OBJECT(view_p->widgets.paper), "paperX"))
1017 ||
1018 view_layout_p->paperY !=
1019 GPOINTER_TO_INT(g_object_get_data(G_OBJECT(view_p->widgets.paper), "paperY"));
1020 #else
1021 // This does not work (at present).
1022 // Does not present too much advantages either, memorywise.
1023 gboolean setup_not_ok =
1024 !view_layout_p->paperX || !view_layout_p->paperY ||
1025 view_layout_p->paperX <
1026 GPOINTER_TO_INT(g_object_get_data(G_OBJECT(view_p->widgets.paper), "paperX"))
1027 ||
1028 view_layout_p->paperY <
1029 GPOINTER_TO_INT(g_object_get_data(G_OBJECT(view_p->widgets.paper), "paperY"));
1030
1031 #endif
1032
1033 if (setup_not_ok){
1034
1035 //static gint c=1;NOOP(stderr, "rfm_layout_configure(): reset paper size (%d)...\n)",c);
1036
1037 // set paper size
1038 g_object_set_data(G_OBJECT(view_p->widgets.paper), "paper_setup", NULL);
1039 rfm_context_function(set_paper_size, view_p);
1040 rfm_context_function(context_sync, NULL);
1041
1042
1043 // now that we have sync'd, activate reload on size changes.
1044 g_object_set_data(G_OBJECT(view_p->widgets.paper), "paper_setup", GINT_TO_POINTER(1));
1045 GtkWidget *size_scale = g_object_get_data(G_OBJECT(view_p->widgets.paper), "size_scale");
1046 if (size_scale != NULL){
1047 // Disable reload by scale change signal,
1048 g_object_set_data(G_OBJECT(view_p->widgets.paper), "size_scale_disabled", GINT_TO_POINTER(1));
1049 rfm_context_function(rfm_layout_set_icon_size_scale, view_p);
1050 // sync
1051 rfm_context_function(context_sync, NULL);
1052 // and now reactivate reload by scale change signal.
1053 g_object_set_data(G_OBJECT(view_p->widgets.paper), "size_scale_disabled", NULL);
1054 }
1055 }
1056 }
1057
1058
1059 ////////////////////////////////////////////////////////////////////////////////////////////
1060
1061 gboolean
rfm_get_population_rect(view_t * view_p,const population_t * population_p,GdkRectangle * rect)1062 rfm_get_population_rect(view_t * view_p, const population_t * population_p, GdkRectangle *rect){
1063 view_layout_t *view_layout_p = &(view_p->view_layout);
1064 if (!(view_layout_p->tripwire & LAYOUT_CELLWIDTH))
1065 g_error("view_layout_p item LAYOUT_CELLWIDTH is not set\n");
1066 if (!(view_layout_p->tripwire & LAYOUT_CELLHEIGHT))
1067 g_error("view_layout_p item LAYOUT_CELLHEIGHT is not set\n");
1068
1069 if (!population_p || !rect) {
1070 DBG("rfm_get_population_rect() called with !population_p || !rect\n");
1071 return FALSE;
1072 }
1073 if (!rfm_population_try_read_lock(view_p, "rfm_get_population_rect")) return FALSE;
1074 gint cellwidth = view_layout_p->cellwidth;
1075 gint cellheight = view_layout_p->cellheight;
1076 rect->x = population_p->column * cellwidth + MARGIN_LEFT(view_p);
1077 rect->y = population_p->row * cellheight + MARGIN_TOP(view_p);
1078 rect->width = cellwidth;
1079 rect->height = cellheight;
1080
1081 rfm_population_read_unlock(view_p, "rfm_get_population_rect");
1082 return TRUE;
1083 }
1084
1085 gboolean
rfm_get_population_icon_rect(view_t * view_p,const population_t * population_p,GdkRectangle * rect)1086 rfm_get_population_icon_rect(view_t * view_p, const population_t * population_p, GdkRectangle *rect){
1087 view_layout_t *view_layout_p = &(view_p->view_layout);
1088 if (!(view_layout_p->tripwire & LAYOUT_CELLWIDTH))
1089 g_error("view_layout_p item LAYOUT_CELLWIDTH is not set\n");
1090 if (!(view_layout_p->tripwire & LAYOUT_CELLHEIGHT))
1091 g_error("view_layout_p item LAYOUT_CELLHEIGHT is not set\n");
1092 gint cellwidth = view_layout_p->cellwidth;
1093 gint cellheight = view_layout_p->cellheight;
1094 if (!rfm_population_try_read_lock(view_p, "rfm_get_population_icon_rect")) {
1095 DBG("rfm_get_population_icon_rect(): failed to get read lock\n");
1096 return FALSE;
1097 }
1098 rect->x = population_p->column * cellwidth + MARGIN_LEFT(view_p);
1099 rect->y = population_p->row * cellheight + MARGIN_TOP(view_p);
1100
1101
1102 gint icon_size = view_layout_p->icon_size;
1103 if (!icon_size) icon_size = TINY_ICON_SIZE;
1104 rect->width = icon_size;
1105 rect->height = icon_size;
1106
1107 rfm_population_read_unlock(view_p, "rfm_get_population_icon_rect");
1108 return TRUE;
1109 }
1110
1111 gboolean
rfm_get_population_label_rect(view_t * view_p,const population_t * population_p,GdkRectangle * rect)1112 rfm_get_population_label_rect(view_t * view_p, const population_t * population_p, GdkRectangle *rect){
1113 view_layout_t *view_layout_p = &(view_p->view_layout);
1114 if (!(view_layout_p->tripwire & LAYOUT_CELLWIDTH))
1115 g_error("view_layout_p item LAYOUT_CELLWIDTH is not set\n");
1116 if (!(view_layout_p->tripwire & LAYOUT_CELLHEIGHT))
1117 g_error("view_layout_p item LAYOUT_CELLHEIGHT is not set\n");
1118 gint cellwidth = view_layout_p->cellwidth;
1119 gint cellheight = view_layout_p->cellheight;
1120 if (!rfm_population_try_read_lock(view_p, "rfm_get_population_label_rect")) {
1121 DBG("rfm_get_population_label_rect(): failed to get read lock\n");
1122 return FALSE;
1123 }
1124 rect->x = population_p->column * cellwidth + MARGIN_LEFT(view_p);
1125 rect->y = population_p->row * cellheight + MARGIN_TOP(view_p);
1126
1127 rect->height=0;
1128 rect->width=0;
1129 if(population_p->layout) {
1130 rect->height = population_p->logical_rect.height;
1131 rect->width = population_p->logical_rect.width;
1132 }
1133 gint x_offset = (view_layout_p->icon_size >= SMALL_ICON_SIZE)?
1134 (cellwidth - population_p->logical_rect.width) / 2:
1135 TINY_ICON_SIZE + 2;
1136 // Details icon_size (0) does not have a layout2.
1137 if (view_layout_p->icon_size && population_p->layout2) {
1138 rect->height += population_p->logical_rect2.height;
1139 if (population_p->logical_rect2.width > population_p->logical_rect.width){
1140 rect->width = population_p->logical_rect2.width;
1141 }
1142 gint x_offset2 = (view_layout_p->icon_size >= SMALL_ICON_SIZE)?
1143 (cellwidth - population_p->logical_rect2.width) / 2:
1144 TINY_ICON_SIZE + 2;
1145
1146 if (x_offset2 < x_offset) {
1147 x_offset = x_offset2;
1148 }
1149 }
1150
1151 if (rect->x + x_offset<0) x_offset=0;
1152 else rect->x += x_offset;
1153 if (view_layout_p->icon_size >= SMALL_ICON_SIZE) {
1154 rect->y += (TEXTSPACING + ICON_SIZE(view_p));
1155 } else {
1156 rect->y += TEXTSPACING;
1157 }
1158
1159 rfm_population_read_unlock(view_p, "rfm_get_population_label_rect");
1160
1161 // test code
1162 //if (population_p->flags & LABEL_SATURATED){
1163 //rect->x -= rect->width; if (rect->x < 0) rect->x = 0;
1164 //rect->width *= 2; rect->width +=2;
1165 //}
1166
1167 return TRUE;
1168 }
1169
1170 gboolean
rfm_get_population_label_rect_full(view_t * view_p,const population_t * population_p,GdkRectangle * rect)1171 rfm_get_population_label_rect_full(view_t * view_p, const population_t * population_p, GdkRectangle *rect){
1172 if (!view_p || ! population_p) {
1173 g_error("incorrect function call: layout_full_dimensions()");
1174 }
1175 if (!rfm_population_try_read_lock(view_p, "rfm_get_population_label_rect_full")) {
1176 DBG("rfm_get_population_label_rect(): failed to get read lock\n");
1177 return FALSE;
1178 }
1179
1180 GdkRectangle item_rect;
1181 GdkRectangle label_rect;
1182 if (!rfm_get_population_label_rect(view_p, population_p, &label_rect)) {
1183 DBG("rfm_get_population_label_rect_full: !rfm_get_population_label_rect\n");
1184 return FALSE;
1185 }
1186 if (!rfm_get_population_rect(view_p, population_p, &item_rect)) {
1187 DBG("rfm_get_population_label_rect_full: !rfm_get_population_rect\n");
1188 return FALSE;
1189 }
1190 view_layout_t *view_layout_p = &(view_p->view_layout);
1191
1192 rect->width = population_p->logical_rect_full.width;
1193 rect->height = population_p->logical_rect_full.height;
1194 rect->y = label_rect.y;
1195
1196 // with texts under the icons, center the saturated text.
1197 if (view_layout_p->icon_size >= SMALL_ICON_SIZE) {
1198 gint center = item_rect.x + (item_rect.width/2);
1199 rect->x = center - (rect->width/2);
1200 // bigger bg square for non details...
1201 rect->width += 4;
1202 rect->height += 4;
1203 rect->y += 2;
1204
1205 } else {
1206 // texts to the right of the icon, use label.x
1207 rect->x = label_rect.x;
1208 }
1209
1210 // correct for overlap
1211 gint scrollbar_width = 25;
1212 gint area_width;
1213 GtkWidget *vpane = g_object_get_data(G_OBJECT(view_p->widgets.paper), "vpane");
1214 if (vpane) {
1215 area_width = view_layout_p->vpane_allocation.width;
1216 } else {
1217 area_width = rfm_allocation.width;
1218 }
1219
1220 NOOP(stderr, "overlap: x=%d, w=%d (%d), aw=%d nx=%d\n",rect->x,rect->width,rect->x+rect->width,area_width,area_width - rect->width);
1221
1222 if (rect->x + rect->width + scrollbar_width >= area_width) {
1223 rect->x = area_width - rect->width - scrollbar_width;
1224 }
1225 // correct for underlap
1226 if (rect->x < MARGIN_LEFT(view_p)) rect->x = MARGIN_LEFT(view_p);
1227 rfm_population_read_unlock(view_p, "rfm_get_population_label_rect_full");
1228 return TRUE;
1229 }
1230 ////////////////////////////////////////////////////////////////////////////////////////////
1231
1232