Subversion Repositories Scribus

Rev

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

Rev Author Line No. Line
3957 mrdocs 1
#!/usr/bin/env python
1048 cbradney 2
# -*- coding: utf-8 -*-
3
 
4
# ****************************************************************************
3957 mrdocs 5
#  This program is free software; you can redistribute it and/or modify
1048 cbradney 6
#  it under the terms of the GNU General Public License as published by
7
#  the Free Software Foundation; either version 2 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 General Public License for more details.
14
#
15
#  You should have received a copy of the GNU General Public License
16
#  along with this program; if not, write to the Free Software
17
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3957 mrdocs 18
#
1048 cbradney 19
# ****************************************************************************
20
 
21
"""
22
******************************************************************************
23
 
24
DESCRIPTION & USAGE:
540 subik 25
This script needs Tkinter. It will create a GUI with an alphabetical list
26
of fonts using the names as they will be shown in Scribus. User can select
27
one or more fonts and create an example sheet(s) to print or create a PDF
28
from. It is heavily commented to make it easier for the user to adjust it
29
for his / her own needs.
222 Franz 30
 
3957 mrdocs 31
Note: this version needs read/write access to .scribus directory in users
1048 cbradney 32
home. You will also need Python Imaging Library (PIL) installed.
33
If your system does not meet these requirements then change showPreviewPanel
34
to a value of 0. This will disable the new preview features.
540 subik 35
 
1048 cbradney 36
******************************************************************************
540 subik 37
 
1048 cbradney 38
First release    : 30/12/2003
3957 mrdocs 39
This release     : v0.8tk final (released 24th Nov 2005)
1066 cbradney 40
Copyright        : (C) 2003 - 2005 Steve Callcott
41
Latest releases
42
and support      : www.firstwish.co.uk/sjc/scribus/index.php
43
Maintainer       : Steve Callcott 2003 - 2005
3002 mrdocs 44
Email            : stotte@firstwish.co.uk
540 subik 45
 
46
For revision history see the ChangeLog file.
47
Bugs and future plans are listed in the TODO file.
48
See NEWS for new features since last version.
49
 
3957 mrdocs 50
WHATS NEW v0.8tk Final:
51
Cleaned up the checkbox labels and layout.
3448 mrdocs 52
 
3957 mrdocs 53
WHATS NEW v0.8tk Preview 3:
54
Calls the new Scribus zoomDocument() function to make the completed font
55
sample document fit in Scribus window.
3012 mrdocs 56
 
3957 mrdocs 57
Grey out "Start page number count from first page" when "Print TOC" is
58
not checked as without a table of contents the first page would always
59
start on the same page number making this option irrelevant.
3002 mrdocs 60
 
3957 mrdocs 61
WHATS NEW v0.8tk Preview 2:
62
Replaced the newDoc() with newDocument(). Have not put any fallback code
63
for use with earlier Scribus versions.
64
 
65
When using double sided option we now make use of Scribus ability to display
66
pages side by side as default. You may need to zoom out to view the
67
complete document width.
68
 
69
WHATS NEW v0.8tk Preview 1:
70
Rearanged the initialisation. If no fonts are found for the Table of
71
Contents, page numbers and font sample labels, the script shows a
72
message box listing the problem and a possible solution as well as a message
1072 cbradney 73
to the console.
74
 
3957 mrdocs 75
A Scribus messagebox alerts the user if Tkinter is not found. Previously
76
this message was only printed to the console.
1066 cbradney 77
 
3957 mrdocs 78
Now able to do a dummy run to calculate and report the amount of samples
79
that will fit on a page. This enables the script to correctly calculate
80
how many sheets will be required. Previously it was always assumed that
81
there would be 3 sample blocks on a sheet. This is now not always the case.
540 subik 82
 
3957 mrdocs 83
Added menu. Also added "about" and "settings" dialogs.
84
 
85
Sample rows can be selected or unselected to save on paper. The settings are
86
automatically saved when changed and can be set as user defaults.
87
 
88
User can choose to have page numbers count from first page of the toc instead
89
of the first page of samples. This can be helpful if wanting to quickly look
90
up a font in the toc and then using the Scribus page navigator dialog to go to
91
the actual page on the screen to view it without printing it out.
92
 
93
Added initial support for a sample paragraph. The sample paragraph defaults
94
to "off" due to the amount of space it uses on the page.
95
 
96
Some widgets read their defaults from a config dictionary.
97
 
98
Many code cleanups. Classes used for settings storage have been replaced with
99
dictionaries to make it easier for users to customise.
100
 
1048 cbradney 101
******************************************************************************
540 subik 102
"""
103
 
1048 cbradney 104
import sys
105
import os
3957 mrdocs 106
import cPickle
222 Franz 107
 
3957 mrdocs 108
 
109
showPreviewPanel = 1 # change to 0 to permanently hide the preview
110
TEMP_PATH = os.path.join(os.path.expanduser('~'), '.scribus')
111
CONFIG_PATH = os.path.join(os.path.expanduser('~'), '.scribus/fontsampler')
112
 
113
 
1048 cbradney 114
try:
115
    import scribus
116
except ImportError,err:
3957 mrdocs 117
    print 'This Python script is written for the Scribus scripting interface.'
118
    print 'It can only be run from within Scribus.'
1048 cbradney 119
    sys.exit(1)
222 Franz 120
 
3957 mrdocs 121
 
1048 cbradney 122
try:
123
    from Tkinter import *
124
except ImportError,err:
3957 mrdocs 125
    print 'This script will not work without Tkinter'
126
    scribus.messageBox('Error','This script will not work without Tkinter\nPlease install and try again',
127
                    scribus.ICON_WARNING)
1048 cbradney 128
    sys.exit(1)
129
 
130
 
3957 mrdocs 131
if not os.path.exists(CONFIG_PATH):
132
    try:
133
        print 'Attempting to creating configuration file directory...'
134
        os.mkdir(CONFIG_PATH)
135
        print 'Success, now testing for write access of new directory...'
136
        if os.access(CONFIG_PATH, os.W_OK):
137
            print 'Write access ok.'
138
        else:
139
            print 'Error, unable to write to .scribus/fontsampler directory.'
140
    except:
141
        CONFIG_PATH = ''
142
        print 'Failed to make configuration file directory,'
143
        print 'do you have a .scribus directory in your home directory?'
144
        print 'font sampler will not be able to save your preferences'
1048 cbradney 145
 
146
 
3957 mrdocs 147
try:
148
    import Image
149
except ImportError,err:
150
    print 'You need to install Python Imaging Library (PIL).'
151
    print 'If using gentoo then you need to emerge /dev-python/imaging'
152
    print 'If using an RPM based linux distribution then you add python-imaging or similar.'
153
    print 'Script will continue without the font preview panel.'
154
    showPreviewPanel = 0
1048 cbradney 155
 
156
 
3957 mrdocs 157
try:
158
    import ImageTk
159
except ImportError,err:
160
    print 'Module ImageTk not found, font preview disabled'
161
    showPreviewPanel = 0
1048 cbradney 162
 
3957 mrdocs 163
 
1048 cbradney 164
if showPreviewPanel:
3957 mrdocs 165
    if not os.path.exists(TEMP_PATH):
166
        print '.scribus folder not found, disabling font preview panel'
1048 cbradney 167
        showPreviewPanel = 0
3957 mrdocs 168
    if not os.access(TEMP_PATH, os.W_OK):
169
        print 'Unable to write to .scribus folder, disabling font preview panel'
170
        showPreviewPanel = 0
1048 cbradney 171
 
172
 
3957 mrdocs 173
# A few globals for use later...
174
gSamplePic = None
175
gPreviewId = None
1048 cbradney 176
 
3957 mrdocs 177
#*************************************************************************
1048 cbradney 178
 
3957 mrdocs 179
WINDOW_TITLE = 'Font Sampler v0.8tk - Steve Callcott'
180
SUPPORT_PAGE = 'www.firstwish.co.uk/sjc/scribus/index.php'
1048 cbradney 181
 
3957 mrdocs 182
fontsListFixed = (
183
    'Luxi Mono Regular',
184
    'Nimbus Mono L Regular',
185
    'Courier 10 Pitch Regular',
186
    'Courier New Regular',
187
    'Courier Regular',
188
    'Andale Mono Regular',
189
    'Larabiefont Regular'
190
)
222 Franz 191
 
3957 mrdocs 192
fontsListProportional = (
193
    'Nimbus Sans L Regular',
194
    'Luxi Sans Regular',
195
    'Bitstream Vera Sans',
196
    'Helvetica',
197
    'Arial Regular'
198
)
222 Franz 199
 
3957 mrdocs 200
defaultPrefs = {
201
    'wantDoubleSided': 0,
202
    'paperSize':'A4',           # currently PAPER_LETTER or PAPER_A4
203
    'wantTOC': 1,
204
    'wantBindingOffset': 0,
205
    'wantPageNumbers': 1,
206
    'wantPageOneOnFirst': 0,
207
    'wantAlphabet' : 1,
208
    'want6Point' : 1,
209
    'want8Point' : 1,
210
    'want10Point' : 1,
211
    'want12Point' : 1,
212
    'want16Point' : 1,
213
    'want20Point' : 1,
214
    'want32Point' : 1,
215
    'wantParagraph' : 0         # Uses a lot of space so default is off
216
}
222 Franz 217
 
3957 mrdocs 218
userPrefs = {}
222 Franz 219
 
3957 mrdocs 220
geometriesList = [
221
    {
222
        'paperName' : 'A4',
223
        'paperSize' : scribus.PAPER_A4,
224
        'paperWidth' : 595,
225
        'paperHeight' : 842,
226
        'paperTopMargin' : 60,
227
        'paperBottomMargin' : 50,
228
        'paperLeftMargin' : 50,
229
        'paperRightMargin' : 50,
230
        'paperBinding' : 16,
231
        'tocRowsPerPage' : 57,
232
        'paperPageNumVertOffset' : 16
233
    },
234
    {
235
        'paperName' : 'US Letter',
236
        'paperSize' : scribus.PAPER_LETTER,
237
        'paperWidth' : 612,
238
        'paperHeight' : 792,
239
        'paperTopMargin' : 27,
240
        'paperBottomMargin' : 45,
241
        'paperLeftMargin' : 50,
242
        'paperRightMargin' : 50,
243
        'paperBinding' : 18,
244
        'tocRowsPerPage' : 56,
245
        'paperPageNumVertOffset' : 16
246
    }
247
]
222 Franz 248
 
