~ubuntu-branches/ubuntu/raring/remmina/raring

« back to all changes in this revision

Viewing changes to src/remminamain.c

  • Committer: Package Import Robot
  • Author(s): Luca Falavigna
  • Date: 2012-02-11 17:28:48 UTC
  • mfrom: (1.2.8)
  • Revision ID: package-import@ubuntu.com-20120211172848-rh3ffi7075qyobuq
Tags: 1.0.0-1
* New upstream release.
  - Compatible with FreeRDP 1.0 (Closes: #658363).
  - Ported to GTK3, this also fixes an incompatibility with
    GTK2 and recent Avahi with GTK3 support, which lead to
    crashes when scanning network services (Closes: #626499).
* debian/patches/libvncserver.patch:
  - Do not use convenience copy of libvncserver.
* debian/patches/g_thread_init.patch:
  - Do not use deprecated g_thread_init function.
* debian/patches/REMMINA_COMMAND_NONE.patch:
  - Removed, obsoleted by GApplication port.
* debian/clean:
  - Remove spurious files created at build-time.
* debian/compat:
  - Bump compatibility level to 9.
* debian/control:
  - Refresh build-dependencies to match new structure.
  - Drop remmina-dev package, no longer used.
  - Build packages once provided by remmina-plugins.
  - Provide remmina-common package.
  - Provide remmina-plugin-gnome package.
* debian/copyright:
  - Refresh copyright information.
* debian/docs:
  - Documentation is no longer accurate, do not ship it anymore.
* debian/remmina-dev.install:
  - Drop remmina-dev package, no longer used.
* debian/remmina-plugin-telepathy.install:
  - Adjust location for Remmina.client.
  - Disable D-BUS support for now.
* debian/rules:
  - Compile with -DWITH_APPINDICATOR=OFF.
  - Do not treat plugins as shared libraries.
* debian/watch:
  - Adjust watch file to match new download location.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Remmina - The GTK+ Remote Desktop Client
3
 
 * Copyright (C) 2009-2010 Vic Lee 
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
17
 
 * Foundation, Inc., 59 Temple Place, Suite 330, 
18
 
 * Boston, MA 02111-1307, USA.
19
 
 */
20
 
 
21
 
#include "config.h"
22
 
#include <gtk/gtk.h>
23
 
#include <glib/gstdio.h>
24
 
#include <glib/gi18n.h>
25
 
#include "remminastringarray.h"
26
 
#include "remminapublic.h"
27
 
#include "remminafile.h"
28
 
#include "remminafilemanager.h"
29
 
#include "remminafileeditor.h"
30
 
#include "remminaconnectionwindow.h"
31
 
#include "remminaabout.h"
32
 
#include "remminapref.h"
33
 
#include "remminaprefdialog.h"
34
 
#include "remminawidgetpool.h"
35
 
#include "remminapluginmanager.h"
36
 
#include "remminalog.h"
37
 
#include "remminamain.h"
38
 
 
39
 
G_DEFINE_TYPE (RemminaMain, remmina_main, GTK_TYPE_WINDOW)
40
 
 
41
 
struct _RemminaMainPriv
42
 
{
43
 
    GtkWidget *file_list;
44
 
    GtkTreeModel *file_model;
45
 
    GtkTreeModel *file_model_filter;
46
 
    GtkTreeModel *file_model_sort;
47
 
    GtkUIManager *uimanager;
48
 
    GtkWidget *toolbar;
49
 
    GtkWidget *statusbar;
50
 
 
51
 
    GtkToolItem *quick_search_separator;
52
 
    GtkToolItem *quick_search_item;
53
 
    GtkWidget *quick_search_entry;
54
 
 
55
 
    GtkTreeViewColumn *group_column;
56
 
 
57
 
    GtkActionGroup *main_group;
58
 
    GtkActionGroup *file_sensitive_group;
59
 
 
60
 
    gboolean initialized;
61
 
 
62
 
    gchar *selected_filename;
63
 
    gchar *selected_name;
64
 
    RemminaStringArray *expanded_group;
65
 
};
66
 
 
67
 
static void
68
 
remmina_main_class_init (RemminaMainClass *klass)
69
 
{
70
 
}
71
 
 
72
 
enum
73
 
{
74
 
    PROTOCOL_COLUMN,
75
 
    NAME_COLUMN,
76
 
    GROUP_COLUMN,
77
 
    SERVER_COLUMN,
78
 
    FILENAME_COLUMN,
79
 
    N_COLUMNS
80
 
};
81
 
 
82
 
static GtkTargetEntry remmina_drop_types[] = 
83
 
{
84
 
    { "text/uri-list", 0, 1 }
85
 
};
86
 
 
87
 
static void
88
 
remmina_main_save_size (RemminaMain *remminamain)
89
 
{
90
 
    if ((gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (remminamain))) & GDK_WINDOW_STATE_MAXIMIZED) == 0)
91
 
    {
92
 
        gtk_window_get_size (GTK_WINDOW (remminamain), &remmina_pref.main_width, &remmina_pref.main_height);
93
 
        remmina_pref.main_maximize = FALSE;
94
 
    }
95
 
    else
96
 
    {
97
 
        remmina_pref.main_maximize = TRUE;
98
 
    }
99
 
}
100
 
 
101
 
static void
102
 
remmina_main_save_expanded_group_func (GtkTreeView *tree_view, GtkTreePath *path, RemminaMain *remminamain)
103
 
{
104
 
    GtkTreeIter iter;
105
 
    gchar *group;
106
 
 
107
 
    gtk_tree_model_get_iter (remminamain->priv->file_model_sort, &iter, path);
108
 
    gtk_tree_model_get (remminamain->priv->file_model_sort, &iter, GROUP_COLUMN, &group, -1);
109
 
    if (group)
110
 
    {
111
 
        remmina_string_array_add (remminamain->priv->expanded_group, group);
112
 
        g_free (group);
113
 
    }
114
 
}
115
 
 
116
 
static void
117
 
remmina_main_save_expanded_group (RemminaMain *remminamain)
118
 
{
119
 
    if (GTK_IS_TREE_STORE (remminamain->priv->file_model))
120
 
    {
121
 
        if (remminamain->priv->expanded_group)
122
 
        {
123
 
            remmina_string_array_free (remminamain->priv->expanded_group);
124
 
        }
125
 
        remminamain->priv->expanded_group = remmina_string_array_new ();
126
 
        gtk_tree_view_map_expanded_rows (GTK_TREE_VIEW (remminamain->priv->file_list),
127
 
            (GtkTreeViewMappingFunc) remmina_main_save_expanded_group_func, remminamain);
128
 
    }
129
 
}
130
 
 
131
 
static gboolean
132
 
remmina_main_on_delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
133
 
{
134
 
    RemminaMain *remminamain;
135
 
 
136
 
    remminamain = REMMINA_MAIN (widget);
137
 
 
138
 
    remmina_main_save_size (remminamain);
139
 
 
140
 
    remmina_main_save_expanded_group (remminamain);
141
 
    g_free (remmina_pref.expanded_group);
142
 
    remmina_pref.expanded_group = remmina_string_array_to_string (remminamain->priv->expanded_group);
143
 
    remmina_string_array_free (remminamain->priv->expanded_group);
144
 
    remminamain->priv->expanded_group = NULL;
145
 
 
146
 
    remmina_pref_save ();
147
 
    return FALSE;
148
 
}
149
 
 
150
 
static void
151
 
remmina_main_destroy (GtkWidget *widget, gpointer data)
152
 
{
153
 
    g_free (REMMINA_MAIN (widget)->priv->selected_filename);
154
 
    g_free (REMMINA_MAIN (widget)->priv->selected_name);
155
 
    g_free (REMMINA_MAIN (widget)->priv);
156
 
}
157
 
 
158
 
static void
159
 
remmina_main_clear_selection_data (RemminaMain *remminamain)
160
 
{
161
 
    g_free (remminamain->priv->selected_filename);
162
 
    g_free (remminamain->priv->selected_name);
163
 
    remminamain->priv->selected_filename = NULL;
164
 
    remminamain->priv->selected_name = NULL;
165
 
 
166
 
    gtk_action_group_set_sensitive (remminamain->priv->file_sensitive_group, FALSE);
167
 
}
168
 
 
169
 
