~ubuntu-branches/debian/sid/bijiben/sid

« back to all changes in this revision

Viewing changes to src/bjb-main-view.c

  • Committer: Package Import Robot
  • Author(s): Vincent Cheng
  • Date: 2013-03-26 21:19:36 UTC
  • Revision ID: package-import@ubuntu.com-20130326211936-tu8mpy82juohw8m2
Tags: upstream-3.8.0
ImportĀ upstreamĀ versionĀ 3.8.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* bjb-main-view.c
 
2
 * Copyright (C) Pierre-Yves LUYTEN 2012 <py@luyten.fr>
 
3
 * 
 
4
 * bijiben is free software: you can redistribute it and/or modify it
 
5
 * under the terms of the GNU General Public License as published by the
 
6
 * Free Software Foundation, either version 3 of the License, or
 
7
 * (at your option) any later version.
 
8
 * 
 
9
 * bijiben is distributed in the hope that it will be useful, but
 
10
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
12
 * See the GNU General Public License for more details.
 
13
 * 
 
14
 * You should have received a copy of the GNU General Public License along
 
15
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 
16
 */
 
17
 
 
18
#include <glib/gprintf.h>
 
19
#include <gtk/gtk.h>
 
20
#include <libbiji/libbiji.h>
 
21
#include <libgd/gd-main-view.h>
 
22
 
 
23
#include "utils/bjb-icons-colors.h"
 
24
 
 
25
#include "bjb-app-menu.h"
 
26
#include "bjb-bijiben.h"
 
27
#include "bjb-controller.h"
 
28
#include "bjb-main-toolbar.h"
 
29
#include "bjb-main-view.h"
 
30
#include "bjb-note-tag-dialog.h"
 
31
#include "bjb-note-view.h"
 
32
#include "bjb-rename-note.h"
 
33
#include "bjb-search-toolbar.h"
 
34
#include "bjb-selection-toolbar.h"
 
35
#include "bjb-window-base.h"
 
36
 
 
37
#define DEFAULT_VIEW GD_MAIN_VIEW_ICON
 
38
 
 
39
enum
 
40
{
 
41
  PROP_0,
 
42
  PROP_WINDOW,
 
43
  PROP_BJB_CONTROLLER,
 
44
  NUM_PROPERTIES
 
45
};
 
46
 
 
47
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
 
48
 
 
49
/************************** Gobject ***************************/
 
50
 
 
51
struct _BjbMainViewPriv {  
 
52
  GtkWidget        *window;
 
53
  GtkWidget        *label;
 
54
 
 
55
  /* Toolbar */
 
56
  BjbMainToolbar   *main_toolbar;
 
57
 
 
58
  /* Selection Mode */
 
59
  BjbSelectionToolbar  *select_bar;
 
60
 
 
61
  /* Search Entry  */
 
62
  BjbSearchToolbar *search_bar;
 
63
 
 
64
  /* View Notes , model */
 
65
  GdMainView       *view ; 
 
66
  BjbController    *controller ;
 
67
 
 
68
  /* Signals */
 
69
  gulong key;
 
70
  gulong button;
 
71
  gulong activated;
 
72
  gulong data;
 
73
};
 
74
 
 
75
G_DEFINE_TYPE (BjbMainView, bjb_main_view, GTK_TYPE_BOX);
 
76
 
 
77
static void
 
78
bjb_main_view_init (BjbMainView *object)
 
79
{
 
80
  object->priv = 
 
81
  G_TYPE_INSTANCE_GET_PRIVATE(object,BJB_TYPE_MAIN_VIEW,BjbMainViewPriv);
 
82
}
 
83
 
 
84
static void
 
85
bjb_main_view_finalize (GObject *object)
 
86
{
 
87
  G_OBJECT_CLASS (bjb_main_view_parent_class)->finalize (object);
 
88
}
 
89
 
 
90
static void
 
91
bjb_main_view_disconnect_handlers (BjbMainView *self)
 
