~ubuntu-branches/ubuntu/saucy/cairo-dock-plug-ins/saucy

« back to all changes in this revision

Viewing changes to terminal/src/terminal-widget.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2009-08-26 21:07:39 UTC
  • Revision ID: james.westby@ubuntu.com-20090826210739-gyjuuqezrzuluao4
Tags: upstream-2.0.8.1
ImportĀ upstreamĀ versionĀ 2.0.8.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
* This file is a part of the Cairo-Dock project
 
3
*
 
4
* Copyright : (C) see the 'copyright' file.
 
5
* E-mail    : see the 'copyright' file.
 
6
*
 
7
* This program is free software; you can redistribute it and/or
 
8
* modify it under the terms of the GNU General Public License
 
9
* as published by the Free Software Foundation; either version 3
 
10
* of the License, or (at your option) any later version.
 
11
*
 
12
* This program is distributed in the hope that it will be useful,
 
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
* GNU General Public License for more details.
 
16
* You should have received a copy of the GNU General Public License
 
17
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
*/
 
19
 
 
20
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
 
21
/*
 
22
** Login : <ctaf42@gmail.com>
 
23
** Started on  Fri Nov 30 05:31:31 2007 GESTES Cedric
 
24
** $Id$
 
25
**
 
26
** Author(s):
 
27
**  - Cedric GESTES <ctaf42@gmail.com>
 
28
**
 
29
** Copyright (C) 2007 GESTES Cedric
 
30
** This program is free software; you can redistribute it and/or modify
 
31
** it under the terms of the GNU General Public License as published by
 
32
** the Free Software Foundation; either version 3 of the License, or
 
33
** (at your option) any later version.
 
34
**
 
35
** This program is distributed in the hope that it will be useful,
 
36
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 
37
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
38
** GNU General Public License for more details.
 
39
**
 
40
** You should have received a copy of the GNU General Public License
 
41
** along with this program; if not, write to the Free Software
 
42
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
43
*/
 
44
 
 
45
#include <stdlib.h>
 
46
#include <string.h>
 
47
#include <signal.h>
 
48
#include <gdk/gdkkeysyms.h>
 
49
// gdk.h semble necessaire pour certains
 
50
#include <gdk/gdk.h>
 
51
 
 
52
#include <vte/vte.h>
 
53
 
 
54
#include "terminal-callbacks.h"
 
55
#include "terminal-struct.h"
 
56
#include "terminal-menu-functions.h"
 
57
#include "terminal-widget.h"
 
58
 
 
59
 
 
60
CairoDialog *cd_terminal_build_dialog (void)
 
61
{
 
62
        CairoDialogAttribute attr;
 
63
        memset (&attr, 0, sizeof (CairoDialogAttribute));
 
64
        attr.cText = D_ ("Terminal");
 
65
        attr.pInteractiveWidget = myData.tab;
 
66
        return cairo_dock_build_dialog (&attr, myIcon, myContainer);
 
67
}
 
68
 
 
69
void term_on_keybinding_pull(const char *keystring, gpointer user_data)
 
70
{
 
71
        if (myData.tab)
 
72
        {
 
73
                if (myDesklet)
 
74
                {
 
75
                        gboolean bHasFocus = (gtk_window_has_toplevel_focus (GTK_WINDOW (myDesklet->pWidget)) || GTK_WIDGET_HAS_FOCUS (myData.tab) || GTK_WIDGET_HAS_FOCUS (myDesklet->pWidget));
 
76
                        if (! bHasFocus)
 
77
                        {
 
78
                                GtkWidget *vterm;
 
79
                                int i, iNbPages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (myData.tab));
 
80
                                for (i = 0; i < iNbPages && ! bHasFocus; ++i)
 
81
                                {
 
82
                                        vterm = gtk_notebook_get_nth_page(GTK_NOTEBOOK(myData.tab), i);
 
83
                                        bHasFocus = GTK_WIDGET_HAS_FOCUS (vterm);
 
84
                                }
 
85
                        }
 
86
                        g_print ("%s (%d)\n", __func__, bHasFocus);
 
87
                        
 
88
                        if (bHasFocus)
 
89
                        {
 
90
                                cairo_dock_hide_desklet(myDesklet);
 
91
                        }
 
92
                        else
 
93
                        {
 
94
                                cairo_dock_show_desklet(myDesklet);
 
95
                                int iCurrentNumPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(myData.tab));
 
96
                                GtkWidget *vterm = gtk_notebook_get_nth_page(GTK_NOTEBOOK(myData.tab), iCurrentNumPage);
 
97
                                gtk_widget_grab_focus (vterm);
 
98
                        }
 
99
                }
 
