예제 #1
0
    def saveConfig(self):
        """Save the current preferences to file.
        """
        logger.debug("Saving config file")
        if self.confPath is None:
            return False

        cnfParse = configparser.ConfigParser()

        # Set options

        ## Main
        cnfSec = "Main"
        cnfParse.add_section(cnfSec)
        cnfParse.set(cnfSec, "timestamp", formatTimeStamp(time()))
        cnfParse.set(cnfSec, "theme", str(self.guiTheme))
        cnfParse.set(cnfSec, "syntax", str(self.guiSyntax))
        cnfParse.set(cnfSec, "icons", str(self.guiIcons))
        cnfParse.set(cnfSec, "guidark", str(self.guiDark))
        cnfParse.set(cnfSec, "guifont", str(self.guiFont))
        cnfParse.set(cnfSec, "guifontsize", str(self.guiFontSize))
        cnfParse.set(cnfSec, "lastnotes", str(self.lastNotes))
        cnfParse.set(cnfSec, "guilang", str(self.guiLang))

        ## Sizes
        cnfSec = "Sizes"
        cnfParse.add_section(cnfSec)
        cnfParse.set(cnfSec, "geometry", self._packList(self.winGeometry))
        cnfParse.set(cnfSec, "preferences", self._packList(self.prefGeometry))
        cnfParse.set(cnfSec, "treecols", self._packList(self.treeColWidth))
        cnfParse.set(cnfSec, "novelcols", self._packList(self.novelColWidth))
        cnfParse.set(cnfSec, "projcols", self._packList(self.projColWidth))
        cnfParse.set(cnfSec, "mainpane", self._packList(self.mainPanePos))
        cnfParse.set(cnfSec, "docpane", self._packList(self.docPanePos))
        cnfParse.set(cnfSec, "viewpane", self._packList(self.viewPanePos))
        cnfParse.set(cnfSec, "outlinepane", self._packList(self.outlnPanePos))
        cnfParse.set(cnfSec, "fullscreen", str(self.isFullScreen))
        cnfParse.set(cnfSec, "hidevscroll", str(self.hideVScroll))
        cnfParse.set(cnfSec, "hidehscroll", str(self.hideHScroll))

        ## Project
        cnfSec = "Project"
        cnfParse.add_section(cnfSec)
        cnfParse.set(cnfSec, "autosaveproject", str(self.autoSaveProj))
        cnfParse.set(cnfSec, "autosavedoc", str(self.autoSaveDoc))

        ## Editor
        cnfSec = "Editor"
        cnfParse.add_section(cnfSec)
        cnfParse.set(cnfSec, "textfont", str(self.textFont))
        cnfParse.set(cnfSec, "textsize", str(self.textSize))
        cnfParse.set(cnfSec, "fixedwidth", str(self.textFixedW))
        cnfParse.set(cnfSec, "width", str(self.textWidth))
        cnfParse.set(cnfSec, "margin", str(self.textMargin))
        cnfParse.set(cnfSec, "tabwidth", str(self.tabWidth))
        cnfParse.set(cnfSec, "focuswidth", str(self.focusWidth))
        cnfParse.set(cnfSec, "hidefocusfooter", str(self.hideFocusFooter))
        cnfParse.set(cnfSec, "justify", str(self.doJustify))
        cnfParse.set(cnfSec, "autoselect", str(self.autoSelect))
        cnfParse.set(cnfSec, "autoreplace", str(self.doReplace))
        cnfParse.set(cnfSec, "repsquotes", str(self.doReplaceSQuote))
        cnfParse.set(cnfSec, "repdquotes", str(self.doReplaceDQuote))
        cnfParse.set(cnfSec, "repdash", str(self.doReplaceDash))
        cnfParse.set(cnfSec, "repdots", str(self.doReplaceDots))
        cnfParse.set(cnfSec, "scrollpastend", str(self.scrollPastEnd))
        cnfParse.set(cnfSec, "autoscroll", str(self.autoScroll))
        cnfParse.set(cnfSec, "autoscrollpos", str(self.autoScrollPos))
        cnfParse.set(cnfSec, "fmtsinglequote",
                     self._packList(self.fmtSingleQuotes))
        cnfParse.set(cnfSec, "fmtdoublequote",
                     self._packList(self.fmtDoubleQuotes))
        cnfParse.set(cnfSec, "fmtpadbefore", str(self.fmtPadBefore))
        cnfParse.set(cnfSec, "fmtpadafter", str(self.fmtPadAfter))
        cnfParse.set(cnfSec, "fmtpadthin", str(self.fmtPadThin))
        cnfParse.set(cnfSec, "spelltool", str(self.spellTool))
        cnfParse.set(cnfSec, "spellcheck", str(self.spellLanguage))
        cnfParse.set(cnfSec, "showtabsnspaces", str(self.showTabsNSpaces))
        cnfParse.set(cnfSec, "showlineendings", str(self.showLineEndings))
        cnfParse.set(cnfSec, "bigdoclimit", str(self.bigDocLimit))
        cnfParse.set(cnfSec, "showfullpath", str(self.showFullPath))
        cnfParse.set(cnfSec, "highlightquotes", str(self.highlightQuotes))
        cnfParse.set(cnfSec, "allowopensquote", str(self.allowOpenSQuote))
        cnfParse.set(cnfSec, "allowopendquote", str(self.allowOpenDQuote))
        cnfParse.set(cnfSec, "highlightemph", str(self.highlightEmph))
        cnfParse.set(cnfSec, "stopwhenidle", str(self.stopWhenIdle))
        cnfParse.set(cnfSec, "useridletime", str(self.userIdleTime))

        ## Backup
        cnfSec = "Backup"
        cnfParse.add_section(cnfSec)
        cnfParse.set(cnfSec, "backuppath", str(self.backupPath))
        cnfParse.set(cnfSec, "backuponclose", str(self.backupOnClose))
        cnfParse.set(cnfSec, "askbeforebackup", str(self.askBeforeBackup))

        ## State
        cnfSec = "State"
        cnfParse.add_section(cnfSec)
        cnfParse.set(cnfSec, "showrefpanel", str(self.showRefPanel))
        cnfParse.set(cnfSec, "viewcomments", str(self.viewComments))
        cnfParse.set(cnfSec, "viewsynopsis", str(self.viewSynopsis))
        cnfParse.set(cnfSec, "searchcase", str(self.searchCase))
        cnfParse.set(cnfSec, "searchword", str(self.searchWord))
        cnfParse.set(cnfSec, "searchregex", str(self.searchRegEx))
        cnfParse.set(cnfSec, "searchloop", str(self.searchLoop))
        cnfParse.set(cnfSec, "searchnextfile", str(self.searchNextFile))
        cnfParse.set(cnfSec, "searchmatchcap", str(self.searchMatchCap))

        ## Path
        cnfSec = "Path"
        cnfParse.add_section(cnfSec)
        cnfParse.set(cnfSec, "lastpath", str(self.lastPath))

        # Write config file
        cnfPath = os.path.join(self.confPath, self.confFile)
        try:
            with open(cnfPath, mode="w", encoding="utf8") as outFile:
                cnfParse.write(outFile)
            self.confChanged = False
        except Exception as e:
            logger.error("Could not save config file")
            logException()
            self.hasError = True
            self.errData.append("Could not save config file")
            self.errData.append(str(e))
            return False

        return True
예제 #2
0
def testFormatTimeStamp():
    tTime = time.mktime(time.gmtime(0))
    assert formatTimeStamp(tTime, False) == "1970-01-01 00:00:00"
    assert formatTimeStamp(tTime, True) == "1970-01-01 00.00.00"
예제 #3
0
def testCoreProject_Methods(monkeypatch, nwMinimal, dummyGUI, tmpDir):
    """Test other project class methods and functions.
    """
    theProject = NWProject(dummyGUI)
    theProject.projTree.setSeed(42)
    assert theProject.openProject(nwMinimal)
    assert theProject.projPath == nwMinimal

    # Setting project path
    assert theProject.setProjectPath(None)
    assert theProject.projPath is None
    assert theProject.setProjectPath("")
    assert theProject.projPath is None
    assert theProject.setProjectPath("~")
    assert theProject.projPath == os.path.expanduser("~")

    # Create a new folder and populate it
    projPath = os.path.join(nwMinimal, "dummy1")
    assert theProject.setProjectPath(projPath, newProject=True)

    # Make os.mkdir fail
    monkeypatch.setattr("os.mkdir", causeOSError)
    projPath = os.path.join(nwMinimal, "dummy2")
    assert not theProject.setProjectPath(projPath, newProject=True)

    # Set back
    assert theProject.setProjectPath(nwMinimal)

    # Project Name
    assert theProject.setProjectName("  A Name ")
    assert theProject.projName == "A Name"

    # Project Title
    assert theProject.setBookTitle("  A Title ")
    assert theProject.bookTitle == "A Title"

    # Project Authors
    # Check that the list is cleaned up and that it can be extracted as
    # a properly formatted string, depending on number of names
    assert not theProject.setBookAuthors([])
    assert theProject.setBookAuthors(" Jane Doe \n John Doh \n ")
    assert theProject.bookAuthors == ["Jane Doe", "John Doh"]

    assert theProject.setBookAuthors("")
    assert theProject.getAuthors() == ""

    assert theProject.setBookAuthors("Jane Doe")
    assert theProject.getAuthors() == "Jane Doe"

    assert theProject.setBookAuthors("Jane Doe\nJohn Doh")
    assert theProject.getAuthors() == "Jane Doe and John Doh"

    assert theProject.setBookAuthors("Jane Doe\nJohn Doh\nBod Owens")
    assert theProject.getAuthors() == "Jane Doe, John Doh and Bod Owens"

    # Edit Time
    theProject.editTime = 1234
    theProject.projOpened = 1600000000
    monkeypatch.setattr("nw.core.project.time", lambda: 1600005600)
    assert theProject.getCurrentEditTime() == 6834
    monkeypatch.undo()

    # Trash folder
    # Should create on first call, and just returned on later calls
    assert theProject.projTree["73475cb40a568"] is None
    assert theProject.trashFolder() == "73475cb40a568"
    assert theProject.trashFolder() == "73475cb40a568"

    # Project backup
    assert theProject.doBackup is True
    assert theProject.setProjBackup(False)
    assert theProject.doBackup is False

    assert not theProject.setProjBackup(True)
    theProject.mainConf.backupPath = tmpDir
    assert theProject.setProjBackup(True)

    assert theProject.setProjectName("")
    assert not theProject.setProjBackup(True)
    assert theProject.setProjectName("A Name")
    assert theProject.setProjBackup(True)

    # Spell check
    theProject.projChanged = False
    assert theProject.setSpellCheck(True)
    assert not theProject.setSpellCheck(False)
    assert theProject.projChanged

    # Spell language
    theProject.projChanged = False
    assert theProject.setSpellLang(None)
    assert theProject.projLang is None
    assert theProject.setSpellLang("None")
    assert theProject.projLang is None
    assert theProject.setSpellLang("en_GB")
    assert theProject.projLang == "en_GB"
    assert theProject.projChanged

    # Automatic outline update
    theProject.projChanged = False
    assert theProject.setAutoOutline(True)
    assert not theProject.setAutoOutline(False)
    assert theProject.projChanged

    # Last edited
    theProject.projChanged = False
    assert theProject.setLastEdited("0123456789abc")
    assert theProject.lastEdited == "0123456789abc"
    assert theProject.projChanged

    # Last viewed
    theProject.projChanged = False
    assert theProject.setLastViewed("0123456789abc")
    assert theProject.lastViewed == "0123456789abc"
    assert theProject.projChanged

    # Autoreplace
    theProject.projChanged = False
    assert theProject.setAutoReplace({"A": "B", "C": "D"})
    assert theProject.autoReplace == {"A": "B", "C": "D"}
    assert theProject.projChanged

    # Change project tree order
    oldOrder = [
        "a508bb932959c",
        "a35baf2e93843",
        "a6d311a93600a",
        "f5ab3e30151e1",
        "8c659a11cd429",
        "7695ce551d265",
        "afb3043c7b2b3",
        "9d5247ab588e0",
        "73475cb40a568",
    ]
    newOrder = [
        "f5ab3e30151e1",
        "8c659a11cd429",
        "7695ce551d265",
        "a508bb932959c",
        "a35baf2e93843",
        "a6d311a93600a",
        "afb3043c7b2b3",
        "9d5247ab588e0",
    ]
    assert theProject.projTree.handles() == oldOrder
    assert theProject.setTreeOrder(newOrder)
    assert theProject.projTree.handles() == newOrder
    assert theProject.setTreeOrder(oldOrder)
    assert theProject.projTree.handles() == oldOrder

    # Change status
    theProject.projTree["a35baf2e93843"].setStatus("Finished")
    theProject.projTree["a6d311a93600a"].setStatus("Draft")
    theProject.projTree["f5ab3e30151e1"].setStatus("Note")
    theProject.projTree["8c659a11cd429"].setStatus("Finished")
    newList = [
        ("New", 1, 1, 1, "New"),
        ("Draft", 2, 2, 2, "Note"),  # These are swapped
        ("Note", 3, 3, 3, "Draft"),  # These are swapped
        ("Edited", 4, 4, 4, "Finished"),  # Renamed
        ("Finished", 5, 5, 5, None),  # New, with reused name
    ]
    assert theProject.setStatusColours(newList)
    assert theProject.statusItems._theLabels == [
        "New", "Draft", "Note", "Edited", "Finished"
    ]
    assert theProject.statusItems._theColours == [(1, 1, 1), (2, 2, 2),
                                                  (3, 3, 3), (4, 4, 4),
                                                  (5, 5, 5)]
    assert theProject.projTree[
        "a35baf2e93843"].itemStatus == "Edited"  # Renamed
    assert theProject.projTree["a6d311a93600a"].itemStatus == "Note"  # Swapped
    assert theProject.projTree["f5ab3e30151e1"].itemStatus == "Draft"  # Swapped
    assert theProject.projTree[
        "8c659a11cd429"].itemStatus == "Edited"  # Renamed

    # Change importance
    fHandle = theProject.newFile("Jane Doe", nwItemClass.CHARACTER,
                                 "afb3043c7b2b3")
    theProject.projTree[fHandle].setStatus("Main")
    newList = [
        ("New", 1, 1, 1, "New"),
        ("Minor", 2, 2, 2, "Minor"),
        ("Major", 3, 3, 3, "Major"),
        ("Min", 4, 4, 4, "Main"),
        ("Max", 5, 5, 5, None),
    ]
    assert theProject.setImportColours(newList)
    assert theProject.importItems._theLabels == [
        "New", "Minor", "Major", "Min", "Max"
    ]
    assert theProject.importItems._theColours == [(1, 1, 1), (2, 2, 2),
                                                  (3, 3, 3), (4, 4, 4),
                                                  (5, 5, 5)]
    assert theProject.projTree[fHandle].itemStatus == "Min"

    # Check status counts
    assert theProject.statusItems._theCounts == [0, 0, 0, 0, 0]
    assert theProject.importItems._theCounts == [0, 0, 0, 0, 0]
    theProject.countStatus()
    assert theProject.statusItems._theCounts == [1, 1, 1, 2, 0]
    assert theProject.importItems._theCounts == [3, 0, 0, 1, 0]

    # Check word counts
    theProject.currWCount = 200
    theProject.lastWCount = 100
    assert theProject.getSessionWordCount() == 100

    # Session stats
    monkeypatch.setattr("os.path.isdir", lambda *args, **kwargs: False)
    assert not theProject._appendSessionStats()
    monkeypatch.undo()

    # Block open
    monkeypatch.setattr("builtins.open", causeOSError)
    assert not theProject._appendSessionStats()
    monkeypatch.undo()

    # Write entry
    assert theProject.projMeta == os.path.join(nwMinimal, "meta")
    statsFile = os.path.join(theProject.projMeta, nwFiles.SESS_STATS)

    theProject.projOpened = 1600002000
    theProject.novelWCount = 200
    theProject.notesWCount = 100

    monkeypatch.setattr("nw.core.project.time", lambda: 1600005600)
    assert theProject._appendSessionStats()
    monkeypatch.undo()

    assert readFile(statsFile) == (
        "# Offset 100\n"
        "# Start Time         End Time                Novel     Notes\n"
        "%s  %s       200       100\n") % (formatTimeStamp(1600002000),
                                           formatTimeStamp(1600005600))

    # Pack XML Value
    xElem = etree.Element("element")
    theProject._packProjectValue(xElem, "A", "B", allowNone=False)
    assert etree.tostring(xElem, pretty_print=False,
                          encoding="utf-8") == (b"<element><A>B</A></element>")

    xElem = etree.Element("element")
    theProject._packProjectValue(xElem, "A", "", allowNone=False)
    assert etree.tostring(xElem, pretty_print=False,
                          encoding="utf-8") == (b"<element/>")

    # Pack XML Key/Value
    xElem = etree.Element("element")
    theProject._packProjectKeyValue(xElem, "item", {"A": "B", "C": "D"})
    assert etree.tostring(xElem, pretty_print=False,
                          encoding="utf-8") == (b"<element>"
                                                b"<item>"
                                                b"<entry key=\"A\">B</entry>"
                                                b"<entry key=\"C\">D</entry>"
                                                b"</item>"
                                                b"</element>")
예제 #4
0
def testBaseCommon_FormatTimeStamp():
    """Test the formatTimeStamp function.
    """
    tTime = time.mktime(time.gmtime(0))
    assert formatTimeStamp(tTime, False) == "1970-01-01 00:00:00"
    assert formatTimeStamp(tTime, True) == "1970-01-01 00.00.00"