3957 mrdocs 249
# define our data dictionary and some of the data...
250
dD = {
251
    'tocHeaderTitle' : 'Table of Contents',
252
    'tocCharsInRow' : 75,
253
    'previewpanelFontHeight' : 28,
254
    'previewpanelSampleText' : 'Woven silk pyjamas exchanged for blue quartz'
255
}
222 Franz 256
 
3957 mrdocs 257
samplesHeader = {
258
    'fontSize' : 16,
259
    'lineSpace' : 15,
260
    'textHeight' : 23
261
}
222 Franz 262
 
3957 mrdocs 263
# Use \xBC etc to insert Hex ascii chars into the sample strings below.
264
sampleAlphabet = {
265
    'fontSize' : 10.5,
266
    'lineSpace' : 12,
267
    'textString' : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#?$*&',
268
    'textHeight' : 18
269
}
222 Franz 270
 
3957 mrdocs 271
sample6Point = {
272
    'fontSize' : 6,
273
    'lineSpace' : 6,
274
    'textString' : 'This line is in 6 point',
275
    'textHeight' : 13
276
}
222 Franz 277
 
3957 mrdocs 278
sample8Point = {
279
    'fontSize' : 8,
280
    'lineSpace' : 8,
281
    'textString' : 'This line is in 8 point',
282
    'textHeight' : 16
283
}
284
 
285
sample10Point = {
286
    'fontSize' : 10,
287
    'lineSpace' : 11,
288
    'textString' : 'This line is in 10 point',
289
    'textHeight' : 19
290
}
291
 
292
sample12Point = {
293
    'fontSize' : 12,
294
    'lineSpace' : 11,
295
    'textString' : 'This line is in 12 point',
296
    'textHeight' : 21
297
}
298
 
299
sample16Point = {
300
    'fontSize' : 16,
301
    'lineSpace' : 13,
302
    'textString' : 'This line is in 16 point',
303
    'textHeight' : 26
304
}
305
 
306
sample20Point = {
307
    'fontSize' : 20,
308
    'lineSpace' : 16,
309
    'textString' : 'This line is in 20 point',
310
    'textHeight' : 31
311
}
312
 
313
sample32Point = {
314
    'fontSize' : 32,
315
    'lineSpace' : 29,
316
    'textString' : 'This line is in 32 point',
317
    'textHeight' : 49
318
}
319
 
320
sampleParagraph = {
321
    'fontSize' : 9,
322
    'lineSpace' : 10.8,
323
    'textHeight' : 175
324
}
325
 
326
sampleParagraphText = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut a sapien. \
327
Aliquam aliquet purus molestie dolor. Integer quis eros ut erat posuere dictum. \
328
Curabitur dignissim. Integer orci. Fusce vulputate lacus at ipsum. Quisque in libero \
329
nec mi laoreet volutpat. Aliquam eros pede, scelerisque quis, tristique cursus, \
330
placerat convallis, velit. Nam condimentum. Nulla ut mauris. Curabitur adipiscing, \
331
mauris non dictum aliquam, arcu risus dapibus diam, nec sollicitudin quam erat quis \
332
ligula. Aenean massa nulla, volutpat eu, accumsan et, fringilla eget, odio. \
333
Nulla placerat porta justo. Nulla vitae turpis.\n\nPraesent lacus.Lorem ipsum dolor sit \
334
amet, consectetuer adipiscing elit. Pellentesque habitant morbi tristique senectus \
335
et netus et malesuada fames ac turpis egestas. Quisque vel erat eget diam \
336
consectetuer iaculis. Cras ante velit, suscipit et, porta tempus, dignissim quis, \
337
magna. Vivamus viverra, turpis nec rhoncus ultricies, diam turpis eleifend nisl, a \
338
eleifend ante felis ac sapien. Integer bibendum. Suspendisse in mi non neque \
339
bibendum convallis. Suspendisse potenti. Sed sit amet purus at felis adipiscing \
340
aliquam. Vivamus et nisl sit amet mauris aliquet molestie. Integer tortor massa, \
341
aliquam a, lacinia nonummy, sagittis nec, eros.'
342
 
343
#*************************************************************************
344
 
345
def set_font_fixed(fontList):
346
    """Find a matching font for the Table of Contents."""
347
    availableFonts = scribus.getFontNames()
1048 cbradney 348
    found = 0
3957 mrdocs 349
    for f in fontList:
350
        if found:
1048 cbradney 351
            break
3957 mrdocs 352
        for i in availableFonts:
353
            if not found:
1048 cbradney 354
                if f == i:
3957 mrdocs 355
                    return f
1048 cbradney 356
                    found = 1
357
                    break
3957 mrdocs 358
    if not found:
359
        errorList = ''
360
        for j in fontList:
361
            errorList = errorList + j + '\n'
362
        errorMessage ='No suitable fixed width font found.\nPlease install at least one of these fixed width fonts:\n'+errorList
363
        print errorMessage
364
        raise Exception(errorMessage)
222 Franz 365
 
366
 
3957 mrdocs 367
def set_font_proportional(fontList):
368
    """Find a matching font for the page numbers and font names above samples."""
369
    availableFonts = scribus.getFontNames()
1048 cbradney 370
    found = 0
3957 mrdocs 371
    for p in fontList:
372
        if found:
1048 cbradney 373
            break
3957 mrdocs 374
        for i in availableFonts:
375
            if not found:
1048 cbradney 376
                if p == i:
3957 mrdocs 377
                    return p
1048 cbradney 378
                    found = 1
379
                    break
3957 mrdocs 380
    if not found:
381
        errorList = ''
382
        for j in fontList:
383
            errorList = errorList + j + '\n'
384
        errorMessage = 'No suitable proportional font found.\nPlease install at least one of these proportional fonts:\n'+errorList
385
        print errorMessage
386
        raise Exception(errorMessage)
222 Franz 387
 
388
 
3957 mrdocs 389
def save_user_conf(path):
390
    """Save the data to the save file on the path specified by CONFIG_PATH.
222 Franz 391
 
3957 mrdocs 392
    Note initialisation unsets the CONFIG_PATH if it failed to verify or create"""
393
    if not path == '':
394
        try:
395
            file = open(os.path.join(path,'fontsampler.conf'), 'w')
396
            data = {
397
                'a' : defaultPrefs,
398
                'b' : userPrefs
399
            }
400
            cPickle.dump(data, file)
401
            file.close()
402
        except:
403
            print 'failed to save data'
222 Franz 404
 
405
 
3957 mrdocs 406
def restore_user_conf(path):
407
    """Restore the data from the save file on the path specified by CONFIG_PATH."""
408
    try:
409
        file = open(os.path.join(path,'fontsampler.conf'), 'r')
410
        data = cPickle.load(file)
411
        file.close()
412
        defaultPrefs.update(data['a'])
413
        userPrefs.update(data['b'])
414
    except:
415
        userPrefs.update(defaultPrefs)
416
        print 'failed to load saved data so using default values defined in the script'
222 Franz 417
 
418
 
3957 mrdocs 419
def set_page_geometry(dD, geometriesList, paperSize, wantBindingOffset):
420
    """This is the experimental replacement paper size setting function.
222 Franz 421
 
3957 mrdocs 422
    Each paper size and other associated data are stored in a dictionary.
423
    The dictionaries are stored in a list. We copy appropriate dictionary
424
    and custom calculations into a work dictionary for use.
425
    The advantage of this is its easier to add new paper definitions.
426
    Returns a new dictionary, use .update to merge in new values into dD.
427
    """
428
    try:
429
        result={}
430
        for i in geometriesList:
431
            if i['paperName'] == paperSize:
432
                dD.update(i)
222 Franz 433
 
3957 mrdocs 434
        result['paperLeftMarginOdd'] = dD['paperLeftMargin'] + \
435
                                       dD['paperBinding']
436
        result['paperRightMarginEven'] = dD['paperRightMargin'] + \
437
                                         dD['paperBinding']
438
        result['paperTextHeight'] = dD['paperHeight'] - \
439
                                    dD['paperTopMargin'] - \
440
                                    dD['paperBottomMargin']
441
        result['paperMargins'] =  dD['paperLeftMargin'],dD['paperRightMargin'],dD['paperTopMargin'],dD['paperBottomMargin']
442
 
443
        # if we are adding a binding offset to the margins then we will have less width for our text...
444
        if wantBindingOffset:
445
            result['paperTextWidth'] = dD['paperWidth'] - \
446
                                       dD['paperLeftMargin'] - \
447
                                       dD['paperRightMargin'] - \
448
                                       dD['paperBinding'] - \
449
                                       2
450
        else:
451
            result['paperTextWidth'] = dD['paperWidth'] - \
452
                                       dD['paperLeftMargin'] - \
453
                                       dD['paperRightMargin'] - \
454
                                       2
455
        return result
456
    except:
457
        errorMessage = 'set_page_geometry() failure: %s' % sys.exc_info()[1]
458
        print errorMessage
459
 
460
 
461
def set_odd_even(pageNum):
462
    """ Sets the left margin position.
463
 
464
    Checks the number passed to it and sets left margin accordingly.
465
    Call once after each new page is created.
1048 cbradney 466
    Returns 1 if even and 0 if odd page.
467
    """
468
    if pageNum % 2 == 0:
469
        isEvenPage = 1                                          # Even side
470
    else:
471
        isEvenPage = 0                                          # Odd side
222 Franz 472
 
3957 mrdocs 473
    if userPrefs['wantBindingOffset']:
474
        if isEvenPage and userPrefs['wantDoubleSided']:         # Even (when double sided)
475
            dD['paperLeftSide'] = dD['paperLeftMargin'] + 1
1048 cbradney 476
        else:                                                   # Odd side
3957 mrdocs 477
            dD['paperLeftSide'] = dD['paperLeftMarginOdd'] + 1
1048 cbradney 478
    else:                                                       # No binding
