summaryrefslogtreecommitdiffstats
path: root/scribus/plugins/scriptplugin/scripts/FontSample.py
diff options
context:
space:
mode:
authorcraig <craig@11d20701-8431-0410-a711-e3c959e3b870>2012-01-01 11:40:09 +0000
committercraig <craig@11d20701-8431-0410-a711-e3c959e3b870>2012-01-01 11:40:09 +0000
commit7ed83b6c6666eb8b6b104c211ae7e52907350372 (patch)
tree4430b556abac0ad660a0aacf1887d77f85d8be02 /scribus/plugins/scriptplugin/scripts/FontSample.py
downloadscribus-7ed83b6c6666eb8b6b104c211ae7e52907350372.tar.gz
scribus-7ed83b6c6666eb8b6b104c211ae7e52907350372.tar.xz
scribus-7ed83b6c6666eb8b6b104c211ae7e52907350372.zip
Branch 1.3.5 tree to 1.4.x tree, goodbye 1.3.x
git-svn-id: svn://scribus.net/branches/Version14x/Scribus@17163 11d20701-8431-0410-a711-e3c959e3b870
Diffstat (limited to 'scribus/plugins/scriptplugin/scripts/FontSample.py')
-rw-r--r--scribus/plugins/scriptplugin/scripts/FontSample.py1578
1 files changed, 1578 insertions, 0 deletions
diff --git a/scribus/plugins/scriptplugin/scripts/FontSample.py b/scribus/plugins/scriptplugin/scripts/FontSample.py
new file mode 100644
index 0000000..62bdcfc
--- /dev/null
+++ b/scribus/plugins/scriptplugin/scripts/FontSample.py
@@ -0,0 +1,1578 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# ****************************************************************************
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ****************************************************************************
+
+"""
+******************************************************************************
+
+DESCRIPTION & USAGE:
+This script needs Tkinter. It will create a GUI with an alphabetical list
+of fonts using the names as they will be shown in Scribus. User can select
+one or more fonts and create an example sheet(s) to print or create a PDF
+from. It is heavily commented to make it easier for the user to adjust it
+for his / her own needs.
+
+Note: this version needs read/write access to .scribus directory in users
+home. You will also need Python Imaging Library (PIL) installed.
+If your system does not meet these requirements then change showPreviewPanel
+to a value of 0. This will disable the new preview features.
+
+******************************************************************************
+
+First release : 30/12/2003
+This release : v0.8.1tk (released 4th Dec 2005)
+Copyright : (C) 2003 - 2005 Steve Callcott
+Latest releases
+and support : www.firstwish.co.uk/sjc/scribus/index.php
+Maintainer : Steve Callcott 2003 - 2005
+Email : stotte@firstwish.co.uk
+
+For revision history see the ChangeLog file.
+Bugs and future plans are listed in the TODO file.
+See NEWS for new features since last version.
+
+WHATS NEW v0.8.2tk:
+A one liner change by Jean Ghali to line #734 to add the extra parameter missing.
+See: http://bugs.scribus.net/view.php?id=4377
+
+WHATS NEW v0.8.1tk:
+After reloading users saved preferences the status bar was not showing
+correct calculations.
+Changed text in settings menu.
+
+WHATS NEW v0.8tk Final:
+Cleaned up the checkbox labels and layout.
+
+WHATS NEW v0.8tk Preview 3:
+Calls the new Scribus zoomDocument() function to make the completed font
+sample document fit in Scribus window.
+
+Grey out "Start page number count from first page" when "Print TOC" is
+not checked as without a table of contents the first page would always
+start on the same page number making this option irrelevant.
+
+WHATS NEW v0.8tk Preview 2:
+Replaced the newDoc() with newDocument(). Have not put any fallback code
+for use with earlier Scribus versions.
+
+When using double sided option we now make use of Scribus ability to display
+pages side by side as default. You may need to zoom out to view the
+complete document width.
+
+WHATS NEW v0.8tk Preview 1:
+Rearanged the initialisation. If no fonts are found for the Table of
+Contents, page numbers and font sample labels, the script shows a
+message box listing the problem and a possible solution as well as a message
+to the console.
+
+A Scribus messagebox alerts the user if Tkinter is not found. Previously
+this message was only printed to the console.
+
+Now able to do a dummy run to calculate and report the amount of samples
+that will fit on a page. This enables the script to correctly calculate
+how many sheets will be required. Previously it was always assumed that
+there would be 3 sample blocks on a sheet. This is now not always the case.
+
+Added menu. Also added "about" and "settings" dialogs.
+
+Sample rows can be selected or unselected to save on paper. The settings are
+automatically saved when changed and can be set as user defaults.
+
+User can choose to have page numbers count from first page of the toc instead
+of the first page of samples. This can be helpful if wanting to quickly look
+up a font in the toc and then using the Scribus page navigator dialog to go to
+the actual page on the screen to view it without printing it out.
+
+Added initial support for a sample paragraph. The sample paragraph defaults
+to "off" due to the amount of space it uses on the page.
+
+Some widgets read their defaults from a config dictionary.
+
+Many code cleanups. Classes used for settings storage have been replaced with
+dictionaries to make it easier for users to customise.
+
+******************************************************************************
+"""
+
+import sys
+import os
+import cPickle
+
+
+showPreviewPanel = 1 # change to 0 to permanently hide the preview
+TEMP_PATH = os.path.join(os.path.expanduser('~'), '.scribus')
+CONFIG_PATH = os.path.join(os.path.expanduser('~'), '.scribus/fontsampler')
+
+
+try:
+ import scribus
+except ImportError,err:
+ print 'This Python script is written for the Scribus scripting interface.'
+ print 'It can only be run from within Scribus.'
+ sys.exit(1)
+
+
+try:
+ from Tkinter import *
+except ImportError,err:
+ print 'This script will not work without Tkinter'
+ scribus.messageBox('Error','This script will not work without Tkinter\nPlease install and try again',
+ scribus.ICON_WARNING)
+ sys.exit(1)
+
+
+if not os.path.exists(CONFIG_PATH):
+ try:
+ print 'Attempting to creating configuration file directory...'
+ os.mkdir(CONFIG_PATH)
+ print 'Success, now testing for write access of new directory...'
+ if os.access(CONFIG_PATH, os.W_OK):
+ print 'Write access ok.'
+ else:
+ print 'Error, unable to write to .scribus/fontsampler directory.'
+ except:
+ CONFIG_PATH = ''
+ print 'Failed to make configuration file directory,'
+ print 'do you have a .scribus directory in your home directory?'
+ print 'font sampler will not be able to save your preferences'
+
+
+try:
+ import Image
+except ImportError,err:
+ print 'You need to install Python Imaging Library (PIL).'
+ print 'If using gentoo then you need to emerge /dev-python/imaging'
+ print 'If using an RPM based linux distribution then you add python-imaging or similar.'
+ print 'Script will continue without the font preview panel.'
+ showPreviewPanel = 0
+
+
+try:
+ import ImageTk
+except ImportError,err:
+ print 'Module ImageTk not found, font preview disabled'
+ showPreviewPanel = 0
+
+
+if showPreviewPanel:
+ if not os.path.exists(TEMP_PATH):
+ print '.scribus folder not found, disabling font preview panel'
+ showPreviewPanel = 0
+ if not os.access(TEMP_PATH, os.W_OK):
+ print 'Unable to write to .scribus folder, disabling font preview panel'
+ showPreviewPanel = 0
+
+
+# A few globals for use later...
+gSamplePic = None
+gPreviewId = None
+
+#*************************************************************************
+
+WINDOW_TITLE = 'Font Sampler v0.8.1tk - Steve Callcott'
+SUPPORT_PAGE = 'www.firstwish.co.uk/sjc/scribus/index.php'
+
+fontsListFixed = (
+ 'Luxi Mono Regular',
+ 'Nimbus Mono L Regular',
+ 'Courier 10 Pitch Regular',
+ 'Courier New Regular',
+ 'Courier Regular',
+ 'Andale Mono Regular',
+ 'Larabiefont Regular'
+)
+
+fontsListProportional = (
+ 'Nimbus Sans L Regular',
+ 'Luxi Sans Regular',
+ 'Bitstream Vera Sans',
+ 'Helvetica',
+ 'Arial Regular'
+)
+
+defaultPrefs = {
+ 'wantDoubleSided': 0,
+ 'paperSize':'A4', # currently PAPER_LETTER or PAPER_A4
+ 'wantTOC': 1,
+ 'wantBindingOffset': 0,
+ 'wantPageNumbers': 1,
+ 'wantPageOneOnFirst': 0,
+ 'wantAlphabet' : 1,
+ 'want6Point' : 1,
+ 'want8Point' : 1,
+ 'want10Point' : 1,
+ 'want12Point' : 1,
+ 'want16Point' : 1,
+ 'want20Point' : 1,
+ 'want32Point' : 1,
+ 'wantParagraph' : 0 # Uses a lot of space so default is off
+}
+
+userPrefs = {}
+
+geometriesList = [
+ {
+ 'paperName' : 'A4',
+ 'paperSize' : scribus.PAPER_A4,
+ 'paperWidth' : 595,
+ 'paperHeight' : 842,
+ 'paperTopMargin' : 60,
+ 'paperBottomMargin' : 50,
+ 'paperLeftMargin' : 50,
+ 'paperRightMargin' : 50,
+ 'paperBinding' : 16,
+ 'tocRowsPerPage' : 57,
+ 'paperPageNumVertOffset' : 16
+ },
+ {
+ 'paperName' : 'US Letter',
+ 'paperSize' : scribus.PAPER_LETTER,
+ 'paperWidth' : 612,
+ 'paperHeight' : 792,
+ 'paperTopMargin' : 27,
+ 'paperBottomMargin' : 45,
+ 'paperLeftMargin' : 50,
+ 'paperRightMargin' : 50,
+ 'paperBinding' : 18,
+ 'tocRowsPerPage' : 56,
+ 'paperPageNumVertOffset' : 16
+ }
+]
+
+# define our data dictionary and some of the data...
+dD = {
+ 'tocHeaderTitle' : 'Table of Contents',
+ 'tocCharsInRow' : 75,
+ 'previewpanelFontHeight' : 28,
+ 'previewpanelSampleText' : 'Woven silk pyjamas exchanged for blue quartz'
+}
+
+samplesHeader = {
+ 'fontSize' : 16,
+ 'lineSpace' : 15,
+ 'textHeight' : 23
+}
+
+# Use \xBC etc to insert Hex ascii chars into the sample strings below.
+sampleAlphabet = {
+ 'fontSize' : 10.5,
+ 'lineSpace' : 12,
+ 'textString' : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#?$*&',
+ 'textHeight' : 18
+}
+
+sample6Point = {
+ 'fontSize' : 6,
+ 'lineSpace' : 6,
+ 'textString' : 'This line is in 6 point',
+ 'textHeight' : 13
+}
+
+sample8Point = {
+ 'fontSize' : 8,
+ 'lineSpace' : 8,
+ 'textString' : 'This line is in 8 point',
+ 'textHeight' : 16
+}
+
+sample10Point = {
+ 'fontSize' : 10,
+ 'lineSpace' : 11,
+ 'textString' : 'This line is in 10 point',
+ 'textHeight' : 19
+}
+
+sample12Point = {
+ 'fontSize' : 12,
+ 'lineSpace' : 11,
+ 'textString' : 'This line is in 12 point',
+ 'textHeight' : 21
+}
+
+sample16Point = {
+ 'fontSize' : 16,
+ 'lineSpace' : 13,
+ 'textString' : 'This line is in 16 point',
+ 'textHeight' : 26
+}
+
+sample20Point = {
+ 'fontSize' : 20,
+ 'lineSpace' : 16,
+ 'textString' : 'This line is in 20 point',
+ 'textHeight' : 31
+}
+
+sample32Point = {
+ 'fontSize' : 32,
+ 'lineSpace' : 29,
+ 'textString' : 'This line is in 32 point',
+ 'textHeight' : 49
+}
+
+sampleParagraph = {
+ 'fontSize' : 9,
+ 'lineSpace' : 10.8,
+ 'textHeight' : 175
+}
+
+sampleParagraphText = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut a sapien. \
+Aliquam aliquet purus molestie dolor. Integer quis eros ut erat posuere dictum. \
+Curabitur dignissim. Integer orci. Fusce vulputate lacus at ipsum. Quisque in libero \
+nec mi laoreet volutpat. Aliquam eros pede, scelerisque quis, tristique cursus, \
+placerat convallis, velit. Nam condimentum. Nulla ut mauris. Curabitur adipiscing, \
+mauris non dictum aliquam, arcu risus dapibus diam, nec sollicitudin quam erat quis \
+ligula. Aenean massa nulla, volutpat eu, accumsan et, fringilla eget, odio. \
+Nulla placerat porta justo. Nulla vitae turpis.\n\nPraesent lacus.Lorem ipsum dolor sit \
+amet, consectetuer adipiscing elit. Pellentesque habitant morbi tristique senectus \
+et netus et malesuada fames ac turpis egestas. Quisque vel erat eget diam \
+consectetuer iaculis. Cras ante velit, suscipit et, porta tempus, dignissim quis, \
+magna. Vivamus viverra, turpis nec rhoncus ultricies, diam turpis eleifend nisl, a \
+eleifend ante felis ac sapien. Integer bibendum. Suspendisse in mi non neque \
+bibendum convallis. Suspendisse potenti. Sed sit amet purus at felis adipiscing \
+aliquam. Vivamus et nisl sit amet mauris aliquet molestie. Integer tortor massa, \
+aliquam a, lacinia nonummy, sagittis nec, eros.'
+
+#*************************************************************************
+
+def set_font_fixed(fontList):
+ """Find a matching font for the Table of Contents."""
+ availableFonts = scribus.getFontNames()
+ found = 0
+ for f in fontList:
+ if found:
+ break
+ for i in availableFonts:
+ if not found:
+ if f == i:
+ return f
+ found = 1
+ break
+ if not found:
+ errorList = ''
+ for j in fontList:
+ errorList = errorList + j + '\n'
+ errorMessage ='No suitable fixed width font found.\nPlease install at least one of these fixed width fonts:\n'+errorList
+ print errorMessage
+ raise Exception(errorMessage)
+
+
+def set_font_proportional(fontList):
+ """Find a matching font for the page numbers and font names above samples."""
+ availableFonts = scribus.getFontNames()
+ found = 0
+ for p in fontList:
+ if found:
+ break
+ for i in availableFonts:
+ if not found:
+ if p == i:
+ return p
+ found = 1
+ break
+ if not found:
+ errorList = ''
+ for j in fontList:
+ errorList = errorList + j + '\n'
+ errorMessage = 'No suitable proportional font found.\nPlease install at least one of these proportional fonts:\n'+errorList
+ print errorMessage
+ raise Exception(errorMessage)
+
+
+def save_user_conf(path):
+ """Save the data to the save file on the path specified by CONFIG_PATH.
+
+ Note initialisation unsets the CONFIG_PATH if it failed to verify or create"""
+ if not path == '':
+ try:
+ file = open(os.path.join(path,'fontsampler.conf'), 'w')
+ data = {
+ 'a' : defaultPrefs,
+ 'b' : userPrefs
+ }
+ cPickle.dump(data, file)
+ file.close()
+ except:
+ print 'failed to save data'
+
+
+def restore_user_conf(path):
+ """Restore the data from the save file on the path specified by CONFIG_PATH."""
+ try:
+ file = open(os.path.join(path,'fontsampler.conf'), 'r')
+ data = cPickle.load(file)
+ file.close()
+ defaultPrefs.update(data['a'])
+ userPrefs.update(data['b'])
+ except:
+ userPrefs.update(defaultPrefs)
+ print 'failed to load saved data so using default values defined in the script'
+
+
+def set_page_geometry(dD, geometriesList, paperSize, wantBindingOffset):
+ """This is the experimental replacement paper size setting function.
+
+ Each paper size and other associated data are stored in a dictionary.
+ The dictionaries are stored in a list. We copy appropriate dictionary
+ and custom calculations into a work dictionary for use.
+ The advantage of this is its easier to add new paper definitions.
+ Returns a new dictionary, use .update to merge in new values into dD.
+ """
+ try:
+ result={}
+ for i in geometriesList:
+ if i['paperName'] == paperSize:
+ dD.update(i)
+
+ result['paperLeftMarginOdd'] = dD['paperLeftMargin'] + \
+ dD['paperBinding']
+ result['paperRightMarginEven'] = dD['paperRightMargin'] + \
+ dD['paperBinding']
+ result['paperTextHeight'] = dD['paperHeight'] - \
+ dD['paperTopMargin'] - \
+ dD['paperBottomMargin']
+ result['paperMargins'] = dD['paperLeftMargin'],dD['paperRightMargin'],dD['paperTopMargin'],dD['paperBottomMargin']
+
+ # if we are adding a binding offset to the margins then we will have less width for our text...
+ if wantBindingOffset:
+ result['paperTextWidth'] = dD['paperWidth'] - \
+ dD['paperLeftMargin'] - \
+ dD['paperRightMargin'] - \
+ dD['paperBinding'] - \
+ 2
+ else:
+ result['paperTextWidth'] = dD['paperWidth'] - \
+ dD['paperLeftMargin'] - \
+ dD['paperRightMargin'] - \
+ 2
+ return result
+ except:
+ errorMessage = 'set_page_geometry() failure: %s' % sys.exc_info()[1]
+ print errorMessage
+
+
+def set_odd_even(pageNum):
+ """ Sets the left margin position.
+
+ Checks the number passed to it and sets left margin accordingly.
+ Call once after each new page is created.
+ Returns 1 if even and 0 if odd page.
+ """
+ if pageNum % 2 == 0:
+ isEvenPage = 1 # Even side
+ else:
+ isEvenPage = 0 # Odd side
+
+ if userPrefs['wantBindingOffset']:
+ if isEvenPage and userPrefs['wantDoubleSided']: # Even (when double sided)
+ dD['paperLeftSide'] = dD['paperLeftMargin'] + 1
+ else: # Odd side
+ dD['paperLeftSide'] = dD['paperLeftMarginOdd'] + 1
+ else: # No binding
+ dD['paperLeftSide'] = dD['paperLeftMargin'] + 1
+ return isEvenPage
+
+
+def draw_sample_row(font, fontSize, lineSpace, textString, x, y, w, h, getSizeOnly):
+ """Creates one row of samples or a header for the top of the block.
+
+ Called once by draw_sample_block() to create a block label then as many times
+ as required to create each actual sample found in the list of dictionaries
+ containing each samples definition.
+ """
+ if not getSizeOnly:
+ f = scribus.createText(x, y, w, h)
+ scribus.insertText(textString, 0, f)
+ scribus.setFont(font, f)
+ scribus.setFontSize(fontSize, f)
+ scribus.setLineSpacing(lineSpace, f)
+ scribus.setTextAlignment(0, f)
+ return y + h + 1
+
+
+def draw_sample_block(fontName, x, y, w, getSizeOnly):
+ """Drawing of a complete sample block starts from here.
+
+ Iterates through each sample declared in the "samples" tuple. Places one
+ complete block using the font specified in fontname.
+ Note top line on page is drawn outside of this function. This ensures ease
+ of returning same height of every sample block. Line could have been drawn
+ at top inside this function and page finalised with line at bottom instead.
+ If getSizeOnly is true then returns the overall height of the entire text
+ block but without actually placing it.
+ """
+ startPos = y
+ # Note there are 2 points of space before horizontal line at bottom of block.
+ # This 2 points will not appear at top of page so need to add it.
+
+ # set space below horizontal line to the top of the text block
+ y = y + 4
+
+ # (note there is one extra point inserted by addSampleRow() for each row generated)...
+
+ # first need a header...
+ y = draw_sample_row(dD['bookstylePropFont'], samplesHeader['fontSize'], samplesHeader['lineSpace'], fontName, x, y, w, samplesHeader['textHeight'], getSizeOnly)
+
+ if userPrefs['wantAlphabet']:
+ y = draw_sample_row(fontName, sampleAlphabet['fontSize'], sampleAlphabet['lineSpace'], sampleAlphabet['textString'], x, y, w, sampleAlphabet['textHeight'], getSizeOnly)
+
+ if userPrefs['want6Point']:
+ y = draw_sample_row(fontName, sample6Point['fontSize'], sample6Point['lineSpace'], sample6Point['textString'], x, y, w, sample6Point['textHeight'], getSizeOnly)
+
+ if userPrefs['want8Point']:
+ y = draw_sample_row(fontName, sample8Point['fontSize'], sample8Point['lineSpace'], sample8Point['textString'], x, y, w, sample8Point['textHeight'], getSizeOnly)
+
+ if userPrefs['want10Point']:
+ y = draw_sample_row(fontName, sample10Point['fontSize'], sample10Point['lineSpace'], sample10Point['textString'], x, y, w, sample10Point['textHeight'], getSizeOnly)
+
+ if userPrefs['want12Point']:
+ y = draw_sample_row(fontName, sample12Point['fontSize'], sample12Point['lineSpace'], sample12Point['textString'], x, y, w, sample12Point['textHeight'], getSizeOnly)
+
+ if userPrefs['want16Point']:
+ y = draw_sample_row(fontName, sample16Point['fontSize'], sample16Point['lineSpace'], sample16Point['textString'], x, y, w, sample16Point['textHeight'], getSizeOnly)
+
+ if userPrefs['want20Point']:
+ y = draw_sample_row(fontName, sample20Point['fontSize'], sample20Point['lineSpace'], sample20Point['textString'], x, y, w, sample20Point['textHeight'], getSizeOnly)
+
+ if userPrefs['want32Point']:
+ y = draw_sample_row(fontName, sample32Point['fontSize'], sample32Point['lineSpace'], sample32Point['textString'], x, y, w, sample32Point['textHeight'], getSizeOnly)
+
+ if userPrefs['wantParagraph']:
+ y = draw_sample_row(fontName, sampleParagraph['fontSize'], sampleParagraph['lineSpace'], sampleParagraphText, x, y, w, sampleParagraph['textHeight'], getSizeOnly)
+
+ y = y + 1 # one extra point of space above bottom Horiz. line
+
+ lineHeight = draw_horiz_line(y, x, w + x, getSizeOnly)
+ y = y + lineHeight
+
+ return y - startPos
+
+
+def insert_toc_row(fontName, pageNum, yPos, frame):
+ """Called once for each content line to be drawn in the text frame."""
+ dotLine = ""
+ dotQuant = dD['tocCharsInRow'] - len(fontName) - len(str(pageNum)) + 1
+ for i in range(dotQuant):
+ dotLine = dotLine + '.'
+ oneLine = fontName + dotLine + str(pageNum) + "\n"
+ scribus.insertText(oneLine, yPos, frame)
+ yPos = yPos + len(oneLine) + 0
+ return yPos
+
+
+def build_toc_page_template():
+ """Inserts empty toc template into the currently selected page."""
+ # first put a header on the empty page...
+ textstring = dD['tocHeaderTitle']
+ yPos = dD['paperTopMargin'] + 1
+ header = scribus.createText(dD['paperLeftSide'], yPos, dD['paperTextWidth'], 35)
+ scribus.insertText(textstring, 0, header)
+ scribus.setFont(dD['bookstylePropFont'], header)
+ scribus.setFontSize(24, header)
+ scribus.setTextAlignment(1, header)
+ # now create a text frame for the table of contents...
+ yPos = yPos + 36
+ body = scribus.createText(dD['paperLeftSide'], yPos, dD['paperTextWidth'], dD['paperHeight'] - yPos - dD['paperBottomMargin'] - 1)
+ scribus.setFont(dD['bookstyleFixedFont'], body)
+ scribus.setFontSize(10, body)
+ scribus.setLineSpacing(12, body)
+ return body
+
+
+def build_toc(tocList):
+ """Creates all the Table of Contents pages.
+
+ Calls tocPageFramesBuild() to write the header and empty frame for the
+ toc rows each time a new page is added.
+ Then calls tocRowAdd() to add each line to the toc frame. Creates new page
+ each time it completes last row on page.
+ """
+ rowCount = 0
+ yPos = 0
+ tocPageNum = 1
+ tocPageCount = 1
+
+ scribus.newPage(tocPageNum)
+ isEvenPage = set_odd_even(tocPageNum)
+ body = build_toc_page_template() # create frames for new empty page
+ if isEvenPage == 0:
+ scribus.setTextAlignment(2, body)
+ else:
+ scribus.setTextAlignment(0, body)
+ for i in tocList:
+ if rowCount == dD['tocRowsPerPage']: # Need to build a new TOC page (count is from zero, not one)
+ tocPageNum = tocPageNum + 1
+ scribus.newPage(tocPageNum)
+ isEvenPage = set_odd_even(tocPageNum)
+ body = build_toc_page_template()
+ if not isEvenPage:
+ scribus.setTextAlignment(2, body)
+ else:
+ scribus.setTextAlignment(0, body)
+ rowCount = 0
+ yPos = 0
+ tocPageCount = tocPageCount + 1
+ yPos = insert_toc_row(i[0], i[1], yPos, body)
+ rowCount = rowCount + 1
+ if userPrefs['wantDoubleSided']:
+ if tocPageCount % 2 != 0: # Odd page
+ tocPageNum = tocPageNum + 1
+ scribus.newPage(tocPageNum) # Add an extra page if odd number
+
+
+def add_page_num(pageNum):
+ yPos = dD['paperHeight'] - \
+ dD['paperBottomMargin'] - \
+ dD['paperPageNumVertOffset']
+ footer = scribus.createText(dD['paperLeftSide'], yPos, dD['paperTextWidth'], 15)
+ scribus.insertText('%s' % pageNum, 0, footer)
+ scribus.setFont(dD['bookstylePropFont'], footer)
+ scribus.setFontSize(9, footer)
+ scribus.setTextAlignment(1, footer)
+ scribus.setLineSpacing(10, footer)
+
+
+def create_empty_samplepage(pageNum, getSizeOnly):
+ """Creates a new page and increments page number by one.
+
+ Note getSizeOnly is now evaluated. Will still generate page number increment
+ but will not actually create the new page or place the number on the page."""
+ if not getSizeOnly:
+ scribus.newPage(-1)
+ pageNum = pageNum + 1
+ set_odd_even(pageNum)
+ if not getSizeOnly:
+ if userPrefs['wantPageNumbers']:
+ add_page_num(pageNum)
+ return pageNum
+
+
+def draw_horiz_line(yPos, xStart, xEnd, getSizeOnly):
+ """Draws a line and returns the height.
+
+ If getSizeOnly is set then returns the height it would have
+ used but without actually creating a line.
+ """
+ lineWidth = 1
+ if not getSizeOnly:
+ newLine = scribus.createLine(xStart, yPos, xEnd, yPos)
+ scribus.setLineWidth(lineWidth, newLine)
+ return lineWidth
+
+
+def draw_selection(fontList, getSizeOnly):
+ """Draws the sample blocks onto the Scribus canvas.
+
+ Measure one font sample block including any horizontal lines and extra
+ vertical spaces.
+ Get the amount of vertical space available for the text area between the
+ top line and top of page number area.
+ Use these two values to calculate how many complete sample blocks will fit
+ in the space available. This is the "pageBlocks"
+ Note we always draw the top horizontal line before placing the blocks. This
+ is taken into account when calculating the available text area.
+ Next, if "getSizeOnly" is false we create a page then create the sample
+ blocks while incrementing a counter until it matches the "pageBlocks".
+ Reset the counter and create new page. We keep going until we have processed
+ all the fonts in the selection list.
+ We update the Scribus progress bar as we create each font sample block.
+ The returned result is used to update some values in the status bar.
+ """
+ progress = 1
+ scribus.progressReset()
+ scribus.progressTotal(len(fontList))
+ tocList = []
+ pageNum = 1
+ blockCounter = 0
+ counter = 0
+ facingPages = scribus.NOFACINGPAGES
+
+ # Just get blocks per page value...
+ set_odd_even(pageNum)
+ lineHeight = 1 # include the one point of space below top margin
+ lineHeight = lineHeight + draw_horiz_line(0, dD['paperLeftSide'], dD['paperLeftSide'] + dD['paperTextWidth'], 1)
+ usuableArea = dD['paperHeight'] - \
+ dD['paperTopMargin'] - \
+ lineHeight - \
+ dD['paperBottomMargin'] - \
+ dD['paperPageNumVertOffset']
+
+ blockHeight = draw_sample_block(fontList[0], dD['paperLeftSide'], 0, dD['paperTextWidth'], 1)
+ pageBlocks = int(usuableArea / blockHeight)
+ #print blockHeight
+ #print "Usuable area %s points high" % usuableArea
+ #print "Used space on page is %s points high" % (blockHeight * pageBlocks)
+
+ if not getSizeOnly:
+ # not a dummy run so start by setting up page numbering...
+ if userPrefs['wantPageOneOnFirst'] and userPrefs['wantTOC']:
+ tocPageCount = divmod(len(fontList), dD['tocRowsPerPage'])
+ pageNum = pageNum + tocPageCount[0]
+ if tocPageCount[1] != 0:
+ # (adding more to page number as not whole number)
+ pageNum = pageNum + 1
+ if userPrefs['wantDoubleSided']:
+ oddEvenTest = divmod(pageNum, 2)
+ if oddEvenTest[1] == 0:
+ # (adding extra one to start number as odd amount)
+ pageNum = pageNum + 1
+ if userPrefs['wantDoubleSided']:
+ facingPages = scribus.FACINGPAGES
+ # now create a new document with empty page and start building...
+ scribus.newDocument(dD['paperSize'], dD['paperMargins'], scribus.PORTRAIT, 1, scribus.UNIT_POINTS, facingPages, scribus.FIRSTPAGERIGHT, 1)
+ scribus.zoomDocument(-100)
+ # A new doc gives us a new page by default so set it up first...
+ set_odd_even(pageNum)
+ yPos = dD['paperTopMargin'] + 1
+ lineHeight = draw_horiz_line(yPos, dD['paperLeftSide'], dD['paperLeftSide'] + dD['paperTextWidth'], getSizeOnly)
+ yPos = yPos + lineHeight
+ if userPrefs['wantPageNumbers']:
+ add_page_num(pageNum)
+ for i in fontList:
+ # Now place the actual sample block but create a new page if needed...
+ if counter == pageBlocks:
+ pageNum = create_empty_samplepage(pageNum, getSizeOnly)
+ yPos = dD['paperTopMargin'] + 1
+ lineHeight = draw_horiz_line(yPos, dD['paperLeftSide'], dD['paperLeftSide'] + dD['paperTextWidth'], getSizeOnly)
+ yPos = yPos + lineHeight
+ counter = 0
+ blockHeight = draw_sample_block(i, dD['paperLeftSide'], yPos, dD['paperTextWidth'], getSizeOnly)
+ yPos = yPos + blockHeight
+ # and also increment the Scribus progress bar...
+ scribus.progressSet(progress)
+ progress = progress + 1
+ # Add current font to TOC...
+ tocList.append([i, pageNum])
+ counter = counter + 1
+ if userPrefs['wantTOC']:
+ # Insert table of contents - (before page numbering)...
+ build_toc(tocList)
+ scribus.gotoPage(1)
+ return pageBlocks
+
+
+def preview_font(app, fontName):
+ """Gets the named font and puts a sample in the preview panel.
+
+ Pick up the temp sample qpixmap file and display it in a canvas object
+ The temp file is put in the users ".scribus" folder and cleaned up on exit.
+ We create samplePic as a global as a workaround because the reference count
+ does not increase when we add the image to the canvas. Therefore python
+ garbage collection removes our image before we have even displayed it.
+ Note app.previewPanel is the actual canvas.
+ """
+ global gSamplePic
+ global gPreviewId
+ scribus.renderFont(fontName, os.path.join(TEMP_PATH,'temp079r.bmp'),dD['previewpanelSampleText'],dD['previewpanelFontHeight'])
+ try:
+ tempPic = Image.open(os.path.join(TEMP_PATH,'temp079r.bmp'))
+ tempPic.save(os.path.join(TEMP_PATH,'temp079r.jpeg'),format='JPEG')
+ tempImage = Image.open(os.path.join(TEMP_PATH,'temp079r.jpeg'))
+ imgDimen = tempPic.getbbox()
+ gSamplePic = ImageTk.PhotoImage(tempImage)
+ # To center the image use "Half display height minus half the image height"
+ # preview panel is allegedly 56 (60 less a 2 pixel border top and bottom)
+ # need to be lower than that to look correct visually...
+ topEdge = (32 - (imgDimen[3] / 2))
+ gPreviewId = app.previewPanel.create_image(5, topEdge, anchor=NW, image=gSamplePic)
+ os.remove(os.path.join(TEMP_PATH,'temp079r.bmp'))
+ os.remove(os.path.join(TEMP_PATH,'temp079r.jpeg'))
+ except IOError:
+ gSamplePic = None
+ gPreviewId = app.previewPanel.create_image(0, 0, anchor=NW, image=gSamplePic)
+ return
+
+
+class AboutDialog(Toplevel):
+
+ def __init__(self, parent):
+ Toplevel.__init__(self, parent)
+ self.transient(parent)
+ self.title('About')
+ self.parent = parent
+ self.result = None
+ self.resizable(0, 0)
+
+ infoLabel = Label(self, text=WINDOW_TITLE+'\nSupport page at %s' % SUPPORT_PAGE)
+ infoLabel.pack(padx=5, pady=5)
+ # now the frame for contents...
+ contentFrame = Frame(self)
+ self.btnOk = Button(contentFrame, text='OK', command=self.ok, default=ACTIVE)
+ self.btnOk.pack(side=LEFT, padx=5, pady=5)
+ contentFrame.pack()
+ self.bind('<Return>', self.ok)
+ self.grab_set()
+ self.protocol('WM_DELETE_WINDOW', self.ok)
+ self.initial_focus = self.btnOk
+ self.wait_window(self)
+
+ def ok(self, event=None):
+ self.withdraw()
+ self.update_idletasks()
+ self.parent.focus_set()
+ self.destroy()
+
+
+class ConfigurationDialog(Toplevel):
+
+ def __init__(self, parent):
+ Toplevel.__init__(self, parent)
+ self.transient(parent)
+ self.title('Configuration')
+ self.parent = parent
+ self.result = None
+ self.resizable(0, 0)
+
+ # Create outer frame...
+ self.topFrame = Frame(self, bd=1, relief=FLAT)
+ self.topFrame.grid(row=0, column=0, padx=5, pady=5)
+
+ self.paperSizeLabel = Label(self.topFrame, text='Sample Rows:')
+ self.paperSizeLabel.grid(row=0, column=0, sticky=W)
+
+ # This frame holds each sample selector...
+ self.sampleSelectFrame = Frame(self.topFrame, bd=1, relief=RIDGE)
+ self.sampleSelectFrame.grid(row=1, column=0, padx=0, pady=2)
+
+ # now create the sample selector widgets for the frame...
+ self.__wantAlphabet = IntVar()
+ self.btnWantAlphabet = Checkbutton(self.sampleSelectFrame, text='want alphabet row', variable=self.__wantAlphabet, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
+ self.btnWantAlphabet.grid(row=0, column=0, padx=10, pady=0, sticky=W)
+ if userPrefs['wantAlphabet']:
+ self.btnWantAlphabet.select()
+
+ self.__want6Point = IntVar()
+ self.btnWant6Point = Checkbutton(self.sampleSelectFrame, text='want 6 point row', variable=self.__want6Point, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
+ self.btnWant6Point.grid(row=1, column=0, padx=10, pady=0, sticky=W)
+ if userPrefs['want6Point']:
+ self.btnWant6Point.select()
+
+ self.__want8Point = IntVar()
+ self.btnWant8Point = Checkbutton(self.sampleSelectFrame, text='want 8 point row', variable=self.__want8Point, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
+ self.btnWant8Point.grid(row=2, column=0, padx=10, pady=0, sticky=W)
+ if userPrefs['want8Point']:
+ self.btnWant8Point.select()
+
+ self.__want10Point = IntVar()
+ self.btnWant10Point = Checkbutton(self.sampleSelectFrame, text='want 10 point row', variable=self.__want10Point, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
+ self.btnWant10Point.grid(row=3, column=0, padx=10, pady=0, sticky=W)
+ if userPrefs['want10Point']:
+ self.btnWant10Point.select()
+
+ self.__want12Point = IntVar()
+ self.btnWant12Point = Checkbutton(self.sampleSelectFrame, text='want 12 point row', variable=self.__want12Point, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
+ self.btnWant12Point.grid(row=4, column=0, padx=10, pady=0, sticky=W)
+ if userPrefs['want12Point']:
+ self.btnWant12Point.select()
+
+ self.__want16Point = IntVar()
+ self.btnWant16Point = Checkbutton(self.sampleSelectFrame, text='want 16 point row', variable=self.__want16Point, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
+ self.btnWant16Point.grid(row=5, column=0, padx=10, pady=0, sticky=W)
+ if userPrefs['want16Point']:
+ self.btnWant16Point.select()
+
+ self.__want20Point = IntVar()
+ self.btnWant20Point = Checkbutton(self.sampleSelectFrame, text='want 20 point row', variable=self.__want20Point, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
+ self.btnWant20Point.grid(row=6, column=0, padx=10, pady=0, sticky=W)
+ if userPrefs['want20Point']:
+ self.btnWant20Point.select()
+
+ self.__want32Point = IntVar()
+ self.btnWant32Point = Checkbutton(self.sampleSelectFrame, text='want 32 point row', variable=self.__want32Point, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
+ self.btnWant32Point.grid(row=7, column=0, padx=10, pady=0, sticky=W)
+ if userPrefs['want32Point']:
+ self.btnWant32Point.select()
+
+ self.__wantParagraph = IntVar()
+ self.btnParagraphSelect = Checkbutton(self.sampleSelectFrame, text='want sample paragraph', variable=self.__wantParagraph, offvalue=0, onvalue=1, command=self.__sampleSelectionClick)
+ self.btnParagraphSelect.grid(row=8, column=0, padx=10, pady=0, sticky=W)
+ if userPrefs['wantParagraph']:
+ self.btnParagraphSelect.select()
+
+ self.paperSizeLabel = Label(self.topFrame, text='Paper Sizes:')
+ self.paperSizeLabel.grid(row=2, column=0, sticky=W)
+
+ self.paperSizeFrame = Frame(self.topFrame, bd=1, relief=RIDGE)
+ self.paperSizeFrame.grid(row=3, column=0, padx=0, pady=2, sticky=W)
+
+ self.__paper = StringVar()
+ self.a4papersizeSelect = Radiobutton(self.paperSizeFrame, text='A4', variable=self.__paper, value='A4', command=self.__paperSelectionClick)
+ self.a4papersizeSelect.grid(row=1, column=0, padx=10, sticky=W)
+ self.uspapersizeSelect = Radiobutton(self.paperSizeFrame, text='US Letter', variable=self.__paper, value='US Letter', command=self.__paperSelectionClick)
+ self.uspapersizeSelect.grid(row=2, column=0, padx=10, sticky=W)
+
+ # set to match prefs...
+ if userPrefs['paperSize'] == 'US Letter':
+ self.uspapersizeSelect.select()
+ if userPrefs['paperSize'] == 'A4':
+ self.a4papersizeSelect.select()
+
+ self.btnFrame = Frame(self.topFrame)
+ self.btnFrame.grid(row=4, column=0, padx=10, pady=2)
+ self.btnOk = Button(self.btnFrame, text='OK', command=self.ok)
+ self.btnOk.grid(row=2, column=0, pady=5)
+ self.bind('<Return>', self.ok)
+ self.grab_set()
+ self.initial_focus = self.btnOk
+ self.wait_window(self)
+
+
+ def __sampleSelectionClick(self):
+ """Get and store all the selections.
+
+ Just assigns the lot at once. Not worth being picky and only
+ assigning values that have changed since last time.
+ """
+ userPrefs['wantAlphabet'] = self.__wantAlphabet.get()
+ userPrefs['want6Point'] = self.__want6Point.get()
+ userPrefs['want8Point'] = self.__want8Point.get()
+ userPrefs['want10Point'] = self.__want10Point.get()
+ userPrefs['want12Point'] = self.__want12Point.get()
+ userPrefs['want16Point'] = self.__want16Point.get()
+ userPrefs['want20Point'] = self.__want20Point.get()
+ userPrefs['want32Point'] = self.__want32Point.get()
+ userPrefs['wantParagraph'] = self.__wantParagraph.get()
+ self.parent.statusbarUpdate()
+
+ def __paperSelectionClick(self):
+ userPrefs['paperSize'] = self.__paper.get()
+ self.parent.statusbarUpdate()
+
+ def ok(self, event=None):
+ dD.update(set_page_geometry(dD, geometriesList, userPrefs['paperSize'], userPrefs['wantBindingOffset']))
+ self.withdraw()
+ self.update_idletasks()
+ self.parent.focus_set()
+ self.destroy()
+
+
+class Application(Frame):
+
+ def __init__(self, master = None):
+ Frame.__init__(self, master)
+
+ self.grid()
+
+ # Remove maximise button and resize. Not good to allow resizable window
+ # because the listboxes are fixed width...
+ self.master.resizable(0, 0)
+
+ # build the menu...
+ menubar = Menu(self)
+ settingsmenu = Menu(menubar, tearoff=0)
+ settingsmenu.add_command(label='Configuration', command=self.__configurationDlgShow)
+ settingsmenu.add_separator()
+ settingsmenu.add_command(label='Save current settings', command=self.__saveCurrentSettingsAsDefaults)
+ settingsmenu.add_command(label='Load saved settings', command=self.__restoreCurrentSettingsFromDefault)
+
+ menubar.add_cascade(label='Settings', menu=settingsmenu)
+ helpmenu = Menu(menubar, tearoff=0)
+ helpmenu.add_command(label='About', command=self.__aboutDlgShow)
+ menubar.add_cascade(label='Help', menu=helpmenu)
+ # display menu...
+ self.master.config(menu=menubar)
+
+ # now start adding our widgets starting with the top frame...
+ self.listbox_frame = Frame(self)
+ self.listbox_frame.grid(row=0, column=0, sticky=EW)
+
+ # left hand listbox assembly
+ self.leftListbox_frame = Frame(self.listbox_frame, borderwidth=1, relief=SUNKEN)
+ self.leftListbox_frame.grid(row=1, column=0)
+
+ self.leftLabel = Label(self.listbox_frame, text='Available Fonts')
+ self.leftLabel.grid(row=0, column=0, sticky=NS)
+
+ self.yScroll1 = Scrollbar(self.leftListbox_frame, orient=VERTICAL)
+ self.yScroll1.grid(row=0, column=1, sticky=NS)
+ self.xScroll1 = Scrollbar(self.leftListbox_frame, orient=HORIZONTAL)
+ self.xScroll1.grid(row=1, column=0, sticky=EW)
+
+ self.listbox1 = Listbox(self.leftListbox_frame,
+ xscrollcommand=self.xScroll1.set,
+ yscrollcommand=self.yScroll1.set,
+ selectmode=EXTENDED,
+ height=20, width=40)
+ self.listbox1.grid(row=0, column=0, sticky=NSEW)
+ self.xScroll1['command'] = self.listbox1.xview
+ self.yScroll1['command'] = self.listbox1.yview
+
+ def __listbox1KeyRelease(event):
+ """Check if an Up or Down key has been pressed and released and
+ if so the preview panel is refreshed. If the keys are held down
+ the file system slows the scroll. Need a timer here to delay
+ updates."""
+ if (event.keysym == 'Down' or event.keysym == 'Up'):
+ __listbox1DoLogicCallback(self)
+
+ def __listbox1SingleClick(event):
+ """Call this first when listbox1 is clicked with mouse to put focus
+ into the listbox. Note we call when mouse click is released, not pressed,
+ due to the fact that the listbox does not change the selection until the button
+ is released."""
+ self.listbox1.focus_set()
+ __listbox1DoLogicCallback(self)
+ self.listbox1.bind('<ButtonRelease-1>', __listbox1SingleClick)
+
+ def __listbox1DoLogicCallback(event):
+ """Decides if current selection should be previewed.
+
+ Start by counting items in selection list and if equal to one then
+ show selected font, ignoring if more or less than one. Then also
+ set up buttons logic depending on selection. We bind the FocusIn
+ to this too so button logic and preview gets updated when focus
+ enters the listbox.
+ """
+ # note we are not making use of "self.listbox1.get(ACTIVE)" due to
+ # it not getting the real active name. Always one selection behind
+ # even though we are doing all this in the ButtonRelease event.
+ # Have made a change here. If more than one font name is selected
+ # then we just empty the preview.
+ names = self.listbox1.curselection()
+ if len(names) == 1:
+ selectedFont = self.listbox1.get(names[0])
+ self.__curSelectedItem(selectedFont)
+ else:
+ try:
+ app.previewPanel.delete(previewId)
+ except:
+ pass
+ #else:
+ #selectedFont = self.listbox1.get(ACTIVE)
+ #print selectedFont # for testing
+ #if selectedFont != "":
+ #self.__curSelectedItem(selectedFont)
+
+ # Now do the button logic...
+ self.listbox2.selection_clear(0,END)
+ self.__setUpDownActive(0, 0) # Force a disable if in other box
+ if self.listbox1.size() > 0:
+ self.__setSelButtonsActive(0, 1)
+ else:
+ self.__setSelButtonsActive(0, 0)
+
+ self.listbox1.bind('<FocusIn>', __listbox1DoLogicCallback)
+ self.listbox1.bind('<Any-KeyRelease>', __listbox1KeyRelease)
+
+ def __listbox1DoubleClickCallback(event):
+ """The single click event will fire also when left listbox
+ is double clicked but we are detecting the single click button up event."""
+ self.__listSelectionToRight()
+
+ self.listbox1.bind('<Double-Button-1>', __listbox1DoubleClickCallback)
+
+ # middle button frame assembly
+ self.midbutton_frame = Frame(self.listbox_frame)
+ self.midbutton_frame.grid(row=0, rowspan=2, column=1, sticky=NSEW)
+
+ self.rsingleButton = Button(self.midbutton_frame, state='disabled', text='>', command=self.__rsingleButtonClick)
+ self.rsingleButton.grid(row=0, column=0, padx=5, pady=5, sticky=EW)
+ self.rdoubleButton = Button(self.midbutton_frame, text='>>', command=self.__rdoubleButtonClick)
+ self.rdoubleButton.grid(row=1, column=0, padx=5, pady=5, sticky=EW)
+
+ self.itemupButton = Button(self.midbutton_frame, state='disabled', text='Up', command=self.__itemupButtonClick)
+ self.itemupButton.grid(row=2, column=0, padx=5, pady=5, sticky=EW)
+ self.itemdownButton = Button(self.midbutton_frame, state='disabled', text='Down', command=self.__itemdownButtonClick)
+ self.itemdownButton.grid(row=3, column=0, padx=5, pady=5, sticky=EW)
+
+ self.lsingleButton = Button(self.midbutton_frame, state='disabled', text='<', command=self.__lsingleButtonClick)
+ self.lsingleButton.grid(row=4, column=0, padx=5, pady=5, sticky=EW)
+ self.ldoubleButton = Button(self.midbutton_frame, state='disabled', text='<<', command=self.__ldoubleButtonClick)
+ self.ldoubleButton.grid(row=5, column=0, padx=5, pady=5, sticky=EW)
+
+ # Right hand listbox assembly
+ self.rightListbox_frame = Frame(self.listbox_frame, borderwidth=1, relief=SUNKEN)
+ self.rightListbox_frame.grid(row=1, column=2)
+
+ self.rightLabel = Label(self.listbox_frame, text='Selected Fonts')
+ self.rightLabel.grid(row=0, column=2, sticky=NS)
+
+ self.yScroll2 = Scrollbar(self.rightListbox_frame, orient=VERTICAL)
+ self.yScroll2.grid(row=0, column=1, sticky=NS)
+ self.xScroll2 = Scrollbar(self.rightListbox_frame, orient=HORIZONTAL)
+ self.xScroll2.grid(row=1, column=0, sticky=EW)
+
+ self.listbox2 = Listbox(self.rightListbox_frame,
+ xscrollcommand=self.xScroll2.set,
+ yscrollcommand=self.yScroll2.set,
+ selectmode=EXTENDED,
+ height=20, width=40)
+ self.listbox2.grid(row=0, column=0, sticky=NSEW)
+ self.xScroll2['command'] = self.listbox2.xview
+ self.yScroll2['command'] = self.listbox2.yview
+
+ def __listbox2SingleClick(event):
+ """Similar to __listbox1SingleClick()."""
+ self.listbox2.focus_set()
+ __listbox2DoLogicCallback(self)
+ self.listbox2.bind('<ButtonRelease-1>', __listbox2SingleClick)
+
+ def __listbox2KeyRelease(event):
+ if (event.keysym == 'Down' or event.keysym == 'Up'):
+ __listbox2DoLogicCallback(self)
+
+ def __listbox2DoLogicCallback(event):
+ """Similar to __listbox1DoLogicCallback()."""
+ names = self.listbox2.curselection()
+ if len(names) == 1:
+ selectedFont = self.listbox2.get(names[0])
+ self.__curSelectedItem(selectedFont)
+ else:
+ try:
+ app.previewPanel.delete(previewId)
+ except:
+ pass
+
+ # Now do the button logic...
+ self.listbox1.selection_clear(0,END)
+ self.__testUpDownState()
+ if self.listbox2.size() > 0:
+ self.__setSelButtonsActive(1, 0)
+ else:
+ self.__setSelButtonsActive(0, 0)
+ self.listbox2.bind('<FocusIn>', __listbox2DoLogicCallback)
+ self.listbox2.bind('<Any-KeyRelease>', __listbox2KeyRelease)
+
+ def __listbox2DoubleClickCallback(event):
+ """Similar to __listbox1DoubleClickCallback()."""
+ self.__listSelectionToLeft()
+ self.listbox2.bind('<Double-Button-1>', __listbox2DoubleClickCallback)
+
+ # now draw the bottom font preview frame if required...
+ if showPreviewPanel:
+ self.preview_frame = Frame(self)
+ self.preview_frame.grid(row=1, column=0, sticky=EW)
+ self.previewPanel = Canvas(self.preview_frame, height=60, bg='white', bd=2, relief=SUNKEN)
+ self.previewPanel.pack(fill=X)
+
+ # now draw the bottom controls frame...
+ self.controls_frame = Frame(self)
+ self.controls_frame.grid(row=2, column=0, sticky=EW)
+
+ # create a container...
+ self.button_frame1 = Frame(self.controls_frame, bd=1, relief=RIDGE)
+ self.button_frame1.grid(row=0, column=0, padx=10, pady=2)
+ # create and add page number selection button...
+ self.__wantPageNum = IntVar()
+ self.pagenumSelect = Checkbutton(self.button_frame1, text='Print page numbers', variable=self.__wantPageNum, offvalue=0, onvalue=1, command=self.__pageNumberSelectButtonClick)
+ self.pagenumSelect.grid(row=0, column=0, padx=0, sticky=W)
+
+ # create a container...
+ self.button_frame2 = Frame(self.controls_frame, bd=1, relief=RIDGE)
+ self.button_frame2.grid(row=0, column=1, padx=10, pady=2)
+ # create and add the TOC selector...
+ self.__wantToc = IntVar()
+ self.tocSelect = Checkbutton(self.button_frame2, text='Print table of contents', variable=self.__wantToc, offvalue=0, onvalue=1, command=self.__tocSelectButtonClick)
+ self.tocSelect.grid(row=0, column=0, padx=0, sticky=W)
+ # create and add page one on first selector...
+ self.__wantPageOneOnFirst = IntVar()
+ self.btnPageOneOnFirst = Checkbutton(self.button_frame2, text='Page count includes TOC', variable=self.__wantPageOneOnFirst, offvalue=0, onvalue=1, command=self.__wantPageOneOnFirstClick)
+ self.btnPageOneOnFirst.grid(row=1, column=0, padx=0, sticky=W)
+
+ # create a container...
+ self.button_frame3 = Frame(self.controls_frame, bd=1, relief=RIDGE)
+ self.button_frame3.grid(row=0, column=2, padx=10, pady=2)
+ # create and add the binding offset...
+ self.__wantBindingOffset = IntVar()
+ self.bindingoffsetSelect = Checkbutton(self.button_frame3, text='Extra offset for binding', variable=self.__wantBindingOffset, offvalue=0, onvalue=1, command=self.__bindingoffsetSelectButtonClick)
+ self.bindingoffsetSelect.grid(row=0, column=0, sticky=W)
+ # create and add the double sided selection buttons...
+ self.__wantDoubleSided = IntVar()
+ self.doublesidedSelect = Checkbutton(self.button_frame3, text='Double sided pages', variable=self.__wantDoubleSided, offvalue=0, onvalue=1, command=self.__doubleSidedSelectButtonClick)
+ self.doublesidedSelect.grid(row=1, column=0, rowspan=2, sticky=W)
+
+ # now the ok and cancel buttons...
+ self.cancelButton = Button(self.controls_frame, text='Cancel', command=self.__cancelButtonClick)
+ self.cancelButton.grid(row=0, column=3, padx=5)
+ self.okButton = Button(self.controls_frame, text='OK', state='disabled', command=self.__okButtonClick)
+ self.okButton.grid(row=0, column=4, padx=5)
+
+ # now create the bottom status bar frame and contents...
+ self.status_frame = Frame(self)
+ self.status_frame.grid(row=3, column=0, sticky=E+W)
+ self.status0 = Label(self.status_frame, bd=1, relief=SUNKEN, anchor=W)
+ self.status0.pack(side=LEFT)
+ self.status1 = Label(self.status_frame, bd=1, relief=SUNKEN, anchor=W)
+ self.status1.pack(side=LEFT)
+ self.status2 = Label(self.status_frame, bd=1, relief=SUNKEN, anchor=W)
+ self.status2.pack(side=LEFT)
+ self.status3 = Label(self.status_frame, bd=1, relief=SUNKEN, anchor=W)
+ self.status3.pack(side=LEFT)
+ self.statusPaperSize = Label(self.status_frame, bd=1, relief=SUNKEN, anchor=W)
+ self.statusPaperSize.pack(fill=X)
+
+ def statusbarUpdate(self):
+ """Draws the status bar contents.
+
+ Note "draw_selection()" does a dummy run to count the amount of sample
+ blocks on a sheet.
+ TODO: Statusbar setting and recalculation should be separated. Just recalc
+ and refresh panels as required instead of all of them each time.
+ """
+ available = self.listbox1.size()
+ selected = self.listbox2.size()
+ size = FloatType(selected)
+ blocksPerSheet = draw_selection(scribus.getFontNames(), 1)
+ value = size / blocksPerSheet
+ pages = IntType(value) # Get whole part of number
+ value = value - pages # Remove whole number part
+ if value > 0: # Test remainder
+ pages = pages + 1 # Had remainder so add a page
+ self.status0['text'] = 'Fonts available: %s ' % (available + selected)
+ self.status1['text'] = 'Fonts selected: %s ' % selected
+ self.status2['text'] = 'Sheets required: %s ' % pages
+ self.status3['text'] = 'Fonts per sheet: %s ' % blocksPerSheet
+ self.statusPaperSize['text'] = 'Paper size: %s ' % userPrefs['paperSize']
+
+ def __listSelectionToRight(self):
+ toMoveRight = ListType(self.listbox1.curselection())
+ self.listbox1.selection_clear(0,END)
+ toMoveRight.reverse() # reverse list so we delete from bottom of listbox first
+ tempList = []
+ for i in toMoveRight:
+ tempList.insert(0,self.listbox1.get(i)) # gets the actual strings (reverse again)
+ self.listbox1.delete(i)
+ for j in tempList:
+ self.listbox2.insert(END, j)
+ self.__setButtonsState()
+ self.__setSelButtonsActive(0, 0)
+ self.statusbarUpdate()
+
+ def __listSelectionToLeft(self):
+ toMoveLeft = ListType(self.listbox2.curselection())
+ toMoveLeft.reverse()
+ self.listbox2.selection_clear(0,END)
+ for i in toMoveLeft:
+ self.listbox1.insert(END, self.listbox2.get(i)) # Insert it at the end
+ self.listbox2.delete(i)
+ fontList = ListType(self.listbox1.get(0, END)) # Copy contents to a list type
+ self.listbox1.delete(0, END) # Remove all contents
+ fontList.sort() # Use sort method of list
+ for j in fontList:
+ self.listbox1.insert(END, j) # Replace with sorted version
+ self.__setButtonsState()
+ self.__setSelButtonsActive(0, 0)
+ self.statusbarUpdate()
+
+ def __listAllToRight(self):
+ fontList = self.listbox1.get(0, END) # Get each font name into a list
+ for i in fontList:
+ self.listbox2.insert(END, i) # Copy each one
+ self.listbox1.delete(0, END) # All done so empty the left listbox
+ self.__setButtonsState()
+ self.__setSelButtonsActive(0, 0)
+ self.statusbarUpdate()
+
+ def __listAllToLeft(self):
+ """Moves all selected fonts back to the left hand pane.
+
+ Note we just clear both panes then reload the left listbox in correct
+ order from scratch as this is probably quicker than moving each
+ item individually.
+ """
+ self.listbox1.delete(0, END)
+ fontList = scribus.getFontNames()
+ fontList.sort()
+ for i in fontList:
+ self.listbox1.insert(END, i)
+ self.listbox2.delete(0, END)
+ self.__setButtonsState()
+ self.__setSelButtonsActive(0, 0)
+ self.statusbarUpdate()
+
+ def __setSelButtonsActive(self, selToRight, selToLeft):
+ # The "selection" buttons are the ones with ">" and "<" on them
+ if selToRight == 1:
+ self.lsingleButton['state'] = NORMAL
+ else:
+ self.lsingleButton['state'] = DISABLED
+ if selToLeft == 1:
+ self.rsingleButton['state'] = NORMAL
+ else:
+ self.rsingleButton['state'] = DISABLED
+
+ def __setAllButtonsActive(self, allToRight, allToLeft):
+ # The "all" buttons are the ones with ">>" and "<<" on them
+ if allToRight == 1:
+ self.rdoubleButton['state'] = NORMAL
+ else:
+ self.rdoubleButton['state'] = DISABLED
+ if allToLeft == 1:
+ self.ldoubleButton['state'] = NORMAL
+ else:
+ self.ldoubleButton['state'] = DISABLED
+
+ def __setButtonsState(self):
+ if self.listbox2.size() > 0 and self.listbox1.size() > 0:
+ self.__setAllButtonsActive(1, 1)
+ self.okButton['state'] = NORMAL
+ elif self.listbox2.size() == 0:
+ self.__setAllButtonsActive(1, 0)
+ self.okButton['state'] = DISABLED
+ elif self.listbox1.size() == 0:
+ self.__setAllButtonsActive(0, 1)
+ self.okButton['state'] = NORMAL
+
+ def __itemUp(self):
+ """Test if one item is selected then move it up one position."""
+ selection = self.listbox2.curselection()
+ if len(selection) == 1:
+ indexId = IntType(selection[0]) # Get the first (only) item as integer type
+ if indexId > 0:
+ fontString = self.listbox2.get(indexId)
+ self.listbox2.delete(indexId)
+ newPos = indexId - 1
+ self.listbox2.selection_clear(0, END)
+ self.listbox2.insert(newPos, fontString)
+ self.listbox2.see(newPos - 10) # Scrolls listbox automatically into view if req.
+ self.listbox2.selection_set(newPos)
+ self.listbox2.activate(newPos) # make focus follow selection
+ self.__testUpDownState() # note tests only after an item has been moved
+
+ def __itemDown(self):
+ """Test if one item is selected then move it down one position."""
+ limit = self.listbox2.size()
+ selection = self.listbox2.curselection()
+ if len(selection) == 1:
+ indexId = IntType(selection[0])
+ if indexId < limit - 1:
+ fontString = self.listbox2.get(indexId)
+ self.listbox2.delete(indexId)
+ newPos = indexId + 1
+ self.listbox2.selection_clear(0, END)
+ self.listbox2.insert(newPos, fontString)
+ self.listbox2.see(newPos + 10)
+ self.listbox2.selection_set(newPos)
+ self.listbox2.activate(newPos) # make focus follow selection
+ self.__testUpDownState()
+
+ def __setUpDownActive(self, up, down):
+ """Just sets the buttons active or inactive.
+
+ See testUpDown() for the actual evaluation
+ """
+ if up == 1:
+ self.itemupButton['state'] = NORMAL
+ else:
+ self.itemupButton['state'] = DISABLED
+ if down == 1:
+ self.itemdownButton['state'] = NORMAL
+ else:
+ self.itemdownButton['state'] = DISABLED
+
+ def __testUpDownState(self):
+ """Only enable the up and down buttons when just a single item is selected.
+
+ Enable should be applied to up, down or both depending on its
+ position in the listbox. At all other times disable both.
+ """
+ # Get a count of how many items are currently selected...
+ selection = list(self.listbox2.curselection())
+ tcount = 0
+ for sel in selection:
+ tcount = tcount + 1
+
+ position = 0
+ if tcount == 1:
+ position = IntType(selection[0])
+
+ # If one selected and there is more than one item in the listbox then ok...
+ if tcount == 1 and self.listbox2.size() > 1:
+ # Now test the position of the selected line...
+ if position > 0 and position < self.listbox2.size() - 1: # Both
+ self.__setUpDownActive(1, 1)
+ # If not one less or lesser from the bottom (listbox.count-1?) then gray the down button.
+ elif position == self.listbox2.size() - 1: # Up only
+ self.__setUpDownActive(1, 0)
+ # If not one or more from the top then gray up button.
+ elif position == 0: # Down only
+ self.__setUpDownActive(0, 1)
+ else:
+ self.__setUpDownActive(0, 0)
+
+ def __curSelectedItem(self, selectedFont):
+ """Send the selected font to the preview function if preview available."""
+ if showPreviewPanel:
+ preview_font(self, selectedFont)
+
+ # create the button events...
+ def __rsingleButtonClick(self):
+ self.__listSelectionToRight()
+
+ def __rdoubleButtonClick(self):
+ self.__listAllToRight()
+
+ def __lsingleButtonClick(self):
+ self.__listSelectionToLeft()
+ self.__testUpDownState()
+
+ def __ldoubleButtonClick(self):
+ self.__listAllToLeft()
+ self.__testUpDownState()
+
+ def __itemupButtonClick(self):
+ self.__itemUp()
+
+ def __itemdownButtonClick(self):
+ self.__itemDown()
+
+ def __tocSelectButtonClick(self):
+ userPrefs['wantTOC'] = self.__wantToc.get()
+ if userPrefs['wantTOC']:
+ self.btnPageOneOnFirst['state'] = NORMAL
+ else:
+ self.btnPageOneOnFirst['state'] = DISABLED
+
+ def __pageNumberSelectButtonClick(self):
+ userPrefs['wantPageNumbers'] = self.__wantPageNum.get()
+
+ def __bindingoffsetSelectButtonClick(self):
+ userPrefs['wantBindingOffset'] = self.__wantBindingOffset.get()
+ dD.update(set_page_geometry(dD, geometriesList, userPrefs['paperSize'], userPrefs['wantBindingOffset']))
+
+ def __doubleSidedSelectButtonClick(self):
+ userPrefs['wantDoubleSided'] = self.__wantDoubleSided.get()
+
+ def __wantPageOneOnFirstClick(self):
+ userPrefs['wantPageOneOnFirst'] = self.__wantPageOneOnFirst.get()
+
+ def __cancelButtonClick(self):
+ """We exit the app here if user presses cancel."""
+ self.master.destroy()
+
+ def __okButtonClick(self):
+ """User presses ok, so lets create the pages."""
+ save_user_conf(CONFIG_PATH)
+ draw_selection(self.listbox2.get(0, END), 0)
+ self.master.destroy()
+
+ def __configurationDlgShow(self):
+ """Opens the configuration dialog where user can set up the options"""
+ configs = ConfigurationDialog(self)
+ self.statusbarUpdate()
+
+ def __saveCurrentSettingsAsDefaults(self):
+ """Stores current settings as defaults."""
+ defaultPrefs.update(userPrefs)
+ save_user_conf(CONFIG_PATH)
+
+ def __restoreCurrentSettingsFromDefault(self):
+ """Restores current settings from defaults."""
+ userPrefs.update(defaultPrefs)
+ self.initialiseWidgets()
+ self.statusbarUpdate()
+
+ def initialiseWidgets(self):
+ if userPrefs['wantPageNumbers']:
+ self.pagenumSelect.select()
+ else:
+ self.pagenumSelect.deselect()
+ if userPrefs['wantTOC']:
+ self.tocSelect.select()
+ self.btnPageOneOnFirst['state'] = NORMAL
+ else:
+ self.tocSelect.deselect()
+ self.btnPageOneOnFirst['state'] = DISABLED
+ if userPrefs['wantBindingOffset']:
+ self.bindingoffsetSelect.select()
+ else:
+ self.bindingoffsetSelect.deselect()
+ if userPrefs['wantDoubleSided']:
+ self.doublesidedSelect.select()
+ else:
+ self.doublesidedSelect.deselect()
+ if userPrefs['wantPageOneOnFirst']:
+ self.btnPageOneOnFirst.select()
+ else:
+ self.btnPageOneOnFirst.deselect()
+
+ def __aboutDlgShow(self):
+ """Brings up a dialog with support url etc."""
+ about = AboutDialog(self)
+
+
+def setup_tk():
+ """Create and setup the Tkinter app."""
+ root = Tk()
+ app = Application(root)
+ app.master.title(WINDOW_TITLE)
+
+ # now get a list of all the fonts Scribus knows about...
+ fontList = scribus.getFontNames()
+ fontList.sort()
+ # and load the list into the GUI listbox...
+ for i in fontList:
+ app.listbox1.insert(END, i)
+ app.sampleBlocksPerPage = draw_selection(scribus.getFontNames(), 1)
+ # now set the status bar message...
+ app.statusbarUpdate()
+ # set up widgets using data from userPrefs...
+ app.initialiseWidgets()
+ return app
+
+def initialisation():
+ """Test for suitable fonts and on success creates tkinter app."""
+ try:
+ dD['bookstyleFixedFont'] = set_font_fixed(fontsListFixed)
+ dD['bookstylePropFont'] = set_font_proportional(fontsListProportional)
+ except:
+ scribus.messageBox('Font problem',
+ '%s' % sys.exc_info()[1],
+ scribus.ICON_WARNING)
+ sys.exit(1)
+ # load users saved defaults...
+ restore_user_conf(CONFIG_PATH)
+ # get and set the initial paper size to match default radiobutton selection...
+ dD.update(set_page_geometry(dD, geometriesList, userPrefs['paperSize'], userPrefs['wantBindingOffset']))
+ # Made it this far so its time to create our Tkinter app...
+ app = setup_tk()
+ # now show the main window and wait for user to do something...
+ app.mainloop()
+
+
+def main(argv):
+ """Application initialization, font checks and initial setup."""
+ initialisation()
+
+
+def main_wrapper(argv):
+ """The main_wrapper() function disables redrawing, sets a sensible generic
+ status bar message, and optionally sets up the progress bar. It then runs
+ the main() function. Once everything finishes it cleans up after the main()
+ function, making sure everything is sane before the script terminates."""
+ try:
+ scribus.statusMessage('Running script...')
+ scribus.progressReset()
+ main(argv)
+ finally:
+ # Exit neatly even if the script terminated with an exception,
+ # so we leave the progress bar and status bar blank and make sure
+ # drawing is enabled.
+ if scribus.haveDoc():
+ scribus.setRedraw(True)
+ scribus.statusMessage('')
+ scribus.progressReset()
+
+
+# This code detects if the script is being run as a script, or imported as a module.
+# It only runs main() if being run as a script. This permits you to import your script
+# and control it manually for debugging.
+if __name__ == '__main__':
+ main_wrapper(sys.argv)
+