100
                else if (myData.dialog)
 
101
                {
 
102
                        cairo_dock_toggle_dialog_visibility (myData.dialog);
 
103
                }
 
104
        }
 
105
        else
 
106
        {
 
107
                terminal_build_and_show_tab ();
 
108
        }
 
109
}
 
110
 
 
111
 
 
112
static gchar *_get_label_and_color (const gchar *cLabel, GdkColor *pColor, gboolean *bColorSet)
 
113
{
 
114
        gchar *cUsefulLabel;
 
115
        gchar *str = strchr (cLabel, '>');
 
116
        if (cLabel != NULL && strncmp (cLabel, "<span color='", 13) == 0 && str != NULL)  // approximatif mais devrait suffire.
 
117
        {
 
118
                gchar *cColor = g_strndup (cLabel+13, 7);
 
119
                if (pColor != NULL)
 
120
                        *bColorSet = gdk_color_parse (cColor, pColor);
 
121
                g_free (cColor);
 
122
                
 
123
                cUsefulLabel = g_strdup (str+1);
 
124
                str = strrchr (cLabel, '<');
 
125
                if (str != NULL && strcmp (str, "</span>") == 0)
 
126
                        *str = '\0';
 
127
        }
 
128
        else
 
129
        {
 
130
                cUsefulLabel = g_strdup (cLabel);
 
131
        }
 
132
        return cUsefulLabel;
 
133
}
 
134
 
 
135
void terminal_rename_tab (GtkWidget *vterm)
 
136
{
 
137
        cd_message ("");
 
138
        if (vterm == NULL)
 
139
        {
 
140
                int iCurrentNumPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(myData.tab));
 
141
                vterm = gtk_notebook_get_nth_page (GTK_NOTEBOOK(myData.tab), iCurrentNumPage);
 
142
        }
 
143
        GtkWidget *pTabLabelWidget = gtk_notebook_get_tab_label (GTK_NOTEBOOK(myData.tab), vterm);
 
144
        GList *pTabWidgetList = gtk_container_get_children (GTK_CONTAINER (pTabLabelWidget));
 
145
        GtkLabel *pLabel;
 
146
        const gchar *cCurrentName;
 
147
        if (pTabWidgetList != NULL && pTabWidgetList->data != NULL)
 
148
        {
 
149
                GtkLabel *pLabel = pTabWidgetList->data;
 
150
                const gchar *cCurrentName = gtk_label_get_text (pLabel);
 
151
                GdkColor color;
 
152
                gboolean bColorSet = FALSE;
 
153
                gchar *cUsefulLabel = _get_label_and_color (cCurrentName, &color, &bColorSet);
 
154
                
 
155
                gchar *cNewName = cairo_dock_show_demand_and_wait (D_("Set title for this tab :"), NULL, (myDock ? CAIRO_CONTAINER (myData.dialog) : CAIRO_CONTAINER (myDesklet)), cUsefulLabel);
 
156
                g_free (cUsefulLabel);
 
157
                
 
158
                if (cNewName != NULL)
 
159
                {
 
160
                        if (bColorSet)
 
161
                        {
 
162
                                gchar *cColor = gdk_color_to_string (&color);
 
163
                                gchar *cNewColoredName = g_strdup_printf ("<span color='%s'>%s</span>", cColor, cNewName);
 
164
                                gtk_label_set_markup (pLabel, cNewColoredName);
 
165
                                g_free (cNewColoredName);
 
166
                                g_free (cColor);
 
167
                        }
 
168
                        else
 
169
                        {
 
170
                                gtk_label_set_text (pLabel, cNewName);
 
171
                        }
 
172
                        g_free (cNewName);
 
173
                }
 
174
        }
 
175
}
 
176
 
 
177
static void _set_color (GtkColorSelection *pColorSelection, GtkLabel *pLabel)
 