3957 mrdocs 479
        dD['paperLeftSide'] = dD['paperLeftMargin'] + 1
1048 cbradney 480
    return isEvenPage
222 Franz 481
 
482
 
3957 mrdocs 483
def draw_sample_row(font, fontSize, lineSpace, textString, x, y, w, h, getSizeOnly):
484
    """Creates one row of samples or a header for the top of the block.
485
 
486
    Called once by draw_sample_block() to create a block label then as many times
487
    as required to create each actual sample found in the list of dictionaries
488
    containing each samples definition.
489
    """
490
    if not getSizeOnly:
1048 cbradney 491
        f = scribus.createText(x, y, w, h)
492
        scribus.insertText(textString, 0, f)
3957 mrdocs 493
        scribus.setFont(font, f)
1048 cbradney 494
        scribus.setFontSize(fontSize, f)
495
        scribus.setLineSpacing(lineSpace, f)
496
        scribus.setTextAlignment(0, f)
497
    return y + h + 1
222 Franz 498
 
499
 
3957 mrdocs 500
def draw_sample_block(fontName, x, y, w, getSizeOnly):
501
    """Drawing of a complete sample block starts from here.
502
 
503
    Iterates through each sample declared in the "samples" tuple. Places one
504
    complete block using the font specified in fontname.
505
    Note top line on page is drawn outside of this function. This ensures ease
506
    of returning same height of every sample block. Line could have been drawn
507
    at top inside this function and page finalised with line at bottom instead.
508
    If getSizeOnly is true then returns the overall height of the entire text
509
    block but without actually placing it.
510
    """
1048 cbradney 511
    startPos = y
3957 mrdocs 512
    # Note there are 2 points of space before horizontal line at bottom of block.
513
    # This 2 points will not appear at top of page so need to add it.
222 Franz 514
 
3957 mrdocs 515
    # set space below horizontal line to the top of the text block
516
    y = y + 4
222 Franz 517
 
3957 mrdocs 518
    # (note there is one extra point inserted by addSampleRow() for each row generated)...
222 Franz 519
 
3957 mrdocs 520
    # first need a header...
521
    y = draw_sample_row(dD['bookstylePropFont'], samplesHeader['fontSize'], samplesHeader['lineSpace'], fontName, x, y, w, samplesHeader['textHeight'], getSizeOnly)
222 Franz 522
 
3957 mrdocs 523
    if userPrefs['wantAlphabet']:
524
        y = draw_sample_row(fontName, sampleAlphabet['fontSize'], sampleAlphabet['lineSpace'], sampleAlphabet['textString'], x, y, w, sampleAlphabet['textHeight'], getSizeOnly)
525
 
526
    if userPrefs['want6Point']:
527
        y = draw_sample_row(fontName, sample6Point['fontSize'], sample6Point['lineSpace'], sample6Point['textString'], x, y, w, sample6Point['textHeight'], getSizeOnly)
528
 
529
    if userPrefs['want8Point']:
530
        y = draw_sample_row(fontName, sample8Point['fontSize'], sample8Point['lineSpace'], sample8Point['textString'], x, y, w, sample8Point['textHeight'], getSizeOnly)
531
 
532
    if userPrefs['want10Point']:
533
        y = draw_sample_row(fontName, sample10Point['fontSize'], sample10Point['lineSpace'], sample10Point['textString'], x, y, w, sample10Point['textHeight'], getSizeOnly)
534
 
535
    if userPrefs['want12Point']:
536
        y = draw_sample_row(fontName, sample12Point['fontSize'], sample12Point['lineSpace'], sample12Point['textString'], x, y, w, sample12Point['textHeight'], getSizeOnly)
537
 
538
    if userPrefs['want16Point']:
539
        y = draw_sample_row(fontName, sample16Point['fontSize'], sample16Point['lineSpace'], sample16Point['textString'], x, y, w, sample16Point['textHeight'], getSizeOnly)
540
 
541
    if userPrefs['want20Point']:
542
        y = draw_sample_row(fontName, sample20Point['fontSize'], sample20Point['lineSpace'], sample20Point['textString'], x, y, w, sample20Point['textHeight'], getSizeOnly)
543
 
544
    if userPrefs['want32Point']:
545
        y = draw_sample_row(fontName, sample32Point['fontSize'], sample32Point['lineSpace'], sample32Point['textString'], x, y, w, sample32Point['textHeight'], getSizeOnly)
546
 
547
    if userPrefs['wantParagraph']:
548
        y = draw_sample_row(fontName, sampleParagraph['fontSize'], sampleParagraph['lineSpace'], sampleParagraphText, x, y, w, sampleParagraph['textHeight'], getSizeOnly)
549
 
550
    y = y + 1   # one extra point of space above bottom Horiz. line
551
 
552
    lineHeight = draw_horiz_line(y, x, w + x, getSizeOnly)
553
    y = y + lineHeight
554
 
1048 cbradney 555
    return y - startPos
222 Franz 556
 
557
 
3957 mrdocs 558
def insert_toc_row(fontName, pageNum, yPos, frame):
559
    """Called once for each content line to be drawn in the text frame."""
1048 cbradney 560
    dotLine = ""
3957 mrdocs 561
    dotQuant = dD['tocCharsInRow'] - len(fontName) - len(str(pageNum)) + 1
1048 cbradney 562
    for i in range(dotQuant):
563
        dotLine = dotLine + '.'
564
    oneLine = fontName + dotLine + str(pageNum) + "\n"
565
    scribus.insertText(oneLine, yPos, frame)
566
    yPos = yPos + len(oneLine) + 0
567
    return yPos
222 Franz 568
 
1048 cbradney 569
 
3957 mrdocs 570
def build_toc_page_template():
571
    """Inserts empty toc template into the currently selected page."""
1048 cbradney 572
    # first put a header on the empty page...
3957 mrdocs 573
    textstring = dD['tocHeaderTitle']
574
    yPos = dD['paperTopMargin'] + 1
575
    header = scribus.createText(dD['paperLeftSide'], yPos, dD['paperTextWidth'], 35)
1048 cbradney 576
    scribus.insertText(textstring, 0, header)
3957 mrdocs 577
    scribus.setFont(dD['bookstylePropFont'], header)
1048 cbradney 578
    scribus.setFontSize(24, header)
579
    scribus.setTextAlignment(1, header)
580
    # now create a text frame for the table of contents...
581
    yPos = yPos + 36
3957 mrdocs 582
    body = scribus.createText(dD['paperLeftSide'], yPos, dD['paperTextWidth'], dD['paperHeight'] - yPos - dD['paperBottomMargin'] - 1)
583
    scribus.setFont(dD['bookstyleFixedFont'], body)
1048 cbradney 584
    scribus.setFontSize(10, body)
585
    scribus.setLineSpacing(12, body)
586
    return body
222 Franz 587
 
588
 
3957 mrdocs 589
def build_toc(tocList):
590
    """Creates all the Table of Contents pages.
591
 
592
    Calls tocPageFramesBuild() to write the header and empty frame for the
593
    toc rows each time a new page is added.
594
    Then calls tocRowAdd() to add each line to the toc frame. Creates new page
595
    each time it completes last row on page.
596
    """
1048 cbradney 597
    rowCount = 0
598
    yPos = 0
599
    tocPageNum = 1
600
    tocPageCount = 1
222 Franz 601
 
1048 cbradney 602
    scribus.newPage(tocPageNum)
3957 mrdocs 603
    isEvenPage = set_odd_even(tocPageNum)
604
    body = build_toc_page_template()             # create frames for new empty page
1048 cbradney 605
    if isEvenPage == 0:
606
        scribus.setTextAlignment(2, body)
607
    else:
608
        scribus.setTextAlignment(0, body)
609
    for i in tocList:
3957 mrdocs 610
        if rowCount == dD['tocRowsPerPage']: # Need to build a new TOC page (count is from zero, not one)
1048 cbradney 611
            tocPageNum = tocPageNum + 1
612
            scribus.newPage(tocPageNum)
3957 mrdocs 613
            isEvenPage = set_odd_even(tocPageNum)
614
            body = build_toc_page_template()
615
            if not isEvenPage:
1048 cbradney 616
                scribus.setTextAlignment(2, body)
617
            else:
618
                scribus.setTextAlignment(0, body)
619
            rowCount = 0
620
            yPos = 0
621
            tocPageCount = tocPageCount + 1
3957 mrdocs 622
        yPos = insert_toc_row(i[0], i[1], yPos, body)
3448 mrdocs 623
        rowCount = rowCount + 1
3957 mrdocs 624
    if userPrefs['wantDoubleSided']:
1048 cbradney 625
        if tocPageCount % 2 != 0:           # Odd page
626
            tocPageNum = tocPageNum + 1
627
            scribus.newPage(tocPageNum)     # Add an extra page if odd number
222 Franz 628
 
629
 
3957 mrdocs 630
def add_page_num(pageNum):
631
    yPos = dD['paperHeight'] - \
632
           dD['paperBottomMargin'] - \
633
           dD['paperPageNumVertOffset']
634
    footer = scribus.createText(dD['paperLeftSide'], yPos, dD['paperTextWidth'], 15)
635
    scribus.insertText('%s' % pageNum, 0, footer)
636
    scribus.setFont(dD['bookstylePropFont'], footer)
1048 cbradney 637
    scribus.setFontSize(9, footer)
638
    scribus.setTextAlignment(1, footer)
639
    scribus.setLineSpacing(10, footer)
222 Franz 640
 
641
 
3957 mrdocs 642
def create_empty_samplepage(pageNum, getSizeOnly):
643
    """Creates a new page and increments page number by one.
644
 
645
    Note getSizeOnly is now evaluated. Will still generate page number increment
646
    but will not actually create the new page or place the number on the page."""
647
    if not getSizeOnly:
648
        scribus.newPage(-1)
649
    pageNum = pageNum + 1
650
    set_odd_even(pageNum)
651
    if not getSizeOnly:
652
        if userPrefs['wantPageNumbers']:
653
            add_page_num(pageNum)
654
    return pageNum
655
 
656
 
