Subversion Repositories Scribus

Rev

Rev 17396 | Rev 18692 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3072 subik 1
# -*- coding: utf-8 -*-
2
 
3161 subik 3
""" This is a simple 'Calendar creation wizard' for Scribus. It's a fully
3072 subik 4
rewritten Calender.py from Scribus examples. Enjoy.
5
 
6
DESCRIPTION & USAGE:
7
This script needs Tkinter. It will create a GUI with available options
3100 subik 8
for easy calendar page creation. You'll get new pages with calendar
9
tables into a new document you are asked for. Position of the
10
objects in page is calculated with the "golden-ratio" aspect from the
3072 subik 11
page margins.
12
 
13
Steps to create:
14
    1) Fill requested values in the Calendar dialog
15
    2) You will be prompted for new document
16
    3) You will be prompted for new paragraph style which will be used
17
       in calendar text frames. It could be changed later.
18
 
14638 subik 19
There are 2 types of calendar supported:
3100 subik 20
    1) Classic calendar with one month matrix per page. I suggest
3072 subik 21
       here PORTRAIT orientation.
14638 subik 22
    2) Horizontal event calendar with one week per page with huge place
23
       for human inputs. There should be LANDSCAPE imho.
24
    3) Horizontal event calendar with one week per page with huge place
25
       for human inputs. There should be LANDSCAPE imho.
3072 subik 26
 
3099 mrdocs 27
But everything works with both orientations well of course too.
3072 subik 28
 
14638 subik 29
AUTHORS:
6519 subik 30
    Petr Vanek <petr@scribus.info>
14638 subik 31
    Bernhard Reiter <ockham@raz.or.at>
3072 subik 32
 
33
LICENSE:
3100 subik 34
This program is free software; you can redistribute it and/or modify
3072 subik 35
it under the terms of the GNU General Public License as published by
36
the Free Software Foundation; either version 2 of the License, or
37
(at your option) any later version.
38
 
39
This program is distributed in the hope that it will be useful,
40
but WITHOUT ANY WARRANTY; without even the implied warranty of
41
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
42
GNU General Public License for more details.
43
 
44
You should have received a copy of the GNU General Public License
45
along with this program; if not, write to the Free Software
18122 mrdocs 46
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
3072 subik 47
 
48
"""
49
 
50
import sys
51
import calendar
52
import datetime
53
 
54
try:
55
    from scribus import *
56
except ImportError:
57
    print "This Python script is written for the Scribus scripting interface."
58
    print "It can only be run from within Scribus."
59
    sys.exit(1)
60
 
61
try:
62
    # I wish PyQt installed everywhere :-/
63
    from Tkinter import *
64
    from tkFont import Font
65
except ImportError:
66
    print "This script requires Python's Tkinter properly installed."
67
    messageBox('Script failed',
68
               'This script requires Python\'s Tkinter properly installed.',
69
               ICON_CRITICAL)
70
    sys.exit(1)
71
 
72
 
