~realender/winconn/trunk

« back to all changes in this revision

Viewing changes to winconn/prompts.py

  • Committer: Alex Stanev
  • Date: 2012-11-23 10:27:32 UTC
  • Revision ID: alex@stanev.org-20121123102732-7h9xysxewg65wfm0
-m upgrade, drop quickly-widgets

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
### BEGIN LICENSE
 
2
# Copyright (C) 2012 Alex Stanev <alex@stanev.org>
 
3
# This program is free software: you can redistribute it and/or modify it 
 
4
# under the terms of the GNU General Public License version 3, as published 
 
5
# by the Free Software Foundation.
 
6
 
7
# This program is distributed in the hope that it will be useful, but 
 
8
# WITHOUT ANY WARRANTY; without even the implied warranties of 
 
9
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
 
10
# PURPOSE.  See the GNU General Public License for more details.
 
11
 
12
# You should have received a copy of the GNU General Public License along 
 
13
# with this program.  If not, see <http://www.gnu.org/licenses/>.
 
14
### END LICENSE
 
15
 
 
16
#import Gtk
 
17
#import gobject
 
18
#import GLib
 
19
from gi.repository import Gtk
 
20
from gi.repository import GObject
 
21
from gi.repository import GLib
 
22
 
 
23
import os
 
24
import locale
 
25
from locale import gettext as _
 
26
locale.textdomain('quickly-widgets')
 
27
 
 
28
#TODO: stop using **kwargs and go back to named arguments so you can pass them from the function to the class
 
29
 
 
30
class Prompt(Gtk.Dialog):
 
31
    """A base class for some quickly.prompts - creates Ok and Cancel buttons,
 
32
    displays a title and a label.
 
33
 
 
34
    qiuckly.prompts.Prompt is intended for receiving information back
 
35
    from users. If you only want to display a message, use a
 
36
    quickly.prompts.Alert.
 
37
 
 
38
    Useful subclasses and helper functions are provided:
 
39
    quickly.prompts.string() uses quickly.prompts.StringPrompt
 
40
    quickly.prompts.date() uses quickly.prompts.DatePrompt
 
41
    quickly.prompts.integer() uses quickly.prompts.IntegerPrompt
 
42
    quickly.prompts.decimal() uses quickly.prompts.DecimalPrompt
 
43
    quickly.prompts.price() uses quickly.prompts.PricePrompt
 
44
 
 
45
    Using
 
46
    A quickly.prompts.prompt object is not intended to be used without
 
47
    configuring or extending it. Otherwise, it will only display a 
 
48
    blank dialog with OK and Cancel buttons and a label.
 
49
 
 
50
    Configuring
 
51
    #add some widgets to the prompt using the
 
52
    #the prompt's content_box member (which is a Gtk.VBox)
 
53
    #These widgets will appear below the label
 
54
    #StringPrompt works similar to this:
 
55
    p = quickly.prompts.Prompt(title,text)
 
56
    entry = Gtk.Entry()
 
57
    entry.set_text(default_value)
 
58
    entry.set_activates_default(True)
 
59
    entry.show()
 
60
    p.content_box.pack_end(entry, True, True, 5)
 
61
    response = p.run()
 
62
    if response = Gtk.ResponseType.OK:
 
63
        my_string = entry.get_text()
 
64
 
 
65
    #A Prompt is a Gtk.Dialog, so you can use Gtk.DialogMembers
 
66
    action_area = p.get_action_area()
 
67
 
 
68
    Extending 
 
69
    #Typically you will add widgets to a prompt and override the
 
70
    #get_value function to return the appropriate value entered by the user.
 
71
    #String prompt is implemented as follows:
 
72
    class StringPrompt(Prompt):
 
73
        def __init__(self, title = "Input String",
 
74
                     text = "Input a String:", default_value = ""):
 
75
            Prompt.__init__(self, title, text)
 
76
            self._entry = Gtk.Entry()
 
77
            self._entry.set_text(default_value)
 
78
            self._entry.set_activates_default(True)
 
79
            self._entry.show()
 
80
            self.content_box.pack_end(self._entry, True, True, 5)
 
81
    
 
82
        def get_value(self):
 
83
                return self._entry.get_text()
 
84
 
 
85
    """
 
86
 
 
87
    def __init__(self, title, text):
 
88
        """Creates a Prompt
 
89
        arguments:
 
90
        title - The title for the dialog window
 
91
        text -  The string to display in the Prompts label
 
92
 
 
93
        """
 
94
 
 
95
        Gtk.Dialog.__init__(self, title, None, Gtk.DialogFlags.MODAL,(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OK, Gtk.ResponseType.OK))
 
96
        #self.set_has_separator(False)
 
97
        content_area = self.get_content_area()
 
98
        content_area.set_border_width(5)
 
99
        self.set_default_response(Gtk.ResponseType.OK)
 
100
 
 
101
        self.content_box = Gtk.VBox(False, 10)
 
102
        label = Gtk.Label(text)
 
103
        label.set_line_wrap(True)
 
104
        self.content_box.pack_start(label,False, False, 5)
 
105
        content_area.pack_start(self.content_box,False, False, 5)
 
106
        self.content_box.show()
 
107
        label.show()
 
108
 
 
109
def string(title = _("Input String"), text = _("Input a String:"), default_value = ""):
 
