~ubuntu-branches/ubuntu/jaunty/ekiga/jaunty-updates

« back to all changes in this revision

Viewing changes to src/gui/callshistory.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2008-12-07 10:30:45 UTC
  • mfrom: (1.2.3 experimental)
  • Revision ID: james.westby@ubuntu.com-20081207103045-iaurrjo4p7d1nngo
Tags: 3.0.1-1ubuntu1
* Merge to Debian experimental, to get Ekiga 3. (LP: #274085) Remaining
  Ubuntu changes:
  - Launchpad Integration: (Ubuntu specific)
    + debian/control.in: Add liblaunchpad-integration-dev build dependency.
    + Add ubuntu_lpi.patch: Call launchpad_integration_add_items() in main() and
      check for the launchpad-integration pkg-config module.
    + Add autoconf.patch: autoconf changes from above patch.
  - Add ubuntu_desktop-file-onlyshowin.patch: Show ekiga in Mobile, too.
    (Ubuntu specific).
  - debian/control.in: Add missing fdupes build dependency for identical
    GNOME help file symlinking. (Debian #505536)
* Drop 42_change_pixmaps.dpatch: Many of the old icons do not exist any
  more, some have been replaced, and keeping the remaining three would make
  them look very inconsistent.
* Convert our dpatches to quilt patches and rewrite them for new upstream
  version.
* Add migrate_2.0_settings.patch: Properly migrate settings from
  2.0. Taken from upstream SVN, thanks to Damien Sandras!

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
/* Ekiga -- A VoIP and Video-Conferencing application
3
 
 * Copyright (C) 2000-2006 Damien Sandras
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software Foundation,
17
 
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
18
 
 *
19
 
 *
20
 
 * Ekiga is licensed under the GPL license and as a special exception,
21
 
 * you have permission to link or otherwise combine this program with the
22
 
 * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
23
 
 * without applying the requirements of the GNU GPL to the OPAL, OpenH323
24
 
 * and PWLIB programs, as long as you do follow the requirements of the
25
 
 * GNU GPL for all the rest of the software thus combined.
26
 
 */
27
 
 
28
 
 
29
 
/*
30
 
 *                         calls_history_window.cpp  -  description
31
 
 *                         -----------------------
32
 
 *   begin                : Sun Sep 1 2002
33
 
 *   copyright            : (C) 2000-2006 by Damien Sandras 
34
 
 *   description          : This file defines functions to manage the
35
 
 *                          calls history
36
 
 */
37
 
 
38
 
#include "../../config.h"
39
 
 
40
 
 
41
 
#include "common.h"
42
 
 
43
 
#include "addressbook.h"
44
 
#include "main.h"
45
 
#include "chat.h"
46
 
#include "callshistory.h"
47
 
#include "ekiga.h"
48
 
#include "callbacks.h" 
49
 
#include "urlhandler.h"
50
 
#include "misc.h"
51
 
 
52
 
#include "gmcontacts.h"
53
 
#include "gmmenuaddon.h"
54
 
#include "gmconf.h"
55
 
#include "gmstockicons.h"
56
 
 
57
 
 
58
 
/* internal representation */
59
 
struct _GmCallsHistoryWindow
60
 
{
61
 
  GtkWidget *chw_history_tree_view [3];
62
 
  GtkWidget *chw_search_entry;
63
 
  GtkWidget *chw_notebook;
64
 
};
65
 
typedef struct _GmCallsHistoryWindow GmCallsHistoryWindow;
66
 
 
67
 
enum {
68
 
 
69
 
  COLUMN_DATE,
70
 
  COLUMN_NAME,
71
 
  COLUMN_URL,
72
 
  COLUMN_DURATION,
73
 
  COLUMN_ENDREASON,
74
 
  COLUMN_SOFTWARE,
75
 
  NUM_COLUMNS_HISTORY
76
 
};
77
 
 
78
 
#define GM_CALLS_HISTORY_WINDOW(x) (GmCallsHistoryWindow *) (x)
79
 
 
80
 
 
81
 
/* Declarations */
82
 
 
83
 
/* GUI functions */
84
 
 
85
 
/* DESCRIPTION  : / 
86
 
 * BEHAVIOR     : Frees a GmCallsHistoryWindow and its content.
87
 
 * PRE          : A non-NULL pointer to a GmCallsHistoryWindow.
88
 
 */
89
 
static void gm_chw_destroy (gpointer data);
90
 
 
91
 
 
92
 
/* DESCRIPTION  : / 
93
 
 * BEHAVIOR     : Returns a pointer to the private GmCallsHistoryWindow
94
 
 *                used by the calls history GMObject.
95
 
 * PRE          : The given GtkWidget pointer must be a calls history GMObject.
96
 
 */
97
 
static GmCallsHistoryWindow *gm_chw_get_chw (GtkWidget *calls_history_window);
98
 
 
99
 
 
100
 
/* DESCRIPTION  : / 
101
 
 * BEHAVIOR     : Returns a pointer to a newly allocated GmContact with
102
 
 *                all the info for the contact currently being selected
103
 
 *                in the calls history window given as argument. NULL if none
104
 
 *                is selected.
105
 
 * PRE          : The given GtkWidget pointer must point to the calls history
106
 
 *                window GMObject.
107
 
 */
108
 
static GmContact *gm_chw_get_selected_contact (GtkWidget *calls_history_window);
109
 
 
110
 
 
111
 
/* DESCRIPTION  : / 
112
 
 * BEHAVIOR     : Creates a calls history item menu and returns it.
113
 
 * PRE          : The given GtkWidget pointer must point to the calls history
114
 
 *                window GMObject.
115
 
 */
116
 
static GtkWidget *gm_chw_contact_menu_new (GtkWidget *calls_history_window);
117
 
 
118
 
 
119
 
/* DESCRIPTION  : / 
120
 
 * BEHAVIOR     : Populate the calls history with the stored history.
121
 
 * PRE          : The given GtkWidget pointer must point to the calls history
122
 
 *                window GMObject.
123
 
 */
124
 
static void gm_chw_update (GtkWidget *calls_history_window);
125
 
 
126
 
 
127
 
/* DESCRIPTION  : / 
128
 
 * BEHAVIOR     : Returns the config key associated with the given call type
129
 
 *                indice.
130
 
 * PRE          : /
131
 
 */
132
 
static gchar *gm_chw_get_conf_key (int calltype);
133
 
 
134
 
 
135
 
/* DESCRIPTION  :  This function is called when the user drops the contact.
136
 
 * BEHAVIOR     :  Returns the dragged contact
137
 
 * PRE          :  Assumes data hides a calls history window (widget)
138
 
 */
139
 
static GmContact *dnd_get_contact (GtkWidget *widget, 
140
 
                                   gpointer data);
141
 
 
142
 
 
143
 
/* Callbacks */
144
 
 
145
 
/* DESCRIPTION  :  This callback is called when the user has clicked the clear
146
 
 *                 button.
147
 
 * BEHAVIOR     :  Clears the corresponding calls list using the config DB.
148
 
 * PRE          :  data = the calls history window GMObject.
149
 
 */
150
 
static void clear_button_clicked_cb (GtkButton *widget,
151
 
                                     gpointer data);
152
 
 
153
 
 
154
 
/* DESCRIPTION  :  This callback is called when the user has clicked the find
155
 
 *                 button.
156
 
 * BEHAVIOR     :  Hides the rows that do not contain the text in the search
157
 
 *                 entry.
158
 
 * PRE          :  data = the GtkNotebook containing the 3 lists of calls.
159
 
 */
160
 
static void find_button_clicked_cb (GtkButton *widget,
161
 
                                    gpointer data);
162
 
 
163
 
 
164
 
/* DESCRIPTION  : / 
165
 
 * BEHAVIOR     : This callback is called when the user clicks on a contact.
166
 
 *                Displays a popup.
167
 
 * PRE          : A valid pointer to the calls history window GMObject.
168
 
 */
169
 
static gint contact_clicked_cb (GtkWidget *widget,
170
 
                                GdkEventButton *event,
171
 
                                gpointer data);
172
 
 
173
 
 
174
 
/* DESCRIPTION  : / 
175
 
 * BEHAVIOR     : This callback is called when the user chooses to call 
176
 
 *                a contact using the menu.
177
 
 * PRE          : The calls history window as argument.  
178
 
 */
179
 
static void call_contact1_cb (GtkWidget *widget,
180
 
                              gpointer data);
181
 
 
182
 
 
183
 
/* DESCRIPTION  : / 
184
 
 * BEHAVIOR     : This callback is called when the user chooses to call 
185
 
 *                a contact by double-clicking on it.
186
 
 * PRE          : The calls history window as argument.  
187
 
 */
188
 
static void call_contact2_cb (GtkTreeView *tree_view,
189
 
                              GtkTreePath *arg1,
190
 
                              GtkTreeViewColumn *arg2,
191
 
                              gpointer data);
192
 
 
193
 
 
194
 
/* DESCRIPTION  : / 
195
 
 * BEHAVIOR     : This callback is called when the user chooses to add the
196
 
 *                contact in the address book.
197
 
 *                It presents the dialog to edit a contact. 
198
 
 * PRE          : The gpointer must point to the calls history window. 
199
 
 */
200
 
static void add_contact_cb (GtkWidget *widget,
201
 
                            gpointer data);
202
 
 
203
 
 
204
 
/* DESCRIPTION  :  This function is called to compare 1 GmContact to an URL.
205
 
 * BEHAVIOR     :  Returns 0 if both URLs are equal.
206
 
 * PRE          :  /
207
 
 */
208
 
static gint contact_compare_cb (gconstpointer contact,
209
 
                                gconstpointer url);
210
 
 
211
 
 
212
 
/* DESCRIPTION  :  This callback is called when one of the calls history         *                 config value changes.         
213
 
 * BEHAVIOR     :  Rebuild its content, regenerate the cache of urls in 
214
 
 *                 the main and chat windows.
215
 
 * PRE          :  A valid pointer to the calls history window GMObject.         
216
 
 */      
217
 
static void      
218
 
calls_history_changed_nt (gpointer id,
219
 
                          GmConfEntry *entry,
220
 
                          gpointer data);
221
 
 
222
 
 
223
 
/* Implementation */
224
 
static void
225
 
gm_chw_destroy (gpointer data)
226
 
{
227
 
  g_return_if_fail (data);
228
 
  
229
 
  delete ((GmCallsHistoryWindow *) data);
230
 
}
231
 
 
232
 
 
233
 
static GmCallsHistoryWindow *
234
 
gm_chw_get_chw (GtkWidget *calls_history_window)
235
 
{
236
 
  g_return_val_if_fail (calls_history_window != NULL, NULL);
237
 
 
238
 
  return GM_CALLS_HISTORY_WINDOW (g_object_get_data (G_OBJECT (calls_history_window), "GMObject"));
239
 
}
240
 
 
241
 
 
242
 
static GmContact *
243
 
gm_chw_get_selected_contact (GtkWidget *calls_history_window)
244
 
{
245
 
  GmContact *contact = NULL;
246
 
 
247
 
  GmCallsHistoryWindow *chw = NULL;
248
 
 
249
 
  GtkTreeSelection *selection = NULL;
250
 
  GtkTreeModel *model = NULL;
251
 
  GtkTreeIter iter;
252
 
  
253
 
  int page_num = 0;
254
 
 
255
 
  
256
 
  g_return_val_if_fail (calls_history_window != NULL, NULL);
257
 
 
258
 
  chw = gm_chw_get_chw (calls_history_window);
259
 
 
260
 
  g_return_val_if_fail (chw != NULL, NULL);
261
 
 
262
 
  page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (chw->chw_notebook));
263
 
      
264
 
  g_return_val_if_fail ((page_num == RECEIVED_CALL || page_num == PLACED_CALL || page_num == MISSED_CALL), NULL);
265
 
  
266
 
 
267
 
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (chw->chw_history_tree_view [page_num]));
268
 
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (chw->chw_history_tree_view [page_num]));
269
 
 
270
 
  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