static gboolean
170
 
remmina_main_selection_func (
171
 
    GtkTreeSelection *selection,
172
 
    GtkTreeModel     *model,
173
 
    GtkTreePath      *path,
174
 
    gboolean          path_currently_selected,
175
 
    gpointer          user_data)
176
 
{
177
 
    RemminaMain *remminamain;
178
 
    guint context_id;
179
 
    GtkTreeIter iter;
180
 
    gchar buf[1000];
181
 
 
182
 
    remminamain = (RemminaMain*) user_data;
183
 
    if (path_currently_selected) return TRUE;
184
 
 
185
 
    if (!gtk_tree_model_get_iter (model, &iter, path)) return TRUE;
186
 
 
187
 
    remmina_main_clear_selection_data (remminamain);
188
 
 
189
 
    gtk_tree_model_get (model, &iter,
190
 
        NAME_COLUMN, &remminamain->priv->selected_name,
191
 
        FILENAME_COLUMN, &remminamain->priv->selected_filename,
192
 
        -1);
193
 
 
194
 
    context_id = gtk_statusbar_get_context_id (GTK_STATUSBAR (remminamain->priv->statusbar), "status");
195
 
    gtk_statusbar_pop (GTK_STATUSBAR (remminamain->priv->statusbar), context_id);
196
 
    if (remminamain->priv->selected_filename)
197
 
    {
198
 
        gtk_action_group_set_sensitive (remminamain->priv->file_sensitive_group, TRUE);
199
 
        g_snprintf (buf, sizeof (buf), "%s (%s)", remminamain->priv->selected_name, remminamain->priv->selected_filename);
200
 
        gtk_statusbar_push (GTK_STATUSBAR (remminamain->priv->statusbar), context_id, buf);
201
 
    }
202
 
    else
203
 
    {
204
 
        gtk_statusbar_push (GTK_STATUSBAR (remminamain->priv->statusbar), context_id, remminamain->priv->selected_name);
205
 
    }
206
 
    return TRUE;
207
 
}
208
 
 
209
 
static void
210
 
remmina_main_load_file_list_callback (gpointer data, gpointer user_data)
211
 
{
212
 
    RemminaMain *remminamain;
213
 
    GtkTreeIter iter;
214
 
    GtkListStore *store;
215
 
    RemminaFile *remminafile;
216
 
 
217
 
    remminafile = (RemminaFile*) data;
218
 
    remminamain = (RemminaMain*) user_data;
219
 
    store = GTK_LIST_STORE (remminamain->priv->file_model);
220
 
 
221
 
    gtk_list_store_append (store, &iter);
222
 
    gtk_list_store_set (store, &iter,
223
 
        PROTOCOL_COLUMN, remmina_file_get_icon_name (remminafile),
224
 
        NAME_COLUMN, remmina_file_get_string (remminafile, "name"),
225
 
        GROUP_COLUMN, remmina_file_get_string (remminafile, "group"),
226
 
        SERVER_COLUMN, remmina_file_get_string (remminafile, "server"),
227
 
        FILENAME_COLUMN, remmina_file_get_filename (remminafile),
228
 
        -1);
229
 
}
230
 
 
231
 
static gboolean
232
 
remmina_main_load_file_tree_traverse (GNode *node, GtkTreeStore *store, GtkTreeIter *parent)
233
 
{
234
 
    GtkTreeIter *iter;
235
 
    RemminaGroupData *data;
236
 
    GNode *child;
237
 
 
238
 
    iter = NULL;
239
 
    if (node->data)
240
 
    {
241
 
        data = (RemminaGroupData*)node->data;
242
 
        iter = g_new0 (GtkTreeIter, 1);
243
 
        gtk_tree_store_append (store, iter, parent);
244
 
        gtk_tree_store_set (store, iter,
245
 
            PROTOCOL_COLUMN, GTK_STOCK_DIRECTORY,
246
 
            NAME_COLUMN, data->name,
247
 
            GROUP_COLUMN, data->group,
248
 
            FILENAME_COLUMN, NULL,
249
 
            -1);
250
 
    }
251
 
    for (child = g_node_first_child (node); child; child = g_node_next_sibling (child))
252
 
    {
253
 
        remmina_main_load_file_tree_traverse (child, store, iter);
254
 
    }
255
 
    g_free (iter);
256
 
    return FALSE;
257
 
}
258
 
 
259
 
static void
260
 
remmina_main_load_file_tree_group (GtkTreeStore *store)
261
 
{
262
 
    GNode *root;
263
 
 
264
 
    root = remmina_file_manager_get_group_tree ();
265
 
    remmina_main_load_file_tree_traverse (root, store, NULL);
266
 
    remmina_file_manager_free_group_tree (root);
267
 
}
268
 
 
269
 
static void
270
 
remmina_main_expand_group_traverse (RemminaMain *remminamain, GtkTreeIter *iter)
271
 
{
272
 
    GtkTreeModel *tree;
273
 
    gboolean ret;
274
 
    gchar *group, *filename;
275
 
    GtkTreeIter child;
276
 
    GtkTreePath *path;
277
 
 
278
 
    tree = remminamain->priv->file_model_sort;
279
 
    ret = TRUE;
280
 
    while (ret)
281
 
    {
282
 
        gtk_tree_model_get (tree, iter, GROUP_COLUMN, &group, FILENAME_COLUMN, &filename, -1);
283
 
        if (filename == NULL)
284
 
        {
285
 
            if (remmina_string_array_find (remminamain->priv->expanded_group, group) >= 0)
286
 
            {
287
 
                path = gtk_tree_model_get_path (tree, iter);
288
 
                gtk_tree_view_expand_row (GTK_TREE_VIEW (remminamain->priv->file_list), path, FALSE);
289
 
                gtk_tree_path_free (path);
290
 
            }
291
 
            if (gtk_tree_model_iter_children (tree, &child, iter))
292
 
            {
293
 
                remmina_main_expand_group_traverse (remminamain, &child);
294
 
            }
295
 
        }
296
 
        g_free (group);
297
 
        g_free (filename);
298
 
 
299
 
        ret = gtk_tree_model_iter_next (tree, iter);
300
 
    }
301
 
}
302
 
 
303
 
static void
304
 
remmina_main_expand_group (RemminaMain *remminamain)
305
 
{
306
 
    GtkTreeIter iter;
307
 
 
308
 
    if (gtk_tree_model_get_iter_first (remminamain->priv->file_model_sort, &iter))
309
 
    {
310
 
        remmina_main_expand_group_traverse (remminamain, &iter);
311
 
    }
312
 
}
313
 
 
314
 
static gboolean
315
 
remmina_main_load_file_tree_find (GtkTreeModel *tree, GtkTreeIter *iter, const gchar *match_group)
316
 
{
317
 
    gboolean ret, match;
318
 
    gchar *group, *filename;
319
 
    GtkTreeIter child;
320
 
 
321
 
    match = FALSE;
322
 
    ret = TRUE;
323
 
    while (ret)
324
 
    {
325
 
        gtk_tree_model_get (tree, iter, GROUP_COLUMN, &group, FILENAME_COLUMN, &filename, -1);
326
 
        match = (filename == NULL && g_strcmp0 (group, match_group) == 0);
327
 
        g_free (group);
328
 
        g_free (filename);
329
 
        if (match) break;
330
 
        if (gtk_tree_model_iter_children (tree, &child, iter))
331
 
        {
332
 
            match = remmina_main_load_file_tree_find (tree, &child, match_group);
333
 
            if (match)
334
 
            {
335
 
                memcpy (iter, &child, sizeof (GtkTreeIter));
336
 
                break;
337
 
            }
338
 
        }
339
 
        ret = gtk_tree_model_iter_next (tree, iter);
340
 
    }
341
 
    return match;
342
 
}
343
 
 
344
 
static void
345
 
remmina_main_load_file_tree_callback (gpointer data, gpointer user_data)
346
 