110
    """string - prompts to enter a string via a dialog box.
 
111
 
 
112
    aguments:
 
113
    title - a string to be the title of the dialog
 
114
    text - a string to provide a prompt for the user within dialog
 
115
    default_value - a string to see the entry in the dialog box
 
116
 
 
117
    returns a tuple of (Gtk.DialogResponse, string value)
 
118
    Gtk.ResponseType.OK means the user clicked the "OK" button, otherwise
 
119
    the user cancelled (Gtk.ResponseType.CANCEL) or dismissed the dialog
 
120
    (Gtk.ResponseType.DELETE_EVENT)
 
121
 
 
122
    """
 
123
 
 
124
    sp = StringPrompt(title, text, default_value)
 
125
    response = sp.run()
 
126
    val = sp.get_value()
 
127
    sp.destroy()
 
128
    return (response, val)
 
129
 
 
130
class StringPrompt(Prompt):
 
131
    """A class for receiving a string from a user
 
132
 
 
133
    Using
 
134
    #Collect a string from the user by using the
 
135
    #quickly.prompts.string() helper function
 
136
    reponse, val = string("String select test","String select test")
 
137
    if response == Gtk.ResponseType.OK:
 
138
        my_string = val
 
139
 
 
140
    Configuring
 
141
    #Add widgets to the conent_box member
 
142
    sp = StringPrompt(title, text, default_string)
 
143
    sp.content_box.pack_end(my_additional_widget, False, False, 5)
 
144
 
 
145
    #Modify the _entry member
 
146
    sp._entry.set_max_length(144)
 
147
 
 
148
    Extending
 
149
    A StringPrompt is a Prompt which is Gtk.Dialog
 
150
 
 
151
    """
 
152
 
 
153
    def __init__(self, title = _("Input String"), text = _("Input a String:"), default_value = ""):
 
154
        """Create a StringPrompt
 
155
        arguments:
 
156
        title - a string to be the title of the dialog
 
157
        text - a string to provide a prompt for the user within dialog
 
158
        default_value - a string to see the entry in the dialog box
 
159
 
 
160
        """
 
161
 
 
162
        Prompt.__init__(self, title, text)
 
163
        self._entry = Gtk.Entry()
 
164
        self._entry.set_text(default_value)
 
165
        self._entry.set_activates_default(True)
 
166
        self._entry.show()
 
167
        self.content_box.pack_end(self._entry, True, True, 5)
 
168
 
 
169
    def get_value(self):
 
170
        """get_value - returns the value the user has entered into the Gtk.Entry
 
171
 
 
172
        """
 
173
 
 
174
        return self._entry.get_text()
 
175
 
 
176
def date(title = _("Choose Date"), text = _("Choose a Date:"), default_value = None):
 
177
    """date - prompts to enter a date using a calendar via a dialog box.
 
178
 
 
179
    aguments:
 
180
    title - a string to be the title of the dialog
 
181
    text - a string to provide a prompt for the user within dialog
 
182
    default_value - a tuple in the form of integers for (year,month,day)
 
183
    where month is zero indexed (Jaunary is 0, December is 11)
 
184
 
 
185
    returns a tuple of (Gtk.DialogResponse, tuple)
 
186
    The returnd tuple is in the form of integers for (year,month,day)
 
187
    where month is zero indexed (Jaunary is 0, December is 11)
 
188
 
 
189
    Gtk.ResponseType.OK means the user clicked the "OK" button, otherwise
 
190
    the user cancelled (Gtk.ResponseType.CANCEL) or dismissed the dialog
 
191
    (Gtk.ResponseType.DELETE_EVENT)
 
192
 
 
193
    """
 
194
    dp = DatePrompt(title, text, default_value)
 
195
 
 
196
    response = dp.run()
 
197
    val = dp.get_value()
 
198
    dp.destroy()
 
199
    return (response, val)
 
200
 
 
201
class DatePrompt(Prompt):
 
202
    """A class for receiving a date from a user
 
203
 
 
204
    Using
 
205
    #Collect a date from the user by using the
 
206
    #quickly.prompts.date() helper function
 
207
    reponse, val = date("Date prompt title","Date prompt message")
 
208
    if response == Gtk.ResponseType.OK:
 
209
        my_date = val
 
210
 
 
211
    Configuring
 
212
    #Add widgets to the content_box member
 
213
    dp = DatePrompt(title, text, default_integer)
 
214
    dp.content_box.pack_end(my_additional_widget)
 
215
 
 
216
    #Modify the _calendar member
 
217
    dp._calendar.set_display_options(Gtk.CALENDAR_SHOW_DAY_NAMES)
 
218
 
 
219
    Extending
 
220
    A DatePrompt is a Prompt which is a Gtk.Dialog.
 
221
 
 
222
    """
 
223
 
 
224
    def __init__(self, title = _("Choose Date"), text = _("Choose a Date:"), default_value = None):
 
225
        """Creates a DatePrompt
 
226
        title - a string to be the title of the dialog
 
227
        text - a string to provide a prompt for the user within dialog
 
228
        default_value - a tuple in the form of integers for (year,month,day)
 
229
        where month is zero indexed (Jaunary is 0, December is 11)
 
230
 
 
231
        """
 
232
        Prompt.__init__(self, title, text)          
 
233
        self._calendar = Gtk.Calendar()
 
234
        self._calendar.show()
 
235
        self.content_box.pack_end(self._calendar, True, True, 5)
 
236
 
 
237
        if default_value is not None and len(default_value) is 3:
 
238
            year, month, day = default_value
 
239
            self._calendar.select_month(month, year)
 
240
            self._calendar.select_day(day)
 
241
 
 
242
    def get_value(self):
 
243
        """get_value - return the date currently set in the _calendar member
 
244
        A tuple is in the form of integers for (year,month,day)
 
245
        where month is zero indexed (Jaunary is 0, December is 11)
 
246
 
 
247
        """
 