178
{
 
179
        GdkColor color;
 
180
        gtk_color_selection_get_current_color (pColorSelection, &color);
 
181
        
 
182
        gchar *cColor = gdk_color_to_string (&color);
 
183
        
 
184
        const gchar *cCurrentLabel = gtk_label_get_text (pLabel);
 
185
        gchar *cUsefulLabel = _get_label_and_color (cCurrentLabel, NULL, NULL);
 
186
        gchar *cNewLabel = g_strdup_printf ("<span color='%s'>%s</span>", cColor, cUsefulLabel);
 
187
        gtk_label_set_markup (pLabel, cNewLabel);
 
188
        
 
189
        g_free (cNewLabel);
 
190
        g_free (cUsefulLabel);
 
191
        g_free (cColor);
 
192
}
 
193
void terminal_change_color_tab (GtkWidget *vterm)
 
194
{
 
195
        cd_message ("");
 
196
        if (vterm == NULL)
 
197
        {
 
198
                int iCurrentNumPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(myData.tab));
 
199
                vterm = gtk_notebook_get_nth_page (GTK_NOTEBOOK(myData.tab), iCurrentNumPage);
 
200
        }
 
201
        GtkWidget *pTabLabelWidget = gtk_notebook_get_tab_label (GTK_NOTEBOOK(myData.tab), vterm);
 
202
        GList *pTabWidgetList = gtk_container_get_children (GTK_CONTAINER (pTabLabelWidget));
 
203
        GtkLabel *pLabel;
 
204
        const gchar *cCurrentName = NULL;
 
205
        if (pTabWidgetList != NULL && pTabWidgetList->data != NULL)
 
206
        {
 
207
                GtkLabel *pLabel = pTabWidgetList->data;
 
208
                
 
209
                GtkWidget *pColorDialog = gtk_color_selection_dialog_new (D_("Select a color"));
 
210
                
 
211
                const gchar *cCurrentLabel = gtk_label_get_text (pLabel);
 
212
                GdkColor color;
 
213
                gboolean bColorSet = FALSE;
 
214
                gchar *cUsefulLabel = _get_label_and_color (cCurrentLabel, &color, &bColorSet);
 
215
                if (bColorSet)
 
216
                {
 
217
                        gtk_color_selection_set_current_color (GTK_COLOR_SELECTION (((GtkColorSelectionDialog *) pColorDialog)->colorsel), &color);
 
218
                }
 
219
                
 
220
                gtk_color_selection_set_has_opacity_control (GTK_COLOR_SELECTION (((GtkColorSelectionDialog *) pColorDialog)->colorsel), FALSE);
 
221
                g_signal_connect (((GtkColorSelectionDialog *) pColorDialog)->colorsel, "color-changed", GTK_SIGNAL_FUNC (_set_color), pLabel);
 
222
                gtk_widget_hide (((GtkColorSelectionDialog *) pColorDialog)->cancel_button);
 
223
                gtk_widget_hide (((GtkColorSelectionDialog *) pColorDialog)->help_button);
 
224
                g_signal_connect_swapped (((GtkColorSelectionDialog *) pColorDialog)->ok_button, "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), pColorDialog);
 
225
                
 
226
                gtk_window_present (GTK_WINDOW (pColorDialog));
 
227
        }
 
228
}
 
229
 
 
230
void terminal_close_tab (GtkWidget *vterm)
 
231
{
 
232
        if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(myData.tab)) > 1)
 
233
        {
 
234
                int iNumPage;
 
235
                if (vterm == NULL)
 
236
                {
 
237
                        iNumPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(myData.tab));
 
238
                }
 
239
                else
 
240
                {
 
241
                        iNumPage = gtk_notebook_page_num (GTK_NOTEBOOK(myData.tab), vterm);
 
242
                }
 
243
                gtk_notebook_remove_page(GTK_NOTEBOOK(myData.tab), iNumPage);
 
244
        }
 
245
}
 
246
 
 
247
 
 
248
static void term_apply_settings_on_vterm(GtkWidget *vterm)
 