{
347
 
    RemminaMain *remminamain;
348
 
    GtkTreeIter iter, child;
349
 
    GtkTreeStore *store;
350
 
    RemminaFile *remminafile;
351
 
    gboolean found;
352
 
 
353
 
    remminafile = (RemminaFile*) data;
354
 
    remminamain = (RemminaMain*) user_data;
355
 
    store = GTK_TREE_STORE (remminamain->priv->file_model);
356
 
 
357
 
    found = FALSE;
358
 
    if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
359
 
    {
360
 
        found = remmina_main_load_file_tree_find (GTK_TREE_MODEL (store), &iter,
361
 
            remmina_file_get_string (remminafile, "group"));
362
 
    }
363
 
 
364
 
    gtk_tree_store_append (store, &child, (found ? &iter : NULL));
365
 
    gtk_tree_store_set (store, &child,
366
 
        PROTOCOL_COLUMN, remmina_file_get_icon_name (remminafile),
367
 
        NAME_COLUMN, remmina_file_get_string (remminafile, "name"),
368
 
        GROUP_COLUMN, remmina_file_get_string (remminafile, "group"),
369
 
        SERVER_COLUMN, remmina_file_get_string (remminafile, "server"),
370
 
        FILENAME_COLUMN, remmina_file_get_filename (remminafile),
371
 
        -1);
372
 
}
373
 
 
374
 
static void
375
 
remmina_main_file_model_on_sort (GtkTreeSortable *sortable, RemminaMain *remminamain)
376
 
{
377
 
    gint columnid;
378
 
    GtkSortType order;
379
 
 
380
 
    gtk_tree_sortable_get_sort_column_id (sortable, &columnid, &order);
381
 
    remmina_pref.main_sort_column_id = columnid;
382
 
    remmina_pref.main_sort_order = order;
383
 
    remmina_pref_save ();
384
 
}
385
 
 
386
 
static gboolean
387
 
remmina_main_filter_visible_func (GtkTreeModel *model, GtkTreeIter *iter, RemminaMain *remminamain)
388
 
{
389
 
    gchar *text;
390
 
    gchar *protocol, *name, *group, *server, *s;
391
 
    gboolean result = TRUE;
392
 
 
393
 
    if (!remmina_pref.show_quick_search) return TRUE;
394
 
 
395
 
    text = g_ascii_strdown (gtk_entry_get_text (GTK_ENTRY (remminamain->priv->quick_search_entry)), -1);
396
 
    if (text && text[0])
397
 
    {
398
 
        gtk_tree_model_get (model, iter,
399
 
            PROTOCOL_COLUMN, &protocol,
400
 
            NAME_COLUMN, &name,
401
 
            GROUP_COLUMN, &group,
402
 
            SERVER_COLUMN, &server,
403
 
            -1);
404
 
        if (g_strcmp0 (protocol, GTK_STOCK_DIRECTORY) != 0)
405
 
        {
406
 
            s = g_ascii_strdown (name ? name : "", -1); g_free (name); name = s;
407
 
            s = g_ascii_strdown (group ? group : "", -1); g_free (group); group = s;
408
 
            s = g_ascii_strdown (server ? server : "", -1); g_free (server); server = s;
409
 
            result = (strstr (name, text) || strstr (server, text) || strstr (group, text));
410
 
        }
411
 
        g_free (protocol);
412
 
        g_free (name);
413
 
        g_free (group);
414
 
        g_free (server);
415
 
    }
416
 
    g_free (text);
417
 
    return result;
418
 
}
419
 
 
420
 
static void
421
 
remmina_main_select_file (RemminaMain *remminamain, const gchar *filename)
422
 
{
423
 
    GtkTreeIter iter;
424
 
    GtkTreePath *path;
425
 
    gchar *item_filename;
426
 
    gboolean cmp;
427
 
 
428
 
    if (!gtk_tree_model_get_iter_first (remminamain->priv->file_model_sort, &iter)) return;
429
 
 
430
 
    while (1)
431
 
    {
432
 
        gtk_tree_model_get (remminamain->priv->file_model_sort, &iter, FILENAME_COLUMN, &item_filename, -1);
433
 
        cmp = g_strcmp0 (item_filename, filename);
434
 
        g_free (item_filename);
435
 
        if (cmp == 0)
436
 
        {
437
 
            gtk_tree_selection_select_iter (
438
 
                gtk_tree_view_get_selection (GTK_TREE_VIEW (remminamain->priv->file_list)),
439
 
                &iter);
440
 
            path = gtk_tree_model_get_path (remminamain->priv->file_model_sort, &iter);
441
 
            gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (remminamain->priv->file_list),
442
 
                path, NULL, TRUE, 0.5, 0.0);
443
 
            gtk_tree_path_free (path);
444
 
            return;
445
 
        }
446
 
        if (!gtk_tree_model_iter_next (remminamain->priv->file_model_sort, &iter)) return;
447
 
    }
448
 
}
449
 
 
450
 
static void
451
 
remmina_main_load_files (RemminaMain *remminamain, gboolean refresh)
452
 
{
453
 
    GtkTreeModel *filter;
454
 
    GtkTreeModel *sort;
455
 
    gint n;
456
 
    gchar buf[200];
457
 
    guint context_id;
458
 
 
459
 
    if (refresh)
460
 
    {
461
 
        remmina_main_save_expanded_group (remminamain);
462
 
    }
463
 
 
464
 
    switch (remmina_pref.view_file_mode)
465
 
    {
466
 
 
467
 
    case REMMINA_VIEW_FILE_TREE:
468
 
        gtk_tree_view_column_set_visible (remminamain->priv->group_column, FALSE);
469
 
        remminamain->priv->file_model = GTK_TREE_MODEL (gtk_tree_store_new (N_COLUMNS,
470
 
            G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING));
471
 
        remmina_main_load_file_tree_group (GTK_TREE_STORE (remminamain->priv->file_model));
472
 
        n = remmina_file_manager_iterate (remmina_main_load_file_tree_callback, remminamain);
473
 
        break;
474
 
 
475
 
    case REMMINA_VIEW_FILE_LIST:
476
 
    default:
477
 
        gtk_tree_view_column_set_visible (remminamain->priv->group_column, TRUE);
478
 
        remminamain->priv->file_model = GTK_TREE_MODEL (gtk_list_store_new (N_COLUMNS,
479
 
            G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING));
480
 
        n = remmina_file_manager_iterate (remmina_main_load_file_list_callback, remminamain);
481
 
        break;
482
 
    }
483
 
 
484
 
    filter = gtk_tree_model_filter_new (remminamain->priv->file_model, NULL);
485
 
    gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
486
 
        (GtkTreeModelFilterVisibleFunc) remmina_main_filter_visible_func, remminamain, NULL);
487
 
    remminamain->priv->file_model_filter = filter;
488
 
 
489
 
    sort = gtk_tree_model_sort_new_with_model (filter);
490
 
    remminamain->priv->file_model_sort = sort;
491
 
 
492
 
    gtk_tree_view_set_model (GTK_TREE_VIEW (remminamain->priv->file_list), sort);
493
 
    gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort),
494
 
        remmina_pref.main_sort_column_id, remmina_pref.main_sort_order);
495
 
    g_signal_connect (G_OBJECT (sort), "sort-column-changed",
496
 
        G_CALLBACK (remmina_main_file_model_on_sort), remminamain);
497
 
    remmina_main_expand_group (remminamain);
498
 
 
499
 
    if (remminamain->priv->selected_filename)
500
 
    {
501
 
        remmina_main_select_file (remminamain, remminamain->priv->selected_filename);
502
 
    }
503
 
 
504
 
    g_snprintf (buf, 200, ngettext("Total %i item.", "Total %i items.", n), n);
505
 
    context_id = gtk_statusbar_get_context_id (GTK_STATUSBAR (remminamain->priv->statusbar), "status");
506
 
    gtk_statusbar_pop (GTK_STATUSBAR (remminamain->priv->statusbar), context_id);
507
 
    gtk_statusbar_push (GTK_STATUSBAR (remminamain->priv->statusbar), context_id, buf);
508
 
}
509
 
 
510
 
static void
511
 
