RDI 0.1.0.20091020

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. data/AUTHORS +3 -0
  2. data/ChangeLog +46 -0
  3. data/Credits +21 -0
  4. data/LICENSE +31 -0
  5. data/README +18 -0
  6. data/TODO +17 -0
  7. data/lib/rdi/Installer.rb +678 -0
  8. data/lib/rdi/Model/ContextModifier.rb +20 -0
  9. data/lib/rdi/Model/DependencyDescription.rb +154 -0
  10. data/lib/rdi/Model/DependencyUserChoice.rb +202 -0
  11. data/lib/rdi/Model/Installer.rb +24 -0
  12. data/lib/rdi/Model/LocationSelector.rb +16 -0
  13. data/lib/rdi/Model/ProgressView.rb +16 -0
  14. data/lib/rdi/Model/Tester.rb +20 -0
  15. data/lib/rdi/Model/View.rb +16 -0
  16. data/lib/rdi/Plugins/ContextModifiers/GemPath.desc.rb +13 -0
  17. data/lib/rdi/Plugins/ContextModifiers/GemPath.rb +106 -0
  18. data/lib/rdi/Plugins/ContextModifiers/LibraryPath.rb +74 -0
  19. data/lib/rdi/Plugins/ContextModifiers/RubyLoadPath.rb +76 -0
  20. data/lib/rdi/Plugins/ContextModifiers/SystemPath.rb +74 -0
  21. data/lib/rdi/Plugins/GemCommon.rb +127 -0
  22. data/lib/rdi/Plugins/Installers/Download.rb +72 -0
  23. data/lib/rdi/Plugins/Installers/DownloadAndInstall.desc.rb +11 -0
  24. data/lib/rdi/Plugins/Installers/DownloadAndInstall.rb +54 -0
  25. data/lib/rdi/Plugins/Installers/Gem.desc.rb +13 -0
  26. data/lib/rdi/Plugins/Installers/Gem.rb +67 -0
  27. data/lib/rdi/Plugins/Installers/Icons/Download.png +0 -0
  28. data/lib/rdi/Plugins/Installers/Icons/DownloadAndInstall.png +0 -0
  29. data/lib/rdi/Plugins/Installers/Icons/Gem.png +0 -0
  30. data/lib/rdi/Plugins/Installers/Yum.rb +52 -0
  31. data/lib/rdi/Plugins/ProgressViews/SimpleWxGUI.desc.rb +13 -0
  32. data/lib/rdi/Plugins/ProgressViews/SimpleWxGUI.rb +58 -0
  33. data/lib/rdi/Plugins/ProgressViews/Text.rb +68 -0
  34. data/lib/rdi/Plugins/RubyGemsDepDesc.rb +41 -0
  35. data/lib/rdi/Plugins/Testers/Binaries.rb +56 -0
  36. data/lib/rdi/Plugins/Testers/DynamicLibraries.rb +56 -0
  37. data/lib/rdi/Plugins/Testers/RubyRequires.rb +76 -0
  38. data/lib/rdi/Plugins/Views/SimpleWxGUI/DependenciesLoaderDialog.rb +147 -0
  39. data/lib/rdi/Plugins/Views/SimpleWxGUI/DependencyPanel.rb +301 -0
  40. data/lib/rdi/Plugins/Views/SimpleWxGUI/Icons/Dependency.png +0 -0
  41. data/lib/rdi/Plugins/Views/SimpleWxGUI/Icons/Ignore.png +0 -0
  42. data/lib/rdi/Plugins/Views/SimpleWxGUI/Icons/ValidKO.png +0 -0
  43. data/lib/rdi/Plugins/Views/SimpleWxGUI/Icons/ValidOK.png +0 -0
  44. data/lib/rdi/Plugins/Views/SimpleWxGUI/LocationSelectors/Directory.desc.rb +13 -0
  45. data/lib/rdi/Plugins/Views/SimpleWxGUI/LocationSelectors/Directory.rb +45 -0
  46. data/lib/rdi/Plugins/Views/SimpleWxGUI.desc.rb +13 -0
  47. data/lib/rdi/Plugins/Views/SimpleWxGUI.rb +60 -0
  48. data/lib/rdi/Plugins/Views/Text/LocationSelectors/Directory.rb +44 -0
  49. data/lib/rdi/Plugins/Views/Text.rb +257 -0
  50. data/lib/rdi/Plugins/WxCommon.rb +69 -0
  51. data/lib/rdi/Plugins/WxRubyDepDesc.rb +36 -0
  52. data/lib/rdi/rdi.rb +8 -0
  53. data/test/Common.rb +796 -0
  54. data/test/Flows/BasicFlows.rb +114 -0
  55. data/test/Flows/UIFlows.rb +460 -0
  56. data/test/Plugins/ContextModifiers/GemPath.rb +44 -0
  57. data/test/Plugins/ContextModifiers/LibraryPath.rb +36 -0
  58. data/test/Plugins/ContextModifiers/RubyLoadPath.rb +36 -0
  59. data/test/Plugins/ContextModifiers/SystemPath.rb +36 -0
  60. data/test/Plugins/Installers/Download.rb +65 -0
  61. data/test/Plugins/Installers/DownloadAndInstall.rb +73 -0
  62. data/test/Plugins/Installers/Gem.rb +79 -0
  63. data/test/Plugins/LocationSelectors/Directory.rb +34 -0
  64. data/test/Plugins/Testers/Binaries.rb +46 -0
  65. data/test/Plugins/Testers/DynamicLibraries.rb +46 -0
  66. data/test/Plugins/Testers/RubyRequires.rb +48 -0
  67. data/test/Plugins/Views/SimpleWxGUI.rb +190 -0
  68. data/test/Plugins/Views/Text.rb +112 -0
  69. data/test/Plugins/WxEnv.rb +58 -0
  70. data/test/Plugins/WxEnvApp.rb +53 -0
  71. data/test/Repository/Binaries/DummyBinary +1 -0
  72. data/test/Repository/Libraries/DummyLibrary.so +1 -0
  73. data/test/Repository/RubyGems/DummyGem-0.0.1.20090828.gem +0 -0
  74. data/test/Repository/RubyGems/GemsSources/DummyGem/DummyGem.gemspec.rb +23 -0
  75. data/test/Repository/RubyGems/GemsSources/DummyGem/lib/DummyGemMain.rb +5 -0
  76. data/test/Repository/RubyLibraries/DummyRubyLib.rb +1 -0
  77. data/test/run.rb +23 -0
  78. metadata +145 -0