249
{
 
250
  g_return_if_fail (vterm != NULL);
 
251
  vte_terminal_set_colors(VTE_TERMINAL(vterm), &myConfig.forecolor, &myConfig.backcolor, NULL, 0);
 
252
      //vte_terminal_set_background_saturation(VTE_TERMINAL(vterm), 1.0);
 
253
      //vte_terminal_set_background_transparent(VTE_TERMINAL(vterm), TRUE);
 
254
#if GTK_MINOR_VERSION >= 12
 
255
  vte_terminal_set_opacity(VTE_TERMINAL(vterm), myConfig.transparency);
 
256
#endif
 
257
  
 
258
        if (myDock)
 
259
        {
 
260
                //g_print ("set_size (%d , %d)\n", myConfig.iNbColumns, myConfig.iNbRows);
 
261
                gtk_widget_set (vterm, "width-request", 0, NULL);
 
262
                gtk_widget_set (vterm, "height-request", 0, NULL);
 
263
                vte_terminal_set_size(VTE_TERMINAL(vterm), myConfig.iNbColumns, myConfig.iNbRows);
 
264
                GtkRequisition requisition = {0, 0};
 
265
                gtk_widget_size_request (vterm, &requisition);
 
266
                //g_print (" -> %dx%d\n", requisition.width, requisition.height);
 
267
                if (myData.dialog)
 
268
                        gtk_window_resize (GTK_WINDOW (myData.dialog->pWidget), requisition.width, requisition.height);
 
269
        }
 
270
        else
 
271
        {
 
272
                gtk_widget_set (vterm, "width-request", 64, NULL);
 
273
                gtk_widget_set (vterm, "height-request", 64, NULL);
 
274
        }
 
275
}
 
276
 
 
277
 
 
278
void term_apply_settings (void)
 
279
{
 
280
        int sz = 0;
 
281
        GtkWidget *vterm = NULL;
 
282
 
 
283
        if (myData.tab) {
 
284
                sz = gtk_notebook_get_n_pages(GTK_NOTEBOOK(myData.tab));
 
285
                for (int i = 0; i < sz; ++i) {
 
286
                        vterm = gtk_notebook_get_nth_page(GTK_NOTEBOOK(myData.tab), i);
 
287
                        term_apply_settings_on_vterm(vterm);
 
288
                }
 
289
        }
 
290
        gboolean bKeyBinded = cd_keybinder_bind (myConfig.shortcut, (CDBindkeyHandler)term_on_keybinding_pull, (gpointer)NULL);
 
291
        if (! bKeyBinded)
 
292
        {
 
293
                g_free (myConfig.shortcut);
 
294
                myConfig.shortcut = NULL;
 
295
        }       
 
296
}
 
297
 
 
298
static void on_terminal_child_exited(VteTerminal *vteterminal,
 
299
                                     gpointer t)
 
300
{
 
301
        gint p = gtk_notebook_page_num(GTK_NOTEBOOK(myData.tab), GTK_WIDGET(vteterminal));
 
302
        gint sz = gtk_notebook_get_n_pages(GTK_NOTEBOOK(myData.tab));
 
303
 
 
304
        if (sz > 1)
 
305
                gtk_notebook_remove_page(GTK_NOTEBOOK(myData.tab), p);
 
306
        else {
 
307
                // \r needed to return to the beginning of the line
 
308
                vte_terminal_feed(VTE_TERMINAL(vteterminal), "Shell exited. Another one is launching...\r\n\n", -1);
 
309
                vte_terminal_fork_command(VTE_TERMINAL(vteterminal),
 
310
                        NULL,
 
311
                        NULL,
 
312
                        NULL,
 
313
                        "~/",
 
314
                        FALSE,
 
315
                        FALSE,
 
316
                        FALSE);
 
317
                if (myData.dialog)
 
318
                        cairo_dock_hide_dialog (myData.dialog);
 
319
                else if (myDesklet && myConfig.shortcut)
 
320
                {
 
321
                        cairo_dock_hide_desklet (myDesklet);
 
322
                }
 
323
        }
 
324
}
 
325
 
 
326
 
 
327
static void _terminal_copy (GtkMenuItem *menu_item, GtkWidget *data)
 
328
{
 
329
  vte_terminal_copy_clipboard(VTE_TERMINAL(data));
 
330
}
 
331
static void _terminal_paste (GtkMenuItem *menu_item, GtkWidget *data)
 
332
{
 
333
  vte_terminal_paste_clipboard(VTE_TERMINAL(data));
 
334
}
 
335
 
 
336
 
 
337
 
 
338
static void on_new_tab (GtkMenuItem *menu_item, gpointer *data)
 
339
{
 
340
        terminal_new_tab();
 
341
}
 
342
static void on_rename_tab (GtkMenuItem *menu_item, GtkWidget *vterm)
 
343
{
 
344
        terminal_rename_tab (vterm);
 
345
}
 
346
static void on_change_tab_color (GtkMenuItem *menu_item, GtkWidget *vterm)
 
347
{
 
348
        terminal_change_color_tab (vterm);
 
349
}
 
350
static void on_close_tab (GtkMenuItem *menu_item, GtkWidget *vterm)
 