remmina_main_action_connection_connect (GtkAction *action, RemminaMain *remminamain)
512
 
{
513
 
    remmina_connection_window_open_from_filename (remminamain->priv->selected_filename);
514
 
}
515
 
 
516
 
static void
517
 
remmina_main_file_editor_destroy (GtkWidget *widget, RemminaMain *remminamain)
518
 
{
519
 
    if (GTK_IS_WIDGET (remminamain))
520
 
    {
521
 
        remmina_main_load_files (remminamain, TRUE);
522
 
    }
523
 
}
524
 
 
525
 
static void
526
 
remmina_main_action_connection_new (GtkAction *action, RemminaMain *remminamain)
527
 
{
528
 
    GtkWidget *widget;
529
 
 
530
 
    widget = remmina_file_editor_new ();
531
 
    g_signal_connect (G_OBJECT (widget), "destroy", G_CALLBACK (remmina_main_file_editor_destroy), remminamain);
532
 
    gtk_widget_show (widget);
533
 
}
534
 
 
535
 
static void
536
 
remmina_main_action_connection_copy (GtkAction *action, RemminaMain *remminamain)
537
 
{
538
 
    GtkWidget *widget;
539
 
 
540
 
    if (remminamain->priv->selected_filename == NULL) return;
541
 
 
542
 
    widget = remmina_file_editor_new_copy (remminamain->priv->selected_filename);
543
 
    if (widget)
544
 
    {
545
 
        g_signal_connect (G_OBJECT (widget), "destroy", G_CALLBACK (remmina_main_file_editor_destroy), remminamain);
546
 
        gtk_widget_show (widget);
547
 
    }
548
 
}
549
 
 
550
 
static void
551
 
remmina_main_action_connection_edit (GtkAction *action, RemminaMain *remminamain)
552
 
{
553
 
    GtkWidget *widget;
554
 
 
555
 
    if (remminamain->priv->selected_filename == NULL) return;
556
 
 
557
 
    widget = remmina_file_editor_new_from_filename (remminamain->priv->selected_filename);
558
 
    if (widget)
559
 
    {
560
 
        g_signal_connect (G_OBJECT (widget), "destroy", G_CALLBACK (remmina_main_file_editor_destroy), remminamain);
561
 
        gtk_widget_show (widget);
562
 
    }
563
 
}
564
 
 
565
 
static void
566
 
remmina_main_action_connection_delete (GtkAction *action, RemminaMain *remminamain)
567
 
{
568
 
    GtkWidget *dialog;
569
 
 
570
 
    if (remminamain->priv->selected_filename == NULL) return;
571
 
 
572
 
    dialog = gtk_message_dialog_new (GTK_WINDOW (remminamain),
573
 
        GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
574
 
        _("Are you sure to delete '%s'"), remminamain->priv->selected_name);
575
 
    if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES)
576
 
    {
577
 
        g_unlink (remminamain->priv->selected_filename);
578
 
        remmina_main_load_files (remminamain, TRUE);
579
 
    }
580
 
    gtk_widget_destroy (dialog);
581
 
    remmina_main_clear_selection_data (remminamain);
582
 
}
583
 
 
584
 
static void
585
 
remmina_main_action_edit_preferences (GtkAction *action, RemminaMain *remminamain)
586
 
{
587
 
    GtkWidget *widget;
588
 
 
589
 
    widget = remmina_pref_dialog_new (0);
590
 
    gtk_widget_show (widget);
591
 
}
592
 
 
593
 
static void
594
 
remmina_main_action_connection_close (GtkAction *action, RemminaMain *remminamain)
595
 
{
596
 
    gtk_widget_destroy (GTK_WIDGET (remminamain));
597
 
}
598
 
 
599
 
static void
600
 
remmina_main_action_view_toolbar (GtkToggleAction *action, RemminaMain *remminamain)
601
 
{
602
 
    gboolean toggled;
603
 
 
604
 
    toggled = gtk_toggle_action_get_active (action);
605
 
    if (toggled)
606
 
    {
607
 
        gtk_widget_show (remminamain->priv->toolbar);
608
 
    }
609
 
    else
610
 
    {
611
 
        gtk_widget_hide (remminamain->priv->toolbar);
612
 
    }
613
 
    if (remminamain->priv->initialized)
614
 
    {
615
 
        remmina_pref.hide_toolbar = !toggled;
616
 
        remmina_pref_save ();
617
 
    }
618
 
}
619
 
 
620
 
static void
621
 
remmina_main_action_view_quick_search (GtkToggleAction *action, RemminaMain *remminamain)
622
 
{
623
 
    gboolean toggled;
624
 
 
625
 
    toggled = gtk_toggle_action_get_active (action);
626
 
    if (toggled)
627
 
    {
628
 
        gtk_entry_set_text (GTK_ENTRY (remminamain->priv->quick_search_entry), "");
629
 
        gtk_widget_show (GTK_WIDGET (remminamain->priv->quick_search_separator));
630
 
        gtk_widget_show (GTK_WIDGET (remminamain->priv->quick_search_item));
631
 
        gtk_widget_grab_focus (remminamain->priv->quick_search_entry);
632
 
    }
633
 
    else
634
 
    {
635
 
        gtk_widget_hide (GTK_WIDGET (remminamain->priv->quick_search_separator));
636
 
        gtk_widget_hide (GTK_WIDGET (remminamain->priv->quick_search_item));
637
 
    }
638
 
    if (remminamain->priv->initialized)
639
 
    {
640
 
        remmina_pref.show_quick_search = toggled;
641
 
        remmina_pref_save ();
642
 
 
643
 
        if (!toggled)
644
 
        {
645
 
            gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (remminamain->priv->file_model_filter));
646
 
            gtk_tree_view_expand_all (GTK_TREE_VIEW (remminamain->priv->file_list));
647
 
        }
648
 
    }
649
 
}
650
 
 
651
 
static void
652
 
remmina_main_action_view_statusbar (GtkToggleAction *action, RemminaMain *remminamain)
653
 
{
654
 
    gboolean toggled;
655
 
 
656
 
    toggled = gtk_toggle_action_get_active (action);
657
 
    if (toggled)
658
 
    {
659
 
        gtk_widget_show (remminamain->priv->statusbar);
660
 
    }
661
 
    else
662
 
    {
663
 
        gtk_widget_hide (remminamain->priv->statusbar);
664
 
    }
665
 
    if (remminamain->priv->initialized)
666
 
    {
667
 
        remmina_pref.hide_statusbar = !toggled;
668
 
        remmina_pref_save ();
669
 
    }
670
 
}
671
 
 
672
 
static void
673
 
remmina_main_action_view_small_toolbutton (GtkToggleAction *action, RemminaMain *remminamain)
674
 
{
675
 
    gboolean toggled;
676
 
 
677
 
    toggled = gtk_toggle_action_get_active (action);
678
 
    if (toggled)
679
 
    {
680
 
        gtk_toolbar_set_icon_size (GTK_TOOLBAR (remminamain->priv->toolbar), GTK_ICON_SIZE_MENU);
681
 
    }
682
 
    else
683
 
    {
684
 
        gtk_toolbar_unset_icon_size (GTK_TOOLBAR (remminamain->priv->toolbar));
685
 
    }
686
 
    if (remminamain->priv->initialized)
687
 
    {
688
 
        remmina_pref.small_toolbutton = toggled;
689
 
        remmina_pref_save ();
690
 
    }
691
 
}
692
 
 
693
 
static void
694
 
remmina_main_action_view_file_mode (GtkRadioAction *action, GtkRadioAction *current, RemminaMain *remminamain)
695
 
{
696
 
    remmina_pref.view_file_mode = gtk_radio_action_get_current_value (action);
697
 
    remmina_pref_save ();
698
 
    remmina_main_load_files (remminamain, TRUE);
699
 
}
700
 
 
701
 
static void
702
 
remmina_main_import_file_list (RemminaMain *remminamain, GSList *files)
703
 
