Merge jv
authorMerge Script
Thu, 28 Apr 2016 06:55:28 +0200
branchjv
changeset 16336 57393d9e51b3
parent 16328 50099c2dbdb5 (current diff)
parent 16335 b1930f23f1a7 (diff)
child 16348 10a6bb733b5d
Merge
AbstractLauncherApplication.st
AbstractSettingsApplication.st
BrowserView.st
DiffTextView.st
SettingsDialog.st
Tools__BreakpointService.st
--- a/AbstractLauncherApplication.st	Wed Apr 27 06:50:59 2016 +0200
+++ b/AbstractLauncherApplication.st	Thu Apr 28 06:55:28 2016 +0200
@@ -35,7 +35,8 @@
 		alreadyLoadedString applicationIcon greyApplicationIcon root
 		itemsByPath getItemByPath myHierarchicalItemWithLabelAndIcon
 		filterHolder masterRoot infoTextHolder loadButton
-		loadAndBrowseButton selectedPackageHolder monticelloRoot'
+		loadAndBrowseButton selectedPackageHolder monticelloRoot
+		backgroundPackageFindProcess'
 	classVariableNames:'PreviousPackageDialogItems PreviousPackageDialogExtent'
 	poolDictionaries:''
 	privateIn:AbstractLauncherApplication
@@ -7156,6 +7157,29 @@
     self new openLoadPackageDialogModal:true
 ! !
 
+!AbstractLauncherApplication::PackageLoadDialog methodsFor:'initialize & release'!
+
+initializeIcons
+    folderIcon := ToolbarIconLibrary directoryOpen18x18Icon.
+    "/ folderHalfGreyIcon := ToolbarIconLibrary directoryOpenHalfGrey18x18Icon.
+    packageIcon := ToolbarIconLibrary packageOpen24x24Icon.
+    applicationIcon := ToolbarIconLibrary makeYellow22x22Icon1.
+    greyFolderIcon := folderIcon asGrayImageDepth:8.
+    greyPackageIcon := packageIcon asGrayImageDepth:8.
+    greyApplicationIcon := applicationIcon asGrayImageDepth:(applicationIcon depth min:8).
+!
+
+release
+    |p|
+    
+    (p := backgroundPackageFindProcess) notNil ifTrue:[
+        p isDead ifFalse:[
+            p terminate
+        ]
+    ].
+    super release
+! !
+
 !AbstractLauncherApplication::PackageLoadDialog methodsFor:'opening'!
 
 openLoadPackageDialog
@@ -7231,6 +7255,7 @@
     masterRoot add:monticelloRoot.
 
     self readPackageTree.
+    self readOtherPackageTreesInBackground.
     masterRoot expand.
     root expand.
     list root:masterRoot.
@@ -7292,6 +7317,7 @@
     ].
 
     browse := false.
+    dialog application:self.
     modal ifTrue:[
         dialog openModalAtPointer.
     ] ifFalse:[
@@ -7305,6 +7331,61 @@
 
 !AbstractLauncherApplication::PackageLoadDialog methodsFor:'private'!
 
+addItemWithPackagePath:path target:target asApplication:isApplication toRoot:aRoot
+    |item isAlreadyLoaded defClass packageID|
+
+    "/ see if already loaded
+
+    packageID := (path size > 1) 
+                    ifTrue:[ path first , ':' , ((path copyFrom:2) asStringWith:$/) ]
+                    ifFalse:[ path first ].
+
+    item := self getItemByPath:path packageID:packageID under:aRoot.
+
+    isAlreadyLoaded := false.
+    Error handle:[:ex |
+        item label:(item label , (' ERROR - please rebuild!!' colorizeAllWith:Color red)).
+    ] do:[    
+        isAlreadyLoaded := 
+            (defClass := ProjectDefinition definitionClassForPackage:packageID) notNil
+            and:[ defClass isLoaded
+            and:[ defClass isFullyLoaded ]].
+    ].
+
+    target notNil ifTrue:[
+        ((target startsWith:'lib ') or:[(target startsWith:'app ')]) ifTrue:[
+            pathByItem at:item put:(target copyFrom:(target indexOfSeparator + 1)) withoutSeparators.
+        ].
+    ].
+
+    "/ do not overwrite an app by a lib with the same name (happens in expecco/application)
+    (isApplication or:[ item icon isNil or:[item icon == folderIcon or:[item icon == greyFolderIcon]]]) ifTrue:[
+        isAlreadyLoaded ifTrue:[
+            item icon:(isApplication ifTrue:[greyApplicationIcon] ifFalse:[greyPackageIcon]). 
+            item label:(item label , alreadyLoadedString)
+        ] ifFalse:[
+            item icon:(isApplication ifTrue:[applicationIcon] ifFalse:[packageIcon]). 
+        ].
+    ].
+
+    "/ if it is not already loaded, make all parents non-grey
+    isAlreadyLoaded ifFalse:[
+        path size-1 to:1 by:-1 do:[:n |
+            |parentPath parentItem|
+
+            parentPath := path copyTo:n.
+            parentItem := self getItemByPath:parentPath packageID:packageID under:aRoot.
+            parentItem icon == greyFolderIcon ifTrue:[
+                parentItem icon:folderIcon.
+"/                        ] ifFalse:[
+"/                            parentItem icon == greyApplicationIcon ifTrue:[
+"/                                parentItem icon:applicationIcon.
+"/                            ].
+            ].
+        ]
+    ].
+!
+
 filterChangedAction
     |matchingItems filterPattern isMatch firstMatchingItem|
 
@@ -7356,23 +7437,23 @@
     ].
 !
 