351
{
 
352
        terminal_close_tab (vterm);
 
353
}
 
354
static GtkWidget *_terminal_build_menu_tab (GtkWidget *vterm)
 
355
{
 
356
        GtkWidget *menu = gtk_menu_new ();
 
357
        
 
358
        GtkWidget *menu_item, *image;
 
359
        if (vterm)
 
360
        {
 
361
                menu_item = gtk_image_menu_item_new_with_label (D_("Copy"));
 
362
                image = gtk_image_new_from_stock (GTK_STOCK_COPY, GTK_ICON_SIZE_MENU);
 
363
                gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image);
 
364
                gtk_menu_shell_append  (GTK_MENU_SHELL (menu), menu_item);
 
365
                g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK(_terminal_copy), vterm);
 
366
                
 
367
                menu_item = gtk_image_menu_item_new_with_label (D_("Paste"));
 
368
                image = gtk_image_new_from_stock (GTK_STOCK_PASTE, GTK_ICON_SIZE_MENU);
 
369
                gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image);
 
370
                gtk_menu_shell_append  (GTK_MENU_SHELL (menu), menu_item);
 
371
                g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK(_terminal_paste), vterm);
 
372
                
 
373
                menu_item = gtk_separator_menu_item_new ();
 
374
                gtk_menu_shell_append  (GTK_MENU_SHELL (menu), menu_item);
 
375
        }
 
376
 
 
377
  menu_item = gtk_image_menu_item_new_with_label (D_("New Tab"));
 
378
  image = gtk_image_new_from_stock (GTK_STOCK_NEW, GTK_ICON_SIZE_MENU);
 
379
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image);
 
380
  gtk_menu_shell_append  (GTK_MENU_SHELL (menu), menu_item);
 
381
  g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK(on_new_tab), vterm);
 
382
  
 
383
  menu_item = gtk_image_menu_item_new_with_label (D_("Rename this Tab"));
 
384
  image = gtk_image_new_from_stock (GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU);
 
385
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image);
 
386
  gtk_menu_shell_append  (GTK_MENU_SHELL (menu), menu_item);
 
387
  g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK(on_rename_tab), vterm);
 
388
 
 
389
  menu_item = gtk_image_menu_item_new_with_label (D_("Change this Tab's color"));
 
390
  image = gtk_image_new_from_stock (GTK_STOCK_COLOR_PICKER, GTK_ICON_SIZE_MENU);
 
391
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image);
 
392
  gtk_menu_shell_append  (GTK_MENU_SHELL (menu), menu_item);
 
393
  g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK(on_change_tab_color), vterm);
 
394
 
 
395
  menu_item = gtk_image_menu_item_new_with_label (D_("Close this Tab"));
 
396
  image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
 
397
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image);
 
398
  gtk_menu_shell_append  (GTK_MENU_SHELL (menu), menu_item);
 
399
  g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK(on_close_tab), vterm);
 
400
 
 
401
  return menu;
 
402
}
 
403
 
 
404
static gboolean applet_on_terminal_press_cb(GtkWidget *vterm, GdkEventButton *event, gpointer user_data)
 
405
{
 
406
  g_print ("%s ()\n", __func__);
 
407
  if (event->button == 3)
 
408
    {
 
409
      GtkWidget *menu = _terminal_build_menu_tab (vterm);
 
410
 
 
411
      gtk_widget_show_all (menu);
 
412
 
 
413
      gtk_menu_popup (GTK_MENU (menu),
 
414
                      NULL,
 
415
                      NULL,
 
416
                      NULL,
 
417
                      NULL,
 
418
                      1,
 
419
                      gtk_get_current_event_time ());
 
420
    }
 
421
  return FALSE;
 
422
}
 
423
static void applet_on_terminal_eof(VteTerminal *vteterminal,
 
424
                                   gpointer     user_data)
 
425
{
 
426
  cd_debug ("youkata EOF");
 
427
}
 
428
static gboolean on_key_press_term (GtkWidget *pWidget,
 
429
        GdkEventKey *pKey,
 
430
        gpointer data)
 
431
{
 
432
        if (pKey->type == GDK_KEY_PRESS && (pKey->state & GDK_CONTROL_MASK))
 
433
        {
 
434
                switch (pKey->keyval)
 
435
                {
 
436
                        case GDK_t :
 
437
                                terminal_new_tab();
 
438
                        break ;
 
439
                        case GDK_w :
 
440
                                terminal_close_tab (NULL);
 
441
                        break ;
 
442
                        default :
 
443
                        break ;
 
444
                }
 
445
        }
 
446
        return FALSE;
 
447
}
 