248
 
 
249
        return self._calendar.get_date()
 
250
 
 
251
def integer(title = _("Enter Number"), text = _("Enter an Integer Value:"), 
 
252
            default_value=0, min_value = -1000000000, max_value=1000000000,
 
253
            step = 1):
 
254
    """integer - prompts to enter an integer using a spinner via a dialog box.
 
255
 
 
256
    arguments:
 
257
    title - a string to be the title of the dialog
 
258
    text - a string to provide a prompt for the user within dialog
 
259
    default_value - an integer to display by default, should be greater than
 
260
 
 
261
    keyword arguments:
 
262
    the min_value and less then the max_value
 
263
    min_value - the lowest number accepted by the spinner, 
 
264
    defaults to -1000000000
 
265
    step - set the incriments for each click of the spinner buttons,
 
266
    defaults to 1
 
267
    max_value, the highest number accepted by the spinner,
 
268
    defaults to 1000000000
 
269
 
 
270
    returns a tuple of (Gtk.DialogResponse, integer)
 
271
 
 
272
    Gtk.ResponseType.OK means the user clicked the "OK" button, otherwise
 
273
    the user cancelled (Gtk.ResponseType.CANCEL) or dismissed the dialog
 
274
    (Gtk.ResponseType.DELETE_EVENT)
 
275
 
 
276
    """
 
277
 
 
278
    ip = IntegerPrompt(title,text,default_value, min_value, max_value, step)
 
279
    response = ip.run()
 
280
    val = ip.get_value()
 
281
    ip.destroy()
 
282
    return (response, val)
 
283
 
 
284
 
 
285
class IntegerPrompt(Prompt):
 
286
    """A Prompt for collecting an integer number value from user. Uses
 
287
        a Gtk.Spinner for data entry.
 
288
 
 
289
 
 
290
    Using
 
291
    #Collect an integer value from the user by using the
 
292
    #quickly.prompts.integer() helper function
 
293
    reponse, val = integer("Integer prompt title","Integer prompt message")
 
294
    if response == Gtk.ResponseType.OK:
 
295
        my_date = val
 
296
 
 
297
    Configuring
 
298
    #Add widgets to the content_box member
 
299
    dp = IntegerPrompt(title, text, default_date)
 
300
    dp.content_box.pack_end(my_additional_widget)
 
301
 
 
302
    #Modify the _spinner member
 
303
    dp._spinner.set_value(20)
 
304
 
 
305
    Extending
 
306
    An IntegerPrompt is a Prompt which is a Gtk.Dialog
 
307
 
 
308
    """
 
309
 
 
310
    def __init__(self, title=_("Enter Number"), text=_("Enter an Integer Value:"),
 
311
            default_value=0, min_value = -1000000000, max_value=1000000000,
 
312
            step = 1):
 
313
        """Creates an Integer Prompt
 
314
 
 
315
        """
 
316
 
 
317
        Prompt.__init__(self, title, text)
 
318
        adj = Gtk.Adjustment(default_value,min_value,max_value,step)
 
319
        self._spinner = Gtk.SpinButton()
 
320
        self._spinner.set_adjustment(adj)
 
321
        self._spinner.set_activates_default(True)
 
322
        self._spinner.show()
 
323
        self._spinner.set_numeric(True)
 
324
        self.content_box.pack_end(self._spinner, True, True, 5)
 
325
 
 
326
    def get_value(self):
 
327
            return self._spinner.get_value_as_int()
 
328
 
 
329
def decimal(title=_("Enter Price"), text=_("Choose a Price:"), 
 
330
          default_value=0, min_value=-1000000000, max_value=1000000000,
 
331
          step=1,digits=20):
 
332
    """decimal - prompts to enter a number that inlcudes
 
333
    decimal places using a spinner via a dialog box.
 
334
 
 
335
    aguments:
 
336
    title - a string to be the title of the dialog
 
337
    text - a string to provide a prompt for the user within dialog
 
338
 
 
339
    keyword arguments:
 
340
    default_value - an integer to display by default, should be greater than
 
341
    the min_value and less then the max_value
 
342
    min_value - the lowest number accepted by the spinner, 
 
343
    defaults to -1000000000
 
344
    step - set the incriments for each click of the spinner buttons,
 
345
    defaults to 1
 
346
    max_value, the highest number accepted by the spinner,
 
347
    defaults to 1000000000
 
348
    digits - the number of decimal places to include, defaults to 20
 
349
    supports a maximum of 20 decimal places. Values great than 20 will
 
350
    be converted to 20, and values less than 0 will be converted to 0
 
351
 
 
352
    returns a tuple of (Gtk.DialogResponse, number)
 
353
 
 
354
    Gtk.ResponseType.OK means the user clicked the "OK" button, otherwise
 
355
    the user cancelled (Gtk.ResponseType.CANCEL) or dismissed the dialog
 
356
    (Gtk.ResponseType.DELETE_EVENT)
 
357
 
 
358
    """
 
359
 
 
360
    dp = DecimalPrompt(title, text, default_value, min_value, max_value,
 
361
                       step, digits)
 
362
    response = dp.run()
 
363
    val = dp.get_value()
 
364
    dp.destroy()
 
365
    return (response, val)
 
366
 
 
367
class DecimalPrompt(Prompt):
 