-getItemByPath:path packageID:packageID
+getItemByPath:path packageID:packageID under:aRoot
     "/ ensures an item for a path and returns it.
     "/ if not already present, the item is created as a folder
 
     |item parent subPackageID|
 
     item := path isEmpty   
-            ifTrue:[root]
-            ifFalse:[ itemsByPath at:path ifAbsent:nil ].
+            ifTrue:[aRoot]
+            ifFalse:[ itemsByPath at:( {aRoot label},path) ifAbsent:nil ].
     item isNil ifTrue:[
-        parent := self getItemByPath:(path copyButLast) packageID:packageID.
+        parent := self getItemByPath:(path copyButLast) packageID:packageID under:aRoot.
         item := myHierarchicalItemWithLabelAndIcon new
                 children:#();
                 icon:greyFolderIcon; 
                 label:path last.
         parent add:item.
-        itemsByPath at:path put:item.
+        itemsByPath at:( {aRoot label},path) put:item.
         subPackageID := path size > 1 
                         ifTrue:[ path first , ':' , ((path copyFrom:2) asStringWith:$/) ]
                         ifFalse:[ path first ].
@@ -7406,16 +7487,6 @@
             ].
 !
 
-initializeIcons
-    folderIcon := ToolbarIconLibrary directoryOpen18x18Icon.
-    "/ folderHalfGreyIcon := ToolbarIconLibrary directoryOpenHalfGrey18x18Icon.
-    packageIcon := ToolbarIconLibrary packageOpen24x24Icon.
-    applicationIcon := ToolbarIconLibrary makeYellow22x22Icon1.
-    greyFolderIcon := folderIcon asGrayImageDepth:8.
-    greyPackageIcon := packageIcon asGrayImageDepth:8.
-    greyApplicationIcon := applicationIcon asGrayImageDepth:(applicationIcon depth min:8).
-!
-
 itemMenu
     |item m itemType package defClass|
 
