Subversion Repositories Scribus

Rev

Rev 23278 | Details | Compare with Previous | Last modification | View Log | RSS feed

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