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

« back to all changes in this revision

Viewing changes to remmina/src/remmina_string_list.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 - 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 <gtk/gtk.h>
 
22
#include <string.h>
 
23
#include "remmina_public.h"
 
24
#include "remmina_string_list.h"
 
25
 
 
26
G_DEFINE_TYPE( RemminaStringList, remmina_string_list, GTK_TYPE_TABLE)
 
27
 
 
28
#define ERROR_COLOR "red"
 
29
 
 
30
enum
 
31
{
 
32
        COLUMN_TEXT,
 
33
        COLUMN_COLOR,
 
34
        NUM_COLUMNS
 
35
};
 
36
 
 
37
static void remmina_string_list_status_error(RemminaStringList *gsl, const gchar *error)
 
38
{
 
39
        GdkColor color;
 
40
 
 
41
        gdk_color_parse(ERROR_COLOR, &color);
 
42
        gtk_widget_modify_fg(gsl->status_label, GTK_STATE_NORMAL, &color);
 
43
        gtk_label_set_text(GTK_LABEL(gsl->status_label), error);
 
44
}
 
45
 
 
46
static void remmina_string_list_status_hints(RemminaStringList *gsl)
 
47
{
 
48
        gtk_widget_modify_fg(gsl->status_label, GTK_STATE_NORMAL, NULL);
 
49
        gtk_label_set_text(GTK_LABEL(gsl->status_label), gsl->hints);
 
50
}
 
51
 
 
52
static void remmina_string_list_add(GtkWidget *widget, RemminaStringList *gsl)
 
53
{
 
54
        GtkTreeSelection *selection;
 
55
        GtkTreeIter iter;
 
56
        GtkTreePath *path;
 
57
 
 
58
        selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gsl->list));
 
59
        gtk_list_store_append(gsl->store, &iter);
 
60
        gtk_list_store_set(gsl->store, &iter, COLUMN_COLOR, ERROR_COLOR, -1);
 
61
        gtk_tree_selection_select_iter(selection, &iter);
 
62
 
 
63
        path = gtk_tree_model_get_path(GTK_TREE_MODEL(gsl->store), &iter);
 
64
        gtk_tree_view_set_cursor(GTK_TREE_VIEW(gsl->list), path,
 
65
                        gtk_tree_view_get_column(GTK_TREE_VIEW(gsl->list), COLUMN_TEXT), TRUE);
 
66
        gtk_tree_path_free(path);
 
67
}
 
68
 
 
69
static void remmina_string_list_remove(GtkWidget *widget, RemminaStringList *gsl)
 
70
{
 
71
        GtkTreeSelection *selection;
 
72
        GtkTreeIter iter;
 
73
 
 
74
        selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gsl->list));
 
75
        if (gtk_tree_selection_get_selected(selection, NULL, &iter))
 
76
        {
 
77
                gtk_list_store_remove(gsl->store, &iter);
 
78
        }
 
79
        remmina_string_list_status_hints(gsl);
 
80
}
 
81
 
 
82
static void remmina_string_list_move(RemminaStringList *gsl, GtkTreeIter *from, GtkTreeIter *to)
 
83
{
 
84
        GtkTreePath *path;
 
85
 
 
86
        gtk_list_store_swap(gsl->store, from, to);
 
87
        path = gtk_tree_model_get_path(GTK_TREE_MODEL(gsl->store), from);
 
88
        gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(gsl->list), path, NULL, 0, 0, 0);
 
89
        gtk_tree_path_free(path);
 
90
}
 
91
 
 
92
static void remmina_string_list_down(GtkWidget *widget, RemminaStringList *gsl)
 
93
{
 
94
        GtkTreeSelection *selection;
 
95
        GtkTreeIter iter;
 
96
        GtkTreeIter target_iter;
 
97
 
 
98
        selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gsl->list));
 
99
        if (gtk_tree_selection_get_selected(selection, NULL, &iter))
 