271
 
 
272
 
    contact = gmcontact_new ();
273
 
 
274
 
    gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 
275
 
                        COLUMN_NAME, &contact->fullname,
276
 
                        COLUMN_URL, &contact->url,
277
 
                        -1);
278
 
  }
279
 
  
280
 
 
281
 
  return contact;
282
 
}
283
 
 
284
 
 
285
 
GtkWidget *
286
 
gm_chw_contact_menu_new (GtkWidget *calls_history_window)
287
 
{
288
 
  GtkWidget *menu = NULL;
289
 
 
290
 
  menu = gtk_menu_new ();
291
 
  
292
 
      
293
 
  static MenuEntry contact_menu [] =
294
 
    {
295
 
      GTK_MENU_ENTRY("call", _("C_all Contact"), NULL,
296
 
                     NULL, 0, 
297
 
                     GTK_SIGNAL_FUNC (call_contact1_cb), 
298
 
                     calls_history_window, TRUE),
299
 
 
300
 
      GTK_MENU_SEPARATOR,
301
 
 
302
 
      GTK_MENU_ENTRY("add", _("Add Contact to _Address Book"), NULL,
303
 
                     GTK_STOCK_ADD, 0,
304
 
                     GTK_SIGNAL_FUNC (add_contact_cb), 
305
 
                     calls_history_window, TRUE),
306
 
 
307
 
      GTK_MENU_END
308
 
    };
309
 
  
310
 
    
311
 
  gtk_build_menu (menu, contact_menu, NULL, NULL);
312
 
 
313
 
  
314
 
  return menu;
315
 
}
316
 
 
317
 
 
318
 