368
    """A Prompt for collecting a decimal number value from user. Uses
 
369
        a Gtk.Spinner for data entry.
 
370
 
 
371
    Using
 
372
    #Collect a number from the user by using the
 
373
    #quickly.prompts.decimal() helper function
 
374
    reponse, val = decimal("Decimal prompt title","Decimal prompt message")
 
375
    if response == Gtk.ResponseType.OK:
 
376
        my_decimal = val
 
377
 
 
378
    Configuring
 
379
    #Add widgets to the content_box member
 
380
    dp = DecimalPrompt(title, text, default_number)
 
381
    dp.content_box.pack_end(my_additional_widget)
 
382
 
 
383
    #Modify the _spinner member
 
384
    dp._spinner.set_value(20.0)
 
385
 
 
386
    Extending
 
387
    An DecimalPrompt is a Prompt which is a Gtk.Dialog
 
388
 
 
389
 
 
390
    """
 
391
 
 
392
    def __init__(self, title=_("Enter Number"), text=_("Enter an Integer Value:"),
 
393
                    default_value=0, min_value=-1000000000, max_value=1000000000,
 
394
                    step=1, digits=20):
 
395
        """Creates a DecimalPrompt
 
396
        arguments:
 
397
        title - a string to be the title of the dialog
 
398
        text - a string to provide a prompt for the user within dialog
 
399
        default_value - an integer to display by default, should be greater than
 
400
 
 
401
        keyword arguments:
 
402
        default_value - an integer to display by default, should be greater than
 
403
        the min_value and less then the max_value
 
404
        min_value - the lowest number accepted by the spinner, 
 
405
        defaults to -1000000000
 
406
        step - set the incriments for each click of the spinner buttons,
 
407
        defaults to 1
 
408
        max_value, the highest number accepted by the spinner,
 
409
        defaults to 1000000000
 
410
        digits - the number of decimal places to include, defaults to 20
 
411
        supports a maximum of 20 decimal places. Values great than 20 will
 
412
        be converted to 20, and values less than 0 will be converted to 0
 
413
 
 
414
        returns a tuple of (Gtk.DialogResponse, number)
 
415
    
 
416
        Gtk.ResponseType.OK means the user clicked the "OK" button, otherwise
 
417
        the user cancelled (Gtk.ResponseType.CANCEL) or dismissed the dialog
 
418
        (Gtk.ResponseType.DELETE_EVENT)
 
419
 
 
420
        """
 
421
 
 
422
        Prompt.__init__(self, title, text)
 
423
 
 
424
        self._adjustment = Gtk.Adjustment(default_value,min_value,max_value,step)
 
425
        if digits > 20:
 
426
            digits = 20
 
427
        if digits < 0:
 
428
            digits = 0
 
429
        self._spinner = Gtk.SpinButton()
 
430
        self._spinner.set_adjustment(self._adjustment)
 
431
        self._spinner.set_digits(digits)
 
432
        self._spinner.set_activates_default(True)
 
433
        self._spinner.show()
 
434
        self._spinner.set_numeric(True)
 
435
        self.content_box.pack_end(self._spinner, True, True, 5)
 
436
 
 
437
    def get_value(self):
 
438
            return self._spinner.get_value()
 
439
 
 
440
def price(title=_("Enter Price"), text=_("Choose a Price:"), 
 
441
          default_value=0, min_value=-1000000000, max_value=1000000000,
 
442
          step=1):
 
443
    """price - prompts to enter a number up to the 
 
444
    hundreths place using a spinner via a dialog box.
 
445
 
 
446
    aguments:
 
447
    title - a string to be the title of the dialog
 
448
    text - a string to provide a prompt for the user within dialog
 
449
    default_value - an integer to display by default, should be greater than
 
450
 
 
451
    keyword arguments:
 
452
    the min_value and less then the max_value
 
453
    min_value - the lowest number accepted by the spinner, 
 
454
    defaults to -1000000000
 
455
    max_value, the highest number accepted by the spinner,
 
456
    defaults to 1000000000
 
457
    step - set the incriments for each click of the spinner buttons,
 
458
    defaults to 1
 
459
 
 
460
    returns a tuple of (Gtk.DialogResponse, number)
 
461
 
 
462
    Gtk.ResponseType.OK means the user clicked the "OK" button, otherwise
 
463
    the user cancelled (Gtk.ResponseType.CANCEL) or dismissed the dialog
 
464
    (Gtk.ResponseType.DELETE_EVENT)
 
465
 
 
466
    """
 
467
 
 
468
    pp = PricePrompt(title, text, default_value, min_value, max_value,
 
469
                       step)
 
470
    response = pp.run()
 
471
    val = pp.get_value()
 
472
    pp.destroy()
 
473
    return (response, val)
 
474
 
 
475
class PricePrompt(DecimalPrompt):
 
476
    """A Prompt for collecting a decimal number value from the user,
 
477
        formatted with two decimal places appropriate for entering
 
478
        a currence ammount. Uses a Gtk.Spinner for data entry.
 
479
 
 
480
    Using
 
481
    #Collect a number from the user by using the
 
482
    #quickly.prompts.price() helper function
 
483
    reponse, val = price("Price prompt title","Price prompt message")
 
484
    if response == Gtk.ResponseType.OK:
 
485
        my_date = val
 
486
 
 
487
    Configuring
 
488
    #Add widgets to the content_box member
 
489
    pp = PricePrompt(title, text, default_number)
 
490
    pp.content_box.pack_end(my_additional_widget)
 
491
 
 
492
    #Modify the _spinner member
 
493
    pp._spinner.set_value(20.00)
 
494
 
 
495
    Extending
 
496
    An PricePrompt is Decimal Prompt which is a Prompt which is a Gtk.Dialog
 
497
 
 
498
 
 
499
    """
 