100
        {
 
101
                gtk_tree_selection_get_selected(selection, NULL, &target_iter);
 
102
                if (gtk_tree_model_iter_next(GTK_TREE_MODEL(gsl->store), &target_iter))
 
103
                {
 
104
                        remmina_string_list_move(gsl, &iter, &target_iter);
 
105
                }
 
106
        }
 
107
}
 
108
 
 
109
static void remmina_string_list_up(GtkWidget *widget, RemminaStringList *gsl)
 
110
{
 
111
        GtkTreeSelection *selection;
 
112
        GtkTreeIter iter;
 
113
        GtkTreeIter target_iter;
 
114
        GtkTreePath *path;
 
115
 
 
116
        selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gsl->list));
 
117
        if (gtk_tree_selection_get_selected(selection, NULL, &iter))
 
118
        {
 
119
                gtk_tree_selection_get_selected(selection, NULL, &target_iter);
 
120
                path = gtk_tree_model_get_path(GTK_TREE_MODEL(gsl->store), &target_iter);
 
121
                if (gtk_tree_path_prev(path))
 
122
                {
 
123
                        gtk_tree_model_get_iter(GTK_TREE_MODEL(gsl->store), &target_iter, path);
 
124
                        gtk_tree_path_free(path);
 
125
                        remmina_string_list_move(gsl, &iter, &target_iter);
 
126
                }
 
127
        }
 
128
}
 
129
 
 
130
static void remmina_string_list_cell_edited(GtkCellRendererText *cell, const gchar *path_string, const gchar *new_text,
 
131
                RemminaStringList *gsl)
 
132
{
 
133
        gchar *text, *ptr, *error;
 
134
        GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
 
135
        GtkTreeIter iter;
 
136
        gboolean has_error = FALSE;
 
137
 
 
138
        gtk_tree_model_get_iter(GTK_TREE_MODEL(gsl->store), &iter, path);
 
139
        text = g_strdup(new_text);
 
140
 
 
141
        /* Eliminate delimitors... */
 
142
        for (ptr = text; *ptr; ptr++)
 
143
        {
 
144
                if (*ptr == STRING_DELIMITOR)
 
145
                        *ptr = ' ';
 
146
        }
 
147
 
 
148
        if (gsl->validation_func)
 
149
        {
 
150
                if (!((*gsl->validation_func)(text, &error)))
 
151
                {
 
152
                        remmina_string_list_status_error(gsl, error);
 
153
                        g_free(error);
 
154
                        has_error = TRUE;
 
155
                }
 
156
                else
 
157
                {
 
158
                        remmina_string_list_status_hints(gsl);
 
159
                }
 
160
        }
 
161
 
 
162
        gtk_list_store_set(gsl->store, &iter, COLUMN_TEXT, text, COLUMN_COLOR, (has_error ? ERROR_COLOR : NULL),
 
163
        -1);
 
164
 
 
165
        gtk_tree_path_free
 
166
        (path);
 
167
}
 
168
 
 
169
static void remmina_string_list_class_init(RemminaStringListClass *klass)
 
170
{
 
171
}
 
172
 
 
173
static void remmina_string_list_init(RemminaStringList *gsl)
 
174
{
 
175
        GtkWidget *widget;
 
176
        GtkWidget *image;
 
177
        GtkWidget *scrolled_window;
 
178
        GtkWidget *vbox;
 
179
        GtkCellRenderer *renderer;
 
180
        GtkTreeViewColumn *column;
 
181
        GtkWidget *frame;
 
182
 
 
183
        gtk_table_resize(GTK_TABLE(gsl), 3, 2);
 
184
 
 
185
        /* Create the frame and add a new scrolled window, followed by the group list */
 
186
        frame = gtk_frame_new(NULL);
 
187
        gtk_widget_show(frame);
 
188
        gtk_table_attach_defaults(GTK_TABLE(gsl), frame, 0, 1, 0, 1);
 
189
 
 
190
        scrolled_window = gtk_scrolled_window_new(NULL, NULL);
 
191
        gtk_widget_show(scrolled_window);
 
192
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
193
        gtk_container_add(GTK_CONTAINER(frame), scrolled_window);
 
194
 
 
195
        gsl->store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
 
196
        gsl->list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gsl->store));
 
