~ubuntu-branches/ubuntu/precise/gnome-do/precise-proposed

« back to all changes in this revision

Viewing changes to Do.Addins/src/Do.UI/AbstractLoginWidget.cs

  • Committer: Bazaar Package Importer
  • Author(s): Christopher James Halse Rogers
  • Date: 2008-09-14 10:09:40 UTC
  • mto: (0.1.8 sid)
  • mto: This revision was merged to the branch mainline in revision 7.
  • Revision ID: james.westby@ubuntu.com-20080914100940-kyghudg7py14bu2z
Tags: upstream-0.6.0.0
ImportĀ upstreamĀ versionĀ 0.6.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* AbstractLogin.cs
 
2
 *
 
3
 * GNOME Do is the legal property of its developers. Please refer to the
 
4
 * COPYRIGHT file distributed with this
 
5
 * source distribution.
 
6
 *
 
7
 * This program is free software: you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation, either version 3 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
 */
 
20
 
 
21
using System;
 
22
using System.Threading;
 
23
using System.Collections;
 
24
 
 
25
using Gnome.Keyring;
 
26
using Gtk;
 
27
using Gdk;
 
28
 
 
29
namespace Do.UI
 
30
{
 
31
        /// <summary>
 
32
        /// A class providing a generic login widget for plugins that will need
 
33
        /// to log into an external service. Provides a clean UI and enforces
 
34
        /// asynchronous validation so the plugin developer doesn't need to know
 
35
        /// about delegates or any complex concepts. To see an example of this
 
36
        /// class in use, see GMailContacts.
 
37
        /// </summary>
 
38
        public abstract partial class AbstractLoginWidget : Gtk.Bin
 
39
        {
 
40
                
 
41
                private LinkButton new_acct_btn;
 
42
                
 
43
                /// <summary>
 
44
                /// Builds the generic UI with the name passed in by service. 
 
45
                /// </summary>
 
46
                /// <param name="service">
 
47
                /// A <see cref="System.String"/>
 
48
                /// </param>
 
49
                public AbstractLoginWidget (string service)
 
50
                {
 
51
                        Build ();
 
52
                        get_account_lbl.Markup = String.Format ("<i>Don't have {0}?</i>",service);
 
53
                        new_acct_btn = new LinkButton ("", String.Format ("Sign up for {0}",
 
54
                                service));
 
55
                        new_acct_hbox.Add (new_acct_btn);
 
56
                        Box.BoxChild wInt = new_acct_hbox [new_acct_btn] as Box.BoxChild;
 
57
                        wInt.Position = 1;
 
58
                        
 
59
                        password_entry.Activated += OnPasswordEntryActivated;
 
60
                        new_acct_btn.Clicked += OnNewAcctBtnClicked;
 
61
                        
 
62
                        string username, password;
 
63
                        username = password = "";
 
64
                        GetAccountData (out username, out password, GetType ());
 
65
                        
 
66
                        username_entry.Text = username;
 
67
                        password_entry.Text = password;
 
68
                        
 
69
                        ShowAll ();
 
70
                }
 
71
                
 
72
                /// <summary>
 
73
                /// Default contructor that initializes any service names with the
 
74
                /// generic string "an account".
 
75
                /// </summary>
 
76
                public AbstractLoginWidget () : 
 
77
                        this ("an account")
 
78
                {
 
79
                         // nothing
 
80
                }
 
81
                
 
82
                /// <value>
 
83
                /// Provides access to the Gtk.Entry field for a username
 
84
                /// </value>
 
85
                protected Gtk.Entry UsernameEntry {
 
86
                        get { 
 
87
                                return username_entry;
 
88
                        }
 
89
                }
 
90
                
 
91
                /// <value>
 
92
                /// Provides access to the Gtk.Label for the username
 
93
                /// Access to this field is provided as a courtesy to developers
 
94
                /// who would like to customize their UI. It is not generally needed.
 
95
                /// </value>
 
96
                protected Gtk.Label UsernameLabel {
 
97
                        get {
 
98
                                return username_lbl;
 
99
                        }
 
100
                }
 
101
                
 
102
                /// <value>
 
103
                /// Provides access to the Gtk.Entry field for the password
 
104
                /// </value>
 
105
                protected Gtk.Entry PasswordEntry {
 
106
                        get {
 
107
                                return password_entry;
 
108
                        }
 
109
                }
 
110
                
 
111
                /// <value>
 
112
                /// Provides access to the Gtk.Label for the password
 
113
                /// Access to this field is provided as a courtesy to developers
 
114
                /// who would like to customize their UI. It is not generally needed.
 
115
                /// </value>
 
116
                protected Gtk.Label PasswordLabel {
 
117
                        get {
 
118
                                return password_lbl;
 
119
                        }
 
120
                }
 
121
                
 
122
                /// <value>
 
123
                /// Provides access to the Gtk.Label for current validation status
 
124
                /// </value>
 
125
                protected Gtk.Label StatusLabel {
 
126
                        get {
 
127
                                return validate_lbl;
 
128
                        }
 
129
                }
 
130
                
 
131
                /// <value>
 
132
                /// Provides access to the Gtk.Button to validate account settings
 
133
                /// </value>
 
134
                protected Gtk.Button ValidateButton {
 
135
                        get {
 
136
                                return validate_btn;
 
137
                        }
 
138
                }
 
139
                
 
140
                /// <value>
 
141
                /// Provides access to the Gtk.Label for signing up for the service
 
142
                /// Access to this field is provided as a courtesy to developers
 
143
                /// who would like to customize their UI. It is not generally needed.
 
144
                /// </value>
 
145
                protected Gtk.Label GetAccountLabel {
 
146
                        get {
 
147
                                return get_account_lbl;
 
148
                        }
 
149
                }
 
150
                
 
151
                /// <value>
 
152
                /// Provides access to the Gtk.Label field for the username.
 
153
                /// Generally only the .Uri property needs set.
 
154
                /// </value>
 
155
                protected Gtk.LinkButton GetAccountButton {
 
156
                        get {
 
157
                                return new_acct_btn;
 
158
                        }
 
159
                }
 
160
                
 
161
                /// <summary>
 
162
                /// Fires when button to validate account is clicked
 
163
                /// </summary>
 
164
                /// <param name="sender">
 
165
                /// A <see cref="System.Object"/>
 
166
                /// </param>
 
167
                /// <param name="e">
 
168
                /// A <see cref="EventArgs"/>
 
169
                /// </param>
 
170
                protected virtual void OnApplyBtnClicked (object sender, EventArgs e)
 
171
                {
 
172
                        validate_lbl.Markup = "<i>Validating...</i>";
 
173
                        validate_btn.Sensitive = false;
 
174
                        string username = username_entry.Text;
 
175
                        string password = password_entry.Text;
 
176
                        
 
177
                        Thread thread = new Thread ((ThreadStart) delegate {
 
178
                                bool valid = Validate (username, password);
 
179
                                Gtk.Application.Invoke (delegate {              
 
180
                                        if (valid) {
 
181
                                                validate_lbl.Markup = "<i>Account validation succeeded!</i>";
 
182
                                                SaveAccountData (username_entry.Text, password_entry.Text,
 
183
                                                GetType ());
 
184
                                        } else {
 
185
                                                validate_lbl.Markup = "<i>Account validation failed!</i>";
 
186
                                        }
 
187
                                        validate_btn.Sensitive = true;
 
188
                                });
 
189
                        });
 
190
                        thread.IsBackground = true; //don't hang on exit if fail
 
191
                        thread.Start ();
 
192
                }
 
193
                
 
194
                /// <summary>
 
195
                /// Opens new browser window with the uri from new_acct_btn.
 
196
                /// if uri is unset, button does nothing.
 
197
                /// </summary>
 
198
                /// <param name="sender">
 
199
                /// A <see cref="System.Object"/>
 
200
                /// </param>
 
201
                /// <param name="e">
 
202
                /// A <see cref="EventArgs"/>
 
203
                /// </param>
 
204
                protected virtual void OnNewAcctBtnClicked (object sender, EventArgs e)
 
205
                {
 
206
                        if (!String.IsNullOrEmpty (new_acct_btn.Uri))
 
207
                                Do.Addins.Util.Environment.Open (new_acct_btn.Uri);
 
208
                }
 
209
                
 
210
                /// <summary>
 
211
                /// Saves account data to permanant storage whether it be
 
212
                /// GConf, gnome-keyring, or a flat file.
 
213
                /// </summary>
 
214
                public static void SaveAccountData (string username, string password,
 
215
                        Type type)
 
216
                {
 
217
                        string keyName = type.FullName;
 
218
                        string keyring;
 
219
                        Hashtable ht;
 
220
                        
 
221
                        try {
 
222
                                keyring = Ring.GetDefaultKeyring ();
 
223
                                ht = new Hashtable ();
 
224
                                ht["name"] = keyName;
 
225
                                ht["username"] = username;
 
226
                                
 
227
                                Ring.CreateItem (keyring, ItemType.GenericSecret, keyName,
 
228
                                        ht, password, true);
 
229
                                                 
 
230
                        } catch (Exception e) {
 
231
                                Console.Error.WriteLine (e.Message);
 
232
                        }
 
233
                }
 
234
                
 
235
                /// <summary>
 
236
                /// Loads account data from gnome-keyring
 
237
                /// </summary>
 
238
                public static void GetAccountData (out string username, 
 
239
                        out string password, Type type)
 
240
                {
 
241
                        string keyName = type.FullName;
 
242
                        username = password = "";
 
243
                        Hashtable ht = new Hashtable ();
 
244
                        ht ["name"] = keyName;
 
245
                        
 
246
                        try {
 
247
                                foreach (ItemData s in Ring.Find (ItemType.GenericSecret, ht)) {
 
248
                                        if (s.Attributes.ContainsKey ("name") && s.Attributes.ContainsKey ("username")
 
249
                                            && (s.Attributes ["name"] as string).Equals (keyName)) {
 
250
                                                username = s.Attributes ["username"] as string;
 
251
                                                password = s.Secret;
 
252
                                                return;
 
253
                                        }
 
254
                                }
 
255
                        } catch (Exception) {
 
256
                                Console.Error.WriteLine ("No account info stored for {0}",
 
257
                                        keyName);
 
258
                        }
 
259
                }
 
260
                
 
261
                /// <summary>
 
262
                /// Makes validation call to service
 
263
                /// </summary>
 
264
                /// <param name="username">
 
265
                /// A <see cref="System.String"/>
 
266
                /// </param>
 
267
                /// <param name="password">
 
268
                /// A <see cref="System.String"/>
 
269
                /// </param>
 
270
                /// <returns>
 
271
                /// A <see cref="System.Boolean"/>
 
272
                /// </returns>
 
273
                protected abstract bool Validate (string username, string password);
 
274
 
 
275
                protected virtual void OnPasswordEntryActivated (object sender, System.EventArgs e)
 
276
                {
 
277
                        validate_btn.Click ();
 
278
                }
 
279
        }
 
280
}