Merge commit 'upstream/0.2.4'
[debian/pino.git] / src / pref_dialog.vala
1 /* pref_dialog.vala
2  *
3  * Copyright (C) 2009-2010  troorl
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  * Author:
19  *      troorl <troorl@gmail.com>
20  */
21
22 using Gtk;
23 using Auth;
24
25 public class PrefDialog : Dialog {
26         
27         private Notebook tabs;
28         
29         private SpinButton updateInterval;
30         private SpinButton numberStatuses;
31         private ComboBox urlShorten;
32         private CheckButton enableSpell;
33         private CheckButton startMin;
34         private CheckButton showTray;
35         private CheckButton showTimelineNotify;
36         private CheckButton showMentionsNotify;
37         private CheckButton showDirectNotify;
38         
39         //private RadioButton showFullNotify;
40         private RadioButton showLowNotify;
41         
42         private ComboBox retweetStyle;
43         private Button deleteCache;
44         private CheckButton roundedAvatars;
45         private HScale opacityTweets;
46         private CheckButton rtlSupport;
47         private CheckButton fullNames;
48         private FontButton deFont;
49         private ColorButton freshColor;
50         private Entry login;
51         private Entry password;
52         private CheckButton savePass;
53         
54         public signal void delete_cache();
55         
56         public PrefDialog(Prefs prefs, Window parent, Accounts accounts) {
57                 this.modal = true;
58                 set_title(_("Preferences"));
59                 this.has_separator = false;
60                 
61                 tabs = new Notebook();
62                 
63                 //main page
64                 var main_box = new VBox(false, 10);
65                 
66                 //update interval
67                 var updateLabel = new Label(_("Update interval (in minutes)"));
68                 updateInterval = new SpinButton.with_range(1, 60, 1);
69                 
70                 //default number of statuses in lists
71                 var numberStatusesLabel = new Label(_("Default number of statuses"));
72                 numberStatuses = new SpinButton.with_range(5, 100, 1);
73                 
74                 //URL shortening service
75                 var urlShortenLabel = new Label(_("URL shortening service"));
76                 urlShorten = new ComboBox.text();
77                 urlShorten.append_text("goo.gl");
78                 urlShorten.append_text("is.gd");
79                 
80                 //enabling spell checking
81                 enableSpell = new CheckButton.with_label(_("Enable spell checking"));
82                 
83                 //start in tray
84                 startMin = new CheckButton.with_label(_("Starting up in tray"));
85                 
86                 //show tray icon
87                 showTray = new CheckButton.with_label(_("Show tray icon"));
88                 
89                 //show notifications
90                 showTimelineNotify = new CheckButton.with_label(_("For timeline"));
91                 showMentionsNotify = new CheckButton.with_label(_("For mentions"));
92                 showDirectNotify = new CheckButton.with_label(_("For direct messages"));
93                 /*
94                 weak SList<weak Gtk.RadioButton> group_not  = null;
95                 showFullNotify = new RadioButton.with_label(group_not,
96                         _("Show notification for each status"));
97                 showLowNotify = new RadioButton.with_label(showFullNotify.get_group(),
98                         _("Show overall notification"));
99                 */
100                 //retweet style
101                 var reLabel = new Label(_("Retweets style"));
102                 retweetStyle = new ComboBox.text();
103                 retweetStyle.append_text("RT @username: message");
104                 retweetStyle.append_text("♺ @username: message");
105                 retweetStyle.append_text("message (via @username)");
106                 
107                 //delete cache
108                 deleteCache = new Button.with_label(_("Clear now"));
109                 var del_img = new Image.from_icon_name("gtk-clear", IconSize.BUTTON);
110                 deleteCache.set_image(del_img);
111                 deleteCache.clicked.connect(() => {
112                         delete_cache();
113                 });
114                 
115                 var table_int = new HigTable(_("General"));
116                 table_int.add_two_widgets(updateLabel, updateInterval);
117                 table_int.add_two_widgets(numberStatusesLabel, numberStatuses);
118                 table_int.add_two_widgets(urlShortenLabel, urlShorten);
119                 table_int.add_widget(enableSpell);
120                 
121                 var table_re = new HigTable(_("Retweets"));
122                 table_re.add_two_widgets(reLabel, retweetStyle);
123                 
124                 var table_cache = new HigTable(_("Cache"));
125                 table_cache.add_widget(deleteCache);
126                 
127                 main_box.pack_start(table_int, false, true, 10);
128                 main_box.pack_start(table_re, false, true, 10);
129                 main_box.pack_start(table_cache, false, true, 10);
130                 
131                 //desktop preferences
132                 var de_box = new VBox(false, 0);
133                 
134                 //tray
135                 var table_tr = new HigTable(_("Notification area"));
136                 table_tr.add_widget(startMin);
137                 table_tr.add_widget(showTray);
138                 
139                 var table_not = new HigTable(_("Notification"));
140                 table_not.add_widget(showTimelineNotify);
141                 table_not.add_widget(showMentionsNotify);
142                 table_not.add_widget(showDirectNotify);
143                 
144                 de_box.pack_start(table_tr, false, true, 10);
145                 de_box.pack_start(table_not, false, true, 10);
146                 
147                 //account page
148                 var ac_box = new VBox(false, 0);
149                 
150                 //accounts
151                 AccountWidget accountWidget = new AccountWidget(this, accounts);
152                 
153                 var table_auth = new HigTable(_("Authorization"));
154                 table_auth.add_widget_wide(accountWidget);
155                 
156                 ac_box.pack_start(table_auth, false, true, 10);
157                 
158                 if(prefs.is_new) {
159                         var start_box = new HBox(false, 0);
160                         var start_button = new Button.with_label(_("Create new account..."));
161                         
162                         start_button.clicked.connect(() => {
163                                 GLib.Pid pid;
164                                 GLib.Process.spawn_async(".", {"/usr/bin/xdg-open",
165                                         "http://twitter.com/signup"}, null,
166                                         GLib.SpawnFlags.STDOUT_TO_DEV_NULL, null, out pid);
167                         });
168                         
169                         start_box.pack_start(start_button, false, true, 10);
170                         ac_box.pack_start(start_box, false, true, 10);
171                 }
172                 
173                 //Appearance tab
174                 var app_box = new VBox(false, 0);
175                 
176                 var table_tweets = new HigTable(_("Statuses"));
177                 
178                 //rounded corners
179                 roundedAvatars = new CheckButton.with_label(_("Rounded corners"));
180                 
181                 //rtl support
182                 rtlSupport = new CheckButton.with_label(_("Right-to-left languages detection"));
183                 
184                 //full names or nicks in tweets
185                 fullNames = new CheckButton.with_label(_("Full names instead of nicknames"));
186                 
187                 //default font in statuses
188                 var deFontLabel = new Label(_("Default font"));
189                 deFont = new FontButton();
190                 deFont.set_use_size(true);
191                 deFont.set_show_style(false);
192                 
193                 //color of fresh statuses
194                 var freshColorLabel = new Label(_("Fresh statuses color"));
195                 freshColor = new ColorButton();
196                 freshColor.set_use_alpha(true);
197                 
198                 //opacity for tweets
199                 var opacityTweetsLabel = new Label(_("Opacity"));
200                 opacityTweets = new HScale.with_range(0, 100, 5);
201                 opacityTweets.set_size_request(150, -1);
202                 
203                 table_tweets.add_widget(roundedAvatars);
204                 table_tweets.add_widget(rtlSupport);
205                 table_tweets.add_widget(fullNames);
206                 table_tweets.add_two_widgets(deFontLabel, deFont);
207                 table_tweets.add_two_widgets(freshColorLabel, freshColor);
208                 table_tweets.add_two_widgets(opacityTweetsLabel, opacityTweets);
209                 
210                 app_box.pack_start(table_tweets, false, true, 10);
211                 
212                 tabs.append_page(main_box, new Label(_("Main")));
213                 tabs.append_page(de_box, new Label(_("Desktop")));
214                 tabs.append_page(ac_box, new Label(_("Account")));
215                 tabs.append_page(app_box, new Label(_("Appearance")));
216                 
217                 var hor_box = new HBox(false, 0);
218                 hor_box.pack_start(tabs, true, true, 10);
219                 
220                 this.vbox.pack_start(hor_box, true, true, 10);
221                 this.vbox.set_spacing(0);
222                 
223                 //action buttons
224                 add_button(STOCK_CLOSE, ResponseType.CLOSE);
225                 
226                 this.response.connect(response_acts);
227                 
228                 //setup preferences
229                 setup_prefs(prefs);
230                 
231                 //setup signals for prefs
232                 setup_prefs_signals(prefs);
233                 
234                 set_transient_for(parent);
235                 show_all();
236                 
237                 //if first start or don't want to remember the password
238                 if(accounts.is_new) {   
239                         tabs.set_current_page(2);
240                 }
241         }
242         
243         private void setup_urlshorten(Prefs prefs) {
244                 switch(prefs.urlShorten) {
245                         case "goo.gl":
246                                 urlShorten.set_active(0);
247                                 break;
248                         
249                         case "is.gd":
250                                 urlShorten.set_active(1);
251                                 break;
252                         
253                         default:
254                                 urlShorten.set_active(0);
255                                 break;
256                 }
257         }
258         
259         private void setup_retweet(Prefs prefs) {
260                 switch(prefs.retweetStyle) {
261                         case ReTweet.Style.CLASSIC:
262                                 retweetStyle.set_active(0);
263                                 break;
264                         
265                         case ReTweet.Style.UNI:
266                                 retweetStyle.set_active(1);
267                                 break;
268                         
269                         case ReTweet.Style.VIA:
270                                 retweetStyle.set_active(2);
271                                 break;
272                 }
273         }
274         
275         private void setup_prefs(Prefs prefs) {
276                 updateInterval.value = prefs.updateInterval;
277                 numberStatuses.value = prefs.numberStatuses;
278                 setup_urlshorten(prefs);
279                 enableSpell.active = prefs.enableSpell;
280                 startMin.active = prefs.startMin;
281                 showTray.active = prefs.showTray;
282                 showTimelineNotify.active = prefs.showTimelineNotify;
283                 showMentionsNotify.active = prefs.showMentionsNotify;
284                 /*
285                 if(prefs.showFullNotify)
286                         showFullNotify.active = true;
287                 else
288                         showLowNotify.active = true;
289                 */
290                 showDirectNotify.active = prefs.showDirectNotify;
291                 setup_retweet(prefs);
292                 roundedAvatars.active = prefs.roundedAvatars;
293                 opacityTweets.set_value((int)(prefs.opacityTweets.to_double() * 100));
294                 rtlSupport.active = prefs.rtlSupport;
295                 fullNames.active = prefs.fullNames;
296                 deFont.set_font_name("%s %d".printf(prefs.deFontName, prefs.deFontSize));
297                 
298                 //colorFrsh setup
299                 uint16 alpha_fresh;
300                 var fresh_color = ColorUtils.rgba2color(prefs.freshColor, out alpha_fresh);
301                 //warning("%d", alpha_fresh);
302                 freshColor.set_color(fresh_color);
303                 freshColor.set_alpha(alpha_fresh);
304         }
305         
306         private void setup_prefs_signals(Prefs prefs) {
307                 updateInterval.value_changed.connect(() => {
308                         prefs.updateInterval = (int)updateInterval.value;
309                 });
310                 
311                 numberStatuses.value_changed.connect(() => {
312                         prefs.numberStatuses = (int)numberStatuses.value;
313                 });
314                 
315                 urlShorten.changed.connect(() => {
316                         switch(urlShorten.get_active()) {
317                                 case 0:
318                                         prefs.urlShorten = "goo.gl";
319                                         break;
320                                 
321                                 case 1:
322                                         prefs.urlShorten = "is.gd";
323                                         break;
324                         }
325                 });
326                 
327                 enableSpell.toggled.connect(() => {
328                         prefs.enableSpell = enableSpell.active;
329                 });
330                 
331                 startMin.toggled.connect(() => {
332                         prefs.startMin = startMin.active;
333                         
334                         if(prefs.startMin) //enabling tray
335                                 showTray.active = true;
336                 });
337                 
338                 showTray.toggled.connect(() => {
339                         prefs.showTray = showTray.active;
340                         
341                         if(!prefs.showTray) //disable starting in tray
342                                 startMin.active = false;
343                 });
344                 
345                 roundedAvatars.toggled.connect(() => {
346                         prefs.roundedAvatars = roundedAvatars.active;
347                 });
348                 
349                 opacityTweets.change_value.connect((scroll, new_value) => {
350                         if(new_value > 100)
351                                 new_value = 100;
352                         
353                         string str_val = (new_value / 100).to_string();
354                 
355                         if(str_val != "1" && str_val != "0") {
356                                 if(str_val.length < 4)
357                                         str_val = str_val.substring(1, 2);
358                                 else
359                                         str_val = str_val.substring(1, 3);
360                         }
361                 
362                         prefs.opacityTweets = str_val;
363                         return false;
364                 });
365                 
366                 rtlSupport.toggled.connect(() => {
367                         prefs.rtlSupport = rtlSupport.active;
368                 });
369                 
370                 fullNames.toggled.connect(() => {
371                         prefs.fullNames = fullNames.active;
372                 });
373                 
374                 deFont.font_set.connect(() => {
375                         //warning(deFont.get_font_name());
376                         prefs.deFont = deFont.get_font_name();
377                         //warning("font: %s, size: %d", prefs.deFontName, prefs.deFontSize);
378                 });
379                 
380                 freshColor.color_set.connect(() => {
381                         Gdk.Color fresh_color;
382                         freshColor.get_color(out fresh_color);
383                         double alpha = (double)freshColor.get_alpha() / 256.0 / 256.0;
384
385                         string result = ColorUtils.color2rgba(fresh_color, alpha);
386                         
387                         prefs.freshColor = result;
388                 });
389                 
390                 showTimelineNotify.toggled.connect(() => {
391                         prefs.showTimelineNotify = showTimelineNotify.active;
392                 });
393                 
394                 showMentionsNotify.toggled.connect(() => {
395                         prefs.showMentionsNotify = showMentionsNotify.active;
396                 });
397                 
398                 showDirectNotify.toggled.connect(() => {
399                         prefs.showDirectNotify = showDirectNotify.active;
400                 });
401                 /*
402                 showFullNotify.toggled.connect(() => {
403                         prefs.showFullNotify = showFullNotify.active;
404                 });
405                 */
406                 retweetStyle.changed.connect(() => {
407                         switch(retweetStyle.get_active()) {
408                                 case 0:
409                                         prefs.retweetStyle = ReTweet.Style.CLASSIC;
410                                         break;
411                                 
412                                 case 1:
413                                         prefs.retweetStyle = ReTweet.Style.UNI;
414                                         break;
415                                 
416                                 case 2:
417                                         prefs.retweetStyle = ReTweet.Style.VIA;
418                                         break;
419                         }
420                 });
421         }
422         
423         private void response_acts(int resp_id) {
424                 switch(resp_id) {
425                         case ResponseType.CLOSE:
426                                 close();
427                                 break;
428                 }
429         }       
430 }