{
704
 
    GtkWidget *dlg;
705
 
    GSList *element;
706
 
    gchar *path;
707
 
    RemminaFilePlugin *plugin;
708
 
    GString *err;
709
 
    RemminaFile *remminafile = NULL;
710
 
    gboolean imported;
711
 
 
712
 
    err = g_string_new (NULL);
713
 
    imported = FALSE;
714
 
    for (element = files; element; element = element->next)
715
 
    {
716
 
        path = (gchar*) element->data;
717
 
        plugin = remmina_plugin_manager_get_import_file_handler (path);
718
 
        if (plugin && (remminafile = plugin->import_func (path)) != NULL &&
719
 
            remmina_file_get_string (remminafile, "name"))
720
 
        {
721
 
            remmina_file_generate_filename (remminafile);
722
 
            remmina_file_save_all (remminafile);
723
 
            imported = TRUE;
724
 
        }
725
 
        else
726
 
        {
727
 
            g_string_append (err, path);
728
 
            g_string_append_c (err, '\n');
729
 
        }
730
 
        if (remminafile)
731
 
        {
732
 
            remmina_file_free (remminafile);
733
 
            remminafile = NULL;
734
 
        }
735
 
        g_free (path);
736
 
    }
737
 
    g_slist_free (files);
738
 
    if (err->len > 0)
739
 
    {
740
 
        dlg = gtk_message_dialog_new (GTK_WINDOW (remminamain),
741
 
            GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
742
 
            _("Unable to import:\n%s"), err->str);
743
 
        g_signal_connect (G_OBJECT (dlg), "response", G_CALLBACK (gtk_widget_destroy), NULL);
744
 
        gtk_widget_show (dlg);
745
 
    }
746
 
    g_string_free (err, TRUE);
747
 
    if (imported)
748
 
    {
749
 
        remmina_main_load_files (remminamain, TRUE);
750
 
    }
751
 
}
752
 
 
753
 
static void
754
 
remmina_main_action_tools_import_on_response (GtkDialog *dialog, gint response_id, RemminaMain *remminamain)
755
 
{
756
 
    GSList *files;
757
 
 
758
 
    if (response_id == GTK_RESPONSE_ACCEPT)
759
 
    {
760
 
        files = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dialog));
761
 
        remmina_main_import_file_list (remminamain, files);
762
 
    }
763
 
    gtk_widget_destroy (GTK_WIDGET (dialog));
764
 
}
765
 
 
766
 
static void
767
 
remmina_main_action_tools_import (GtkAction *action, RemminaMain *remminamain)
768
 
{
769
 
    GtkWidget *dialog;
770
 
 
771
 
    dialog = gtk_file_chooser_dialog_new (_("Import"), GTK_WINDOW (remminamain),
772
 
        GTK_FILE_CHOOSER_ACTION_OPEN,
773
 
        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
774
 
        NULL);
775
 
    gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
776
 
    g_signal_connect (G_OBJECT (dialog), "response",
777
 
        G_CALLBACK (remmina_main_action_tools_import_on_response), remminamain);
778
 
    gtk_widget_show (dialog);
779
 
}
780
 
 
781
 
static void
782
 
remmina_main_action_tools_export (GtkAction *action, RemminaMain *remminamain)
783
 
{
784
 
    RemminaFilePlugin *plugin;
785
 
    RemminaFile *remminafile;
786
 
    GtkWidget *dialog;
787
 
 
788
 
    if (remminamain->priv->selected_filename == NULL) return;
789
 
 
790
 
    remminafile = remmina_file_load (remminamain->priv->selected_filename);
791
 
    if (remminafile == NULL) return;
792
 
    plugin = remmina_plugin_manager_get_export_file_handler (remminafile);
793
 
    if (plugin)
794
 
    {
795
 
        dialog = gtk_file_chooser_dialog_new (plugin->export_hints, GTK_WINDOW (remminamain),
796
 
            GTK_FILE_CHOOSER_ACTION_SAVE,
797
 
            GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
798
 
            NULL);
799
 
        if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
800
 
        {
801
 
            plugin->export_func (remminafile, gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)));
802
 
        }
803
 
        gtk_widget_destroy (dialog);
804
 
    }
805
 
    else
806
 
    {
807
 
        dialog = gtk_message_dialog_new (GTK_WINDOW (remminamain),
808
 
            GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
809
 
            _("This protocol does not support exporting."));
810
 
        g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (gtk_widget_destroy), NULL);
811
 
        gtk_widget_show (dialog);
812
 
    }
813
 
    remmina_file_free (remminafile);
814
 
}
815
 
 
816
 
static void
817
 
remmina_main_action_tools_plugins (GtkAction *action, RemminaMain *remminamain)
818
 
{
819
 
    remmina_plugin_manager_show (GTK_WINDOW (remminamain));
820
 
}
821
 
 
822
 
static void
823
 
remmina_main_action_tools_addition (GtkAction *action, RemminaMain *remminamain)
824
 
{
825
 
    RemminaToolPlugin *plugin;
826
 
 
827
 
    plugin = (RemminaToolPlugin *) remmina_plugin_manager_get_plugin (REMMINA_PLUGIN_TYPE_TOOL, gtk_action_get_name (action));
828
 
    if (plugin)
829
 
    {
830
 
        plugin->exec_func();
831
 
    }
832
 
}
833
 
 
834
 
static void
835
 
remmina_main_action_help_homepage (GtkAction *action, RemminaMain *remminamain)
836
 
{
837
 
    g_app_info_launch_default_for_uri ("http://remmina.sourceforge.net", NULL, NULL);
838
 
}
839
 
 
840
 
static void
841
 
remmina_main_action_help_wiki (GtkAction *action, RemminaMain *remminamain)
842
 
{
843
 
    g_app_info_launch_default_for_uri ("http://sourceforge.net/apps/mediawiki/remmina/", NULL, NULL);
844
 
}
845
 
 
846
 
static void
847
 
remmina_main_action_help_debug (GtkAction *action, RemminaMain *remminamain)
848
 
{
849
 
    remmina_log_start ();
850
 
}
851
 
 
852
 
static void
853
 
remmina_main_action_help_about (GtkAction *action, RemminaMain *remminamain)
854
 
{
855
 
    remmina_about_open (GTK_WINDOW (remminamain));
856
 
}
857
 
 
858
 
static const gchar *remmina_main_ui_xml = 
859
 
"<ui>"
860
 
"  <menubar name='MenuBar'>"
861
 
"    <menu name='ConnectionMenu' action='Connection'>"
862
 
"      <menuitem name='ConnectionConnectMenu' action='ConnectionConnect'/>"
863
 
"      <separator/>"
864
 
"      <menuitem name='ConnectionNewMenu' action='ConnectionNew'/>"
865
 
"      <menuitem name='ConnectionCopyMenu' action='ConnectionCopy'/>"
866
 
"      <menuitem name='ConnectionEditMenu' action='ConnectionEdit'/>"
867
 
"      <menuitem name='ConnectionDeleteMenu' action='ConnectionDelete'/>"
868
 
"      <separator/>"
869
 
"      <menuitem name='ConnectionCloseMenu' action='ConnectionClose'/>"
870
 
"    </menu>"
871
 
"    <menu name='EditMenu' action='Edit'>"
872
 
"      <menuitem name='EditPreferencesMenu' action='EditPreferences'/>"
873
 
"    </menu>"
874
 
"    <menu name='ViewMenu' action='View'>"
875
 
"      <menuitem name='ViewToolbarMenu' action='ViewToolbar'/>"
876
 
"      <menuitem name='ViewStatusbarMenu' action='ViewStatusbar'/>"
877
 
"      <menuitem name='ViewQuickSearchMenu' action='ViewQuickSearch'/>"
878
 
"      <separator/>"
879
 
"      <menuitem name='ViewSmallToolbuttonMenu' action='ViewSmallToolbutton'/>"
880
 
"      <separator/>"
881
 
"      <menuitem name='ViewFileListMenu' action='ViewFileList'/>"
882
 
"      <menuitem name='ViewFileTreeMenu' action='ViewFileTree'/>"
883
 
"    </menu>"
884
 
"    <menu name='ToolsMenu' action='Tools'>"
885
 
"      <menuitem name='ToolsImportMenu' action='ToolsImport'/>"
886
 