static void
319
 
gm_chw_update (GtkWidget *calls_history_window)
320
 
{
321
 
  GmCallsHistoryWindow *chw = NULL;
322
 
  
323
 
  GtkTreeIter iter;
324
 
  GtkListStore *list_store = NULL;
325
 
 
326
 
  gchar *conf_key = NULL;
327
 
  gchar **call_data = NULL;
328
 
  
329
 
  GSList *calls_list = NULL;
330
 
  GSList *calls_list_iter = NULL;
331
 
 
332
 
  chw = gm_chw_get_chw (calls_history_window);
333
 
 
334
 
  for (int i = 0 ; i < MAX_VALUE_CALL ; i++) {
335
 
 
336
 
    list_store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (chw->chw_history_tree_view [i])));
337
 
    
338
 
    conf_key = gm_chw_get_conf_key (i);
339
 
 
340
 
    gtk_list_store_clear (list_store);
341
 
    
342
 
    calls_list = gm_conf_get_string_list (conf_key);
343
 
 
344
 
    calls_list_iter = calls_list;
345
 
    while (calls_list_iter && calls_list_iter->data) {
346
 
      
347
 
      call_data = g_strsplit ((char *) calls_list_iter->data, "|", 0);
348
 
      
349
 
      if (call_data) {
350
 
        
351
 
        gtk_list_store_append (list_store, &iter);
352
 
        gtk_list_store_set (list_store,
353
 
                            &iter,
354
 
                            0, call_data [0],
355
 
                            1, call_data [1],
356
 
                            2, call_data [2],
357
 
                            3, call_data [3],
358
 
                            4, call_data [4],
359
 
                            5, call_data [5],
360
 
                            -1);
361
 
      }
362
 
      
363
 
      g_strfreev (call_data);
364
 
 
365
 
      calls_list_iter = g_slist_next (calls_list_iter);
366
 
    }
