RDI 0.1.0.20091020

Sign up to get free protection for your applications and to get access to all the features.
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