Class: Ruber::FindInFiles::ReplaceWidget
- Inherits:
-
OutputWidget
- Object
- Qt::Widget
- OutputWidget
- Ruber::FindInFiles::ReplaceWidget
- Defined in:
- plugins/find_in_files/find_in_files_widgets.rb
Overview
Tool widget which displays the results of a replace operation
The widget consists of a checkable tree view with two columns. The first column contains the text which will be replaced, while the second contains the text after the replacement. The user can uncheck the replacements he doesn’t want, both linewise or filewise. The replacement is only carried out when the user presses the Replace button in the tool widget. A Clear button empties the tool widget.
Defined Under Namespace
Classes: Model
Constant Summary
Constants inherited from OutputWidget
Instance Attribute Summary
Attributes inherited from OutputWidget
action_list, actions, auto_scroll, ignore_word_wrap_option, model, skip_first_file_in_title, view, working_dir
Instance Method Summary (collapse)
-
- (nil) add_line(file, line, orig, repl)
Adds a replacement line to the widget.
-
- (nil) clear_output
Empties the widget.
-
- (nil) display_output(lines)
Inserts the name of the files in the output widget.
-
- (nil) file_modified(file)
slot
private
Slot called when a file among those listed for replacement is modified on disk.
-
- (ReplaceWidget) initialize(parent = nil)
constructor
Creates a new instance.
-
- (nil) replace
slot
private
Performs the replacements chosen by the user.
-
- (Symbol, ...) replace_file(it, doc)
private
Carries out the replacements for a file.
Methods inherited from OutputWidget
#copy, #copy_selected, #create_standard_actions, #create_widgets, #do_auto_scroll, #fill_menu, #find_filename_in_index, #find_filename_in_string, #has_title?, #hints, #load_settings, #maybe_open_file, #pinned_down?, #rows_changed, #scroll_to, #selection_changed, #set_color_for, #set_output_type, #setup_model, #show_menu, #text_for_clipboard, #title=, #update_index_color, #with_auto_scrolling
Methods included from GuiStatesHandler
#change_state, included, #initialize_states_handler, #register_action_handler, #remove_action_handler_for, #state
Signal Summary
-
- file_added(QString str)
Signal emitted when a new file is added to the model.
Constructor Details
- (ReplaceWidget) initialize(parent = nil)
Creates a new instance
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
# File 'plugins/find_in_files/find_in_files_widgets.rb', line 235 def initialize parent = nil super parent, :view => :tree, :use_default_font => true self.auto_scroll = false model.global_flags |= Qt::ItemIsUserCheckable.to_i def model.flags idx if idx.column == 0 then super idx else (Qt::ItemIsEnabled | Qt::ItemIsSelectable).to_i end end @replace_button = Qt::PushButton.new( 'Replace', self){self.enabled = false} @clear_button = Qt::PushButton.new('Clear', self){self.enabled = false} layout. view layout. view, 0,0,1,0 layout. @replace_button, 1, 0 layout. @clear_button, 1, 1 model.horizontal_header_labels = ['Line', 'Original text', 'Replacement text'] @file_items = {} @watcher = KDE::DirWatch.new self connect @watcher, SIGNAL('dirty(QString)'), self, SLOT('file_modified(QString)') connect @replace_button, SIGNAL(:clicked), self, SLOT(:replace) connect @clear_button, SIGNAL(:clicked) , self, SLOT(:clear_output) self.connect(SIGNAL(:about_to_fill_menu)) do actions.delete 'copy' actions.delete 'copy_selected' action_list.delete 'copy' action_list.delete 'copy_selected' end model.connect(SIGNAL('rowsInserted(QModelIndex, int, int)')) do |par, st, en| if !par.valid? st.upto(en) do |i| view.set_first_column_spanned i, par, true view. model.index(i, 0, par) end end end Ruber[:find_in_files].connect SIGNAL(:replace_search_started) do @replace_button.enabled = false @clear_button.enabled = false view.header.resize_mode = Qt::HeaderView::Fixed self.cursor = Qt::Cursor.new Qt::WaitCursor end Ruber[:find_in_files].connect SIGNAL(:replace_search_finished) do @watcher.start_scan @replace_button.enabled = true @clear_button.enabled = true h = view.header view.resize_column_to_contents 0 view.header.resize_mode = Qt::HeaderView::Fixed av_size = h.rect.width - h.section_size( 0) view.set_column_width 1, av_size / 2.0 view.set_column_width 2, av_size / 2.0 unset_cursor end view.all_columns_show_focus = true end |
Instance Method Details
- (nil) add_line(file, line, orig, repl)
Adds a replacement line to the widget
A replacement line is made of three columns: the line number in the file, the original text and the text after the replacement.
324 325 326 327 328 329 330 |
# File 'plugins/find_in_files/find_in_files_widgets.rb', line 324 def add_line file, line, orig, repl parent = @file_items[file] row = model.insert [(line+1).to_s, orig, repl], [:output1, :output, :output], nil, :parent => parent row[0].checked = true view. parent.index nil end |
- (nil) clear_output
Empties the widget
337 338 339 340 341 342 343 |
# File 'plugins/find_in_files/find_in_files_widgets.rb', line 337 def clear_output @file_items.clear @file_items.each_key{|k| @watcher.remove_file k} @replace_button.enabled = false @clear_button.enabled = false super end |
- (nil) display_output(lines)
Inserts the name of the files in the output widget
Each file is added to the file watcher, so that replacing in it can be disabled if it changes.
300 301 302 303 304 305 306 307 308 309 310 |
# File 'plugins/find_in_files/find_in_files_widgets.rb', line 300 def display_output lines lines.each do |l| it = model.insert([l, nil, nil], :message, nil)[0] it.checked = true @watcher.add_file l @watcher.stop_scan @file_items[l] = it emit file_added(l) end nil end |
- (nil) file_modified(file) (private)
Slot called when a file among those listed for replacement is modified on disk
When this happens, the file is marked as modified in the view and it is no longer checkable (the same happens for its children)
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
# File 'plugins/find_in_files/find_in_files_widgets.rb', line 445 def file_modified file @watcher.remove_file file it = @file_items[file] if it it.text = it.text + "\t [MODIFIED]" it.checked = false view.collapse it.index model.set_data it.index, Qt::Variant.new, Qt::ForegroundRole it.flags = Qt::ItemIsSelectable it.each_row do |r| r[0].checked = false r.each{|i| i.flags = Qt::ItemIsSelectable} end end nil end |
Slot Signature:
file_modified(QString)
- (nil) replace (private)
Performs the replacements chosen by the user
Calling this method applies replaces the original text with the replacement texts for all the lines chosen by the user (that is, the checked lines which belong to a checked file). A message box is shown if some replacements cannot be carrried out.
Items corresponding to successful replacements are removed from the view.
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 |
# File 'plugins/find_in_files/find_in_files_widgets.rb', line 359 def replace failed = {} success = [] docs = Ruber[:world].documents.documents_with_file.map{|d| [d.path, d]}.to_h model.each_row.each_with_index do |r, i| if r[0].checked? res = replace_file r[0], docs[r[0].text] if res then failed[r[0].text] = res else success << r[0] end end end success.reverse_each do |i| @file_items.delete i.text model.remove_row i.row end = Proc.new do |f, err| if err == :doc_modified then "#{f}: modified in editor" else "#{f}: #{err.}" end end unless failed.empty? failed_text = failed.map{|f, err| .call f, err}.join "\n" KDE::MessageBox.sorry Ruber[:main_window], "The following files couldn't be modified:\n#{failed_text}" end nil end |
Slot Signature:
replace()
- (Symbol, ...) replace_file(it, doc) (private)
Carries out the replacements for a file
If the file is associated with a document and the document isn’t modified, the text in the editor is changed to reflect the modifications in the file. If the document is modified (which means its contents differ from the contents of the file), instead, nothing will be done.
correctly; an exception derived from SystemCallError
if it wasn’t possible to
write the file and the symbol :doc_modified
if the replacement wasn’t attempted
because the document corresponding to the file was modified
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 |
# File 'plugins/find_in_files/find_in_files_widgets.rb', line 402 def replace_file it, doc file = it.text lines_to_replace = {} it.each_row do |line, _, repl| lines_to_replace[line.text.to_i] = repl.text if line.checked? end lines = File.readlines(file) lines_to_replace.each_pair{|idx, text| lines[idx - 1] = text + "\n"} new_text = lines.join '' if doc pos = doc.view.cursor_position if doc.view return :doc_modified if doc.modified? text = nil doc.editing do text = doc.text doc.clear doc.text = new_text end doc.save #If the document doesn't have a view, pos will be nil doc.view.go_to pos.line, pos.column if pos else Tempfile.open(File.basename(file)) do |f| f.write new_text f.flush begin FileUtils.cp f.path, file rescue SystemCallError => e return e end end end nil end |
Signal Details
- file_added(QString str)
Signal emitted when a new file is added to the model.