source: applications/FeatureProof/trunk/Lib/featureProof/documentWindow.py @ 46

Revision 46, 27.2 KB checked in by tal, 6 years ago (diff)
The canvas element experiment didn't work out. The support for the element is too buggy. So, I've reverted back to generating PNG files in a temp directory.
Line 
1import os
2import shutil
3from AppKit import *
4import vanilla
5from compositor.logger import Logger
6from fontAppTools import splitText
7from baseWindow import BaseWindow
8from scriptAndLanguageTags import scriptTags, languageTags
9from glyphLineView import GlyphLineView
10from browser import Browser
11from htmlView import HTMLView
12from htmlView.template import defaultHTML
13
14
15inDevelopmentMode = "/site-packages.zip/" not in __file__
16sourceListBackgroundColor = NSColor.colorWithCalibratedRed_green_blue_alpha_(212/255.0, 219/255.0, 227/255.0, 1.0)
17sourceListTitleColor = NSColor.colorWithCalibratedRed_green_blue_alpha_(113/255.0, 125/255.0, 142/255.0, 1.0)
18
19
20class DocumentWindow(BaseWindow):
21
22    def __init__(self, font):
23        self.font = font
24
25        gsub = font.gsub
26        if gsub is None:
27            gsubFeatureList = []
28        else:
29            gsubFeatureList = [{"state":gsub.getFeatureState(name), "name":name}
30                                for name in gsub.getFeatureList()]
31        gpos = font.gpos
32        if gpos is None:
33            gposFeatureList = []
34        else:
35            gposFeatureList = [{"state":gpos.getFeatureState(name), "name":name}
36                                for name in gpos.getFeatureList()]
37
38        self.w = vanilla.Window((800, 520), minSize=(500, 520), autosaveName="DocumentWindow")
39
40        ## font state controls for interactive and log views
41        self.fontStateControls = vanilla.Group((0, 0, 140, 1005))
42        s = vanilla.ScrollView((0, 50, 140, -0), self.fontStateControls.getNSView(),
43                backgroundColor=sourceListBackgroundColor, hasHorizontalScroller=False)
44        s._frameAdjustments = (-1, -1, 1, 1)
45        self.w.fontStateControlsScrollView = s
46        frame = self.w.fontStateControlsScrollView.getNSScrollView().contentView().frame()
47        self.fontStateControls._setFrame(frame)
48
49        # script
50        supported = []
51        unsupported = []
52        scriptIndex = 0
53        attributes = {NSForegroundColorAttributeName : NSColor.grayColor()}
54        fontScriptTags = self.font.getScriptList()
55        for tag in scriptTags:
56            if tag not in fontScriptTags:
57                tag = NSMutableAttributedString.alloc().initWithString_attributes_(tag, attributes)
58                unsupported.append(dict(item=tag))
59            else:
60                if tag == "latn":
61                    scriptIndex = len(supported)
62                supported.append(dict(item=tag))
63
64        self.fontStateControls.scriptTitle = vanilla.TextBox((10, 10, -0, 17), "SCRIPT")
65        self.fontStateControls.scriptList = vanilla.List((10, 30, 100, 100), supported+unsupported,
66            allowsEmptySelection=False, allowsMultipleSelection=False, enableTypingSensitivity=True,
67            selectionCallback=self.updateInteractiveDisplay)
68        self.fontStateControls.scriptList.getNSTableView().setFocusRingType_(NSFocusRingTypeNone)
69
70        # language
71        supported = []
72        unsupported = []
73        attributes = {NSForegroundColorAttributeName : NSColor.grayColor()}
74        fontLanguageTags = self.font.getLanguageList()
75        for tag in languageTags:
76            if tag not in fontLanguageTags and tag != "Default":
77                tag = NSMutableAttributedString.alloc().initWithString_attributes_(tag, attributes)
78                unsupported.append(dict(item=tag))
79            else:
80                supported.append(dict(item=tag))
81
82        self.fontStateControls.languageTitle = vanilla.TextBox((10, 145, -0, 17), "LANGUAGE")
83        self.fontStateControls.languageList = vanilla.List((10, 165, 100, 100), supported+unsupported,
84            allowsEmptySelection=False, allowsMultipleSelection=False, enableTypingSensitivity=True,
85            selectionCallback=self.updateInteractiveDisplay)
86        self.fontStateControls.languageList.getNSTableView().setFocusRingType_(NSFocusRingTypeNone)
87
88        # direction
89        self.fontStateControls.directionTitle = vanilla.TextBox((10, 280, -0, 17), "DIRECTION")
90        self.fontStateControls.directionRadioGroup = vanilla.RadioGroup((10, 300, 100, 40),
91            ["Left to Right", "Right to Left"], callback=self.updateInteractiveDisplay)
92
93        self.fontStateControls.line1 = vanilla.HorizontalLine((0, 355, -0, 1))
94
95        # GSUB
96        columnDescriptions = [
97            dict(title="state", cell=vanilla.CheckBoxListCell(), editable=True, width=16),
98            dict(title="name", editable=False, width=69),
99        ]
100        self.fontStateControls.gsubTitle = vanilla.TextBox((10, 370, -0, 17), "GSUB")
101        self.fontStateControls.gsubList = vanilla.List((10, 390, 100, 200), gsubFeatureList,
102            columnDescriptions=columnDescriptions, allowsEmptySelection=True, allowsMultipleSelection=False,
103            showColumnTitles=False, editCallback=self.updateInteractiveDisplay)
104        self.fontStateControls.gsubList.getNSTableView().setFocusRingType_(NSFocusRingTypeNone)
105
106        # GPOS
107        columnDescriptions = [
108            dict(title="state", cell=vanilla.CheckBoxListCell(), editable=True, width=16),
109            dict(title="name", editable=False, width=69),
110        ]
111        self.fontStateControls.gposTitle = vanilla.TextBox((10, 605, -0, 17), "GPOS")
112        self.fontStateControls.gposList = vanilla.List((10, 625, 100, 200), gposFeatureList,
113            columnDescriptions=columnDescriptions, allowsEmptySelection=True, allowsMultipleSelection=False,
114            showColumnTitles=False, editCallback=self.updateInteractiveDisplay)
115        self.fontStateControls.gposList.getNSTableView().setFocusRingType_(NSFocusRingTypeNone)
116
117        self.fontStateControls.line2 = vanilla.HorizontalLine((0, 840, -0, 1))
118
119        # case
120        self.fontStateControls.caseTitle = vanilla.TextBox((10, 855, -0, 17), "CASE")
121        self.fontStateControls.caseRadioGroup = vanilla.RadioGroup((10, 875, 100, 60),
122            ["Unchanged", "Uppercase", "Lowercase"], callback=self.updateInteractiveDisplay)
123
124        # point size
125        self.fontStateControls.pointSizeTitle = vanilla.TextBox((10, 950, -0, 17), "POINT SIZE")
126        self.fontStateControls.pointSizeComboBox = vanilla.ComboBox((10, 970, 100, 21),
127            ["Auto", "200", "100", "75", "50", "25"], callback=self.pointSizeEditCallback)
128
129        ## test case controls
130        self.testCaseControls = vanilla.Group((0, 0, 189, 490))
131        s = vanilla.ScrollView((0, 0, 190, -0), self.testCaseControls.getNSView(),
132                backgroundColor=sourceListBackgroundColor, autohidesScrollers=True)
133        s._frameAdjustments = (-1, -1, 1, 1)
134        self.w.testCaseControlsScrollView = s
135        frame = self.w.testCaseControlsScrollView.getNSScrollView().contentView().frame()
136        self.testCaseControls._setFrame(frame)
137        self.w.testCaseControlsScrollView.show(False)
138
139        # file list
140        self.testCaseControls.fileTitle = vanilla.TextBox((10, 10, -10, 17), "TEST CASE FILES")
141        columnDescriptions = [dict(title="name", editable=False)]
142        self.testCaseControls.fileList = vanilla.List((10, 30, -10, 150), [], columnDescriptions=columnDescriptions, showColumnTitles=False)
143        self.testCaseControls.fileList.getNSTableView().setFocusRingType_(NSFocusRingTypeNone)
144        self.testCaseControls.fileListButtonFill = vanilla.ImageView((10, 180, 169, 19))
145        self.testCaseControls.fileListButtonFill.setImage(imageNamed="fileListButtonFill")
146        self.testCaseControls.addFileButton = vanilla.ImageButton((10, 180, 20, 19), imageNamed="buttonAdd", bordered=False, callback=self.testCasesAddFilesCallback)
147        self.testCaseControls.removeFileButton = vanilla.ImageButton((30, 180, 19, 19), imageNamed="buttonRemove", bordered=False, callback=self.testCasesRemoveFilesCallback)
148
149        self.testCaseControls.line1 = vanilla.HorizontalLine((0, 215, -0, 1))
150
151        # buttons
152        self.testCaseControls.evaluateButton = vanilla.Button((10, 230, -10, 20), "Evaluate Tests", callback=self.evaluateTestsCallback)
153        self.testCaseControls.evaluateButton.enable(False)
154        self.testCaseControls.exportButton = vanilla.Button((10, 260, -10, 20), "Export Results", callback=self.exportTestResultsCallback)
155        self.testCaseControls.exportButton.enable(False)
156
157        self.testCaseControls.line2 = vanilla.HorizontalLine((0, 295, -0, 1))
158
159        # view options
160        self.testCaseControls.viewOptionsTitle = vanilla.TextBox((10, 310, -10, 17), "SHOW")
161        self.testCaseControls.viewOptionsGlyphOrStringRadioGroup = vanilla.RadioGroup((10, 330, -10, 40),
162            ["Glyphs", "Glyph Records"], callback=self.updateTestCaseView)
163        self.testCaseControls.viewOptionsShowNotes = vanilla.CheckBox((12, 375, -10, 22), "Notes", value=True, callback=self.updateTestCaseView)
164        self.testCaseControls.viewOptionsShowPassed = vanilla.CheckBox((12, 400, -10, 22), "Passed Tests", value=True, callback=self.updateTestCaseView)
165        self.testCaseControls.viewOptionsGlyphSizeTitle = vanilla.TextBox((10, 435, -10, 17), "GLYPH SIZE")
166        self.testCaseControls.viewOptionsGlyphSizeSlider = vanilla.Slider((10, 455, -10, 15), value=20, minValue=10, maxValue=100, continuous=False, callback=self.updateTestCaseView)
167        self.testCaseControls.viewOptionsGlyphOrStringRadioGroup.enable(False)
168        self.testCaseControls.viewOptionsShowNotes.enable(False)
169        self.testCaseControls.viewOptionsShowPassed.enable(False)
170        self.testCaseControls.viewOptionsGlyphSizeSlider.enable(False)
171
172        ## text entry
173        self.w.textEntryField = vanilla.EditText((15, 15, -15, 22), callback=self.updateInteractiveDisplay)
174
175        ## interactive glyph view
176        self.interactivePreview = GlyphLineView.alloc().initWithFont(font)
177        s = vanilla.ScrollView((140, 50, -0, -0), self.interactivePreview)
178        s._frameAdjustments = (-1, -1, 2, 1)
179        self.w.interactivePreviewScrollView = s
180
181        ## interactive glyph list
182        columnDescriptions = [
183            dict(title="Name", width=100),
184            dict(title="XP", width=50),
185            dict(title="YP", width=50),
186            dict(title="XA", width=50),
187            dict(title="YA", width=50),
188            dict(title="Alternates", width=100)
189        ]
190        s = vanilla.List((139, 50, -0, -0), [], columnDescriptions=columnDescriptions,
191            showColumnTitles=True, drawVerticalLines=True)
192        s._frameAdjustments = (-1, -1, 2, 1)
193        self.w.interactiveGlyphList = s
194        self.w.interactiveGlyphList.show(False)
195
196        ## interactive log
197        l = HTMLView((139, 50, -0, -0))
198        l._frameAdjustments = (-1, -1, 2, 1)
199        self.w.interactiveLogView = l
200        self.w.interactiveLogView.show(False)
201
202        ## test case view
203        s = HTMLView((190, 0, -0, -0))
204        s._frameAdjustments = (-1, -1, 2, 1)
205        self.w.testCaseView = s
206        self.w.testCaseView.set(defaultHTML)
207        self.w.testCaseView.show(False)
208
209        ## source browser
210        tree = dict(
211            GSUB=self.font.gsub,
212            GPOS=self.font.gpos,
213            GDEF=self.font.gdef,
214        )
215        if inDevelopmentMode:
216            self.font.source["OS/2"]
217            tree["Source"] = self.font.source
218        b = Browser((0, 0, -0, -0), tree)
219        b._frameAdjustments = (-1, -1, 2, 1)
220        self.w.sourceBrowser = b
221        self.w.sourceBrowser.show(False)
222
223        ## set the drawing style for the source list section titles
224        titles = [
225            self.fontStateControls.scriptTitle,
226            self.fontStateControls.languageTitle,
227            self.fontStateControls.directionTitle,
228            self.fontStateControls.gsubTitle,
229            self.fontStateControls.gposTitle,
230            self.fontStateControls.caseTitle,
231            self.fontStateControls.pointSizeTitle,
232            self.testCaseControls.fileTitle,
233            self.testCaseControls.viewOptionsTitle,
234            self.testCaseControls.viewOptionsGlyphSizeTitle
235        ]
236        titleShadow = NSShadow.alloc().init()
237        titleShadow.setShadowOffset_((2, -2))
238        titleShadow.setShadowColor_(NSColor.whiteColor())
239        titleShadow.setShadowBlurRadius_(1.0)
240        attributes = {NSShadowAttributeName : titleShadow}
241        for textBox in titles:
242            nsTextField = textBox.getNSTextField()
243            nsTextField.setFont_(NSFont.boldSystemFontOfSize_(12))
244            nsTextField.setTextColor_(sourceListTitleColor)
245            attributedString = NSAttributedString.alloc().initWithString_attributes_(textBox.get(), attributes)
246            nsTextField.setAttributedStringValue_(attributedString)
247
248        ## set up the toolbar
249        items = [
250            dict(itemIdentifier="interactivePreview",
251                label="Preview",
252                #imageNamed="toolbarPreview",
253                callback=self.toolbarSelection
254                ),
255            dict(itemIdentifier="interactiveList",
256                label="List",
257                #imageNamed="toolbarPreview",
258                callback=self.toolbarSelection
259                ),
260            dict(itemIdentifier="interactiveLog",
261                label="Log",
262                #imageNamed="toolbarPreview",
263                callback=self.toolbarSelection
264                ),
265            dict(itemIdentifier="testCases",
266                label="Tests",
267                #imageNamed="toolbarPreview",
268                callback=self.toolbarSelection
269                ),
270            dict(itemIdentifier="sourceBrowse",
271                label="Browse",
272                #imageNamed="toolbarPreview",
273                callback=self.toolbarSelection
274                ),
275        ]
276        self.w.addToolbar(toolbarIdentifier="FeatureProofDocumentToolbar", toolbarItems=items, addStandardItems=False)
277        toolbar = self.w.getNSWindow().toolbar()
278        toolbar.setAllowsUserCustomization_(False)
279        toolbar.setShowsBaselineSeparator_(False)
280        self.currentView = "interactivePreview"
281
282        ## default settings
283        self.fontStateControls.pointSizeComboBox.set("150")
284        self.interactivePreview.setPointSize(150)
285        self.fontStateControls.caseRadioGroup.set(0)
286        self.fontStateControls.directionRadioGroup.set(0)
287        self.fontStateControls.scriptList.setSelection([scriptIndex])
288        self.fontStateControls.languageList.setSelection([0])
289
290        self.setupDefaultWindowBehavior()
291        self.windowResizeCallback(None)
292        self.w.open()
293
294    # --------------------
295    # Window Notifications
296    # --------------------
297
298    def setupDefaultWindowBehavior(self):
299        super(DocumentWindow, self).setupDefaultWindowBehavior()
300        self.w.bind("resize", self.windowResizeCallback)
301
302    def windowResizeCallback(self, sender):
303        scrollViews = [
304            self.w.fontStateControlsScrollView,
305            self.w.testCaseControlsScrollView
306        ]
307        for scrollView in scrollViews:
308            scrollView = scrollView.getNSScrollView()
309            contentView = scrollView.contentView()
310            vanillaView = scrollView.documentView().vanillaWrapper()
311            frame = contentView.frame()
312            vanillaView._setFrame(frame)
313            contentView.scrollToPoint_((0, 0))
314            scrollView.reflectScrolledClipView_(contentView)
315
316    def windowCloseCallback(self, sender):
317        super(DocumentWindow, self).windowCloseCallback(sender)
318        self.tearDownTestCaseImageDirectory()
319
320    # ------------------
321    # Interface Updating
322    # ------------------
323
324    def toolbarSelection(self, sender):
325        itemIdentifier = sender.itemIdentifier()
326        self.currentView = itemIdentifier
327        visibleItems = {
328            "interactivePreview" : [
329                self.w.fontStateControlsScrollView,
330                self.w.textEntryField,
331                self.w.interactivePreviewScrollView
332            ],
333            "interactiveList" : [
334                self.w.fontStateControlsScrollView,
335                self.w.textEntryField,
336                self.w.interactiveGlyphList
337            ],
338            "interactiveLog" : [
339                self.w.fontStateControlsScrollView,
340                self.w.textEntryField,
341                self.w.interactiveLogView
342            ],
343            "testCases" : [
344                self.w.testCaseControlsScrollView,
345                self.w.testCaseView
346            ],
347            "sourceBrowse" : [
348                self.w.sourceBrowser
349            ],
350        }
351        allItems = []
352        for l in visibleItems.values():
353            allItems.extend(l)
354        allItems = set(allItems)
355        # show/hide the appropriate items
356        for item in allItems:
357            state = False
358            if item in visibleItems[itemIdentifier]:
359                state = True
360            item.show(state)
361        # update the interactive views as needed
362        if itemIdentifier.startswith("interactive"):
363            self.updateInteractiveDisplay()
364
365    # --------------------------
366    # User Interaction Callbacks
367    # --------------------------
368
369    def updateInteractiveDisplay(self, sender=None):
370        # create a log if the log view is open
371        if self.currentView == "interactiveLog":
372            logger = Logger()
373        else:
374            logger = None
375        # get the text
376        glyphNames = splitText(self.w.textEntryField.get(), self.font.cmap)
377        # get the script
378        script = self.fontStateControls.scriptList[self.fontStateControls.scriptList.getSelection()[0]]
379        # get the language
380        language = self.fontStateControls.languageList[self.fontStateControls.languageList.getSelection()[0]]
381        if language == "Default":
382            language = None
383        # get the direction
384        rightToLeft = self.fontStateControls.directionRadioGroup.get() == 1
385        # get the case
386        case = ["unchanged", "upper", "lower"][self.fontStateControls.caseRadioGroup.get()]
387        # handle the feature states
388        for i in self.fontStateControls.gsubList:
389            tag = i["name"]
390            state = i["state"]
391            self.font.gsub.setFeatureState(tag, state)
392        for i in self.fontStateControls.gposList:
393            tag = i["name"]
394            state = i["state"]
395            self.font.gpos.setFeatureState(tag, state)
396        # get the records
397        glyphRecords = self.font.process(glyphNames, script=script, langSys=language, rightToLeft=rightToLeft, logger=logger, case=case)
398        # update the appropriate view
399        if self.currentView == "interactivePreview":
400            self.interactivePreview.set(glyphRecords, rightToLeft)
401        elif self.currentView == "interactiveList":
402            items = []
403            for r in glyphRecords:
404                alternates = ", ".join(r.alternates)
405                i = dict(
406                    Name=r.glyphName,
407                    XP=r.xPlacement, YP=r.yPlacement, XA=r.xAdvance, YA=r.yAdvance,
408                    Alternates=alternates)
409                items.append(i)
410            self.w.interactiveGlyphList.set(items)
411        elif self.currentView == "interactiveLog":
412            from htmlView.logToHTML import logToHTML
413            html = logToHTML(logger.getText())
414            self.w.interactiveLogView.set(html)
415
416    def pointSizeEditCallback(self, sender):
417        value = sender.get()
418        loweredValue = str(value).lower()
419        if loweredValue == "auto" or loweredValue.startswith("a"):
420            value = None
421        else:
422            try:
423                value = int(value)
424            except ValueError:
425                NSBeep()
426                return
427        if value == 0:
428            NSBeep()
429            return
430        self.interactivePreview.setPointSize(value)
431
432    # ---------------
433    # Test Evaluation
434    # ---------------
435
436    def testCasesAddFilesCallback(self, sender):
437        self.showGetFile(["featest"], self._addTestFiles, True)
438
439    def _addTestFiles(self, result):
440        if result:
441            existing = [i["path"] for i in self.testCaseControls.fileList]
442            for path in result:
443                if path in existing:
444                    continue
445                self.testCaseControls.fileList.append(dict(name=os.path.basename(path), path=path))
446            # enable evaluate button
447            self.testCaseControls.evaluateButton.enable(True)
448            # disable export button
449            self.testCaseControls.exportButton.enable(False)
450            # destroy any existing controller
451            self.featureTestCaseController = None
452            # drop back to default html
453            self.tearDownTestCaseImageDirectory()
454            self.w.testCaseView.set(defaultHTML)
455            # turn of view options
456            self.testCaseControls.viewOptionsGlyphOrStringRadioGroup.enable(False)
457            self.testCaseControls.viewOptionsShowNotes.enable(False)
458            self.testCaseControls.viewOptionsShowPassed.enable(False)
459            self.testCaseControls.viewOptionsGlyphSizeSlider.enable(False)
460
461    def testCasesRemoveFilesCallback(self, sender):
462        toRemove = reversed(sorted(self.testCaseControls.fileList.getSelection()))
463        haveRemoved = False
464        for index in toRemove:
465            del self.testCaseControls.fileList[index]
466            haveRemoved = True
467        if not len(self.testCaseControls.fileList):
468            # turn off evaluate button
469            self.testCaseControls.evaluateButton.enable(False)
470        if haveRemoved:
471            # turn off export button
472            self.testCaseControls.exportButton.enable(False)
473            # destroy any existing controller
474            self.featureTestCaseController = None
475            # drop back to default html
476            self.tearDownTestCaseImageDirectory()
477            self.w.testCaseView.set(defaultHTML)
478            # turn of view options
479            self.testCaseControls.viewOptionsGlyphOrStringRadioGroup.enable(False)
480            self.testCaseControls.viewOptionsShowNotes.enable(False)
481            self.testCaseControls.viewOptionsShowPassed.enable(False)
482            self.testCaseControls.viewOptionsGlyphSizeSlider.enable(False)
483
484    def evaluateTestsCallback(self, sender):
485        from feaTest import FeaTest, FeaTestError
486        # start the progress
487        progressController = self.startProgress(text="Evaluating Tests...")
488        # get the viable paths
489        paths = [i["path"] for i in self.testCaseControls.fileList]
490        # set up the tester
491        tester = self.featureTestCaseController = FeaTest(self.font)
492        # process each file
493        for path in paths:
494            # make sure it exists
495            if not os.path.exists(path):
496                self.showMessage(messageText="Missing File: %s" % path, informativeText=str(message))
497            # test each file
498            else:
499                gsubStates, gposStates = self._getFeatureStates()
500                try:
501                    tester.evaluateTests(path)
502                except FeaTestError, message:
503                    self.parentController.showMessage(messageText="There was a problem parsing the file: %s" % path, informativeText=str(message))
504                self._restoreFeatureStates(gsubStates, gposStates)
505        # update the view
506        self.updateTestCaseView()
507        progressController.close()
508        # enable export
509        self.testCaseControls.exportButton.enable(True)
510        # enable view options
511        self.testCaseControls.viewOptionsGlyphOrStringRadioGroup.enable(True)
512        self.testCaseControls.viewOptionsShowNotes.enable(True)
513        self.testCaseControls.viewOptionsShowPassed.enable(True)
514        self.testCaseControls.viewOptionsGlyphSizeSlider.enable(True)
515
516    def _getFeatureStates(self):
517        savedGSUBStates = {}
518        savedGPOSStates = {}
519        if self.font.gsub is not None:
520            for tag in self.font.gsub.getFeatureList():
521                savedGSUBStates[tag] = self.font.gsub.getFeatureState(tag)
522        if self.font.gpos is not None:
523            for tag in self.font.gpos.getFeatureList():
524                savedGPOSStates[tag] = self.font.gpos.getFeatureState(tag)
525        return savedGSUBStates, savedGPOSStates
526
527    def _restoreFeatureStates(self, savedGSUBStates, savedGPOSStates):
528        if self.font.gsub is not None:
529            for tag, state in savedGSUBStates.items():
530                self.font.gsub.setFeatureState(tag, state)
531        if self.font.gpos is not None:
532            for tag, state in savedGPOSStates.items():
533                self.font.gpos.setFeatureState(tag, state)
534
535    def exportTestResultsCallback(self, sender):
536        self.fileExportAccessoryView = ExportTestResultsAccessoryView()
537        fileName = os.path.splitext(os.path.basename(self.font.path))[0] + ".pdf"
538        self.showPutFile(fileTypes=["pdf", "txt"], fileName=fileName, callback=self._exportTestResults, accessoryView=self.fileExportAccessoryView.getView())
539
540    def _exportTestResults(self, path):
541        from feaTest.toInDesignTaggedText import makeTaggedText
542        from feaTest.toPDF import makePDF
543        if path:
544            progress = self.startProgress("Exporting Results...")
545            xml = self.featureTestCaseController.exportResults()
546            format, pageSize = self.fileExportAccessoryView.getResult()
547            if format == "PDF":
548                makePDF(xml, self.font, pageSize, path)
549            else:
550                makeTaggedText(xml, self.font, path)
551            progress.close()
552        del self.fileExportAccessoryView
553
554    def updateTestCaseView(self, sender=None):
555        from htmlView.testResultsToHTML import makeHTML
556        self.tearDownTestCaseImageDirectory()
557        showGlyphs = self.testCaseControls.viewOptionsGlyphOrStringRadioGroup.get() != 1
558        showNotes = self.testCaseControls.viewOptionsShowNotes.get()
559        showPassed = self.testCaseControls.viewOptionsShowPassed.get()
560        glyphPointSize = int(self.testCaseControls.viewOptionsGlyphSizeSlider.get())
561        width = self.w.testCaseView.getNSScrollView().contentView().visibleRect().size[0] - 20
562        xml = self.featureTestCaseController.exportResults()
563        html, self.testCaseImageDirectory = makeHTML(xml, self.font, width, showGlyphs=showGlyphs, showNotes=showNotes, showPassed=showPassed, glyphPointSize=glyphPointSize)
564        self.w.testCaseView.set(html)
565
566    def tearDownTestCaseImageDirectory(self):
567        if hasattr(self, "testCaseImageDirectory") and self.testCaseImageDirectory is not None:
568            if os.path.exists(self.testCaseImageDirectory):
569                shutil.rmtree(self.testCaseImageDirectory)
570            del self.testCaseImageDirectory
571
572
573class ExportTestResultsAccessoryView(object):
574
575    def __init__(self):
576        pageSizes = [
577            "Letter",
578            "Legal",
579            "Tabloid",
580            "A4",
581            "A3"
582        ]
583        self.view = vanilla.Group((0, 0, 255, 80))
584        self.view.formatTitle = vanilla.TextBox((0, 17, 70, 17), "Format:", alignment="right")
585        self.view.formatPopUp = vanilla.PopUpButton((75, 15, 180, 20), ["PDF", "InDesign Tagged Text"], callback=self.formatCallback)
586        self.view.pageSizeTitle = vanilla.TextBox((0, 47, 70, 17), "Page Size:", alignment="right")
587        self.view.pageSizesPopUp = vanilla.PopUpButton((75, 45, 180, 20), pageSizes)
588
589    def getView(self):
590        return self.view
591
592    def formatCallback(self, sender):
593        if sender.get() == 0:
594            self.view.pageSizesPopUp.enable(True)
595        else:
596            self.view.pageSizesPopUp.enable(False)
597
598    def getResult(self):
599        from reportlab.lib.pagesizes import LETTER, LEGAL, ELEVENSEVENTEEN, A4, A3
600        pageSizes = [
601            LETTER,
602            LEGAL,
603            ELEVENSEVENTEEN,
604            A4,
605            A3
606        ]
607        if self.view.formatPopUp.get() == 0:
608            return "PDF", pageSizes[self.view.pageSizesPopUp.get()]
609        else:
610            return "InDesign Tagged Text", None
Note: See TracBrowser for help on using the repository browser.