73
localization = {
13020 subik 74
'Catalan' :
75
    [['Gener', 'Febrer', 'Març', 'Abril', 'Maig',
76
      'Juny', 'Juliol', 'Agost', 'Setembre',
77
      'Octubre', 'Novembre', 'Desembre'],
78
     ['Dilluns', 'Dimarts', 'Dimecres', 'Dijous', 'Divendres', 'Dissabte', 'Diumenge']],
79
'Catalan-short' :
80
    [['Gener', 'Febrer', 'Març', 'Abril', 'Maig',
81
      'Juny', 'Juliol', 'Agost', 'Setembre',
82
      'Octubre', 'Novembre', 'Desembre'],
83
     ['Dl', 'Dm', 'Dc', 'Dj', 'Dv', 'Ds', 'Dg']],
84
# Catalan by "Cesc Morata" <atarom@gmail.com>
3100 subik 85
'Czech' :
3072 subik 86
    [['Leden', 'Únor', 'Březen', 'Duben', 'Květen',
87
        'Červen', 'Červenec', 'Srpen', 'Září',
88
        'Říjen', 'Listopad', 'Prosinec'],
89
     ['Pondělí','Úterý','Středa','Čtvrtek','Pátek','Sobota', 'Neděle']],
6519 subik 90
'Czech-short' :
91
    [['Leden', 'Únor', 'Březen', 'Duben', 'Květen',
92
        'Červen', 'Červenec', 'Srpen', 'Září',
93
        'Říjen', 'Listopad', 'Prosinec'],
94
     ['Po', 'Út', 'St', 'Čt', 'Pá', 'So', 'Ne']],
16355 mrdocs 95
# Croatian by daweed
96
'Croatian' :
97
    [['Siječanj', 'Veljača', 'Ožujak', 'Travanj', 'Svibanj',
98
        'Lipanj', 'Srpanj', 'Kolovoz', 'Rujan',
99
        'Listopad', 'Studeni', 'Prosinac'],
100
     ['Ponedjeljak','Utorak','Srijeda','Četvrtak','Petak','Subota', 'Nedjelja']],
101
 
9571 mrdocs 102
'Dutch' :
103
    [['Januari', 'Februari', 'Maart', 'April',
104
      'Mei', 'Juni', 'Juli', 'Augustus', 'September',
105
      'Oktober', 'November', 'December'],
106
     ['Maandag','Dinsdag','Woensdag','Donderdag','Vrijdag','Zaterdag', 'Zondag']],
107
# Dutch by "Christoph Schäfer" <christoph-schaefer@gmx.de>
3100 subik 108
'English' :
3072 subik 109
    [['January', 'February', 'March', 'April',
110
      'May', 'June', 'July', 'August', 'September',
111
      'October', 'November', 'December'],
112
     ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday', 'Sunday']],
6519 subik 113
'English-short' :
114
    [['January', 'February', 'March', 'April', 'May',
115
      'June', 'July', 'August', 'September', 'October',
116
      'November', 'December'],
117
     ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']],
3845 tsoots 118
'Finnish' :
119
    [['Tammikuu', 'Helmikuu', 'Maaliskuu', 'Huhtikuu',
120
      'Toukokuu', 'Kesäkuu', 'Heinäkuu', 'Elokuu', 'Syyskuu',
121
      'Lokakuu', 'Marraskuu', 'Joulukuu'],
122
     ['ma','ti','ke','to','pe','la', 'su']],
3100 subik 123
'French':
3072 subik 124
    [['Janvier', u'F\xe9vrier', 'Mars', 'Avril',
125
      'Mai', 'Juin', 'Juillet', u'Ao\xfbt', 'Septembre',
126
      'Octobre', 'Novembre', u'D\xe9cembre'],
127
     ['Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi','Dimanche']],
3100 subik 128
'German' :
3072 subik 129
    [['Januar', 'Februar', u'M\xe4rz', 'April',
130
      'Mai', 'Juni', 'Juli', 'August', 'September',
131
      'Oktober', 'November', 'Dezember'],
132
     ['Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag','Sonntag']],
14638 subik 133
'German (Austrian)' :
134
    [[u'J\xe4nner', 'Feber', u'M\xe4rz', 'April',
135
      'Mai', 'Juni', 'Juli', 'August', 'September',
136
      'Oktober', 'November', 'Dezember'],
137
     ['Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag','Sonntag']],
15682 petr 138
# Hungarian by Gergely Szalay szalayg@gmail.com       
139
'Hungarian' :
140
    [['Január', 'Február', 'Március', 'Április',
141
       'Május', 'Június', 'Július', 'Augusztus', 'Szeptember',
142
       'Október', 'November', 'December'],
143
    ['Hétfő','Kedd','Szerda','Csütörtök','Péntek','Szombat','Vasárnap']],
3072 subik 144
'Italian' :
145
    [['Gennaio', 'Febbraio', 'Marzo', 'Aprile',
6519 subik 146
       'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre',
147
       'Ottobre', 'Novembre', 'Dicembre'],
13757 jghali 148
    [u'Luned\xec', u'Marted\xec', u'Mercoled\xec', u'Gioved\xec', u'Venerd\xec', 'Sabato', 'Domenica']],
14821 subik 149
# Norwegian by Joacim Thomassen joacim@net.homelinux.org
150
'Norwegian' :
151
    [['Januar', 'Februar','Mars', 'April','Mai', 'Juni','Juli', 'August','September', 'Oktober', 'November', 'Desember'],
152
     ['Mandag', 'Tirsdag','Onsdag', 'Torsdag','Fredag', 'Lørdag','Søndag']],
3530 subik 153
# Polish by "Łukasz [DeeJay1] Jernaś" <deejay1@nsj.srem.pl>
154
'Polish' :
155
    [['Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj',
156
      'Czerwiec', 'Lipiec', 'Sierpień', 'Wrzesień',
157
      'Październik', 'Listopad', 'Grudzień'],
158
     ['Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota', 'Niedziela']],
3072 subik 159
'Portuguese' :
160
    [['Janeiro', 'Fevereiro', u'Mar\xe7o', 'Abril',
11980 subik 161
      'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro',
3072 subik 162
      'Outubro', 'Novembro', 'Dezembro'],
163
     ['Segunda-feira', u'Ter\xe7a-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', u'S\xe1bado', 'Domingo']],
14378 subik 164
# Romanian by Costin Stroie <costinstroie@eridu.eu.org>
165
'Romanian' :
166
    [['Ianuarie', 'Februarie', 'Martie', 'Aprilie',
167
      'Mai', 'Iunie', 'Iulie', 'August', 'Septembrie',
168
      'Octombrie', 'Noiembrie', 'Decembrie'],
169
     ['Luni','Mar\xc8\x9bi','Miercuri','Joi','Vineri','S\xc3\xa2mb\xc4\x83t\xc4\x83', 'Duminic\xc4\x83']],
3704 mrdocs 170
'Russian' :
171
    [['Январь', 'Февраль', 'Март', 'Апрель',
172
      'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь',
173
      'Октябрь', 'Ноябрь', 'Декабрь'],
174
     ['Понедельник','Вторник','Среда','Четверг','Пятница','Суббота', 'Воскресенье']],
9765 mrdocs 175
'Slovak' :
176
    [['Január', 'Február', 'Marec', 'Apríl',
177
      'Máj', 'Jún', 'Júl', 'August', 'September',
178
      'Október', 'November', 'December'],
179
      ['Pondelok','Utorok','Streda','Štvrtok','Piatok','Sobota', 'Nedeľa']],
180
'Slovak-short' :
181
    [['Január', 'Február', 'Marec', 'Apríl',
182
      'Máj', 'Jún', 'Júl', 'August', 'September',
183
      'Október', 'November', 'December'],
184
      ['Po','Ut','St','Št','Pi','So', 'Ne']],
3072 subik 185
'Spanish' :
10568 subik 186
    [['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo',
3072 subik 187
      'Junio', 'Julio', 'Agosto', 'Septiembre',
188
      'Octubre', 'Noviembre', 'Diciembre'],
4035 cbradney 189
     ['Lunes', 'Martes', u'Mi\xe9rcoles', 'Jueves', 'Viernes', u'S\xe1bado', 'Domingo']],
190
'Swedish' :
191
    [['Januari', 'Februari','Mars', 'April','Maj', 'Juni','Juli', 'Augusti','September', 'Oktober', 'November', 'December'],
192
     ['Måndag', 'Tisdag','Onsdag', 'Torsdag','Fredag', 'Lördag','Söndag']]
3072 subik 193
}
194
 
195
 
196
from math import sqrt
197
 
198
class ScCalendar:
199
    """ Parent class for all calendar types """
200
 
14638 subik 201
    def __init__(self, year, months=[], firstDay=calendar.SUNDAY, drawSauce=True, sepMonths='/', lang='English'):
202
        """ Setup basic things """
3072 subik 203
        # params
204
        self.drawSauce = drawSauce # draw supplementary image?
205
        self.year = year
206
        self.months = months
14638 subik 207
        self.lang = lang
208
        # day order
209
        self.dayOrder = localization[self.lang][1]
210
        if firstDay == calendar.SUNDAY:
211
            dl = self.dayOrder[:6]
212
            dl.insert(0, self.dayOrder[6])
213
            self.dayOrder = dl
214
        self.mycal = calendar.Calendar(firstDay)
3072 subik 215
        self.layerImg = 'Calendar image'
216
        self.layerCal = 'Calendar'
14638 subik 217
        self.pStyleDate = "Date" # paragraph styles
218
        self.pStyleWeekday = "Weekday"
219
        self.pStyleMonth = "Month"
220
        self.pStyleWeekNo = "WeekNo"
221
        self.masterPage = "Weekdays"
222
        self.sepMonths = sepMonths
3072 subik 223
        # settings
224
        self.firstPage = True # create only 2nd 3rd ... pages. No 1st one.
225
        calendar.setfirstweekday(firstDay)
226
        progressTotal(len(months))
227
 
228
    def setupDocVariables(self):
229
        """ Compute base metrics here. Page layout is bordered by margins and
230
        virtually divided by golden mean 'cut' in the bottom. The calendar is
231
        in the bottom part - top is occupied with empty image frame. """
232
        page = getPageSize()
233
        self.pagex = page[0]
234
        self.pagey = page[1]
235
        marg = getPageMargins()
14638 subik 236
        # See http://docs.scribus.net/index.php?lang=en&page=scripterapi-page#-getPageMargins
237
        self.margint = marg[0]
238
        self.marginl = marg[1]
239
        self.marginr = marg[2]
3072 subik 240
        self.marginb = marg[3]
241
        self.width = self.pagex - self.marginl - self.marginr
242
        self.height = self.pagey - self.margint - self.marginb
243
 
244
    def goldenMean(self, aSize):
245
        """ Taken from samples/golden-mean.py."""
246
        return aSize * ((sqrt(5) - 1)/2)
247
 
3161 subik 248
    def applyTextToFrame(self, aText, aFrame):
249
        """ Insert the text with style. """
250
        setText(aText, aFrame)
14638 subik 251
        setStyle(self.pStyleDate, aFrame)
3161 subik 252
 
3072 subik 253
    def createCalendar(self):
14638 subik 254
        """ Walk through months dict and call monthly sheet """
3072 subik 255
        if not newDocDialog():
3099 mrdocs 256
            return 'Create a new document first, please'
14638 subik 257
        createParagraphStyle(name=self.pStyleDate, alignment=ALIGN_RIGHT)
258
        createParagraphStyle(name=self.pStyleWeekday, alignment=ALIGN_RIGHT)
259
        createParagraphStyle(name=self.pStyleMonth)
260
        createParagraphStyle(name=self.pStyleWeekNo, alignment=ALIGN_RIGHT)
3072 subik 261
        originalUnit = getUnit()
262
        setUnit(UNIT_POINTS)
263
        self.setupDocVariables()
264
        if self.drawSauce:
265
            createLayer(self.layerImg)
266
        createLayer(self.layerCal)
14638 subik 267
        self.setupMasterPage()
3072 subik 268
        run = 0
269
        for i in self.months:
270
            run += 1
271
            progressSet(run)
14638 subik 272
            cal = self.mycal.monthdatescalendar(self.year, i + 1)
273
            self.createMonthCalendar(i, cal)
3072 subik 274
        setUnit(originalUnit)
275
        return None
276
 
277
    def createLayout(self):
14638 subik 278
        """ Create the page and optional bells and whistles around """
3072 subik 279
        self.createPage()
280
        if self.drawSauce:
281
            setActiveLayer(self.layerImg)
282
            self.createImage()
283
        setActiveLayer(self.layerCal)
284
 
285
    def createPage(self):
286
        """ Wrapper to the new page with layers """
287
        if self.firstPage:
288
            self.firstPage = False
14638 subik 289
            newPage(-1, self.masterPage) # create a new page using the masterPage
290
            deletePage(1) # now it's safe to delete the first page
3072 subik 291
            gotoPage(1)
292
            return
14638 subik 293
        newPage(-1, self.masterPage)
3072 subik 294
 
14638 subik 295
class ScEventCalendar(ScCalendar):
14821 subik 296
    """ Parent class for event
14638 subik 297
        (horizontal event, vertical event) calendar types """
3072 subik 298
 
14638 subik 299
    def __init__(self, year, months = [], firstDay = calendar.SUNDAY, drawSauce=True, sepMonths='/', lang='English'):
300
        ScCalendar.__init__(self, year, months, firstDay, drawSauce, sepMonths, lang)
301
 
302
    def printMonth(self, cal, month, week):
303
            """ Print the month name(s) """
304
            if week[6].day < 7:
305
                    if (week == cal[len(cal)-1]):
306
                            self.createHeader(localization[self.lang][0][month] + self.sepMonths + localization[self.lang][0][(month+1)%12])
307
                    elif ((month-1) not in self.months):
308
                            self.createHeader(localization[self.lang][0][(month-1)%12] + self.sepMonths + localization[self.lang][0][month])
309
            else:
310
                    self.createHeader(localization[self.lang][0][month])
311
 
312
    def createMonthCalendar(self, month, cal):
313
        """ Draw one week calendar per page """
314
        for week in cal:
315
            # Avoid duplicate week around the turn of the months:
316
            # Only include week:
317
            # * If it's not the first week in a month, or, if it is:
318
            # * If it starts on the first weekday
319
            # * If the month before it isn't included
320
            if (week != cal[0]) or (week[0].day == 1) or ((month-1) not in self.months):
321
                                self.createLayout()
322
                                self.printMonth(cal, month, week)
323
                                self.printWeekNo(week)
324
 
325
                                for day in week:
326
                                    self.printDay(day)
327
 
328
class ScHorizontalEventCalendar(ScEventCalendar):
3072 subik 329
    """ One day = one row calendar. I suggest LANDSCAPE orientation.\
330
        One week per page."""
331
 
14638 subik 332
    def __init__(self, year, months = [], firstDay = calendar.SUNDAY, drawSauce=True, sepMonths='/', lang='English'):
333
        ScEventCalendar.__init__(self, year, months, firstDay, drawSauce, sepMonths, lang)
3072 subik 334
 
335
    def setupDocVariables(self):
336
        """ Compute base metrics here. Page layout is bordered by margins and
337
        virtually divided by golden mean 'cut' in the bottom. The calendar is
338
        in the bottom part - top is occupied with empty image frame. """
14638 subik 339
        # golden mean
3072 subik 340
        ScCalendar.setupDocVariables(self)
341
        self.gmean = self.width - self.goldenMean(self.width) + self.marginl
342
        # calendar size = gmean
343
        # rows and cols
344
        self.rowSize = self.height / 8
345
 
14638 subik 346
    def printWeekNo(self, week):
14821 subik 347
        """ Dummy for now
14638 subik 348
            (for this type of calendar - see ScVerticalEventCalendar) """
349
        return
3072 subik 350
 
14638 subik 351
    def printDay(self, j):
352
        """ Print a given day """
353
        cel = createText(self.gmean + self.marginl,
354
                         self.margint + (1 + (j.weekday()-calendar.firstweekday())%7) * self.rowSize,
355
                         self.width - self.gmean, self.rowSize)
356
        setText(str(j.day), cel)
357
        setStyle(self.pStyleDate, cel)
358
 
3072 subik 359
    def createHeader(self, monthName):
14638 subik 360
        """ Draw calendar header: Month name """
3072 subik 361
        cel = createText(self.gmean + self.marginl, self.margint,
362
                            self.width - self.gmean, self.rowSize)
14638 subik 363
        setText(monthName, cel)
364
        setStyle(self.pStyleMonth, cel)
3072 subik 365
 
366
    def createImage(self):
367
        """ Wrapper for everytime-the-same image frame. """
368
        if self.drawSauce:
369
            createImage(self.marginl, self.margint, self.gmean, self.height)
370
 
14638 subik 371
    def setupMasterPage(self):
372
        """ Create a master page (not used for this type of calendar """
373
        createMasterPage(self.masterPage)
14821 subik 374
        closeMasterPage()
3072 subik 375
 
14638 subik 376
class ScVerticalCalendar(ScCalendar):
14821 subik 377
    """ Parent class for vertical
14638 subik 378
        (classic, vertical event) calendar types """
3072 subik 379
 
14638 subik 380
    def __init__(self, year, months = [], firstDay = calendar.SUNDAY, drawSauce=True, sepMonths='/', lang='English'):
381
        ScCalendar.__init__(self, year, months, firstDay, drawSauce, sepMonths, lang)
382
 
3072 subik 383
    def setupDocVariables(self):
384
        """ Compute base metrics here. Page layout is bordered by margins and
385
        virtually divided by golden mean 'cut' in the bottom. The calendar is
386
        in the bottom part - top is occupied with empty image frame. """
387
        # gloden mean
388
        ScCalendar.setupDocVariables(self)
389
        self.gmean = self.height - self.goldenMean(self.height) + self.margint
390
        # calendar size
391
        self.calHeight = self.height - self.gmean + self.margint
392
        # rows and cols
393
        self.rowSize = self.gmean / 8
394
        self.colSize = self.width / 7
395
 
14638 subik 396
    def setupMasterPage(self):
397
        """ Draw invariant calendar header: Days of the week """
398
        createMasterPage(self.masterPage)
399
        editMasterPage(self.masterPage)
400
        setActiveLayer(self.layerCal)
401
        rowCnt = 0
402
        for j in self.dayOrder: # days
403
            cel = createText(self.marginl + rowCnt*self.colSize,
404
                             self.calHeight + self.rowSize,
405
                             self.colSize, self.rowSize)
406
            setText(j, cel)
407
            setStyle(self.pStyleWeekday, cel)
408
            rowCnt+=1
409
        closeMasterPage()
410
 
411
    def createHeader(self, monthName):
412
        """ Draw calendar header: Month name """
413
        header = createText(self.marginl, self.calHeight, self.width, self.rowSize)
414
        setText(monthName, header)
415
        setStyle(self.pStyleMonth, header)
416
 
417
    def createImage(self):
418
        """ Wrapper for everytime-the-same image frame. """
419
        if self.drawSauce:
420
            createImage(self.marginl, self.margint,
421
                        self.width, self.calHeight - self.margint)
422
 
423
class ScClassicCalendar(ScVerticalCalendar):
424
    """ Calendar matrix creator itself. I suggest PORTRAIT orientation.
425
        One month per page."""
426
 
427
    def __init__(self, year, months = [], firstDay = calendar.SUNDAY, drawSauce=True, sepMonths='/', lang='English'):
428
        ScVerticalCalendar.__init__(self, year, months, firstDay, drawSauce, sepMonths, lang)
429
 
430
    def createMonthCalendar(self, month, cal):
431
        """ Create a page and draw one month calendar on it """
3072 subik 432
        self.createLayout()
14638 subik 433
        self.createHeader(localization[self.lang][0][month])
3072 subik 434
        rowCnt = 2
14638 subik 435
        for week in cal:
3072 subik 436
            colCnt = 0
14638 subik 437
            for day in week:
3072 subik 438
                cel = createText(self.marginl + colCnt * self.colSize,
439
                                 self.calHeight + rowCnt * self.rowSize,
440
                                 self.colSize, self.rowSize)
441
                colCnt += 1
14638 subik 442
                if day.month == month + 1:
443
                                        setText(str(day.day), cel)
444
                                        setStyle(self.pStyleDate, cel)
3072 subik 445
            rowCnt += 1
446
 
14638 subik 447
class ScVerticalEventCalendar(ScVerticalCalendar, ScEventCalendar):
448
    """ One day = one column calendar. I suggest LANDSCAPE orientation.\
449
        One week per page."""
3072 subik 450
 
14638 subik 451
    def __init__(self, year, months = [], firstDay = calendar.SUNDAY, drawSauce=True, sepMonths='/', lang='English'):
452
        ScVerticalCalendar.__init__(self, year, months, firstDay, drawSauce, sepMonths, lang)
453
        ScEventCalendar.__init__(self, year, months, firstDay, drawSauce, sepMonths, lang)
3072 subik 454
 
14638 subik 455
    def printDay(self, j):
456
        """ Print a given day """
457
        cel = createText(self.marginl + ((j.weekday()-calendar.firstweekday())%7)*self.colSize,
458
                         self.calHeight + self.rowSize,
459
                         self.colSize/5, self.rowSize)
460
        setText(str(j.day), cel)
461
        setStyle(self.pStyleDate, cel)
3072 subik 462
 
14638 subik 463
    def printWeekNo(self, week):
464
        """ Print the week number for the given week"""
465
        weekCel = createText(self.marginl, self.calHeight, self.width, self.rowSize)
14821 subik 466
        # Week number: of this week's Thursday.
14638 subik 467
        # See http://docs.python.org/library/datetime.html#datetime.date.isocalendar
468
        # Note that week calculation isn't perfectly universal yet:
469
        # http://en.wikipedia.org/wiki/Week_number#Week_number
470
        setText(str(week[(calendar.THURSDAY-calendar.firstweekday())%7].isocalendar()[1]), weekCel)
471
        setStyle(self.pStyleWeekNo, weekCel)
472
 
3072 subik 473
class TkCalendar(Frame):
474
    """ GUI interface for Scribus calendar wizard.
475
        It's ugly and very simple. I can say I hate Tkinter :-/"""
476
 
477
    def __init__(self, master=None):
478
        """ Setup the dialog """
14638 subik 479
        # reference to the localization dictionary
6519 subik 480
        self.key = 'English'
3072 subik 481
        Frame.__init__(self, master)
482
        self.grid()
483
        self.master.resizable(0, 0)
484
        self.master.title('Scribus Calendar Wizard')
485
        #define widgets
486
        self.statusVar = StringVar()
487
        self.statusLabel = Label(self, textvariable=self.statusVar)
3099 mrdocs 488
        self.statusVar.set('Select Options and Values')
3072 subik 489
        # langs
10568 subik 490
        # change the height = to match number of langs.
3072 subik 491
        self.langLabel = Label(self, text='Select language:')
10568 subik 492
 
493
        self.langFrame = Frame(self)
494
        self.langFrame.pack()
495
        self.langScrollbar = Scrollbar(self.langFrame)
496
        self.langScrollbar.pack(fill=Y, side=RIGHT)
497
        self.langListbox = Listbox(self.langFrame, selectmode=SINGLE, height=10, yscrollcommand=self.langScrollbar.set)
498
        self.langListbox.pack(fill=X,side=LEFT)
499
        self.langScrollbar.config(command=self.langListbox.yview)
500
 
6519 subik 501
        keys = localization.keys()
502
        keys.sort()
503
        for i in keys:
3072 subik 504
            self.langListbox.insert(END, i)
505
        self.langButton = Button(self, text='Change language', command=self.languageChange)
506
        # calendar type
507
        self.typeLabel = Label(self, text='Calendar type')
508
        self.typeVar = IntVar()
509
        self.typeClRadio = Radiobutton(self, text='Classic', variable=self.typeVar, value=0)
14638 subik 510
        self.typeEvRadio = Radiobutton(self, text='Event (Horizontal)', variable=self.typeVar, value=1)
511
        self.typeVERadio = Radiobutton(self, text='Event (Vertical)', variable=self.typeVar, value=2)
3072 subik 512
        # start of week
3099 mrdocs 513
        self.weekStartsLabel = Label(self, text='Week begins with:')
3072 subik 514
        self.weekVar = IntVar()
515
        self.weekMondayRadio = Radiobutton(self, text='Mon', variable=self.weekVar, value=calendar.MONDAY)
516
        self.weekSundayRadio = Radiobutton(self, text='Sun', variable=self.weekVar, value=calendar.SUNDAY)
517
        # year
518
        self.yearLabel = Label(self, text='Year:')
519
        self.yearVar = StringVar()
520
        self.yearEntry = Entry(self, textvariable=self.yearVar, width=4)
521
        self.wholeYearLabel = Label(self, text='Whole year:')
522
        self.wholeYear = IntVar()
523
        self.wholeYearCheck = Checkbutton(self, command=self.setWholeYear, variable=self.wholeYear)
524
        # months
525
        self.monthLabel = Label(self, text='Months:')
526
        self.monthListbox = Listbox(self, selectmode=MULTIPLE, height=12)
527
        # layout stuff
3099 mrdocs 528
        self.imageLabel = Label(self, text='Draw Image Frame:')
3072 subik 529
        self.imageVar = IntVar()
530
        self.imageCheck = Checkbutton(self, variable=self.imageVar)
14638 subik 531
        # Months separator
532
        self.sepMonthsLabel = Label(self, text='Months separator:')
533
        self.sepMonthsVar = StringVar()
534
        self.sepMonthsEntry = Entry(self, textvariable=self.sepMonthsVar, width=4)
3072 subik 535
        # closing/running
536
        self.okButton = Button(self, text="OK", width=6, command=self.okButonn_pressed)
537
        self.cancelButton = Button(self, text="Cancel", command=self.quit)
538
        # setup values
539
        self.weekMondayRadio.select()
540
        self.typeClRadio.select()
541
        self.yearVar.set(str(datetime.date(1, 1, 1).today().year))
14638 subik 542
        self.sepMonthsVar.set('/')
3072 subik 543
        self.imageCheck.select()
544
        # make layout
545
        self.columnconfigure(0, pad=6)
546
        currRow = 0
547
        self.statusLabel.grid(column=0, row=currRow, columnspan=4)
548
        currRow += 1
549
        self.langLabel.grid(column=0, row=currRow, sticky=W)
550
        self.monthLabel.grid(column=3, row=currRow, sticky=W)
551
        currRow += 1
10568 subik 552
        self.langFrame.grid(column=0, row=currRow, rowspan=6, sticky=N)
3072 subik 553
        self.typeLabel.grid(column=1, row=currRow, sticky=E)
554
        self.typeClRadio.grid(column=2, row=currRow, sticky=W)
555
        self.monthListbox.grid(column=3, row=currRow, rowspan=8)
556
        currRow += 1
557
        self.typeEvRadio.grid(column=2, row=currRow, sticky=W)
558
        currRow += 1
14638 subik 559
        self.typeVERadio.grid(column=2, row=currRow, sticky=W)
560
        currRow += 1
3072 subik 561
        self.weekStartsLabel.grid(column=1, row=currRow, sticky=N+E)
562
        self.weekMondayRadio.grid(column=2, row=currRow, sticky=N+W)
563
        currRow += 1
564
        self.weekSundayRadio.grid(column=2, row=currRow, sticky=N+W)
565
        currRow += 1
566
        self.yearLabel.grid(column=1, row=currRow, sticky=N+E)
567
        self.yearEntry.grid(column=2, row=currRow, sticky=N+W)
568
        currRow += 1
569
        self.wholeYearLabel.grid(column=1, row=currRow, sticky=N+E)
570
        self.wholeYearCheck.grid(column=2, row=currRow, sticky=N+W)
571
        currRow += 1
572
        self.imageLabel.grid(column=1, row=currRow, sticky=N+E)
573
        self.imageCheck.grid(column=2, row=currRow, sticky=N+W)
574
        self.langButton.grid(column=0, row=currRow)
14638 subik 575
        currRow += 1
576
        self.sepMonthsLabel.grid(column=1, row=currRow, sticky=N+E)
577
        self.sepMonthsEntry.grid(column=2, row=currRow, sticky=N+W)
3072 subik 578
        currRow += 3
579
        self.rowconfigure(currRow, pad=6)
580
        self.okButton.grid(column=1, row=currRow, sticky=E)
581
        self.cancelButton.grid(column=2, row=currRow, sticky=W)
582
        # fill the values
583
        self.realLangChange()
584
 
6519 subik 585
    def languageChange(self, lang='English'):
3072 subik 586
        """ Called by Change button. Get language list value and
587
            call real re-filling. """
588
        ix = self.langListbox.curselection()
589
        if len(ix)==0:
3099 mrdocs 590
            self.statusVar.set('Select a language, please')
3072 subik 591
            return
592
        self.realLangChange(lang=self.langListbox.get(ix[0]))
593
 
6519 subik 594
    def realLangChange(self, lang='English'):
3072 subik 595
        """ Real widget setup. Ot takes values from localization dictionary.
596
        [0] = months, [1] Days """
597
        self.key = lang
598
        self.monthListbox.delete(0, END)
599
        self.wholeYear.set(0)
600
        for i in localization[lang][0]:
601
            self.monthListbox.insert(END, i)
602
 
603
    def setWholeYear(self):
604
        """ All/none months selection. It's called after "Whole year" check button
605
        click. """
606
        if self.wholeYear.get() == 1:
607
            self.monthListbox.selection_set(0, END)
608
        else:
609
            self.monthListbox.selection_clear(0, END)
610
 
611
    def okButonn_pressed(self):
612
        """ User variables testing and preparing """
613
        # year
614
        try:
615
            year = self.yearVar.get().strip()
616
            if len(year) != 4:
617
                raise ValueError
618
            year = int(year, 10)
619
        except ValueError:
620
            self.statusVar.set('Year must be in the "YYYY" format e.g. 2005.')
621
            return
622
        # months
623
        selMonths = self.monthListbox.curselection()
624
        if len(selMonths) == 0:
625
            self.statusVar.set('At least one month must be selected.')
626
            return
14638 subik 627
        months = []
3072 subik 628
        for i in selMonths:
14638 subik 629
            months.append(int(i))
3072 subik 630
        # draw images etc.
631
        if self.imageVar.get() == 0:
632
            draw = False
633
        else:
634
            draw = True
635
        # create calendar (finally)
636
        if self.typeVar.get() == 0:
14638 subik 637
            cal = ScClassicCalendar(year, months, self.weekVar.get(), draw, self.sepMonthsVar.get(), self.key)
638
        elif self.typeVar.get() == 1:
639
            cal = ScHorizontalEventCalendar(year, months, self.weekVar.get(), draw, self.sepMonthsVar.get(), self.key)
3072 subik 640
        else:
14638 subik 641
            cal = ScVerticalEventCalendar(year, months, self.weekVar.get(), draw, self.sepMonthsVar.get(), self.key)
3100 subik 642
        self.master.withdraw()
3072 subik 643
        err = cal.createCalendar()
644
        if err != None:
3100 subik 645
            self.master.deiconify()
3072 subik 646
            self.statusVar.set(err)
647
        else:
648
            self.quit()
649
 
650
    def quit(self):
651
        self.master.destroy()
652
 
653
 
654
def main():
655
    """ Application/Dialog loop with Scribus sauce around """
656
    try:
657
        statusMessage('Running script...')
658
        progressReset()
659
        root = Tk()
660
        app = TkCalendar(root)
661
        root.mainloop()
662
    finally:
17396 fschmid 663
        if haveDoc() > 0:
3072 subik 664
            redrawAll()
665
        statusMessage('Done.')
666
        progressReset()
667
 
668
if __name__ == '__main__':
669
    main()
15682 petr 670