"      <menuitem name='ToolsExportMenu' action='ToolsExport'/>"
887
 
"      <placeholder name='ToolsAdditions'/>"
888
 
"      <separator/>"
889
 
"      <menuitem name='ToolsPluginsMenu' action='ToolsPlugins'/>"
890
 
"    </menu>"
891
 
"    <menu name='HelpMenu' action='Help'>"
892
 
"      <menuitem name='HelpHomepageMenu' action='HelpHomepage'/>"
893
 
"      <menuitem name='HelpWikiMenu' action='HelpWiki'/>"
894
 
"      <menuitem name='HelpDebugMenu' action='HelpDebug'/>"
895
 
"      <separator/>"
896
 
"      <menuitem name='HelpAboutMenu' action='HelpAbout'/>"
897
 
"    </menu>"
898
 
"  </menubar>"
899
 
"  <toolbar name='ToolBar'>"
900
 
"    <toolitem action='ConnectionConnect'/>"
901
 
"    <separator/>"
902
 
"    <toolitem action='ConnectionNew'/>"
903
 
"    <toolitem action='ConnectionCopy'/>"
904
 
"    <toolitem action='ConnectionEdit'/>"
905
 
"    <toolitem action='ConnectionDelete'/>"
906
 
"    <separator/>"
907
 
"    <toolitem action='EditPreferences'/>"
908
 
"  </toolbar>"
909
 
"  <popup name='PopupMenu'>"
910
 
"    <menuitem action='ConnectionConnect'/>"
911
 
"    <separator/>"
912
 
"    <menuitem action='ConnectionCopy'/>"
913
 
"    <menuitem action='ConnectionEdit'/>"
914
 
"    <menuitem action='ConnectionDelete'/>"
915
 
"  </popup>"
916
 
"</ui>";
917
 
 
918
 
static const GtkActionEntry remmina_main_ui_menu_entries[] =
919
 
{
920
 
    { "Connection", NULL, N_("_Connection") },
921
 
    { "Edit", NULL, N_("_Edit") },
922
 
    { "View", NULL, N_("_View") },
923
 
    { "Tools", NULL, N_("_Tools") },
924
 
    { "Help", NULL, N_("_Help") },
925
 
 
926
 
    { "ConnectionNew", GTK_STOCK_NEW, NULL, "<control>N",
927
 
        N_("Create a new remote desktop file"),
928
 
        G_CALLBACK (remmina_main_action_connection_new) },
929
 
 
930
 
    { "EditPreferences", GTK_STOCK_PREFERENCES, NULL, "<control>P",
931
 
        N_("Open the preferences dialog"),
932
 
        G_CALLBACK (remmina_main_action_edit_preferences) },
933
 
 
934
 
    { "ConnectionClose", GTK_STOCK_CLOSE, NULL, "<control>X",
935
 
        NULL,
936
 
        G_CALLBACK (remmina_main_action_connection_close) },
937
 
 
938
 
    { "ToolsImport", NULL, N_("Import"), NULL,
939
 
        NULL,
940
 
        G_CALLBACK (remmina_main_action_tools_import) },
941
 
 
942
 
    { "ToolsPlugins", NULL, N_("Plugins"), NULL,
943
 
        NULL,
944
 
        G_CALLBACK (remmina_main_action_tools_plugins) },
945
 
 
946
 
    { "HelpHomepage", NULL, N_("Homepage"), NULL,
947
 
        NULL,
948
 
        G_CALLBACK (remmina_main_action_help_homepage) },
949
 
 
950
 
    { "HelpWiki", NULL, N_("Online Wiki"), NULL,
951
 
        NULL,
952
 
        G_CALLBACK (remmina_main_action_help_wiki) },
953
 
 
954
 
    { "HelpDebug", NULL, N_("Debug Window"), NULL,
955
 
        NULL,
956
 
        G_CALLBACK (remmina_main_action_help_debug) },
957
 
 
958
 
    { "HelpAbout", GTK_STOCK_ABOUT, NULL, NULL,
959
 
        NULL,
960
 
        G_CALLBACK (remmina_main_action_help_about) }
961
 
};
962
 
 
963
 
static const GtkActionEntry remmina_main_ui_file_sensitive_menu_entries[] =
964
 
{
965
 
    { "ConnectionConnect", GTK_STOCK_CONNECT, NULL, "<control>O",
966
 
        N_("Open the connection to the selected remote desktop file"),
967
 
        G_CALLBACK (remmina_main_action_connection_connect) },
968
 
 
969
 
    { "ConnectionCopy", GTK_STOCK_COPY, NULL, "<control>C",
970
 
        N_("Create a copy of the selected remote desktop file"),
971
 
        G_CALLBACK (remmina_main_action_connection_copy) },
972
 
 
973
 
    { "ConnectionEdit", GTK_STOCK_EDIT, NULL, "<control>E",
974
 
        N_("Edit the selected remote desktop file"),
975
 
        G_CALLBACK (remmina_main_action_connection_edit) },
976
 
 
977
 
    { "ConnectionDelete", GTK_STOCK_DELETE, NULL, "<control>D",
978
 
        N_("Delete the selected remote desktop file"),
979
 
        G_CALLBACK (remmina_main_action_connection_delete) },
980
 
 
981
 
    { "ToolsExport", NULL, N_("Export"), NULL,
982
 
        NULL,
983
 
        G_CALLBACK (remmina_main_action_tools_export) }
984
 
};
985
 
 
986
 
static const GtkToggleActionEntry remmina_main_ui_toggle_menu_entries[] =
987
 
{
988
 
    { "ViewToolbar", NULL, N_("Toolbar"), NULL, NULL,
989
 
        G_CALLBACK (remmina_main_action_view_toolbar), TRUE },
990
 
 
991
 
    { "ViewStatusbar", NULL, N_("Statusbar"), NULL, NULL,
992
 
        G_CALLBACK (remmina_main_action_view_statusbar), TRUE },
993
 
 
994
 
    { "ViewQuickSearch", NULL, N_("Quick Search"), NULL, NULL,
995
 
        G_CALLBACK (remmina_main_action_view_quick_search), FALSE },
996
 
 
997
 
    { "ViewSmallToolbutton", NULL, N_("Small Toolbar Buttons"), NULL, NULL,
998
 
        G_CALLBACK (remmina_main_action_view_small_toolbutton), FALSE }
999
 
};
1000
 
 
1001
 
static const GtkRadioActionEntry remmina_main_ui_view_file_mode_entries[] =
1002
 
{
1003
 
    { "ViewFileList", NULL, N_("List View"), NULL, NULL, REMMINA_VIEW_FILE_LIST },
1004
 
    { "ViewFileTree", NULL, N_("Tree View"), NULL, NULL, REMMINA_VIEW_FILE_TREE }
1005
 
};
1006
 
 
1007
 
static gboolean
1008
 
remmina_main_file_list_on_button_press (GtkWidget *widget, GdkEventButton *event, RemminaMain *remminamain)
1009
 
{
1010
 
    GtkWidget *popup;
1011
 
 
1012
 
    if (event->button == 3)
1013
 
    {
1014
 
        popup = gtk_ui_manager_get_widget (remminamain->priv->uimanager, "/PopupMenu");
1015
 
        if (popup)
1016
 
        {
1017
 
            gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, NULL, event->button, event->time);
1018
 
        }
1019
 
    }
1020
 
    else if (event->type == GDK_2BUTTON_PRESS && remminamain->priv->selected_filename)
1021
 
    {
1022
 
        switch (remmina_pref.default_action)
1023
 
        {
1024
 
        case REMMINA_ACTION_EDIT:
1025
 
            remmina_main_action_connection_edit (NULL, remminamain);
1026
 
            break;
1027
 
        case REMMINA_ACTION_CONNECT:
1028
 
        default:
1029
 
            remmina_main_action_connection_connect (NULL, remminamain);
1030
 
            break;
1031
 
        }
1032
 
    }
1033
 
    return FALSE;
1034
 
}
1035
 
 
1036
 
static void
1037
 
remmina_main_quick_search_on_icon_press (GtkEntry *entry,
1038
 
    GtkEntryIconPosition icon_pos,
1039
 
    GdkEvent *event,
1040
 
    RemminaMain *remminamain)
