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,239 @@
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 'facets/enumerable/sum'
22
+
23
+ module Ruber
24
+
25
+ class MainWindow < KParts::MainWindow
26
+
27
+ =begin rdoc
28
+ A list of strings to be used to create the filter for open file dialogs
29
+ =end
30
+ OPEN_DLG_FILTERS = [
31
+ '*.rb|Ruby source file (*.rb)',
32
+ '*.yaml *.yml|YAML files (*.yaml, *.yml)',
33
+ '*|All files'
34
+ ]
35
+
36
+ slots 'remove_view(QWidget*)', 'document_modified_changed(bool)',
37
+ :document_url_changed, :next_document, :previous_document,
38
+ 'store_splitter_sizes(QString)', 'update_document_icon(QObject*)',
39
+ 'remove_plugin_ui_actions(QObject*)', 'close_project_files(QObject*)'
40
+
41
+ private
42
+
43
+ =begin rdoc
44
+ Checks whether an editor view for the given document exists and creates it if it
45
+ doesn't. In both cases, An editor view for the document is returned. _doc_ is the
46
+ Document for which the editor should be created.
47
+
48
+ <b>Note:</b> this also creates a new tab with the new view, if it needs to create
49
+ one
50
+ =end
51
+ def create_editor_if_needed doc
52
+ if doc.view then doc.view
53
+ else
54
+ view = doc.create_view
55
+ @editors_mapper.set_mapping view, view
56
+ connect view, SIGNAL(:closing), @editors_mapper, SLOT(:map)
57
+ connect view.document, SIGNAL('modified_changed(bool, QObject*)'), self, SLOT('document_modified_changed(bool)')
58
+ connect view.document, SIGNAL('modified_on_disk(QObject*, bool, KTextEditor::ModificationInterface::ModifiedOnDiskReason)'), self, SLOT('update_document_icon(QObject*)')
59
+ connect view.document, SIGNAL('document_url_changed(QObject*)'), self, SLOT(:document_url_changed)
60
+ @views.add_tab view, doc.icon, doc.document_name
61
+ view
62
+ end
63
+ end
64
+
65
+ =begin rdoc
66
+ Changes the icon in the tab corresponding to the Document _doc_ so that it reflects
67
+ its current status
68
+ =end
69
+ def update_document_icon doc
70
+ ed = editor_for doc
71
+ return unless ed
72
+ idx = @views.index_of ed
73
+ return unless idx
74
+ @views.set_tab_icon idx, doc.icon
75
+ end
76
+
77
+ =begin rdoc
78
+ Opens a file, creating a document and an editor for it, activates and gives focus
79
+ to the editor and adds the file to the list of recent files. _file_ is the absolute
80
+ path of the file to open
81
+ =end
82
+ def gui_open_file file
83
+ editor = editor_for! file
84
+ return unless editor
85
+ focus_on_editor editor
86
+ url = KDE::Url.from_path(file)
87
+ action_collection.action('file_open_recent').add_url url, url.file_name
88
+ end
89
+
90
+ =begin rdoc
91
+ If _ed_ is the active editor, it deactivates it and removes it from the gui. If
92
+ _ed_ is not the active editor (or if it's *nil*), nothing is done.
93
+
94
+ <b>Note:</b> this doesn't change the status bar associated with the view.
95
+ =end
96
+ def deactivate_editor ed
97
+ return unless ed and ed == @active_editor
98
+ @active_editor.document.deactivate
99
+ gui_factory.remove_client ed.send( :internal)
100
+ end
101
+
102
+ =begin rdoc
103
+ Remove the editor _ed_ from the tab widget, deactivating it before (if needed).
104
+ If automatical activation of editors is on, it also activates another editor,
105
+ if any
106
+ =end
107
+ def remove_view ed
108
+ status_bar.view = nil if ed == @active_editor
109
+ deactivate_editor ed
110
+ idx = @views.index_of ed
111
+ @views.remove_tab idx
112
+ #This assumes that only one editor can exist for each document
113
+ ed.document.disconnect SIGNAL('modified_changed(bool, QObject*)'), self
114
+ ed.document.disconnect SIGNAL('document_url_changed(QObject*)'), self
115
+ if @views.current_widget and @auto_activate_editors
116
+ activate_editor @views.current_widget
117
+ @views.current_widget.set_focus
118
+ end
119
+ end
120
+
121
+ protected
122
+
123
+ =begin rdoc
124
+ Override of <tt>KParts::MainWindow#queryClose</tt> which calls the <tt>query_close</tt>
125
+ method of the component manager. This means that the latter method will be called
126
+ everytime the application is closed.
127
+ =end
128
+ def queryClose
129
+ Ruber[:components].query_close
130
+ end
131
+
132
+ =begin rdoc
133
+ Override of <tt>KParts::MainWindow#queryExit</tt> which calls the +shutdown+ method
134
+ of the component
135
+ =end
136
+ def queryExit
137
+ Ruber[:app].quit_ruber
138
+ true
139
+ end
140
+
141
+ =begin rdoc
142
+ Saves the properties for session management.
143
+ TODO: currently, session management doesn't work at all. So, either remove the
144
+ method or make it work
145
+ =end
146
+ def saveProperties conf
147
+ data = YAML.dump @session_data
148
+ conf.write_entry 'Ruber', data
149
+ end
150
+
151
+ =begin rdoc
152
+ Reads the properties from the config object for session management
153
+ =end
154
+ def readProperties conf
155
+ @last_session_data = YAML.load conf.read_entry('Ruber', '{}')
156
+ end
157
+
158
+ =begin rdoc
159
+ Creates a suitable title for the main window.
160
+ =end
161
+ def make_title
162
+ title = ''
163
+ prj = Ruber[:projects].current_project
164
+ if prj
165
+ title << (prj.project_name ? prj.project_name :
166
+ File.basename(prj.project_file, '.ruprj'))
167
+ end
168
+ if @active_editor and @active_editor.document.path.empty?
169
+ title << ' - ' << @active_editor.document.document_name
170
+ elsif @active_editor
171
+ title << ' - ' << @active_editor.document.path
172
+ end
173
+ title.sub!(/\A\s+-/, '')
174
+ mod = current_document.modified? rescue false
175
+ set_caption title, mod
176
+ end
177
+
178
+ =begin rdoc
179
+ :call-seq: document_modified_changed(mod) [SLOT]
180
+
181
+ Slot called whenever the modified status of a document changes. It updates the
182
+ icon on the tab of the document's editor and the window title (if the document
183
+ was the active one) accordingly.
184
+ =end
185
+ def document_modified_changed mod
186
+ doc = self.sender
187
+ make_title
188
+ #This assumes that only one editor exists for each document
189
+ update_document_icon doc
190
+ end
191
+
192
+ =begin rdoc
193
+ Slot called whenever the document url changes (usually because the document has
194
+ been saved). It changes the title and icon of the tab and changes the title of the
195
+ window is the document is active.
196
+ =end
197
+ def document_url_changed
198
+ doc = self.sender
199
+ make_title
200
+ idx = @views.index_of doc.view
201
+ @views.set_tab_text idx, doc.document_name
202
+ update_document_icon doc
203
+
204
+ unless doc.path.empty?
205
+ action_collection.action('file_open_recent').add_url KDE::Url.new(doc.path)
206
+ end
207
+ end
208
+
209
+ =begin rdoc
210
+ Removes the action handlers for all the actions belonging to the plugin _plug_
211
+ from the list of handlers
212
+ =end
213
+ def remove_plugin_ui_actions plug
214
+ @actions_state_handlers.delete_if do |state, hs|
215
+ hs.delete_if{|h| h.plugin == plug}
216
+ hs.empty?
217
+ end
218
+ end
219
+
220
+ =begin
221
+ Sets the UI states defined by the main window to their initial values.
222
+ =end
223
+ def setup_initial_states
224
+ change_state 'active_project_exists', false
225
+ change_state 'current_document', false
226
+ end
227
+
228
+ def close_project_files prj
229
+ to_close = @views.select do |v|
230
+ prj.project_files.file_in_project? v.document.path
231
+ end
232
+ save_documents to_close.map &:document
233
+ to_close.each{|v| v.document.close}
234
+ end
235
+
236
+
237
+ end
238
+
239
+ end
@@ -0,0 +1,212 @@
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 'facets/boolean'
22
+
23
+ require 'pathname'
24
+
25
+ require_relative "ui/open_file_in_project_dlg"
26
+
27
+ module Ruber
28
+
29
+ =begin rdoc
30
+ This class is a dialog where the user can choose a file to open among the
31
+ files of the project.
32
+
33
+ The dialog is made by two widgets: a <tt>KDE::LineEdit</tt>, where the user
34
+ can enter a file pattern, and a <tt>Qt::ListView</tt>, where all files in
35
+ the project matching the
36
+ given regexp are shown. The user can choose the file either by pressing the
37
+ Return key or by activating an item in the list.
38
+
39
+ The pattern is interpreted as a regexp and is checked against the whole path
40
+ of the file if it contains a pattern separator character (the '/' character
41
+ on UNIX) and only
42
+ against the name of the file otherwise. When the user changes the pattern,
43
+ the file list is changed accordingly. This is achieved using a
44
+ filter model derived from <tt>Qt::SortFilterProxyModel</tt>.
45
+ =end
46
+ class OpenFileInProjectDlg < Qt::Dialog
47
+
48
+ =begin rdoc
49
+ Class implementing the filter for the +OpenFileInProjectDlg+ class.
50
+ =end
51
+ class FilterModel < Qt::SortFilterProxyModel
52
+
53
+ =begin rdoc
54
+ Returns a new +FilterModel+.
55
+ =====Arguments
56
+ _parent_:: the <tt>Qt::Object</tt> parent of the filter
57
+ =end
58
+ def initialize parent = nil
59
+ super
60
+ @filter = nil
61
+ @role = Qt::DisplayRole
62
+ end
63
+
64
+ =begin rdoc
65
+ Changes the regexp used to filter the files, then re-applies the filter
66
+ calling the +invalidate+ method.
67
+ =====Arguments
68
+ _value_:: the new regexp. It can be +nil+ or a regexp. In the first case,
69
+ the filter won't be applied.
70
+ =====TODO
71
+ On Windows, allow to also use the '\' character as pattern separator.
72
+ The problem is that that character is also the escape character in a regexp,
73
+ so things may become complicated.
74
+ =end
75
+ def filter= value
76
+ @filter = value
77
+ # TODO This doesn't work
78
+ #on windows, where one can also use \ as separator. The problem is that in regexp
79
+ #it's the escape character, so one must use something like
80
+ #value.include?(File::SEPARATOR) || (File::ALT_SEPARATOR and value.match(/\\{2}))
81
+ @role = if @filter and !value.source.include?(File::SEPARATOR) then Qt::UserRole + 1
82
+ else Qt::DisplayRole
83
+ end
84
+ invalidate
85
+ end
86
+
87
+ protected
88
+
89
+ =begin rdoc
90
+ Reimplementation of Qt::SortFilterProxyModel#filterAcceptsRow which returns
91
+ +true+ if the file matches the regexp and +false+ otherwise (if the regexp
92
+ is +nil+, this method always returns +true+).
93
+
94
+ If the source of the regexp contains the pattern separator, the whole
95
+ filename is tested, otherwise only the name of the file will be tested.
96
+ =end
97
+ def filterAcceptsRow r, parent
98
+ return true unless @filter
99
+ idx = source_model.index r, 0, parent
100
+ res = idx.data(@role).to_string.match @filter
101
+ res.to_bool #It seems that it's required to return true or false - other objects don't work
102
+ end
103
+
104
+ end
105
+
106
+ slots 'change_filter(const QString &)', 'item_activated(const QModelIndex &)'
107
+
108
+ =begin rdoc
109
+ Returns a new +OpenFileInProjectDlg+.
110
+ =====Arguments
111
+ _parent_:: the widget parent of the dialog
112
+ =end
113
+ def initialize parent = nil
114
+ super
115
+ files = Ruber.current_project.project_files.to_a
116
+ @base_dir = Ruber.current_project.project_directory
117
+ @ui = Ui::OpenFileInProjectDlg.new
118
+ @ui.setupUi self
119
+ @ui.regexp_error.hide
120
+ filter = FilterModel.new @ui.file_list
121
+ model = Qt::StandardItemModel.new filter
122
+ @ui.file_list.model = filter
123
+ filter.source_model = model
124
+ files.each do |f|
125
+ path = f.sub %r{\A#{Regexp.quote(@base_dir)}/}, ''
126
+ it = Qt::StandardItem.new path
127
+ it.set_data Qt::Variant.new(File.basename(path))
128
+ it.editable = false
129
+ model.append_row it
130
+ end
131
+ @ui.pattern.install_event_filter self
132
+ connect @ui.pattern, SIGNAL('textChanged(const QString &)'), self, SLOT('change_filter(const QString &)')
133
+ connect @ui.file_list, SIGNAL('activated(const QModelIndex &)'), self, SLOT('item_activated(const QModelIndex &)')
134
+ @ui.file_list.selection_model.select @ui.file_list.model.index(0,0),
135
+ Qt::ItemSelectionModel::ClearAndSelect|Qt::ItemSelectionModel::Rows
136
+ @ui.file_list.current_index = @ui.file_list.model.index(0,0)
137
+ # @ui.file_list.header.resize_sections Qt::HeaderView::ResizeToContents
138
+ end
139
+
140
+ =begin rdoc
141
+ Returns the file chosen by the user or +nil+ if no file has been chosen. The
142
+ chosen file is the file last selected in the file list.
143
+ =end
144
+ def chosen_file
145
+ selection = @ui.file_list.selection_model.selected_indexes
146
+ return nil if selection.empty?
147
+ idx = selection.first
148
+ File.join(@base_dir, idx.data.to_string.gsub(/\A\./,''))
149
+ end
150
+
151
+ =begin rdoc
152
+ Reimplements Qt::Object.eventFilter. It blocks the +KeyPress+ events for the
153
+ up and down keys (but only if there's no modifier) and redirects them to the
154
+ file list widget. All other events are allowed to pass. This allows to scroll
155
+ the list without taking the focus from the pattern widget.
156
+ =====Arguments
157
+ _obj_:: the object whose events should be filtered
158
+ _e_:: the event
159
+ =end
160
+ def eventFilter obj, e
161
+ if e.type != Qt::Event::KeyPress then return false
162
+ else
163
+ if (e.key == Qt::Key_Down || e.key == Qt::Key_Up) and e.modifiers == Qt::NoModifier
164
+ # TODO: reintroduce the last parameter when it stops giving errors
165
+ new_ev = Qt::KeyEvent.new e.type, e.key, e.modifiers, e.text,
166
+ e.is_auto_repeat, e.count
167
+ Ruber[:app].post_event @ui.file_list, new_ev
168
+ true
169
+ else false
170
+ end
171
+ end
172
+ end
173
+
174
+ private
175
+
176
+ =begin rdoc
177
+ Changes the pattern used by the filter model applied to the view so that it is
178
+ equal to the text currently in the pattern widget and selects the first item in
179
+ the view (if any). If the list is empty, it also disables the Ok button.
180
+ =====Arguments
181
+ _text_:: the new pattern
182
+ =end
183
+ def change_filter text
184
+ begin
185
+ reg = text.empty? ? nil : Regexp.new( text )
186
+ @ui.file_list.model.filter= reg
187
+ @ui.file_list.selection_model.select @ui.file_list.model.index(0,0),
188
+ Qt::ItemSelectionModel::ClearAndSelect|Qt::ItemSelectionModel::Rows
189
+ @ui.file_list.current_index = @ui.file_list.model.index(0,0)
190
+ @ui.buttons.button(Qt::DialogButtonBox::Ok).enabled = @ui.file_list.model.row_count > 0
191
+ @ui.regexp_error.hide
192
+ rescue RegexpError
193
+ @ui.regexp_error.show
194
+ end
195
+ end
196
+
197
+ =begin rdoc
198
+ Closes the dialog with the <tt>Qt::Dialog::Accepted</tt> status and selects the
199
+ index passed as argument.
200
+ =====Arguments
201
+ _idx_:: the index of the activated item.
202
+ =end
203
+ def item_activated idx
204
+ @ui.file_list.selection_model.select idx, Qt::ItemSelectionModel::ClearAndSelect|
205
+ Qt::ItemSelectionModel::Rows
206
+ @ui.file_list.current_index = idx
207
+ accept
208
+ end
209
+
210
+ end
211
+
212
+ end