197
        gtk_widget_show(gsl->list);
 
198
        gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(gsl->list), FALSE);
 
199
        gtk_container_add(GTK_CONTAINER(scrolled_window), gsl->list);
 
200
 
 
201
        renderer = gtk_cell_renderer_text_new();
 
202
        g_object_set(G_OBJECT(renderer), "editable", TRUE, NULL);
 
203
        g_signal_connect(renderer, "edited", G_CALLBACK(remmina_string_list_cell_edited), gsl);
 
204
        column = gtk_tree_view_column_new_with_attributes(NULL, renderer, "text", COLUMN_TEXT, "foreground", COLUMN_COLOR,
 
205
                        NULL);
 
206
        gtk_tree_view_append_column(GTK_TREE_VIEW(gsl->list), column);
 
207
 
 
208
        /* buttons packed into a vbox */
 
209
        vbox = gtk_vbox_new(FALSE, 0);
 
210
        gtk_widget_show(vbox);
 
211
        gtk_table_attach(GTK_TABLE(gsl), vbox, 1, 2, 0, 3, 0, GTK_EXPAND | GTK_FILL, 0, 0);
 
212
 
 
213
        image = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_MENU);
 
214
        gtk_widget_show(image);
 
215
        widget = gtk_button_new();
 
216
        gtk_widget_show(widget);
 
217
        gtk_container_add(GTK_CONTAINER(widget), image);
 
218
        gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, FALSE, 0);
 
219
        g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_string_list_add), gsl);
 
220
 
 
221
        image = gtk_image_new_from_stock(GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU);
 
222
        gtk_widget_show(image);
 
223
        widget = gtk_button_new();
 
224
        gtk_widget_show(widget);
 
225
        gtk_container_add(GTK_CONTAINER(widget), image);
 
226
        gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, FALSE, 0);
 
227
        g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_string_list_remove), gsl);
 
228
 
 
229
        image = gtk_image_new_from_stock(GTK_STOCK_GO_UP, GTK_ICON_SIZE_MENU);
 
230
        gtk_widget_show(image);
 
231
        widget = gtk_button_new();
 
232
        gtk_widget_show(widget);
 
233
        gtk_container_add(GTK_CONTAINER(widget), image);
 
234
        gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, FALSE, 0);
 
235
        g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_string_list_up), gsl);
 
236
        gsl->up_button = widget;
 
237
 
 
238
        image = gtk_image_new_from_stock(GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_MENU);
 
239
        gtk_widget_show(image);
 
240
        widget = gtk_button_new();
 
241
        gtk_widget_show(widget);
 
242
        gtk_container_add(GTK_CONTAINER(widget), image);
 
243
        gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, FALSE, 0);
 
244
        g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_string_list_down), gsl);
 
245
        gsl->down_button = widget;
 
246
 
 
247
        /* The last status label */
 
248
        gsl->status_label = gtk_label_new(NULL);
 
249
        gtk_widget_show(gsl->status_label);
 
250
        gtk_misc_set_alignment(GTK_MISC(gsl->status_label), 0.0, 0.5);
 
251
        gtk_table_attach(GTK_TABLE(gsl), gsl->status_label, 0, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 0, 0);
 
252
 
 
253
        gsl->hints = NULL;
 
254
        gsl->validation_func = NULL;
 
255
}
 
256
 
 
257
GtkWidget*
 
258
remmina_string_list_new(void)
 
259
{
 
260
        return GTK_WIDGET(g_object_new(REMMINA_TYPE_STRING_LIST, NULL));
 
261
}
 
