ruber 0.0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. data/COPYING +339 -0
  2. data/INSTALL +137 -0
  3. data/LICENSE +8 -0
  4. data/bin/ruber +65 -0
  5. data/data/share/apps/ruber/core_components.yaml +31 -0
  6. data/data/share/apps/ruber/ruberui.rc +109 -0
  7. data/data/share/icons/ruber.png +0 -0
  8. data/data/share/pixmaps/ruby.png +0 -0
  9. data/icons/ruber-16.png +0 -0
  10. data/icons/ruber-32.png +0 -0
  11. data/icons/ruber-48.png +0 -0
  12. data/icons/ruber-8.png +0 -0
  13. data/lib/ruber/application/application.rb +288 -0
  14. data/lib/ruber/application/plugin.yaml +11 -0
  15. data/lib/ruber/component_manager.rb +899 -0
  16. data/lib/ruber/config/config.rb +82 -0
  17. data/lib/ruber/config/plugin.yaml +3 -0
  18. data/lib/ruber/document_project.rb +209 -0
  19. data/lib/ruber/documents/document_list.rb +416 -0
  20. data/lib/ruber/documents/plugin.yaml +4 -0
  21. data/lib/ruber/editor/document.rb +506 -0
  22. data/lib/ruber/editor/editor_view.rb +167 -0
  23. data/lib/ruber/editor/ktexteditor_wrapper.rb +202 -0
  24. data/lib/ruber/exception_widgets.rb +245 -0
  25. data/lib/ruber/external_program_plugin.rb +397 -0
  26. data/lib/ruber/filtered_output_widget.rb +342 -0
  27. data/lib/ruber/gui_states_handler.rb +231 -0
  28. data/lib/ruber/kde_config_option_backend.rb +167 -0
  29. data/lib/ruber/kde_sugar.rb +249 -0
  30. data/lib/ruber/main_window/choose_plugins_dlg.rb +353 -0
  31. data/lib/ruber/main_window/main_window.rb +524 -0
  32. data/lib/ruber/main_window/main_window_actions.rb +537 -0
  33. data/lib/ruber/main_window/main_window_internal.rb +239 -0
  34. data/lib/ruber/main_window/open_file_in_project_dlg.rb +212 -0
  35. data/lib/ruber/main_window/output_color_widget.rb +35 -0
  36. data/lib/ruber/main_window/plugin.yaml +58 -0
  37. data/lib/ruber/main_window/save_modified_files_dlg.rb +89 -0
  38. data/lib/ruber/main_window/status_bar.rb +156 -0
  39. data/lib/ruber/main_window/ui/choose_plugins_widget.rb +90 -0
  40. data/lib/ruber/main_window/ui/choose_plugins_widget.ui +77 -0
  41. data/lib/ruber/main_window/ui/main_window_settings_widget.rb +108 -0
  42. data/lib/ruber/main_window/ui/main_window_settings_widget.ui +89 -0
  43. data/lib/ruber/main_window/ui/new_project_widget.rb +119 -0
  44. data/lib/ruber/main_window/ui/new_project_widget.ui +178 -0
  45. data/lib/ruber/main_window/ui/open_file_in_project_dlg.rb +109 -0
  46. data/lib/ruber/main_window/ui/open_file_in_project_dlg.ui +168 -0
  47. data/lib/ruber/main_window/ui/output_color_widget.rb +241 -0
  48. data/lib/ruber/main_window/ui/output_color_widget.ui +204 -0
  49. data/lib/ruber/main_window/workspace.rb +442 -0
  50. data/lib/ruber/output_widget.rb +1093 -0
  51. data/lib/ruber/plugin.rb +264 -0
  52. data/lib/ruber/plugin_like.rb +589 -0
  53. data/lib/ruber/plugin_specification.rb +106 -0
  54. data/lib/ruber/plugin_specification_reader.rb +451 -0
  55. data/lib/ruber/project.rb +493 -0
  56. data/lib/ruber/project_backend.rb +105 -0
  57. data/lib/ruber/projects/plugin.yaml +11 -0
  58. data/lib/ruber/projects/project_files_list.rb +314 -0
  59. data/lib/ruber/projects/project_files_widget.rb +301 -0
  60. data/lib/ruber/projects/project_list.rb +314 -0
  61. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +74 -0
  62. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.ui +61 -0
  63. data/lib/ruber/projects/ui/project_files_widget.rb +117 -0
  64. data/lib/ruber/projects/ui/project_files_widget.ui +123 -0
  65. data/lib/ruber/qt_sugar.rb +673 -0
  66. data/lib/ruber/settings_container.rb +515 -0
  67. data/lib/ruber/settings_dialog.rb +244 -0
  68. data/lib/ruber/settings_dialog_manager.rb +503 -0
  69. data/lib/ruber/utils.rb +414 -0
  70. data/lib/ruber/yaml_option_backend.rb +159 -0
  71. data/outsider_files +15 -0
  72. data/plugins/autosave/autosave.rb +404 -0
  73. data/plugins/autosave/plugin.yaml +16 -0
  74. data/plugins/autosave/ui/autosave_config_widget.rb +83 -0
  75. data/plugins/autosave/ui/autosave_config_widget.ui +68 -0
  76. data/plugins/command/command.png +0 -0
  77. data/plugins/command/command.rb +74 -0
  78. data/plugins/command/plugin.yaml +11 -0
  79. data/plugins/find_in_files/find_in_files.rb +337 -0
  80. data/plugins/find_in_files/find_in_files_dlg.rb +411 -0
  81. data/plugins/find_in_files/find_in_files_ui.rc +11 -0
  82. data/plugins/find_in_files/find_in_files_widgets.rb +485 -0
  83. data/plugins/find_in_files/plugin.yaml +23 -0
  84. data/plugins/find_in_files/ui/config_widget.rb +58 -0
  85. data/plugins/find_in_files/ui/config_widget.ui +41 -0
  86. data/plugins/find_in_files/ui/find_in_files_widget.rb +260 -0
  87. data/plugins/find_in_files/ui/find_in_files_widget.ui +324 -0
  88. data/plugins/project_browser/plugin.yaml +10 -0
  89. data/plugins/project_browser/project_browser.rb +245 -0
  90. data/plugins/rake/plugin.yaml +39 -0
  91. data/plugins/rake/rake.png +0 -0
  92. data/plugins/rake/rake.rb +567 -0
  93. data/plugins/rake/rake_extension.rb +153 -0
  94. data/plugins/rake/rake_widgets.rb +615 -0
  95. data/plugins/rake/rakeui.rc +27 -0
  96. data/plugins/rake/ui/add_quick_task_widget.rb +71 -0
  97. data/plugins/rake/ui/add_quick_task_widget.ui +59 -0
  98. data/plugins/rake/ui/choose_task_widget.rb +77 -0
  99. data/plugins/rake/ui/choose_task_widget.ui +72 -0
  100. data/plugins/rake/ui/config_widget.rb +127 -0
  101. data/plugins/rake/ui/config_widget.ui +123 -0
  102. data/plugins/rake/ui/project_widget.rb +217 -0
  103. data/plugins/rake/ui/project_widget.ui +246 -0
  104. data/plugins/rspec/plugin.yaml +30 -0
  105. data/plugins/rspec/rspec.png +0 -0
  106. data/plugins/rspec/rspec.rb +945 -0
  107. data/plugins/rspec/rspec.svg +90 -0
  108. data/plugins/rspec/rspecui.rc +20 -0
  109. data/plugins/rspec/ruber_rspec_formatter.rb +312 -0
  110. data/plugins/rspec/ui/rspec_project_widget.rb +170 -0
  111. data/plugins/rspec/ui/rspec_project_widget.ui +193 -0
  112. data/plugins/ruby_development/plugin.yaml +27 -0
  113. data/plugins/ruby_development/ruby_development.png +0 -0
  114. data/plugins/ruby_development/ruby_development.rb +453 -0
  115. data/plugins/ruby_development/ruby_developmentui.rc +19 -0
  116. data/plugins/ruby_development/ui/project_widget.rb +112 -0
  117. data/plugins/ruby_development/ui/project_widget.ui +108 -0
  118. data/plugins/ruby_runner/config_widget.rb +116 -0
  119. data/plugins/ruby_runner/plugin.yaml +26 -0
  120. data/plugins/ruby_runner/project_widget.rb +62 -0
  121. data/plugins/ruby_runner/ruby.png +0 -0
  122. data/plugins/ruby_runner/ruby_interpretersui.rc +26 -0
  123. data/plugins/ruby_runner/ruby_runner.rb +411 -0
  124. data/plugins/ruby_runner/ui/config_widget.rb +92 -0
  125. data/plugins/ruby_runner/ui/config_widget.ui +91 -0
  126. data/plugins/ruby_runner/ui/project_widget.rb +60 -0
  127. data/plugins/ruby_runner/ui/project_widget.ui +48 -0
  128. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.rb +59 -0
  129. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.ui +44 -0
  130. data/plugins/state/plugin.yaml +28 -0
  131. data/plugins/state/state.rb +520 -0
  132. data/plugins/state/ui/config_widget.rb +92 -0
  133. data/plugins/state/ui/config_widget.ui +89 -0
  134. data/plugins/syntax_checker/plugin.yaml +18 -0
  135. data/plugins/syntax_checker/syntax_checker.rb +662 -0
  136. data/ruber.desktop +10 -0
  137. data/spec/annotation_model_spec.rb +174 -0
  138. data/spec/common.rb +119 -0
  139. data/spec/component_manager_spec.rb +1259 -0
  140. data/spec/document_list_spec.rb +626 -0
  141. data/spec/document_project_spec.rb +373 -0
  142. data/spec/document_spec.rb +779 -0
  143. data/spec/editor_view_spec.rb +167 -0
  144. data/spec/external_program_plugin_spec.rb +676 -0
  145. data/spec/filtered_output_widget_spec.rb +642 -0
  146. data/spec/gui_states_handler_spec.rb +304 -0
  147. data/spec/kde_config_option_backend_spec.rb +214 -0
  148. data/spec/kde_sugar_spec.rb +101 -0
  149. data/spec/ktexteditor_wrapper_spec.rb +305 -0
  150. data/spec/output_widget_spec.rb +1703 -0
  151. data/spec/plugin_spec.rb +1393 -0
  152. data/spec/plugin_specification_reader_spec.rb +1765 -0
  153. data/spec/plugin_specification_spec.rb +401 -0
  154. data/spec/project_backend_spec.rb +172 -0
  155. data/spec/project_files_list_spec.rb +401 -0
  156. data/spec/project_list_spec.rb +511 -0
  157. data/spec/project_spec.rb +990 -0
  158. data/spec/qt_sugar_spec.rb +328 -0
  159. data/spec/settings_container_spec.rb +617 -0
  160. data/spec/settings_dialog_manager_spec.rb +773 -0
  161. data/spec/settings_dialog_spec.rb +419 -0
  162. data/spec/state_spec.rb +991 -0
  163. data/spec/utils_spec.rb +406 -0
  164. data/spec/workspace_spec.rb +869 -0
  165. data/spec/yaml_option_backend_spec.rb +246 -0
  166. metadata +284 -0