500
 
 
501
    def __init__(self, title=_("Enter Price"), text=_("Choose a Price:"), 
 
502
          default_value=0, min_value=-1000000000, max_value=1000000000,
 
503
          step=1):
 
504
        """Creates a DecimalPrompt
 
505
        arguments:
 
506
        title - a string to be the title of the dialog
 
507
        text - a string to provide a prompt for the user within dialog
 
508
        default_value - an integer to display by default, should be greater than
 
509
 
 
510
        keywrod arguments:
 
511
        keyword arguments:
 
512
        the min_value and less then the max_value
 
513
        min_value - the lowest number accepted by the spinner, 
 
514
        defaults to -1000000000
 
515
        max_value, the highest number accepted by the spinner,
 
516
        defaults to 1000000000
 
517
        step - set the incriments for each click of the spinner buttons,
 
518
        defaults to 1
 
519
 
 
520
        returns a tuple of (Gtk.DialogResponse, number)
 
521
 
 
522
        Gtk.ResponseType.OK means the user clicked the "OK" button, otherwise
 
523
        the user cancelled (Gtk.ResponseType.CANCEL) or dismissed the dialog
 
524
        (Gtk.ResponseType.DELETE_EVENT)
 
525
 
 
526
        """
 
527
 
 
528
        DecimalPrompt.__init__(self,title,text,default_value,min_value,
 
529
                              max_value, step)
 
530
        self._spinner.set_digits(2)
 
531
 
 
532
def yes_no(title = _("Choose Yes or No"), text = "", yes="", no=""):
 
533
    """yes_no - prompts the user to choose between two options,
 
534
        one "yes" and one "no", though typically the button labels
 
535
        should be set as verbs.
 
536
 
 
537
    aguments:
 
538
    title - a string to be the title of the dialog
 
539
    text - a string, typically a question, prompting the
 
540
    user to choose Yes or No
 
541
    yes - a string that is a verb representing the Yes action
 
542
    no - a string that is a verb representing the No action
 
543
 
 
544
    returns a Gtk.DialogResponse
 
545
    Gtk.ResponseType.YES means the user clicked the "YES" button, otherwise
 
546
    Gtk.ResponseType.NO means the user clicked the "NO" button, otherwise
 
547
    the user dismissed the dialogv(Gtk.ResponseType.DELETE_EVENT)
 
548
 
 
549
    """
 
550
    yn = YesNoPrompt(title,text,yes,no)
 
551
    response = yn.run()
 
552
    yn.destroy()
 
553
    return response
 
554
 
 
555
class YesNoPrompt(Gtk.Dialog):
 
556
    """A prompt to collect a user choice between two options,
 
557
        one "yes" and one "no", though typically the button labels
 
558
        should be set as verbs.
 
559
 
 
560
    Using
 
561
    #Collect a response from the user using the
 
562
    #quickly.prompts.yes_no() helper function
 
563
    reponse = decimal(title,message,"Do it", "Don't do it")
 
564
    if response == Gtk.ResponseType.YES:
 
565
        yes = True
 
566
    else:
 
567
        yes = False
 
568
 
 
569
    Configuring
 
570
    #Add widgets to the content_box member
 
571
    dp = DecimalPrompt(title, text, default_number)
 
572
    dp.content_box.pack_end(my_additional_widget)
 
573
 
 
574
    #add a widget to the response by creating it and
 
575
    #passing it in with a Gtk.ResponseType.ID
 
576
    dp.add_action_widget(new_widget, response_id)
 
577
 
 
578
    Extending
 
579
    An YesNoPrompt is a Gtk.Dialog
 
580
 
 
581
    """
 
582
 
 
583
    def __init__(self, title=_("Choose an option"),text="",yes="",no=""):
 
584
        """creaets a YesNoPrompt.
 
585
        
 
586
        aguments:
 
587
        title - a string to be the title of the dialog
 
588
        text - a string, typically a question, prompting the
 
589
        user to choose Yes or No
 
590
        yes - a string that is a verb representing the Yes action
 
591
        no - a string that is a verb representing the No action
 
592
 
 
593
        """
 
594
 
 
595
        Gtk.Dialog.__init__(self, title, None, Gtk.DialogFlags.MODAL)
 
596
 
 
597
        if no == "":
 
598
            no_button = Gtk.Button(stock=Gtk.STOCK_NO)
 
599
        else:
 
600
            no_button = Gtk.Button(label=no, use_underline=True)
 
601
        self.add_action_widget(no_button,Gtk.ResponseType.NO)
 
602
        no_button.show()
 
603
 
 
604
        if yes == "":
 
605
            yes_button = Gtk.Button(stock=Gtk.STOCK_YES)
 
606
        else:
 
607
            yes_button = Gtk.Button(label=yes, use_underline=True)
 
608
        self.add_action_widget(yes_button,Gtk.ResponseType.YES)
 
609
        yes_button.show()
 
610
        yes_button.set_can_default(True)
 
611
 
 
612
 
 
613
        #self.set_has_separator(False)
 
614
        content_area = self.get_content_area()
 
615
        content_area.set_border_width(5)
 
616
        self.set_default_response(Gtk.ResponseType.YES)
 
617
 
 
618
        self.content_box = Gtk.HBox(False, 10)
 
619
        img = Gtk.Image()
 
620
        img.set_from_stock(Gtk.STOCK_DIALOG_QUESTION,Gtk.IconSize.DIALOG)
 
621
        self.content_box.pack_start(img, False, False, 5)
 
622
        label = Gtk.Label(text)
 
623
        label.set_line_wrap(True)
 
624
        self.content_box.pack_start(label,False, False, 5)
 
625
        content_area.pack_start(self.content_box, False, False, 5)
 
