Mercurial > hg > octave-nkf
comparison libgui/src/m-editor/file-editor-tab.cc @ 15848:424edeca3c66
Redo portions of file editor to use more signals/slots rather than casting.
* file-editor-tab.cc, file-editor-tab.h (file_editor_tab::~file_editor_tab):
Add. Delete lexer to prevent memory leak. Delete _edit_area to prevent memory
leak. (file_editor_tab::conditional_close): Add. Simple slot that uses QWidget
pointer as unique ID, not for function call.
(file_editor_tab::file_name_query): Add. Simple slot that signals file name to
whomever is connected. (file_editor_tab::find,
file_editor_tab : public QWidget): Removed use of exec() and keep a pointer to
the find_dialog as a member. Toggle hide()/show() via a connected slot to
toggle visibility as desired.
* file-editor.cc, file-editor.h, file-editor-tab.cc file-editor-tab.h
(file_editor : public file_editor_interface, file_editor_tab : public QWidget,
file_editor_tab::file_editor_tab, file_editor_tab::closeEvent,
file_editor_tab::load_file, file_editor_tab::new_file,
file_editor_tab::run_file): Remove _file_editor pointer member from
file_editor_tab and rid file_editor::get_main_window from file_editor. There
should be no need for such information about higher-level hierarchy inside
lower-level objects. (file_editor::request_open_file,
file_editor_tab::open_file): Move QFileDialog to file_editor::request_open_file
and delete file_editor_tab::open_file since most of the remaining functionality
is in file_editor_tab::load_file. (file_editor::active_editor_tab): Deleted.
(file_editor::fetab_change_request, file_editor_tab::change_editor_state):
Added to initiate a request for the editor tab to change focus.
(file_editor_tab::editor_state_changed): Added arguments to pass the copy
status and the directory path so that editor doesn't have to call functions for
such information. (file_editor::handle_editor_state_changed): Add copying
directory of the file_editor_tab to the current editing directory.
(file_editor::check_conflict_save, file_editor_tab::editor_check_conflict_save,
file_editor_tab::save_file_as, file_editor_tab::handle_save_file_as_answer):
Moved a portion of the save-file-as dialog mechanism to the file_editor where
all file names can be obtained to check for conflict with already open files.
The new signal indicates to the editor that a name check be done, and in turn
the editor signals the tab to save the file.
* main-window.cc, file-editor.cc, file-editor.h, file-editor-interface.h
(file_editor::terminal, file_editor : public file_editor_interface,
file_editor_interface : public QDockWidget): Since file_editor_tab no longer
looks up to main_window, remove _main_window and _terminal from file_editor and
file_editor_interface, as well as file_editor::terminal.
* file-editor-tab.cc (file_editor_tab::file_has_changed): Make the dialog
boxes non-modal and use slots to handle user answers.
(file_editor_tab::closeEvent): Remove portion that accesses upper hierarchy
member functions, can find better approaches.
(file_editor_tab::file_editor_tab): Make there no parent for QsciScintilla so
that window modality can be set to individual editor.
* file-editor-tab.cc, file-editor.cc (file_editor_tab::load_file): Use show()
member rather than exec() and set modality to window so that rest of
application may function. Return a QString with message rather than a boolean.
* file-editor-tab.cc, (file_editor_tab::file_has_changed): Remove static
variable alreadyAsking. Multiple file_editor_tabs are using this code so do
not want to block recognition of multiple file having changed on disk
(bug #37406). Instead, simply stop tracking via the file watcher.
(file_editor_tab::save_file, file_editor_tab::save_file_as,
file_editor_tab::handle_save_file_as_answer,
file_editor_tab::handle_save_file_as_answer_close): Added a remove_on_success
variable. Changed the QFileDialog to WindowModal and created slots to handle
file selected signal and finished signal. Signal/slot connects vary based upon
remove_on_success setting. (file_editor_tab::check_file_modified): Changed the
QFileDialog to NonModal and attach some slots. Editor tab can't be parent in
case deleted, so use read-only state of the editor area.
* file-editor-tab.h (file_editor_tab : public QWidget): New signals for
file_editor for tab and file name management. (file_editor_tab::get_file_name):
Delete.
* file-editor.h (file_editor : public file_editor_interface): Make QStringList
sessionFileNames a member of file_editor so that it can retain data between
file_editor_tab signals. Also can be used for checking precense of filenames
and prevent opening multiple copies (bug #36869) Added signals for file editor
tabs--settings_changed, fetab_close_request, and query_file_name. Three new
slots for tab and file name management.
* file-editor-interface.h, file-editor.h
(file_editor_interface::add_file_editor_tab, file_editor::add_file_editor_tab):
Made the text name for the tab an input variable.
* file-editor.cc (file_editor::~file_editor): Replace dynamic_cast with simple
signal querying all file editor tabs for file names which end up in
savedSessionTabs. (file_editor::handle_file_name_changed): Dynamic cast not
necessary since QObject and QWidget are compatible.
(file_editor::handle_tab_close_request): Replace dynamic_cast with signal to
request file_editor_tab with associated tabID tag should close.
(file_editor::handle_tab_remove_request): Rename of handle_tab_close_request.
Instead of dynamic cast, loop through pointers comparing QWidget* to QObject*,
if same tag remove tab via index and also delete which fixes a memory leak.
(file_editor::handle_add_filename_to_list): Simple slot that uses append() of
the list member functions. (file_editor::notice_settings): Rather than dynamic
cast, emit signal for the file_editor_tabs. (file_editor::add_file_editor_tab):
New variety of connections for improved flow. (file_editor::request_open_file):
Given error messages are made WindowModal, the tab shouldn't be delete if file
open is not successful. The file_editor_tab takes care of that.
(file_editor::request_open_file): Added check and message box for the
requested file already open in editor. For the non-interactive overloaded
version, open a message dialog box to tell the user file not found, e.g.,
could not find file in the settings when launched.
(file_editor::request_open_file): Inquire file names and update list before
checking for existence of files. Supply empty title to editor tab then have
file_editor_tab update name.
* file-editor-tab.h, file-editor-tab.cc, file-editor.cc
(file_editor_tab::run_file): New signal process_octave_code.
(file_editor::add_file_editor_tab): Connect signal process_octave_code to
file_editor's parent's slot handle_command_double_clicked.
author | Daniel J Sebald <daniel.sebald@ieee.org> |
---|---|
date | Sun, 23 Dec 2012 14:33:48 -0600 |
parents | 63dd6c30b294 |
children | e55a64f49346 |
comparison
equal
deleted
inserted
replaced
15847:13d1e9bfa362 | 15848:424edeca3c66 |
---|---|
40 #include <QTextStream> | 40 #include <QTextStream> |
41 #include <QVBoxLayout> | 41 #include <QVBoxLayout> |
42 | 42 |
43 #include "file-editor-tab.h" | 43 #include "file-editor-tab.h" |
44 #include "file-editor.h" | 44 #include "file-editor.h" |
45 #include "find-dialog.h" | |
46 #include "octave-link.h" | 45 #include "octave-link.h" |
47 | 46 |
48 #include "debug.h" | 47 #include "debug.h" |
49 #include "oct-env.h" | 48 #include "oct-env.h" |
50 | 49 |
51 file_editor_tab::file_editor_tab(file_editor *fileEditor) | 50 // Make parent null for the file editor tab so that warning |
52 : QWidget ((QWidget*)fileEditor) | 51 // WindowModal messages don't affect grandparents. |
53 { | 52 file_editor_tab::file_editor_tab (QString directory) |
54 _file_editor = fileEditor; | 53 { |
55 _file_name = ""; | 54 // Make sure there is a slash at the end of the directory name |
55 // for identification when saved later. | |
56 if (directory.count () && directory.at (directory.count () - 1) != '/') | |
57 directory.append ("/"); | |
58 _file_name = directory; | |
56 _edit_area = new QsciScintilla (this); | 59 _edit_area = new QsciScintilla (this); |
60 | |
61 // Leave the find dialog box out of memory until requested. | |
62 _find_dialog = 0; | |
63 _find_dialog_is_visible = false; | |
57 | 64 |
58 // symbols | 65 // symbols |
59 _edit_area->setMarginType (1, QsciScintilla::SymbolMargin); | 66 _edit_area->setMarginType (1, QsciScintilla::SymbolMargin); |
60 _edit_area->setMarginSensitivity (1, true); | 67 _edit_area->setMarginSensitivity (1, true); |
61 _edit_area->markerDefine (QsciScintilla::RightTriangle, bookmark); | 68 _edit_area->markerDefine (QsciScintilla::RightTriangle, bookmark); |
104 connect (_edit_area, SIGNAL (copyAvailable (bool)), | 111 connect (_edit_area, SIGNAL (copyAvailable (bool)), |
105 this, SLOT (handle_copy_available (bool))); | 112 this, SLOT (handle_copy_available (bool))); |
106 connect (&_file_system_watcher, SIGNAL (fileChanged (QString)), | 113 connect (&_file_system_watcher, SIGNAL (fileChanged (QString)), |
107 this, SLOT (file_has_changed (QString))); | 114 this, SLOT (file_has_changed (QString))); |
108 | 115 |
109 _file_name = ""; | |
110 | |
111 notice_settings (); | 116 notice_settings (); |
112 } | 117 } |
113 | 118 |
114 bool | 119 file_editor_tab::~file_editor_tab () |
115 file_editor_tab::copy_available () | 120 { |
116 { | 121 // Destroy items attached to _edit_area. |
117 return _copy_available; | 122 QsciLexer *lexer = _edit_area->lexer (); |
123 if (lexer) | |
124 { | |
125 delete lexer; | |
126 _edit_area->setLexer(0); | |
127 } | |
128 if (_find_dialog) | |
129 { | |
130 delete _find_dialog; | |
131 _find_dialog = 0; | |
132 } | |
133 | |
134 // Destroy _edit_area. | |
135 delete _edit_area; | |
118 } | 136 } |
119 | 137 |
120 void | 138 void |
121 file_editor_tab::closeEvent (QCloseEvent *e) | 139 file_editor_tab::closeEvent (QCloseEvent *e) |
122 { | 140 { |
123 if (_file_editor->get_main_window ()->is_closing ()) | 141 // ignore close event if file is not saved and user cancels |
124 { | 142 // closing this window |
125 // close whole application: save file or not if modified | 143 if (check_file_modified ("Close File", |
126 check_file_modified ("Closing Octave", 0); // no cancel possible | 144 QMessageBox::Cancel) == QMessageBox::Cancel) |
127 e->accept (); | 145 { |
128 } | 146 e->ignore (); |
129 else | 147 } |
130 { | 148 else |
131 // ignore close event if file is not saved and user cancels | 149 { |
132 // closing this window | 150 e->accept(); |
133 if (check_file_modified ("Close File", | |
134 QMessageBox::Cancel) == QMessageBox::Cancel) | |
135 { | |
136 e->ignore (); | |
137 } | |
138 else | |
139 { | |
140 e->accept(); | |
141 } | |
142 } | 151 } |
143 } | 152 } |
144 | 153 |
145 void | 154 void |
146 file_editor_tab::set_file_name (const QString& fileName) | 155 file_editor_tab::set_file_name (const QString& fileName) |
147 { | 156 { |
148 if (fileName != UNNAMED_FILE) | 157 // update tracked file if we really have a file on disk |
149 { | 158 QStringList trackedFiles = _file_system_watcher.files (); |
150 // update tracked file if wie really hae a file on disk | 159 if (!trackedFiles.isEmpty ()) |
151 QStringList trackedFiles = _file_system_watcher.files (); | 160 _file_system_watcher.removePath (_file_name); |
152 if (!trackedFiles.isEmpty ()) | 161 if (!fileName.isEmpty ()) |
153 _file_system_watcher.removePath (_file_name); | 162 _file_system_watcher.addPath (fileName); |
154 _file_system_watcher.addPath (fileName); | |
155 } | |
156 _file_name = fileName; | 163 _file_name = fileName; |
157 | 164 |
158 // update lexer after _file_name change | 165 // update lexer after _file_name change |
159 update_lexer (); | 166 update_lexer (); |
167 | |
168 // update the file editor with current editing directory | |
169 emit editor_state_changed (_copy_available, QDir::cleanPath (_file_name)); | |
160 } | 170 } |
161 | 171 |
162 void | 172 void |
163 file_editor_tab::handle_margin_clicked(int margin, int line, | 173 file_editor_tab::handle_margin_clicked(int margin, int line, |
164 Qt::KeyboardModifiers state) | 174 Qt::KeyboardModifiers state) |
189 } | 199 } |
190 | 200 |
191 void | 201 void |
192 file_editor_tab::update_lexer () | 202 file_editor_tab::update_lexer () |
193 { | 203 { |
194 QsciLexer *lexer = _edit_area->lexer (); | 204 QsciLexer *lexer = _edit_area->lexer (); |
195 delete lexer; | 205 delete lexer; |
196 | 206 |
197 if (_file_name.endsWith (".m") || _file_name.endsWith (".M")) | 207 if (_file_name.endsWith (".m") || _file_name.endsWith (".M")) |
198 { | 208 { |
199 lexer = new lexer_octave_gui (); | 209 lexer = new lexer_octave_gui (); |
244 | 254 |
245 _edit_area->setLexer (lexer); | 255 _edit_area->setLexer (lexer); |
246 } | 256 } |
247 | 257 |
248 void | 258 void |
259 file_editor_tab::undo (const QWidget* ID) | |
260 { | |
261 if (ID != this) | |
262 return; | |
263 | |
264 _edit_area->undo (); | |
265 } | |
266 | |
267 void | |
268 file_editor_tab::redo (const QWidget* ID) | |
269 { | |
270 if (ID != this) | |
271 return; | |
272 | |
273 _edit_area->redo (); | |
274 } | |
275 | |
276 void | |
277 file_editor_tab::copy (const QWidget* ID) | |
278 { | |
279 if (ID != this) | |
280 return; | |
281 | |
282 _edit_area->copy (); | |
283 } | |
284 | |
285 void | |
286 file_editor_tab::cut (const QWidget* ID) | |
287 { | |
288 if (ID != this) | |
289 return; | |
290 | |
291 _edit_area->cut (); | |
292 } | |
293 | |
294 void | |
295 file_editor_tab::paste (const QWidget* ID) | |
296 { | |
297 if (ID != this) | |
298 return; | |
299 | |
300 _edit_area->paste (); | |
301 } | |
302 | |
303 void | |
304 file_editor_tab::save_file (const QWidget* ID) | |
305 { | |
306 if (ID != this) | |
307 return; | |
308 | |
309 save_file (_file_name); | |
310 } | |
311 void | |
312 | |
313 file_editor_tab::save_file (const QWidget* ID, const QString& fileName, bool remove_on_success) | |
314 { | |
315 if (ID != this) | |
316 return; | |
317 | |
318 save_file (fileName, remove_on_success); | |
319 } | |
320 | |
321 void | |
322 file_editor_tab::save_file_as (const QWidget* ID) | |
323 { | |
324 if (ID != this) | |
325 return; | |
326 | |
327 save_file_as (); | |
328 } | |
329 | |
330 void | |
331 file_editor_tab::run_file_callback (void) | |
332 { | |
333 // Maybe someday we will do something here? | |
334 } | |
335 | |
336 void | |
337 file_editor_tab::run_file (const QWidget* ID) | |
338 { | |
339 if (ID != this) | |
340 return; | |
341 | |
342 if (_edit_area->isModified ()) | |
343 save_file (_file_name); | |
344 | |
345 QFileInfo file_info (_file_name); | |
346 QString path = file_info.absolutePath (); | |
347 QString current_path | |
348 = QString::fromStdString (octave_link::last_working_directory ()); | |
349 QString function_name = file_info.fileName (); | |
350 | |
351 // We have to cut off the suffix, because octave appends it. | |
352 function_name.chop (file_info.suffix ().length () + 1); | |
353 emit process_octave_code (QString ("cd \'%1\'\n%2\n") | |
354 .arg(path).arg (function_name)); | |
355 | |
356 // TODO: Sending a run event crashes for long scripts. Find out why. | |
357 // octave_link::post_event | |
358 // (this, &file_editor_tab::run_file_callback, _file_name.toStdString ())); | |
359 } | |
360 | |
361 void | |
362 file_editor_tab::toggle_bookmark (const QWidget* ID) | |
363 { | |
364 if (ID != this) | |
365 return; | |
366 | |
367 int line, cur; | |
368 _edit_area->getCursorPosition (&line,&cur); | |
369 if ( _edit_area->markersAtLine (line) && (1 << bookmark) ) | |
370 _edit_area->markerDelete (line, bookmark); | |
371 else | |
372 _edit_area->markerAdd (line, bookmark); | |
373 } | |
374 | |
375 void | |
376 file_editor_tab::next_bookmark (const QWidget* ID) | |
377 { | |
378 if (ID != this) | |
379 return; | |
380 | |
381 int line, cur, nextline; | |
382 _edit_area->getCursorPosition (&line, &cur); | |
383 if ( _edit_area->markersAtLine (line) && (1 << bookmark) ) | |
384 line++; // we have a breakpoint here, so start search from next line | |
385 nextline = _edit_area->markerFindNext (line, (1 << bookmark)); | |
386 _edit_area->setCursorPosition (nextline, 0); | |
387 } | |
388 | |
389 void | |
390 file_editor_tab::previous_bookmark (const QWidget* ID) | |
391 { | |
392 if (ID != this) | |
393 return; | |
394 | |
395 int line, cur, prevline; | |
396 _edit_area->getCursorPosition (&line, &cur); | |
397 if ( _edit_area->markersAtLine (line) && (1 << bookmark) ) | |
398 line--; // we have a breakpoint here, so start search from prev line | |
399 prevline = _edit_area->markerFindPrevious (line, (1 << bookmark)); | |
400 _edit_area->setCursorPosition (prevline, 0); | |
401 } | |
402 | |
403 void | |
404 file_editor_tab::remove_bookmark (const QWidget* ID) | |
405 { | |
406 if (ID != this) | |
407 return; | |
408 | |
409 _edit_area->markerDeleteAll (bookmark); | |
410 } | |
411 | |
412 void | |
413 file_editor_tab::add_breakpoint_callback (const bp_info& info) | |
414 { | |
415 bp_table::intmap intmap; | |
416 intmap[0] = info.line + 1; | |
417 | |
418 std::string previous_directory = octave_env::get_current_directory (); | |
419 octave_env::chdir (info.path); | |
420 intmap = bp_table::add_breakpoint (info.function_name, intmap); | |
421 octave_env::chdir (previous_directory); | |
422 | |
423 if (intmap.size () > 0) | |
424 { | |
425 // FIXME -- Check file. | |
426 _edit_area->markerAdd (info.line, breakpoint); | |
427 } | |
428 } | |
429 | |
430 void | |
431 file_editor_tab::remove_breakpoint_callback (const bp_info& info) | |
432 { | |
433 bp_table::intmap intmap; | |
434 intmap[0] = info.line; | |
435 | |
436 std::string previous_directory = octave_env::get_current_directory (); | |
437 octave_env::chdir (info.path); | |
438 bp_table::remove_breakpoint (info.function_name, intmap); | |
439 octave_env::chdir (previous_directory); | |
440 | |
441 // FIXME -- check result | |
442 bool success = true; | |
443 | |
444 if (success) | |
445 { | |
446 // FIXME -- check file. | |
447 _edit_area->markerDelete (info.line, breakpoint); | |
448 } | |
449 } | |
450 | |
451 void | |
452 file_editor_tab::remove_all_breakpoints_callback (const bp_info& info) | |
453 { | |
454 bp_table::intmap intmap; | |
455 std::string previous_directory = octave_env::get_current_directory (); | |
456 octave_env::chdir (info.path); | |
457 intmap = bp_table::remove_all_breakpoints_in_file (info.function_name, true); | |
458 octave_env::chdir (previous_directory); | |
459 | |
460 if (intmap.size() > 0) | |
461 _edit_area->markerDeleteAll (breakpoint); | |
462 } | |
463 | |
464 void | |
249 file_editor_tab::request_add_breakpoint (int line) | 465 file_editor_tab::request_add_breakpoint (int line) |
250 { | 466 { |
251 QFileInfo file_info (_file_name); | 467 QFileInfo file_info (_file_name); |
252 QString path = file_info.absolutePath (); | 468 QString path = file_info.absolutePath (); |
253 QString function_name = file_info.fileName (); | 469 QString function_name = file_info.fileName (); |
276 octave_link::post_event | 492 octave_link::post_event |
277 (this, &file_editor_tab::remove_breakpoint_callback, info); | 493 (this, &file_editor_tab::remove_breakpoint_callback, info); |
278 } | 494 } |
279 | 495 |
280 void | 496 void |
281 file_editor_tab::comment_selected_text () | 497 file_editor_tab::toggle_breakpoint (const QWidget* ID) |
282 { | 498 { |
499 if (ID != this) | |
500 return; | |
501 | |
502 int line, cur; | |
503 _edit_area->getCursorPosition (&line, &cur); | |
504 if ( _edit_area->markersAtLine (line) && (1 << breakpoint) ) | |
505 request_remove_breakpoint (line); | |
506 else | |
507 request_add_breakpoint (line); | |
508 } | |
509 | |
510 void | |
511 file_editor_tab::next_breakpoint (const QWidget* ID) | |
512 { | |
513 if (ID != this) | |
514 return; | |
515 | |
516 int line, cur, nextline; | |
517 _edit_area->getCursorPosition (&line, &cur); | |
518 if ( _edit_area->markersAtLine (line) && (1 << breakpoint) ) | |
519 line++; // we have a breakpoint here, so start search from next line | |
520 nextline = _edit_area->markerFindNext (line, (1 << breakpoint)); | |
521 _edit_area->setCursorPosition (nextline, 0); | |
522 } | |
523 | |
524 void | |
525 file_editor_tab::previous_breakpoint (const QWidget* ID) | |
526 { | |
527 if (ID != this) | |
528 return; | |
529 | |
530 int line, cur, prevline; | |
531 _edit_area->getCursorPosition (&line, &cur); | |
532 if ( _edit_area->markersAtLine (line) && (1 << breakpoint) ) | |
533 line--; // we have a breakpoint here, so start search from prev line | |
534 prevline = _edit_area->markerFindPrevious (line, (1 << breakpoint)); | |
535 _edit_area->setCursorPosition (prevline, 0); | |
536 } | |
537 | |
538 void | |
539 file_editor_tab::remove_all_breakpoints (const QWidget* ID) | |
540 { | |
541 if (ID != this) | |
542 return; | |
543 | |
544 QFileInfo file_info (_file_name); | |
545 QString path = file_info.absolutePath (); | |
546 QString function_name = file_info.fileName (); | |
547 | |
548 // We have to cut off the suffix, because octave appends it. | |
549 function_name.chop (file_info.suffix ().length () + 1); | |
550 | |
551 bp_info info (path, function_name, 0); | |
552 | |
553 octave_link::post_event | |
554 (this, &file_editor_tab::remove_all_breakpoints_callback, info); | |
555 } | |
556 | |
557 void | |
558 file_editor_tab::comment_selected_text (const QWidget* ID) | |
559 { | |
560 if (ID != this) | |
561 return; | |
562 | |
283 do_comment_selected_text (true); | 563 do_comment_selected_text (true); |
284 } | 564 } |
285 | 565 |
286 void | 566 void |
287 file_editor_tab::uncomment_selected_text () | 567 file_editor_tab::uncomment_selected_text (const QWidget* ID) |
288 { | 568 { |
569 if (ID != this) | |
570 return; | |
571 | |
289 do_comment_selected_text (false); | 572 do_comment_selected_text (false); |
573 } | |
574 | |
575 void | |
576 file_editor_tab::handle_find_dialog_finished (int) | |
577 { | |
578 // Find dialog is going to hide. Save location of window for | |
579 // when it is reshown. | |
580 _find_dialog_geometry = _find_dialog->geometry (); | |
581 _find_dialog_is_visible = false; | |
582 } | |
583 | |
584 void | |
585 file_editor_tab::find (const QWidget* ID) | |
586 { | |
587 if (ID != this) | |
588 return; | |
589 | |
590 // The find_dialog feature doesn't need a slot for return info. | |
591 // Rather than Qt::DeleteOnClose, let the find feature hang about | |
592 // in case it contains useful information like previous searches | |
593 // and so on. Perhaps one find dialog for the whole editor is | |
594 // better, but individual find dialogs has the nice feature of | |
595 // retaining position per file editor tabs, which can be undocked. | |
596 | |
597 if (!_find_dialog) | |
598 { | |
599 _find_dialog = new find_dialog (_edit_area); | |
600 connect (_find_dialog, SIGNAL (finished (int)), | |
601 this, SLOT (handle_find_dialog_finished (int))); | |
602 _find_dialog->setWindowModality (Qt::NonModal); | |
603 _find_dialog_geometry = _find_dialog->geometry (); | |
604 } | |
605 | |
606 if (!_find_dialog->isVisible ()) | |
607 { | |
608 _find_dialog->setGeometry (_find_dialog_geometry); | |
609 _find_dialog->show (); | |
610 _find_dialog_is_visible = true; | |
611 } | |
612 | |
613 _find_dialog->activateWindow (); | |
290 } | 614 } |
291 | 615 |
292 void | 616 void |
293 file_editor_tab::do_comment_selected_text (bool comment) | 617 file_editor_tab::do_comment_selected_text (bool comment) |
294 { | 618 { |
316 _edit_area->endUndoAction (); | 640 _edit_area->endUndoAction (); |
317 } | 641 } |
318 } | 642 } |
319 | 643 |
320 void | 644 void |
321 file_editor_tab::find () | |
322 { | |
323 find_dialog dialog (_edit_area); | |
324 dialog.exec (); | |
325 } | |
326 | |
327 void | |
328 file_editor_tab::update_window_title (bool modified) | 645 file_editor_tab::update_window_title (bool modified) |
329 { | 646 { |
330 QString title(_file_name); | 647 QString title (""); |
648 if (_file_name.isEmpty () || _file_name.at (_file_name.count () - 1) == '/') | |
649 title = UNNAMED_FILE; | |
650 else | |
651 title = _file_name; | |
331 if ( !_long_title ) | 652 if ( !_long_title ) |
332 { | 653 { |
333 QFileInfo file(_file_name); | 654 QFileInfo file(_file_name); |
334 title = file.fileName(); | 655 title = file.fileName(); |
335 } | 656 } |
344 | 665 |
345 void | 666 void |
346 file_editor_tab::handle_copy_available(bool enableCopy) | 667 file_editor_tab::handle_copy_available(bool enableCopy) |
347 { | 668 { |
348 _copy_available = enableCopy; | 669 _copy_available = enableCopy; |
349 emit editor_state_changed (); | 670 emit editor_state_changed (_copy_available, QDir::cleanPath (_file_name)); |
350 } | 671 } |
351 | 672 |
352 int | 673 int |
353 file_editor_tab::check_file_modified (const QString& msg, int cancelButton) | 674 file_editor_tab::check_file_modified (const QString& msg, int cancelButton) |
354 { | 675 { |
355 int decision = QMessageBox::Yes; | 676 int decision = QMessageBox::Yes; |
356 if (_edit_area->isModified ()) | 677 if (_edit_area->isModified ()) |
357 { | 678 { |
358 // file is modified but not saved, ask user what to do | 679 // File is modified but not saved, ask user what to do. The file |
359 decision = QMessageBox::warning (this, | 680 // editor tab can't be made parent because it may be deleted depending |
360 msg, | 681 // upon the response. Instead, change the _edit_area to read only. |
361 tr ("The file %1\n" | 682 QMessageBox* msgBox = new QMessageBox ( |
362 "has been modified. Do you want to save the changes?"). | 683 QMessageBox::Warning, tr ("Octave Editor"), |
363 arg (_file_name), | 684 tr ("The file \'%1\' has been modified. Do you want to save the changes?"). |
364 QMessageBox::Save, | 685 arg (_file_name), QMessageBox::Yes | QMessageBox::No, 0); |
365 QMessageBox::Discard, cancelButton ); | 686 _edit_area->setReadOnly (true); |
366 if (decision == QMessageBox::Save) | 687 connect (msgBox, SIGNAL (finished (int)), |
367 { | 688 this, SLOT (handle_file_modified_answer (int))); |
368 save_file (); | 689 msgBox->setWindowModality (Qt::NonModal); |
369 if (_edit_area->isModified ()) | 690 msgBox->setAttribute (Qt::WA_DeleteOnClose); |
370 { | 691 msgBox->show (); |
371 // If the user attempted to save the file, but it's still | 692 return (QMessageBox::Cancel); |
372 // modified, then probably something went wrong, so return | 693 } |
373 // cancel for cancel this operation or try to save files | 694 else |
374 // as if cancel not possible | 695 { |
375 if ( cancelButton ) | 696 // Nothing was modified, just remove from editor. |
376 return (QMessageBox::Cancel); | 697 emit tab_remove_request (); |
377 else | 698 } |
378 save_file_as (); | 699 |
379 } | |
380 } | |
381 } | |
382 return (decision); | 700 return (decision); |
383 } | 701 } |
384 | 702 |
385 void | 703 void |
386 file_editor_tab::remove_bookmark () | 704 file_editor_tab::handle_file_modified_answer (int decision) |
387 { | 705 { |
388 _edit_area->markerDeleteAll (bookmark); | 706 if (decision == QMessageBox::Yes) |
389 } | 707 { |
390 | 708 // Save file, then remove from editor. |
391 void | 709 save_file (_file_name, true); |
392 file_editor_tab::toggle_bookmark () | 710 } |
393 { | 711 else if (decision == QMessageBox::No) |
394 int line, cur; | 712 { |
395 _edit_area->getCursorPosition (&line,&cur); | 713 // User doesn't want to save, just remove from editor. |
396 if ( _edit_area->markersAtLine (line) && (1 << bookmark) ) | 714 emit tab_remove_request (); |
397 _edit_area->markerDelete (line, bookmark); | 715 } |
398 else | 716 else |
399 _edit_area->markerAdd (line, bookmark); | 717 { |
400 } | 718 // User canceled, allow editing again. |
401 | 719 _edit_area->setReadOnly (false); |
402 void | |
403 file_editor_tab::next_bookmark() | |
404 { | |
405 int line, cur, nextline; | |
406 _edit_area->getCursorPosition (&line, &cur); | |
407 if ( _edit_area->markersAtLine (line) && (1 << bookmark) ) | |
408 line++; // we have a breakpoint here, so start search from next line | |
409 nextline = _edit_area->markerFindNext (line, (1 << bookmark)); | |
410 _edit_area->setCursorPosition (nextline, 0); | |
411 } | |
412 | |
413 void | |
414 file_editor_tab::previous_bookmark () | |
415 { | |
416 int line, cur, prevline; | |
417 _edit_area->getCursorPosition (&line, &cur); | |
418 if ( _edit_area->markersAtLine (line) && (1 << bookmark) ) | |
419 line--; // we have a breakpoint here, so start search from prev line | |
420 prevline = _edit_area->markerFindPrevious (line, (1 << bookmark)); | |
421 _edit_area->setCursorPosition (prevline, 0); | |
422 } | |
423 | |
424 void | |
425 file_editor_tab::remove_all_breakpoints () | |
426 { | |
427 QFileInfo file_info (_file_name); | |
428 QString path = file_info.absolutePath (); | |
429 QString function_name = file_info.fileName (); | |
430 | |
431 // We have to cut off the suffix, because octave appends it. | |
432 function_name.chop (file_info.suffix ().length () + 1); | |
433 | |
434 bp_info info (path, function_name, 0); | |
435 | |
436 octave_link::post_event | |
437 (this, &file_editor_tab::remove_all_breakpoints_callback, info); | |
438 } | |
439 | |
440 void | |
441 file_editor_tab::toggle_breakpoint () | |
442 { | |
443 int line, cur; | |
444 _edit_area->getCursorPosition (&line, &cur); | |
445 if ( _edit_area->markersAtLine (line) && (1 << breakpoint) ) | |
446 request_remove_breakpoint (line); | |
447 else | |
448 request_add_breakpoint (line); | |
449 } | |
450 | |
451 void | |
452 file_editor_tab::next_breakpoint () | |
453 { | |
454 int line, cur, nextline; | |
455 _edit_area->getCursorPosition (&line, &cur); | |
456 if ( _edit_area->markersAtLine (line) && (1 << breakpoint) ) | |
457 line++; // we have a breakpoint here, so start search from next line | |
458 nextline = _edit_area->markerFindNext (line, (1 << breakpoint)); | |
459 _edit_area->setCursorPosition (nextline, 0); | |
460 } | |
461 | |
462 void | |
463 file_editor_tab::previous_breakpoint () | |
464 { | |
465 int line, cur, prevline; | |
466 _edit_area->getCursorPosition (&line, &cur); | |
467 if ( _edit_area->markersAtLine (line) && (1 << breakpoint) ) | |
468 line--; // we have a breakpoint here, so start search from prev line | |
469 prevline = _edit_area->markerFindPrevious (line, (1 << breakpoint)); | |
470 _edit_area->setCursorPosition (prevline, 0); | |
471 } | |
472 | |
473 void | |
474 file_editor_tab::cut () | |
475 { | |
476 _edit_area->cut (); | |
477 } | |
478 | |
479 void | |
480 file_editor_tab::copy () | |
481 { | |
482 _edit_area->copy (); | |
483 } | |
484 | |
485 void | |
486 file_editor_tab::paste () | |
487 { | |
488 _edit_area->paste (); | |
489 } | |
490 | |
491 void | |
492 file_editor_tab::undo () | |
493 { | |
494 _edit_area->undo (); | |
495 } | |
496 | |
497 void | |
498 file_editor_tab::redo () | |
499 { | |
500 _edit_area->redo (); | |
501 } | |
502 | |
503 void | |
504 file_editor_tab::set_debugger_position (int line) | |
505 { | |
506 _edit_area->markerDeleteAll (debugger_position); | |
507 if (line > 0) | |
508 { | |
509 _edit_area->markerAdd (line, debugger_position); | |
510 } | 720 } |
511 } | 721 } |
512 | 722 |
513 void | 723 void |
514 file_editor_tab::set_modified (bool modified) | 724 file_editor_tab::set_modified (bool modified) |
515 { | 725 { |
516 _edit_area->setModified (modified); | 726 _edit_area->setModified (modified); |
517 } | 727 } |
518 | 728 |
519 bool | 729 QString |
520 file_editor_tab::open_file (const QString& dir) | 730 file_editor_tab::load_file(const QString& fileName) |
521 { | 731 { |
522 QString openFileName; | |
523 QFileDialog fileDialog(this); | |
524 fileDialog.setNameFilter(SAVE_FILE_FILTER); | |
525 fileDialog.setAcceptMode(QFileDialog::AcceptOpen); | |
526 fileDialog.setViewMode(QFileDialog::Detail); | |
527 fileDialog.setDirectory(dir); | |
528 if (fileDialog.exec () == QDialog::Accepted) | |
529 { | |
530 openFileName = fileDialog.selectedFiles().at(0); | |
531 if (openFileName.isEmpty ()) | |
532 return false; | |
533 | |
534 return load_file(openFileName); | |
535 } | |
536 else | |
537 { | |
538 return false; | |
539 } | |
540 } | |
541 | |
542 bool | |
543 file_editor_tab::load_file(const QString& fileName, bool silent) | |
544 { | |
545 if (!_file_editor->isVisible ()) | |
546 { | |
547 _file_editor->show (); | |
548 } | |
549 | |
550 QFile file (fileName); | 732 QFile file (fileName); |
551 if (!file.open (QFile::ReadOnly)) | 733 if (!file.open (QFile::ReadOnly)) |
552 { | 734 { |
553 if (silent==false) | 735 return file.errorString (); |
554 QMessageBox::warning (this, tr ("Octave Editor"), | |
555 tr ("Could not open file %1 for read:\n%2.").arg (fileName). | |
556 arg (file.errorString ())); | |
557 return false; | |
558 } | 736 } |
559 | 737 |
560 QTextStream in (&file); | 738 QTextStream in (&file); |
561 QApplication::setOverrideCursor (Qt::WaitCursor); | 739 QApplication::setOverrideCursor (Qt::WaitCursor); |
562 _edit_area->setText (in.readAll ()); | 740 _edit_area->setText (in.readAll ()); |
564 | 742 |
565 set_file_name (fileName); | 743 set_file_name (fileName); |
566 update_window_title (false); // window title (no modification) | 744 update_window_title (false); // window title (no modification) |
567 _edit_area->setModified (false); // loaded file is not modified yet | 745 _edit_area->setModified (false); // loaded file is not modified yet |
568 | 746 |
569 return true; | 747 return QString (); |
570 } | 748 } |
571 | 749 |
572 void | 750 void |
573 file_editor_tab::new_file () | 751 file_editor_tab::new_file () |
574 { | 752 { |
575 if (!_file_editor->isVisible ()) | |
576 { | |
577 _file_editor->show (); | |
578 } | |
579 | |
580 set_file_name (UNNAMED_FILE); | |
581 update_window_title (false); // window title (no modification) | 753 update_window_title (false); // window title (no modification) |
582 _edit_area->setText (""); | 754 _edit_area->setText (""); |
583 _edit_area->setModified (false); // new file is not modified yet | 755 _edit_area->setModified (false); // new file is not modified yet |
584 } | 756 } |
585 | 757 |
586 bool file_editor_tab::save_file() | 758 void |
587 { | 759 file_editor_tab::save_file (const QString& saveFileName, bool remove_on_success) |
588 return save_file (_file_name); | 760 { |
589 } | 761 // If it is a new file with no name, signal that saveFileAs |
590 | 762 // should be performed. |
591 bool | 763 if (saveFileName.isEmpty () || saveFileName.at (saveFileName.count () - 1) == '/') |
592 file_editor_tab::save_file (const QString& saveFileName) | 764 { |
593 { | 765 save_file_as (remove_on_success); |
594 // it is a new file with the name "<unnamed>" -> call saveFielAs | 766 return; |
595 if (saveFileName == UNNAMED_FILE || saveFileName.isEmpty ()) | 767 } |
596 { | 768 |
597 return save_file_as(); | 769 // stop watching file |
598 } | 770 QStringList trackedFiles = _file_system_watcher.files (); |
599 | 771 if (!trackedFiles.isEmpty ()) |
600 // remove the file to save from the tracker since we will change it on disk now | 772 _file_system_watcher.removePath (saveFileName); |
601 QStringList watched_files = _file_system_watcher.files(); | 773 |
602 if (!watched_files.isEmpty ()) | |
603 _file_system_watcher.removePath(saveFileName); | |
604 | |
605 // open the file for writing | 774 // open the file for writing |
606 QFile file (saveFileName); | 775 QFile file (saveFileName); |
607 if (!file.open (QFile::WriteOnly)) | 776 if (!file.open (QIODevice::WriteOnly)) |
608 { | 777 { |
609 QMessageBox::warning (this, tr ("Octave Editor"), | 778 // Unsuccessful, begin watching file again if it was being |
610 tr ("Could not open file %1 for write:\n%2."). | 779 // watched previously. |
611 arg (saveFileName).arg (file.errorString ())); | 780 if (trackedFiles.contains (saveFileName)) |
612 return false; | 781 _file_system_watcher.addPath (saveFileName); |
782 | |
783 // Create a NonModal message about error. | |
784 QMessageBox* msgBox = new QMessageBox ( | |
785 QMessageBox::Critical, tr ("Octave Editor"), | |
786 tr ("Could not open file %1 for write:\n%2."). | |
787 arg (saveFileName).arg (file.errorString ()), | |
788 QMessageBox::Ok, 0); | |
789 msgBox->setWindowModality (Qt::NonModal); | |
790 msgBox->setAttribute (Qt::WA_DeleteOnClose); | |
791 msgBox->show (); | |
792 return; | |
613 } | 793 } |
614 | 794 |
615 // save the contents into the file | 795 // save the contents into the file |
616 QTextStream out (&file); | 796 QTextStream out (&file); |
617 QApplication::setOverrideCursor (Qt::WaitCursor); | 797 QApplication::setOverrideCursor (Qt::WaitCursor); |
618 out << _edit_area->text (); | 798 out << _edit_area->text (); |
619 QApplication::restoreOverrideCursor (); | 799 QApplication::restoreOverrideCursor (); |
620 file.close(); | 800 file.close(); |
621 | 801 |
622 // save file name after closing file otherwise tracker will notice file change | 802 // save file name after closing file as set_file_name starts watching again |
623 set_file_name (saveFileName); | 803 set_file_name (saveFileName); |
624 // set the window title to actual file name (not modified) | 804 // set the window title to actual file name (not modified) |
625 update_window_title (false); | 805 update_window_title (false); |
626 // files is save -> not modified | 806 // files is save -> not modified |
627 _edit_area->setModified (false); | 807 _edit_area->setModified (false); |
628 | 808 |
629 return true; | 809 if (remove_on_success) |
630 } | 810 { |
631 | 811 emit tab_remove_request (); |
632 bool | 812 return; // Don't touch member variables after removal |
633 file_editor_tab::save_file_as () | 813 } |
634 { | 814 } |
635 QString saveFileName(_file_name); | 815 |
636 QFileDialog fileDialog(this); | 816 void |
637 if (saveFileName == UNNAMED_FILE || saveFileName.isEmpty ()) | 817 file_editor_tab::save_file_as (bool remove_on_success) |
638 { | 818 { |
639 QString directory = QString::fromStdString | 819 // Simply put up the file chooser dialog box with a slot connection |
640 (octave_link::last_working_directory ()); | 820 // then return control to the system waiting for a file selection. |
641 | 821 |
642 if (directory.isEmpty ()) | 822 // If the tab is removed in response to a QFileDialog signal, the tab |
823 // can't be a parent. | |
824 QFileDialog* fileDialog; | |
825 if (remove_on_success) | |
826 { | |
827 // If tab is closed, "this" cannot be parent in which case modality | |
828 // has no effect. Disable editing instead. | |
829 _edit_area->setReadOnly (true); | |
830 fileDialog = new QFileDialog (); | |
831 } | |
832 else | |
833 fileDialog = new QFileDialog (this); | |
834 | |
835 if (!_file_name.isEmpty () && _file_name.at (_file_name.count () - 1) != '/') | |
836 { | |
837 fileDialog->selectFile (_file_name); | |
838 } | |
839 else | |
840 { | |
841 fileDialog->selectFile (""); | |
842 if (_file_name.isEmpty ()) | |
643 { | 843 { |
644 directory = QDir::homePath (); | 844 fileDialog->setDirectory (QDir::currentPath ()); |
645 } | |
646 | |
647 fileDialog.setDirectory (directory); | |
648 } | |
649 else | |
650 { | |
651 fileDialog.selectFile (saveFileName); | |
652 } | |
653 fileDialog.setNameFilter (SAVE_FILE_FILTER); | |
654 fileDialog.setDefaultSuffix ("m"); | |
655 fileDialog.setAcceptMode (QFileDialog::AcceptSave); | |
656 fileDialog.setViewMode (QFileDialog::Detail); | |
657 | |
658 if (fileDialog.exec ()) | |
659 { | |
660 saveFileName = fileDialog.selectedFiles ().at (0); | |
661 if (saveFileName.isEmpty ()) | |
662 return false; | |
663 | |
664 return save_file (saveFileName); | |
665 } | |
666 | |
667 return false; | |
668 } | |
669 | |
670 void | |
671 file_editor_tab::run_file () | |
672 { | |
673 if (_edit_area->isModified ()) | |
674 save_file(_file_name); | |
675 | |
676 QFileInfo file_info (_file_name); | |
677 QString path = file_info.absolutePath (); | |
678 QString current_path | |
679 = QString::fromStdString (octave_link::last_working_directory ()); | |
680 QString function_name = file_info.fileName (); | |
681 | |
682 // We have to cut off the suffix, because octave appends it. | |
683 function_name.chop (file_info.suffix ().length () + 1); | |
684 _file_editor->terminal ()->sendText (QString ("cd \'%1\'\n%2\n") | |
685 .arg(path).arg (function_name)); | |
686 // TODO: Sending a run event crashes for long scripts. Find out why. | |
687 // octave_link::post_event | |
688 // (this, &file_editor_tab::run_file_callback, _file_name.toStdString ())); | |
689 } | |
690 | |
691 void | |
692 file_editor_tab::file_has_changed (const QString&) | |
693 { | |
694 if (QFile::exists (_file_name)) | |
695 { | |
696 // Prevent popping up multiple message boxes when the file has | |
697 // been changed multiple times. | |
698 static bool alreadyAsking = false; | |
699 if (!alreadyAsking) | |
700 { | |
701 alreadyAsking = true; | |
702 | |
703 int decision = | |
704 QMessageBox::warning (this, tr ("Octave Editor"), | |
705 tr ("It seems that \'%1\' has been modified by another application. Do you want to reload it?"). | |
706 arg (_file_name), QMessageBox::Yes, | |
707 QMessageBox::No); | |
708 | |
709 if (decision == QMessageBox::Yes) | |
710 { | |
711 load_file (_file_name); | |
712 } | |
713 | |
714 alreadyAsking = false; | |
715 } | |
716 } | |
717 else | |
718 { | |
719 int decision = | |
720 QMessageBox::warning (this, tr ("Octave Editor"), | |
721 tr ("It seems that \'%1\' has been deleted or renamed. Do you want to save it now?"). | |
722 arg (_file_name), QMessageBox::Save, | |
723 QMessageBox::Close); | |
724 if (decision == QMessageBox::Save) | |
725 { | |
726 if (!save_file_as ()) | |
727 { | |
728 set_file_name (UNNAMED_FILE); | |
729 update_window_title (true); // window title (no modification) | |
730 set_modified (true); | |
731 } | |
732 } | 845 } |
733 else | 846 else |
734 { | 847 { |
735 emit close_request (); | 848 // The file name is actually the directory name from the |
849 // constructor argument. | |
850 fileDialog->setDirectory (_file_name); | |
736 } | 851 } |
852 } | |
853 fileDialog->setNameFilter (SAVE_FILE_FILTER); | |
854 fileDialog->setDefaultSuffix ("m"); | |
855 fileDialog->setAcceptMode (QFileDialog::AcceptSave); | |
856 fileDialog->setViewMode (QFileDialog::Detail); | |
857 if (remove_on_success) | |
858 { | |
859 connect (fileDialog, SIGNAL (fileSelected (const QString&)), | |
860 this, SLOT (handle_save_file_as_answer_close (const QString&))); | |
861 connect (fileDialog, SIGNAL (rejected ()), | |
862 this, SLOT (handle_save_file_as_answer_cancel ())); | |
863 } | |
864 else | |
865 { | |
866 connect (fileDialog, SIGNAL (fileSelected (const QString&)), | |
867 this, SLOT (handle_save_file_as_answer (const QString&))); | |
868 } | |
869 fileDialog->setWindowModality (Qt::WindowModal); | |
870 fileDialog->setAttribute (Qt::WA_DeleteOnClose); | |
871 fileDialog->show (); | |
872 } | |
873 | |
874 void | |
875 file_editor_tab::message_duplicate_file_name (const QString& saveFileName) | |
876 { | |
877 // Could overwrite the file here (and tell user the file was | |
878 // overwritten), but the user could have unintentionally | |
879 // selected the same name not intending to overwrite. | |
880 | |
881 // Create a NonModal message about error. | |
882 QMessageBox* msgBox = new QMessageBox ( | |
883 QMessageBox::Critical, tr ("Octave Editor"), | |
884 tr ("File not saved! You've selected a file name\n\n %1\n\nwhich is the same as the current file name. Use ""Save"" to overwrite. (Could allow overwriting, with message, if that is what folks want.)"). | |
885 arg (saveFileName), | |
886 QMessageBox::Ok, 0); | |
887 msgBox->setWindowModality (Qt::NonModal); | |
888 msgBox->setAttribute (Qt::WA_DeleteOnClose); | |
889 msgBox->show (); | |
890 } | |
891 | |
892 void | |
893 file_editor_tab::handle_save_file_as_answer (const QString& saveFileName) | |
894 { | |
895 if (saveFileName == _file_name) | |
896 { | |
897 message_duplicate_file_name (saveFileName); | |
898 // Nothing done, allow editing again. | |
899 _edit_area->setReadOnly (false); | |
900 } | |
901 else | |
902 { | |
903 // Have editor check for conflict, do not delete tab after save. | |
904 emit editor_check_conflict_save (saveFileName, false); | |
905 } | |
906 } | |
907 | |
908 void | |
909 file_editor_tab::handle_save_file_as_answer_close (const QString& saveFileName) | |
910 { | |
911 if (saveFileName == _file_name) | |
912 { | |
913 message_duplicate_file_name (saveFileName); | |
914 // Nothing done, allow editing again. | |
915 _edit_area->setReadOnly (false); | |
916 } | |
917 else | |
918 { | |
919 // Have editor check for conflict, delete tab after save. | |
920 emit editor_check_conflict_save (saveFileName, true); | |
921 } | |
922 } | |
923 | |
924 void | |
925 file_editor_tab::handle_save_file_as_answer_cancel () | |
926 { | |
927 // User canceled, allow editing again. | |
928 _edit_area->setReadOnly (false); | |
929 } | |
930 | |
931 void | |
932 file_editor_tab::file_has_changed (const QString&) | |
933 { | |
934 // Prevent popping up multiple message boxes when the file has | |
935 // been changed multiple times by temporarily removing from the | |
936 // file watcher. | |
937 QStringList trackedFiles = _file_system_watcher.files (); | |
938 if (!trackedFiles.isEmpty ()) | |
939 _file_system_watcher.removePath (_file_name); | |
940 | |
941 if (QFile::exists (_file_name)) | |
942 { | |
943 // Create a WindowModal message that blocks the edit area | |
944 // by making _edit_area parent. | |
945 QMessageBox* msgBox = new QMessageBox ( | |
946 QMessageBox::Warning, tr ("Octave Editor"), | |
947 tr ("It seems that \'%1\' has been modified by another application. Do you want to reload it?"). | |
948 arg (_file_name), QMessageBox::Yes | QMessageBox::No, this); | |
949 connect (msgBox, SIGNAL (finished (int)), | |
950 this, SLOT (handle_file_reload_answer (int))); | |
951 msgBox->setWindowModality (Qt::WindowModal); | |
952 msgBox->setAttribute (Qt::WA_DeleteOnClose); | |
953 msgBox->show (); | |
954 } | |
955 else | |
956 { | |
957 // Create a WindowModal message that blocks the edit area | |
958 // by making _edit_area parent. | |
959 QMessageBox* msgBox = new QMessageBox ( | |
960 QMessageBox::Warning, tr ("Octave Editor"), | |
961 tr ("It seems that \'%1\' has been deleted or renamed. Do you want to save it now?"). | |
962 arg (_file_name), QMessageBox::Save | QMessageBox::Close, this); | |
963 connect (msgBox, SIGNAL (finished (int)), | |
964 this, SLOT (handle_file_resave_answer (int))); | |
965 msgBox->setWindowModality (Qt::WindowModal); | |
966 msgBox->setAttribute (Qt::WA_DeleteOnClose); | |
967 msgBox->show (); | |
737 } | 968 } |
738 } | 969 } |
739 | 970 |
740 void | 971 void |
741 file_editor_tab::notice_settings () | 972 file_editor_tab::notice_settings () |
773 | 1004 |
774 update_window_title (false); | 1005 update_window_title (false); |
775 } | 1006 } |
776 | 1007 |
777 void | 1008 void |
778 file_editor_tab::run_file_callback (void) | 1009 file_editor_tab::conditional_close (const QWidget* ID) |
779 { | 1010 { |
780 // Maybe someday we will do something here? | 1011 if (ID != this) |
781 } | 1012 return; |
782 | 1013 |
783 void | 1014 close (); |
784 file_editor_tab::add_breakpoint_callback (const bp_info& info) | 1015 } |
785 { | 1016 |
786 bp_table::intmap intmap; | 1017 void |
787 intmap[0] = info.line + 1; | 1018 file_editor_tab::change_editor_state (const QWidget* ID) |
788 | 1019 { |
789 std::string previous_directory = octave_env::get_current_directory (); | 1020 if (ID != this) |
790 octave_env::chdir (info.path); | 1021 { |
791 intmap = bp_table::add_breakpoint (info.function_name, intmap); | 1022 // Widget may be going out of focus. If so, record location. |
792 octave_env::chdir (previous_directory); | 1023 if (_find_dialog) |
793 | 1024 { |
794 if (intmap.size () > 0) | 1025 if (_find_dialog->isVisible ()) |
795 { | 1026 { |
796 // FIXME -- Check file. | 1027 _find_dialog_geometry = _find_dialog->geometry (); |
797 _edit_area->markerAdd (info.line, breakpoint); | 1028 _find_dialog->hide (); |
798 } | 1029 } |
799 } | 1030 } |
800 | 1031 return; |
801 void | 1032 } |
802 file_editor_tab::remove_breakpoint_callback (const bp_info& info) | 1033 |
803 { | 1034 if (_find_dialog && _find_dialog_is_visible) |
804 bp_table::intmap intmap; | 1035 { |
805 intmap[0] = info.line; | 1036 _find_dialog->setGeometry (_find_dialog_geometry); |
806 | 1037 _find_dialog->show (); |
807 std::string previous_directory = octave_env::get_current_directory (); | 1038 } |
808 octave_env::chdir (info.path); | 1039 emit editor_state_changed (_copy_available, QDir::cleanPath (_file_name)); |
809 bp_table::remove_breakpoint (info.function_name, intmap); | 1040 } |
810 octave_env::chdir (previous_directory); | 1041 |
811 | 1042 void |
812 // FIXME -- check result | 1043 file_editor_tab::file_name_query (const QWidget* ID) |
813 bool success = true; | 1044 { |
814 | 1045 // A zero (null pointer) means that all file editor tabs |
815 if (success) | 1046 // should respond, otherwise just the desired file editor tab. |
816 { | 1047 if (ID != this && ID != 0) |
817 // FIXME -- check file. | 1048 return; |
818 _edit_area->markerDelete (info.line, breakpoint); | 1049 |
819 } | 1050 // Unnamed files shouldn't be transmitted. |
820 } | 1051 if (!_file_name.isEmpty ()) |
821 | 1052 emit add_filename_to_list (_file_name); |
822 void | 1053 } |
823 file_editor_tab::remove_all_breakpoints_callback (const bp_info& info) | 1054 |
824 { | 1055 void |
825 bp_table::intmap intmap; | 1056 file_editor_tab::handle_file_reload_answer (int decision) |
826 std::string previous_directory = octave_env::get_current_directory (); | 1057 { |
827 octave_env::chdir (info.path); | 1058 if (decision == QMessageBox::Yes) |
828 intmap = bp_table::remove_all_breakpoints_in_file (info.function_name, true); | 1059 { |
829 octave_env::chdir (previous_directory); | 1060 load_file (_file_name); |
830 | 1061 } |
831 if (intmap.size() > 0) | 1062 |
832 _edit_area->markerDeleteAll (breakpoint); | 1063 // Start watching file once again. |
833 } | 1064 _file_system_watcher.addPath (_file_name); |
1065 } | |
1066 | |
1067 void | |
1068 file_editor_tab::handle_file_resave_answer (int decision) | |
1069 { | |
1070 if (decision == QMessageBox::Save) | |
1071 { | |
1072 save_file (_file_name); | |
1073 } | |
1074 else | |
1075 { | |
1076 if (close ()) | |
1077 { | |
1078 emit tab_remove_request (); | |
1079 return; // Don't touch member variables after removal | |
1080 } | |
1081 } | |
1082 | |
1083 // Start watching file once again. | |
1084 _file_system_watcher.addPath (_file_name); | |
1085 } | |
1086 | |
1087 void | |
1088 file_editor_tab::set_debugger_position (int line) | |
1089 { | |
1090 _edit_area->markerDeleteAll (debugger_position); | |
1091 if (line > 0) | |
1092 { | |
1093 _edit_area->markerAdd (line, debugger_position); | |
1094 } | |
1095 } |