@@ -0,0 +1,153 @@
1
+ =begin
2
+ Copyright (C) 2010 by Stefano Crocco
3
+ stefano.crocco@alice.it
4
+
5
+ This program is free software; you can redistribute it andor modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation; either version 2 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program; if not, write to the
17
+ Free Software Foundation, Inc.,
18
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
+ =end
20
+
21
+ module Ruber
22
+
23
+ module Rake
24
+
25
+ =begin rdoc
26
+ Extension which takes care of storing and rebuilding the task list contained in the rake/tasks
27
+ project option when one of the rake/rake, rake/rakefile, rake/options or rake/environment
28
+ changes.
29
+ =end
30
+ class ProjectExtension < Qt::Object
31
+
32
+ include Extension
33
+
34
+ signals :tasks_updated
35
+
36
+ =begin rdoc
37
+ @param [Ruber::AbstractProject] prj the project associated with the extension
38
+ =end
39
+ def initialize prj
40
+ super
41
+ @project = prj
42
+ @project.connect SIGNAL('option_changed(QString, QString)') do |grp, name|
43
+ emit tasks_updated if grp == 'rake' and name == 'tasks'
44
+ end
45
+ end
46
+
47
+ =begin rdoc
48
+ The tasks defined in the rakefile associated with the project
49
+
50
+ This method uses {Rake::Plugin#tasks} to retrieve the list of tasks.
51
+
52
+ @return [Hash] a hash having the task names as keys and their descriptions as
53
+ values
54
+
55
+ @see Rake::Plugin#tasks
56
+ =end
57
+ def tasks
58
+ pars = gather_parameters
59
+ ruby, *ruby_opts = Ruber[:rake].ruby_command_for @project, pars[:dir]
60
+ pars[:ruby_options] = ruby_opts
61
+ Ruber[:rake].tasks ruby, pars[:dir], pars
62
+ end
63
+
64
+ =begin rdoc
65
+ Runs a given task in rake
66
+
67
+ The output from rake is displayed in the associated output widget, according to
68
+ the settings for the associated project.
69
+
70
+ Before running rake, all the open documents belonging to the project are saved using
71
+ autosave (this means that if the associated project is a {DocumentProject}, only
72
+ the corresponding document will be saved).
73
+
74
+ @param [String, nil] task the name of the task to execute or *nil* to execute the
75
+ default task
76
+ @raise RakeError if rake reports an error while executing the rakefile
77
+ @raise RakefileNotFound if rake can't find the rakefile
78
+ @raise Timeout if @rake -T@ doesn't exit after a suitable time
79
+ @return [nil]
80
+ =end
81
+ def run_rake task
82
+ params = gather_parameters
83
+ files = @project.files
84
+ docs= Ruber[:documents].documents_with_file.select{|d| files.include? d.path}
85
+ return unless Ruber[:autosave].autosave Ruber[:rake], docs, :on_failure => :ask
86
+ ruby, *ruby_opts = Ruber[:rake].ruby_command_for @project, params[:dir]
87
+ params[:ruby_options] = ruby_opts
88
+ params[:task] = task
89
+ Ruber[:rake].run_rake ruby, params[:dir], params
90
+ end
91
+
92
+ =begin rdoc
93
+ Updates the @rake/tasks@ project option so that the tasks match those reported
94
+ by rake.
95
+
96
+ @raise {Plugin::RakefileNotFound} if rake reports that no rakefile has been found
97
+ @raise {Plugin::Rake::Timeout} if rake doesn't return the list of task in the amount of time set
98
+ by the user
99
+ @raise {Plugin::Rake::RakeError} if rake aborts with an error
100
+
101
+ @return [nil]
102
+ =end
103
+ def update_tasks
104
+ new_tasks = tasks
105
+ old_tasks = @project[:rake, :tasks]
106
+ new_tasks.each_pair do |k, v|
107
+ data = [v]
108
+ old_data = old_tasks[k]
109
+ data << old_data[1] if old_data and old_data[1]
110
+ new_tasks[k] = data
111
+ end
112
+ @project[:rake, :tasks] = new_tasks
113
+ @project.save
114
+ emit tasks_updated
115
+ self
116
+ end
117
+
118
+ private
119
+
120
+ =begin rdoc
121
+ Retrieves the parameters to run rake with from the associated project.
122
+
123
+ @return [Hash] a hash contains the following entries
124
+ @:rake@: the path of the rake program to use
125
+ @:env@: the environment to pass to rake
126
+ @:options@: the options to pass to rake
127
+ @:dir@: the directory to run rake from
128
+ @:rakefile@: the path of the rakefile to use (relative to the @dir+ entry) or
129
+ *nil* if it is not specified in _prj_. If _prj_ is a {DocumentProject}, this
130
+ entry will always contain the path of the document
131
+ =end
132
+ def gather_parameters
133
+ res = {}
134
+ res[:rake] = @project[:rake, :rake].dup
135
+ res[:env] = @project[:rake, :environment].dup
136
+ res[:options] = @project[:rake, :options].dup
137
+ sync_stdout = @project[:rake, :sync_stdout]
138
+ res[:options] << '-E' << '$stdout.sync = true' if sync_stdout
139
+ rakefile = @project[:rake, :rakefile, :abs] rescue @project.document.path
140
+ rakefile = rakefile.dup if rakefile
141
+ if rakefile
142
+ res[:rakefile] = File.basename rakefile
143
+ res[:dir] = File.dirname rakefile
144
+ else res[:dir] = @project.project_directory.dup
145
+ end
146
+ res
147
+ end
148
+
149
+ end
150
+
151
+ end
152
+
153
+ end
@@ -0,0 +1,615 @@
1
+ =begin
2
+ Copyright (C) 2010 by Stefano Crocco
3
+ stefano.crocco@alice.it
4
+
5
+ This program is free software; you can redistribute it andor modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation; either version 2 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program; if not, write to the
17
+ Free Software Foundation, Inc.,
18
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
+ =end
20
+
21
+ require 'shellwords'
22
+ require 'facets/enumerable/mash'
23
+
24
+ require 'ruber/filtered_output_widget'
25
+
26
+ require_relative 'ui/config_widget'
27
+ require_relative 'ui/add_quick_task_widget'
28
+ require_relative 'ui/choose_task_widget'
29
+ require_relative 'ui/project_widget'
30
+
31
+ class RakeQuickTasksView < Qt::TreeView
32
+ signals :tasks_changed
33
+ end
34
+
35
+ module Ruber
36
+
37
+ module Rake
38
+
39
+ =begin rdoc
40
+ Where the user can choose the rake task to execute
41
+ =end
42
+ class ChooseTaskDlg < KDE::Dialog
43
+
44
+ =begin rdoc
45
+ @param [Qt::Widget, nil] parent the dialog's parent widget
46
+ @param [Ruber::AbstractProject] prj as in {Rake::Plugin#choose_task_for}
47
+ =end
48
+ def initialize prj, parent = Ruber[:main_window]
49
+ super parent
50
+ @ui = Ui::RakeChooseTaskWidget.new
51
+ @ui.setupUi main_widget
52
+ @project = prj
53
+ @ui.tasks.model = Qt::SortFilterProxyModel.new @ui.tasks
54
+ @tasks_model = Qt::StandardItemModel.new self
55
+ @ui.tasks.model.source_model = @tasks_model
56
+ @tasks_model.horizontal_header_labels = %w[Task Description]
57
+ fill_tasks_widget
58
+ enable_button_ok false
59
+ @ui.tasks.selection_model.connect(SIGNAL('selectionChanged(QItemSelection, QItemSelection)')) do
60
+ enable_button_ok @ui.tasks.selection_model.has_selection
61
+ end
62
+ connect @ui.refresh_tasks, SIGNAL(:clicked), self, SLOT(:update_tasks)
63
+ @ui.search_line.proxy = @ui.tasks.model
64
+ @ui.tasks.set_focus
65
+ end
66
+
67
+ =begin rdoc
68
+ The selected task
69
+
70
+ @return [String,nil] the selected task or *nil* if no task has been selected
71
+ =end
72
+ def task
73
+ sel = @ui.tasks.selection_model.selected_rows[0]
74
+ sel ? sel.data.to_string : nil
75
+ end
76
+
77
+ private
78
+
79
+ =begin rdoc
80
+ Inserts the tasks for the object passed to the constructor in the task widget.
81
+
82
+ @Note:@ this method uses the {Rake::ProjectExtension#update_tasks} method,
83
+ so it can take some seconds to complete.
84
+ @return [nil]
85
+ =end
86
+ def fill_tasks_widget
87
+ tasks = @project[:rake, :tasks]
88
+ items = tasks.sort.map{|task, data| [Qt::StandardItem.new(task), Qt::StandardItem.new(data[0])]}
89
+ @tasks_model.remove_rows 0, @ui.tasks.model.row_count
90
+ items.each{|i| @tasks_model.append_row i}
91
+ @ui.tasks.resize_column_to_contents 0
92
+ @ui.tasks.enabled = true
93
+ nil
94
+ end
95
+ slots :fill_tasks_widget
96
+
97
+ =begin rdoc
98
+ Updates the list of tasks
99
+
100
+ @return [nil]
101
+ =end
102
+ def update_tasks
103
+ Ruber::Application.with_override_cursor do
104
+ @project.extension(:rake).update_tasks
105
+ fill_tasks_widget
106
+ end
107
+ end
108
+ slots :update_tasks
109
+
110
+ end
111
+
112
+ =begin rdoc
113
+ Delegate which allows to edit the entries using a @KDE::KeySequenceWidget@
114
+ =end
115
+ class ShortcutDelegate < Qt::StyledItemDelegate
116
+
117
+ =begin rdoc
118
+ @param [Integer] col the column number
119
+ @param [Qt::Widget, nil] parent the parent widget
120
+ =end
121
+ def initialize col, parent = nil
122
+ super parent
123
+ @column = col
124
+ end
125
+
126
+ =begin rdoc
127
+ Override of @Qt::StyledItemDelegate#createEditor@ which returns a
128
+ @KDE::KeySequenceWidget@.
129
+
130
+ @param [Qt::Object] parent the parent object
131
+ @param [Qt::StyleOptionViewItem] opt controls how the editor appears
132
+ @param [Qt::ModelIndex] idx the index the editor is for
133
+ @return [Qt::Widget] the editor widget
134
+ =end
135
+ def createEditor parent, opt, idx
136
+ if idx.column != @column then super
137
+ else
138
+ w = KDE::KeySequenceWidget.new parent
139
+ connect w, SIGNAL('stealShortcut(QKeySequence, KAction*)'), w, SLOT(:applyStealShortcut)
140
+ collections = Ruber[:main_window].factory.clients.map{|cl| cl.action_collection}
141
+ w.check_action_collections = collections
142
+ w
143
+ end
144
+ end
145
+
146
+ =begin rdoc
147
+ Override of @Qt::StyledItemDelegate#setEditorData@ which fills the editor
148
+ with the content of the model.
149
+
150
+ @param [Qt::Widget] w the editor widget
151
+ @param [Qt::ModelIndex] idx the index the editor is for
152
+ @return [nil]
153
+ =end
154
+ def setEditorData w, idx
155
+ if idx.column != @column then super
156
+ else w.key_sequence = Qt::KeySequence.new(idx.data.to_string)
157
+ end
158
+ nil
159
+ end
160
+
161
+ =begin rdoc
162
+ Override of @Qt::StyledItemDelegate#setModelData@ which inserts the contents
163
+ of the shortcut widget in the model.
164
+
165
+ @param [Qt::Widget] w the editor widget
166
+ @param [Qt::AbstractItemModel] the model the index refers to
167
+ @param [Qt::ModelIndex] the index to modify
168
+ @return [nil]
169
+ =end
170
+ def setModelData w, model, idx
171
+ if idx.column != @column then super
172
+ else model.set_data idx, Qt::Variant.new(w.key_sequence.to_string), Qt::DisplayRole
173
+ end
174
+ nil
175
+ end
176
+
177
+ =begin rdoc
178
+ Override of @Qt::StyledItemDelegate#updateEditorGeometry@
179
+
180
+ @param [Qt::Widget] w the editor widget
181
+ @param [Qt::StyleOptionViewItem] opt the option to use when changing the editor
182
+ geometry
183
+ @param [Qt::ModelIndex] the index associated with the editor
184
+ @return [nil]
185
+ =end
186
+ def updateEditorGeometry w, opt, idx
187
+ if idx.column != @column then super
188
+ else
189
+ tl = opt.rect.top_left
190
+ size = w.rect.size
191
+ size.width += 50
192
+ w.geometry = Qt::Rect.new tl, size
193
+ end
194
+ nil
195
+ end
196
+
197
+ end
198
+
199
+ =begin rdoc
200
+ The configuration widget for the plugin
201
+ =end
202
+ class ConfigWidget < Qt::Widget
203
+
204
+ =begin rdoc
205
+ Dialog used by the configuration widget to have the user choose a quick task,
206
+ that is associate a shortcut with a name (which is supposed to correspond to
207
+ a task in the rakefile)
208
+ =end
209
+ class AddQuickActionDlg < KDE::Dialog
210
+
211
+ =begin rdoc
212
+ @param [Qt::Widget,nil] the parent widget
213
+ =end
214
+ def initialize parent = Ruber[:main_window]
215
+ super
216
+ @ui = Ui::RakeAddQuickTaskWidget.new
217
+ @ui.setupUi main_widget
218
+ collections = Ruber[:main_window].factory.clients.map{|cl| cl.action_collection}
219
+ @ui.shortcut.check_action_collections = collections
220
+ connect @ui.shortcut, SIGNAL('stealShortcut(QKeySequence, KAction*)'), @ui.shortcut, SLOT(:applyStealShortcut)
221
+ enable_button_ok false
222
+ @ui.task.set_focus
223
+ connect @ui.task, SIGNAL('textChanged(QString)'), self, SLOT(:change_ok_state)
224
+ connect @ui.shortcut, SIGNAL('keySequenceChanged(QKeySequence)'), self, SLOT(:change_ok_state)
225
+ end
226
+
227
+ =begin rdoc
228
+ The name chosen by the user
229
+ @return [String] the name chosen by the user
230
+ =end
231
+ def task
232
+ @ui.task.text
233
+ end
234
+
235
+ =begin rdoc
236
+ The shortcut chosen by the user
237
+ @return [String] the shortcut chosen by the user
238
+ =end
239
+ def shortcut
240
+ @ui.shortcut.key_sequence.to_string
241
+ end
242
+
243
+ private
244
+
245
+ =begin rdoc
246
+ Enables or disables the Ok button depending on whether both the task name and
247
+ the corresponding shortcut have been chosen
248
+ @return [nil]
249
+ =end
250
+ def change_ok_state
251
+ enable_button_ok !(@ui.task.text.empty? || @ui.shortcut.key_sequence.empty?)
252
+ nil
253
+ end
254
+ slots :change_ok_state
255
+
256
+ end
257
+
258
+ slots :add_task, :remove_current_task, :change_buttons_state
259
+
260
+ =begin rdoc
261
+ @param [Qt::Widget,nil] parent the widget's parent widget
262
+ =end
263
+ def initialize parent = nil
264
+ super
265
+ @ui = Ui::RakeConfigWidget.new
266
+ @ui.setupUi self
267
+ m = Qt::StandardItemModel.new self
268
+ v = @ui._rake__quick_tasks
269
+ @ui._rake__quick_tasks.model = m
270
+
271
+ connect m, SIGNAL('itemChanged(QStandardItem*)'), v, SIGNAL(:tasks_changed)
272
+ connect m, SIGNAL('rowsInserted(QModelIndex, int, int)'), v, SIGNAL(:tasks_changed)
273
+ connect m, SIGNAL('rowsRemoved(QModelIndex, int, int)'), v, SIGNAL(:tasks_changed)
274
+
275
+ @ui._rake__quick_tasks.model.horizontal_header_labels = %w[Tasks Shortcuts]
276
+ delegate = ShortcutDelegate.new 1, @ui._rake__quick_tasks
277
+ @ui._rake__quick_tasks.item_delegate = delegate
278
+ connect @ui.add_task, SIGNAL(:clicked), self, SLOT(:add_task)
279
+ connect @ui.remove_task, SIGNAL(:clicked), self, SLOT(:remove_current_task)
280
+ @ui._rake__quick_tasks.selection_model.connect SIGNAL('selectionChanged(QItemSelection, QItemSelection)') do
281
+ @ui.remove_task.enabled = @ui._rake__quick_tasks.selection_model.has_selection
282
+ end
283
+ end
284
+
285
+ =begin rdoc
286
+ Fills the "Quick tasks" widget
287
+ @param [Hash] tasks the tasks to insert in the widget. The keys are the task names,
288
+ while the values are strings representing the shortcuts to associate to each task
289
+ @return [nil]
290
+ =end
291
+ def read_quick_tasks tasks
292
+ m = @ui._rake__quick_tasks.model
293
+ tasks.each_pair do |k, v|
294
+ m.append_row [Qt::StandardItem.new(k), Qt::StandardItem.new(v)]
295
+ end
296
+ if m.row_count > 0
297
+ @ui._rake__quick_tasks.selection_model.select m.index(0,0), Qt::ItemSelectionModel::ClearAndSelect|Qt::ItemSelectionModel::Rows|Qt::ItemSelectionModel::Current
298
+ end
299
+ nil
300
+ end
301
+
302
+ =begin rdoc
303
+ Gathers data from the "Quick tasks" widget
304
+ @return [Hash] a hash having the task names as keys and strings representing the
305
+ associated shortcuts as values
306
+ =end
307
+ def store_quick_tasks
308
+ m = @ui._rake__quick_tasks.model
309
+ res = {}
310
+ m.each_row do |task, short|
311
+ res[task.text] = short.text
312
+ end
313
+ res
314
+ end
315
+
316
+ private
317
+
318
+ =begin rdoc
319
+ Displays a dialog where the user can create a quick task by associating a (task)
320
+ name with a shortcut.
321
+
322
+ If the user presses the Ok button in the dialog, the new task is added to the task
323
+ widget. If he presses the Cancel button, nothing is done.
324
+ @return [nil]
325
+ =end
326
+ def add_task
327
+ dlg = AddQuickActionDlg.new
328
+ return if dlg.exec == Qt::Dialog::Rejected
329
+ row = [Qt::StandardItem.new(dlg.task), Qt::StandardItem.new(dlg.shortcut)]
330
+ @ui._rake__quick_tasks.model.append_row(row)
331
+ @ui._rake__quick_tasks.selection_model.select row[0].index, Qt::ItemSelectionModel::ClearAndSelect|Qt::ItemSelectionModel::Rows|Qt::ItemSelectionModel::Current
332
+ nil
333
+ end
334
+
335
+ =begin rdoc
336
+ Removes the currently selected entry from the "Quick tasks" widget
337
+
338
+ *Note:* this method assumes an item is selected.
339
+ @return [nil]
340
+ =end
341
+ def remove_current_task
342
+ #We don't check wheter there's a selected item because the Remove task
343
+ #button is disabled if no entry is selected
344
+ row = @ui._rake__quick_tasks.selection_model.selected_rows[0].row
345
+ @ui._rake__quick_tasks.model.remove_row row
346
+ nil
347
+ end
348
+
349
+ end
350
+
351
+ =begin rdoc
352
+ Project configuration widget
353
+ =end
354
+ class ProjectWidget < ProjectConfigWidget
355
+
356
+ slots :refresh_tasks, :add_task, :remove_task
357
+
358
+ =begin rdoc
359
+ @param [Ruber::AbstractProject] prj the project the widget refers to
360
+ =end
361
+ def initialize prj
362
+ super
363
+ @ui = Ui::RakeProjectWidget.new
364
+ @ui.setupUi self
365
+ @ui.tasks.model = Qt::StandardItemModel.new @ui.tasks
366
+ @ui.tasks.item_delegate = ShortcutDelegate.new 1, @ui.refresh_tasks
367
+ view = @ui.tasks
368
+ view.header.resize_mode = Qt::HeaderView::ResizeToContents
369
+ def view.mouseDoubleClickEvent e
370
+ idx = index_at e.pos
371
+ if idx.valid? then super
372
+ else
373
+ it = Qt::StandardItem.new
374
+ model.append_row 3.times.map{Qt::StandardItem.new ''}
375
+ edit it.index
376
+ end
377
+ end
378
+ connect @ui.refresh_tasks, SIGNAL(:clicked), self, SLOT(:refresh_tasks)
379
+ connect @ui.add_task, SIGNAL(:clicked), self, SLOT(:add_task)
380
+ connect @ui.remove_task, SIGNAL(:clicked), self, SLOT(:remove_task)
381
+ view.selection_model.connect SIGNAL('selectionChanged(QItemSelection, QItemSelection)') do
382
+ @ui.remove_task.enabled = !view.selection_model.selected_indexes.empty?
383
+ end
384
+ fill_tasks_widget @project[:rake, :tasks]
385
+ end
386
+
387
+ =begin rdoc
388
+ Fills the Tasks widget according to the rake/tasks and rake/quick_tasks project
389
+ options
390
+ @return [nil]
391
+ =end
392
+ def read_settings
393
+ fill_tasks_widget @project[:rake, :tasks]
394
+ nil
395
+ end
396
+
397
+ =begin rdoc
398
+ Sets the rake/tasks and rake/quick_task project options according to the contents
399
+ of the Tasks widget
400
+ @return [nil]
401
+ =end
402
+ def store_settings
403
+ @project[:rake, :tasks] = tasks
404
+ nil
405
+ end
406
+
407
+ =begin rdoc
408
+ Clears the task widget
409
+ @return [ni;]
410
+ =end
411
+ def read_default_settings
412
+ mod = @ui.tasks.model
413
+ mod.remove_rows 0, mod.row_count
414
+ nil
415
+ end
416
+
417
+ =begin rdoc
418
+ The list of tasks
419
+
420
+ @return [Hash] a hash containing the tasks. The keys are the names of the tasks,
421
+ while the values are arrays having as first argument the task descriptions and
422
+ as second argument a string corresponding to the shortcut chosen by the user,
423
+ or *nil* if no shortcut has been chosen.
424
+ =end
425
+ def tasks
426
+ res = {}
427
+ @ui.tasks.model.each_row do |r|
428
+ unless r[0].text.empty?
429
+ new_task = [r[2].text]
430
+ new_task << r[1].text unless r[1].text.empty?
431
+ res[r[0].text] = new_task
432
+ end
433
+ end
434
+ res
435
+ end
436
+
437
+ =begin rdoc
438
+ Fills the Rake options widget
439
+ @param [<String>] value an array with the rake options
440
+ @return [<String>]
441
+ =end
442
+ def options= value
443
+ @ui._rake__options.text = value.join " "
444
+ end
445
+
446
+ =begin rdoc
447
+ The options set in the Rake options widget
448
+ @return [<String>] an array containing the options chosen by the user, split and
449
+ quoted according to {Shellwords.split_with_quotes}
450
+ =end
451
+ def options
452
+ Shellwords.split_with_quotes @ui._rake__options.text
453
+ end
454
+
455
+ =begin rdoc
456
+ Fills the Rake environment widget
457
+ @param [<String>] value an array containing the environment variables to set. Each
458
+ entry of the array should have the form @ENV_VAR=value@ (with quotes added as needed)
459
+ @return [<String>]
460
+ =end
461
+ def environment= value
462
+ @ui._rake__environment.text = value.join " "
463
+ end
464
+
465
+ =begin rdoc
466
+ The environment variables set in the Environment variables widget
467
+ @return [<String>] the environment variables chosen by the user, split according
468
+ to {Shellwords.split_with_quotes}.
469
+ =end
470
+ def environment
471
+ Shellwords.split_with_quotes @ui._rake__environment.text
472
+ end
473
+
474
+ =begin rdoc
475
+ Fills the rakefile widget
476
+ @param [String,nil] value the path to the rakefile to use or *nil* to let rake
477
+ decide
478
+ @return [String]
479
+ =end
480
+ def rakefile= value
481
+ @ui._rake__rakefile.text = value || ''
482
+ end
483
+
484
+ =begin rdoc
485
+ The rakefile chosen by the user
486
+ @return [String,nil] the path to the rakefile chosen by the user or *nil* to let
487
+ rake decide
488
+ =end
489
+ def rakefile
490
+ text = @ui._rake__rakefile.text
491
+ text.empty? ? nil : text
492
+ end
493
+
494
+ private
495
+
496
+ =begin rdoc
497
+ Fills the task widget with an up to date list of tasks, according to the current
498
+ content of the various widgets
499
+
500
+ Shortcut assigned to tasks which still exist after the update are kept.
501
+
502
+ This also enables the Tasks widget and hides the outdated tasks warning.
503
+
504
+ If the tasks couldn't be retrieved because of a rake error, a message box is shown
505
+ and nothing is done
506
+ @return [nil]
507
+ =end
508
+ def refresh_tasks
509
+ new_tasks = begin find_updated_tasks
510
+ rescue Rake::Error => e
511
+ Ruber[:rake].display_task_retrival_error_dialog ex
512
+ end
513
+ new_tasks.each_pair{|k, v| new_tasks[k] = [v]}
514
+ old_tasks = tasks
515
+ old_tasks.each_pair do |t, data|
516
+ if data[1]
517
+ new = new_tasks[t]
518
+ new << data[1] if new
519
+ end
520
+ end
521
+ fill_tasks_widget new_tasks
522
+ nil
523
+ end
524
+
525
+ =begin rdoc
526
+ Fills the task widget
527
+ @param [Hash] tasks a hash with the information about the tasks to display. The
528
+ keys of the hash are the task names, while the values are arrays of size 1 or 2.
529
+ The first element of the array is a string representing the task description,
530
+ while the second, if it exists, is a string representing the shortcut associated
531
+ with the task
532
+ *Note:* the previous contents of the widget will be removed
533
+ @return [nil]
534
+ =end
535
+ def fill_tasks_widget tasks
536
+ mod = @ui.tasks.model
537
+ mod.clear
538
+ tasks = tasks.sort
539
+ @ui.tasks.model.horizontal_header_labels = %w[Task Shortcut Description]
540
+ tasks.each do |n, i|
541
+ name = Qt::StandardItem.new n
542
+ desc = Qt::StandardItem.new i[0]
543
+ key = Qt::StandardItem.new(i[1] || '')
544
+ mod.append_row [name, key, desc]
545
+ end
546
+ nil
547
+ end
548
+
549
+ =begin rdoc
550
+ Uses the values in the Rake, Rake program, Rake options and environment variables
551
+ widgets to retrieve an up-to-date list of tasks
552
+
553
+ @raise {Plugin::RakeError} if rake fails
554
+ @return [Hash] a hash with the information about the tasks to display. The
555
+ keys of the hash are the task names, while the values are arrays of size 1 or 2.
556
+ The first element of the array is a string representing the task description,
557
+ while the second, if it exists, is a string representing the shortcut associated
558
+ with the task
559
+ =end
560
+ def find_updated_tasks
561
+ rake = @ui._rake__rake.text
562
+ rakefile = @ui._rake__rakefile.text
563
+ rakefile = nil if rakefile.empty?
564
+ rake_options = Shellwords.split_with_quotes @ui._rake__options.text
565
+ rake_options << '-T'
566
+ env = Shellwords.split_with_quotes(@ui._rake__environment.text).select{|s| s.include? '='}
567
+ dir = @project.project_directory
568
+ if rakefile
569
+ rel_dir = File.dirname(rakefile)
570
+ dir = File.join dir, rel_dir unless rel_dir == '.'
571
+ end
572
+ ruby, *ruby_opts = Ruber[:rake].ruby_command_for @project, dir
573
+ Ruber[:app].with_override_cursor do
574
+ begin
575
+ Ruber[:rake].tasks ruby, dir, :env => env, :ruby_options => ruby_opts,
576
+ :rake_options => rake_options, :rakefile => rakefile, :rake => rake,
577
+ :timeout => @ui._rake__timeout.value
578
+ rescue Error => ex
579
+ display_task_retrival_error_dialog ex
580
+ return
581
+ end
582
+ end
583
+ end
584
+
585
+ =begin rdoc
586
+ Displays a dialog where the user can add a new task and adds it to the task widget
587
+ @return [nil]
588
+ =end
589
+ def add_task
590
+ name = Qt::InputDialog.get_text self, 'Add task', 'Task name'
591
+ return if name.nil? or name.empty?
592
+ row = [name, '', ''].map{|i| Qt::StandardItem.new i}
593
+ @ui.tasks.model.append_row row
594
+ nil
595
+ end
596
+
597
+ =begin rdoc
598
+ Removes the currently selected task from the task widget
599
+
600
+ *Note:* this method assumes a task is selected
601
+ @return [nil]
602
+ =end
603
+ def remove_task
604
+ #We don't check whether a task is selected or not as the button should
605
+ #be disabled otherwise
606
+ idx = @ui.tasks.selection_model.selected_indexes.first
607
+ @ui.tasks.model.remove_row idx.row
608
+ nil
609
+ end
610
+
611
+ end
612
+
613
+ end
614
+
615
+ end