Example #1
0
    def OnSuggest(self, event):
        if not self.sc.word:
            return

        isAllCaps = self.sc.word == util.upper(self.sc.word)
        isCapitalized = self.sc.word[:1] == util.upper(self.sc.word[:1])

        word = util.lower(self.sc.word)

        wl = len(word)
        wstart = word[:2]
        d = 500
        fifo = util.FIFO(5)
        wx.BeginBusyCursor()

        for w in spellcheck.prefixDict[util.getWordPrefix(word)]:
            if w.startswith(wstart):
                d = self.tryWord(word, wl, w, d, fifo)

        for w in self.gScDict.words.iterkeys():
            if w.startswith(wstart):
                d = self.tryWord(word, wl, w, d, fifo)

        for w in self.ctrl.sp.scDict.words.iterkeys():
            if w.startswith(wstart):
                d = self.tryWord(word, wl, w, d, fifo)

        items = fifo.get()

        wx.EndBusyCursor()

        if len(items) == 0:
            wx.MessageBox("No similar words found.", "Results",
                          wx.OK, self)

            return

        dlg = wx.SingleChoiceDialog(
            self, "Most similar words:", "Suggestions", items)

        if dlg.ShowModal() == wx.ID_OK:
            sel = dlg.GetSelection()

            newWord = items[sel]

            if isAllCaps:
                newWord = util.upper(newWord)
            elif isCapitalized:
                newWord = util.capitalize(newWord)

            self.replaceEntry.SetValue(newWord)

        dlg.Destroy()
Example #2
0
    def refresh(self):
        for t in self.types.itervalues():
            tmp = []

            for v in t.items:
                v = util.upper(util.toInputStr(v)).strip()

                if len(v) > 0:
                    tmp.append(v)

            t.items = tmp
Example #3
0
    def OnPaint(self, event):
        dc = wx.BufferedPaintDC(self, self.screenBuf)

        size = self.GetClientSize()
        dc.SetBrush(wx.WHITE_BRUSH)
        dc.SetPen(wx.WHITE_PEN)
        dc.DrawRectangle(0, 0, size.width, size.height)

        dc.SetPen(wx.BLACK_PEN)
        dc.SetTextForeground(wx.BLACK)

        for y in range(self.rows + 1):
            util.drawLine(dc, self.offset, self.offset + y * self.cellSize,
                          self.cols * self.cellSize + 1, 0)

        for x in range(self.cols + 1):
            util.drawLine(dc, self.offset + x * self.cellSize,
                self.offset, 0, self.rows * self.cellSize)

        dc.SetFont(self.normalFont)

        for y in range(self.rows):
            for x in range(self.cols):
                i = y * self.cols + x
                if i < len(self.chars):
                    util.drawText(dc, self.chars[i],
                        x * self.cellSize + self.offset + self.cellSize // 2 + 1,
                        y * self.cellSize + self.offset + self.cellSize // 2 + 1,
                        util.ALIGN_CENTER, util.VALIGN_CENTER)

        y = self.offset + self.rows * self.cellSize
        pad = 5

        if self.selected:
            self.drawCharBox(dc, "Selected:", self.selected, self.offset,
                             y + pad, 75)

            c = util.upper(self.selected)
            if c == self.selected:
                c = util.lower(self.selected)
                if c == self.selected:
                    c = None

            if c:
                self.drawCharBox(dc, "Opposite case:", c, self.offset + 150,
                                 y + pad, 110)

            dc.SetFont(self.smallFont)
            dc.DrawText("Character code: %d" % ord(self.selected),
                        360, y + pad)
        else:
            dc.SetFont(self.smallFont)
            dc.DrawText("Click on a character to select it.", self.offset,
                        y + pad)
Example #4
0
    def refresh(self):
        for t in self.types.itervalues():
            tmp = []

            for v in t.items:
                v = util.upper(util.toInputStr(v)).strip()

                if len(v) > 0:
                    tmp.append(v)

            t.items = tmp
Example #5
0
    def getScreen(self, ctrl, doExtra, partials=False, pageCache=None):
        cfg = ctrl.sp.cfg
        cfgGui = ctrl.getCfgGui()

        width, height = ctrl.GetClientSizeTuple()
        ls = ctrl.sp.lines
        y = 15
        i = ctrl.sp.getTopLine()

        marginLeft = int(ctrl.mm2p * cfg.marginLeft)
        cox = util.clamp((width - ctrl.pageW) // 2, 0)
        fyd = ctrl.sp.cfgGl.fontYdelta
        length = len(ls)

        texts = []

        while (y < height) and (i < length):
            y += int((ctrl.sp.getSpacingBefore(i) / 10.0) * fyd)

            if y >= height:
                break

            if not partials and ((y + fyd) > height):
                break

            l = ls[i]
            tcfg = cfg.getType(l.lt)

            if tcfg.screen.isCaps:
                text = util.upper(l.text)
            else:
                text = l.text

            fi = cfgGui.tt2fi(tcfg.screen)

            extraIndent = 1 if ctrl.sp.needsExtraParenIndent(i) else 0

            texts.append(
                TextString(
                    i, text,
                    cox + marginLeft + (tcfg.indent + extraIndent) * fi.fx, y,
                    fi, tcfg.screen.isUnderlined))

            y += fyd
            i += 1

        return (texts, [])
Example #6
0
    def read(self, sp, startLine, endLine):
        self.number = sp.getSceneNumber(startLine)

        ls = sp.lines

        # TODO: handle multi-line scene names
        if ls[startLine].lt == screenplay.SCENE:
            s = util.upper(ls[startLine].text)

            if len(s.strip()) == 0:
                self.name = "(EMPTY SCENE NAME)"
            else:
                self.name = s
        else:
            self.name = "(NO SCENE NAME)"

        self.pages.addPage(sp.line2page(startLine))

        line = startLine

        # skip over scene headers
        while (line <= endLine) and (ls[line].lt == screenplay.SCENE):
            line = sp.getElemLastIndexFromLine(line) + 1

        if line > endLine:
            # empty scene
            return

        # re-define startLine to be first line after scene header
        startLine = line

        self.lines = endLine - startLine + 1

        # get number of action lines and store page information
        for i in range(startLine, endLine + 1):
            self.pages.addPage(sp.line2page(i))

            if ls[i].lt == screenplay.ACTION:
                self.actionLines += 1

        line = startLine
        while 1:
            line = self.readSpeech(sp, line, endLine)
            if line >= endLine:
                break
Example #7
0
    def read(self, sp, startLine, endLine):
        self.number = sp.getSceneNumber(startLine)

        ls = sp.lines

        # TODO: handle multi-line scene names
        if ls[startLine].lt == screenplay.SCENE:
            s = util.upper(ls[startLine].text)

            if len(s.strip()) == 0:
                self.name = "(EMPTY SCENE NAME)"
            else:
                self.name = s
        else:
            self.name = "(NO SCENE NAME)"

        self.pages.addPage(sp.line2page(startLine))

        line = startLine

        # skip over scene headers
        while (line <= endLine) and (ls[line].lt == screenplay.SCENE):
            line = sp.getElemLastIndexFromLine(line) + 1

        if line > endLine:
            # empty scene
            return

        # re-define startLine to be first line after scene header
        startLine = line

        self.lines = endLine - startLine + 1

        # get number of action lines and store page information
        for i in range(startLine, endLine + 1):
            self.pages.addPage(sp.line2page(i))

            if ls[i].lt == screenplay.ACTION:
                self.actionLines += 1

        line = startLine
        while 1:
            line = self.readSpeech(sp, line, endLine)
            if line >= endLine:
                break
Example #8
0
    def getScreen(self, ctrl, doExtra, partials = False, pageCache = None):
        cfg = ctrl.sp.cfg
        cfgGui = ctrl.getCfgGui()

        width, height = ctrl.GetClientSizeTuple()
        ls = ctrl.sp.lines
        y = 15
        i = ctrl.sp.getTopLine()

        marginLeft = int(ctrl.mm2p * cfg.marginLeft)
        cox = util.clamp((width - ctrl.pageW) // 2, 0)
        fyd = ctrl.sp.cfgGl.fontYdelta
        length = len(ls)

        texts = []

        while (y < height) and (i < length):
            y += int((ctrl.sp.getSpacingBefore(i) / 10.0) * fyd)

            if y >= height:
                break

            if not partials and ((y + fyd) > height):
                break

            l = ls[i]
            tcfg = cfg.getType(l.lt)

            if tcfg.screen.isCaps:
                text = util.upper(l.text)
            else:
                text = l.text

            fi = cfgGui.tt2fi(tcfg.screen)

            extraIndent = 1 if ctrl.sp.needsExtraParenIndent(i) else 0

            texts.append(TextString(i, text,
                cox + marginLeft + (tcfg.indent + extraIndent) * fi.fx, y, fi,
                tcfg.screen.isUnderlined))

            y += fyd
            i += 1

        return (texts, [])
Example #9
0
    def readSpeech(self, sp, line, endLine):
        ls = sp.lines

        # find start of speech
        while (line < endLine) and (ls[line].lt != screenplay.CHARACTER):
            line += 1

        if line >= endLine:
            # no speech found, or CHARACTER was on last line, leaving no
            # space for dialogue.
            return endLine

        # TODO: handle multi-line character names
        s = util.upper(ls[line].text)
        if len(s.strip()) == 0:
            name = "(EMPTY CHARACTER NAME)"
        else:
            name = s

        # skip over character name
        line = sp.getElemLastIndexFromLine(line) + 1

        # dialogue lines
        dlines = 0

        while 1:
            if line > endLine:
                break

            lt = ls[line].lt

            if lt == screenplay.DIALOGUE:
                dlines += 1
            elif lt != screenplay.PAREN:
                break

            line += 1

        if dlines > 0:
            self.chars[name] = self.chars.get(name, 0) + dlines

        return line
Example #10
0
    def readSpeech(self, sp, line, endLine):
        ls = sp.lines

        # find start of speech
        while (line < endLine) and (ls[line].lt != screenplay.CHARACTER):
            line += 1

        if line >= endLine:
            # no speech found, or CHARACTER was on last line, leaving no
            # space for dialogue.
            return endLine

        # TODO: handle multi-line character names
        s = util.upper(ls[line].text)
        if len(s.strip()) == 0:
            name = "(EMPTY CHARACTER NAME)"
        else:
            name = s

        # skip over character name
        line = sp.getElemLastIndexFromLine(line) + 1

        # dialogue lines
        dlines = 0

        while 1:
            if line > endLine:
                break

            lt = ls[line].lt

            if lt == screenplay.DIALOGUE:
                dlines += 1
            elif lt != screenplay.PAREN:
                break

            line += 1

        if dlines > 0:
            self.chars[name] = self.chars.get(name, 0) + dlines

        return line
Example #11
0
    def refresh(self, sceneNames):
        locs = []

        added = {}

        for sceneList in self.locations:
            scenes = []

            for scene in sceneList:
                name = util.upper(scene)

                if (name in sceneNames) and (name not in added):
                    scenes.append(name)
                    added[name] = None

            if scenes:
                scenes.sort()
                locs.append(scenes)

        locs.sort()

        self.locations = locs
Example #12
0
    def refresh(self, sceneNames):
        locs = []

        added = {}

        for sceneList in self.locations:
            scenes = []

            for scene in sceneList:
                name = util.upper(scene)

                if (name in sceneNames) and (name not in added):
                    scenes.append(name)
                    added[name] = None

            if scenes:
                scenes.sort()
                locs.append(scenes)

        locs.sort()

        self.locations = locs
Example #13
0
    def generate(self):
        tf = pml.TextFormatter(self.sp.cfg.paperWidth,
                               self.sp.cfg.paperHeight, 15.0, 12)

        ls = self.sp.lines

        total = len(ls)
        tf.addText("%5d Lines in Screenplay" % total)

        tf.addSpace(2.0)

        for t in config.getTIs():
            cnt = sum([1 for line in ls if line.lt == t.lt])
            tf.addText("        %13s  %4d (%d%%)" % (t.name, cnt,
                                                      util.pct(cnt, total)))

        tf.addSpace(4.0)

        intLines = sum([si.lines for si in self.sr.scenes if
                        util.upper(si.name).startswith("INT.")])
        extLines = sum([si.lines for si in self.sr.scenes if
                        util.upper(si.name).startswith("EXT.")])

        tf.addText("%d%% Interior / %d%% Exterior Scenes" % (
            util.pct(intLines, intLines + extLines),
            util.pct(extLines, intLines + extLines)))

        tf.addSpace(4.0)

        tf.addText("Scene Length in Lines: %d Max / %.2f Avg." % (
            self.sr.longestScene, self.sr.avgScene))

        # lengths of action elements
        actions = []

        # length of current action element
        curLen = 0

        for ln in ls:
            if curLen > 0:
                if ln.lt == screenplay.ACTION:
                    curLen += 1

                    if ln.lb == screenplay.LB_LAST:
                        actions.append(curLen)
                        curLen = 0
                else:
                    actions.append(curLen)
                    curLen = 0
            else:
                if ln.lt == screenplay.ACTION:
                    curLen = 1

        if curLen > 0:
            actions.append(curLen)

        tf.addSpace(4.0)

        # avoid divide-by-zero
        if len(actions) > 0:
            maxA = max(actions)
            avgA = sum(actions) / float(len(actions))
        else:
            maxA = 0
            avgA = 0.0

        tf.addText("Action Length in Lines: %d Max / %.2f Avg." % (
            maxA, avgA))

        tf.addSpace(4.0)

        tf.addText("%d Speaking Characters" % len(self.cr.cinfo))

        return pdf.generate(tf.doc)
Example #14
0
    def OnFind(self, event=None, autoFind=False):
        if not autoFind:
            self.getParams()

        value = misc.fromGUI(self.findEntry.GetValue())
        if not self.matchCase:
            value = util.upper(value)

        if value == "":
            return

        self.searchWidth = len(value)

        if self.dirUp:
            inc = -1
        else:
            inc = 1

        line = self.ctrl.sp.line
        col = self.ctrl.sp.column
        ls = self.ctrl.sp.lines

        if (line == self.searchLine) and (col == self.searchColumn):
            text = ls[line].text

            col += inc
            if col >= len(text):
                line += 1
                col = 0
            elif col < 0:
                line -= 1
                if line >= 0:
                    col = max(len(ls[line].text) - 1, 0)

        fullSearch = False
        if inc > 0:
            if (line == 0) and (col == 0):
                fullSearch = True
        else:
            if (line == (len(ls) - 1)) and (col == (len(ls[line].text))):
                fullSearch = True

        self.searchLine = -1

        while True:
            found = False

            while True:
                if (line >= len(ls)) or (line < 0):
                    break

                if self.typeIncluded(ls[line].lt):
                    text = ls[line].text
                    if not self.matchCase:
                        text = util.upper(text)

                    if inc > 0:
                        res = text.find(value, col)
                    else:
                        res = text.rfind(value, 0, col + 1)

                    if res != -1:
                        if not self.matchWhole or (
                            util.isWordBoundary(text[res - 1: res]) and
                            util.isWordBoundary(text[res + len(value):
                                                     res + len(value) + 1])):

                            found = True

                            break

                line += inc
                if inc > 0:
                    col = 0
                else:
                    if line >= 0:
                        col = max(len(ls[line].text) - 1, 0)

            if found:
                self.searchLine = line
                self.searchColumn = res
                self.ctrl.sp.gotoPos(line, res)
                self.ctrl.sp.setMark(line, res + self.searchWidth - 1)

                if not autoFind:
                    self.ctrl.makeLineVisible(line)
                    self.ctrl.updateScreen()

                break
            else:
                if autoFind:
                    break

                if fullSearch:
                    wx.MessageBox("Nothing was found.",
                                  "No Matches", wx.OK, self)

                    break

                if inc > 0:
                    s1 = "end"
                    s2 = "start"
                    restart = 0
                else:
                    s1 = "start"
                    s2 = "end"
                    restart = len(ls) - 1

                if wx.MessageBox("Search finished at the %s of the screenplay.\n"
                                 "Continue at the %s of the screenplay?"
                                 % (s1, s2), "Continue?",
                                 wx.YES_NO | wx.YES_DEFAULT, self) == wx.YES:
                    line = restart
                    fullSearch = True
                else:
                    break

        if not autoFind:
            self.ctrl.updateScreen()
Example #15
0
    def generate(self):
        tf = pml.TextFormatter(self.sp.cfg.paperWidth, self.sp.cfg.paperHeight,
                               15.0, 12)

        ls = self.sp.lines

        total = len(ls)
        tf.addText("%5d Lines in Screenplay" % total)

        tf.addSpace(2.0)

        for t in config.getTIs():
            cnt = sum([1 for line in ls if line.lt == t.lt])
            tf.addText("        %13s  %4d (%d%%)" %
                       (t.name, cnt, util.pct(cnt, total)))

        tf.addSpace(4.0)

        intLines = sum([
            si.lines for si in self.sr.scenes
            if util.upper(si.name).startswith("INT.")
        ])
        extLines = sum([
            si.lines for si in self.sr.scenes
            if util.upper(si.name).startswith("EXT.")
        ])

        tf.addText("%d%% Interior / %d%% Exterior Scenes" %
                   (util.pct(intLines, intLines + extLines),
                    util.pct(extLines, intLines + extLines)))

        tf.addSpace(4.0)

        tf.addText("Scene Length in Lines: %d Max / %.2f Avg." %
                   (self.sr.longestScene, self.sr.avgScene))

        # lengths of action elements
        actions = []

        # length of current action element
        curLen = 0

        for ln in ls:
            if curLen > 0:
                if ln.lt == screenplay.ACTION:
                    curLen += 1

                    if ln.lb == screenplay.LB_LAST:
                        actions.append(curLen)
                        curLen = 0
                else:
                    actions.append(curLen)
                    curLen = 0
            else:
                if ln.lt == screenplay.ACTION:
                    curLen = 1

        if curLen > 0:
            actions.append(curLen)

        tf.addSpace(4.0)

        # avoid divide-by-zero
        if len(actions) > 0:
            maxA = max(actions)
            avgA = sum(actions) / float(len(actions))
        else:
            maxA = 0
            avgA = 0.0

        tf.addText("Action Length in Lines: %d Max / %.2f Avg." % (maxA, avgA))

        tf.addSpace(4.0)

        tf.addText("%d Speaking Characters" % len(self.cr.cinfo))

        return pdf.generate(tf.doc)
Example #16
0
    def __init__(self, sp):

        self.sp = sp

        ls = sp.lines

        # key = character name, value = CharInfo
        chars = {}

        name = None
        scene = "(NO SCENE NAME)"

        # how many lines processed for current speech
        curSpeechLines = 0

        for i in xrange(len(ls)):
            line = ls[i]

            if (line.lt == screenplay.SCENE) and\
                   (line.lb == screenplay.LB_LAST):
                scene = util.upper(line.text)

            elif (line.lt == screenplay.CHARACTER) and\
                   (line.lb == screenplay.LB_LAST):
                name = util.upper(line.text)
                curSpeechLines = 0

            elif line.lt in (screenplay.DIALOGUE, screenplay.PAREN) and name:
                ci = chars.get(name)
                if not ci:
                    ci = CharInfo(name, sp)
                    chars[name] = ci

                if scene:
                    ci.scenes[scene] = ci.scenes.get(scene, 0) + 1

                if curSpeechLines == 0:
                    ci.speechCnt += 1

                curSpeechLines += 1

                # PAREN lines don't count as spoken words
                if line.lt == screenplay.DIALOGUE:
                    ci.lineCnt += 1

                    words = util.splitToWords(line.text)

                    ci.wordCnt += len(words)
                    ci.wordCharCnt += reduce(lambda x, y: x + len(y), words,
                                             0)

                ci.pages.addPage(sp.line2page(i))

            else:
                name = None
                curSpeechLines = 0

        # list of CharInfo objects
        self.cinfo = []
        for v in chars.values():
            self.cinfo.append(v)

        self.cinfo.sort(cmpLines)

        self.totalSpeechCnt = self.sum("speechCnt")
        self.totalLineCnt = self.sum("lineCnt")
        self.totalWordCnt = self.sum("wordCnt")
        self.totalWordCharCnt = self.sum("wordCharCnt")

        # information types and what to include
        self.INF_BASIC, self.INF_PAGES, self.INF_LOCATIONS = range(3)
        self.inf = []
        for s in ["Basic information", "Page list", "Location list"]:
            self.inf.append(misc.CheckBoxItem(s))
Example #17
0
    def __init__(self, sp, minLines):

        self.sp = sp

        ls = sp.lines

        # PageInfo's for each page, 0-indexed.
        self.pages = []

        for i in xrange(len(sp.pages) - 1):
            self.pages.append(PageInfo())

        # map of CharInfo objects. key = name, value = CharInfo.
        tmpCinfo = {}

        name = "UNKNOWN"

        for i in xrange(len(ls)):
            pgNr = sp.line2page(i) - 1
            pi = self.pages[pgNr]
            line = ls[i]

            pi.addLine(line.lt)

            if (line.lt == screenplay.CHARACTER) and (line.lb == screenplay.LB_LAST):
                name = util.upper(line.text)

            elif line.lt == screenplay.DIALOGUE:
                pi.addLineToSpeaker(name)

                ci = tmpCinfo.get(name)

                if ci:
                    ci.addLine(pgNr)
                else:
                    tmpCinfo[name] = CharInfo(name, pgNr)

            elif line.lt != screenplay.PAREN:
                name = "UNKNOWN"

        # CharInfo's.
        self.cinfo = []
        for v in tmpCinfo.values():
            if v.lineCnt >= minLines:
                self.cinfo.append(v)

        # start Y of page markers
        self.pageY = 20.0

        # where dialogue density bars start and how tall they are
        self.barY = 30.0
        self.barHeight = 15.0

        # chart Y pos
        self.chartY = 50.0

        # how much to leave empty on each side (mm)
        self.margin = 10.0

        # try point sizes 10,9,8,7,6 until all characters fit on the page
        # (if 6 is still too big, too bad)
        size = 10
        while 1:
            # character font size in points
            self.charFs = size

            # how many mm in Y direction for each character
            self.charY = util.getTextHeight(self.charFs)

            # height of chart
            self.chartHeight = len(self.cinfo) * self.charY

            if size <= 6:
                break

            if (self.chartY + self.chartHeight) <= (sp.cfg.paperWidth - self.margin):
                break

            size -= 1

        # calculate maximum length of character name, and start position
        # of chart from that

        maxLen = 0
        for ci in self.cinfo:
            maxLen = max(maxLen, len(ci.name))
        maxLen = max(10, maxLen)

        charX = util.getTextWidth(" ", pml.COURIER, self.charFs)

        # chart X pos
        self.chartX = self.margin + maxLen * charX + 3

        # width of chart
        self.chartWidth = sp.cfg.paperHeight - self.chartX - self.margin

        # page contents bar legends' size and position
        self.legendWidth = 23.0
        self.legendHeight = 23.0
        self.legendX = self.margin + 2.0
        self.legendY = self.barY + self.barHeight - self.legendHeight

        # margin from legend border to first item
        self.legendMargin = 2.0

        # spacing from one legend item to next
        self.legendSpacing = 5.0

        # spacing from one legend item to next
        self.legendSize = 4.0
Example #18
0
    def OnPaint(self, event):
        dc = wx.BufferedPaintDC(self, self.screenBuf)

        size = self.GetClientSize()
        dc.SetBrush(wx.WHITE_BRUSH)
        dc.SetPen(wx.WHITE_PEN)
        dc.DrawRectangle(0, 0, size.width, size.height)

        dc.SetPen(wx.BLACK_PEN)
        dc.SetTextForeground(wx.BLACK)

        for y in range(self.rows + 1):
            util.drawLine(dc, self.offset, self.offset + y * self.cellSize,
                          self.cols * self.cellSize + 1, 0)

        for x in range(self.cols + 1):
            util.drawLine(dc, self.offset + x * self.cellSize, self.offset, 0,
                          self.rows * self.cellSize)

        dc.SetFont(self.normalFont)

        for y in range(self.rows):
            for x in range(self.cols):
                i = y * self.cols + x
                if i < len(self.chars):
                    util.drawText(
                        dc, self.chars[i], x * self.cellSize + self.offset +
                        self.cellSize // 2 + 1, y * self.cellSize +
                        self.offset + self.cellSize // 2 + 1,
                        util.ALIGN_CENTER, util.VALIGN_CENTER)

        y = self.offset + self.rows * self.cellSize
        pad = 5

        if self.selected:
            code = ord(self.selected)

            self.drawCharBox(dc, "Selected", self.selected, self.offset,
                             y + pad, 75)

            c = util.upper(self.selected)
            if c == self.selected:
                c = util.lower(self.selected)
                if c == self.selected:
                    c = None

            if c:
                self.drawCharBox(dc, "Opposite Case", c, self.offset + 150,
                                 y + pad, 110)

            dc.SetFont(self.smallFont)
            dc.DrawText("Character Code: %d" % code, 360, y + pad)

            if code == 32:
                dc.DrawText("Normal Space", 360, y + pad + 30)
            elif code == 160:
                dc.DrawText("Non-breaking Space", 360, y + pad + 30)

        else:
            dc.SetFont(self.smallFont)
            dc.DrawText("Select a character", self.offset, y + pad)
Example #19
0
    def __init__(self, sp, minLines):

        self.sp = sp

        ls = sp.lines

        # PageInfo's for each page, 0-indexed.
        self.pages = []

        for i in xrange(len(sp.pages) - 1):
            self.pages.append(PageInfo())

        # map of CharInfo objects. key = name, value = CharInfo.
        tmpCinfo = {}

        name = "UNKNOWN"

        for i in xrange(len(ls)):
            pgNr = sp.line2page(i) - 1
            pi = self.pages[pgNr]
            line = ls[i]

            pi.addLine(line.lt)

            if (line.lt == screenplay.CHARACTER) and\
                   (line.lb == screenplay.LB_LAST):
                name = util.upper(line.text)

            elif line.lt == screenplay.DIALOGUE:
                pi.addLineToSpeaker(name)

                ci = tmpCinfo.get(name)

                if ci:
                    ci.addLine(pgNr)
                else:
                    tmpCinfo[name] = CharInfo(name, pgNr)

            elif line.lt != screenplay.PAREN:
                name = "UNKNOWN"

        # CharInfo's.
        self.cinfo = []
        for v in tmpCinfo.values():
            if v.lineCnt >= minLines:
                self.cinfo.append(v)

        # start Y of page markers
        self.pageY = 20.0

        # where dialogue density bars start and how tall they are
        self.barY = 30.0
        self.barHeight = 15.0

        # chart Y pos
        self.chartY = 50.0

        # how much to leave empty on each side (mm)
        self.margin = 10.0

        # try point sizes 10,9,8,7,6 until all characters fit on the page
        # (if 6 is still too big, too bad)
        size = 10
        while 1:
            # character font size in points
            self.charFs = size

            # how many mm in Y direction for each character
            self.charY = util.getTextHeight(self.charFs)

            # height of chart
            self.chartHeight = len(self.cinfo) * self.charY

            if size <= 6:
                break

            if (self.chartY + self.chartHeight) <= \
                   (sp.cfg.paperWidth - self.margin):
                break

            size -= 1

        # calculate maximum length of character name, and start position
        # of chart from that

        maxLen = 0
        for ci in self.cinfo:
            maxLen = max(maxLen, len(ci.name))
        maxLen = max(10, maxLen)

        charX = util.getTextWidth(" ", pml.COURIER, self.charFs)

        # chart X pos
        self.chartX = self.margin + maxLen * charX + 3

        # width of chart
        self.chartWidth = sp.cfg.paperHeight - self.chartX - self.margin

        # page contents bar legends' size and position
        self.legendWidth = 23.0
        self.legendHeight = 23.0
        self.legendX = self.margin + 2.0
        self.legendY = self.barY + self.barHeight - self.legendHeight

        # margin from legend border to first item
        self.legendMargin = 2.0

        # spacing from one legend item to next
        self.legendSpacing = 5.0

        # spacing from one legend item to next
        self.legendSize = 4.0
Example #20
0
    def OnFind(self, event=None, autoFind=False):
        if not autoFind:
            self.getParams()

        value = misc.fromGUI(self.findEntry.GetValue())
        if not self.matchCase:
            value = util.upper(value)

        if value == "":
            return

        self.searchWidth = len(value)

        if self.dirUp:
            inc = -1
        else:
            inc = 1

        line = self.ctrl.sp.line
        col = self.ctrl.sp.column
        ls = self.ctrl.sp.lines

        if (line == self.searchLine) and (col == self.searchColumn):
            text = ls[line].text

            col += inc
            if col >= len(text):
                line += 1
                col = 0
            elif col < 0:
                line -= 1
                if line >= 0:
                    col = max(len(ls[line].text) - 1, 0)

        fullSearch = False
        if inc > 0:
            if (line == 0) and (col == 0):
                fullSearch = True
        else:
            if (line == (len(ls) - 1)) and (col == (len(ls[line].text))):
                fullSearch = True

        self.searchLine = -1

        while True:
            found = False

            while True:
                if (line >= len(ls)) or (line < 0):
                    break

                if self.typeIncluded(ls[line].lt):
                    text = ls[line].text
                    if not self.matchCase:
                        text = util.upper(text)

                    if inc > 0:
                        res = text.find(value, col)
                    else:
                        res = text.rfind(value, 0, col + 1)

                    if res != -1:
                        if not self.matchWhole or (util.isWordBoundary(
                                text[res - 1:res]) and util.isWordBoundary(
                                    text[res + len(value):res + len(value) +
                                         1])):

                            found = True

                            break

                line += inc
                if inc > 0:
                    col = 0
                else:
                    if line >= 0:
                        col = max(len(ls[line].text) - 1, 0)

            if found:
                self.searchLine = line
                self.searchColumn = res
                self.ctrl.sp.gotoPos(line, res)
                self.ctrl.sp.setMark(line, res + self.searchWidth - 1)

                if not autoFind:
                    self.ctrl.makeLineVisible(line)
                    self.ctrl.updateScreen()

                break
            else:
                if autoFind:
                    break

                if fullSearch:
                    wx.MessageBox("Search finished without results.",
                                  "No matches", wx.OK, self)

                    break

                if inc > 0:
                    s1 = "end"
                    s2 = "start"
                    restart = 0
                else:
                    s1 = "start"
                    s2 = "end"
                    restart = len(ls) - 1

                if wx.MessageBox(
                        "Search finished at the %s of the script. Do\n"
                        "you want to continue at the %s of the script?" %
                    (s1, s2), "Continue?", wx.YES_NO | wx.YES_DEFAULT,
                        self) == wx.YES:
                    line = restart
                    fullSearch = True
                else:
                    break

        if not autoFind:
            self.ctrl.updateScreen()
Example #21
0
    def __init__(self, sp):

        self.sp = sp

        ls = sp.lines

        # key = character name, value = CharInfo
        chars = {}

        name = None
        scene = "(NO SCENE NAME)"

        # how many lines processed for current speech
        curSpeechLines = 0

        for i in xrange(len(ls)):
            line = ls[i]

            if (line.lt == screenplay.SCENE) and\
                   (line.lb == screenplay.LB_LAST):
                scene = util.upper(line.text)

            elif (line.lt == screenplay.CHARACTER) and\
                   (line.lb == screenplay.LB_LAST):
                name = util.upper(line.text)
                curSpeechLines = 0

            elif line.lt in (screenplay.DIALOGUE, screenplay.PAREN) and name:
                ci = chars.get(name)
                if not ci:
                    ci = CharInfo(name, sp)
                    chars[name] = ci

                if scene:
                    ci.scenes[scene] = ci.scenes.get(scene, 0) + 1

                if curSpeechLines == 0:
                    ci.speechCnt += 1

                curSpeechLines += 1

                # PAREN lines don't count as spoken words
                if line.lt == screenplay.DIALOGUE:
                    ci.lineCnt += 1

                    words = util.splitToWords(line.text)

                    ci.wordCnt += len(words)
                    ci.wordCharCnt += reduce(lambda x, y: x + len(y), words, 0)

                ci.pages.addPage(sp.line2page(i))

            else:
                name = None
                curSpeechLines = 0

        # list of CharInfo objects
        self.cinfo = []
        for v in chars.values():
            self.cinfo.append(v)

        self.cinfo.sort(cmpLines)

        self.totalSpeechCnt = self.sum("speechCnt")
        self.totalLineCnt = self.sum("lineCnt")
        self.totalWordCnt = self.sum("wordCnt")
        self.totalWordCharCnt = self.sum("wordCharCnt")

        # information types and what to include
        self.INF_BASIC, self.INF_PAGES, self.INF_LOCATIONS = range(3)
        self.inf = []
        for s in ["Basic information", "Page list", "Location list"]:
            self.inf.append(misc.CheckBoxItem(s))
Example #22
0
    def getNavigatorItems(self, sp):
        ls = sp.lines
        navList = []
        curLine = ""
        line_no = 0

        # keep track of scene number and length
        scene_no = 1
        scene_line_nos = []
        scene_indexes = []

        #tracks the first line multiple line elements
        firstline = -1
        lineCount = len(ls)
        line_no = 0

        # start from the first scene.
        while line_no < lineCount and (ls[line_no].lt not in (SCENE, ACTBREAK)):
            line_no += 1

        while line_no < lineCount:
            line = ls[line_no]
            if not(line.lt in (NOTE, ACTION, SCENE, ACTBREAK, TRANSITION)):
                line_no += 1
                continue

            lineText = line.text
            if sp.cfg.getType(line.lt).export.isCaps:
                    lineText = util.upper(lineText)
            curLine += lineText

            lnIncremented = False

            if line.lb == LB_LAST:
                if line.lt == SCENE:
                    # Create a new item for scenes.
                    navList.append(NavigatorItem(line_no, curLine,
                                        scene_no))
                    scene_no += 1
                    scene_line_nos.append(line_no)
                    scene_indexes.append(len(navList) - 1)

                elif line.lt == ACTBREAK:
                    navList.append(NavigatorItem(line_no, curLine))
                    scene_line_nos.append(line_no)
                    scene_indexes.append(len(navList) - 1)

                elif line.lt == TRANSITION:
                    navList[-1].setTransition(curLine)

                else:
                    # NOTE or ACTION
                    # handle first line in multiline elements.
                    # if note immediately after scene, add it to that.
                    if firstline == -1:
                        ni_line = line_no
                    else:
                        ni_line = firstline

                    # Note/action after scene line.
                    if len(navList) > 0 and navList[-1].lineNo == ni_line - 1 and navList[-1].sceneText:
                        if line.lt == NOTE:
                            navList[-1].setBlurb(curLine)
                            navList[-1].annotated = True
                        else:
                            # ACTION
                            navList[-1].setBlurb(curLine)

                    # Note elsewhere
                    elif line.lt == NOTE:
                        navList[-1].appendNote(curLine, ni_line)

                        # Skip ahead to next line we care about
                        line_no += 1
                        while line_no < lineCount and not ls[line_no].lt in (
                            SCENE, ACTBREAK, NOTE, TRANSITION):
                                line_no += 1
                        lnIncremented = True

                if not lnIncremented:
                    line_no += 1
                firstline = -1
                curLine = ""

            elif line.lb == LB_SPACE:
                if firstline == -1:
                    firstline = line_no
                curLine += " "
                line_no += 1

            elif line.lb == LB_FORCED:
                if firstline == -1:
                    firstline = line_no
                curLine += " "
                line_no += 1

        # update length of scenes.
        #  add final line number for last scene length.
        #  -1 so you don't count the scene line itself.
        scene_line_nos.append(line_no)

        for i  in xrange(len(scene_indexes)):
            navList[scene_indexes[i]].sceneLen = \
                scene_line_nos[i + 1] - scene_line_nos[i] - 1
            # refresh internal sublines data
            navList[scene_indexes[i]].genLines()

        return navList