ruber 0.0.1.1

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 (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