@@ -0,0 +1,41 @@
1
+ #--
2
+ # Copyright (c) 2009 Muriel Salvan (murielsalvan@users.sourceforge.net)
3
+ # Licensed under the terms specified in LICENSE file. No warranty is provided.
4
+ #++
5
+
6
+ module RDI
7
+
8
+ # Give the description of the RubyGems dependency
9
+ # It has been put in this singular file because it is required by many different plugins
10
+ #
11
+ # Return:
12
+ # * <em>map<Symbol,Object></em>: The description
13
+ def self.getRubyGemsDepDesc
14
+ return RDI::Model::DependencyDescription.new('RubyGems 1.3.5').addDescription( {
15
+ :Testers => [
16
+ {
17
+ :Type => 'RubyRequires',
18
+ :Content => [ 'rubygems' ]
19
+ }
20
+ ],
21
+ :Installers => [
22
+ {
23
+ :Type => 'DownloadAndInstall',
24
+ :Content => [
25
+ 'http://rubyforge.org/frs/download.php/60719/rubygems-1.3.5.zip',
26
+ Proc.new do |iInstallLocation|
27
+ next system("ruby -w setup.rb --destdir #{iInstallLocation}")
28
+ end
29
+ ],
30
+ :ContextModifiers => [
31
+ {
32
+ :Type => 'RubyLoadPath',
33
+ :Content => "%INSTALLDIR%/lib/ruby/site_ruby/#{Config::CONFIG['ruby_version']}"
34
+ }
35
+ ]
36
+ }
37
+ ]
38
+ } )
39
+ end
40
+
41
+ end
@@ -0,0 +1,56 @@
1
+ #--
2
+ # Copyright (c) 2009 Muriel Salvan (murielsalvan@users.sourceforge.net)
3
+ # Licensed under the terms specified in LICENSE file. No warranty is provided.
4
+ #++
5
+
6
+ require 'rdi/Model/Tester'
7
+
8
+ module RDI
9
+
10
+ module Testers
11
+
12
+ # Test that some Exes are accessible
13
+ class Binaries < RDI::Model::Tester
14
+
15
+ # Give the name of possible ContextModifiers that might change the resolution of this Tester.
16
+ # This is used to know what context modifiers the user can use to resolve dependencies without having to install.
17
+ #
18
+ # Return:
19
+ # * <em>list<String></em>: The list of ContextModifiers names
20
+ def getAffectingContextModifiers
21
+ return [ 'SystemPath' ]
22
+ end
23
+
24
+ # Test if a given content is resolved
25
+ #
26
+ # Parameters:
27
+ # * *iContent* (_Object_): The tester's content
28
+ # Return:
29
+ # * _Boolean_: Is the content resolved ?
30
+ def isContentResolved?(iContent)
31
+ # * *iContent* (<em>list<String></em>): The list of Exes to resolve (extensions might be guessed)
32
+ rSuccess = false
33
+
34
+ # For each required file, test that it exists among PATH
35
+ iContent.each do |iExeName|
36
+ $rUtilAnts_Platform_Info.getSystemExePath.each do |iDir|
37
+ rSuccess = (!Dir.glob(File.expand_path("#{iDir}/#{iExeName}{,#{$rUtilAnts_Platform_Info.getDiscreteExeExtensions.join(',')}}")).empty?)
38
+ if (rSuccess)
39
+ # We found it. Don't try other paths.
40
+ break
41
+ end
42
+ end
43
+ if (!rSuccess)
44
+ # We didn't find this exe. Don't try other requires.
45
+ break
46
+ end
47
+ end
48
+
49
+ return rSuccess
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,56 @@
1
+ #--
2
+ # Copyright (c) 2009 Muriel Salvan (murielsalvan@users.sourceforge.net)
3
+ # Licensed under the terms specified in LICENSE file. No warranty is provided.
4
+ #++
5
+
6
+ require 'rdi/Model/Tester'
7
+
8
+ module RDI
9
+
10
+ module Testers
11
+
12
+ # Test that some DLLs are accessible
13
+ class DynamicLibraries < RDI::Model::Tester
14
+
15
+ # Give the name of possible ContextModifiers that might change the resolution of this Tester.
16
+ # This is used to know what context modifiers the user can use to resolve dependencies without having to install.
17
+ #
18
+ # Return:
19
+ # * <em>list<String></em>: The list of ContextModifiers names
20
+ def getAffectingContextModifiers
21
+ return [ 'LibraryPath' ]
22
+ end
23
+
24
+ # Test if a given content is resolved
25
+ #
26
+ # Parameters:
27
+ # * *iContent* (_Object_): The tester's content
28
+ # Return:
29
+ # * _Boolean_: Is the content resolved ?
30
+ def isContentResolved?(iContent)
31
+ # * *iContent* (<em>list<String></em>): The list of DLLs to resolve
32
+ rSuccess = false
33
+
34
+ # For each required file, test that it exists among $LOAD_PATH
35
+ iContent.each do |iDLLName|
36
+ $rUtilAnts_Platform_Info.getSystemLibsPath.each do |iDir|
37
+ rSuccess = File.exists?("#{iDir}/#{iDLLName}")
38
+ if (rSuccess)
39
+ # We found it. Don't try other paths.
40
+ break
41
+ end
42
+ end
43
+ if (!rSuccess)
44
+ # We didn't find this require. Don't try other requires.
45
+ break
46
+ end
47
+ end
48
+
49
+ return rSuccess
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,76 @@
1
+ #--
2
+ # Copyright (c) 2009 Muriel Salvan (murielsalvan@users.sourceforge.net)
3
+ # Licensed under the terms specified in LICENSE file. No warranty is provided.
4
+ #++
5
+
6
+ require 'rdi/Model/Tester'
7
+ require 'rdi/Plugins/GemCommon'
8
+
9
+ module RDI
10
+
11
+ module Testers
12
+
13
+ # Test that some Ruby files are accessible
14
+ class RubyRequires < RDI::Model::Tester
15
+
16
+ # Give the name of possible ContextModifiers that might change the resolution of this Tester.
17
+ # This is used to know what context modifiers the user can use to resolve dependencies without having to install.
18
+ #
19
+ # Return:
20
+ # * <em>list<String></em>: The list of ContextModifiers names
21
+ def getAffectingContextModifiers
22
+ return [ 'GemPath', 'RubyLoadPath' ]
23
+ end
24
+
25
+ # Test if a given content is resolved
26
+ #
27
+ # Parameters:
28
+ # * *iContent* (_Object_): The tester's content
29
+ # Return:
30
+ # * _Boolean_: Is the content resolved ?
31
+ def isContentResolved?(iContent)
32
+ # * *iContent* (<em>list<String></em>): The list of requires to resolve
33
+ rSuccess = false
34
+
35
+ # Handle RubyGems as an option
36
+ if (defined?(Gem) == nil)
37
+ # No RubyGem.
38
+ # For each required file, test that it exists among $LOAD_PATH
39
+ iContent.each do |iRequireName|
40
+ lFileFilter = iRequireName
41
+ if (File.extname(iRequireName).empty?)
42
+ lFileFilter = "#{iRequireName}.{rb,so,o,sl,dll}"
43
+ end
44
+ rSuccess = false
45
+ $LOAD_PATH.each do |iDir|
46
+ rSuccess = (!Dir.glob(File.expand_path("#{iDir}/#{lFileFilter}")).empty?)
47
+ if (rSuccess)
48
+ # We found it. Don't try other paths.
49
+ break
50
+ end
51
+ end
52
+ if (!rSuccess)
53
+ # We didn't find this require. Don't try other requires.
54
+ break
55
+ end
56
+ end
57
+ else
58
+ # RubyGems is here. Use it.
59
+ # For each required file, test that it exists among the RubyGems' loaded paths
60
+ iContent.each do |iRequireName|
61
+ rSuccess = (!Gem.find_files(iRequireName).empty?)
62
+ if (!rSuccess)
63
+ # We did not find this one: don't even try the next ones
64
+ break
65
+ end
66
+ end
67
+ end
68
+
69
+ return rSuccess
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,147 @@
1
+ #--
2
+ # Copyright (c) 2009 Muriel Salvan (murielsalvan@users.sourceforge.net)
3
+ # Licensed under the terms specified in LICENSE file. No warranty is provided.
4
+ #++
5
+
6
+ module RDI
7
+
8
+ module Views
9
+
10
+ class SimpleWxGUI
11
+
12
+ # Dialog that downloads missing dependencies
13
+ # Apart launchers, only this class has a dependency on RubyGems
14
+ class DependenciesLoaderDialog < Wx::Dialog
15
+
16
+ # Constructor
17
+ #
18
+ # Parameters:
19
+ # * *iParent* (<em>Wx::Window</em>): The parent
20
+ # * *ioInstaller* (_Installer_): The installer
21
+ # * *iDepsUserChoices* (<em>list<DependencyUserChoice></em>): The dependency user choices to reflect in this dialog
22
+ def initialize(iParent, ioInstaller, iDepsUserChoices)
23
+ super(iParent,
24
+ :title => 'RDI: Runtime Dependencies Installer',
25
+ :style => Wx::DEFAULT_DIALOG_STYLE|Wx::RESIZE_BORDER|Wx::MAXIMIZE_BOX
26
+ )
27
+
28
+ # This boolean will prevent undesirable refreshes
29
+ @DuringInit = true
30
+
31
+ @Installer, @DepsUserChoices = ioInstaller, iDepsUserChoices
32
+ @IconsDir = "#{File.dirname(__FILE__)}/Icons"
33
+
34
+ # Create components
35
+ @BApply = Wx::Button.new(self, Wx::ID_ANY, 'Apply')
36
+ lSTMessage = Wx::StaticText.new(self, Wx::ID_ANY, "#{@DepsUserChoices.size} dependencies could not be found.\nPlease indicate what action to take for each one of them before continuing.",
37
+ :style => Wx::ALIGN_CENTRE
38
+ )
39
+ lFont = lSTMessage.font
40
+ lFont.weight = Wx::FONTWEIGHT_BOLD
41
+ lSTMessage.font = lFont
42
+
43
+ # The notebook containing the scroll windows
44
+ @NBDeps = Wx::Notebook.new(self)
45
+ # Create the image list for the notebook
46
+ lNotebookImageList = Wx::ImageList.new(16, 16)
47
+ @NBDeps.image_list = lNotebookImageList
48
+ # Make this image list driven by a manager
49
+ @NBImageListManager = RUtilAnts::GUI::ImageListManager.new(lNotebookImageList, 16, 16)
50
+
51
+ # Create the list of Panels displaying each dependency
52
+ @DependencyPanels = []
53
+ require 'rdi/Plugins/Views/SimpleWxGUI/DependencyPanel'
54
+ @DepsUserChoices.each do |iDepUserChoice|
55
+ @DependencyPanels << DependencyPanel.new(
56
+ @NBDeps,
57
+ @Installer,
58
+ iDepUserChoice,
59
+ self
60
+ )
61
+ end
62
+
63
+ # The notebook pages, 1 per dependency
64
+ lIdx = 0
65
+ @DepsUserChoices.each do |iDepUserChoice|
66
+ @NBDeps.add_page(
67
+ @DependencyPanels[lIdx],
68
+ iDepUserChoice.DepDesc.ID,
69
+ false,
70
+ -1
71
+ )
72
+ lIdx += 1
73
+ end
74
+
75
+ # Resize some components as they will be used for sizers
76
+ @NBDeps.fit
77
+
78
+ # Put everything in sizers
79
+ lMainSizer = Wx::BoxSizer.new(Wx::VERTICAL)
80
+ lMainSizer.add_item(lSTMessage, :border => 8, :flag => Wx::ALIGN_CENTER|Wx::ALL, :proportion => 0)
81
+ lMainSizer.add_item(@NBDeps, :flag => Wx::GROW, :proportion => 1)
82
+ lMainSizer.add_item(@BApply, :border => 8, :flag => Wx::ALIGN_RIGHT|Wx::ALL, :proportion => 0)
83
+ self.sizer = lMainSizer
84
+
85
+ self.fit
86
+
87
+ # Events
88
+ evt_button(@BApply) do |iEvent|
89
+ self.end_modal(Wx::ID_OK)
90
+ end
91
+
92
+ @DuringInit = false
93
+
94
+ # Update the tabs
95
+ @DependencyPanels.each do |iPanel|
96
+ notifyRefresh(iPanel)
97
+ end
98
+
99
+ end
100
+
101
+ # A panel has been refreshed
102
+ #
103
+ # Parameters:
104
+ # * *iPanel* (<em>Wx::Panel</em>): The panel just refreshed
105
+ def notifyRefresh(iPanel)
106
+ if (!@DuringInit)
107
+ # Find the Tab containing this Panel
108
+ lIdx = @DependencyPanels.index(iPanel)
109
+ lDepUserChoice = @DepsUserChoices[lIdx]
110
+ lIconName = "#{@IconsDir}/Dependency.png"
111
+ if (lDepUserChoice.Locate)
112
+ if (lDepUserChoice.ResolvedTesters.size == lDepUserChoice.DepDesc.Testers.size)
113
+ # Complete
114
+ lIconName = "#{@IconsDir}/ValidOK.png"
115
+ else
116
+ # Incomplete
117
+ lIconName = "#{@IconsDir}/ValidKO.png"
118
+ end
119
+ elsif (lDepUserChoice.Ignore)
120
+ lIconName = "#{@IconsDir}/Ignore.png"
121
+ else
122
+ # Get the icon of the selected Installer
123
+ lInstallerName = lDepUserChoice.DepDesc.Installers[lDepUserChoice.IdxInstaller][0]
124
+ # TODO: Accept more data formats
125
+ lInstallerIconName = "#{@Installer.RDILibDir}/Plugins/Installers/Icons/#{lInstallerName}.png"
126
+ if (File.exists?(lInstallerIconName))
127
+ lIconName = lInstallerIconName
128
+ end
129
+ end
130
+ lIdxImage = @NBImageListManager.getImageIndex(lIconName) do
131
+ lIcon, lError = getBitmapFromURL(lIconName)
132
+ if (lIcon == nil)
133
+ lIcon, lError = getBitmapFromURL("#{@IconsDir}/Dependency.png")
134
+ end
135
+ next lIcon
136
+ end
137
+ @NBDeps.set_page_image(lIdx, lIdxImage)
138
+ end
139
+ end
140
+
141
+ end
142
+
143
+ end
144
+
145
+ end
146
+
147
+ end
@@ -0,0 +1,301 @@
1
+ #--
2
+ # Copyright (c) 2009 Muriel Salvan (murielsalvan@users.sourceforge.net)
3
+ # Licensed under the terms specified in LICENSE file. No warranty is provided.
4
+ #++
5
+
6
+ module RDI
7
+
8
+ module Views
9
+
10
+ class SimpleWxGUI
11
+
12
+ # Panel that proposes how to resolve a dependency
13
+ class DependencyPanel < Wx::Panel
14
+
15
+ # Constructor
16
+ # The notifier control window must have a notifyInstallDecisionChanged method implemented
17
+ #
18
+ # Parameters:
19
+ # * *iParent* (<em>Wx::Window</em>): The parent window
20
+ # * *ioInstaller* (_Installer_): The installer
21
+ # * *iDepUserChoice* (_DependencyUserChoice_): The dependency's user choice
22
+ # * *iNotifierControl* (_Object_): The notifier control that will be notified upon changes
23
+ def initialize(iParent, ioInstaller, iDepUserChoice, iNotifierControl)
24
+ super(iParent)
25
+
26
+ @Installer, @DepUserChoice, @NotifierControl = ioInstaller, iDepUserChoice, iNotifierControl
27
+ @IconsDir = "#{File.dirname(__FILE__)}/Icons"
28
+
29
+ # Create components
30
+
31
+ # The locate part
32
+ @RBLocate = Wx::RadioButton.new(self, Wx::ID_ANY, 'Locate', :style => Wx::RB_GROUP)
33
+ # The Testers' statuses
34
+ # The list of [ StaticBitmap, StaticText ] used to represent Testers' state
35
+ # list< [ Wx::StaticBitmap, Wx::StaticText ] >
36
+ @TesterComponents = []
37
+ @DepUserChoice.DepDesc.Testers.each do |iTesterInfo|
38
+ iTesterName, iTesterContent = iTesterInfo
39
+ @TesterComponents << [
40
+ Wx::StaticBitmap.new(self, Wx::ID_ANY, Wx::Bitmap.new),
41
+ Wx::StaticText.new(self, Wx::ID_ANY, "#{iTesterName}: #{iTesterContent}")
42
+ ]
43
+ end
44
+ # The buttons affecting ContextModifiers
45
+ # The list of Buttons used to affect ContextModifiers
46
+ # list< Wx::Button >
47
+ lACMComponents = []
48
+ @DepUserChoice.AffectingContextModifiers.each do |iCMName|
49
+ lACMComponents << Wx::Button.new(self, Wx::ID_ANY, "Change #{iCMName}")
50
+ end
51
+
52
+ # The ignore part
53
+ @RBIgnore = Wx::RadioButton.new(self, Wx::ID_ANY, 'Ignore')
54
+
55
+ # The install part
56
+ @RBInstall = Wx::RadioButton.new(self, Wx::ID_ANY, 'Install')
57
+ # The list of installers info
58
+ # list< [ RadioButton, StaticBitmap, list< RadioButton > ] >
59
+ @InstallerComponents = []
60
+ # First, create the installers radio buttons before their respective destinations radio buttons.
61
+ # This is done this way to ensure correct radio buttons grouping
62
+ @DepUserChoice.DepDesc.Installers.each do |iInstallerInfo|
63
+ iInstallerName, iInstallerContent, iContextModifiers = iInstallerInfo
64
+ lRBInstaller = nil
65
+ if (@InstallerComponents.empty?)
66
+ # First item of the group
67
+ lRBInstaller = Wx::RadioButton.new(self, Wx::ID_ANY, "#{iInstallerName} - #{iInstallerContent}", :style => Wx::RB_GROUP)
68
+ else
69
+ lRBInstaller = Wx::RadioButton.new(self, Wx::ID_ANY, "#{iInstallerName} - #{iInstallerContent}")
70
+ end
71
+ # Icon of the installer
72
+ lIconName = "#{@IconsDir}/Dependency.png"
73
+ # TODO: Accept more data formats
74
+ lInstallerIconName = "#{@Installer.RDILibDir}/Plugins/Installers/Icons/#{iInstallerName}.png"
75
+ if (File.exists?(lInstallerIconName))
76
+ lIconName = lInstallerIconName
77
+ end
78
+ @InstallerComponents << [
79
+ lRBInstaller,
80
+ Wx::StaticBitmap.new(self, Wx::ID_ANY, Wx::Bitmap.new(lIconName)),
81
+ []
82
+ ]
83
+ end
84
+ lIdxInstaller = 0
85
+ @DepUserChoice.DepDesc.Installers.each do |iInstallerInfo|
86
+ iInstallerName, iInstallerContent, iContextModifiers = iInstallerInfo
87
+ lDestinationComponents = @InstallerComponents[lIdxInstaller][2]
88
+ @Installer.accessPlugin('Installers', iInstallerName) do |iPlugin|
89
+ iPlugin.PossibleDestinations.each do |iDestInfo|
90
+ iFlavour, iLocation = iDestInfo
91
+ lFlavourText = nil
92
+ lDestLocation = iLocation
93
+ case iFlavour
94
+ when DEST_LOCAL
95
+ lFlavourText = 'Local'
96
+ when DEST_SYSTEM
97
+ lFlavourText = 'System'
98
+ when DEST_USER
99
+ lFlavourText = 'User'
100
+ when DEST_TEMP
101
+ lFlavourText = 'Temporary'
102
+ when DEST_OTHER
103
+ lFlavourText = 'Other'
104
+ lDestLocation = "Choose #{iLocation}"
105
+ else
106
+ logBug "Unknown flavour ID: #{iFlavour}"
107
+ lFlavourText = 'Unknown'
108
+ end
109
+ if (lDestinationComponents.empty?)
110
+ # First destination radio button
111
+ lDestinationComponents << Wx::RadioButton.new(self, Wx::ID_ANY, "#{lFlavourText} - #{lDestLocation}", :style => Wx::RB_GROUP)
112
+ else
113
+ lDestinationComponents << Wx::RadioButton.new(self, Wx::ID_ANY, "#{lFlavourText} - #{lDestLocation}")
114
+ end
115
+ end
116
+ end
117
+ lIdxInstaller += 1
118
+ end
119
+
120
+ # Put them into sizers
121
+ lMainSizer = Wx::BoxSizer.new(Wx::VERTICAL)
122
+ lMainSizer.add_item(@RBLocate, :proportion => 0)
123
+
124
+ lLocateSizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
125
+ lLocateSizer.add_item([16,0], :proportion => 0)
126
+
127
+ lLocateChoicesSizer = Wx::BoxSizer.new(Wx::VERTICAL)
128
+ @TesterComponents.each do |iTesterComponentsList|
129
+ lSB, lST = iTesterComponentsList
130
+ lTesterSizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
131
+ lTesterSizer.add_item(lSB, :proportion => 0)
132
+ lTesterSizer.add_item([8,0], :proportion => 0)
133
+ lTesterSizer.add_item(lST, :proportion => 0)
134
+ lLocateChoicesSizer.add_item(lTesterSizer, :proportion => 0)
135
+ end
136
+ lACMComponents.each do |iACMButton|
137
+ lLocateChoicesSizer.add_item(iACMButton, :proportion => 0)
138
+ end
139
+
140
+ lLocateSizer.add_item(lLocateChoicesSizer, :proportion => 0)
141
+
142
+ lMainSizer.add_item(lLocateSizer, :proportion => 0)
143
+ lMainSizer.add_item([0,16], :proportion => 0)
144
+ lMainSizer.add_item(@RBIgnore, :proportion => 0)
145
+ lMainSizer.add_item([0,16], :proportion => 0)
146
+ lMainSizer.add_item(@RBInstall, :proportion => 0)
147
+
148
+ lInstallSizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
149
+ lInstallSizer.add_item([16,0], :proportion => 0)
150
+
151
+ lInstallersListSizer = Wx::BoxSizer.new(Wx::VERTICAL)
152
+ @InstallerComponents.each do |iInstallerComponentsInfo|
153
+ lRBInstaller, lSBIcon, lRBListDests = iInstallerComponentsInfo
154
+
155
+ lInstallerChoiceSizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
156
+ lInstallerChoiceSizer.add_item(lRBInstaller, :proportion => 0)
157
+ lInstallerChoiceSizer.add_item(lSBIcon, :proportion => 0)
158
+
159
+ lInstallersListSizer.add_item(lInstallerChoiceSizer, :proportion => 0)
160
+
161
+ lDestinationsListWithTabSizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
162
+ lDestinationsListWithTabSizer.add_item([16,0], :proportion => 0)
163
+
164
+ lDestinationsListSizer = Wx::BoxSizer.new(Wx::VERTICAL)
165
+ lRBListDests.each do |iRBDestination|
166
+ lDestinationsListSizer.add_item(iRBDestination, :proportion => 0)
167
+ end
168
+
169
+ lDestinationsListWithTabSizer.add_item(lDestinationsListSizer, :proportion => 0)
170
+
171
+ lInstallersListSizer.add_item(lDestinationsListWithTabSizer, :proportion => 0)
172
+ end
173
+
174
+ lInstallSizer.add_item(lInstallersListSizer, :proportion => 0)
175
+
176
+ lMainSizer.add_item(lInstallSizer, :proportion => 0)
177
+
178
+ self.sizer = lMainSizer
179
+ self.fit
180
+
181
+ # Set events
182
+ # Click on "Locate"
183
+ evt_radiobutton(@RBLocate) do |iEvent|
184
+ @DepUserChoice.setLocate
185
+ refreshComponents
186
+ end
187
+ # Click on any of the ACM
188
+ lACMIdx = 0
189
+ lACMComponents.each do |iACMButton|
190
+ # Clone indexes for them to be persistent in the code block
191
+ lACMIdxCloned = lACMIdx
192
+ evt_button(iACMButton) do |iEvent|
193
+ # Call the correct LocationSelector
194
+ @DepUserChoice.affectContextModifier(@DepUserChoice.AffectingContextModifiers[lACMIdxCloned])
195
+ refreshComponents
196
+ end
197
+ lACMIdx += 1
198
+ end
199
+ # Click on "Ignore"
200
+ evt_radiobutton(@RBIgnore) do |iEvent|
201
+ @DepUserChoice.setIgnore
202
+ refreshComponents
203
+ end
204
+ # Click on "Install"
205
+ evt_radiobutton(@RBInstall) do |iEvent|
206
+ @DepUserChoice.setInstaller(0, 0)
207
+ refreshComponents
208
+ end
209
+ # Click on any of the installers
210
+ lIdxInstaller = 0
211
+ @InstallerComponents.each do |iInstallerComponentsInfo|
212
+ # Clone the indexes to make them persistent in the code block
213
+ lIdxInstallerCloned = lIdxInstaller
214
+ lRBInstaller, lSBIcon, lRBListDests = iInstallerComponentsInfo
215
+ evt_radiobutton(lRBInstaller) do |iEvent|
216
+ @DepUserChoice.setInstaller(lIdxInstallerCloned, 0)
217
+ refreshComponents
218
+ end
219
+ # Click on any of the destinations
220
+ lIdxDest = 0
221
+ lRBListDests.each do |iRBDestination|
222
+ lIdxDestCloned = lIdxDest
223
+ evt_radiobutton(iRBDestination) do |iEvent|
224
+ @DepUserChoice.setInstaller(lIdxInstallerCloned, lIdxDestCloned)
225
+ # If it is DEST_OTHER, call the LocationSelector
226
+ @Installer.accessPlugin('Installers', @DepUserChoice.DepDesc.Installers[lIdxInstallerCloned][0]) do |iPlugin|
227
+ iFlavour, iLocation = iPlugin.PossibleDestinations[lIdxDestCloned]
228
+ if (iFlavour == DEST_OTHER)
229
+ @DepUserChoice.selectOtherInstallLocation(iLocation)
230
+ end
231
+ end
232
+ refreshComponents
233
+ end
234
+ lIdxDest += 1
235
+ end
236
+ lIdxInstaller += 1
237
+ end
238
+
239
+ # Refresh the components
240
+ refreshComponents
241
+
242
+ end
243
+
244
+ # Refresh components
245
+ def refreshComponents
246
+ # Testers icons
247
+ lIdxTester = 0
248
+ @TesterComponents.each do |iTesterComponentsList|
249
+ iSBStatus, iSTTitle = iTesterComponentsList
250
+ # Check if the Tester is resolved
251
+ if (@DepUserChoice.ResolvedTesters.has_key?(lIdxTester))
252
+ iSBStatus.bitmap, lError = getBitmapFromURL("#{@IconsDir}/ValidOK.png")
253
+ else
254
+ iSBStatus.bitmap, lError = getBitmapFromURL("#{@IconsDir}/ValidKO.png")
255
+ end
256
+ lIdxTester += 1
257
+ end
258
+ # Selections
259
+ @RBLocate.set_value(@DepUserChoice.Locate)
260
+ @RBIgnore.set_value(@DepUserChoice.Ignore)
261
+ @RBInstall.set_value(@DepUserChoice.IdxInstaller != nil)
262
+ lIdxInstaller = 0
263
+ @InstallerComponents.each do |iInstallerComponentsInfo|
264
+ lRBInstaller, lSBIcon, lRBListDests = iInstallerComponentsInfo
265
+ lRBInstaller.set_value((@DepUserChoice.IdxInstaller == lIdxInstaller))
266
+ lIdxDest = 0
267
+ lRBListDests.each do |iRBDestination|
268
+ iRBDestination.set_value(
269
+ ((@DepUserChoice.IdxInstaller == lIdxInstaller) and
270
+ (@DepUserChoice.IdxDestination == lIdxDest))
271
+ )
272
+ # Change the text if it is DEST_OTHER
273
+ @Installer.accessPlugin('Installers', @DepUserChoice.DepDesc.Installers[lIdxInstaller][0]) do |iPlugin|
274
+ iFlavour, iLocation = iPlugin.PossibleDestinations[lIdxDest]
275
+ if (iFlavour == DEST_OTHER)
276
+ # If it is the current one, use OtherLocation
277
+ if ((@DepUserChoice.IdxInstaller == lIdxInstaller) and
278
+ (@DepUserChoice.IdxDestination == lIdxDest))
279
+ iRBDestination.label = "Other (#{@DepUserChoice.OtherLocation})"
280
+ else
281
+ iRBDestination.label = "Other (Choose #{iLocation})"
282
+ end
283
+ end
284
+ end
285
+ lIdxDest += 1
286
+ end
287
+ lIdxInstaller += 1
288
+ end
289
+ # Fit again, as some labels might have changed
290
+ self.fit
291
+ # Notify refresh
292
+ @NotifierControl.notifyRefresh(self)
293
+ end
294
+
295
+ end
296
+
297
+ end
298
+
299
+ end
300
+
301
+ end