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