367
 
    
368
 
    g_free (conf_key);
369
 
 
370
 
    g_slist_foreach (calls_list, (GFunc) g_free, NULL);
371
 
    g_slist_free (calls_list);
372
 
  }
373
 
}
374
 
 
375
 
 
376
 
static gchar *
377
 
gm_chw_get_conf_key (int i)
378
 
{
379
 
  gchar *conf_key = NULL;
380
 
  
381
 
  g_return_val_if_fail ((i >= 0 && i < MAX_VALUE_CALL), NULL);
382
 
  
383
 
  switch (i) {
384
 
 
385
 
  case RECEIVED_CALL:
386
 
    conf_key =
387
 
      g_strdup (USER_INTERFACE_KEY "calls_history_window/received_calls_history");
388
 
    break;
389
 
  case PLACED_CALL:
390
 
    conf_key =
391
 
      g_strdup (USER_INTERFACE_KEY "calls_history_window/placed_calls_history");
392
 
    break;
393
 
  case MISSED_CALL:
394
 
    conf_key =
395
 
      g_strdup (USER_INTERFACE_KEY "calls_history_window/missed_calls_history");
396
 
    break;
397
 
  }
398
 
 
399
 
 
400
 
  return conf_key;
401
 
}
402
 
 
403
 
 
404
 
static GmContact *
405
 
dnd_get_contact (GtkWidget *widget, 
406
 
                 gpointer data)
407
 
{
408
 
  GtkWidget *chw = NULL;
409
 
  
410
 
  chw = GTK_WIDGET (data);
411
 
  
412
 
  return gm_chw_get_selected_contact (chw);
413
 
}
414
 
 
415
 
 
416
 
static void
417
 
clear_button_clicked_cb (GtkButton *widget, 
418
 
                         gpointer data)
419
 
{
420
 
  GmCallsHistoryWindow *chw  = NULL;
421
 
 
422
 
  int i = 0;
423
 
  
424
 
  g_return_if_fail (data != NULL);
425
 
  
426
 
  chw = gm_chw_get_chw (GTK_WIDGET (data));
427
 
 
428
 
  g_return_if_fail (chw);
429
 
  
430
 
  i = gtk_notebook_get_current_page (GTK_NOTEBOOK (chw->chw_notebook));
431
 
  
432
 
  gm_calls_history_clear (i);
433
 
}
434
 
 
435
 
 
436
 
static void
437
 
find_button_clicked_cb (GtkButton *widget,
438
 
                        gpointer data)
439
 
{
440
 
  GmCallsHistoryWindow *chw = NULL;
441
 
 
442
 
  GtkListStore *list_store = NULL;
443
 
  GtkTreeIter iter;
444
 
  const char *entry_text = NULL;
445
 
  gchar *date = NULL;
446
 
  gchar *software = NULL;
447
 
  gchar *remote_user = NULL;
448
 
  gchar *end_reason = NULL;
449
 
 
450
 
  BOOL removed = FALSE;
451
 
  BOOL ok = FALSE;
452
 
 
453
 
  gint page = 0;
454
 
 
455
 
  
456
 
  g_return_if_fail (data != NULL);
457
 
 
458
 
  /* Fill in the window */
459
 
  gm_chw_update (GTK_WIDGET (data));  
460
 
 
461
 
  chw = gm_chw_get_chw (GTK_WIDGET (data));
462
 
 
463
 
  g_return_if_fail (chw);
464
 
 
465
 
 
466
 
  entry_text = gtk_entry_get_text (GTK_ENTRY (chw->chw_search_entry));
467
 
 
468
 
  page = gtk_notebook_get_current_page (GTK_NOTEBOOK (chw->chw_notebook));
469
 
    
470
 
  list_store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (chw->chw_history_tree_view [page])));
471
 
 
472
 
 
473
 
  if (strcmp (entry_text, "")
474
 
      && gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store), &iter)) {
475
 
 
476
 
    do {
477
 
 
478
 
      ok = FALSE;
479
 
      removed = FALSE;
480
 
      gtk_tree_model_get (GTK_TREE_MODEL (list_store),
481
 
                          &iter,
482
 
                          COLUMN_DATE, &date,
483
 
                          COLUMN_NAME, &remote_user,
484
 
                          COLUMN_ENDREASON, &end_reason,
485
 
                          COLUMN_SOFTWARE, &software,
486
 
                          -1);
487
 
 
488
 
      if (!(PString (date).Find (entry_text) != P_MAX_INDEX
489
 
          || PString (remote_user).Find (entry_text) != P_MAX_INDEX
490
 
          || PString (end_reason).Find (entry_text) != P_MAX_INDEX
491
 
            || PString (software).Find (entry_text) != P_MAX_INDEX)) {
492
 
        
493
 
        ok = gtk_list_store_remove (GTK_LIST_STORE (list_store), &iter);
494
 
        removed = TRUE;
495
 
      }
496
 
      
497
 
      g_free (date);
498
 
      g_free (remote_user);
499
 
      g_free (end_reason);
500
 
      g_free (software);
501
 
 
502
 
      if (!removed)
503
 
        ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (list_store), &iter);
504
 
        
505
 
    } while (ok);