@@ -7444,7 +7515,7 @@
                             ]
                         enabled:package notNil).
             m addItem:(MenuItem 
-                        label: (resources string:'Load with All SubPackages')
+                        label: (resources string:'Load with All Subpackages')
                         itemValue: 
                             [
                                 package notNil ifTrue:[
@@ -7593,6 +7664,148 @@
     ].
 !
 
+readOtherPackageTrees
+    |packagePath|
+    
+    packagePath := Smalltalk packagePath.
+    packagePath do:[:eachDirName |
+        |folderRoot eachDir|
+        
+        eachDir := eachDirName asFilename.
+        selectedPackageHolder value isNil ifTrue:[
+            infoTextHolder value:('searching %1...' bindWith:eachDirName).
+        ].    
+        eachDir
+            recursiveDirectoryContentsWithPrefix:'' 
+            filesDo:nil 
+            directoriesDo:[:subDir |
+                |dfnBasename expectedDfnFilename|
+
+                (eachDir /  subDir / 'abbrev.stc') exists ifTrue:[
+                    "/ see if there is a project definition file in this dir
+                    dfnBasename := subDir copyReplaceAll:(Filename separator) with:$_.
+                    expectedDfnFilename := (eachDir /  subDir / dfnBasename) withSuffix:'st'.
+                    expectedDfnFilename exists ifTrue:[
+                        |path|
+                        
+                        path := subDir asFilename components.
+                        (itemsByPath at:( {root label},path) ifAbsent:nil) isNil ifTrue:[
+                            folderRoot isNil ifTrue:[
+                                folderRoot := myHierarchicalItemWithLabelAndIcon new.
+                                folderRoot icon:folderIcon.
+                                folderRoot label:((resources string:'[%1]' with:eachDirName) asText allItalic colorizeAllWith:Color grey).
+                                folderRoot type:#compiledPackagesRoot.
+                            ].    
+                            self 
+                                addItemWithPackagePath:path
+                                target:nil
+                                asApplication:false
+                                toRoot:folderRoot.
+                        ].
+                    ]
+                ].
+            ].
+        folderRoot notNil ifTrue:[
+            masterRoot add:folderRoot.
+        ].
+    ].
+    selectedPackageHolder value isNil ifTrue:[
+        infoTextHolder value:('done searching other package folders.').
+    ].    
+    
+"/    packageDirPath isNil ifTrue:[
+"/        root label:root label,((resources string:' (no "packages" folder found)') colorizeAllWith:Color red).
+"/    ] ifFalse:[
+"/        packageDirPath asFilename directoryContentsAsFilenames sort do:[:fn |
+"/            |item base nm path parentPath parent isLibrary isApplication isAlreadyLoaded 
+"/             defClass target packageID|
+"/
+"/            ((fn suffix = 'mcz') 
+"/            or:[ fn isDirectory   
+"/            or:[ (fn baseName startsWith:'.')   
+"/            or:[ (fn baseName = 'README') ]]]) ifFalse:[    
+"/                base := fn withoutSuffix baseName.
+"/                (base startsWith:'lib') ifTrue:[
+"/                    nm := (base copyFrom:4).
+"/                    fn suffix notEmptyOrNil ifTrue:[
+"/                        isLibrary := true.
+"/                        isApplication := false.
+"/                    ] ifFalse:[
+"/                        isLibrary := false.
+"/                        isApplication := true.
+"/                    ]
+"/                ] ifFalse:[
+"/                    nm := base.
+"/                    isLibrary := false.
+"/                    isApplication := true.
+"/                ].
+"/
+"/                path := nm asCollectionOfSubstringsSeparatedBy:$_.
+"/                "/ see if already loaded
+"/
+"/                packageID := (path size > 1) 
+"/                                ifTrue:[ path first , ':' , ((path copyFrom:2) asStringWith:$/) ]
+"/                                ifFalse:[ path first ].
+"/
+"/                item := self getItemByPath:path packageID:packageID.
+"/
+"/                isAlreadyLoaded := false.
+"/                Error handle:[:ex |
+"/                    item label:(item label , (' ERROR - please rebuild!!' colorizeAllWith:Color red)).
+"/                ] do:[    
+"/                    isAlreadyLoaded := 
+"/                        (defClass := ProjectDefinition definitionClassForPackage:packageID) notNil
+"/                        and:[ defClass isLoaded
+"/                        and:[ defClass isFullyLoaded ]].
+"/                ].
+"/
+"/                target := fn contents first.
+"/                ((target startsWith:'lib ') or:[(target startsWith:'app ')]) ifTrue:[
+"/                    pathByItem at:item put:(target copyFrom:(target indexOfSeparator + 1)) withoutSeparators.
+"/                ].
+"/
+"/                "/ do not overwrite an app by a lib with the same name (happens in expecco/application)
+"/                (isApplication or:[ item icon isNil or:[item icon == folderIcon or:[item icon == greyFolderIcon]]]) ifTrue:[
+"/                    isAlreadyLoaded ifTrue:[
+"/                        item icon:(isApplication ifTrue:[greyApplicationIcon] ifFalse:[greyPackageIcon]). 
+"/                        item label:(item label , alreadyLoadedString)
+"/                    ] ifFalse:[
+"/                        item icon:(isApplication ifTrue:[applicationIcon] ifFalse:[packageIcon]). 
+"/                    ].
+"/                ].
+"/
+"/                "/ if it is not already loaded, make all parents non-grey
+"/                isAlreadyLoaded ifFalse:[
+"/                    path size-1 to:1 by:-1 do:[:n |
+"/                        |parentPath parentItem|
+"/
+"/                        parentPath := path copyTo:n.
+"/                        parentItem := self getItemByPath:parentPath packageID:packageID.
+"/                        parentItem icon == greyFolderIcon ifTrue:[
+"/                            parentItem icon:folderIcon.
+"/"/                        ] ifFalse:[
+"/"/                            parentItem icon == greyApplicationIcon ifTrue:[
+"/"/                                parentItem icon:applicationIcon.
+"/"/                            ].
+"/                        ].
+"/                    ]
+"/                ].
+"/            ].
+"/        ].
+"/    ].
+!
+
+readOtherPackageTreesInBackground
+    backgroundPackageFindProcess := 
+        [
+            [
+                self readOtherPackageTrees.
+            ] ensure:[
+                backgroundPackageFindProcess := nil.
+            ].    
+        ] forkAt:(Processor userBackgroundPriority).    
+!
+
 readPackageTree
     packageDirPath := Smalltalk getSystemFileName:'packages'.
     packageDirPath isNil ifTrue:[
@@ -7623,6 +7836,14 @@
                 ].
 
                 path := nm asCollectionOfSubstringsSeparatedBy:$_.
+                target := fn contents first.
+
+                self 
+                    addItemWithPackagePath:path 
+                    target:target 
+                    asApplication:isApplication 
+                    toRoot:root.
+false ifTrue:[
                 "/ see if already loaded
 
                 packageID := (path size > 1) 
@@ -7641,7 +7862,6 @@
                         and:[ defClass isFullyLoaded ]].
                 ].
 
-                target := fn contents first.
                 ((target startsWith:'lib ') or:[(target startsWith:'app ')]) ifTrue:[
                     pathByItem at:item put:(target copyFrom:(target indexOfSeparator + 1)) withoutSeparators.
                 ].
@@ -7672,6 +7892,7 @@
                         ].
                     ]
                 ].