448
static gchar * _terminal_get_tab_name (int iNumPage)
 
449
{
 
450
        GtkWidget *vterm = gtk_notebook_get_nth_page (GTK_NOTEBOOK(myData.tab), iNumPage);
 
451
        GtkWidget *pTabLabelWidget = gtk_notebook_get_tab_label (GTK_NOTEBOOK(myData.tab), vterm);
 
452
        GList *pTabWidgetList = gtk_container_get_children (GTK_CONTAINER (pTabLabelWidget));
 
453
        GtkLabel *pLabel;
 
454
        const gchar *cCurrentName;
 
455
        if (pTabWidgetList != NULL && pTabWidgetList->data != NULL)
 
456
        {
 
457
                GtkLabel *pLabel = pTabWidgetList->data;
 
458
                const gchar *cCurrentName = gtk_label_get_text (pLabel);
 
459
                return _get_label_and_color (cCurrentName, NULL, NULL);
 
460
        }
 
461
        return NULL;
 
462
}
 
463
void terminal_new_tab(void)
 
464
{
 
465
  GtkWidget *vterm = NULL;
 
466
 
 
467
  vterm = vte_terminal_new();
 
468
  //transparency enable, otherwise we cant change value after
 
469
  //vte_terminal_set_background_transparent(VTE_TERMINAL(vterm), TRUE);
 
470
#if GTK_MINOR_VERSION >= 12
 
471
  vte_terminal_set_opacity(VTE_TERMINAL(vterm), myConfig.transparency);
 
472
#endif
 
473
  vte_terminal_set_emulation(VTE_TERMINAL(vterm), "xterm");
 
474
  vte_terminal_fork_command(VTE_TERMINAL(vterm),
 
475
                            NULL,
 
476
                            NULL,
 
477
                            NULL,
 
478
                            "~/",
 
479
                            FALSE,
 
480
                            FALSE,
 
481
                            FALSE);
 
482
  g_signal_connect (G_OBJECT (vterm), "child-exited",
 
483
                    G_CALLBACK (on_terminal_child_exited), NULL);
 
484
  g_signal_connect (G_OBJECT (vterm), "button-release-event",
 
485
                    G_CALLBACK (applet_on_terminal_press_cb), NULL);
 
486
  g_signal_connect (G_OBJECT (vterm),
 
487
                "key-press-event",
 
488
                G_CALLBACK (on_key_press_term),
 
489
                NULL);
 
490
  g_signal_connect (G_OBJECT (vterm), "eof",
 
491
                    G_CALLBACK (applet_on_terminal_eof), NULL);
 
492
 
 
493
  cairo_dock_allow_widget_to_receive_data (vterm, G_CALLBACK (on_terminal_drag_data_received), NULL);
 
494
 
 
495
        GtkWidget *pHBox = gtk_hbox_new (FALSE, 0);
 
496
        
 
497
        //\_________________On choisit un nom qui ne soit pas deja present, de la forme " # n ".
 
498
        int i, iNbPages = gtk_notebook_get_n_pages (GTK_NOTEBOOK(myData.tab));
 
499
        GList *pTabNameList = NULL;
 
500
        for (i = 0; i < iNbPages; i ++)
 
501
        {
 
502
                pTabNameList = g_list_prepend (pTabNameList, _terminal_get_tab_name (i));
 
503
        }
 
504
        int iChoosedNum = 1;
 
505
        gchar *cLabel = g_strdup_printf (" # %d ", iChoosedNum);
 
506
        gchar *cTabName;
 
507
        GList *pElement = pTabNameList;
 
508
        do
 
509
        {
 
510
                if (pElement == NULL)
 
511
                        break ;
 
512
                cTabName = pElement->data;
 
513
                if (cTabName != NULL && strcmp (cTabName, cLabel) == 0)
 
514
                {
 
515
                        g_free (cLabel);
 
516
                        iChoosedNum ++;
 
517
                        cLabel = g_strdup_printf (" # %d ", iChoosedNum);
 
518
                        
 
519
                        g_free (cTabName);
 
520
                        pElement->data = NULL;
 
521
                        pElement = pTabNameList;
 
522
                }
 
523
                else
 
524
                        pElement = pElement->next;
 
525
        } while (TRUE);
 
526
        g_list_foreach (pTabNameList, (GFunc) g_free, NULL);
 
527
        g_list_free (pTabNameList);
 
528
        
 
529
        GtkWidget *pLabel = gtk_label_new (cLabel);
 
530
        g_free (cLabel);
 
531
        gtk_label_set_use_markup (GTK_LABEL (pLabel), TRUE);
 
532
        gtk_box_pack_start (GTK_BOX (pHBox),
 
533
                pLabel,
 
534
                FALSE,
 
535
                FALSE,
 
536
                0);
 
537
        
 
538
        GtkWidget *pButton = gtk_button_new_with_label ("x");
 
539
        g_signal_connect (G_OBJECT (pButton),
 
540
                "clicked",
 
541
                G_CALLBACK (on_close_tab),
 
542
                NULL);
 
543
        gtk_box_pack_start (GTK_BOX (pHBox),
 
544
                pButton,
 
545
                FALSE,
 
546
                FALSE,
 
547
                0);
 
548
        
 
549
        gtk_widget_show_all (pHBox);
 
550
        int num_new_tab = gtk_notebook_append_page(GTK_NOTEBOOK(myData.tab), vterm, pHBox);
 
551
        GtkWidget *pNewTab = gtk_notebook_get_nth_page (GTK_NOTEBOOK(myData.tab), num_new_tab);
 
552
        
 
553
  gtk_widget_show(vterm);
 
554
  cd_message ("num_new_tab : %d", num_new_tab);
 
555
  gtk_notebook_set_current_page (GTK_NOTEBOOK (myData.tab), num_new_tab);
 
556
  
 
557
  term_apply_settings_on_vterm (vterm);
 
558
}
 