262
 
 
263
void remmina_string_list_set_auto_sort(RemminaStringList *gsl, gboolean auto_sort)
 
264
{
 
265
        if (auto_sort)
 
266
        {
 
267
                gtk_widget_hide(gsl->up_button);
 
268
                gtk_widget_hide(gsl->down_button);
 
269
                gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(gsl->store), COLUMN_TEXT, GTK_SORT_ASCENDING);
 
270
        }
 
271
        else
 
272
        {
 
273
                gtk_widget_show(gsl->up_button);
 
274
                gtk_widget_show(gsl->down_button);
 
275
                gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(gsl->store), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
 
276
                                GTK_SORT_ASCENDING);
 
277
        }
 
278
}
 
279
 
 
280
void remmina_string_list_set_hints(RemminaStringList *gsl, const gchar *hints)
 
281
{
 
282
        gsl->hints = hints;
 
283
        remmina_string_list_status_hints(gsl);
 
284
}
 
285
 
 
286
void remmina_string_list_set_text(RemminaStringList *gsl, const gchar *text)
 
287
{
 
288
        GtkTreeIter iter;
 
289
        gchar *buf, *ptr1, *ptr2;
 
290
 
 
291
        gtk_list_store_clear(gsl->store);
 
292
 
 
293
        buf = g_strdup(text);
 
294
        ptr1 = buf;
 
295
        while (ptr1 && *ptr1 != '\0')
 
296
        {
 
297
                ptr2 = strchr(ptr1, STRING_DELIMITOR);
 
298
                if (ptr2)
 
299
                        *ptr2++ = '\0';
 
300
 
 
301
                gtk_list_store_append(gsl->store, &iter);
 
302
                gtk_list_store_set(gsl->store, &iter, COLUMN_TEXT, ptr1, COLUMN_COLOR, NULL, -1);
 
303
 
 
304
                ptr1 = ptr2;
 
305
        }
 
306
 
 
307
        g_free(buf);
 
308
}
 
309
 
 
310
gchar*
 
311
remmina_string_list_get_text(RemminaStringList *gsl)
 
312
{
 
313
        GString *str;
 
314
        GtkTreeIter iter;
 
315
        gboolean first, ret;
 
316
        GValue value =
 
317
        { 0 };
 
318
        const gchar *s;
 
319
 
 
320
        str = g_string_new(NULL);
 
321
        first = TRUE;
 
322
 
 
323
        ret = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(gsl->store), &iter);
 
324
        while (ret)
 
325
        {
 
326
                gtk_tree_model_get_value(GTK_TREE_MODEL(gsl->store), &iter, COLUMN_COLOR, &value);
 
327
                if (g_value_get_string(&value) == NULL)
 
328
                {
 
329
                        g_value_unset(&value);
 
330
                        gtk_tree_model_get_value(GTK_TREE_MODEL(gsl->store), &iter, COLUMN_TEXT, &value);
 
331
                        s = g_value_get_string(&value);
 
332
                        if (s && s[0] != '\0')
 
333
                        {
 
334
                                if (!first)
 
335
                                {
 
336
                                        g_string_append_c(str, STRING_DELIMITOR);
 
337
                                }
 
338
                                else
 
339
                                {
 
340
                                        first = FALSE;
 
341
                                }
 
342
                                g_string_append(str, s);
 
343
                        }
 
344
                }
 
345
                g_value_unset(&value);
 
346
 
 
347
                ret = gtk_tree_model_iter_next(GTK_TREE_MODEL(gsl->store), &iter);
 
348
        }
 
349
 
 
350
        return g_string_free(str, FALSE);
 
351
}
 
352
 
 
353
void remmina_string_list_set_validation_func(RemminaStringList *gsl, RemminaStringListValidationFunc func)
 
354
{
 
355
        gsl->validation_func = func;
 
356
}
 
357