+].
             ].
         ].
     ].
@@ -7791,7 +8012,7 @@
     (whatChanged == #postPackageLoad or:[whatChanged == #postLoad]) ifTrue:[
         parameter notNil ifTrue:[
             packageID := parameter asSymbol.
-            item := self getItemByPath:(packageID splitByAny:':/') packageID:packageID.
+            item := self getItemByPath:(packageID splitByAny:':/') packageID:packageID under:root.
             item notNil ifTrue:[
                 isLoaded := (ProjectDefinition definitionClassForPackage:packageID) notNil.
                 isLoaded ifTrue:[
--- a/AbstractSettingsApplication.st	Wed Apr 27 06:50:59 2016 +0200
+++ b/AbstractSettingsApplication.st	Thu Apr 28 06:55:28 2016 +0200
@@ -242,6 +242,13 @@
 	privateIn:AbstractSettingsApplication
 !
 
+AbstractSettingsApplication subclass:#PackagePathSettingsAppl
+	instanceVariableNames:'listOfFoldersInPath selectedFolder'
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:AbstractSettingsApplication
+!
+
 AbstractSettingsApplication subclass:#PrinterSettingsAppl
 	instanceVariableNames:'selectedUnit supportsColor topMargin rightMargin bottomMargin
 		landscape pageFormatList pageFormat unitList leftMargin
@@ -442,7 +449,7 @@
     For a real settings dialog, you need a concrete settings dialog class to hold the pages
     (as an example, see SettingsDialog)
     and someone who specifies the hierarchy of settings-pages in a spec.
-    (as an example, see NewLauncher class>>defaultSettingsApplicationList)
+    (as an example, see SettingsDialog class>>defaultSettingsApplicationList)
 
     typical use:
 
@@ -1324,7 +1331,8 @@
     <resource: #help>
 
     ^ super flyByHelpSpec addPairsFrom:#(
-
+#autoloadedPackages
+'Select known packages from the left list, and click on ">>>" to add them to the autoloaded list.\These will be automatically loaded when ST/X is started without a snapshot image.\Packages are searched along the packagePath.'
 
 )
 ! !
@@ -1359,8 +1367,8 @@
        name: windowSpec
        window: 
       (WindowSpec
-         label: 'Memory Manager Settings'
-         name: 'Memory Manager Settings'
+         label: 'Autoloaded Packages Settings'
+         name: 'Autoloaded Packages Settings'
          min: (Point 10 10)
          bounds: (Rectangle 0 0 705 722)
        )
@@ -1373,6 +1381,7 @@
              layout: (LayoutFrame 0 0 0 0 0 1 0 1)
              labelPosition: topLeft
              translateLabel: true
+             activeHelpKey: autoloadedPackages
              component: 
             (SpecCollection
                collection: (
@@ -3376,8 +3385,8 @@
        name: windowSpec
        window:
       (WindowSpec
-         label: 'Tool Settings'
-         name: 'Tool Settings'
+         label: 'Code Generator Settings'
+         name: 'Code Generator Settings'
          min: (Point 10 10)
          bounds: (Rectangle 0 0 607 786)
        )
@@ -5945,6 +5954,8 @@
 createServerApplicationFor:aServerInstance
     |settingsApp itemPathName newItem openApps|
 
+    "/ settingsDialog isNil ifTrue:[^ self].
+    
     openApps := settingsDialog getAllChildrenAppsForApplication:self childrenClass:HTTPServerSettingsAppl.
     (openApps contains:[:app | app httpServerInstance == aServerInstance]) ifTrue:[
         " already have an Item for this application "
@@ -5959,15 +5970,15 @@
     ].
 
     settingsApp := HTTPServerSettingsAppl basicNew.
-    settingsApp settingsDialog:self settingsDialog.
+    settingsApp settingsDialog:settingsDialog.
     settingsApp httpServerInstance:aServerInstance.
     settingsApp defaultSettingsApplication:false.
     settingsApp basicInitialize.
     itemPathName := self itemPathName , '/', settingsApp nameInSettingsDialog.
-    newItem := self settingsDialog addApplClass:#'HTTPServerSettingsAppl' withName:itemPathName.
+    newItem := settingsDialog addApplClass:#'HTTPServerSettingsAppl' withName:itemPathName.
     newItem application:settingsApp.
     self createdServerChanged.
-    self settingsDialog expandItemForApplication:self.
+    settingsDialog expandItemForApplication:self.
     settingsApp readSettings.
     settingsApp initialize.
 
@@ -6084,6 +6095,8 @@
 !
 
 removeAllServerSubApplications
+    "/ settingsDialog isNil ifTrue:[^ self].
+ 
     settingsDialog removeAllSubApplicationsFor:self
 !
 
@@ -6104,6 +6117,8 @@
 setPortOnFreePort
     |serverClass highestUsedPortNr portToUse instances|
 
+    "/ settingsDialog isNil ifTrue:[^ self].
+
     serverClass := self serverClass.
     (serverClass notNil and:[serverClass isLoaded]) ifTrue:[
         instances := serverClass runningServers asNewSet.
@@ -6227,6 +6242,7 @@
 !AbstractSettingsApplication::HTTPStartServerSettingsApplication methodsFor:'queries'!
 
 hasCreatedServer
+    "/ settingsDialog isNil ifTrue:[^ false].
     ^ (settingsDialog getAllChildrenAppsForApplication:self childrenClass:HTTPServerSettingsAppl)
         notEmpty
 !
@@ -11284,6 +11300,192 @@
         self osiCMISEMessageLogging value ~= OSI::CMISE messageLogging]]])
 ! !
 
+!AbstractSettingsApplication::PackagePathSettingsAppl class methodsFor:'help specs'!
+
+flyByHelpSpec
+    "This resource specification was automatically generated
+     by the UIHelpTool of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIHelpTool may not be able to read the specification."
+
+    "
+     UIHelpTool openOnClass:AbstractSettingsApplication::MemorySettingsAppl    
+    "
+
+    <resource: #help>
+
+    ^ super flyByHelpSpec addPairsFrom:#(
+
+
+)
+! !
+
+!AbstractSettingsApplication::PackagePathSettingsAppl class methodsFor:'image specs'!
+
+defaultIcon
+    <resource: #programImage>
+
+    ^ ToolbarIconLibrary packageOpen24x24Icon 
+! !
+
+!AbstractSettingsApplication::PackagePathSettingsAppl class methodsFor:'interface specs'!
+
+windowSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:AbstractSettingsApplication::PackagePathSettingsAppl andSelector:#windowSpec
+     AbstractSettingsApplication::PackagePathSettingsAppl new openInterface:#windowSpec
+     AbstractSettingsApplication::PackagePathSettingsAppl open
+    "
+
+    <resource: #canvas>
+
+    ^ 
+    #(FullSpec
+       name: windowSpec
+       window: 
+      (WindowSpec
+         label: 'Package Path Settings'
+         name: 'Package Path Settings'
+         min: (Point 10 10)
+         bounds: (Rectangle 0 0 659 287)
+       )
+       component: 
+      (SpecCollection
+         collection: (
+          (FramedBoxSpec
+             label: 'Package Path'
+             name: 'FramedBox1'
+             layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+             labelPosition: topLeft
+             translateLabel: true
+             component: 
+            (SpecCollection
+               collection: (
+                (LabelSpec
+                   label: 'Folders in Package Path'
+                   name: 'Label1'
+                   layout: (LayoutFrame 0 0.0 10 0 0 1.0 40 0)
+                   translateLabel: true
+                 )
+                (SequenceViewSpec
+                   name: 'List1'
+                   layout: (LayoutFrame 0 0 40 0 0 1 -40 1)
+                   model: selectedFolder
+                   hasHorizontalScrollBar: true
+                   hasVerticalScrollBar: true
+                   useIndex: false
+                   sequenceList: listOfFoldersInPath
+                 )
+                (HorizontalPanelViewSpec
+                   name: 'HorizontalPanel1'
+                   layout: (LayoutFrame 0 0.0 -36 1 0 1.0 4 1)
+                   horizontalLayout: right
+                   verticalLayout: center
+                   horizontalSpace: 3
+                   verticalSpace: 3
+                   component: 
+                  (SpecCollection
+                     collection: (
+                      (ActionButtonSpec
+                         label: 'Add...'
+                         name: 'Button1'
+                         translateLabel: true
+                         model: addFolder
+                         extent: (Point 93 31)
+                         usePreferredWidth: true
+                         usePreferredHeight: true
+                       )
+                      (ActionButtonSpec
+                         label: 'Remove Selected'
+                         name: 'Button2'
+                         translateLabel: true
+                         model: removeSelectedFolder
+                         extent: (Point 144 31)
+                         usePreferredWidth: true
+                         usePreferredHeight: true
+                       )
+                      )
+                    
+                   )
+                 )
+                )
+              
+             )
+           )
+          )
+        
+       )
+     )
+! !
+
+!AbstractSettingsApplication::PackagePathSettingsAppl methodsFor:'actions'!
+
+addFolder
+    |folder|
+
+    folder := Dialog requestDirectoryName:'Additional Folder with Packages:'.
+    folder isEmptyOrNil ifTrue:[^ self].
+    (self listOfFoldersInPath includes:folder) ifFalse:[
+        self listOfFoldersInPath add:folder.
+        self updateModifiedChannel.
+    ].
+!
+
+basicReadSettings
+    self listOfFoldersInPath contents:(Smalltalk packagePath).
+!
+
+basicSaveSettings
+    Smalltalk packagePath:(self listOfFoldersInPath asOrderedCollection).
+!
+
+removeSelectedFolder
+    self listOfFoldersInPath remove:(self selectedFolder value) ifAbsent:[].
+    self updateModifiedChannel.
+! !
+
+!AbstractSettingsApplication::PackagePathSettingsAppl methodsFor:'aspects'!
+
+aspects
+    ^ #(
+    )
+!
+
+listOfFoldersInPath 
+    listOfFoldersInPath isNil ifTrue:[
+        listOfFoldersInPath := List new.
+        listOfFoldersInPath addAll:Smalltalk packagePath
+    ].    
+    ^ listOfFoldersInPath
+!
+
+selectedFolder 
+    selectedFolder isNil ifTrue:[
+        selectedFolder := nil asValue.
+    ].    
+    ^ selectedFolder
+! !
+
+!AbstractSettingsApplication::PackagePathSettingsAppl methodsFor:'help'!
+
+helpFilename
+    ^ 'Launcher/packagePathSettings.html'
+! !
+
+!AbstractSettingsApplication::PackagePathSettingsAppl methodsFor:'queries'!
+
+hasUnsavedChanges
+    self listOfFoldersInPath asOrderedCollection ~= Smalltalk packagePath asOrderedCollection ifTrue:[^ true].
+    ^ false.
+! !
+
 !AbstractSettingsApplication::PrinterSettingsAppl class methodsFor:'image specs'!
 
 defaultIcon