506
 
  }
507
 
}
508
 
 
509
 
 
510
 
static gint
511
 
contact_clicked_cb (GtkWidget *widget,
512
 
                    GdkEventButton *event,
513
 
                    gpointer data)
514
 
{
515
 
  GtkWidget *menu = NULL;
516
 
  
517
 
  g_return_val_if_fail (data != NULL, FALSE);
518
 
 
519
 
  if (event->type == GDK_BUTTON_PRESS || event->type == GDK_KEY_PRESS) {
520
 
 
521
 
    if (event->button == 3) {
522
 
 
523
 
      menu = gm_chw_contact_menu_new (GTK_WIDGET (data));
524
 
      gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
525
 
                      event->button, event->time);
526
 
      g_signal_connect (G_OBJECT (menu), "hide",
527
 
                        GTK_SIGNAL_FUNC (g_object_unref), (gpointer) menu);
528
 
      g_object_ref (G_OBJECT (menu));
529
 
      gtk_object_sink (GTK_OBJECT (menu));
530
 
    }
531
 
  }
532
 
 
533
 
  return TRUE;
534
 
}
535
 
 
536
 
 
537
 
static void
538
 
call_contact1_cb (GtkWidget *widget,
539
 
                  gpointer data)
540
 
{
541
 
  GmContact *contact = NULL;
542
 
 
543
 
  GtkWidget *calls_history_window = NULL;
544
 
 
545
 
  g_return_if_fail (data != NULL);
546
 
 
547
 
  calls_history_window = GTK_WIDGET (data);
548
 
  
549
 
  contact = gm_chw_get_selected_contact (calls_history_window);
550
 
 
551
 
  if (contact) {
552
 
 
553
 
    GnomeMeeting::Process ()->Connect (contact->url);
554
 
    gmcontact_delete (contact);
555
 
  }
556
 
}
557
 
 
558
 
 
559
 
static void
560
 
call_contact2_cb (GtkTreeView *tree_view,
561
 
                  GtkTreePath *arg1,
562
 
                  GtkTreeViewColumn *arg2,
563
 
                  gpointer data)
564
 
{
565
 
  g_return_if_fail (data != NULL);
566
 
 
567
 
  call_contact1_cb (NULL, data);
568
 
}
569
 
 
570
 
 
571
 
static void
572
 
add_contact_cb (GtkWidget *widget,
573
 
                gpointer data)
574
 
{
575
 
  GmContact *contact = NULL;
576
 
 
577
 
  GtkWidget *calls_history_window = NULL;
578
 
  GtkWidget *addressbook_window = NULL;
579
 
 
580
 
  g_return_if_fail (data != NULL);
581
 
 
582
 
  calls_history_window = GTK_WIDGET (data);
583
 
  addressbook_window = GnomeMeeting::Process ()->GetAddressbookWindow ();
584
 
  
585
 
  contact = gm_chw_get_selected_contact (calls_history_window);
586
 
 
587
 
  if (contact) {
588
 
    
589
 
    gm_addressbook_window_edit_contact_dialog_run (addressbook_window,
590
 
                                                   NULL, 
591
 
                                                   contact, 
592
 
                                                   FALSE,
593
 
                                                   calls_history_window);
594
 
    gmcontact_delete (contact);  
595
 
  }
596
 
}
597
 
 
598
 
 
599
 
static gint 
600
 
contact_compare_cb (gconstpointer contact,
601
 
                    gconstpointer url)
602
 
{
603
 
  GmContact *gmcontact = NULL;
604
 
  
605
 
  if (!contact || !url)
606
 
    return 1;
607
 
  
608
 
  gmcontact = GM_CONTACT (contact);
609
 
  
610
 
  if (gmcontact->url && url) {
611
 
  
612
 
    if (GMURL (gmcontact->url) == GMURL ((char *) url))
613
 
      return 0;
614
 
    else
615
 
      return 1;
616
 
  }
617
 
  else 
618
 
    return 1;
619
 
}
620
 
 
621
 
 
622
 
static void      
623
 
calls_history_changed_nt (gpointer id,   
624
 
                          GmConfEntry *entry,    
625
 
                          gpointer data)         
626
 
{        
627
 
  GtkWidget *main_window = NULL;
628
 
  GtkWidget *chat_window = NULL;
629
 
 
630
 
  g_return_if_fail (data != NULL);
631
 
  g_return_if_fail (gm_conf_entry_get_type (entry) == GM_CONF_LIST);     
632
 
 
633
 
  main_window = GnomeMeeting::Process ()->GetMainWindow ();
634
 
  chat_window = GnomeMeeting::Process ()->GetChatWindow ();
635
 
 
636
 
  gdk_threads_enter ();          
637
 
  gm_chw_update (GTK_WIDGET (data));
638
 
  gm_main_window_urls_history_update (main_window);
639
 
  gm_text_chat_window_urls_history_update (chat_window);
640
 
  gdk_threads_leave ();          
641
 
}
642
 
 
643
 
 
644
 
/* The functions */
645
 
GtkWidget *
646
 