92
{
 
93
  BjbMainViewPriv *priv = self->priv;
 
94
 
 
95
  g_signal_handler_disconnect (priv->window, priv->key);
 
96
  g_signal_handler_disconnect (priv->view, priv->button);
 
97
  g_signal_handler_disconnect (priv->view, priv->activated);
 
98
  g_signal_handler_disconnect (priv->view, priv->data);
 
99
}
 
100
 
 
101
static void
 
102
bjb_main_view_set_controller ( BjbMainView *self, BjbController *controller)
 
103
{
 
104
  self->priv->controller = controller ;
 
105
}
 
106
 
 
107
static void
 
108
bjb_main_view_get_property ( GObject      *object,
 
109
                             guint        prop_id,
 
110
                             GValue       *value,
 
111
                             GParamSpec   *pspec)
 
112
{
 
113
  BjbMainView *self = BJB_MAIN_VIEW (object);
 
114
 
 
115
  switch (prop_id)
 
116
  {
 
117
    case PROP_WINDOW:
 
118
      g_value_set_object (value, self->priv->window);
 
119
      break;
 
120
    case PROP_BJB_CONTROLLER:
 
121
      g_value_set_object (value, self->priv->controller);
 
122
      break;
 
123
    default:
 
124
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
125
      break;
 
126
  }
 
127
}
 
128
 
 
129
static void
 
130
bjb_main_view_set_property ( GObject        *object,
 
131
                             guint          prop_id,
 
132
                             const GValue   *value,
 
133
                             GParamSpec     *pspec)
 
134
{
 
135
  BjbMainView *self = BJB_MAIN_VIEW (object);
 
136
 
 
137
  switch (prop_id)
 
138
  {
 
139
    case PROP_WINDOW:
 
140
      self->priv->window = g_value_get_object(value);
 
141
      break;
 
142
    case PROP_BJB_CONTROLLER:
 
143
      bjb_main_view_set_controller(self,g_value_get_object(value));
 
144
      break;
 
145
    default:
 
146
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
147
      break;
 
148
  }
 
149
}
 
150
 
 
151
static GObject *
 
152
biji_main_view_constructor (GType                  gtype,
 
153
                            guint                  n_properties,
 
154
                            GObjectConstructParam  *properties)
 
155
{
 
156
  GObject *obj;
 
157
  {
 
158
    obj = G_OBJECT_CLASS (bjb_main_view_parent_class)->constructor (gtype, n_properties, properties);
 
159
  }
 
160
  return obj;
 
161
}
 
162
 
 
163
/* Callbacks */
 
164
 
 
165
void
 
166
switch_to_note_view (BjbMainView *self, BijiNoteObj *note)
 
167
{
 
168
  bjb_search_toolbar_disconnect (self->priv->search_bar);
 
169
  bjb_main_view_disconnect_handlers (self);
 
170
  bjb_window_base_switch_to_note (BJB_WINDOW_BASE (self->priv->window), note);
 
171
}
 
172
 
 
173
static void
 
174
show_window_if_note (gpointer data, gpointer user_data)
 
175
{
 
176
  BjbWindowBase *window = data;
 
177
  BijiNoteObj *to_open = user_data;
 
178
  BijiNoteObj *cur = NULL;
 
179
 
 
180
  cur = bjb_window_base_get_note (window);
 
181
 
 
182
  if (cur && biji_note_obj_are_same (to_open, cur))
 
183
    gtk_window_present (data);
 
184
}
 
185
 
 
186
static void
 
187
switch_to_note (BjbMainView *view, BijiNoteObj *to_open)
 
188
{
 
189
  /* If the note is already opened in another window, just show it. */
 
190
  if (biji_note_obj_is_opened (to_open))
 
191
  {
 
192
    GList *notes ;
 
193
 
 
194
    notes = gtk_application_get_windows(GTK_APPLICATION(g_application_get_default()));
 
195
    g_list_foreach (notes, show_window_if_note, to_open);
 
196
    return ;
 
197
  }
 
198
 
 
199
  /* Otherwise, leave main view */
 
200
  switch_to_note_view(view,to_open);
 
201
}
 