559
 
 
560
 
 
561
static void _hide_show_tab_button (GtkNotebook *pNotebook, int iNumPage, gboolean bShow)
 
562
{
 
563
        GtkWidget *pPageChild = gtk_notebook_get_nth_page (pNotebook, iNumPage);
 
564
        GtkWidget *pTabLabelWidget = gtk_notebook_get_tab_label (pNotebook, pPageChild);
 
565
        GList *pTabWidgetList = gtk_container_get_children (GTK_CONTAINER (pTabLabelWidget));
 
566
        if (pTabWidgetList != NULL && pTabWidgetList->next != NULL)
 
567
        {
 
568
                GtkWidget *pButton = pTabWidgetList->next->data;
 
569
                if (pButton != NULL)
 
570
                {
 
571
                        if (bShow)
 
572
                                gtk_widget_show (pButton);
 
573
                        else
 
574
                                gtk_widget_hide (pButton);
 
575
                }
 
576
        }
 
577
        g_list_free (pTabWidgetList);
 
578
}
 
579
static void on_switch_page (GtkNotebook *pNotebook,
 
580
        GtkNotebookPage *pNextPage,
 
581
        guint iNextNumPage,
 
582
        gpointer user_data)
 
583
{
 
584
        int iCurrentNumPage = gtk_notebook_get_current_page (pNotebook);
 
585
        
 
586
        _hide_show_tab_button (pNotebook, iCurrentNumPage, FALSE);
 
587
        _hide_show_tab_button (pNotebook, iNextNumPage, TRUE);
 
588
}
 
589
static GtkWidget * _terminal_find_clicked_tab_child (int x, int y)  // x,y relativement au notebook.
 
590
{
 
591
        GtkRequisition requisition;
 
592
        GtkWidget *pPageChild, *pTabLabelWidget, *vterm = NULL;
 
593
        
 
594
        int iMaxTabHeight = 0;
 
595
        int iCurrentNumPage = gtk_notebook_get_current_page (GTK_NOTEBOOK (myData.tab));
 
596
        pPageChild = gtk_notebook_get_nth_page(GTK_NOTEBOOK(myData.tab), iCurrentNumPage);
 
597
        pTabLabelWidget = gtk_notebook_get_tab_label (GTK_NOTEBOOK(myData.tab), pPageChild);
 
598
        gtk_widget_get_child_requisition (pTabLabelWidget, &requisition);
 
599
        iMaxTabHeight = requisition.height;
 
600
        //g_print ("iMaxTabHeight : %d\n", iMaxTabHeight);
 
601
        
 
602
        int i, iNbPages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (myData.tab));
 
603
        gint src_x, src_y, dest_x, dest_y;
 
604
        for (i = 0; i < iNbPages; ++i)
 
