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