202
 
 
203
static GList *
 
204
get_selected_paths(BjbMainView *self)
 
205
{
 
206
  return gd_main_view_get_selection ( self->priv->view ) ; 
 
207
}
 
208
 
 
209
static gchar *
 
210
get_note_url_from_tree_path(GtkTreePath *path, BjbMainView *self)
 
211
{
 
212
  GtkTreeIter iter ;
 
213
  gchar *note_path ;
 
214
  GtkTreeModel *model ;
 
215
 
 
216
  model = bjb_controller_get_model(self->priv->controller);  
 
217
  gtk_tree_model_get_iter (model,&iter, path);
 
218
  gtk_tree_model_get (model, &iter,GD_MAIN_COLUMN_URI, &note_path,-1);
 
219
 
 
220
  return note_path ;
 
221
}
 
222
 
 
223
void
 
224
action_tag_selected_notes (GtkWidget *w, BjbMainView *view)
 
225
{
 
226
  GList *notes = NULL;
 
227
  GList *paths, *l;
 
228
 
 
229
  /*  GtkTreePath */
 
230
  paths = get_selected_paths(view);
 
231
 
 
232
  for (l=paths ; l != NULL ; l=l->next)
 
233
  {
 
234
    gchar *url = get_note_url_from_tree_path (l->data, view) ;
 
235
    notes = g_list_prepend (notes, note_book_get_note_at_path
 
236
                                 (bjb_window_base_get_book(view->priv->window),url));
 
237
    g_free (url);
 
238
  }
 
239
 
 
240
  g_list_free_full (paths, (GDestroyNotify) gtk_tree_path_free);
 
241
  bjb_note_tag_dialog_new (GTK_WINDOW (view->priv->window), notes);
 
242
  g_list_free (notes);
 
243
}
 
244
 
 
245
gboolean
 
246
bjb_main_view_get_selected_notes_color (BjbMainView *view, GdkRGBA *color)
 
247
{
 
248
  GList *paths;
 
249
  gchar *url;
 
250
  BijiNoteObj *note;
 
251
 
 
252
  /*  GtkTreePath */
 
253
  paths = get_selected_paths(view);
 
254
  url = get_note_url_from_tree_path (paths->data, view) ;
 
255
  note = note_book_get_note_at_path (bjb_window_base_get_book(view->priv->window), url);
 
256
  g_free (url);
 
257
  g_list_free_full (paths, (GDestroyNotify) gtk_tree_path_free);
 
258
 
 
259
  return biji_note_obj_get_rgba (note, color);
 
260
}
 
261
 
 
262
void
 
263
action_color_selected_notes (GtkWidget *w, BjbMainView *view)
 
264
{
 
265
  GList *notes = NULL ;
 
266
  GList *paths, *l;
 
267
 
 
268
  GdkRGBA color;
 
269
  gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (w), &color);
 
270
 
 
271
  /*  GtkTreePath */
 
272
  paths = get_selected_paths(view);
 
273
 
 
274
  for (l=paths ; l != NULL ; l=l->next)
 
275
  {
 
276
    gchar *url = get_note_url_from_tree_path (l->data, view) ;
 
277
    notes = g_list_prepend (notes, note_book_get_note_at_path
 
278
                                   (bjb_window_base_get_book(view->priv->window),url));
 
279
    g_free (url);
 
280
  }
 
281
 
 
282
  g_list_free_full (paths, (GDestroyNotify) gtk_tree_path_free);
 
283
 
 
284
  for (l=notes ; l != NULL ; l=l->next)
 
285
  {
 
286
    biji_note_obj_set_rgba (BIJI_NOTE_OBJ (l->data), &color);
 
287
  }
 
288
 
 
289
  g_list_free (notes);
 
290
}
 
291
 
 
292
void
 
293
action_delete_selected_notes(GtkWidget *w,BjbMainView *view)
 