gm_calls_history_window_new ()
647
 
{
648
 
  GtkWidget *hbox = NULL;
649
 
  GtkWidget *button = NULL;
650
 
  GtkWidget *window = NULL;
651
 
  GtkWidget *scr = NULL;
652
 
  GtkWidget *label = NULL;
653
 
  GdkPixbuf *icon = NULL;
654
 
  
655
 
  GmCallsHistoryWindow *chw = NULL;
656
 
  
657
 
  GtkTreeViewColumn *column = NULL;
658
 
  GtkCellRenderer *renderer = NULL;
659
 
 
660
 
  GtkListStore *list_store = NULL;
661
 
 
662
 
  gchar *conf_key = NULL;
663
 
  const gchar *label_text [3] =
664
 
    {N_("Received Calls"), N_("Placed Calls"), N_("Missed Calls")};
665
 
  label_text [0] = gettext (label_text [0]);
666
 
  label_text [1] = gettext (label_text [1]);
667
 
  label_text [2] = gettext (label_text [2]);
668
 
 
669
 
  
670
 
  window = gtk_dialog_new ();
671
 
  gtk_dialog_add_button (GTK_DIALOG (window), GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL);
672
 
 
673
 
  g_object_set_data_full (G_OBJECT (window), "window_name",
674
 
                          g_strdup ("calls_history_window"), g_free);
675
 
  
676
 
  gtk_window_set_title (GTK_WINDOW (window), _("Calls History"));
677
 
  gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
678
 
  icon = gtk_widget_render_icon (GTK_WIDGET (window),
679
 
                                 GM_STOCK_CALLS_HISTORY,
680
 
                                 GTK_ICON_SIZE_MENU, NULL);
681
 
  gtk_window_set_icon (GTK_WINDOW (window), icon);
682
 
  g_object_unref (icon);
683
 
 
684
 
  chw = new GmCallsHistoryWindow ();
685
 
  g_object_set_data_full (G_OBJECT (window), "GMObject", 
686
 
                          chw, gm_chw_destroy);
687
 
 
688
 
 
689
 
  /* The notebook containing the 3 lists of calls */
690
 
  chw->chw_notebook = gtk_notebook_new ();
691
 
  gtk_container_set_border_width (GTK_CONTAINER (chw->chw_notebook), 6);
692
 
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
693
 
                      chw->chw_notebook, TRUE, TRUE, 0);
694
 
 
695
 
 
696
 
  for (int i = 0 ; i < MAX_VALUE_CALL ; i++) {
697
 
 
698
 
    label = gtk_label_new (N_(label_text [i]));
699
 
    
700
 
    scr = gtk_scrolled_window_new (NULL, NULL);
701
 
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), 
702
 
                                    GTK_POLICY_AUTOMATIC,
703
 
                                    GTK_POLICY_AUTOMATIC);
704
 
 
705
 
    list_store = 
706
 
      gtk_list_store_new (6,
707
 
                          G_TYPE_STRING,
708
 
                          G_TYPE_STRING,
709
 
                          G_TYPE_STRING,
710
 
                          G_TYPE_STRING,
711
 
                          G_TYPE_STRING,
712
 
                          G_TYPE_STRING);
713
 
    
714
 
    chw->chw_history_tree_view [i] = 
715
 
      gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
716
 
    gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (chw->chw_history_tree_view [i]), TRUE);
717
 
 
718
 
    renderer = gtk_cell_renderer_text_new ();
719
 
    column = gtk_tree_view_column_new_with_attributes (_("Date"),
720
 
                                                       renderer,
721
 
                                                       "text", 
722
 
                                                       COLUMN_DATE,
723
 
                                                       NULL);
724
 
    gtk_tree_view_append_column (GTK_TREE_VIEW (chw->chw_history_tree_view [i]), column);
725
 
    
726
 
    renderer = gtk_cell_renderer_text_new ();
727
 
    column = gtk_tree_view_column_new_with_attributes (_("Remote User"),
728
 
                                                       renderer,
729
 
                                                       "text", 
730
 
                                                       COLUMN_NAME,
731
 
                                                       NULL);
732
 
    gtk_tree_view_append_column (GTK_TREE_VIEW (chw->chw_history_tree_view [i]), column);
733
 
    g_object_set (G_OBJECT (renderer), "weight", "bold", NULL);
734
 
        
735
 
    renderer = gtk_cell_renderer_text_new ();
736
 
    column = gtk_tree_view_column_new_with_attributes (_("Call Duration"),
737
 
                                                       renderer,
738
 
                                                       "text", 
739
 
                                                       COLUMN_DURATION,
740
 
                                                       NULL);
741
 
    gtk_tree_view_append_column (GTK_TREE_VIEW (chw->chw_history_tree_view [i]), column);
742
 
    if (i == 2)
743
 
      gtk_tree_view_column_set_visible (column, false);
744
 
 
745
 
    renderer = gtk_cell_renderer_text_new ();
746
 
    column = gtk_tree_view_column_new_with_attributes (_("Call End Reason"),
747
 
                                                       renderer,
748
 
                                                       "text", 
749
 
                                                       COLUMN_ENDREASON,
750
 
                                                       NULL);