626
        self.content_box.show()
 
627
        label.show()
 
628
        img.show()
 
629
 
 
630
def warning(title = _("Warning"), text = ""):
 
631
    """warning - displays a warning to the user, includes an appropriate icon
 
632
    and an OK button
 
633
 
 
634
    aguments:
 
635
    title - a string to be the title of the dialog
 
636
    text - a string describing the warning
 
637
 
 
638
    returns a Gtk.DialogResponse
 
639
    Gtk.ResponseType.OK means the user clicked the "OK" button, otherwise
 
640
    the user dismissed the dialogv(Gtk.ResponseType.DELETE_EVENT)
 
641
 
 
642
    """
 
643
 
 
644
    w = Alert(title,text,Gtk.STOCK_DIALOG_WARNING)
 
645
    response = w.run()
 
646
    w.destroy()
 
647
    return response
 
648
 
 
649
def error(title = _("Error"), text = ""):
 
650
    """error - displays an error to the user, includes an appropriate icon
 
651
    and an OK button
 
652
 
 
653
    aguments:
 
654
    title - a string to be the title of the dialog
 
655
    text - a string describing the error
 
656
 
 
657
    returns a Gtk.DialogResponse
 
658
    Gtk.ResponseType.OK means the user clicked the "OK" button, otherwise
 
659
    the user dismissed the dialogv(Gtk.ResponseType.DELETE_EVENT)
 
660
 
 
661
    """
 
662
 
 
663
    e = Alert(title,text,Gtk.STOCK_DIALOG_ERROR)
 
664
    response = e.run()
 
665
    e.destroy()
 
666
    return response
 
667
 
 
668
 
 
669
def info(title = _("Information"), text = ""):
 
670
    """info - displays information to the user, includes an appropriate
 
671
    icon and an OK button
 
672
 
 
673
    aguments:
 
674
    title - a string to be the title of the dialog
 
675
    text - a string providing the information
 
676
 
 
677
    returns a Gtk.DialogResponse
 
678
    Gtk.ResponseType.OK means the user clicked the "OK" button, otherwise
 
679
    the user dismissed the dialogv(Gtk.ResponseType.DELETE_EVENT)
 
680
 
 
681
    """
 
682
 
 
683
    i = Alert(title,text,Gtk.STOCK_DIALOG_INFO)
 
684
    response = i.run()
 
685
    i.destroy()
 
686
    return response
 
687
 
 
688
class Alert(Gtk.Dialog):
 
689
    """Displays an icon, a message, and an OK button to users.
 
690
    Used by quickly.prompts.info(), quickly.prompts.warning(),
 
691
    and quickly.prompts.error(). 
 
692
 
 
693
    Using
 
694
    #Display a message to the user using one of the helper functions
 
695
    quickly.prompts.info(title,useful_message)
 
696
 
 
697
    Configuring
 
698
    #Add widgets to the content_box member
 
699
    alert = Alert(title, text, image)
 
700
    alert.content_box.pack_end(my_additional_widget, False, False, 5)
 
701
 
 
702
    #change the image by passing in a stock Gtk image
 
703
    alert.set_image(stock_image)
 
704
 
 
705
    Extending
 
706
    An Alert is a Gtk.Dialog.
 
707
 
 
708
    """
 
709
 
 
710
    def __init__(self,title="",text="",image=None):
 
711
        Gtk.Dialog.__init__(self, title,None,Gtk.DialogFlags.MODAL,(Gtk.STOCK_OK, Gtk.ResponseType.OK))
 
712
        #self.set_has_separator(False)
 
713
        content_area = self.get_content_area()
 
714
        content_area.set_border_width(5)
 
715
        self.set_default_response(Gtk.ResponseType.OK)
 
716
 
 
717
        self.content_box = Gtk.HBox(False, 10)
 
718
        label = Gtk.Label(text)
 
719
        label.set_line_wrap(True)
 
720
        self._image = Gtk.Image()
 
721
        self._image.set_from_stock(image,Gtk.IconSize.DIALOG)
 
722
        self.content_box.pack_start(self._image, False, False, 5)
 
723
        self.content_box.pack_end(label,False, False, 5)
 
724
        content_area.pack_start(self.content_box, False, False, 5)
 
725
        self.content_box.show()
 
726
        label.show()
 
727
        self._image.show()
 
728
 
 
729
    def set_image(self, image):
 
730
        self._image.set_from_stock(image,Gtk.IconSize.DIALOG)        
 
731
    
 
732
 
 
733
def save_image_file(title=_("Choose an Image"),path=None):
 
734
    """save_image_file - prompts the user to choose an image file
 
735
 
 
736
    aguments:
 
737
    title - a string to be the title of the dialog
 
738
    path - a string providing a path to a directory where the
 
739
    dialog should start. Defaults to Pictures directory.
 
740
 
 
741
    returns a Gtk.DialogResponse
 
742
    Gtk.ResponseType.OK means the user clicked the "OK" button, otherwise
 
743
    the user clicked "Cancel" or the userdismissed the 
 
744
    dialogv(Gtk.ResponseType.DELETE_EVENT)
 
745
 
 
746
    """
 
747
 
 
748
    sid = SaveImageDialog(title,path)
 
749
    response = sid.run()
 
750
    value = sid.get_filename()
 
751
    sid.destroy()
 
752
    return (response, value)
 
753
 
 
754
 
 
755
class ImageDialog(Gtk.FileChooserDialog):
 