657
def draw_horiz_line(yPos, xStart, xEnd, getSizeOnly):
658
    """Draws a line and returns the height.
659
 
660
    If getSizeOnly is set then returns the height it would have
661
    used but without actually creating a line.
662
    """
663
    lineWidth = 1
664
    if not getSizeOnly:
665
        newLine = scribus.createLine(xStart, yPos, xEnd, yPos)
666
        scribus.setLineWidth(lineWidth, newLine)
667
    return lineWidth
668
 
669
 
670
def draw_selection(fontList, getSizeOnly):
671
    """Draws the sample blocks onto the Scribus canvas.
672
 
673
    Measure one font sample block including any horizontal lines and extra
674
    vertical spaces.
675
    Get the amount of vertical space available for the text area between the
676
    top line and top of page number area.
677
    Use these two values to calculate how many complete sample blocks will fit
678
    in the space available. This is the "pageBlocks"
679
    Note we always draw the top horizontal line before placing the blocks. This
680
    is taken into account when calculating the available text area.
681
    Next, if "getSizeOnly" is false we create a page then create the sample
682
    blocks while incrementing a counter until it matches the "pageBlocks".
683
    Reset the counter and create new page. We keep going until we have processed
684
    all the fonts in the selection list.
685
    We update the Scribus progress bar as we create each font sample block.
686
    The returned result is used to update some values in the status bar.
687
    """
3012 mrdocs 688
    progress = 1
689
    scribus.progressReset()
690
    scribus.progressTotal(len(fontList))
1048 cbradney 691
    tocList = []
692
    pageNum = 1
3957 mrdocs 693
    blockCounter = 0
694
    counter = 0
695
    facingPages = scribus.NOFACINGPAGES
696
 
697
    # Just get blocks per page value...
698
    set_odd_even(pageNum)
699
    lineHeight = 1 # include the one point of space below top margin
700
    lineHeight = lineHeight + draw_horiz_line(0, dD['paperLeftSide'], dD['paperLeftSide'] + dD['paperTextWidth'], 1)
701
    usuableArea = dD['paperHeight'] - \
702
                  dD['paperTopMargin'] - \
703
                  lineHeight - \
704
                  dD['paperBottomMargin'] - \
705
                  dD['paperPageNumVertOffset']
706
 
707
    blockHeight = draw_sample_block(fontList[0], dD['paperLeftSide'], 0, dD['paperTextWidth'], 1)
708
    pageBlocks = int(usuableArea / blockHeight)
709
    #print blockHeight
710
    #print "Usuable area %s points high" % usuableArea
711
    #print "Used space on page is %s points high" % (blockHeight * pageBlocks)
712
 
713
    if not getSizeOnly:
714
        # not a dummy run so start by setting up page numbering...
715
        if userPrefs['wantPageOneOnFirst'] and userPrefs['wantTOC']:
716
            tocPageCount = divmod(len(fontList), dD['tocRowsPerPage'])
717
            pageNum = pageNum + tocPageCount[0]
718
            if tocPageCount[1] != 0:
719
                # (adding more to page number as not whole number)
720
                pageNum = pageNum + 1
721
            if userPrefs['wantDoubleSided']:
722
                oddEvenTest = divmod(pageNum, 2)
723
                if oddEvenTest[1] == 0:
724
                    # (adding extra one to start number as odd amount)
725
                    pageNum = pageNum + 1
726
        if userPrefs['wantDoubleSided']:
727
            facingPages = scribus.FACINGPAGES
728
        # now create a new document with empty page and start building...
729
        scribus.newDocument(dD['paperSize'], dD['paperMargins'], scribus.PORTRAIT, 1, scribus.UNIT_POINTS, facingPages, scribus.FIRSTPAGERIGHT)
730
        scribus.zoomDocument(-100)
731
        # A new doc gives us a new page by default so set it up first...
732
        set_odd_even(pageNum)
733
        yPos = dD['paperTopMargin'] + 1
734
        lineHeight = draw_horiz_line(yPos, dD['paperLeftSide'], dD['paperLeftSide'] + dD['paperTextWidth'], getSizeOnly)
735
        yPos = yPos + lineHeight
736
        if userPrefs['wantPageNumbers']:
737
            add_page_num(pageNum)
1048 cbradney 738
        for i in fontList:
3957 mrdocs 739
            # Now place the actual sample block but create a new page if needed...
740
            if counter == pageBlocks:
741
                pageNum = create_empty_samplepage(pageNum, getSizeOnly)
742
                yPos = dD['paperTopMargin'] + 1
743
                lineHeight = draw_horiz_line(yPos, dD['paperLeftSide'], dD['paperLeftSide'] + dD['paperTextWidth'], getSizeOnly)
744
                yPos = yPos + lineHeight
745
                counter = 0
746
            blockHeight = draw_sample_block(i, dD['paperLeftSide'], yPos, dD['paperTextWidth'], getSizeOnly)
747
            yPos = yPos + blockHeight
3012 mrdocs 748
            # and also increment the Scribus progress bar...
749
            scribus.progressSet(progress)
750
            progress = progress + 1
3957 mrdocs 751
            # Add current font to TOC...
752
            tocList.append([i, pageNum])
753
            counter = counter + 1
754
        if userPrefs['wantTOC']:
755
            # Insert table of contents - (before page numbering)...
756
            build_toc(tocList)
1048 cbradney 757
        scribus.gotoPage(1)
3957 mrdocs 758
    return pageBlocks
222 Franz 759
 
760
 
3957 mrdocs 761
def preview_font(app, fontName):
1048 cbradney 762
    """Gets the named font and puts a sample in the preview panel.
763
 
764
    Pick up the temp sample qpixmap file and display it in a canvas object
765
    The temp file is put in the users ".scribus" folder and cleaned up on exit.
766
    We create samplePic as a global as a workaround because the reference count
767
    does not increase when we add the image to the canvas. Therefore python
768
    garbage collection removes our image before we have even displayed it.
769
    Note app.previewPanel is the actual canvas.
770
    """
3957 mrdocs 771
    global gSamplePic
772
    global gPreviewId
773
    scribus.renderFont(fontName, os.path.join(TEMP_PATH,'temp079r.bmp'),dD['previewpanelSampleText'],dD['previewpanelFontHeight'])
1072 cbradney 774
    try:
3957 mrdocs 775
        tempPic = Image.open(os.path.join(TEMP_PATH,'temp079r.bmp'))
776
        tempPic.save(os.path.join(TEMP_PATH,'temp079r.jpeg'),format='JPEG')
777
        tempImage = Image.open(os.path.join(TEMP_PATH,'temp079r.jpeg'))
1072 cbradney 778
        imgDimen = tempPic.getbbox()
3957 mrdocs 779
        gSamplePic = ImageTk.PhotoImage(tempImage)
1072 cbradney 780
        # To center the image use "Half display height minus half the image height"
781
        # preview panel is allegedly 56 (60 less a 2 pixel border top and bottom)
3957 mrdocs 782
        # need to be lower than that to look correct visually...
1072 cbradney 783
        topEdge = (32 - (imgDimen[3] / 2))
3957 mrdocs 784
        gPreviewId = app.previewPanel.create_image(5, topEdge, anchor=NW, image=gSamplePic)
785
        os.remove(os.path.join(TEMP_PATH,'temp079r.bmp'))
786
        os.remove(os.path.join(TEMP_PATH,'temp079r.jpeg'))
1072 cbradney 787
    except IOError:
3957 mrdocs 788
        gSamplePic = None
789
        gPreviewId = app.previewPanel.create_image(0, 0, anchor=NW, image=gSamplePic)
1048 cbradney 790
    return
791
 
792
 
3957 mrdocs 793
class AboutDialog(Toplevel):
794
 
795
    def __init__(self, parent):
796
        Toplevel.__init__(self, parent)
797
        self.transient(parent)
798
        self.title('About')
799
        self.parent = parent
800
        self.result = None
801
        self.resizable(0, 0)
802
 
803
        infoLabel = Label(self, text=WINDOW_TITLE+'\nSupport page at %s' % SUPPORT_PAGE)
804
        infoLabel.pack(padx=5, pady=5)
805
        # now the frame for contents...
806
        contentFrame = Frame(self)
807
        self.btnOk = Button(contentFrame, text='OK', command=self.ok, default=ACTIVE)
808
        self.btnOk.pack(side=LEFT, padx=5, pady=5)
809
        contentFrame.pack()
810
        self.bind('<Return>', self.ok)
811
        self.grab_set()
812
        self.protocol('WM_DELETE_WINDOW', self.ok)
813
        self.initial_focus = self.btnOk
814
        self.wait_window(self)
815
 
816
    def ok(self, event=None):
817
        self.withdraw()
818
        self.update_idletasks()
819
        self.parent.focus_set()
820
        self.destroy()
821
 
822
 
823
class ConfigurationDialog(Toplevel):
824
 
825
    def __init__(self, parent):
826
        Toplevel.__init__(self, parent)
827
        self.transient(parent)
828
        self.title('Configuration')
829
        self.parent = parent
830
        self.result = None
831
        self.resizable(0, 0)
832
 
833
        # Create outer frame...
834
        self.topFrame = Frame(self, bd=1, relief=FLAT)
835
        self.topFrame.grid(row=0, column=0, padx=5, pady=5)
836
 
837
        self.paperSizeLabel = Label(self.topFrame, text='Sample Rows:')
838
        self.paperSizeLabel.grid(row=0, column=0, sticky=W)
839
 
840
        # This frame holds each sample selector...
841
        self.sampleSelectFrame = Frame(self.topFrame, bd=1, relief=RIDGE)
842
        self.sampleSelectFrame.grid(row=1, column=0, padx=0, pady=2)
843
 
844
        # now create the sample selector widgets for the frame...
845
        self.__wantAlphabet = IntVar()
