commit/placeMarkers: 4 new changesets

  • From: commits-noreply@xxxxxxxxxxxxx
  • To: commits+int+220+6085746285340533186@xxxxxxxxxxxxxxxxxxxxx, nvda-addons-commits@xxxxxxxxxxxxx
  • Date: Sun, 24 Nov 2019 11:21:53 +0000 (UTC)

4 new commits in placeMarkers:

https://bitbucket.org/nvdaaddonteam/placemarkers/commits/388e46f1f97b/
Changeset:   388e46f1f97b
Branch:      None
User:        norrumar
Date:        2019-11-24 02:29:15+00:00
Summary:     2019.3 (#19)

* Updates

* Update sconstruct

* Update buildVars

* Ready for NVDA 2019.3 (for now)

* Update readme

* Update readme

* Cosmetics: try to follow NVDA's code style

* Update sconstruct

Affected #:  11 files

diff --git a/addon/globalPlugins/placeMarkers/__init__.py 
b/addon/globalPlugins/placeMarkers/__init__.py
index e0df89b..59824fb 100644
--- a/addon/globalPlugins/placeMarkers/__init__.py
+++ b/addon/globalPlugins/placeMarkers/__init__.py
@@ -4,11 +4,7 @@
 # Released under GPL 2
 # Converted to Python 3 by Joseph Lee in 2017
 
-try:
-       import cPickle as pickle
-except ImportError:
-       import pickle
-import codecs
+import pickle
 import re
 import os
 import shutil
@@ -38,10 +34,11 @@ from .skipTranslation import translate
 addonHandler.initTranslation()
 
 ### Constants
-PLACE_MARKERS_PATH = os.path.join(os.path.dirname(__file__), 
"savedPlaceMarkers").decode("mbcs")
+CONFIG_PATH = globalVars.appArgs.configPath
+PLACE_MARKERS_PATH = os.path.join(CONFIG_PATH, "addons", "placeMarkers", 
"globalPlugins", "placeMarkers", "savedPlaceMarkers")
 SEARCH_FOLDER = os.path.join(PLACE_MARKERS_PATH, "search")
 BOOKMARKS_FOLDER = os.path.join(PLACE_MARKERS_PATH, "bookmarks")
-CONFIG_PATH = globalVars.appArgs.configPath
+
 ADDON_SUMMARY = addonHandler.getCodeAddon().manifest["summary"]
 
 ### Globals
@@ -87,12 +84,14 @@ def doFindText(text, reverse=False, caseSensitive=False):
                try:
                        res=info.find(text,reverse=reverse, 
caseSensitive=caseSensitive)
                except WindowsError:
-                       wx.CallAfter(gui.messageBox,
+                       wx.CallAfter(
+                               gui.messageBox,
                                # Message translated in NVDA core.
                                translate('text "%s" not found') % text,
                                # Message translated in NVDA core.
                                translate("Find Error"),
-                               wx.OK|wx.ICON_ERROR)
+                               wx.OK|wx.ICON_ERROR
+                       )
                except:
                        if api.copyToClip(text):
                                # Translators: message presented when a string 
of text has been copied to the clipboard.
@@ -107,12 +106,14 @@ def doFindText(text, reverse=False, caseSensitive=False):
                        info.move(textInfos.UNIT_LINE,1,endPoint="end")
                        
speech.speakTextInfo(info,reason=controlTypes.REASON_CARET)
                else:
-                       wx.CallAfter(gui.messageBox,
+                       wx.CallAfter(
+                               gui.messageBox,
                                # Message translated in NVDA core.
                                translate('text "%s" not found') % text,
                                # Message translated in NVDA core.
                                translate("Find Error"),
-                               wx.OK|wx.ICON_ERROR)
+                               wx.OK|wx.ICON_ERROR
+                       )
 
 def doFindTextUp(text, caseSensitive=False):
        doFindText(text, reverse=True, caseSensitive=caseSensitive)
@@ -131,12 +132,8 @@ def moveToBookmark(position):
                speech.speakTextInfo(info,reason=controlTypes.REASON_CARET)
 
 def standardFileName(fileName):
-       fileName.encode("mbcs")
        notAllowed = re.compile("\?|:|\*|\t|<|>|\"|\/|\\||") # Invalid 
characters
-       try:
-               allowed = re.sub(notAllowed, "", unicode(fileName))
-       except NameError:
-               allowed = re.sub(notAllowed, "", str(fileName))
+       allowed = re.sub(notAllowed, "", fileName)
        return allowed
 
 def getFile(folder, ext=""):
@@ -170,7 +167,7 @@ def getFileSearch():
 def getSavedTexts():
        searchFile = getFileSearch()
        try:
-               with codecs.open(searchFile, "r", "utf-8") as f:
+               with open(searchFile, "r", encoding="utf-8") as f:
                        savedStrings = f.read().split("\n")
        except:
                savedStrings = []
@@ -191,7 +188,8 @@ def getFileTempBookmark():
 def getSavedBookmarks():
        fileName = getFileBookmarks()
        try:
-               savedBookmarks = pickle.load(file(fileName, "r"))
+               with open(fileName, "rb") as f:
+                       savedBookmarks = pickle.load(f)
                if isinstance(savedBookmarks, list):
                        bookmarksDic = {}
                        for bookmark in savedBookmarks:
@@ -296,7 +294,7 @@ class SpecificSearchDialog(wx.Dialog):
                                os.remove(self.searchFile)
                                return
                        try:
-                               with codecs.open(self.searchFile, "w", "utf-8") 
as f:
+                               with open(self.searchFile, "w", 
encoding="utf-8") as f:
                                        f.write("\n".join(savedStrings))
                        except Exception as e:
                                log.debugWarning("Error saving strings of text 
for specific search", exc_info=True)
@@ -312,32 +310,40 @@ def doCopy(copyDirectory):
                        #if it exists, only placeMarkersBackup folder will be 
removed, which is the base name of copyDirectory path
                        shutil.rmtree(copyDirectory, ignore_errors=True)
                shutil.copytree(PLACE_MARKERS_PATH, copyDirectory)
-               core.callLater(100, ui.message,
+               core.callLater(
+                       100, ui.message,
                        # Translators: Message presented when place markers 
have been copied.
-                       _("Place markers copied"))
+                       _("Place markers copied")
+               )
        except Exception as e:
-               wx.CallAfter(gui.messageBox,
+               wx.CallAfter(
+                       gui.messageBox,
                        # Translators: label of error dialog shown when cannot 
copy placeMarkers folder.
                        _("Folder not copied"),
                        # Translators: title of error dialog shown when cannot 
copy placeMarkers folder.
                        _("Copy Error"),
-                       wx.OK|wx.ICON_ERROR)
+                       wx.OK|wx.ICON_ERROR
+               )
                raise e
 
 def doRestore(restoreDirectory):
        try:
                shutil.rmtree(PLACE_MARKERS_PATH, ignore_errors=True)
                shutil.copytree(restoreDirectory, PLACE_MARKERS_PATH)
-               core.callLater(100, ui.message,
+               core.callLater(
+                       100, ui.message,
                        # Translators: Message presented when place markers 
have been restored.
-                       _("Place markers restored"))
+                       _("Place markers restored")
+               )
        except Exception as e:
-               wx.CallAfter(gui.messageBox,
+               wx.CallAfter(
+                       gui.messageBox,
                        # Translators: label of error dialog shown when cannot 
copy placeMarkers folder.
                        _("Folder not copied"),
                        # Translators: title of error dialog shown when cannot 
copy placeMarkers folder.
                        _("Copy Error"),
-                       wx.OK|wx.ICON_ERROR)
+                       wx.OK|wx.ICON_ERROR
+               )
                raise e
 
 class NotesDialog(wx.Dialog):
@@ -351,8 +357,7 @@ class NotesDialog(wx.Dialog):
                # Translators: The label of a list box in the Notes dialog.
                notesLabel = _("&Bookmarks")
                self.bookmarks = getSavedBookmarks()
-               positions = list(self.bookmarks.keys())
-               positions.sort()
+               positions = sorted(self.bookmarks)
                self.pos = positions[0]
                firstNoteBody = self.bookmarks[self.pos].body
                notesChoices = []
@@ -387,12 +392,13 @@ class NotesDialog(wx.Dialog):
                self.noteEdit.Value = self.bookmarks[self.pos].body
 
        def onSave(self, evt):
-               noteTitle = self.notesListBox.GetStringSelection().split(" - 
")[1].encode("mbcs")
+               noteTitle = self.notesListBox.GetStringSelection().split(" - 
")[1]
                noteBody = self.noteEdit.Value
                note = Note(noteTitle, noteBody)
                self.bookmarks[self.pos] = note
                try:
-                       pickle.dump(self.bookmarks, file(self.fileName, "wb"))
+                       with open(self.fileName, "wb") as f:
+                               pickle.dump(self.bookmarks, f, protocol=0)
                        self.notesListBox.SetFocus()
                except Exception as e:
                        log.debugWarning("Error saving bookmark", exc_info=True)
@@ -410,7 +416,8 @@ class NotesDialog(wx.Dialog):
                del self.bookmarks[self.pos]
                if len(self.bookmarks.keys()) > 0:
                        try:
-                               pickle.dump(self.bookmarks, file(self.fileName, 
"wb"))
+                               with open(self.fileName, "wb") as f:
+                                       pickle.dump(self.bookmarks, f, 
protocol=0)
                                
self.notesListBox.Delete(self.notesListBox.Selection)
                                self.notesListBox.Selection = 0
                                self.onNotesChange(None)
@@ -422,12 +429,14 @@ class NotesDialog(wx.Dialog):
                        try:
                                os.remove(self.fileName)
                                self.Destroy()
-                               wx.CallAfter(gui.messageBox,
+                               wx.CallAfter(
+                                       gui.messageBox,
                                        # Translators: The message presented 
when all bookmarks have been deleted from the Notes dialog.
                                        _("No bookmarks"),
                                        # Translators: The title of the warning 
dialog when all bookmarks have been deleted.
                                        _("Bookmarks deleted"),
-                                       wx.OK | wx.ICON_WARNING, None)
+                                       wx.OK | wx.ICON_WARNING, None
+                               )
                        except WindowsError:
                                pass
 
@@ -472,18 +481,22 @@ class CopyDialog(wx.Dialog):
        def onCopy(self, evt):
                if not self.copyDirectoryEdit.Value:
                        # Message translated in NVDA core.
-                       gui.messageBox(translate("Please specify a directory."),
+                       gui.messageBox(
+                               translate("Please specify a directory."),
                                # Message translated in NVDA core.
                                translate("Error"),
-                               wx.OK | wx.ICON_ERROR)
+                               wx.OK | wx.ICON_ERROR
+                       )
                        return
                drv=os.path.splitdrive(self.copyDirectoryEdit.Value)[0]
                if drv and not os.path.isdir(drv):
                        # Message translated in NVDA core.
-                       gui.messageBox(translate("Invalid drive %s")%drv,
+                       gui.messageBox(
+                               translate("Invalid drive %s")%drv,
                                # Message translated in NVDA core.
                                translate("Error"),
-                               wx.OK | wx.ICON_ERROR)
+                               wx.OK | wx.ICON_ERROR
+                       )
                        return
                self.Hide()
                doCopy(self.copyDirectoryEdit.Value)
@@ -542,18 +555,22 @@ class RestoreDialog(wx.Dialog):
        def onRestore(self, evt):
                if not self.restoreDirectoryEdit.Value:
                        # Message translated in NVDA core.
-                       gui.messageBox(translate("Please specify a directory."),
+                       gui.messageBox(
+                               translate("Please specify a directory."),
                                # Message translated in NVDA core.
                                translate("Error"),
-                               wx.OK | wx.ICON_ERROR)
+                               wx.OK | wx.ICON_ERROR
+                       )
                        return
                drv=os.path.splitdrive(self.restoreDirectoryEdit.Value)[0]
                if drv and not os.path.isdir(drv):
                        # Message translated in NVDA core.
-                       gui.messageBox(translate("Invalid drive %s")%drv,
+                       gui.messageBox(
+                               translate("Invalid drive %s")%drv,
                                # Message translated in NVDA core.
                                translate("Error"),
-                               wx.OK | wx.ICON_ERROR)
+                               wx.OK | wx.ICON_ERROR
+                       )
                        return
                self.Hide()
                doRestore(self.restoreDirectoryEdit.Value)
@@ -575,43 +592,50 @@ class Note(object):
 
 class GlobalPlugin(globalPluginHandler.GlobalPlugin):
 
-       try:
-               scriptCategory = unicode(ADDON_SUMMARY)
-       except NameError:
-               scriptCategory = str(ADDON_SUMMARY)
+       scriptCategory = ADDON_SUMMARY
 
        def __init__(self):
                super(GlobalPlugin, self).__init__()
                self.menu = gui.mainFrame.sysTrayIcon.preferencesMenu
                self.BSMenu = wx.Menu()
-               self.mainItem = self.menu.AppendSubMenu(self.BSMenu,
+               self.mainItem = self.menu.AppendSubMenu(
+                       self.BSMenu,
                        # Translators: the name of addon submenu.
                        _("P&lace markers"),
                        # Translators: the tooltip text for addon submenu.
-                       _("Bookmarks and Search menu"))
-               self.searchItem = self.BSMenu.Append(wx.ID_ANY,
+                       _("Bookmarks and Search menu")
+               )
+               self.searchItem = self.BSMenu.Append(
+                       wx.ID_ANY,
                        # Translators: the name for an item of addon submenu.
                        _("&Specific search folder"),
                        # Translators: the tooltip text for an item of addon 
submenu.
-                       _("Opens the specific search folder"))
+                       _("Opens the specific search folder")
+               )
                gui.mainFrame.sysTrayIcon.Bind(wx.EVT_MENU, 
self.onSpecificSearch, self.searchItem)
-               self.bookmarksItem = self.BSMenu.Append(wx.ID_ANY,
+               self.bookmarksItem = self.BSMenu.Append(
+                       wx.ID_ANY,
                        # Translators: the name for an item of addon submenu.
                        _("&Bookmarks folder"),
                        # Translators: the tooltip text for an item of addon 
submenu.
-                       _("Opens the bookmarks folder"))
+                       _("Opens the bookmarks folder")
+               )
                gui.mainFrame.sysTrayIcon.Bind(wx.EVT_MENU, self.onBookmarks, 
self.bookmarksItem)
-               self.copyItem = self.BSMenu.Append(wx.ID_ANY,
+               self.copyItem = self.BSMenu.Append(
+                       wx.ID_ANY,
                        # Translators: the name for an item of addon submenu.
                        _("&Copy placeMarkers folder..."),
                        # Translators: the tooltip text for an item of addon 
submenu.
-                       _("Backup of place markers"))
+                       _("Backup of place markers")
+               )
                gui.mainFrame.sysTrayIcon.Bind(wx.EVT_MENU, self.onCopy, 
self.copyItem)
-               self.restoreItem = self.BSMenu.Append(wx.ID_ANY,
+               self.restoreItem = self.BSMenu.Append(
+                       wx.ID_ANY,
                        # Translators: the name for an item of addon submenu.
                        _("R&estore place markers..."),
                        # Translators: the tooltip text for an item of addon 
submenu.
-                       _("Restore previously saved place markers"))
+                       _("Restore previously saved place markers")
+               )
                gui.mainFrame.sysTrayIcon.Bind(wx.EVT_MENU, self.onRestore, 
self.restoreItem)
 
        def terminate(self):
@@ -723,7 +747,8 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                if getSavedBookmarks() == {}:
                        ui.message(
                                # Translators: message presented when the 
current document doesn't contain bookmarks.
-                               _("No bookmarks"))
+                               _("No bookmarks")
+                       )
                        return
                gui.mainFrame.prePopup()
                d = NotesDialog(gui.mainFrame, getFileBookmarks())
@@ -742,7 +767,7 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                        gesture.send()
                        return
                treeInterceptor=obj.treeInterceptor
-               if not (hasattr(treeInterceptor,'TextInfo') and not 
treeInterceptor.passThrough):
+               if not (isinstance(treeInterceptor, 
BrowseModeDocumentTreeInterceptor) and not treeInterceptor.passThrough):
                        gesture.send()
                        return
                wx.CallAfter(self.popupNotesDialog)
@@ -766,7 +791,7 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                        return
                bookmark = obj.makeTextInfo(textInfos.POSITION_CARET).bookmark
                bookmarks = getSavedBookmarks()
-               noteTitle = 
obj.makeTextInfo(textInfos.POSITION_SELECTION).text[:100].encode("utf-8")
+               noteTitle = 
obj.makeTextInfo(textInfos.POSITION_SELECTION).text[:100]
                if bookmark.startOffset in bookmarks:
                        noteBody = bookmarks[bookmark.startOffset].body
                else:
@@ -774,15 +799,18 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                bookmarks[bookmark.startOffset] = Note(noteTitle, noteBody)
                fileName = getFileBookmarks()
                try:
-                       pickle.dump(bookmarks, file(fileName, "wb"))
+                       with open(fileName, "wb") as f:
+                               pickle.dump(bookmarks, f, protocol=0)
                        ui.message(
                                # Translators: message presented when a 
position is saved as a bookmark.
-                               _("Saved position at character %d") % 
bookmark.startOffset)
+                               _("Saved position at character %d") % 
bookmark.startOffset
+                       )
                except Exception as e:
                        log.debugWarning("Error saving bookmark", exc_info=True)
                        ui.message(
                                # Translators: message presented when a 
bookmark cannot be saved.
-                               _("Cannot save bookmark"))
+                               _("Cannot save bookmark")
+                       )
                        raise e
 
        @script(
@@ -802,22 +830,26 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                if bookmarks == {}:
                        ui.message(
                                # Translators: message presented when the 
current document doesn't contain bookmarks.
-                               _("No bookmarks"))
+                               _("No bookmarks")
+                       )
                        return
                curPos = 
obj.makeTextInfo(textInfos.POSITION_CARET).bookmark.startOffset
                if curPos not in bookmarks:
                        ui.message(
                                # Translators: message presented when the 
current document has bookmarks, but none is selected.
-                               _("No bookmark selected"))
+                               _("No bookmark selected")
+                       )
                        return
                del(bookmarks[curPos])
                fileName = getFileBookmarks()
                if bookmarks != {}:
                        try:
-                               pickle.dump(bookmarks, file(fileName, "wb"))
+                               with open(fileName, "wb") as f:
+                                       pickle.dump(bookmarks, f, protocol=0)
                                ui.message(
                                        # Translators: message presented when a 
bookmark is deleted.
-                                       _("Bookmark deleted"))
+                                       _("Bookmark deleted")
+                               )
                                return
                        except:
                                pass
@@ -826,14 +858,16 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                                os.remove(fileName)
                                ui.message(
                                        # Translators: message presented when 
the current document doesn't contain bookmarks.
-                                       _("No bookmarks"))
+                                       _("No bookmarks")
+                               )
                                return
                        except WindowsError:
                                pass
                log.debugWarning("Error saving bookmarks", exc_info=True)
                ui.message(
                        # Translators: message presented when cannot delete a 
bookmark.
-                       _("Cannot delete bookmark"))
+                       _("Cannot delete bookmark")
+               )
 
        @script(
                # Translators: message presented in input mode, when a 
keystroke of an addon script is pressed.
@@ -857,7 +891,8 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                if bookmarks == {}:
                        ui.message(
                                # Translators: message presented when trying to 
select a bookmark, but none is found.
-                               _("No bookmarks found"))
+                               _("No bookmarks found")
+                       )
                        return
                curPos = 
obj.makeTextInfo(textInfos.POSITION_CARET).bookmark.startOffset
                nextPos = None
@@ -871,15 +906,16 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                        review.handleCaretMove(info)
                        if willSayAllResume(gesture):
                                info.move(textInfos.UNIT_LINE,1,endPoint="end")
-                               
#speech.speakTextInfo(info,reason=controlTypes.REASON_CARET)
                        else:
                                ui.message(
                                        # Translators: message presented when a 
bookmark is selected.
-                                       _("Position: character %d") % nextPos)
+                                       _("Position: character %d") % nextPos
+                               )
                        return
                ui.message(
                        # Translators: message presented when the next bookmark 
is not found.
-                       _("Next bookmark not found"))
+                       _("Next bookmark not found")
+               )
 
        @script(
                # Translators: message presented in input mode, when a 
keystroke of an addon script is pressed.
@@ -903,7 +939,8 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                if bookmarks == {}:
                        ui.message(
                                # Translators: message presented when trying to 
select a bookmark, but none is found.
-                               _("No bookmarks found"))
+                               _("No bookmarks found")
+                       )
                        return
                curPos = 
obj.makeTextInfo(textInfos.POSITION_CARET).bookmark.startOffset
                prevPos = None
@@ -917,37 +954,33 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                        review.handleCaretMove(info)
                        if willSayAllResume(gesture):
                                info.move(textInfos.UNIT_LINE,1,endPoint="end")