294
{
 
295
  GList *notes = NULL;
 
296
  GList *paths, *l;
 
297
 
 
298
  /*  GtkTreePath */
 
299
  paths = get_selected_paths(view);
 
300
 
 
301
  for (l=paths ; l != NULL ; l=l->next)
 
302
  {
 
303
    gchar *url = get_note_url_from_tree_path (l->data, view) ;
 
304
    notes = g_list_prepend (notes, note_book_get_note_at_path
 
305
                               (bjb_window_base_get_book(view->priv->window),url));
 
306
    g_free (url);
 
307
  }
 
308
 
 
309
  g_list_free_full (paths, (GDestroyNotify) gtk_tree_path_free);
 
310
 
 
311
  for (l=notes ; l != NULL ; l=l->next)
 
312
  {
 
313
    biji_note_book_remove_note (bjb_window_base_get_book (view->priv->window),
 
314
                                BIJI_NOTE_OBJ (l->data));
 
315
  }
 
316
 
 
317
  g_list_free (notes);
 
318
}
 
319
 
 
320
/* Select all, escape */
 
321
static gboolean
 
322
on_key_press_event_cb (GtkWidget *widget,
 
323
                       GdkEvent  *event,
 
324
                       gpointer   user_data)
 
325
{
 
326
  BjbMainView *self = BJB_MAIN_VIEW (user_data);
 
327
  BjbMainViewPriv *priv = self->priv;
 
328
 
 
329
  switch (event->key.keyval)
 
330
  {
 
331
    case GDK_KEY_a:
 
332
    case GDK_KEY_A:
 
333
      if (gd_main_view_get_selection_mode (priv->view) && event->key.state & GDK_CONTROL_MASK)
 
334
      {
 
335
        gd_main_view_select_all (priv->view);
 
336
        return TRUE;
 
337
      }
 
338
      break;
 
339
 
 
340
    case GDK_KEY_Escape:
 
341
      if (gd_main_view_get_selection_mode (priv->view))
 
342
      {
 
343
        gd_main_view_set_selection_mode (priv->view, FALSE);
 
344
        on_selection_mode_changed (priv->main_toolbar);
 
345
        return TRUE;
 
346
      }
 
347
 
 
348
    default:
 
349
      break;
 
350
  }
 
351
 
 
352
  return FALSE;
 
353
}
 
354
 
 
355
/* Go to selection mode with right-click */
 
356
static gboolean
 
357
on_button_press_event_cb (GtkWidget *widget,
 
358
                          GdkEvent  *event,
 
359
                          gpointer   user_data)
 
360
{
 
361
  BjbMainView *self = BJB_MAIN_VIEW (user_data);
 
362
  BjbMainViewPriv *priv = self->priv;
 
363
 
 
364
  switch (event->button.button)
 
365
  {
 
366
    /* Right click */
 
367
    case 3:
 
368
      if (!gd_main_view_get_selection_mode (priv->view))
 
369
      {
 
370
        gd_main_view_set_selection_mode (priv->view, TRUE);
 
371
        on_selection_mode_changed (priv->main_toolbar);
 
372
      }
 
373
 
 
374
      return TRUE;
 
375
 
 
376
    default:
 
377
      return FALSE;
 
378
  }
 
379
}
 
380
 
 
381
static gboolean
 
382
on_item_activated(GdMainView        * gd, 
 
383
                  const gchar       * id,
 
384
                  const GtkTreePath * path,
 
385
                  BjbMainView       * view)
 
386
{
 
387
  BijiNoteBook * book ;
 
388
  BijiNoteObj  * to_open ;
 
389
  GtkTreeIter    iter ;
 
390
  gchar        * note_path ;
 
391
  GtkTreeModel * model ;
 
392
 
 
393
  /* Get Note Path */
 
394
  model = gd_main_view_get_model (gd);
 
395
  gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) path);
 
396
  gtk_tree_model_get (model, &iter,COL_URI, &note_path,-1);
 
397
 
 
398
  /* Switch to that note */
 
399
  book = bjb_window_base_get_book (view->priv->window); 
 
400
  to_open = note_book_get_note_at_path (book, note_path);
 
401
  g_free (note_path);
 
402
  switch_to_note (view, to_open); 
 
403
 
 
404
  return FALSE ;
 
405
}
 
406
 
 
407
static GtkTargetEntry target_list[] = {
 
408
  { "text/plain", 0, 2}
 
409
};
 
410
 
 
411
static void
 
412
on_drag_data_received (GtkWidget        *widget,
 
413
                       GdkDragContext   *context,
 
414
                       gint              x,
 
415
                       gint              y,
 
416
                       GtkSelectionData *data,
 
417
                       guint             info,
 
418
                       guint             time,
 
419
                       gpointer          user_data)
 
420
{
 
421
  gint length = gtk_selection_data_get_length (data) ;
 
422
 
 
423
  if (length >= 0)
 
424
  {
 
425
    guchar *text = gtk_selection_data_get_text(data);
 
426
 
 
427
    if (text)
 
428
    {
 
429
      BijiNoteBook *book;
 
430
      BijiNoteObj *ret;
 
431
      BjbMainView *self = BJB_MAIN_VIEW (user_data);
 
432
 
 
433
      /* FIXME Text is guchar utf 8, conversion to perform */
 
434
      book =  bjb_window_base_get_book (self->priv->window); 
 
435
      ret = biji_note_book_new_note_with_text (book, (gchar*) text);
 
436
      switch_to_note_view (self, ret); // maybe AFTER drag finish?
 
437
 
 
438
      g_free (text);
 
439
    }
 
440
  }
 
441
 
 
442
  /* Return false to ensure text is not removed from source
 
443
   * We just want to create a note. */
 
444
  gtk_drag_finish (context, FALSE, FALSE, time);
 
445
}
 
446
 
 
447
void
 
448
bjb_main_view_connect_signals (BjbMainView *self)
 
449
{
 
450
  BjbMainViewPriv *priv = self->priv;
 
451
 
 
452
  bjb_controller_connect (priv->controller);
 
453
  bjb_search_toolbar_connect (priv->search_bar);
 
454
 
 
455
  priv->key = g_signal_connect (priv->window, "key-press-event",
 
456
                              G_CALLBACK (on_key_press_event_cb), self);
 
457
  priv->button = g_signal_connect (priv->view, "button-press-event",
 
458
                           G_CALLBACK (on_button_press_event_cb), self);
 
459
  priv->activated = g_signal_connect(priv->view,"item-activated",
 
460
                                    G_CALLBACK(on_item_activated),self);
 
461
  priv->data = g_signal_connect (priv->view, "drag-data-received",
 
462
                              G_CALLBACK (on_drag_data_received), self);
 
463
}
 
464
 
 
465
static void
 
466
bjb_main_view_constructed(GObject *o)
 
467
{
 
468
  BjbMainView          *self;
 
469
  GtkBox               *vbox; //self, too
 
470
  BjbMainViewPriv      *priv;
 
471
  GtkOverlay           *overlay;
 
472
  GdRevealer           *revealer;
 
473
 
 
474
  G_OBJECT_CLASS (bjb_main_view_parent_class)->constructed(G_OBJECT(o));
 
475
 
 
476
  self = BJB_MAIN_VIEW(o);
 
477
  priv = self->priv ;
 
478
  vbox = GTK_BOX (self);
 
479
 
 
480
  gtk_box_set_homogeneous (vbox, FALSE);
 
481
  gtk_box_set_spacing (vbox, 0);
 
482
  gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_VERTICAL);
 
483
 
 
484
  priv->view = gd_main_view_new (DEFAULT_VIEW);
 
485
  bjb_controller_set_main_view (priv->controller, priv->view);
 
486
 
 
487
  /* main Toolbar */
 
488
  priv->main_toolbar = bjb_main_toolbar_new (priv->view, self, priv->controller);
 
489
  gtk_box_pack_start (vbox, GTK_WIDGET (priv->main_toolbar), FALSE, FALSE, 0);
 