751
 
    gtk_tree_view_append_column (GTK_TREE_VIEW (chw->chw_history_tree_view [i]), column);
752
 
    g_object_set (G_OBJECT (renderer), "style", PANGO_STYLE_ITALIC, NULL);
753
 
    
754
 
    renderer = gtk_cell_renderer_text_new ();
755
 
    column = gtk_tree_view_column_new_with_attributes (_("Software"),
756
 
                                                       renderer,
757
 
                                                       "text", 
758
 
                                                       COLUMN_SOFTWARE,
759
 
                                                       NULL);
760
 
    gtk_tree_view_append_column (GTK_TREE_VIEW (chw->chw_history_tree_view [i]), column);
761
 
    g_object_set (G_OBJECT (renderer), "style", PANGO_STYLE_ITALIC, NULL);
762
 
        
763
 
    
764
 
    gtk_container_add (GTK_CONTAINER (scr), chw->chw_history_tree_view [i]);
765
 
    gtk_notebook_append_page (GTK_NOTEBOOK (chw->chw_notebook), scr, label);
766
 
 
767
 
 
768
 
    /* Signal to call the person on the double-clicked row */
769
 
    g_signal_connect (G_OBJECT (chw->chw_history_tree_view [i]), 
770
 
                      "row_activated", 
771
 
                      G_CALLBACK (call_contact2_cb), 
772
 
                      window);
773
 
 
774
 
    /* The drag and drop information */
775
 
    gmcontacts_dnd_set_source (GTK_WIDGET (chw->chw_history_tree_view [i]),
776
 
                                dnd_get_contact, window);
777
 
 
778
 
    /* Right-click on a contact */
779
 
    g_signal_connect (G_OBJECT (chw->chw_history_tree_view [i]), "event_after",
780
 
                      G_CALLBACK (contact_clicked_cb), 
781
 
                      window);
782
 
    
783
 
    /* The notifier */  
784
 
    conf_key = gm_chw_get_conf_key (i);
785
 
    gm_conf_notifier_add (conf_key, 
786
 
                          calls_history_changed_nt, (gpointer) window);
787
 
 
788
 
    g_free (conf_key);
789
 
  }
790
 
 
791
 
 
792
 
  /* The hbox added below the notebook that contains the Search field,
793
 
     and the search and clear buttons */
794
 
  hbox = gtk_hbox_new (FALSE, 0);  
795
 
  gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
796
 
  chw->chw_search_entry = gtk_entry_new ();
797
 
  gtk_box_pack_start (GTK_BOX (hbox), chw->chw_search_entry, TRUE, TRUE, 2);
798
 
  g_signal_connect (G_OBJECT (chw->chw_search_entry), "activate",
799
 
                    G_CALLBACK (find_button_clicked_cb),
800
 
                    (gpointer) window);  
801
 
  
802
 
  button = gtk_button_new_from_stock (GTK_STOCK_FIND);
803
 
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 2);
804
 
  g_signal_connect (G_OBJECT (button), "clicked",
805
 
                    G_CALLBACK (find_button_clicked_cb),
806
 
                    (gpointer) window);
807
 
 
808
 
  button = gtk_button_new_from_stock (GTK_STOCK_CLEAR);
809
 
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 2);
810
 
  g_signal_connect (G_OBJECT (button), "clicked",
811
 
                    G_CALLBACK (clear_button_clicked_cb),
812
 
                    (gpointer) window);
813
 
 
814
 
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox,
815
 
                      FALSE, FALSE, 0); 
816
 
 
817
 
  
818
 
  /* Generic signals */
819
 
  g_signal_connect_swapped (GTK_OBJECT (window), 
820
 
                            "response", 
821
 
                            G_CALLBACK (gnomemeeting_window_hide),
822
 
                            (gpointer) window);
823
 
 
824
 
  g_signal_connect (GTK_OBJECT (window), "delete-event", 
825
 
                    G_CALLBACK (delete_window_cb), NULL);
826
 
 
827
 
  
828
 
  /* Fill in the window with old calls */
829
 
  gm_chw_update (window);
830
 
 
831
 
  
832
 
  gtk_widget_show_all (GTK_WIDGET (GTK_DIALOG (window)->vbox));
833
 
  
834
 
  return window;
835
 
}
836
 
 
837
 
 
838
 
void
839
 
gm_calls_history_add_call (int calltype,
840
 
                           const char *remote_user,
841
 
                           const char *ip,
842
 
                           const char *duration,
843
 
                           const char *reason,
844
 
                           const char *software)
845
 