756
    """A base class for OpenImageDialog and SaveImageDialog
 
757
 
 
758
    Sets up typical mime types and file name patterns suitable
 
759
    for saving images.
 
760
 
 
761
    This class is not typically used configured or extended directly,
 
762
    but rather through OpenImageDialog and SaveImageDialog.
 
763
 
 
764
    """
 
765
 
 
766
 
 
767
    def __init__(self, action, button, title="", path=None):
 
768
        """Create an ImageDialog.
 
769
 
 
770
        arguments:
 
771
        action - a file chooser action, either Gtk.FILE_CHOOSER_ACTION_SAVE
 
772
        or Gtk.FILE_CHOOSER_ACTION_OPEN
 
773
        button - a Gtk stock button for the intended action, either
 
774
        Gtk.STOCK_SAVE or Gtk.STOCK_OPEN
 
775
 
 
776
        keyword arguments:
 
777
        title - a title for the dialog, defaults to an empty string
 
778
        path - a directory path to initially open to, defaults to 
 
779
        ~/Pictures
 
780
 
 
781
        """
 
782
 
 
783
        Gtk.FileChooserDialog.__init__(self,title,
 
784
                                            None,
 
785
                                            action,
 
786
                                            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
 
787
                                            button, Gtk.ResponseType.OK))
 
788
 
 
789
        self.set_default_response(Gtk.ResponseType.OK)
 
790
 
 
791
        if path == None:
 
792
            path = GLib.get_user_special_dir(GLib.USER_DIRECTORY_PICTURES)        
 
793
        self.set_current_folder(path)
 
794
 
 
795
        self._filter = Gtk.FileFilter()
 
796
        self._filter.set_name("All files")
 
797
        self._filter.add_pattern("*")
 
798
        self.add_filter(self._filter)
 
799
 
 
800
        self._filter = Gtk.FileFilter()
 
801
        self._filter.set_name("Images")
 
802
        self._filter.add_mime_type("image/png")
 
803
        self._filter.add_mime_type("image/jpeg")
 
804
        self._filter.add_mime_type("image/gif")
 
805
        self._filter.add_pattern("*.png")
 
806
        self._filter.add_pattern("*.jpg")
 
807
        self._filter.add_pattern("*.gif")
 
808
        self._filter.add_pattern("*.tif")
 
809
        self._filter.add_pattern("*.xpm")
 
810
        self.add_filter(self._filter)
 
811
        self.set_do_overwrite_confirmation(True)          
 
812
 
 
813
class SaveImageDialog(ImageDialog):
 
814
    """
 
815
    A dialog to prompt the user for a place to save an image file.
 
816
 
 
817
    Using
 
818
    #Collect a location using the quickly.prompts.save_image_file()
 
819
    #helper function
 
820
    response, path = save_image_file(title)
 
821
    if response == Gtk.ResponseType.OK:
 
822
        save_to_path = path
 
823
 
 
824
    Configuring
 
825
    #Modify the _filter member
 
826
    sid._filter.add_mime_type("image/svg")
 
827
    sid._filter.add_pattern("*.svg")
 
828
 
 
829
    Extending
 
830
    A SaveImageDialog is an ImageDialog which is a Gtk.FileChooserDialog
 
831
 
 
832
    """
 
833
 
 
834
    def __init__(self, title="Choose File Location", path=None):
 
835
        """Create a SaveImageDialog.
 
836
 
 
837
        keyword arguments:
 
838
        title - a title for the dialog, defaults to an empty string
 
839
        path - a directory path to initially open to, defaults to 
 
840
        ~/Pictures
 
841
 
 
842
        """
 
843
 
 
844
        ImageDialog.__init__(self,Gtk.FileChooserAction.SAVE, Gtk.STOCK_SAVE, title,path)
 
845
 
 
846
class OpenImageDialog(ImageDialog):
 
847
    """
 
848
    A dialog to prompt the user for an image to open
 
849
 
 
850
    Using
 
851
    #Collect a location using the quickly.prompts.open_image_file()
 
852
    #helper function
 
853
    response, path = open_image_file(title)
 
854
    if response == Gtk.ResponseType.OK:
 
855
        path_to_image = path
 
856
 
 
857
    Configuring
 
858
    #Modify the _filter member
 
859
    sid._filter.add_mime_type("image/svg")
 
860
    sid._filter.add_pattern("*.svg")
 
861
 
 
862
    Extending
 
863
    A SaveImageDialog is an ImageDialog which is a Gtk.FileChooserDialog
 
864
 
 
865
    """
 
866
 
 
867
    def __init__(self, title="Choose File Location", path=None):
 
868
        """Create an OpenImageDialog.
 
869
 
 
870
        keyword arguments:
 
871
        title - a title for the dialog, defaults to an empty string
 
872
        path - a directory path to initially open to, defaults to 
 
873
        ~/Pictures
 
874
 
 
875
        """
 
876
        ImageDialog.__init__(self,Gtk.FileChooserAction.OPEN, Gtk.STOCK_OPEN, title,path)
 
877
 
 
878
def open_image_file(title=_("Choose an Image"),path=None):
 
879
    """open_image_file - prompts the user to choose an image file
 
880
 
 
881
    aguments:
 
882
    title - a string to be the title of the dialog
 
883
    path - a string providing a path to a directory where the
 
884
    dialog should start. Defaults to Pictures directory.
 
885
 
 
886
     returns a tuple of (Gtk.DialogResponse, str)
 
887
    Gtk.ResponseType.OK means the user clicked the "OK" button, otherwise
 
888
    the user cancelled (Gtk.ResponseType.CANCEL) or dismissed the dialog
 
889
    (Gtk.ResponseType.DELETE_EVENT)
 
890
    The str is the path to the image chosen by the user, if any.
 
891
 
 
892
 
 
893
    """
 