1041
 
{
1042
 
    if (icon_pos == GTK_ENTRY_ICON_SECONDARY)
1043
 
    {
1044
 
        gtk_entry_set_text (entry, "");
1045
 
    }
1046
 
}
1047
 
 
1048
 
static void
1049
 
remmina_main_quick_search_on_changed (GtkEditable *editable, RemminaMain *remminamain)
1050
 
{
1051
 
    gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (remminamain->priv->file_model_filter));
1052
 
    gtk_tree_view_expand_all (GTK_TREE_VIEW (remminamain->priv->file_list));
1053
 
}
1054
 
 
1055
 
static void
1056
 
remmina_main_create_quick_search (RemminaMain *remminamain)
1057
 
{
1058
 
    GtkWidget *widget;
1059
 
    GValue val = { 0 };
1060
 
 
1061
 
    remminamain->priv->quick_search_separator = gtk_separator_tool_item_new ();
1062
 
    gtk_toolbar_insert (GTK_TOOLBAR (remminamain->priv->toolbar), remminamain->priv->quick_search_separator, -1);
1063
 
 
1064
 
    remminamain->priv->quick_search_item = gtk_tool_item_new ();
1065
 
    gtk_toolbar_insert (GTK_TOOLBAR (remminamain->priv->toolbar), remminamain->priv->quick_search_item, -1);
1066
 
 
1067
 
    widget = gtk_entry_new ();
1068
 
    gtk_widget_show (widget);
1069
 
    gtk_entry_set_icon_from_stock (GTK_ENTRY (widget), GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_FIND);
1070
 
    gtk_entry_set_icon_from_stock (GTK_ENTRY (widget), GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1071
 
    gtk_entry_set_width_chars (GTK_ENTRY (widget), 25);
1072
 
    gtk_container_add (GTK_CONTAINER (remminamain->priv->quick_search_item), widget);
1073
 
 
1074
 
    g_value_init (&val, G_TYPE_BOOLEAN);
1075
 
    g_value_set_boolean (&val, FALSE);
1076
 
    g_object_set_property (G_OBJECT (widget), "primary-icon-activatable", &val);
1077
 
    g_value_unset (&val);
1078
 
 
1079
 
    g_signal_connect (G_OBJECT (widget), "icon-press", G_CALLBACK (remmina_main_quick_search_on_icon_press), remminamain);
1080
 
    g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (remmina_main_quick_search_on_changed), remminamain);
1081
 
 
1082
 
    remminamain->priv->quick_search_entry = widget;
1083
 
}
1084
 
 
1085
 
static void
1086
 
remmina_main_on_drag_data_received (RemminaMain *remminamain, GdkDragContext *drag_context, gint x, gint y,
1087
 
    GtkSelectionData *data, guint info, guint time, gpointer user_data)
1088
 
{
1089
 
    gchar **uris;
1090
 
    GSList *files = NULL;
1091
 
    gint i;
1092
 
 
1093
 
    uris = g_uri_list_extract_uris ((gchar *) data->data);
1094
 
    for (i = 0; uris[i]; i++)
1095
 
    {
1096
 
        if (strncmp (uris[i], "file://", 7) != 0) continue;
1097
 
        files = g_slist_append (files, g_strdup (uris[i] + 7));
1098
 
    }
1099
 
    g_strfreev (uris);
1100
 
    remmina_main_import_file_list (remminamain, files);
1101
 
}
1102
 
 
1103
 
static gboolean
1104
 
remmina_main_add_tool_plugin (gchar *name, RemminaPlugin *plugin, gpointer data)
1105
 
{
1106
 
    RemminaMain *remminamain = REMMINA_MAIN (data);
1107
 
    guint merge_id;
1108
 
    GtkAction *action;
1109
 
 
1110
 
    merge_id = gtk_ui_manager_new_merge_id (remminamain->priv->uimanager);
1111
 
    action = gtk_action_new (name, plugin->description, NULL, NULL);
1112
 
    gtk_action_group_add_action (remminamain->priv->main_group, action);
1113
 
    g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (remmina_main_action_tools_addition), remminamain);
1114
 
    g_object_unref (action);
1115
 
 
1116
 
    gtk_ui_manager_add_ui (remminamain->priv->uimanager, merge_id, "/MenuBar/ToolsMenu/ToolsAdditions",
1117
 
        name, name, GTK_UI_MANAGER_MENUITEM, FALSE);
1118
 
 
1119
 
    return FALSE;
1120
 
}
1121
 
 
1122
 
static gboolean
1123
 
remmina_main_on_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer user_data)
1124
 
{
1125
 
    GdkScreen *screen;
1126
 
 
1127
 
    screen = gdk_screen_get_default ();
1128
 
    if (remmina_pref.minimize_to_tray &&
1129
 
        (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) != 0 &&
1130
 
        (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) != 0 &&
1131
 
        remmina_public_get_current_workspace (screen) ==
1132
 
        remmina_public_get_window_workspace (GTK_WINDOW (widget)) &&
1133
 
        gdk_screen_get_number (screen) ==
1134
 
        gdk_screen_get_number (gtk_widget_get_screen (widget))
1135
 
    )
1136
 
    {
1137
 
        gtk_widget_hide (widget);
1138
 
        return TRUE;
1139
 
    }
1140
 
    return FALSE;
1141
 
}
1142
 
 
1143
 
static void
1144
 
remmina_main_init (RemminaMain *remminamain)
1145
 