{
846
 
  gchar *conf_key = NULL;
847
 
  gchar *call_data = NULL;
848
 
  
849
 
  GSList *calls_list = NULL;
850
 
  
851
 
  PString time;  
852
 
  
853
 
  time = PTime ().AsString ("yyyy/MM/dd hh:mm:ss");
854
 
 
855
 
 
856
 
  call_data =
857
 
    g_strdup_printf ("%s|%s|%s|%s|%s|%s",
858
 
                     (const char *) time ? (const char *) time : "",
859
 
                     remote_user ? remote_user : "",
860
 
                     ip ? ip : "",
861
 
                     duration ? duration : "",
862
 
                     reason ? reason : "",
863
 
                     software ? software : "");
864
 
  
865
 
  conf_key = gm_chw_get_conf_key (calltype);
866
 
 
867
 
  calls_list = gm_conf_get_string_list (conf_key);
868
 
  calls_list = g_slist_append (calls_list, (gpointer) call_data);
869
 
 
870
 
  while (g_slist_length (calls_list) > 100) 
871
 
    calls_list = g_slist_delete_link (calls_list, calls_list);
872
 
  
873
 
  gm_conf_set_string_list (conf_key, calls_list);
874
 
  
875
 
  g_free (conf_key);
876
 
  
877
 
  g_slist_foreach (calls_list, (GFunc) g_free, NULL);
878
 
  g_slist_free (calls_list);
879
 
}
880
 
 
881
 
 
882
 
void 
883
 
gm_calls_history_clear (int calltype)
884
 
{
885
 
  gchar *conf_key = NULL;
886
 
 
887
 
  g_return_if_fail ((calltype >= 0 && calltype < MAX_VALUE_CALL));
888
 
  
889
 
  conf_key = gm_chw_get_conf_key (calltype);
890
 
  gm_conf_set_string_list (conf_key, NULL);
891
 
  g_free (conf_key);
892
 
}
893
 
 
894
 
 
895
 
GSList *
896
 
gm_calls_history_get_calls (int calltype,
897
 
                            int at_most,
898
 
                            gboolean unique,
899
 
                            gboolean reversed)
900
 
{
901
 
  GmContact *contact = NULL;
902
 
 
903
 
  GSList *calls_list = NULL;
904
 
  GSList *calls_list_iter = NULL;
905
 
  GSList *work_list = NULL;
906
 
  GSList *work_list_iter = NULL;
907
 
  GSList *result = NULL;
908
 
 
909
 
  gchar **call_data = NULL;
910
 
  gchar *conf_key = NULL;
911
 
 
912
 
  gboolean found = FALSE;
913
 
 
914
 
  for (int i = 0 ; i < MAX_VALUE_CALL ; i++) {
915
 
 
916
 
    if (calltype == MAX_VALUE_CALL
917
 
        || calltype == i)  {
918
 
 
919
 
      conf_key = gm_chw_get_conf_key (i);
920
 
      calls_list = gm_conf_get_string_list (conf_key);
921
 
 
922
 
      if (reversed) calls_list = g_slist_reverse (calls_list);
923
 
 
924
 
      calls_list_iter = calls_list;
925
 
      while (calls_list_iter && calls_list_iter->data) {
926
 
 
927
 
        if ((calltype == MAX_VALUE_CALL && at_most != -1) 
928
 
            || (calltype == i)) {
929
 
 
930
 
          call_data = g_strsplit ((char *) calls_list_iter->data, "|", 0);
931
 
 
932
 
          if (call_data) {
933
 
 
934
 
            contact = gmcontact_new ();
935
 
 
936
 
            if (call_data [1])
937
 
              contact->fullname = g_strdup (call_data [1]);
938
 
 
939
 
            if (call_data [2])
940
 
              contact->url = g_strdup (call_data [2]);
941
 
 
942
 
            found = (g_slist_find_custom (work_list, 
943
 
                                          (gconstpointer) contact->url,
944
 
                                          (GCompareFunc) contact_compare_cb) 
945
 
                     != NULL);
946
 
 
947
 
            if ((unique && !found) || (!unique)) {
948
 
 
949
 
              work_list = g_slist_append (work_list, (gpointer) contact);
950
 
            }
951
 
            else
952
 
              gmcontact_delete (contact);
953
 
          }
954
 
        }
955
 
 
956
 
        g_strfreev (call_data);
957
 
        call_data = NULL;
958
 
 
959
 
        calls_list_iter = g_slist_next (calls_list_iter);
960
 
      }
961
 
 
962
 
      g_slist_foreach (calls_list, (GFunc) g_free, NULL);
963
 
      g_slist_free (calls_list);
964
 
 
965
 
      g_free (conf_key);
966
 
    }
967
 
  }
968
 
 
969
 
  
970
 
  /* #INV: work_list contains the result, with unique items or not */
971
 
  if (at_most == -1 || calltype == MAX_VALUE_CALL) // Return all values
972
 
    result = work_list;
973
 
  else { // Return the last at_most results
974
 
 
975
 
    if (reversed) work_list = g_slist_reverse (work_list);
976
 
    work_list_iter = work_list;
977
 
    while (work_list_iter && work_list_iter->data) {
978
 
 
979
 
      if (g_slist_position (work_list, work_list_iter) >=
980
 
          (int) g_slist_length (work_list) - at_most) {
981
 
 
982
 
        result = 
983
 
          g_slist_append (result, 
984
 
                          (gpointer) work_list_iter->data);
985
 
      }
986
 
      else
987
 
        g_free (work_list_iter->data);
988
 
 
989
 
      work_list_iter = g_slist_next (work_list_iter);
990
 
    }
991
 
 
992
 
    if (reversed) result = g_slist_reverse (result);
993
 
 
994
 
    g_slist_free (work_list);
995
 
  }
996
 
 
997
 
  return result;
998
 
}