894
 
 
895
    oid = OpenImageDialog(title,path)
 
896
    response = oid.run()
 
897
    value = oid.get_filename()
 
898
    oid.destroy()
 
899
    return (response, value)
 
900
 
 
901
def choose_directory(title=_("Choose a Directory"),path=None):
 
902
    """choose_directory - prompts the user to choose an directory
 
903
 
 
904
    aguments:
 
905
    title - a string to be the title of the dialog
 
906
    path - a string providing a path to a directory where the
 
907
    dialog should start.
 
908
 
 
909
 
 
910
    returns a tuple of (Gtk.DialogResponse, str)
 
911
    Gtk.ResponseType.OK means the user clicked the "OK" button, otherwise
 
912
    the user cancelled (Gtk.ResponseType.CANCEL) or dismissed the dialog
 
913
    (Gtk.ResponseType.DELETE_EVENT)
 
914
    The str is the path to the directory chosen by the user, if any.
 
915
 
 
916
    """
 
917
 
 
918
    dcd = DirectoryChooserDialog(title, path)
 
919
    response = dcd.run()
 
920
    value = dcd.get_filename()
 
921
    dcd.destroy()
 
922
    return (response, value)
 
923
 
 
924
class DirectoryChooserDialog(Gtk.FileChooserDialog):
 
925
    """A Dialog to prompt the user to choose a directory path.
 
926
 
 
927
    Using
 
928
    #prompt the user to provide a directory path using 
 
929
    quickly.prompts.choose_directory(title)
 
930
 
 
931
    Configuring
 
932
    #A DirectoryChooseDialog is a Gtk.FileChooserDialog, so you can
 
933
    #use Gtk.FileChooseDialog members
 
934
    dcd = DirectoryChooserDialog(title)
 
935
    dcd.set_local_only(False)
 
936
 
 
937
    Extending
 
938
    #A DirectoryChooseDialog is a Gtk.FileChooserDialog
 
939
 
 
940
    """
 
941
 
 
942
    def __init__(self, title, path=None):
 
943
        """Creates a DirectoryChooseDialog
 
944
 
 
945
        arguments:
 
946
        title - A title for the dialog
 
947
 
 
948
        keyword arguments:
 
949
        path - a default location for opening the dialogs
 
950
 
 
951
        """
 
952
 
 
953
        Gtk.FileChooserDialog.__init__(self, title,
 
954
                                    None,
 
955
                                    Gtk.FileChooserAction.SELECT_FOLDER,
 
956
                                    (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
 
957
                                    Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
 
958
        self.set_default_response(Gtk.ResponseType.OK)
 
959
        if path is not None:
 
960
            self.set_current_folder(path)
 
961
 
 
962
 
 
963
if __name__ == "__main__":
 
964
    """test code to try out the dialogs"""
 
965
    #these don't have return values to test for
 
966
    warning("Warning Prompt","Warning Prompt")
 
967
    info("Information Prompt","Information Prompt")
 
968
    error("Error Prompt","Error Prompt")
 
969
 
 
970
    #the rest of values to test for
 
971
    response, val = choose_directory("directory choose test")
 
972
    if response == Gtk.ResponseType.OK:
 
973
        print "response was OK"
 
974
    else:
 
975
        print "response was not OK"
 
976
    print "selected directory was " + str(val)
 
977
 
 
978
    response, val = open_image_file("image open test")
 
979
    if response == Gtk.ResponseType.OK:
 
980
        print "response was OK"
 
981
    else:
 
982
        print "response was not OK"
 
983
    print "selected locations was " + str(val)
 
984
 
 
985
    response, val = save_image_file("image save test")
 
986
    if response == Gtk.ResponseType.OK:
 
987
        print "response was OK"
 
988
    else:
 
989
        print "response was not OK"
 
990
    print "selected locations was " + str(val)
 
991
 
 
992
    reponse, val = string("String select test","String select test")
 
993
    if response == Gtk.ResponseType.OK:
 
994
        print "response was OK"
 
995
    else:
 
996
        print "response was not OK"
 
997
    print "string was " + str(val)
 
998
 
 
999
    reponse, val = date("Date select test","Date select test")
 
1000
    if response == Gtk.ResponseType.OK:
 
1001
        print "response was OK"
 
1002
    else:
 
1003
        print "response was not OK"
 
1004
    print "date was " + str(val)
 
1005
 
 
1006
    reponse, val = integer("Integer select test","Integer select test",default_value=20)
 
1007
    if response == Gtk.ResponseType.OK:
 
1008
        print "response was OK"
 
1009
    else:
 
1010
        print "response was not OK"
 
1011
    print "integer was " + str(val)
 
1012
 
 
1013
    reponse, val = decimal("Decimal select test","Decimal select test",default_value=20,digits=5)
 
1014
    if response == Gtk.ResponseType.OK:
 
1015
        print "response was OK"
 
1016
    else:
 
1017
        print "response was not OK"
 
1018
    print "decimal was " + str(val)
 
1019
 
 
1020
    reponse, val = price("Price select test","Price select test",default_value=20)
 
1021
    if response == Gtk.ResponseType.OK:
 
1022
        print "response was OK"
 
1023
    else:
 
1024
        print "response was not OK"
 
1025
    print "price was " + str(val)
 
1026
 
 
1027
    response = yes_no("Yes/No Test","Yes/No Test", "_Yes Verb","_No Verb")
 
1028
    if response == Gtk.ResponseType.YES:
 
1029
        print "response was yes"
 
1030
 
 
1031