source: trunk/gtk/dialogs.c @ 10993

Last change on this file since 10993 was 10993, checked in by charles, 12 years ago

(trunk gtk) #3416 "clicking close on the transmission window causes new "Quit Transmission?" dialog even if one already exists" -- fixed

  • Property svn:keywords set to Date Rev Author Id
File size: 9.1 KB
Line 
1/******************************************************************************
2 * $Id: dialogs.c 10993 2010-07-11 06:46:46Z charles $
3 *
4 * Copyright (c) 2005-2008 Transmission authors and contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
24
25#include <gtk/gtk.h>
26#include <glib/gi18n.h>
27
28#include <libtransmission/transmission.h>
29
30#include "conf.h"
31#include "dialogs.h"
32#include "hig.h"
33#include "tr-core.h"
34#include "tr-prefs.h"
35
36/***
37****
38***/
39
40struct quitdata
41{
42    TrCore *          core;
43    callbackfunc_t    func;
44    void *            cbdata;
45    GtkWidget *       dontask;
46};
47
48static void
49quitresp( GtkWidget * widget,
50          int         response,
51          gpointer    data )
52{
53    struct quitdata * stuff = data;
54    GtkToggleButton * tb = GTK_TOGGLE_BUTTON( stuff->dontask );
55
56    tr_core_set_pref_bool( stuff->core,
57                          PREF_KEY_ASKQUIT,
58                          !gtk_toggle_button_get_active( tb ) );
59
60    if( response == GTK_RESPONSE_ACCEPT )
61        stuff->func( stuff->cbdata );
62
63    g_free( stuff );
64    gtk_widget_destroy( widget );
65}
66
67GtkWidget *
68askquit( TrCore *       core,
69         GtkWindow *    parent,
70         callbackfunc_t func,
71         void *         cbdata )
72{
73    struct quitdata * stuff;
74    GtkWidget *       w;
75    GtkWidget *       wind;
76    GtkWidget *       dontask;
77
78    stuff          = g_new( struct quitdata, 1 );
79    stuff->func    = func;
80    stuff->cbdata  = cbdata;
81    stuff->core    = core;
82
83    wind = gtk_message_dialog_new_with_markup(
84         parent,
85        GTK_DIALOG_DESTROY_WITH_PARENT,
86        GTK_MESSAGE_WARNING,
87        GTK_BUTTONS_NONE,
88        _(
89            "<big><b>Quit Transmission?</b></big>" ) );
90
91    gtk_dialog_add_button( GTK_DIALOG( wind ), GTK_STOCK_CANCEL,
92                                               GTK_RESPONSE_CANCEL );
93    w = gtk_dialog_add_button( GTK_DIALOG( wind ), GTK_STOCK_QUIT,
94                                                   GTK_RESPONSE_ACCEPT );
95    gtk_dialog_set_default_response( GTK_DIALOG( wind ),
96                                     GTK_RESPONSE_ACCEPT );
97    gtk_dialog_set_alternative_button_order( GTK_DIALOG( wind ),
98                                             GTK_RESPONSE_ACCEPT,
99                                             GTK_RESPONSE_CANCEL,
100                                             -1 );
101    dontask = gtk_check_button_new_with_mnemonic( _( "_Don't ask me again" ) );
102    stuff->dontask = dontask;
103
104    gtk_box_pack_start( GTK_BOX( GTK_DIALOG(
105                                     wind )->vbox ), dontask, FALSE, FALSE,
106                        GUI_PAD );
107
108    g_signal_connect( G_OBJECT( wind ), "response",
109                      G_CALLBACK( quitresp ), stuff );
110    gtk_widget_grab_focus( w );
111
112    gtk_widget_show_all( wind );
113
114    return wind;
115}
116
117/***
118****
119***/
120
121struct DeleteData
122{
123    gboolean    delete_files;
124    GSList *    torrents;
125    TrCore *    core;
126};
127
128static void
129removeTorrents( struct DeleteData * data )
130{
131    GSList * l;
132
133    for( l = data->torrents; l != NULL; l = l->next )
134        tr_core_remove_torrent( data->core, l->data, data->delete_files );
135    g_slist_free( data->torrents );
136    data->torrents = NULL;
137}
138
139static void
140removeResponse( GtkDialog * dialog,
141                gint        response,
142                gpointer    gdata )
143{
144    struct DeleteData * data = gdata;
145
146    if( response == GTK_RESPONSE_ACCEPT )
147        removeTorrents( data );
148
149    gtk_widget_destroy( GTK_WIDGET( dialog ) );
150    g_slist_free( data->torrents );
151    g_free( data );
152}
153
154struct count_data
155{
156    int incomplete;
157    int connected;
158};
159
160static void
161countBusyTorrents( gpointer gtor, gpointer gdata )
162{
163    const tr_stat * stat = tr_torrent_stat( gtor );
164    struct count_data * data = gdata;
165
166    if( stat->leftUntilDone ) ++data->incomplete;
167    if( stat->peersConnected ) ++data->connected;
168}
169
170void
171confirmRemove( GtkWindow * parent,
172               TrCore *    core,
173               GSList *    torrents,
174               gboolean    delete_files )
175{
176    GtkWidget *         d;
177    const int           count = g_slist_length( torrents );
178    struct count_data   counts;
179    GString           * primary_text;
180    GString           * secondary_text;
181    struct DeleteData * dd;
182
183    if( !count )
184        return;
185
186    dd = g_new0( struct DeleteData, 1 );
187    dd->core = core;
188    dd->torrents = torrents;
189    dd->delete_files = delete_files;
190
191    counts.incomplete = 0;
192    counts.connected = 0;
193    g_slist_foreach( torrents, countBusyTorrents, &counts );
194
195    primary_text = g_string_new( NULL );
196
197    if( !delete_files )
198    {
199        g_string_printf( primary_text, ngettext( "Remove torrent?",
200                                                 "Remove %d torrents?",
201                                                 count ), count );
202    }
203    else
204    {
205        g_string_printf( primary_text, ngettext( "Delete this torrent's downloaded files?",
206                                                 "Delete these %d torrents' downloaded files?",
207                                                 count ), count );
208    }
209
210    secondary_text = g_string_new( NULL );
211
212    if( !counts.incomplete && !counts.connected )
213    {
214        g_string_assign( secondary_text, ngettext(
215                "Once removed, continuing the transfer will require the torrent file or magnet link.",
216                "Once removed, continuing the transfers will require the torrent files or magnet links.",
217                count ) );
218    }
219    else if( count == counts.incomplete )
220    {
221        g_string_assign( secondary_text, ngettext( "This torrent has not finished downloading.",
222                                                   "These torrents have not finished downloading.",
223                                                   count ) );
224    }
225    else if( count == counts.connected )
226    {
227        g_string_assign( secondary_text, ngettext( "This torrent is connected to peers.",
228                                                   "These torrents are connected to peers.",
229                                                   count ) );
230    }
231    else
232    {
233        if( counts.connected )
234            g_string_append( secondary_text, ngettext( "One of these torrents is connected to peers.",
235                                                       "Some of these torrents are connected to peers.",
236                                                       counts.connected ) );
237        if( counts.connected && counts.incomplete )
238            g_string_append( secondary_text, "\n" );
239
240        if( counts.incomplete )
241            g_string_assign( secondary_text, ngettext( "One of these torrents has not finished downloading.",
242                                                       "Some of these torrents have not finished downloading.",
243                                                       counts.incomplete ) );
244    }
245
246    d = gtk_message_dialog_new_with_markup( parent,
247                                            GTK_DIALOG_DESTROY_WITH_PARENT,
248                                            GTK_MESSAGE_QUESTION,
249                                            GTK_BUTTONS_NONE,
250                                            "<big><b>%s</b></big>",
251                                            primary_text->str );
252    if( secondary_text->len )
253        gtk_message_dialog_format_secondary_markup( GTK_MESSAGE_DIALOG( d ),
254                                                    "%s", secondary_text->str );
255    gtk_dialog_add_buttons( GTK_DIALOG( d ),
256                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
257                            ( delete_files ? GTK_STOCK_DELETE :
258                              GTK_STOCK_REMOVE ), GTK_RESPONSE_ACCEPT,
259                            NULL );
260    gtk_dialog_set_default_response( GTK_DIALOG ( d ),
261                                     GTK_RESPONSE_CANCEL );
262    gtk_dialog_set_alternative_button_order( GTK_DIALOG( d ),
263                                             GTK_RESPONSE_ACCEPT,
264                                             GTK_RESPONSE_CANCEL,
265                                             -1 );
266    g_signal_connect( d, "response", G_CALLBACK( removeResponse ), dd );
267    gtk_widget_show_all( d );
268
269    g_string_free( primary_text, TRUE );
270    g_string_free( secondary_text, TRUE );
271}
Note: See TracBrowser for help on using the repository browser.