490
 
 
491
  /* Search entry toolbar */
 
492
  priv->search_bar = bjb_search_toolbar_new (priv->window, priv->controller);
 
493
  revealer = bjb_search_toolbar_get_revealer (priv->search_bar);
 
494
  gtk_box_pack_start (vbox, GTK_WIDGET (revealer), FALSE, FALSE, 0);
 
495
 
 
496
  /* Main view */
 
497
  overlay = GTK_OVERLAY (gtk_overlay_new ());
 
498
 
 
499
  gd_main_view_set_selection_mode (priv->view, FALSE);
 
500
  gd_main_view_set_model (priv->view, bjb_controller_get_model(priv->controller));
 
501
 
 
502
  gtk_container_add (GTK_CONTAINER (overlay), GTK_WIDGET (priv->view));
 
503
  gtk_box_pack_start (vbox, GTK_WIDGET (overlay), TRUE, TRUE, 0);
 
504
 
 
505
  /* Selection Panel */
 
506
  priv->select_bar = bjb_selection_toolbar_new (priv->view, self);
 
507
  gtk_overlay_add_overlay (overlay, GTK_WIDGET (priv->select_bar));
 
508
 
 
509
  /* Drag n drop */
 
510
  gtk_drag_dest_set (GTK_WIDGET (priv->view), GTK_DEST_DEFAULT_ALL,
 
511
                     target_list, 1, GDK_ACTION_COPY);
 
512
 
 
513
  bjb_main_view_connect_signals (self);
 
514
  gtk_widget_show_all (GTK_WIDGET (self));
 
515
}
 
516
 
 
517
static void
 
518
bjb_main_view_class_init (BjbMainViewClass *klass)
 
519
{
 
520
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
521
 
 
522
  object_class->finalize = bjb_main_view_finalize;
 
523
  object_class->get_property = bjb_main_view_get_property;
 
524
  object_class->set_property = bjb_main_view_set_property;
 
525
  object_class->constructor = biji_main_view_constructor;
 
526
  object_class->constructed = bjb_main_view_constructed;
 
527
    
 
528
  g_type_class_add_private (klass, sizeof (BjbMainViewPriv));
 
529
  
 
530
  properties[PROP_WINDOW] = g_param_spec_object ("window",
 
531
                                                 "Window",
 
532
                                                 "Parent Window",
 
533
                                                 GTK_TYPE_WIDGET,
 
534
                                                 G_PARAM_READWRITE |
 
535
                                                 G_PARAM_CONSTRUCT |
 
536
                                                 G_PARAM_STATIC_STRINGS);
 
537
 
 
538
  properties[PROP_BJB_CONTROLLER] = g_param_spec_object ("controller",
 
539
                                                         "Controller",
 
540
                                                         "BjbController",
 
541
                                                         BJB_TYPE_CONTROLLER,
 
542
                                                         G_PARAM_READWRITE |
 
543
                                                         G_PARAM_CONSTRUCT |
 
544
                                                         G_PARAM_STATIC_STRINGS);
 
545
 
 
546
  g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
 
547
}
 
548
 
 
549
BjbMainView *
 
550
bjb_main_view_new(GtkWidget *win,
 
551
                  BjbController *controller)
 
552
{
 
553
  return g_object_new( BJB_TYPE_MAIN_VIEW,
 
554
                       "window", win,
 
555
                       "controller", controller,
 
556
                       NULL);
 
557
}
 
558
 
 
559
GtkWidget *
 
560
bjb_main_view_get_window(BjbMainView *view)
 
561
{
 
562
  return view->priv->window ;
 
563
}
 
564
 
 
565
void
 
566
bjb_main_view_update_model (BjbMainView *self)
 
567
{
 
568
  BjbMainViewPriv *priv = self->priv;
 
569
  
 
570
  bjb_controller_set_main_view (priv->controller,priv->view);
 
571
  gd_main_view_set_model(priv->view,bjb_controller_get_model(priv->controller));
 
572
}