846
        self.btnWantAlphabet = Checkbutton(self.sampleSelectFrame, text='want alphabet row', variable=self.__wantAlphabet, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
847
        self.btnWantAlphabet.grid(row=0, column=0, padx=10, pady=0, sticky=W)
848
        if userPrefs['wantAlphabet']:
849
            self.btnWantAlphabet.select()
850
 
851
        self.__want6Point = IntVar()
852
        self.btnWant6Point = Checkbutton(self.sampleSelectFrame, text='want 6 point row', variable=self.__want6Point, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
853
        self.btnWant6Point.grid(row=1, column=0, padx=10, pady=0, sticky=W)
854
        if userPrefs['want6Point']:
855
            self.btnWant6Point.select()
856
 
857
        self.__want8Point = IntVar()
858
        self.btnWant8Point = Checkbutton(self.sampleSelectFrame, text='want 8 point row', variable=self.__want8Point, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
859
        self.btnWant8Point.grid(row=2, column=0, padx=10, pady=0, sticky=W)
860
        if userPrefs['want8Point']:
861
            self.btnWant8Point.select()
862
 
863
        self.__want10Point = IntVar()
864
        self.btnWant10Point = Checkbutton(self.sampleSelectFrame, text='want 10 point row', variable=self.__want10Point, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
865
        self.btnWant10Point.grid(row=3, column=0, padx=10, pady=0, sticky=W)
866
        if userPrefs['want10Point']:
867
            self.btnWant10Point.select()
868
 
869
        self.__want12Point = IntVar()
870
        self.btnWant12Point = Checkbutton(self.sampleSelectFrame, text='want 12 point row', variable=self.__want12Point, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
871
        self.btnWant12Point.grid(row=4, column=0, padx=10, pady=0, sticky=W)
872
        if userPrefs['want12Point']:
873
            self.btnWant12Point.select()
874
 
875
        self.__want16Point = IntVar()
876
        self.btnWant16Point = Checkbutton(self.sampleSelectFrame, text='want 16 point row', variable=self.__want16Point, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
877
        self.btnWant16Point.grid(row=5, column=0, padx=10, pady=0, sticky=W)
878
        if userPrefs['want16Point']:
879
            self.btnWant16Point.select()
880
 
881
        self.__want20Point = IntVar()
882
        self.btnWant20Point = Checkbutton(self.sampleSelectFrame, text='want 20 point row', variable=self.__want20Point, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
883
        self.btnWant20Point.grid(row=6, column=0, padx=10, pady=0, sticky=W)
884
        if userPrefs['want20Point']:
885
            self.btnWant20Point.select()
886
 
887
        self.__want32Point = IntVar()
888
        self.btnWant32Point = Checkbutton(self.sampleSelectFrame, text='want 32 point row', variable=self.__want32Point, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
889
        self.btnWant32Point.grid(row=7, column=0, padx=10, pady=0, sticky=W)
890
        if userPrefs['want32Point']:
891
            self.btnWant32Point.select()
892
 
893
        self.__wantParagraph = IntVar()
894
        self.btnParagraphSelect = Checkbutton(self.sampleSelectFrame, text='want sample paragraph', variable=self.__wantParagraph, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
895
        self.btnParagraphSelect.grid(row=8, column=0, padx=10, pady=0, sticky=W)
896
        if userPrefs['wantParagraph']:
897
            self.btnParagraphSelect.select()
898
 
899
        self.paperSizeLabel = Label(self.topFrame, text='Paper Sizes:')
900
        self.paperSizeLabel.grid(row=2, column=0, sticky=W)
901
 
902
        self.paperSizeFrame = Frame(self.topFrame, bd=1, relief=RIDGE)
903
        self.paperSizeFrame.grid(row=3, column=0, padx=0, pady=2, sticky=W)
904
 
905
        self.__paper = StringVar()
906
        self.a4papersizeSelect = Radiobutton(self.paperSizeFrame, text='A4', variable=self.__paper, value='A4', command=self.__paperSelectionClick)
907
        self.a4papersizeSelect.grid(row=1, column=0, padx=10, sticky=W)
908
        self.uspapersizeSelect = Radiobutton(self.paperSizeFrame, text='US Letter', variable=self.__paper, value='US Letter', command=self.__paperSelectionClick)
909
        self.uspapersizeSelect.grid(row=2, column=0, padx=10, sticky=W)
910
 
911
        # set to match prefs...
912
        if userPrefs['paperSize'] == 'US Letter':
913
            self.uspapersizeSelect.select()
914
        if userPrefs['paperSize'] == 'A4':
915
            self.a4papersizeSelect.select()
916
 
917
        self.btnFrame = Frame(self.topFrame)
918
        self.btnFrame.grid(row=4, column=0, padx=10, pady=2)
919
        self.btnOk = Button(self.btnFrame, text='OK', command=self.ok)
920
        self.btnOk.grid(row=2, column=0, pady=5)
921
        self.bind('<Return>', self.ok)
922
        self.grab_set()
923
        self.initial_focus = self.btnOk
924
        self.wait_window(self)
925
 
926
 
927
    def __sampleSelectionClick(self):
928
        """Get and store all the selections.
929
 
930
        Just assigns the lot at once. Not worth being picky and only
931
        assigning values that have changed since last time.
932
        """
933
        userPrefs['wantAlphabet'] = self.__wantAlphabet.get()
934
        userPrefs['want6Point'] = self.__want6Point.get()
935
        userPrefs['want8Point'] = self.__want8Point.get()
936
        userPrefs['want10Point'] = self.__want10Point.get()
937
        userPrefs['want12Point'] = self.__want12Point.get()
938
        userPrefs['want16Point'] = self.__want16Point.get()
939
        userPrefs['want20Point'] = self.__want20Point.get()
940
        userPrefs['want32Point'] = self.__want32Point.get()
941
        userPrefs['wantParagraph'] = self.__wantParagraph.get()
942
        self.parent.statusbarUpdate()
943
 
944
    def __paperSelectionClick(self):
945
        userPrefs['paperSize'] = self.__paper.get()
946
        self.parent.statusbarUpdate()
947
 
948
    def ok(self, event=None):
949
        dD.update(set_page_geometry(dD, geometriesList, userPrefs['paperSize'], userPrefs['wantBindingOffset']))
950
        self.withdraw()
951
        self.update_idletasks()
952
        self.parent.focus_set()
953
        self.destroy()
954
 
955
 
222 Franz 956
class Application(Frame):
3957 mrdocs 957
 
1048 cbradney 958
    def __init__(self, master = None):
959
        Frame.__init__(self, master)
222 Franz 960
 
1048 cbradney 961
        self.grid()
222 Franz 962
 
3002 mrdocs 963
        # Remove maximise button and resize. Not good to allow resizable window
964
        # because the listboxes are fixed width...
3957 mrdocs 965
        self.master.resizable(0, 0)
222 Franz 966
 
3957 mrdocs 967
        # build the menu...
968
        menubar = Menu(self)
969
        settingsmenu = Menu(menubar, tearoff=0)
970
        settingsmenu.add_command(label='Configuration', command=self.__configurationDlgShow)
971
        settingsmenu.add_separator()
972
        settingsmenu.add_command(label='Save current settings as user defaults', command=self.__saveCurrentSettingsAsDefaults)
973
        settingsmenu.add_command(label='Restore current settings from defaults', command=self.__restoreCurrentSettingsFromDefault)
974
 
975
        menubar.add_cascade(label='Settings', menu=settingsmenu)
976
        helpmenu = Menu(menubar, tearoff=0)
977
        helpmenu.add_command(label='About', command=self.__aboutDlgShow)
978
        menubar.add_cascade(label='Help', menu=helpmenu)
979
        # display menu...
980
        self.master.config(menu=menubar)
981
 
1048 cbradney 982
        # now start adding our widgets starting with the top frame...
983
        self.listbox_frame = Frame(self)
984
        self.listbox_frame.grid(row=0, column=0, sticky=EW)
222 Franz 985
 
1048 cbradney 986
        # left hand listbox assembly
987
        self.leftListbox_frame = Frame(self.listbox_frame, borderwidth=1, relief=SUNKEN)
988
        self.leftListbox_frame.grid(row=1, column=0)
222 Franz 989
 
3957 mrdocs 990
        self.leftLabel = Label(self.listbox_frame, text='Available Fonts')
1048 cbradney 991
        self.leftLabel.grid(row=0, column=0, sticky=NS)
222 Franz 992
 
1048 cbradney 993
        self.yScroll1 = Scrollbar(self.leftListbox_frame, orient=VERTICAL)
994
        self.yScroll1.grid(row=0, column=1, sticky=NS)
995
        self.xScroll1 = Scrollbar(self.leftListbox_frame, orient=HORIZONTAL)
996
        self.xScroll1.grid(row=1, column=0, sticky=EW)
222 Franz 997
 
1048 cbradney 998
        self.listbox1 = Listbox(self.leftListbox_frame,
999
            xscrollcommand=self.xScroll1.set,
1000
            yscrollcommand=self.yScroll1.set,
1001
            selectmode=EXTENDED,
1002
            height=20, width=40)
1003
        self.listbox1.grid(row=0, column=0, sticky=NSEW)
3957 mrdocs 1004
        self.xScroll1['command'] = self.listbox1.xview
1005
        self.yScroll1['command'] = self.listbox1.yview
222 Franz 1006
 
1048 cbradney 1007
        def __listbox1KeyRelease(event):
1008
            """Check if an Up or Down key has been pressed and released and
3957 mrdocs 1009
            if so the preview panel is refreshed. If the keys are held down
1010
            the file system slows the scroll. Need a timer here to delay
1048 cbradney 1011
            updates."""
3957 mrdocs 1012
            if (event.keysym == 'Down' or event.keysym == 'Up'):
1048 cbradney 1013
                __listbox1DoLogicCallback(self)
222 Franz 1014
 
1048 cbradney 1015
        def __listbox1SingleClick(event):
1016
            """Call this first when listbox1 is clicked with mouse to put focus
1017
            into the listbox. Note we call when mouse click is released, not pressed,
1018
            due to the fact that the listbox does not change the selection until the button
1019
            is released."""
1020
            self.listbox1.focus_set()
1021
            __listbox1DoLogicCallback(self)
3957 mrdocs 1022
        self.listbox1.bind('<ButtonRelease-1>', __listbox1SingleClick)
222 Franz 1023
 
1048 cbradney 1024
        def __listbox1DoLogicCallback(event):
3957 mrdocs 1025
            """Decides if current selection should be previewed.
1066 cbradney 1026
 
1048 cbradney 1027
            Start by counting items in selection list and if equal to one then
1028
            show selected font, ignoring if more or less than one. Then also
3957 mrdocs 1029
            set up buttons logic depending on selection. We bind the FocusIn
1048 cbradney 1030
            to this too so button logic and preview gets updated when focus
1031
            enters the listbox.
3957 mrdocs 1032
            """
1048 cbradney 1033
            # note we are not making use of "self.listbox1.get(ACTIVE)" due to
1034
            # it not getting the real active name. Always one selection behind
1035
            # even though we are doing all this in the ButtonRelease event.
1036
            # Have made a change here. If more than one font name is selected
1037
            # then we just empty the preview.
1038
            names = self.listbox1.curselection()
1039
            if len(names) == 1:
1040
                selectedFont = self.listbox1.get(names[0])
1041
                self.__curSelectedItem(selectedFont)
1042
            else:
1043
                try:
1044
                    app.previewPanel.delete(previewId)
1045
                except:
1046
                    pass
1047
            #else:
3957 mrdocs 1048
                #selectedFont = self.listbox1.get(ACTIVE)
1048 cbradney 1049
                #print selectedFont  # for testing
1050
                #if selectedFont != "":
3957 mrdocs 1051
                    #self.__curSelectedItem(selectedFont)
222 Franz 1052
 
1048 cbradney 1053
            # Now do the button logic...
1054
            self.listbox2.selection_clear(0,END)
1055
            self.__setUpDownActive(0, 0)    # Force a disable if in other box
1056
            if self.listbox1.size() > 0:
1057
                self.__setSelButtonsActive(0, 1)
1058
            else:
1059
                self.__setSelButtonsActive(0, 0)
3957 mrdocs 1060
 
1061
        self.listbox1.bind('<FocusIn>', __listbox1DoLogicCallback)
1048 cbradney 1062
        self.listbox1.bind('<Any-KeyRelease>', __listbox1KeyRelease)
222 Franz 1063
 
1048 cbradney 1064
        def __listbox1DoubleClickCallback(event):
1065
            """The single click event will fire also when left listbox
1066
            is double clicked but we are detecting the single click button up event."""
1067
            self.__listSelectionToRight()
222 Franz 1068
 
3957 mrdocs 1069
        self.listbox1.bind('<Double-Button-1>', __listbox1DoubleClickCallback)
1070
 
1048 cbradney 1071
        # middle button frame assembly
1072
        self.midbutton_frame = Frame(self.listbox_frame)
1073
        self.midbutton_frame.grid(row=0, rowspan=2, column=1, sticky=NSEW)
222 Franz 1074
 
3957 mrdocs 1075
        self.rsingleButton = Button(self.midbutton_frame, state='disabled', text='>', command=self.__rsingleButtonClick)
1048 cbradney 1076
        self.rsingleButton.grid(row=0, column=0, padx=5, pady=5, sticky=EW)
3957 mrdocs 1077
        self.rdoubleButton = Button(self.midbutton_frame, text='>>', command=self.__rdoubleButtonClick)
1048 cbradney 1078
        self.rdoubleButton.grid(row=1, column=0, padx=5, pady=5, sticky=EW)
222 Franz 1079
 
3957 mrdocs 1080
        self.itemupButton = Button(self.midbutton_frame, state='disabled', text='Up', command=self.__itemupButtonClick)
1048 cbradney 1081
        self.itemupButton.grid(row=2, column=0, padx=5, pady=5, sticky=EW)
3957 mrdocs 1082
        self.itemdownButton = Button(self.midbutton_frame, state='disabled', text='Down', command=self.__itemdownButtonClick)
1048 cbradney 1083
        self.itemdownButton.grid(row=3, column=0, padx=5, pady=5, sticky=EW)
222 Franz 1084
 
3957 mrdocs 1085
        self.lsingleButton = Button(self.midbutton_frame, state='disabled', text='<', command=self.__lsingleButtonClick)
1048 cbradney 1086
        self.lsingleButton.grid(row=4, column=0, padx=5, pady=5, sticky=EW)
3957 mrdocs 1087
        self.ldoubleButton = Button(self.midbutton_frame, state='disabled', text='<<', command=self.__ldoubleButtonClick)
1048 cbradney 1088
        self.ldoubleButton.grid(row=5, column=0, padx=5, pady=5, sticky=EW)
222 Franz 1089
 
1048 cbradney 1090
        # Right hand listbox assembly
1091
        self.rightListbox_frame = Frame(self.listbox_frame, borderwidth=1, relief=SUNKEN)
1092
        self.rightListbox_frame.grid(row=1, column=2)
222 Franz 1093
 
3957 mrdocs 1094
        self.rightLabel = Label(self.listbox_frame, text='Selected Fonts')
1048 cbradney 1095
        self.rightLabel.grid(row=0, column=2, sticky=NS)
222 Franz 1096
 
1048 cbradney 1097
        self.yScroll2 = Scrollbar(self.rightListbox_frame, orient=VERTICAL)
1098
        self.yScroll2.grid(row=0, column=1, sticky=NS)
1099
        self.xScroll2 = Scrollbar(self.rightListbox_frame, orient=HORIZONTAL)
1100
        self.xScroll2.grid(row=1, column=0, sticky=EW)
222 Franz 1101
 
1048 cbradney 1102
        self.listbox2 = Listbox(self.rightListbox_frame,
1103
            xscrollcommand=self.xScroll2.set,
1104
            yscrollcommand=self.yScroll2.set,
1105
            selectmode=EXTENDED,
1106
            height=20, width=40)
1107
        self.listbox2.grid(row=0, column=0, sticky=NSEW)
3957 mrdocs 1108
        self.xScroll2['command'] = self.listbox2.xview
1109
        self.yScroll2['command'] = self.listbox2.yview
222 Franz 1110
 
1048 cbradney 1111
        def __listbox2SingleClick(event):
1112
            """Similar to __listbox1SingleClick()."""
1113
            self.listbox2.focus_set()
1114
            __listbox2DoLogicCallback(self)
3957 mrdocs 1115
        self.listbox2.bind('<ButtonRelease-1>', __listbox2SingleClick)
222 Franz 1116
 
1048 cbradney 1117
        def __listbox2KeyRelease(event):
3957 mrdocs 1118
            if (event.keysym == 'Down' or event.keysym == 'Up'):
1048 cbradney 1119
                __listbox2DoLogicCallback(self)
222 Franz 1120
 
1048 cbradney 1121
        def __listbox2DoLogicCallback(event):
3957 mrdocs 1122
            """Similar to __listbox1DoLogicCallback()."""
1048 cbradney 1123
            names = self.listbox2.curselection()
1124
            if len(names) == 1:
1125
                selectedFont = self.listbox2.get(names[0])
1126
                self.__curSelectedItem(selectedFont)
1127
            else:
1128
                try:
1129
                    app.previewPanel.delete(previewId)
1130
                except:
1131
                    pass
222 Franz 1132
 
1048 cbradney 1133
            # Now do the button logic...
1134
            self.listbox1.selection_clear(0,END)
1135
            self.__testUpDownState()
1136
            if self.listbox2.size() > 0:
1137
                self.__setSelButtonsActive(1, 0)
1138
            else:
1139
                self.__setSelButtonsActive(0, 0)
3957 mrdocs 1140
        self.listbox2.bind('<FocusIn>', __listbox2DoLogicCallback)
1048 cbradney 1141
        self.listbox2.bind('<Any-KeyRelease>', __listbox2KeyRelease)
222 Franz 1142
 
1048 cbradney 1143
        def __listbox2DoubleClickCallback(event):
1144
            """Similar to __listbox1DoubleClickCallback()."""
1145
            self.__listSelectionToLeft()
3957 mrdocs 1146
        self.listbox2.bind('<Double-Button-1>', __listbox2DoubleClickCallback)
222 Franz 1147
 
1048 cbradney 1148
        # now draw the bottom font preview frame if required...
1149
        if showPreviewPanel:
1150
            self.preview_frame = Frame(self)
1151
            self.preview_frame.grid(row=1, column=0, sticky=EW)
3957 mrdocs 1152
            self.previewPanel = Canvas(self.preview_frame, height=60, bg='white', bd=2, relief=SUNKEN)
1048 cbradney 1153
            self.previewPanel.pack(fill=X)
222 Franz 1154
 
1048 cbradney 1155
        # now draw the bottom controls frame...
1156
        self.controls_frame = Frame(self)
1157
        self.controls_frame.grid(row=2, column=0, sticky=EW)
222 Franz 1158
 
3957 mrdocs 1159
        # create a container...
1160
        self.button_frame1 = Frame(self.controls_frame, bd=1, relief=RIDGE)
1161
        self.button_frame1.grid(row=0, column=0, padx=10, pady=2)
1162
        # create and add page number selection button...
1163
        self.__wantPageNum = IntVar()
1164
        self.pagenumSelect = Checkbutton(self.button_frame1, text='Print page numbers', variable=self.__wantPageNum, offvalue=0, onvalue=1, command=self.__pageNumberSelectButtonClick)
1048 cbradney 1165
        self.pagenumSelect.grid(row=0, column=0, padx=0, sticky=W)
222 Franz 1166
 
3957 mrdocs 1167
        # create a container...
1168
        self.button_frame2 = Frame(self.controls_frame, bd=1, relief=RIDGE)
1169
        self.button_frame2.grid(row=0, column=1, padx=10, pady=2)
1170
        # create and add the TOC selector...
1171
        self.__wantToc = IntVar()
1172
        self.tocSelect = Checkbutton(self.button_frame2, text='Print table of contents', variable=self.__wantToc, offvalue=0, onvalue=1, command=self.__tocSelectButtonClick)
1173
        self.tocSelect.grid(row=0, column=0, padx=0, sticky=W)
1174
        # create and add page one on first selector...
1175
        self.__wantPageOneOnFirst = IntVar()
1176
        self.btnPageOneOnFirst = Checkbutton(self.button_frame2, text='Page count includes TOC', variable=self.__wantPageOneOnFirst, offvalue=0, onvalue=1, command=self.__wantPageOneOnFirstClick)
1177
        self.btnPageOneOnFirst.grid(row=1, column=0, padx=0, sticky=W)
1178
 
1179
        # create a container...
1180
        self.button_frame3 = Frame(self.controls_frame, bd=1, relief=RIDGE)
1181
        self.button_frame3.grid(row=0, column=2, padx=10, pady=2)
1182
        # create and add the binding offset...
1183
        self.__wantBindingOffset = IntVar()
1184
        self.bindingoffsetSelect = Checkbutton(self.button_frame3, text='Extra offset for binding', variable=self.__wantBindingOffset, offvalue=0, onvalue=1, command=self.__bindingoffsetSelectButtonClick)
1048 cbradney 1185
        self.bindingoffsetSelect.grid(row=0, column=0, sticky=W)
3957 mrdocs 1186
        # create and add the double sided selection buttons...
1187
        self.__wantDoubleSided = IntVar()
1188
        self.doublesidedSelect = Checkbutton(self.button_frame3, text='Double sided pages', variable=self.__wantDoubleSided, offvalue=0, onvalue=1, command=self.__doubleSidedSelectButtonClick)
1048 cbradney 1189
        self.doublesidedSelect.grid(row=1, column=0, rowspan=2, sticky=W)
222 Franz 1190
 
1048 cbradney 1191
        # now the ok and cancel buttons...
3957 mrdocs 1192
        self.cancelButton = Button(self.controls_frame, text='Cancel', command=self.__cancelButtonClick)
1048 cbradney 1193
        self.cancelButton.grid(row=0, column=3, padx=5)
3957 mrdocs 1194
        self.okButton = Button(self.controls_frame, text='OK', state='disabled', command=self.__okButtonClick)
1048 cbradney 1195
        self.okButton.grid(row=0, column=4, padx=5)
222 Franz 1196
 
1048 cbradney 1197
        # now create the bottom status bar frame and contents...
1198
        self.status_frame = Frame(self)
1199
        self.status_frame.grid(row=3, column=0, sticky=E+W)
1200
        self.status0 = Label(self.status_frame, bd=1, relief=SUNKEN, anchor=W)
1201
        self.status0.pack(side=LEFT)
1202
        self.status1 = Label(self.status_frame, bd=1, relief=SUNKEN, anchor=W)
1203
        self.status1.pack(side=LEFT)
1204
        self.status2 = Label(self.status_frame, bd=1, relief=SUNKEN, anchor=W)
3957 mrdocs 1205
        self.status2.pack(side=LEFT)
1206
        self.status3 = Label(self.status_frame, bd=1, relief=SUNKEN, anchor=W)
1207
        self.status3.pack(side=LEFT)
1208
        self.statusPaperSize = Label(self.status_frame, bd=1, relief=SUNKEN, anchor=W)
1209
        self.statusPaperSize.pack(fill=X)
222 Franz 1210
 
1048 cbradney 1211
    def statusbarUpdate(self):
3957 mrdocs 1212
        """Draws the status bar contents.
1213
 
1214
        Note "draw_selection()" does a dummy run to count the amount of sample
1215
        blocks on a sheet.
1216
        TODO: Statusbar setting and recalculation should be separated. Just recalc
1217
        and refresh panels as required instead of all of them each time.
1218
        """
1048 cbradney 1219
        available = self.listbox1.size()
1220
        selected = self.listbox2.size()
1221
        size = FloatType(selected)
3957 mrdocs 1222
        blocksPerSheet = draw_selection(scribus.getFontNames(), 1)
1223
        value = size / blocksPerSheet
1048 cbradney 1224
        pages = IntType(value)                  # Get whole part of number
1225
        value = value - pages                   # Remove whole number part
1226
        if value > 0:                           # Test remainder
1227
            pages = pages + 1                   # Had remainder so add a page
3957 mrdocs 1228
        self.status0['text'] = 'Fonts available: %s   ' % (available + selected)
1229
        self.status1['text'] = 'Fonts selected: %s   ' % selected
1230
        self.status2['text'] = 'Sheets required: %s   ' % pages
1231
        self.status3['text'] = 'Fonts per sheet: %s   ' % blocksPerSheet
1232
        self.statusPaperSize['text'] = 'Paper size: %s   ' % userPrefs['paperSize']
222 Franz 1233
 
1048 cbradney 1234
    def __listSelectionToRight(self):
1235
        toMoveRight = ListType(self.listbox1.curselection())
1236
        self.listbox1.selection_clear(0,END)
1237
        toMoveRight.reverse()   # reverse list so we delete from bottom of listbox first
1238
        tempList = []
1239
        for i in toMoveRight:
1240
            tempList.insert(0,self.listbox1.get(i)) # gets the actual strings (reverse again)
1241
            self.listbox1.delete(i)
1242
        for j in tempList:
1243
            self.listbox2.insert(END, j)
1244
        self.__setButtonsState()
1245
        self.__setSelButtonsActive(0, 0)
1246
        self.statusbarUpdate()
222 Franz 1247
 
1048 cbradney 1248
    def __listSelectionToLeft(self):
1249
        toMoveLeft = ListType(self.listbox2.curselection())
1250
        toMoveLeft.reverse()
1251
        self.listbox2.selection_clear(0,END)
1252
        for i in toMoveLeft:
1253
            self.listbox1.insert(END, self.listbox2.get(i)) # Insert it at the end
1254
            self.listbox2.delete(i)
1255
        fontList = ListType(self.listbox1.get(0, END))      # Copy contents to a list type
1256
        self.listbox1.delete(0, END)                        # Remove all contents
1257
        fontList.sort()                                     # Use sort method of list
1258
        for j in fontList:
1259
            self.listbox1.insert(END, j)                    # Replace with sorted version
1260
        self.__setButtonsState()
1261
        self.__setSelButtonsActive(0, 0)
1262
        self.statusbarUpdate()
222 Franz 1263
 
1048 cbradney 1264
    def __listAllToRight(self):
1265
        fontList = self.listbox1.get(0, END)    # Get each font name into a list
1266
        for i in fontList:
1267
            self.listbox2.insert(END, i)        # Copy each one
1268
        self.listbox1.delete(0, END)            # All done so empty the left listbox
1269
        self.__setButtonsState()
1270
        self.__setSelButtonsActive(0, 0)
1271
        self.statusbarUpdate()
222 Franz 1272
 
1048 cbradney 1273
    def __listAllToLeft(self):
3957 mrdocs 1274
        """Moves all selected fonts back to the left hand pane.
1275
 
1276
        Note we just clear both panes then reload the left listbox in correct
1277
        order from scratch as this is probably quicker than moving each
1278
        item individually.
1279
        """
1048 cbradney 1280
        self.listbox1.delete(0, END)
1281
        fontList = scribus.getFontNames()
1282
        fontList.sort()
1283
        for i in fontList:
1284
            self.listbox1.insert(END, i)
1285
        self.listbox2.delete(0, END)
1286
        self.__setButtonsState()
1287
        self.__setSelButtonsActive(0, 0)
1288
        self.statusbarUpdate()
222 Franz 1289
 
1048 cbradney 1290
    def __setSelButtonsActive(self, selToRight, selToLeft):
1291
        # The "selection" buttons are the ones with ">"  and "<"  on them
1292
        if selToRight == 1:
1293
            self.lsingleButton['state'] = NORMAL
1294
        else:
1295
            self.lsingleButton['state'] = DISABLED
1296
        if selToLeft == 1:
1297
            self.rsingleButton['state'] = NORMAL
1298
        else:
1299
            self.rsingleButton['state'] = DISABLED
222 Franz 1300
 
1048 cbradney 1301
    def __setAllButtonsActive(self, allToRight, allToLeft):
1302
        # The "all" buttons are the ones with ">>"  and "<<"  on them
1303
        if allToRight == 1:
1304
            self.rdoubleButton['state'] = NORMAL
1305
        else:
1306
            self.rdoubleButton['state'] = DISABLED
1307
        if allToLeft == 1:
1308
            self.ldoubleButton['state'] = NORMAL
1309
        else:
1310
            self.ldoubleButton['state'] = DISABLED
222 Franz 1311
 
1048 cbradney 1312
    def __setButtonsState(self):
1313
        if self.listbox2.size() > 0 and self.listbox1.size() > 0:
1314
            self.__setAllButtonsActive(1, 1)
1315
            self.okButton['state'] = NORMAL
1316
        elif self.listbox2.size() == 0:
1317
            self.__setAllButtonsActive(1, 0)
1318
            self.okButton['state'] = DISABLED
1319
        elif self.listbox1.size() == 0:
1320
            self.__setAllButtonsActive(0, 1)
1321
            self.okButton['state'] = NORMAL
222 Franz 1322
 
1048 cbradney 1323
    def __itemUp(self):
1324
        """Test if one item is selected then move it up one position."""
1325
        selection = self.listbox2.curselection()
3957 mrdocs 1326
        if len(selection) == 1:
1048 cbradney 1327
            indexId = IntType(selection[0]) # Get the first (only) item as integer type
1328
            if indexId > 0:
1329
                fontString = self.listbox2.get(indexId)
1330
                self.listbox2.delete(indexId)
1331
                newPos = indexId - 1
1332
                self.listbox2.selection_clear(0, END)
1333
                self.listbox2.insert(newPos, fontString)
1334
                self.listbox2.see(newPos - 10)  # Scrolls listbox automatically into view if req.
1335
                self.listbox2.selection_set(newPos)
1336
                self.listbox2.activate(newPos)  # make focus follow selection
1337
                self.__testUpDownState()  # note tests only after an item has been moved
222 Franz 1338
 
1048 cbradney 1339
    def __itemDown(self):
1340
        """Test if one item is selected then move it down one position."""
1341
        limit = self.listbox2.size()
1342
        selection = self.listbox2.curselection()
1343
        if len(selection) == 1:
1344
            indexId = IntType(selection[0])
1345
            if indexId < limit - 1:
1346
                fontString = self.listbox2.get(indexId)
1347
                self.listbox2.delete(indexId)
1348
                newPos = indexId + 1
1349
                self.listbox2.selection_clear(0, END)
1350
                self.listbox2.insert(newPos, fontString)
1351
                self.listbox2.see(newPos + 10)
1352
                self.listbox2.selection_set(newPos)
1353
                self.listbox2.activate(newPos)  # make focus follow selection
1354
                self.__testUpDownState()
222 Franz 1355
 
1048 cbradney 1356
    def __setUpDownActive(self, up, down):
3957 mrdocs 1357
        """Just sets the buttons active or inactive.
1358
 
1359
        See testUpDown() for the actual evaluation
1360
        """
1048 cbradney 1361
        if up == 1:
1362
            self.itemupButton['state'] = NORMAL
1363
        else:
1364
            self.itemupButton['state'] = DISABLED
1365
        if down == 1:
1366
            self.itemdownButton['state'] = NORMAL
1367
        else:
1368
            self.itemdownButton['state'] = DISABLED
222 Franz 1369
 
1048 cbradney 1370
    def __testUpDownState(self):
3957 mrdocs 1371
        """Only enable the up and down buttons when just a single item is selected.
222 Franz 1372
 
3957 mrdocs 1373
        Enable should be applied to up, down or both depending on its
1374
        position in the listbox. At all other times disable both.
1375
        """
1048 cbradney 1376
        # Get a count of how many items are currently selected...
1377
        selection = list(self.listbox2.curselection())
1378
        tcount = 0
1379
        for sel in selection:
1380
            tcount = tcount + 1
222 Franz 1381
 
1048 cbradney 1382
        position = 0
1383
        if tcount == 1:
1384
            position = IntType(selection[0])
222 Franz 1385
 
1048 cbradney 1386
        # If one selected and there is more than one item in the listbox then ok...
1387
        if tcount == 1 and self.listbox2.size() > 1:
1388
            # Now test the position of the selected line...
1389
            if position > 0 and position < self.listbox2.size() - 1:    # Both
1390
                self.__setUpDownActive(1, 1)
1391
            # If not one less or lesser from the bottom (listbox.count-1?) then gray the down button.
1392
            elif position == self.listbox2.size() - 1:                  # Up only
1393
                self.__setUpDownActive(1, 0)
1394
            # If not one or more from the top then gray up button.
1395
            elif position == 0:                                         # Down only
1396
                self.__setUpDownActive(0, 1)
1397
        else:
1398
            self.__setUpDownActive(0, 0)
222 Franz 1399
 
1048 cbradney 1400
    def __curSelectedItem(self, selectedFont):
1401
        """Send the selected font to the preview function if preview available."""
1402
        if showPreviewPanel:
3957 mrdocs 1403
            preview_font(self, selectedFont)
222 Franz 1404
 
1048 cbradney 1405
    # create the button events...
1406
    def __rsingleButtonClick(self):
1407
        self.__listSelectionToRight()
751 subik 1408
 
1048 cbradney 1409
    def __rdoubleButtonClick(self):
1410
        self.__listAllToRight()
1411
 
1412
    def __lsingleButtonClick(self):
1413
        self.__listSelectionToLeft()
1414
        self.__testUpDownState()
1415
 
1416
    def __ldoubleButtonClick(self):
1417
        self.__listAllToLeft()
1418
        self.__testUpDownState()
1419
 
1420
    def __itemupButtonClick(self):
1421
        self.__itemUp()
1422
 
1423
    def __itemdownButtonClick(self):
1424
        self.__itemDown()
1425
 
3957 mrdocs 1426
    def __tocSelectButtonClick(self):
1427
        userPrefs['wantTOC'] = self.__wantToc.get()
1428
        if userPrefs['wantTOC']:
1429
            self.btnPageOneOnFirst['state'] = NORMAL
1430
        else:
1431
            self.btnPageOneOnFirst['state'] = DISABLED
1432
 
1433
    def __pageNumberSelectButtonClick(self):
1434
        userPrefs['wantPageNumbers'] = self.__wantPageNum.get()
1435
 
1436
    def __bindingoffsetSelectButtonClick(self):
1437
        userPrefs['wantBindingOffset'] = self.__wantBindingOffset.get()
1438
        dD.update(set_page_geometry(dD, geometriesList, userPrefs['paperSize'], userPrefs['wantBindingOffset']))
1439
 
1440
    def __doubleSidedSelectButtonClick(self):
1441
        userPrefs['wantDoubleSided'] = self.__wantDoubleSided.get()
1442
 
1443
    def __wantPageOneOnFirstClick(self):
1444
        userPrefs['wantPageOneOnFirst'] = self.__wantPageOneOnFirst.get()
1445
 
1048 cbradney 1446
    def __cancelButtonClick(self):
3957 mrdocs 1447
        """We exit the app here if user presses cancel."""
1048 cbradney 1448
        self.master.destroy()
1449
 
3957 mrdocs 1450
    def __okButtonClick(self):
1451
        """User presses ok, so lets create the pages."""
1452
        save_user_conf(CONFIG_PATH)
1453
        draw_selection(self.listbox2.get(0, END), 0)
1454
        self.master.destroy()
1048 cbradney 1455
 
3957 mrdocs 1456
    def __configurationDlgShow(self):
1457
        """Opens the configuration dialog where user can set up the options"""
1458
        configs = ConfigurationDialog(self)
1459
        self.statusbarUpdate()
1048 cbradney 1460
 
3957 mrdocs 1461
    def __saveCurrentSettingsAsDefaults(self):
1462
        """Stores current settings as defaults."""
1463
        defaultPrefs.update(userPrefs)
1464
        save_user_conf(CONFIG_PATH)
1465
        self.initialiseWidgets()
1048 cbradney 1466
 
3957 mrdocs 1467
    def __restoreCurrentSettingsFromDefault(self):
1468
        """Restores current settings from defaults."""
1469
        userPrefs.update(defaultPrefs)
1470
        self.initialiseWidgets()
1048 cbradney 1471
 
3957 mrdocs 1472
    def initialiseWidgets(self):
1473
        if userPrefs['wantPageNumbers']:
1474
            self.pagenumSelect.select()
1475
        else:
1476
            self.pagenumSelect.deselect()
1477
        if userPrefs['wantTOC']:
1478
            self.tocSelect.select()
1479
            self.btnPageOneOnFirst['state'] = NORMAL
1480
        else:
1481
            self.tocSelect.deselect()
1482
            self.btnPageOneOnFirst['state'] = DISABLED
1483
        if userPrefs['wantBindingOffset']:
1484
            self.bindingoffsetSelect.select()
1485
        else:
1486
            self.bindingoffsetSelect.deselect()
1487
        if userPrefs['wantDoubleSided']:
1488
            self.doublesidedSelect.select()
1489
        else:
1490
            self.doublesidedSelect.deselect()
1491
        if userPrefs['wantPageOneOnFirst']:
1492
            self.btnPageOneOnFirst.select()
1493
        else:
1494
            self.btnPageOneOnFirst.deselect()
1048 cbradney 1495
 
3957 mrdocs 1496
    def __aboutDlgShow(self):
1497
        """Brings up a dialog with support url etc."""
1498
        about = AboutDialog(self)
1499
 
1500
 
1501
def setup_tk():
1048 cbradney 1502
    """Create and setup the Tkinter app."""
1503
    root = Tk()
1504
    app = Application(root)
3957 mrdocs 1505
    app.master.title(WINDOW_TITLE)
1048 cbradney 1506
 
3957 mrdocs 1507
    # now get a list of all the fonts Scribus knows about...
1048 cbradney 1508
    fontList = scribus.getFontNames()
1509
    fontList.sort()
3957 mrdocs 1510
    # and load the list into the GUI listbox...
1048 cbradney 1511
    for i in fontList:
1512
        app.listbox1.insert(END, i)
3957 mrdocs 1513
    app.sampleBlocksPerPage = draw_selection(scribus.getFontNames(), 1)
1514
    # now set the status bar message...
1515
    app.statusbarUpdate()
1516
    # set up widgets using data from userPrefs...
1517
    app.initialiseWidgets()
1518
    return app
1048 cbradney 1519
 
3957 mrdocs 1520
def initialisation():
1521
    """Test for suitable fonts and on success creates tkinter app."""
1522
    try:
1523
        dD['bookstyleFixedFont'] = set_font_fixed(fontsListFixed)
1524
        dD['bookstylePropFont'] = set_font_proportional(fontsListProportional)
1525
    except:
1526
        scribus.messageBox('Font problem',
1527
                           '%s' % sys.exc_info()[1],
1528
                           scribus.ICON_WARNING)
1529
        sys.exit(1)
1530
    # load users saved defaults...
1531
    restore_user_conf(CONFIG_PATH)
1532
    # get and set the initial paper size to match default radiobutton selection...
1533
    dD.update(set_page_geometry(dD, geometriesList, userPrefs['paperSize'], userPrefs['wantBindingOffset']))
1534
    # Made it this far so its time to create our Tkinter app...
1535
    app = setup_tk()
1536
    # now show the main window and wait for user to do something...
1537
    app.mainloop()
1048 cbradney 1538
 
3957 mrdocs 1539
 
1048 cbradney 1540
def main(argv):
1541
    """Application initialization, font checks and initial setup."""
3957 mrdocs 1542
    initialisation()
1048 cbradney 1543
 
1544
 
1545
def main_wrapper(argv):
1546
    """The main_wrapper() function disables redrawing, sets a sensible generic
1547
    status bar message, and optionally sets up the progress bar. It then runs
1548
    the main() function. Once everything finishes it cleans up after the main()
1549
    function, making sure everything is sane before the script terminates."""
1550
    try:
3957 mrdocs 1551
        scribus.statusMessage('Running script...')
1048 cbradney 1552
        scribus.progressReset()
1553
        main(argv)
1554
    finally:
1555
        # Exit neatly even if the script terminated with an exception,
1556
        # so we leave the progress bar and status bar blank and make sure
1557
        # drawing is enabled.
1558
        if scribus.haveDoc():
1559
            scribus.setRedraw(True)
3957 mrdocs 1560
        scribus.statusMessage('')
1048 cbradney 1561
        scribus.progressReset()
1562
 
1563
 
1564
# This code detects if the script is being run as a script, or imported as a module.
1565
# It only runs main() if being run as a script. This permits you to import your script
1566
# and control it manually for debugging.
1567
if __name__ == '__main__':
1568
    main_wrapper(sys.argv)
1569