605
        {
 
606
                pPageChild = gtk_notebook_get_nth_page(GTK_NOTEBOOK(myData.tab), i);
 
607
                pTabLabelWidget = gtk_notebook_get_tab_label (GTK_NOTEBOOK(myData.tab), pPageChild);
 
608
                gtk_widget_get_child_requisition (pTabLabelWidget, &requisition);
 
609
                gtk_widget_translate_coordinates (myData.tab,
 
610
                        pTabLabelWidget,
 
611
                        x, y,
 
612
                        &dest_x,
 
613
                        &dest_y);
 
614
                //g_print ("%d) (%d;%d) (%dx%d)\n", i, dest_x, dest_y, requisition.width, requisition.height);
 
615
                if (dest_x >= 0 && dest_y >= 0 && dest_x <= requisition.width && dest_y <= iMaxTabHeight)
 
616
                {
 
617
                        vterm = pPageChild;
 
618
                        break;
 
619
                }
 
620
        }
 
621
        return vterm;
 
622
}
 
623
static gboolean on_button_press_tab (GtkWidget* pWidget,
 
624
        GdkEventButton* pButton,
 
625
        GtkWidget *vterm)
 
626
{
 
627
        //g_print ("%s (%d;%d)\n", __func__, (int)pButton->x, (int)pButton->y);
 
628
        if (pButton->type == GDK_2BUTTON_PRESS)
 
629
        {
 
630
                if (vterm == NULL)
 
631
                        vterm = _terminal_find_clicked_tab_child (pButton->x, pButton->y);
 
632
                if (vterm == NULL)
 
633
                        terminal_new_tab ();
 
634
                else
 
635
                        terminal_rename_tab (vterm);
 
636
        }
 
637
        else if (pButton->button == 3)
 
638
        {
 
639
                if (vterm == NULL)
 
640
                        vterm = _terminal_find_clicked_tab_child (pButton->x, pButton->y);
 
641
                if (vterm != NULL)
 
642
                {
 
643
                        GtkWidget *menu = _terminal_build_menu_tab (vterm);
 
644
                        
 
645
                        gtk_widget_show_all (menu);
 
646
                        
 
647
                        gtk_menu_popup (GTK_MENU (menu),
 
648
                                NULL,
 
649
                                NULL,
 
650
                                NULL,
 
651
                                NULL,
 
652
                                1,
 
653
                                gtk_get_current_event_time ());
 
654
                        return TRUE;  // on empeche le menu de cairo-dock d'apparaitre par-dessus.
 
655
                }
 
656
        }
 
657
        else if (pButton->button == 2)
 
658
        {
 
659
                if (vterm == NULL)
 
660
                        vterm = _terminal_find_clicked_tab_child (pButton->x, pButton->y);
 
661
                if (vterm != NULL)
 
662
                {
 
663
                        terminal_close_tab (vterm);
 
664
                }
 
665
        }
 
666
        return FALSE;
 
667
}
 
668
void terminal_build_and_show_tab (void)
 
669
{
 
670
        myData.tab = gtk_notebook_new();
 
671
        g_signal_connect (G_OBJECT (myData.tab),
 
672
                "switch-page",
 
673
                G_CALLBACK (on_switch_page),
 
674
                NULL);
 
675
        g_signal_connect (G_OBJECT (myData.tab),
 
676
                "button-press-event",
 
677
                G_CALLBACK (on_button_press_tab),
 
678
                NULL);
 
679
        g_signal_connect (G_OBJECT (myData.tab),
 
680
                "key-press-event",
 
681
                G_CALLBACK (on_key_press_term),
 
682
                NULL);
 
683
        
 
684
        terminal_new_tab();
 
685
        gtk_widget_show(myData.tab);
 
686
 
 
687
        term_apply_settings();
 
688
 
 
689
        if (myDock)
 
690
        {
 
691
                myData.dialog = cd_terminal_build_dialog ();
 
692
                //myData.dialog = cairo_dock_build_dialog (D_("Terminal"), myIcon, myContainer, NULL, myData.tab, GTK_BUTTONS_NONE, NULL, NULL, NULL);
 
693
        }
 
694
        else
 
695
        {
 
696
                cairo_dock_add_interactive_widget_to_desklet (myData.tab, myDesklet);
 
697
                cairo_dock_set_desklet_renderer_by_name (myDesklet, NULL, NULL, ! CAIRO_DOCK_LOAD_ICONS_FOR_DESKLET, NULL);
 
698
        }
 
699
}