{
1146
 
    RemminaMainPriv *priv;
1147
 
    GtkWidget *vbox;
1148
 
    GtkWidget *menubar;
1149
 
    GtkUIManager *uimanager;
1150
 
    GtkActionGroup *action_group;
1151
 
    GtkWidget *scrolledwindow;
1152
 
    GtkWidget *tree;
1153
 
    GtkCellRenderer *renderer;
1154
 
    GtkTreeViewColumn *column;
1155
 
    GError *error;
1156
 
 
1157
 
    priv = g_new0 (RemminaMainPriv, 1);
1158
 
    remminamain->priv = priv;
1159
 
 
1160
 
    remminamain->priv->expanded_group = remmina_string_array_new_from_string (remmina_pref.expanded_group);
1161
 
 
1162
 
    /* Create main window */
1163
 
    g_signal_connect (G_OBJECT (remminamain), "delete-event", G_CALLBACK (remmina_main_on_delete_event), NULL);
1164
 
    g_signal_connect (G_OBJECT (remminamain), "destroy", G_CALLBACK (remmina_main_destroy), NULL);
1165
 
    g_signal_connect (G_OBJECT (remminamain), "window-state-event", G_CALLBACK (remmina_main_on_window_state_event), NULL);
1166
 
    gtk_container_set_border_width (GTK_CONTAINER (remminamain), 0);
1167
 
    gtk_window_set_title (GTK_WINDOW (remminamain), _("Remmina Remote Desktop Client"));
1168
 
    gtk_window_set_default_size (GTK_WINDOW (remminamain), remmina_pref.main_width, remmina_pref.main_height);
1169
 
    gtk_window_set_position (GTK_WINDOW (remminamain), GTK_WIN_POS_CENTER);
1170
 
    if (remmina_pref.main_maximize)
1171
 
    {
1172
 
        gtk_window_maximize (GTK_WINDOW (remminamain));
1173
 
    }
1174
 
 
1175
 
    /* Create the main container */
1176
 
    vbox = gtk_vbox_new (FALSE, 0);
1177
 
    gtk_container_add (GTK_CONTAINER (remminamain), vbox);
1178
 
    gtk_widget_show (vbox);
1179
 
 
1180
 
    /* Create the menubar and toolbar */
1181
 
    uimanager = gtk_ui_manager_new ();
1182
 
    priv->uimanager = uimanager;
1183
 
 
1184
 
    action_group = gtk_action_group_new ("RemminaMainActions");
1185
 
    gtk_action_group_set_translation_domain (action_group, NULL);
1186
 
    gtk_action_group_add_actions (action_group, remmina_main_ui_menu_entries,
1187
 
        G_N_ELEMENTS (remmina_main_ui_menu_entries), remminamain);
1188
 
    gtk_action_group_add_toggle_actions (action_group, remmina_main_ui_toggle_menu_entries,
1189
 
        G_N_ELEMENTS (remmina_main_ui_toggle_menu_entries), remminamain);
1190
 
    gtk_action_group_add_radio_actions (action_group, remmina_main_ui_view_file_mode_entries,
1191
 
        G_N_ELEMENTS (remmina_main_ui_view_file_mode_entries),
1192
 
        remmina_pref.view_file_mode, G_CALLBACK (remmina_main_action_view_file_mode), remminamain);
1193
 
 
1194
 
    gtk_ui_manager_insert_action_group (uimanager, action_group, 0);
1195
 
    g_object_unref (action_group);
1196
 
    priv->main_group = action_group;
1197
 
 
1198
 
    action_group = gtk_action_group_new ("RemminaMainFileSensitiveActions");
1199
 
    gtk_action_group_set_translation_domain (action_group, NULL);
1200
 
    gtk_action_group_add_actions (action_group, remmina_main_ui_file_sensitive_menu_entries,
1201
 
        G_N_ELEMENTS (remmina_main_ui_file_sensitive_menu_entries), remminamain);
1202
 
 
1203
 
    gtk_ui_manager_insert_action_group (uimanager, action_group, 0);
1204
 
    g_object_unref (action_group);
1205
 
    priv->file_sensitive_group = action_group;
1206
 
 
1207
 
    error = NULL;
1208
 
    gtk_ui_manager_add_ui_from_string (uimanager, remmina_main_ui_xml, -1, &error);
1209
 
    if (error)
1210
 
    {
1211
 
        g_message ("building menus failed: %s", error->message);
1212
 
        g_error_free (error);
1213
 
    }
1214
 
 
1215
 
    remmina_plugin_manager_for_each_plugin (REMMINA_PLUGIN_TYPE_TOOL, remmina_main_add_tool_plugin, remminamain);
1216
 
 
1217
 
    menubar = gtk_ui_manager_get_widget (uimanager, "/MenuBar");
1218
 
    gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
1219
 
 
1220
 
    priv->toolbar = gtk_ui_manager_get_widget (uimanager, "/ToolBar");
1221
 
    gtk_box_pack_start (GTK_BOX (vbox), priv->toolbar, FALSE, FALSE, 0);
1222
 
 
1223
 
    remmina_main_create_quick_search (remminamain);
1224
 
 
1225
 
    gtk_window_add_accel_group (GTK_WINDOW (remminamain), gtk_ui_manager_get_accel_group (uimanager));
1226
 
 
1227
 
    gtk_action_group_set_sensitive (priv->file_sensitive_group, FALSE);
1228
 
 
1229
 
    /* Create the scrolled window for the file list */
1230
 
    scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
1231
 
    gtk_widget_show (scrolledwindow);
1232
 
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
1233
 
        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1234
 
    gtk_box_pack_start (GTK_BOX (vbox), scrolledwindow, TRUE, TRUE, 0);
1235
 
 
1236
 
    /* Create the remmina file list */
1237
 
    tree = gtk_tree_view_new ();
1238
 
 
1239
 
    column = gtk_tree_view_column_new ();
1240
 
    gtk_tree_view_column_set_title (column, _("Name"));
1241
 
    gtk_tree_view_column_set_resizable (column, TRUE);
1242
 
    gtk_tree_view_column_set_sort_column_id (column, NAME_COLUMN);
1243
 
    renderer = gtk_cell_renderer_pixbuf_new ();
1244
 
    gtk_tree_view_column_pack_start (column, renderer, FALSE);
1245
 
    gtk_tree_view_column_add_attribute (column, renderer, "icon-name", PROTOCOL_COLUMN);
1246
 
    g_object_set (G_OBJECT (renderer), "stock-size", GTK_ICON_SIZE_LARGE_TOOLBAR, NULL);
1247
 
    renderer = gtk_cell_renderer_text_new ();
1248
 
    gtk_tree_view_column_pack_start (column, renderer, FALSE);
1249
 
    gtk_tree_view_column_add_attribute (column, renderer, "text", NAME_COLUMN);
1250
 
    gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1251
 
 
1252
 
    renderer = gtk_cell_renderer_text_new ();
1253
 
    column = gtk_tree_view_column_new_with_attributes (_("Group"),
1254
 
        renderer, "text", GROUP_COLUMN, NULL);
1255
 
    gtk_tree_view_column_set_resizable (column, TRUE);
1256
 
    gtk_tree_view_column_set_sort_column_id (column, GROUP_COLUMN);
1257
 
    gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1258
 
    priv->group_column = column;
1259
 
 
1260
 
    renderer = gtk_cell_renderer_text_new ();
1261
 
    column = gtk_tree_view_column_new_with_attributes (_("Server"),
1262
 
        renderer, "text", SERVER_COLUMN, NULL);
1263
 
    gtk_tree_view_column_set_resizable (column, TRUE);
1264
 
    gtk_tree_view_column_set_sort_column_id (column, SERVER_COLUMN);
1265
 
    gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1266
 
 
1267
 
    gtk_container_add (GTK_CONTAINER (scrolledwindow), tree);
1268
 
    gtk_widget_show (tree);
1269
 
 
1270
 
    gtk_tree_selection_set_select_function (
1271
 
        gtk_tree_view_get_selection (GTK_TREE_VIEW (tree)),
1272
 
        remmina_main_selection_func, remminamain, NULL);
1273
 
    g_signal_connect (G_OBJECT (tree), "button-press-event",
1274
 
        G_CALLBACK (remmina_main_file_list_on_button_press), remminamain);
1275
 
 
1276
 
    priv->file_list = tree;
1277
 
 
1278
 
    /* Create statusbar */
1279
 
    priv->statusbar = gtk_statusbar_new ();
1280
 
    gtk_box_pack_start (GTK_BOX (vbox), priv->statusbar, FALSE, FALSE, 0);
1281
 
    gtk_widget_show (priv->statusbar);
1282
 
 
1283
 
    /* Prepare the data */
1284
 
    remmina_main_load_files (remminamain, FALSE);
1285
 
 
1286
 
    /* Load the preferences */
1287
 
    if (remmina_pref.hide_toolbar)
1288
 
    {
1289
 
        gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (
1290
 
            gtk_action_group_get_action (priv->main_group, "ViewToolbar")), FALSE);
1291
 
    }
1292
 
    if (remmina_pref.hide_statusbar)
1293
 
    {
1294
 
        gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (
1295
 
            gtk_action_group_get_action (priv->main_group, "ViewStatusbar")), FALSE);
1296
 
    }
1297
 
    if (remmina_pref.show_quick_search)
1298
 
    {
1299
 
        gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (
1300
 
            gtk_action_group_get_action (priv->main_group, "ViewQuickSearch")), TRUE);
1301
 
    }
1302
 
    if (remmina_pref.small_toolbutton)
1303
 
    {
1304
 
        gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (
1305
 
            gtk_action_group_get_action (priv->main_group, "ViewSmallToolbutton")), TRUE);
1306
 
    }
1307
 
 
1308
 
    /* Drag-n-drop support */
1309
 
    gtk_drag_dest_set (GTK_WIDGET (remminamain), GTK_DEST_DEFAULT_ALL, remmina_drop_types, 1, GDK_ACTION_COPY);
1310
 
    g_signal_connect (G_OBJECT (remminamain), "drag-data-received",
1311
 
        G_CALLBACK (remmina_main_on_drag_data_received), NULL);
1312
 
 
1313
 
    priv->initialized = TRUE;
1314
 
 
1315
 
    remmina_widget_pool_register (GTK_WIDGET (remminamain));
1316
 
}
1317
 
 
1318
 
GtkWidget*
1319
 
remmina_main_new (void)
1320
 
{
1321
 
    RemminaMain *window;
1322
 
 
1323
 
    window = REMMINA_MAIN (g_object_new (REMMINA_TYPE_MAIN, NULL));
1324
 
    return GTK_WIDGET (window);
1325
 
}
1326