@@ -19297,8 +19499,8 @@
        name: windowSpec
        window: 
       (WindowSpec
-         label: 'Editor Settings'
-         name: 'Editor Settings'
+         label: 'Terminalview Settings'
+         name: 'Terminalview Settings'
          flags: 1
          min: (Point 10 10)
          bounds: (Rectangle 0 0 658 543)
--- a/BrowserView.st	Wed Apr 27 06:50:59 2016 +0200
+++ b/BrowserView.st	Thu Apr 28 06:55:28 2016 +0200
@@ -8302,7 +8302,7 @@
     ].
 
     box := self listBoxTitle:title 
-                      okText:'Ok' 
+                      okText:'OK' 
                         list:(environment allClasses collect:[:cls | cls name]) asArray sort.
 
     box label:(resources string:'Copy methods').
--- a/DiffTextView.st	Wed Apr 27 06:50:59 2016 +0200
+++ b/DiffTextView.st	Thu Apr 28 06:55:28 2016 +0200
@@ -600,7 +600,8 @@
 
     |container vScroller thumb|
 
-    (container := self container) isScrollWrapper ifTrue:[
+    ((container := self container) notNil
+    and:[container isScrollWrapper]) ifTrue:[
         (vScroller := container verticalScrollBar) notNil ifTrue:[
             (thumb := vScroller thumb) notNil ifTrue:[
                 thumb viewBackground:(DiffTextScrollerBackground new diffView:self).
--- a/SettingsDialog.st	Wed Apr 27 06:50:59 2016 +0200
+++ b/SettingsDialog.st	Thu Apr 28 06:55:28 2016 +0200
@@ -252,6 +252,7 @@
                 #('System/Memory'                              #'AbstractSettingsApplication::MemorySettingsAppl'              )
                 #('System/Processor & Scheduler'               #'AbstractSettingsApplication::ProcessorSchedulerSettingsAppl'  )
                 #('System/Autoloaded Packages'                 #'AbstractSettingsApplication::AutoloadedPackagesSettingsAppl'  )
+                #('System/Package Path'                 #'AbstractSettingsApplication::PackagePathSettingsAppl'  )
                 #('Tools'                               #'AbstractSettingsApplication::ToolsSettingsAppl'               )
                 #('Tools/Toolbox'                       #'AbstractSettingsApplication::ToolboxSettingsAppl'             )
                 #('Tools/Editor'                        #'AbstractSettingsApplication::EditSettingsAppl'                )
@@ -1620,10 +1621,11 @@
         ].
 
         item application:app.
+        app settingsDialog:self.
         app basicInitialize.
-        app settingsDialog:self.
     ].
     self withWaitCursorDo:[
+        app settingsDialog:self.
         app initialize.
         app readSettings.
     ].
--- a/Tools__BreakpointService.st	Wed Apr 27 06:50:59 2016 +0200
+++ b/Tools__BreakpointService.st	Thu Apr 28 06:55:28 2016 +0200
@@ -155,7 +155,7 @@
 The reason is that the method needs to be recompiled for the breakpoint, which would not affect the method being currently executed.
 
 You can proceed to set the breakpoint, but it will only affect the next call into this method, not the current invocation.'
-                        yesLabel:'Set Breakpoint for Next Call' noLabel:'Ok') ifTrue:[
+                        yesLabel:'Set Breakpoint for Next Call' noLabel:'OK') ifTrue:[
 "/ self halt.
                             ok := true.
                         ]