-                               
#speech.speakTextInfo(info,reason=controlTypes.REASON_CARET)
                        else:
                                ui.message(
                                        # Translators: message presented when a 
bookmark is selected.
-                                       _("Position: character %d") % prevPos)
+                                       _("Position: character %d") % prevPos
+                               )
                        return
                ui.message(
                        # Translators: message presented when the previous 
bookmark is not found.
-                       _("Previous bookmark not found"))
+                       _("Previous bookmark not found")
+               )
 
        @script(
                # Translators: message presented in input mode, when a 
keystroke of an addon script is pressed.
-               description=_("Copies the name of the current file for place 
markers to the clipboard."),
-               gesture="kb:control+shift+k"
+               description=_("Shows the name of the current file for place 
markers in browse mode.")
        )
-       def script_copyCurrentBookmarksFile(self, gesture):
+       def script_showCurrentBookmarksFile(self, gesture):
                obj=api.getFocusObject()
                if not controlTypes.STATE_MULTILINE in obj.states:
                        treeInterceptor=obj.treeInterceptor
-                       if not (hasattr(treeInterceptor,'TextInfo') and not 
treeInterceptor.passThrough) and controlTypes.STATE_MULTILINE not in obj.states:
+                       if not (isinstance(treeInterceptor, 
BrowseModeDocumentTreeInterceptor) and not treeInterceptor.passThrough):
                                gesture.send()
                                return
                fileName = getFile("bookmarks")
-               if not api.copyToClip(os.path.basename(fileName)):
-                       ui.message(
-                               # Translators: message presented when cannot 
copy the file name corresponding to place markers.
-                               _("Cannot copy file name for place markers"))
-                       return
-               ui.message(
-                       # Translators: message presented when file name for 
place markers is copied to clipboard.
-                       _("Place markers file name copied to clipboard"))
+               ui.browseableMessage(
+                       # Translators: Title for the message presented when the 
file name for place markers is shown in browse mode.
+                       fileName, _("%s file" % ADDON_SUMMARY)
+               )
 
        @script(
                # Translators: message presented in input mode, when a 
keystroke of an addon script is pressed.
@@ -968,7 +1001,7 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                bookmark = obj.makeTextInfo(textInfos.POSITION_CARET).bookmark
                fileName = getFileTempBookmark()
                try:
-                       with codecs.open(fileName, "w", "utf-8") as f:
+                       with open(fileName, "w", encoding="utf-8") as f:
                                f.write(str(bookmark.startOffset))
                                # Translators: Message presented when a 
temporary bookmark is saved.
                                ui.message(_("Saved temporary bookmark at 
position %d" % bookmark.startOffset))
@@ -994,7 +1027,7 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                        return
                fileName = getFileTempBookmark()
                try:
-                       with codecs.open(fileName, "r", "utf-8") as f:
+                       with open(fileName, "r", encoding="utf-8") as f:
                                tempBookmark = int(f.read())
                        moveToBookmark(tempBookmark)
                except:

diff --git a/addon/installTasks.py b/addon/installTasks.py
index 9b48893..57f2c27 100644
--- a/addon/installTasks.py
+++ b/addon/installTasks.py
@@ -20,7 +20,7 @@ def copyTree(src, dst):
 
 def onInstall():
        configPath = globalVars.appArgs.configPath
-       addonDir = os.path.dirname(__file__).decode("mbcs")
+       addonDir = os.path.abspath(os.path.dirname(__file__))
        placeMarkersPath = os.path.join(addonDir, "globalPlugins", 
"placeMarkers", "savedPlaceMarkers")
        addonBackupPath = os.path.join(configPath, "placeMarkersBackup")
        if os.path.isdir(addonBackupPath):

diff --git a/buildVars.py b/buildVars.py
index aaabb07..29d659f 100755
--- a/buildVars.py
+++ b/buildVars.py
@@ -19,7 +19,7 @@ addon_info = {
        # Translators: Long description to be shown for this add-on on add-on 
information from add-ons manager
        "addon_description" : _("Add-on for setting place markers on specific 
virtual documents"),
        # version
-       "addon_version" : "13.0",
+       "addon_version" : "14.0-dev",
        # Author(s)
        "addon_author" : u"Noelia <nrm1977@xxxxxxxxx>, Chris 
<llajta2012@xxxxxxxxx>",
        # URL for the add-on documentation support
@@ -27,9 +27,9 @@ addon_info = {
        # Documentation file name
        "addon_docFileName" : "readme.html",
        # Minimum NVDA version supported (e.g. "2018.3")
-       "addon_minimumNVDAVersion" : "2018.3.0",
+       "addon_minimumNVDAVersion" : "2019.3",
        # Last NVDA version supported/tested (e.g. "2018.4", ideally more 
recent than minimum version)
-       "addon_lastTestedNVDAVersion" : "2019.2.0",
+       "addon_lastTestedNVDAVersion" : "2019.3",
        # Add-on update channel (default is stable or None)
        "addon_updateChannel" : None,
 }

diff --git a/readme.md b/readme.md
index 9789d2e..ed1dedd 100644
--- a/readme.md
+++ b/readme.md
@@ -1,7 +1,7 @@
 # placeMarkers #
 
 * Authors: Noelia, Chris.
-* NVDA compatibility: 2018.3 to 2019.2
+* NVDA compatibility: 2019.3 or later
 * download [stable version][1]
 * download [development version][2]
 
@@ -16,7 +16,7 @@ This addon is based on SpecificSearch and Bookmark&Search, 
developed by the same
 *      control+shift+NVDA+delete: Deletes the bookmark corresponding to this 
position.
 *      NVDA+k: Moves to the next bookmark.
 *      shift+NVDA+k: Moves to the previous bookmark.
-*      control+shift+k: Copies the file name where the place markers data will 
be saved to the clipboard, without an extension.
+*      Not assigned: Shows the file name where the place markers data will be 
saved in browse mode, without an extension.
 *      alt+NVDA+k: Opens a dialog with the bookmarks saved for this document. 
You can write a note for each bookmark; press Save note to save changes. 
Pressing Delete you can remove the selected bookmark. Pressing OK you can move 
to the selected position.
 *      Not assigned: Saves a position as a temporary bookmark.
 *      Not assigned: Moves to the temporary bookmark for the current document.
@@ -35,6 +35,10 @@ Using the Place markers submenu under NVDA's Preferences 
menu, you can access:
 
 Note: The bookmark position is based on the number of characters; and 
therefore in dynamic pages it is better to use the specific search, not 
bookmarks.
 
+## Changes for 14.0 ##
+*      The command to copy the name of the file where place markers data will 
be saved has been replaced by a command which shows this file name in browse 
mode. This is not assigned to a gesture.
+*      Requires NVDA 2019.3 or later.
+
 ## Changes for 13.0 ##
 *      Added not assigned commands to find the next and previous occurrences 
of the last text searched for any specific document.
 *      The specific search feature works when the NVDA's About dialog is open.

diff --git a/scons b/scons
new file mode 100644
index 0000000..98f4e62
--- /dev/null
+++ b/scons
@@ -0,0 +1,210 @@
+#! /usr/bin/env python
+#
+# SCons - a Software Constructor
+#
+# Copyright (c) 2001 - 2019 The SCons Foundation
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+from __future__ import print_function
+
+__revision__ = "src/script/scons.py ae4de9ab2249be220b6658a514eef8c3a57afc04 
2019-07-21 02:32:15 bdeegan"
+
+__version__ = "3.1.0"
+
+__build__ = "ae4de9ab2249be220b6658a514eef8c3a57afc04"
+
+__buildsys__ = "kufra"
+
+__date__ = "2019-07-21 02:32:15"
+
+__developer__ = "bdeegan"
+
+# This is the entry point to the SCons program.
+# The only job of this script is to work out where the guts of the program
+# could be and import them, where the real work begins.
+# SCons can be invoked several different ways
+# - from an installed location
+# - from a "local install" copy
+# - from a source tree, which has a different dir struture than the other two
+# Try to account for all those possibilities.
+
+import os
+import sys
+
+##############################################################################
+# BEGIN STANDARD SCons SCRIPT HEADER
+#
+# This is the cut-and-paste logic so that a self-contained script can
+# interoperate correctly with different SCons versions and installation
+# locations for the engine.  If you modify anything in this section, you
+# should also change other scripts that use this same header.
+##############################################################################
+
+# compatibility check
+if (3,0,0) < sys.version_info < (3,5,0) or sys.version_info < (2,7,0):
+    msg = "scons: *** SCons version %s does not run under Python version %s.\n\
+Python 2.7 or >= 3.5 is required.\n"
+    sys.stderr.write(msg % (__version__, sys.version.split()[0]))
+    sys.exit(1)
+
+# Strip the script directory from sys.path so on case-insensitive
+# (WIN32) systems Python doesn't think that the "scons" script is the
+# "SCons" package.
+script_dir = os.path.dirname(os.path.realpath(__file__))
+script_path = os.path.realpath(os.path.dirname(__file__))
+if script_path in sys.path:
+    sys.path.remove(script_path)
+
+libs = []
+
+if "SCONS_LIB_DIR" in os.environ:
+    libs.append(os.environ["SCONS_LIB_DIR"])
+
+# running from source takes 2nd priority (since 2.3.2), following SCONS_LIB_DIR
+source_path = os.path.join(script_path, os.pardir, 'engine')
+if os.path.isdir(source_path):
+    libs.append(source_path)
+
+# add local-install locations
+local_version = 'scons-local-' + __version__
+local = 'scons-local'
+if script_dir:
+    local_version = os.path.join(script_dir, local_version)
+    local = os.path.join(script_dir, local)
+if os.path.isdir(local_version):
+    libs.append(os.path.abspath(local_version))
+if os.path.isdir(local):
+    libs.append(os.path.abspath(local))
+
+scons_version = 'scons-%s' % __version__
+
+# preferred order of scons lookup paths
+prefs = []
+
+# if we can find package information, use it
+try:
+    import pkg_resources
+except ImportError:
+    pass
+else:
+    try:
+        d = pkg_resources.get_distribution('scons')
+    except pkg_resources.DistributionNotFound:
+        pass
+    else:
+        prefs.append(d.location)
+
+if sys.platform == 'win32':
+    # Use only sys.prefix on Windows
+    prefs.append(sys.prefix)
+    prefs.append(os.path.join(sys.prefix, 'Lib', 'site-packages'))
+else:
+    # On other (POSIX) platforms, things are more complicated due to
+    # the variety of path names and library locations.
+    # Build up some possibilities, then transform them into candidates
+    temp = []
+    if script_dir == 'bin':
+        # script_dir is `pwd`/bin;
+        # check `pwd`/lib/scons*.
+        temp.append(os.getcwd())
+    else:
+        if script_dir == '.' or script_dir == '':
+            script_dir = os.getcwd()
+        head, tail = os.path.split(script_dir)
+        if tail == "bin":
+            # script_dir is /foo/bin;
+            # check /foo/lib/scons*.
+            temp.append(head)
+
+    head, tail = os.path.split(sys.prefix)
+    if tail == "usr":
+        # sys.prefix is /foo/usr;
+        # check /foo/usr/lib/scons* first,
+        # then /foo/usr/local/lib/scons*.
+        temp.append(sys.prefix)
+        temp.append(os.path.join(sys.prefix, "local"))
+    elif tail == "local":
+        h, t = os.path.split(head)
+        if t == "usr":
+            # sys.prefix is /foo/usr/local;
+            # check /foo/usr/local/lib/scons* first,
+            # then /foo/usr/lib/scons*.
+            temp.append(sys.prefix)
+            temp.append(head)
+        else:
+            # sys.prefix is /foo/local;
+            # check only /foo/local/lib/scons*.
+            temp.append(sys.prefix)
+    else:
+        # sys.prefix is /foo (ends in neither /usr or /local);
+        # check only /foo/lib/scons*.
+        temp.append(sys.prefix)
+
+    # suffix these to add to our original prefs:
+    prefs.extend([os.path.join(x, 'lib') for x in temp])
+    prefs.extend([os.path.join(x, 'lib', 'python' + sys.version[:3],
+                               'site-packages') for x in temp])
+
+
+    # Add the parent directory of the current python's library to the
+    # preferences.  This picks up differences between, e.g., lib and lib64,
+    # and finds the base location in case of a non-copying virtualenv.
+    try:
+        libpath = os.__file__
+    except AttributeError:
+        pass
+    else:
+        # Split /usr/libfoo/python*/os.py to /usr/libfoo/python*.
+        libpath, tail = os.path.split(libpath)
+        # Split /usr/libfoo/python* to /usr/libfoo
+        libpath, tail = os.path.split(libpath)
+        # Check /usr/libfoo/scons*.
+        prefs.append(libpath)
+
+# Look first for 'scons-__version__' in all of our preference libs,
+# then for 'scons'.  Skip paths that do not exist.
+libs.extend([os.path.join(x, scons_version) for x in prefs if 
os.path.isdir(x)])
+libs.extend([os.path.join(x, 'scons') for x in prefs if os.path.isdir(x)])
+
+sys.path = libs + sys.path
+
+##############################################################################
+# END STANDARD SCons SCRIPT HEADER
+##############################################################################
+
+if __name__ == "__main__":
+    try:
+        import SCons.Script
+    except ImportError:
+        sys.stderr.write("SCons import failed. Unable to find engine files 
in:\n")
+        for path in libs:
+            sys.stderr.write("  {}\n".format(path))
+        raise
+
+    # this does all the work, and calls sys.exit
+    # with the proper exit status when done.
+    SCons.Script.main()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:

diff --git a/scons-3.1.0 b/scons-3.1.0
new file mode 100644
index 0000000..98f4e62
--- /dev/null
+++ b/scons-3.1.0
@@ -0,0 +1,210 @@
+#! /usr/bin/env python
+#
+# SCons - a Software Constructor
+#
+# Copyright (c) 2001 - 2019 The SCons Foundation
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+from __future__ import print_function
+
+__revision__ = "src/script/scons.py ae4de9ab2249be220b6658a514eef8c3a57afc04 
2019-07-21 02:32:15 bdeegan"
+
+__version__ = "3.1.0"
+
+__build__ = "ae4de9ab2249be220b6658a514eef8c3a57afc04"
+
+__buildsys__ = "kufra"
+
+__date__ = "2019-07-21 02:32:15"
+
+__developer__ = "bdeegan"
+
+# This is the entry point to the SCons program.
+# The only job of this script is to work out where the guts of the program
+# could be and import them, where the real work begins.
+# SCons can be invoked several different ways
+# - from an installed location
+# - from a "local install" copy
+# - from a source tree, which has a different dir struture than the other two
+# Try to account for all those possibilities.
+
+import os
+import sys
+
+##############################################################################
+# BEGIN STANDARD SCons SCRIPT HEADER
+#
+# This is the cut-and-paste logic so that a self-contained script can
+# interoperate correctly with different SCons versions and installation
+# locations for the engine.  If you modify anything in this section, you
+# should also change other scripts that use this same header.
+##############################################################################
+
+# compatibility check
+if (3,0,0) < sys.version_info < (3,5,0) or sys.version_info < (2,7,0):
+    msg = "scons: *** SCons version %s does not run under Python version %s.\n\
+Python 2.7 or >= 3.5 is required.\n"
+    sys.stderr.write(msg % (__version__, sys.version.split()[0]))
+    sys.exit(1)
+
+# Strip the script directory from sys.path so on case-insensitive
+# (WIN32) systems Python doesn't think that the "scons" script is the
+# "SCons" package.
+script_dir = os.path.dirname(os.path.realpath(__file__))
+script_path = os.path.realpath(os.path.dirname(__file__))
+if script_path in sys.path:
+    sys.path.remove(script_path)
+
+libs = []
+
+if "SCONS_LIB_DIR" in os.environ:
+    libs.append(os.environ["SCONS_LIB_DIR"])
+
+# running from source takes 2nd priority (since 2.3.2), following SCONS_LIB_DIR
+source_path = os.path.join(script_path, os.pardir, 'engine')
+if os.path.isdir(source_path):
+    libs.append(source_path)
+
+# add local-install locations
+local_version = 'scons-local-' + __version__
+local = 'scons-local'
+if script_dir:
+    local_version = os.path.join(script_dir, local_version)
+    local = os.path.join(script_dir, local)
+if os.path.isdir(local_version):
+    libs.append(os.path.abspath(local_version))
+if os.path.isdir(local):
+    libs.append(os.path.abspath(local))
+
+scons_version = 'scons-%s' % __version__
+
+# preferred order of scons lookup paths
+prefs = []
+
+# if we can find package information, use it
+try:
+    import pkg_resources
+except ImportError:
+    pass
+else:
+    try:
+        d = pkg_resources.get_distribution('scons')
+    except pkg_resources.DistributionNotFound:
+        pass
+    else:
+        prefs.append(d.location)
+
+if sys.platform == 'win32':
+    # Use only sys.prefix on Windows
+    prefs.append(sys.prefix)
+    prefs.append(os.path.join(sys.prefix, 'Lib', 'site-packages'))
+else:
+    # On other (POSIX) platforms, things are more complicated due to
+    # the variety of path names and library locations.
+    # Build up some possibilities, then transform them into candidates
+    temp = []
+    if script_dir == 'bin':
+        # script_dir is `pwd`/bin;
+        # check `pwd`/lib/scons*.
+        temp.append(os.getcwd())
+    else:
+        if script_dir == '.' or script_dir == '':
+            script_dir = os.getcwd()
+        head, tail = os.path.split(script_dir)
+        if tail == "bin":
+            # script_dir is /foo/bin;
+            # check /foo/lib/scons*.
+            temp.append(head)
+
+    head, tail = os.path.split(sys.prefix)
+    if tail == "usr":
+        # sys.prefix is /foo/usr;
+        # check /foo/usr/lib/scons* first,
+        # then /foo/usr/local/lib/scons*.
+        temp.append(sys.prefix)
+        temp.append(os.path.join(sys.prefix, "local"))
+    elif tail == "local":
+        h, t = os.path.split(head)
+        if t == "usr":
+            # sys.prefix is /foo/usr/local;
+            # check /foo/usr/local/lib/scons* first,
+            # then /foo/usr/lib/scons*.
+            temp.append(sys.prefix)
+            temp.append(head)
+        else:
+            # sys.prefix is /foo/local;
+            # check only /foo/local/lib/scons*.
+            temp.append(sys.prefix)
+    else:
+        # sys.prefix is /foo (ends in neither /usr or /local);
+        # check only /foo/lib/scons*.
+        temp.append(sys.prefix)
+
+    # suffix these to add to our original prefs:
+    prefs.extend([os.path.join(x, 'lib') for x in temp])
+    prefs.extend([os.path.join(x, 'lib', 'python' + sys.version[:3],
+                               'site-packages') for x in temp])
+
+
+    # Add the parent directory of the current python's library to the
+    # preferences.  This picks up differences between, e.g., lib and lib64,
+    # and finds the base location in case of a non-copying virtualenv.
+    try:
+        libpath = os.__file__
+    except AttributeError:
+        pass
+    else:
+        # Split /usr/libfoo/python*/os.py to /usr/libfoo/python*.
+        libpath, tail = os.path.split(libpath)
+        # Split /usr/libfoo/python* to /usr/libfoo
+        libpath, tail = os.path.split(libpath)
+        # Check /usr/libfoo/scons*.
+        prefs.append(libpath)
+
+# Look first for 'scons-__version__' in all of our preference libs,
+# then for 'scons'.  Skip paths that do not exist.
+libs.extend([os.path.join(x, scons_version) for x in prefs if 
os.path.isdir(x)])
+libs.extend([os.path.join(x, 'scons') for x in prefs if os.path.isdir(x)])
+
+sys.path = libs + sys.path
+
+##############################################################################
+# END STANDARD SCons SCRIPT HEADER
+##############################################################################
+
+if __name__ == "__main__":
+    try:
+        import SCons.Script
+    except ImportError:
+        sys.stderr.write("SCons import failed. Unable to find engine files 
in:\n")
+        for path in libs:
+            sys.stderr.write("  {}\n".format(path))
+        raise
+
+    # this does all the work, and calls sys.exit
+    # with the proper exit status when done.
+    SCons.Script.main()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:

diff --git a/scons-3.1.0.bat b/scons-3.1.0.bat
new file mode 100644
index 0000000..42c44c2
--- /dev/null
+++ b/scons-3.1.0.bat
@@ -0,0 +1,38 @@
+@REM Copyright (c) 2001 - 2019 The SCons Foundation
+@REM src/script/scons.bat e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 
00:04:47 bdeegan
+@echo off
+set SCONS_ERRORLEVEL=
+if "%OS%" == "Windows_NT" goto WinNT
+
+@REM for 9x/Me you better not have more than 9 args
+python -c "from os.path import join; import sys; sys.path = [ join(sys.prefix, 
'Lib', 'site-packages', 'scons-3.1.0'), join(sys.prefix, 'Lib', 
'site-packages', 'scons'), join(sys.prefix, 'scons-3.1.0'), join(sys.prefix, 
'scons')] + sys.path; import SCons.Script; SCons.Script.main()" %1 %2 %3 %4 %5 
%6 %7 %8 %9
+@REM no way to set exit status of this script for 9x/Me
+goto endscons
+
+@REM Credit where credit is due:  we return the exit code despite our
+@REM use of setlocal+endlocal using a technique from Bear's Journal:
+@REM 
http://code-bear.com/bearlog/2007/06/01/getting-the-exit-code-from-a-batch-file-that-is-run-from-a-python-program/
+
+:WinNT
+setlocal
+@REM ensure the script will be executed with the Python it was installed for
+pushd %~dp0..
+set path=%~dp0;%CD%;%path%
+popd
+@REM try the script named as the .bat file in current dir, then in Scripts 
subdir
+set scriptname=%~dp0%~n0.py
+if not exist "%scriptname%" set scriptname=%~dp0Scripts\%~n0.py
+@REM Handle when running from wheel where the script has no .py extension
+if not exist "%scriptname%" set scriptname=%~dp0%~n0
+python "%scriptname%" %*
+endlocal & set SCONS_ERRORLEVEL=%ERRORLEVEL%
+
+if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto returncode
+if errorlevel 9009 echo you do not have python in your PATH
+goto endscons
+
+:returncode
+exit /B %SCONS_ERRORLEVEL%
+
+:endscons
+call :returncode %SCONS_ERRORLEVEL%

diff --git a/scons-configure-cache b/scons-configure-cache
new file mode 100644
index 0000000..757a79f
--- /dev/null
+++ b/scons-configure-cache
@@ -0,0 +1,178 @@
+#! /usr/bin/env python
+#
+# SCons - a Software Constructor
+#
+# Copyright (c) 2001 - 2019 The SCons Foundation
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+'''Show or convert the configuration of an SCons cache directory.
+
+A cache of derived files is stored by file signature.
+The files are split into directories named by the first few
+digits of the signature. The prefix length used for directory
+names can be changed by this script.
+'''
+
+from __future__ import print_function
+import argparse
+import glob
+import json
+import os
+
+__revision__ = "src/script/scons-configure-cache.py 
e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 00:04:47 bdeegan"
+
+__version__ = "3.1.0"
+
+__build__ = "e724ae812eb96f4858a132f5b8c769724744faf6"
+
+__buildsys__ = "kufra"
+
+__date__ = "2019-07-21 00:04:47"
+
+__developer__ = "bdeegan"
+
+
+def rearrange_cache_entries(current_prefix_len, new_prefix_len):
+    '''Move cache files if prefix length changed.
+
+    Move the existing cache files to new directories of the
+    appropriate name length and clean up the old directories.
+    '''
+    print('Changing prefix length from', current_prefix_len,
+          'to', new_prefix_len)
+    dirs = set()
+    old_dirs = set()
+    for file in glob.iglob(os.path.join('*', '*')):
+        name = os.path.basename(file)
+        dname = name[:current_prefix_len].upper()
+        if dname not in old_dirs:
+            print('Migrating', dname)
+            old_dirs.add(dname)
+        dname = name[:new_prefix_len].upper()
+        if dname not in dirs:
+            os.mkdir(dname)
+            dirs.add(dname)
+        os.rename(file, os.path.join(dname, name))
+
+    # Now delete the original directories
+    for dname in old_dirs:
+        os.rmdir(dname)
+
+
+# The configuration dictionary should have one entry per entry in the
+# cache config. The value of each entry should include the following:
+#   implicit - (optional) This is to allow adding a new config entry and also
+#              changing the behaviour of the system at the same time. This
+#              indicates the value the config entry would have had if it had
+#              been specified.
+#   default - The value the config entry should have if it wasn't previously
+#             specified
+#   command-line - parameters to pass to ArgumentParser.add_argument
+#   converter - (optional) Function to call if conversion is required
+#               if this configuration entry changes
+config_entries = {
+    'prefix_len': {
+        'implicit': 1,
+        'default': 2,
+        'command-line': {
+            'help': 'Length of cache file name used as subdirectory prefix',
+            'metavar': '<number>',
+            'type': int
+        },
+        'converter': rearrange_cache_entries
+    }
+}
+
+parser = argparse.ArgumentParser(
+    description='Modify the configuration of an scons cache directory',
+    epilog='''
+           Unspecified options will not be changed unless they are not
+           set at all, in which case they are set to an appropriate default.
+           ''')
+
+parser.add_argument('cache-dir', help='Path to scons cache directory')
+for param in config_entries:
+    parser.add_argument('--' + param.replace('_', '-'),
+                        **config_entries[param]['command-line'])
+parser.add_argument('--version',
+                    action='version',
+                    version='%(prog)s 1.0')
+parser.add_argument('--show',
+                    action="store_true",
+                    help="show current configuration")
+
+# Get the command line as a dict without any of the unspecified entries.
+args = dict([x for x in vars(parser.parse_args()).items() if x[1]])
+
+# It seems somewhat strange to me, but positional arguments don't get the -
+# in the name changed to _, whereas optional arguments do...
+cache = args['cache-dir']
+if not os.path.isdir(cache):
+    raise RuntimeError("There is no cache directory named %s" % cache)
+os.chdir(cache)
+del args['cache-dir']
+
+if not os.path.exists('config'):
+    # old config dirs did not have a 'config' file. Try to update.
+    # Validate the only files in the directory are directories 0-9, a-f
+    expected = ['{:X}'.format(x) for x in range(0, 16)]
+    if not set(os.listdir('.')).issubset(expected):
+        raise RuntimeError(
+            "%s does not look like a valid version 1 cache directory" % cache)
+    config = dict()
+else:
+    with open('config') as conf:
+        config = json.load(conf)
+
+if args.get('show', None):
+    print("Current configuration in '%s':" % cache)
+    print(json.dumps(config, sort_keys=True,
+                     indent=4, separators=(',', ': ')))
+    # in case of the show argument, emit some stats as well
+    file_count = 0
+    for _, _, files in os.walk('.'):
+        file_count += len(files)
+    if file_count:  # skip config file if it exists
+        file_count -= 1
+    print("Cache contains %s files" % file_count)
+    del args['show']
+
+# Find any keys that are not currently set but should be
+for key in config_entries:
+    if key not in config:
+        if 'implicit' in config_entries[key]:
+            config[key] = config_entries[key]['implicit']
+        else:
+            config[key] = config_entries[key]['default']
+        if key not in args:
+            args[key] = config_entries[key]['default']
+
+# Now go through each entry in args to see if it changes an existing config
+# setting.
+for key in args:
+    if args[key] != config[key]:
+        if 'converter' in config_entries[key]:
+            config_entries[key]['converter'](config[key], args[key])
+        config[key] = args[key]
+
+# and write the updated config file
+with open('config', 'w') as conf:
+    json.dump(config, conf)

diff --git a/scons-configure-cache-3.1.0 b/scons-configure-cache-3.1.0
new file mode 100644
index 0000000..757a79f
--- /dev/null
+++ b/scons-configure-cache-3.1.0
@@ -0,0 +1,178 @@
+#! /usr/bin/env python
+#
+# SCons - a Software Constructor
+#
+# Copyright (c) 2001 - 2019 The SCons Foundation
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+'''Show or convert the configuration of an SCons cache directory.
+
+A cache of derived files is stored by file signature.
+The files are split into directories named by the first few
+digits of the signature. The prefix length used for directory
+names can be changed by this script.
+'''
+
+from __future__ import print_function
+import argparse
+import glob
+import json
+import os
+
+__revision__ = "src/script/scons-configure-cache.py 
e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 00:04:47 bdeegan"
+
+__version__ = "3.1.0"
+
+__build__ = "e724ae812eb96f4858a132f5b8c769724744faf6"
+
+__buildsys__ = "kufra"
+
+__date__ = "2019-07-21 00:04:47"
+
+__developer__ = "bdeegan"
+
+
+def rearrange_cache_entries(current_prefix_len, new_prefix_len):
+    '''Move cache files if prefix length changed.
+
+    Move the existing cache files to new directories of the
+    appropriate name length and clean up the old directories.
+    '''
+    print('Changing prefix length from', current_prefix_len,
+          'to', new_prefix_len)
+    dirs = set()
+    old_dirs = set()
+    for file in glob.iglob(os.path.join('*', '*')):
+        name = os.path.basename(file)
+        dname = name[:current_prefix_len].upper()
+        if dname not in old_dirs:
+            print('Migrating', dname)
+            old_dirs.add(dname)
+        dname = name[:new_prefix_len].upper()
+        if dname not in dirs:
+            os.mkdir(dname)
+            dirs.add(dname)
+        os.rename(file, os.path.join(dname, name))
+
+    # Now delete the original directories
+    for dname in old_dirs:
+        os.rmdir(dname)
+
+
+# The configuration dictionary should have one entry per entry in the
+# cache config. The value of each entry should include the following:
+#   implicit - (optional) This is to allow adding a new config entry and also
+#              changing the behaviour of the system at the same time. This
+#              indicates the value the config entry would have had if it had
+#              been specified.
+#   default - The value the config entry should have if it wasn't previously
+#             specified
+#   command-line - parameters to pass to ArgumentParser.add_argument
+#   converter - (optional) Function to call if conversion is required
+#               if this configuration entry changes
+config_entries = {
+    'prefix_len': {
+        'implicit': 1,
+        'default': 2,
+        'command-line': {
+            'help': 'Length of cache file name used as subdirectory prefix',
+            'metavar': '<number>',
+            'type': int
+        },
+        'converter': rearrange_cache_entries
+    }
+}
+
+parser = argparse.ArgumentParser(
+    description='Modify the configuration of an scons cache directory',
+    epilog='''
+           Unspecified options will not be changed unless they are not
+           set at all, in which case they are set to an appropriate default.
+           ''')
+
+parser.add_argument('cache-dir', help='Path to scons cache directory')
+for param in config_entries:
+    parser.add_argument('--' + param.replace('_', '-'),
+                        **config_entries[param]['command-line'])
+parser.add_argument('--version',
+                    action='version',
+                    version='%(prog)s 1.0')
+parser.add_argument('--show',
+                    action="store_true",
+                    help="show current configuration")
+
+# Get the command line as a dict without any of the unspecified entries.
+args = dict([x for x in vars(parser.parse_args()).items() if x[1]])
+
+# It seems somewhat strange to me, but positional arguments don't get the -
+# in the name changed to _, whereas optional arguments do...
+cache = args['cache-dir']
+if not os.path.isdir(cache):
+    raise RuntimeError("There is no cache directory named %s" % cache)
+os.chdir(cache)
+del args['cache-dir']
+
+if not os.path.exists('config'):
+    # old config dirs did not have a 'config' file. Try to update.
+    # Validate the only files in the directory are directories 0-9, a-f
+    expected = ['{:X}'.format(x) for x in range(0, 16)]
+    if not set(os.listdir('.')).issubset(expected):
+        raise RuntimeError(
+            "%s does not look like a valid version 1 cache directory" % cache)
+    config = dict()
+else:
+    with open('config') as conf:
+        config = json.load(conf)
+
+if args.get('show', None):
+    print("Current configuration in '%s':" % cache)
+    print(json.dumps(config, sort_keys=True,
+                     indent=4, separators=(',', ': ')))
+    # in case of the show argument, emit some stats as well
+    file_count = 0
+    for _, _, files in os.walk('.'):
+        file_count += len(files)
+    if file_count:  # skip config file if it exists
+        file_count -= 1
+    print("Cache contains %s files" % file_count)
+    del args['show']
+
+# Find any keys that are not currently set but should be
+for key in config_entries:
+    if key not in config:
+        if 'implicit' in config_entries[key]:
+            config[key] = config_entries[key]['implicit']
+        else:
+            config[key] = config_entries[key]['default']
+        if key not in args:
+            args[key] = config_entries[key]['default']
+
+# Now go through each entry in args to see if it changes an existing config
+# setting.
+for key in args:
+    if args[key] != config[key]:
+        if 'converter' in config_entries[key]:
+            config_entries[key]['converter'](config[key], args[key])
+        config[key] = args[key]
+
+# and write the updated config file
+with open('config', 'w') as conf:
+    json.dump(config, conf)

diff --git a/scons.bat b/scons.bat
new file mode 100644
index 0000000..42c44c2
--- /dev/null
+++ b/scons.bat
@@ -0,0 +1,38 @@
+@REM Copyright (c) 2001 - 2019 The SCons Foundation
+@REM src/script/scons.bat e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 
00:04:47 bdeegan
+@echo off
+set SCONS_ERRORLEVEL=
+if "%OS%" == "Windows_NT" goto WinNT
+
+@REM for 9x/Me you better not have more than 9 args
+python -c "from os.path import join; import sys; sys.path = [ join(sys.prefix, 
'Lib', 'site-packages', 'scons-3.1.0'), join(sys.prefix, 'Lib', 
'site-packages', 'scons'), join(sys.prefix, 'scons-3.1.0'), join(sys.prefix, 
'scons')] + sys.path; import SCons.Script; SCons.Script.main()" %1 %2 %3 %4 %5 
%6 %7 %8 %9
+@REM no way to set exit status of this script for 9x/Me
+goto endscons
+
+@REM Credit where credit is due:  we return the exit code despite our
+@REM use of setlocal+endlocal using a technique from Bear's Journal:
+@REM 
http://code-bear.com/bearlog/2007/06/01/getting-the-exit-code-from-a-batch-file-that-is-run-from-a-python-program/
+
+:WinNT
+setlocal
+@REM ensure the script will be executed with the Python it was installed for
+pushd %~dp0..
+set path=%~dp0;%CD%;%path%
+popd
+@REM try the script named as the .bat file in current dir, then in Scripts 
subdir
+set scriptname=%~dp0%~n0.py
+if not exist "%scriptname%" set scriptname=%~dp0Scripts\%~n0.py
+@REM Handle when running from wheel where the script has no .py extension
+if not exist "%scriptname%" set scriptname=%~dp0%~n0
+python "%scriptname%" %*
+endlocal & set SCONS_ERRORLEVEL=%ERRORLEVEL%
+
+if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto returncode
+if errorlevel 9009 echo you do not have python in your PATH
+goto endscons
+
+:returncode
+exit /B %SCONS_ERRORLEVEL%
+
+:endscons
+call :returncode %SCONS_ERRORLEVEL%

diff --git a/sconstruct b/sconstruct
index d1e3c76..e890d97 100755
--- a/sconstruct
+++ b/sconstruct
@@ -3,7 +3,6 @@
 #This file is covered by the GNU General Public License.
 #See the file COPYING.txt for more details.
 
-import codecs
 import gettext
 import os
 import os.path
@@ -19,7 +18,7 @@ def md2html(source, dest):
        lang = os.path.basename(os.path.dirname(source)).replace('_', '-')
        localeLang = os.path.basename(os.path.dirname(source))
        try:
-               _ = gettext.translation("nvda", localedir=os.path.join("addon", 
"locale"), languages=[localeLang]).ugettext if sys.version_info.major == 2 else 
gettext.translation("nvda", localedir=os.path.join("addon", "locale"), 
languages=[localeLang]).gettext
+               _ = gettext.translation("nvda", localedir=os.path.join("addon", 
"locale"), languages=[localeLang]).gettext
                title=u"{0}".format(_(buildVars.addon_info["addon_summary"]))
        except:
                title="{0}".format(buildVars.addon_info["addon_summary"]) 
@@ -27,20 +26,18 @@ def md2html(source, dest):
                "[[!meta title=\"": "# ",
                "\"]]": " #",
        }
-       with codecs.open(source, "r", "utf-8") as f:
+       with open(source, 'r', encoding="utf-8") as f:
                mdText = f.read()
-               headerList = headerDic.iteritems () if sys.version_info.major 
== 2 else list(headerDic.items())
-               for k, v in headerList:
+               for k, v in headerDic.items():
                        mdText = mdText.replace(k, v, 1)
                htmlText = markdown.markdown(mdText)
-       with codecs.open(dest, "w", "utf-8") as f:
-               f.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
-                       "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 
Strict//EN\"\n" +
-                       "    
\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\";>\n" +
-                       "<html xmlns=\"http://www.w3.org/1999/xhtml\" ;
xml:lang=\"%s\" lang=\"%s\">\n" % (lang, lang) +
+       with open(dest, 'w', encoding="utf-8") as f:
+               f.write("<!DOCTYPE html>\n" +
+                       "<html lang=\"%s\">\n" % lang +
                        "<head>\n" +
-                       "<meta http-equiv=\"Content-Type\" content=\"text/html; 
charset=UTF-8\"/>\n" +
-                       "<link rel=\"stylesheet\" type=\"text/css\" 
href=\"../style.css\" media=\"screen\"/>\n" +
+                       "<meta charset=\"UTF-8\">\n" +
+                       "<meta name=\"viewport\" content=\"width=device-width, 
initial-scale=1.0\">\n" +
+                       "<link rel=\"stylesheet\" type=\"text/css\" 
href=\"../style.css\" media=\"screen\">\n" +
                        "<title>%s</title>\n" % title +
                        "</head>\n<body>\n"
                )
@@ -109,21 +106,27 @@ def createAddonBundleFromPath(path, dest):
        return dest
 
 def generateManifest(source, dest):
-       with codecs.open(source, "r", "utf-8") as f:
+       with open(source, 'r', encoding="utf-8") as f:
                manifest_template = f.read()
        manifest = manifest_template.format(**buildVars.addon_info)
-       with codecs.open(dest, "w", "utf-8") as f:
+       with open(dest, 'w', encoding="utf-8") as f:
                f.write(manifest)
 
 def generateTranslatedManifest(source, language, out):
-       _ = gettext.translation("nvda", localedir=os.path.join("addon", 
"locale"), languages=[language]).ugettext if sys.version_info.major == 2 else 
gettext.translation("nvda", localedir=os.path.join("addon", "locale"), 
languages=[language]).gettext
+       _ = gettext.translation("nvda", localedir=os.path.join("addon", 
"locale"), languages=[language]).gettext
        vars = {}
        for var in ("addon_summary", "addon_description"):
-               vars[var] = _(buildVars.addon_info[var])
-       with codecs.open(source, "r", "utf-8") as f:
+               if isinstance(buildVars.addon_info[var], str):
+                       vars[var] = _(buildVars.addon_info[var])
+               elif isinstance(buildVars.addon_info[var], list):
+                       vars[var] = ''.join([_(l) for l in 
buildVars.addon_info[var]])
+               else:
+                       raise TypeError("Error with %s key in buildVars" % var)
+
+       with open(source, 'r', encoding="utf-8") as f:
                manifest_template = f.read()
        result = manifest_template.format(**vars)
-       with codecs.open(out, "w", "utf-8") as f:
+       with open(out, 'w', encoding="utf-8") as f:
                f.write(result)
 
 def expandGlobs(files):
@@ -167,10 +170,10 @@ for dir in langDirs:
        translatedManifest = 
env.NVDATranslatedManifest(dir.File("manifest.ini"), [moFile, 
os.path.join("manifest-translated.ini.tpl")])
        env.Depends(translatedManifest, ["buildVars.py"])
        env.Depends(addon, [translatedManifest, moFile])
-       #Convert markdown files to html
-       for mdFile in env.Glob(os.path.join('addon', 'doc', '*', '*.md')):
-               htmlFile = env.markdown(mdFile)
-               env.Depends(htmlFile, [mdFile, moFile])
-               env.Depends(addon, htmlFile)
+#Convert markdown files to html
+for mdFile in env.Glob(os.path.join('addon', 'doc', '*', '*.md')):
+       htmlFile = env.markdown(mdFile)
+       env.Depends(htmlFile, mdFile)
+       env.Depends(addon, htmlFile)
 env.Default(addon)
 env.Clean (addon, ['.sconsign.dblite', 'addon/doc/en/'])


https://bitbucket.org/nvdaaddonteam/placemarkers/commits/a027af04ef19/
Changeset:   a027af04ef19
Branch:      None
User:        CyrilleB79
Date:        2019-11-24 02:42:06+00:00
Summary:     Fix Speicific find dialog layout: no more objects overlap (#20)


Affected #:  1 file

diff --git a/addon/globalPlugins/placeMarkers/__init__.py 
b/addon/globalPlugins/placeMarkers/__init__.py
index 59824fb..18ee19e 100644
--- a/addon/globalPlugins/placeMarkers/__init__.py
+++ b/addon/globalPlugins/placeMarkers/__init__.py
@@ -219,8 +219,7 @@ class SpecificSearchDialog(wx.Dialog):
                self.removeCheckBox.Disable()
                # Translators: The label of an edit box in the Specific Search 
dialog.
                searchTextLabel = _("&Text to search:")
-               searchLabeledCtrl = gui.guiHelper.LabeledControlHelper(self, 
searchTextLabel, wx.TextCtrl)
-               self.searchTextEdit = searchLabeledCtrl.control
+               self.searchTextEdit = 
sHelper.addLabeledControl(searchTextLabel, wx.TextCtrl)
                self.searchTextEdit.Value = getLastSpecificFindText()
                self.searchTextEdit.Bind(wx.EVT_TEXT, 
self.onSearchEditTextChange)
                # Translators: A label for a chekbox in the Specific search 
dialog.


https://bitbucket.org/nvdaaddonteam/placemarkers/commits/f085ba19ed54/
Changeset:   f085ba19ed54
Branch:      None
User:        norrumar
Date:        2019-11-24 02:47:25+00:00
Summary:     Deleted extra scons files

Affected #:  6 files

diff --git a/scons b/scons
deleted file mode 100644
index 98f4e62..0000000
--- a/scons
+++ /dev/null
@@ -1,210 +0,0 @@
-#! /usr/bin/env python
-#
-# SCons - a Software Constructor
-#
-# Copyright (c) 2001 - 2019 The SCons Foundation
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-from __future__ import print_function
-
-__revision__ = "src/script/scons.py ae4de9ab2249be220b6658a514eef8c3a57afc04 
2019-07-21 02:32:15 bdeegan"
-
-__version__ = "3.1.0"
-
-__build__ = "ae4de9ab2249be220b6658a514eef8c3a57afc04"
-
-__buildsys__ = "kufra"
-
-__date__ = "2019-07-21 02:32:15"
-
-__developer__ = "bdeegan"
-
-# This is the entry point to the SCons program.
-# The only job of this script is to work out where the guts of the program
-# could be and import them, where the real work begins.
-# SCons can be invoked several different ways
-# - from an installed location
-# - from a "local install" copy
-# - from a source tree, which has a different dir struture than the other two
-# Try to account for all those possibilities.
-
-import os
-import sys
-
-##############################################################################
-# BEGIN STANDARD SCons SCRIPT HEADER
-#
-# This is the cut-and-paste logic so that a self-contained script can
-# interoperate correctly with different SCons versions and installation
-# locations for the engine.  If you modify anything in this section, you
-# should also change other scripts that use this same header.
-##############################################################################
-
-# compatibility check
-if (3,0,0) < sys.version_info < (3,5,0) or sys.version_info < (2,7,0):
-    msg = "scons: *** SCons version %s does not run under Python version %s.\n\
-Python 2.7 or >= 3.5 is required.\n"
-    sys.stderr.write(msg % (__version__, sys.version.split()[0]))
-    sys.exit(1)
-
-# Strip the script directory from sys.path so on case-insensitive
-# (WIN32) systems Python doesn't think that the "scons" script is the
-# "SCons" package.
-script_dir = os.path.dirname(os.path.realpath(__file__))
-script_path = os.path.realpath(os.path.dirname(__file__))
-if script_path in sys.path:
-    sys.path.remove(script_path)
-
-libs = []
-
-if "SCONS_LIB_DIR" in os.environ:
-    libs.append(os.environ["SCONS_LIB_DIR"])
-
-# running from source takes 2nd priority (since 2.3.2), following SCONS_LIB_DIR
-source_path = os.path.join(script_path, os.pardir, 'engine')
-if os.path.isdir(source_path):
-    libs.append(source_path)
-
-# add local-install locations
-local_version = 'scons-local-' + __version__
-local = 'scons-local'
-if script_dir:
-    local_version = os.path.join(script_dir, local_version)
-    local = os.path.join(script_dir, local)
-if os.path.isdir(local_version):
-    libs.append(os.path.abspath(local_version))
-if os.path.isdir(local):
-    libs.append(os.path.abspath(local))
-
-scons_version = 'scons-%s' % __version__
-
-# preferred order of scons lookup paths
-prefs = []
-
-# if we can find package information, use it
-try:
-    import pkg_resources
-except ImportError:
-    pass
-else:
-    try:
-        d = pkg_resources.get_distribution('scons')
-    except pkg_resources.DistributionNotFound:
-        pass
-    else:
-        prefs.append(d.location)
-
-if sys.platform == 'win32':
-    # Use only sys.prefix on Windows
-    prefs.append(sys.prefix)
-    prefs.append(os.path.join(sys.prefix, 'Lib', 'site-packages'))
-else:
-    # On other (POSIX) platforms, things are more complicated due to
-    # the variety of path names and library locations.
-    # Build up some possibilities, then transform them into candidates
-    temp = []
-    if script_dir == 'bin':
-        # script_dir is `pwd`/bin;
-        # check `pwd`/lib/scons*.
-        temp.append(os.getcwd())
-    else:
-        if script_dir == '.' or script_dir == '':
-            script_dir = os.getcwd()
-        head, tail = os.path.split(script_dir)
-        if tail == "bin":
-            # script_dir is /foo/bin;
-            # check /foo/lib/scons*.
-            temp.append(head)
-
-    head, tail = os.path.split(sys.prefix)
-    if tail == "usr":
-        # sys.prefix is /foo/usr;
-        # check /foo/usr/lib/scons* first,
-        # then /foo/usr/local/lib/scons*.
-        temp.append(sys.prefix)
-        temp.append(os.path.join(sys.prefix, "local"))
-    elif tail == "local":
-        h, t = os.path.split(head)
-        if t == "usr":
-            # sys.prefix is /foo/usr/local;
-            # check /foo/usr/local/lib/scons* first,
-            # then /foo/usr/lib/scons*.
-            temp.append(sys.prefix)
-            temp.append(head)
-        else:
-            # sys.prefix is /foo/local;
-            # check only /foo/local/lib/scons*.
-            temp.append(sys.prefix)
-    else:
-        # sys.prefix is /foo (ends in neither /usr or /local);
-        # check only /foo/lib/scons*.
-        temp.append(sys.prefix)
-
-    # suffix these to add to our original prefs:
-    prefs.extend([os.path.join(x, 'lib') for x in temp])
-    prefs.extend([os.path.join(x, 'lib', 'python' + sys.version[:3],
-                               'site-packages') for x in temp])
-
-
-    # Add the parent directory of the current python's library to the
-    # preferences.  This picks up differences between, e.g., lib and lib64,
-    # and finds the base location in case of a non-copying virtualenv.
-    try:
-        libpath = os.__file__
-    except AttributeError:
-        pass
-    else:
-        # Split /usr/libfoo/python*/os.py to /usr/libfoo/python*.
-        libpath, tail = os.path.split(libpath)
-        # Split /usr/libfoo/python* to /usr/libfoo
-        libpath, tail = os.path.split(libpath)
-        # Check /usr/libfoo/scons*.
-        prefs.append(libpath)
-
-# Look first for 'scons-__version__' in all of our preference libs,
-# then for 'scons'.  Skip paths that do not exist.
-libs.extend([os.path.join(x, scons_version) for x in prefs if 
os.path.isdir(x)])
-libs.extend([os.path.join(x, 'scons') for x in prefs if os.path.isdir(x)])
-
-sys.path = libs + sys.path
-
-##############################################################################
-# END STANDARD SCons SCRIPT HEADER
-##############################################################################
-
-if __name__ == "__main__":
-    try:
-        import SCons.Script
-    except ImportError:
-        sys.stderr.write("SCons import failed. Unable to find engine files 
in:\n")
-        for path in libs:
-            sys.stderr.write("  {}\n".format(path))
-        raise
-
-    # this does all the work, and calls sys.exit
-    # with the proper exit status when done.
-    SCons.Script.main()
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:

diff --git a/scons-3.1.0 b/scons-3.1.0
deleted file mode 100644
index 98f4e62..0000000
--- a/scons-3.1.0
+++ /dev/null
@@ -1,210 +0,0 @@
-#! /usr/bin/env python
-#
-# SCons - a Software Constructor
-#
-# Copyright (c) 2001 - 2019 The SCons Foundation
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-from __future__ import print_function
-
-__revision__ = "src/script/scons.py ae4de9ab2249be220b6658a514eef8c3a57afc04 
2019-07-21 02:32:15 bdeegan"
-
-__version__ = "3.1.0"
-
-__build__ = "ae4de9ab2249be220b6658a514eef8c3a57afc04"
-
-__buildsys__ = "kufra"
-
-__date__ = "2019-07-21 02:32:15"
-
-__developer__ = "bdeegan"
-
-# This is the entry point to the SCons program.
-# The only job of this script is to work out where the guts of the program
-# could be and import them, where the real work begins.
-# SCons can be invoked several different ways
-# - from an installed location
-# - from a "local install" copy
-# - from a source tree, which has a different dir struture than the other two
-# Try to account for all those possibilities.
-
-import os
-import sys
-
-##############################################################################
-# BEGIN STANDARD SCons SCRIPT HEADER
-#
-# This is the cut-and-paste logic so that a self-contained script can
-# interoperate correctly with different SCons versions and installation
-# locations for the engine.  If you modify anything in this section, you
-# should also change other scripts that use this same header.
-##############################################################################
-
-# compatibility check
-if (3,0,0) < sys.version_info < (3,5,0) or sys.version_info < (2,7,0):
-    msg = "scons: *** SCons version %s does not run under Python version %s.\n\
-Python 2.7 or >= 3.5 is required.\n"
-    sys.stderr.write(msg % (__version__, sys.version.split()[0]))
-    sys.exit(1)
-
-# Strip the script directory from sys.path so on case-insensitive
-# (WIN32) systems Python doesn't think that the "scons" script is the
-# "SCons" package.
-script_dir = os.path.dirname(os.path.realpath(__file__))
-script_path = os.path.realpath(os.path.dirname(__file__))
-if script_path in sys.path:
-    sys.path.remove(script_path)
-
-libs = []
-
-if "SCONS_LIB_DIR" in os.environ:
-    libs.append(os.environ["SCONS_LIB_DIR"])
-
-# running from source takes 2nd priority (since 2.3.2), following SCONS_LIB_DIR
-source_path = os.path.join(script_path, os.pardir, 'engine')
-if os.path.isdir(source_path):
-    libs.append(source_path)
-
-# add local-install locations
-local_version = 'scons-local-' + __version__
-local = 'scons-local'
-if script_dir:
-    local_version = os.path.join(script_dir, local_version)
-    local = os.path.join(script_dir, local)
-if os.path.isdir(local_version):
-    libs.append(os.path.abspath(local_version))
-if os.path.isdir(local):
-    libs.append(os.path.abspath(local))
-
-scons_version = 'scons-%s' % __version__
-
-# preferred order of scons lookup paths
-prefs = []
-
-# if we can find package information, use it
-try:
-    import pkg_resources
-except ImportError:
-    pass
-else:
-    try:
-        d = pkg_resources.get_distribution('scons')
-    except pkg_resources.DistributionNotFound:
-        pass
-    else:
-        prefs.append(d.location)
-
-if sys.platform == 'win32':
-    # Use only sys.prefix on Windows
-    prefs.append(sys.prefix)
-    prefs.append(os.path.join(sys.prefix, 'Lib', 'site-packages'))
-else:
-    # On other (POSIX) platforms, things are more complicated due to
-    # the variety of path names and library locations.
-    # Build up some possibilities, then transform them into candidates
-    temp = []
-    if script_dir == 'bin':
-        # script_dir is `pwd`/bin;
-        # check `pwd`/lib/scons*.
-        temp.append(os.getcwd())
-    else:
-        if script_dir == '.' or script_dir == '':
-            script_dir = os.getcwd()
-        head, tail = os.path.split(script_dir)
-        if tail == "bin":
-            # script_dir is /foo/bin;
-            # check /foo/lib/scons*.
-            temp.append(head)
-
-    head, tail = os.path.split(sys.prefix)
-    if tail == "usr":
-        # sys.prefix is /foo/usr;
-        # check /foo/usr/lib/scons* first,
-        # then /foo/usr/local/lib/scons*.
-        temp.append(sys.prefix)
-        temp.append(os.path.join(sys.prefix, "local"))
-    elif tail == "local":
-        h, t = os.path.split(head)
-        if t == "usr":
-            # sys.prefix is /foo/usr/local;
-            # check /foo/usr/local/lib/scons* first,
-            # then /foo/usr/lib/scons*.
-            temp.append(sys.prefix)
-            temp.append(head)
-        else:
-            # sys.prefix is /foo/local;
-            # check only /foo/local/lib/scons*.
-            temp.append(sys.prefix)
-    else:
-        # sys.prefix is /foo (ends in neither /usr or /local);
-        # check only /foo/lib/scons*.
-        temp.append(sys.prefix)
-
-    # suffix these to add to our original prefs:
-    prefs.extend([os.path.join(x, 'lib') for x in temp])
-    prefs.extend([os.path.join(x, 'lib', 'python' + sys.version[:3],
-                               'site-packages') for x in temp])
-
-
-    # Add the parent directory of the current python's library to the
-    # preferences.  This picks up differences between, e.g., lib and lib64,
-    # and finds the base location in case of a non-copying virtualenv.
-    try:
-        libpath = os.__file__
-    except AttributeError:
-        pass
-    else:
-        # Split /usr/libfoo/python*/os.py to /usr/libfoo/python*.
-        libpath, tail = os.path.split(libpath)
-        # Split /usr/libfoo/python* to /usr/libfoo
-        libpath, tail = os.path.split(libpath)
-        # Check /usr/libfoo/scons*.
-        prefs.append(libpath)
-
-# Look first for 'scons-__version__' in all of our preference libs,
-# then for 'scons'.  Skip paths that do not exist.
-libs.extend([os.path.join(x, scons_version) for x in prefs if 
os.path.isdir(x)])
-libs.extend([os.path.join(x, 'scons') for x in prefs if os.path.isdir(x)])
-
-sys.path = libs + sys.path
-
-##############################################################################
-# END STANDARD SCons SCRIPT HEADER
-##############################################################################
-
-if __name__ == "__main__":
-    try:
-        import SCons.Script
-    except ImportError:
-        sys.stderr.write("SCons import failed. Unable to find engine files 
in:\n")
-        for path in libs:
-            sys.stderr.write("  {}\n".format(path))
-        raise
-
-    # this does all the work, and calls sys.exit
-    # with the proper exit status when done.
-    SCons.Script.main()
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:

diff --git a/scons-3.1.0.bat b/scons-3.1.0.bat
deleted file mode 100644
index 42c44c2..0000000
--- a/scons-3.1.0.bat
+++ /dev/null
@@ -1,38 +0,0 @@
-@REM Copyright (c) 2001 - 2019 The SCons Foundation
-@REM src/script/scons.bat e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 
00:04:47 bdeegan
-@echo off
-set SCONS_ERRORLEVEL=
-if "%OS%" == "Windows_NT" goto WinNT
-
-@REM for 9x/Me you better not have more than 9 args
-python -c "from os.path import join; import sys; sys.path = [ join(sys.prefix, 
'Lib', 'site-packages', 'scons-3.1.0'), join(sys.prefix, 'Lib', 
'site-packages', 'scons'), join(sys.prefix, 'scons-3.1.0'), join(sys.prefix, 
'scons')] + sys.path; import SCons.Script; SCons.Script.main()" %1 %2 %3 %4 %5 
%6 %7 %8 %9
-@REM no way to set exit status of this script for 9x/Me
-goto endscons
-
-@REM Credit where credit is due:  we return the exit code despite our
-@REM use of setlocal+endlocal using a technique from Bear's Journal:
-@REM 
http://code-bear.com/bearlog/2007/06/01/getting-the-exit-code-from-a-batch-file-that-is-run-from-a-python-program/
-
-:WinNT
-setlocal
-@REM ensure the script will be executed with the Python it was installed for
-pushd %~dp0..
-set path=%~dp0;%CD%;%path%
-popd
-@REM try the script named as the .bat file in current dir, then in Scripts 
subdir
-set scriptname=%~dp0%~n0.py
-if not exist "%scriptname%" set scriptname=%~dp0Scripts\%~n0.py
-@REM Handle when running from wheel where the script has no .py extension
-if not exist "%scriptname%" set scriptname=%~dp0%~n0
-python "%scriptname%" %*
-endlocal & set SCONS_ERRORLEVEL=%ERRORLEVEL%
-
-if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto returncode
-if errorlevel 9009 echo you do not have python in your PATH
-goto endscons
-
-:returncode
-exit /B %SCONS_ERRORLEVEL%
-
-:endscons
-call :returncode %SCONS_ERRORLEVEL%

diff --git a/scons-configure-cache b/scons-configure-cache
deleted file mode 100644
index 757a79f..0000000
--- a/scons-configure-cache
+++ /dev/null
@@ -1,178 +0,0 @@
-#! /usr/bin/env python
-#
-# SCons - a Software Constructor
-#
-# Copyright (c) 2001 - 2019 The SCons Foundation
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-'''Show or convert the configuration of an SCons cache directory.
-
-A cache of derived files is stored by file signature.
-The files are split into directories named by the first few
-digits of the signature. The prefix length used for directory
-names can be changed by this script.
-'''
-
-from __future__ import print_function
-import argparse
-import glob
-import json
-import os
-
-__revision__ = "src/script/scons-configure-cache.py 
e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 00:04:47 bdeegan"
-
-__version__ = "3.1.0"
-
-__build__ = "e724ae812eb96f4858a132f5b8c769724744faf6"
-
-__buildsys__ = "kufra"
-
-__date__ = "2019-07-21 00:04:47"
-
-__developer__ = "bdeegan"
-
-
-def rearrange_cache_entries(current_prefix_len, new_prefix_len):
-    '''Move cache files if prefix length changed.
-
-    Move the existing cache files to new directories of the
-    appropriate name length and clean up the old directories.
-    '''
-    print('Changing prefix length from', current_prefix_len,
-          'to', new_prefix_len)
-    dirs = set()
-    old_dirs = set()
-    for file in glob.iglob(os.path.join('*', '*')):
-        name = os.path.basename(file)
-        dname = name[:current_prefix_len].upper()
-        if dname not in old_dirs:
-            print('Migrating', dname)
-            old_dirs.add(dname)
-        dname = name[:new_prefix_len].upper()
-        if dname not in dirs:
-            os.mkdir(dname)
-            dirs.add(dname)
-        os.rename(file, os.path.join(dname, name))
-
-    # Now delete the original directories
-    for dname in old_dirs:
-        os.rmdir(dname)
-
-
-# The configuration dictionary should have one entry per entry in the
-# cache config. The value of each entry should include the following:
-#   implicit - (optional) This is to allow adding a new config entry and also
-#              changing the behaviour of the system at the same time. This
-#              indicates the value the config entry would have had if it had
-#              been specified.
-#   default - The value the config entry should have if it wasn't previously
-#             specified
-#   command-line - parameters to pass to ArgumentParser.add_argument
-#   converter - (optional) Function to call if conversion is required
-#               if this configuration entry changes
-config_entries = {
-    'prefix_len': {
-        'implicit': 1,
-        'default': 2,
-        'command-line': {
-            'help': 'Length of cache file name used as subdirectory prefix',
-            'metavar': '<number>',
-            'type': int
-        },
-        'converter': rearrange_cache_entries
-    }
-}
-
-parser = argparse.ArgumentParser(
-    description='Modify the configuration of an scons cache directory',
-    epilog='''
-           Unspecified options will not be changed unless they are not
-           set at all, in which case they are set to an appropriate default.
-           ''')
-
-parser.add_argument('cache-dir', help='Path to scons cache directory')
-for param in config_entries:
-    parser.add_argument('--' + param.replace('_', '-'),
-                        **config_entries[param]['command-line'])
-parser.add_argument('--version',
-                    action='version',
-                    version='%(prog)s 1.0')
-parser.add_argument('--show',
-                    action="store_true",
-                    help="show current configuration")
-
-# Get the command line as a dict without any of the unspecified entries.
-args = dict([x for x in vars(parser.parse_args()).items() if x[1]])
-
-# It seems somewhat strange to me, but positional arguments don't get the -
-# in the name changed to _, whereas optional arguments do...
-cache = args['cache-dir']
-if not os.path.isdir(cache):
-    raise RuntimeError("There is no cache directory named %s" % cache)
-os.chdir(cache)
-del args['cache-dir']
-
-if not os.path.exists('config'):
-    # old config dirs did not have a 'config' file. Try to update.
-    # Validate the only files in the directory are directories 0-9, a-f
-    expected = ['{:X}'.format(x) for x in range(0, 16)]
-    if not set(os.listdir('.')).issubset(expected):
-        raise RuntimeError(
-            "%s does not look like a valid version 1 cache directory" % cache)
-    config = dict()
-else:
-    with open('config') as conf:
-        config = json.load(conf)
-
-if args.get('show', None):
-    print("Current configuration in '%s':" % cache)
-    print(json.dumps(config, sort_keys=True,
-                     indent=4, separators=(',', ': ')))
-    # in case of the show argument, emit some stats as well
-    file_count = 0
-    for _, _, files in os.walk('.'):
-        file_count += len(files)
-    if file_count:  # skip config file if it exists
-        file_count -= 1
-    print("Cache contains %s files" % file_count)
-    del args['show']
-
-# Find any keys that are not currently set but should be
-for key in config_entries:
-    if key not in config:
-        if 'implicit' in config_entries[key]:
-            config[key] = config_entries[key]['implicit']
-        else:
-            config[key] = config_entries[key]['default']
-        if key not in args:
-            args[key] = config_entries[key]['default']
-
-# Now go through each entry in args to see if it changes an existing config
-# setting.
-for key in args:
-    if args[key] != config[key]:
-        if 'converter' in config_entries[key]:
-            config_entries[key]['converter'](config[key], args[key])
-        config[key] = args[key]
-
-# and write the updated config file
-with open('config', 'w') as conf:
-    json.dump(config, conf)

diff --git a/scons-configure-cache-3.1.0 b/scons-configure-cache-3.1.0
deleted file mode 100644
index 757a79f..0000000
--- a/scons-configure-cache-3.1.0
+++ /dev/null
@@ -1,178 +0,0 @@
-#! /usr/bin/env python
-#
-# SCons - a Software Constructor
-#
-# Copyright (c) 2001 - 2019 The SCons Foundation
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-'''Show or convert the configuration of an SCons cache directory.
-
-A cache of derived files is stored by file signature.
-The files are split into directories named by the first few
-digits of the signature. The prefix length used for directory
-names can be changed by this script.
-'''
-
-from __future__ import print_function
-import argparse
-import glob
-import json
-import os
-
-__revision__ = "src/script/scons-configure-cache.py 
e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 00:04:47 bdeegan"
-
-__version__ = "3.1.0"
-
-__build__ = "e724ae812eb96f4858a132f5b8c769724744faf6"
-
-__buildsys__ = "kufra"
-
-__date__ = "2019-07-21 00:04:47"
-
-__developer__ = "bdeegan"
-
-
-def rearrange_cache_entries(current_prefix_len, new_prefix_len):
-    '''Move cache files if prefix length changed.
-
-    Move the existing cache files to new directories of the
-    appropriate name length and clean up the old directories.
-    '''
-    print('Changing prefix length from', current_prefix_len,
-          'to', new_prefix_len)
-    dirs = set()
-    old_dirs = set()
-    for file in glob.iglob(os.path.join('*', '*')):
-        name = os.path.basename(file)
-        dname = name[:current_prefix_len].upper()
-        if dname not in old_dirs:
-            print('Migrating', dname)
-            old_dirs.add(dname)
-        dname = name[:new_prefix_len].upper()
-        if dname not in dirs:
-            os.mkdir(dname)
-            dirs.add(dname)
-        os.rename(file, os.path.join(dname, name))
-
-    # Now delete the original directories
-    for dname in old_dirs:
-        os.rmdir(dname)
-
-
-# The configuration dictionary should have one entry per entry in the
-# cache config. The value of each entry should include the following:
-#   implicit - (optional) This is to allow adding a new config entry and also
-#              changing the behaviour of the system at the same time. This
-#              indicates the value the config entry would have had if it had
-#              been specified.
-#   default - The value the config entry should have if it wasn't previously
-#             specified
-#   command-line - parameters to pass to ArgumentParser.add_argument
-#   converter - (optional) Function to call if conversion is required
-#               if this configuration entry changes
-config_entries = {
-    'prefix_len': {
-        'implicit': 1,
-        'default': 2,
-        'command-line': {
-            'help': 'Length of cache file name used as subdirectory prefix',
-            'metavar': '<number>',
-            'type': int
-        },
-        'converter': rearrange_cache_entries
-    }
-}
-
-parser = argparse.ArgumentParser(
-    description='Modify the configuration of an scons cache directory',
-    epilog='''
-           Unspecified options will not be changed unless they are not
-           set at all, in which case they are set to an appropriate default.
-           ''')
-
-parser.add_argument('cache-dir', help='Path to scons cache directory')
-for param in config_entries:
-    parser.add_argument('--' + param.replace('_', '-'),
-                        **config_entries[param]['command-line'])
-parser.add_argument('--version',
-                    action='version',
-                    version='%(prog)s 1.0')
-parser.add_argument('--show',
-                    action="store_true",
-                    help="show current configuration")
-
-# Get the command line as a dict without any of the unspecified entries.
-args = dict([x for x in vars(parser.parse_args()).items() if x[1]])
-
-# It seems somewhat strange to me, but positional arguments don't get the -
-# in the name changed to _, whereas optional arguments do...
-cache = args['cache-dir']
-if not os.path.isdir(cache):
-    raise RuntimeError("There is no cache directory named %s" % cache)
-os.chdir(cache)
-del args['cache-dir']
-
-if not os.path.exists('config'):
-    # old config dirs did not have a 'config' file. Try to update.
-    # Validate the only files in the directory are directories 0-9, a-f
-    expected = ['{:X}'.format(x) for x in range(0, 16)]
-    if not set(os.listdir('.')).issubset(expected):
-        raise RuntimeError(
-            "%s does not look like a valid version 1 cache directory" % cache)
-    config = dict()
-else:
-    with open('config') as conf:
-        config = json.load(conf)
-
-if args.get('show', None):
-    print("Current configuration in '%s':" % cache)
-    print(json.dumps(config, sort_keys=True,
-                     indent=4, separators=(',', ': ')))
-    # in case of the show argument, emit some stats as well
-    file_count = 0
-    for _, _, files in os.walk('.'):
-        file_count += len(files)
-    if file_count:  # skip config file if it exists
-        file_count -= 1
-    print("Cache contains %s files" % file_count)
-    del args['show']
-
-# Find any keys that are not currently set but should be
-for key in config_entries:
-    if key not in config:
-        if 'implicit' in config_entries[key]:
-            config[key] = config_entries[key]['implicit']
-        else:
-            config[key] = config_entries[key]['default']
-        if key not in args:
-            args[key] = config_entries[key]['default']
-
-# Now go through each entry in args to see if it changes an existing config
-# setting.
-for key in args:
-    if args[key] != config[key]:
-        if 'converter' in config_entries[key]:
-            config_entries[key]['converter'](config[key], args[key])
-        config[key] = args[key]
-
-# and write the updated config file
-with open('config', 'w') as conf:
-    json.dump(config, conf)

diff --git a/scons.bat b/scons.bat
deleted file mode 100644
index 42c44c2..0000000
--- a/scons.bat
+++ /dev/null
@@ -1,38 +0,0 @@
-@REM Copyright (c) 2001 - 2019 The SCons Foundation
-@REM src/script/scons.bat e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 
00:04:47 bdeegan
-@echo off
-set SCONS_ERRORLEVEL=
-if "%OS%" == "Windows_NT" goto WinNT
-
-@REM for 9x/Me you better not have more than 9 args
-python -c "from os.path import join; import sys; sys.path = [ join(sys.prefix, 
'Lib', 'site-packages', 'scons-3.1.0'), join(sys.prefix, 'Lib', 
'site-packages', 'scons'), join(sys.prefix, 'scons-3.1.0'), join(sys.prefix, 
'scons')] + sys.path; import SCons.Script; SCons.Script.main()" %1 %2 %3 %4 %5 
%6 %7 %8 %9
-@REM no way to set exit status of this script for 9x/Me
-goto endscons
-
-@REM Credit where credit is due:  we return the exit code despite our
-@REM use of setlocal+endlocal using a technique from Bear's Journal:
-@REM 
http://code-bear.com/bearlog/2007/06/01/getting-the-exit-code-from-a-batch-file-that-is-run-from-a-python-program/
-
-:WinNT
-setlocal
-@REM ensure the script will be executed with the Python it was installed for
-pushd %~dp0..
-set path=%~dp0;%CD%;%path%
-popd
-@REM try the script named as the .bat file in current dir, then in Scripts 
subdir
-set scriptname=%~dp0%~n0.py
-if not exist "%scriptname%" set scriptname=%~dp0Scripts\%~n0.py
-@REM Handle when running from wheel where the script has no .py extension
-if not exist "%scriptname%" set scriptname=%~dp0%~n0
-python "%scriptname%" %*
-endlocal & set SCONS_ERRORLEVEL=%ERRORLEVEL%
-
-if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto returncode
-if errorlevel 9009 echo you do not have python in your PATH
-goto endscons
-
-:returncode
-exit /B %SCONS_ERRORLEVEL%
-
-:endscons
-call :returncode %SCONS_ERRORLEVEL%


https://bitbucket.org/nvdaaddonteam/placemarkers/commits/1ba80e8e1f96/
Changeset:   1ba80e8e1f96
Branch:      None
User:        norrumar
Date:        2019-11-24 02:55:31+00:00
Summary:     Update readme an version

Affected #:  2 files

diff --git a/buildVars.py b/buildVars.py
index 29d659f..c913773 100755
--- a/buildVars.py
+++ b/buildVars.py
@@ -19,7 +19,7 @@ addon_info = {
        # Translators: Long description to be shown for this add-on on add-on 
information from add-ons manager
        "addon_description" : _("Add-on for setting place markers on specific 
virtual documents"),
        # version
-       "addon_version" : "14.0-dev",
+       "addon_version" : "14.1-dev",
        # Author(s)
        "addon_author" : u"Noelia <nrm1977@xxxxxxxxx>, Chris 
<llajta2012@xxxxxxxxx>",
        # URL for the add-on documentation support

diff --git a/readme.md b/readme.md
index ed1dedd..d976ed6 100644
--- a/readme.md
+++ b/readme.md
@@ -37,6 +37,7 @@ Note: The bookmark position is based on the number of 
characters; and therefore
 
 ## Changes for 14.0 ##
 *      The command to copy the name of the file where place markers data will 
be saved has been replaced by a command which shows this file name in browse 
mode. This is not assigned to a gesture.
+*      The "Text to search" field does not overlap the "Saved text" field 
anymore. (Thanks to Cyrille Bougot).
 *      Requires NVDA 2019.3 or later.
 
 ## Changes for 13.0 ##

Repository URL: https://bitbucket.org/nvdaaddonteam/placemarkers/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.


Other related posts: