diff options
Diffstat (limited to 'lib/editor/generalproc.tcl')
-rw-r--r--[-rwxr-xr-x] | lib/editor/generalproc.tcl | 539 |
1 files changed, 412 insertions, 127 deletions
diff --git a/lib/editor/generalproc.tcl b/lib/editor/generalproc.tcl index f73be85..3bf8767 100755..100644 --- a/lib/editor/generalproc.tcl +++ b/lib/editor/generalproc.tcl @@ -2,7 +2,7 @@ # Part of MCU 8051 IDE ( http://mcu8051ide.sf.net ) ############################################################################ -# Copyright (C) 2007-2009 by Martin Ošmera # +# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera # # martin.osmera@gmail.com # # # # This program is free software; you can redistribute it and#or modify # @@ -21,6 +21,11 @@ # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # ############################################################################ +# >>> File inclusion guard +if { ! [ info exists _GENERALPROC_TCL ] } { +set _GENERALPROC_TCL _ +# <<< File inclusion guard + # -------------------------------------------------------------------------- # DESCRIPTION # Implements general purpose procedures @@ -43,7 +48,7 @@ public method switch_sel_mode {} { if {$selection_mode} { adjust_selection_to_block $sel_mode_lbl configure -text [mc "BLK"] -fg #0088CC - } { + } else { if {[llength [$editor tag nextrange sel 1.0]]} { $editor tag add sel sel.first sel.last } @@ -73,7 +78,7 @@ public method getBreakpoints {} { # @parm Bool inSelection - Search in the selected block / search globaly # @parm String Sindex - index in the text where the search should start # @parm String String - String to search - # @return List - {indexMatchBegining indexMatchEnd matchesCount} + # @return List - {indexMatchBeginning indexMatchEnd matchesCount} public method find {fromCursor Backwards regExp noCase inSelection Sindex String} { ## adjust search options @@ -85,10 +90,10 @@ public method find {fromCursor Backwards regExp noCase inSelection Sindex String if {$inSelection} { set Sindex sel.first set Eindex sel.last - } { + } else { if {$Backwards} { set Eindex 1.0 - } { + } else { set Eindex {end} } } @@ -97,12 +102,12 @@ public method find {fromCursor Backwards regExp noCase inSelection Sindex String if {$fromCursor} { # Sindex set Sindex {insert} - } { + } else { # Sindex if {$Sindex == {}} { if {$Backwards} { set Sindex end - } { + } else { set Sindex 1.0 } } @@ -112,7 +117,7 @@ public method find {fromCursor Backwards regExp noCase inSelection Sindex String if {$Backwards} { append Sindex -[expr {[string length $String] - 1}]c set direction {-backwards} - } { + } else { set direction {-forwards} } @@ -125,7 +130,7 @@ public method find {fromCursor Backwards regExp noCase inSelection Sindex String set index [$editor search $direction $regexp -nocase \ -count {::editor_search_count} -- \ $String $Sindex $Eindex] - } { + } else { set index [$editor search $direction $regexp \ -count {::editor_search_count} -- \ $String $Sindex $Eindex] @@ -149,14 +154,14 @@ public method find {fromCursor Backwards regExp noCase inSelection Sindex String # Goto line with the found match and select that matched string if {$Backwards} { goto $lineNumber.$colNumber - } { + } else { goto $lineNumber.$end_col } $editor tag remove sel 1.0 end $editor tag add sel $index $lineNumber.$end_col - # set result acording to values determinated above + # set result according to values determinated above set matches "$index $lineNumber.$end_col ${::editor_search_count}" - } { + } else { # set result to something like 'nothing found' set matches "$Sindex $Sindex 0" } @@ -196,33 +201,58 @@ public method replace {fromCursor Backwards regExp noCase SearchString Replaceme if {$critical_edit_proc} {return 0} set critical_edit_proc 1 - ## Derminate indexes of area to be affected + ## Derminate indexes of the area to be affected if {$fromCursor} { # from actual cursor position set index {insert} - } { + } else { if {$Backwards} { set index {end} - } { + } else { set index 1.0 } } ## Perform replacement for each match - while $remaining { + set index_org {} + set index_new {} + while {1} { # Initiate search and determinate count of remaining matches - set result [find $fromCursor $Backwards $regExp $noCase 0 $index $SearchString] - - set remaining [lindex $result 2] - if {$remaining == 0} {break} - - # Determinate index where to reinitiate search - set index [lindex $result [expr {!$Backwards}]] + set last_chance 0 + while {1} { + set result [find $fromCursor $Backwards $regExp $noCase 0 $index $SearchString] + + set remaining [lindex $result 2] + if {$remaining == 0} {break} + + # Determinate index where to reinitiate search + set index_org $index_new + set index [lindex $result [expr {!$Backwards}]] + set index_new $index + if {$index_org == $index} { + if {$last_chance} { + break + } else { + if {!$Backwards} { + set index [$editor index [list $index {+1c}]] + } else { + set index [$editor index [list $index {-1c}]] + } + set last_chance 1 + } + } else { + set last_chance 0 + break + } + } + if {$last_chance || $remaining == 0 || $remaining == {}} { + break + } - # "Annoy user" if there is requested confirmation before each replace + # Ask user if there is requested confirmation before each replace if {$confirm} { # invoke confirmation command and setup new parameters - switch [$confirmCMD] { + switch -- [$confirmCMD] { 0 { ;# Replace set cnd 1 } @@ -246,8 +276,8 @@ public method replace {fromCursor Backwards regExp noCase SearchString Replaceme break } } - } { - # automaticaly replace all without any prompt + } else { + # automatically replace all without any prompt set cnd 1 } @@ -272,7 +302,7 @@ public method replace {fromCursor Backwards regExp noCase SearchString Replaceme for {set line $start} {$line <= $end} {incr line} { parse $line } - } { + } else { for {set line $start} {$line <= $end} {incr line} { restore_line_markers $line } @@ -303,9 +333,9 @@ public method replace {fromCursor Backwards regExp noCase SearchString Replaceme # @return void public method select_all {} { catch { - $editor tag remove sel 1.0 end + $editor tag remove sel 1.0 end } - $editor tag add sel 1.0 end + $editor tag add sel 1.0 end } ## Comment the selected area or current line @@ -323,7 +353,7 @@ public method comment {} { if {[getselection] == {}} { set restore_sel 0 set end $start - } { + } else { set restore_sel 1 set start [expr {int([$editor index sel.first])}] set end_o [$editor index sel.last] @@ -345,7 +375,7 @@ public method comment {} { set by_lines 1 set restore_sel 0 set end $start - } { + } else { set start_o [$editor index sel.first] set start [expr {int($start_o)}] set end_o [$editor index sel.last] @@ -353,7 +383,7 @@ public method comment {} { if {$end == $end_o && $start == $start_o} { set restore_sel 1 set by_lines 1 - } { + } else { set restore_sel 0 set by_lines 0 } @@ -370,7 +400,7 @@ public method comment {} { restore_line_markers $line } # Comment only selected characters - } { + } else { $editor insert $end_o { */} $editor insert $start_o {/* } $editor tag add sel sel.first-3c sel.last+3c @@ -388,7 +418,7 @@ public method comment {} { # Restore highlight if {$prog_language == 1 && ![string index $highlighted_lines $start] == 6} { parse $start - } { + } else { for {set i $start} {$i <= $end} {incr i} { parse $i } @@ -417,7 +447,7 @@ public method uncomment {} { if {[getselection] == {}} { set restore_sel 0 set end $start - } { + } else { set restore_sel 1 set start [expr {int([$editor index sel.first])}] set end_o [$editor index sel.last] @@ -431,7 +461,7 @@ public method uncomment {} { set line_data [$editor get $line.0 "$line.0 lineend"] if {[regexp {^\s*;\s*} $line_data comment]} { - detete_text_in_editor $line.0 $line.[string length $comment] + detete_text_in_editor $line.0 $line.[string length $comment] 0 regsub {;} $comment {} comment $editor insert $line.0 $comment restore_line_markers $line @@ -447,7 +477,7 @@ public method uncomment {} { set by_lines 1 set restore_sel 0 set end $start - } { + } else { set start_o [$editor index sel.first] set start [expr {int($start_o)}] set end_o [$editor index sel.last] @@ -455,7 +485,7 @@ public method uncomment {} { if {$end == $end_o && $start == $start_o} { set restore_sel 1 set by_lines 1 - } { + } else { set restore_sel 0 set by_lines 0 } @@ -476,8 +506,8 @@ public method uncomment {} { set succesful 1 set start_data [string length $start_data] set end_data [string length $end_data] - detete_text_in_editor $end_o-${end_data}c $end_o - detete_text_in_editor $start_o $start_o+${start_data}c + detete_text_in_editor $end_o-${end_data}c $end_o 0 + detete_text_in_editor $start_o $start_o+${start_data}c 0 } } @@ -486,13 +516,13 @@ public method uncomment {} { set line_data [$editor get $line.0 [list $line.0 lineend]] if {[regexp {^\s*// ?} $line_data line_data]} { set line_data [string length $line_data] - detete_text_in_editor $line.0 $line.$line_data + detete_text_in_editor $line.0 $line.$line_data 0 manage_autocompletion_list $line set succesful 1 } restore_line_markers $line } - } { + } else { $editor edit separator $editor configure -autoseparators 1 return $succesful @@ -504,7 +534,7 @@ public method uncomment {} { # Restore highlight if {$prog_language == 1 && ![string index $highlighted_lines $start] == 6} { parse $start - } { + } else { for {set i $start} {$i <= $end} {incr i} { parse $i } @@ -517,6 +547,13 @@ public method uncomment {} { } + # Perform spell checking for all the affected lines + if {$spellchecker_enabled} { + for {set i $start} {$i <= $end} {incr i} { + spellcheck_check_all $i + } + } + # Return result return $succesful } @@ -545,7 +582,7 @@ public method goto {textIndex} { [$editor index "$textIndex +1 line linestart"] } recalc_status_counter {} 0 - update idle + update idletasks $editor see insert } @@ -599,7 +636,7 @@ public method indent {} { set restore_sel 0 set start [expr {int([$editor index insert])}] set end $start - } { + } else { set restore_sel 1 set start [expr {int([$editor index sel.first])}] set end_o [$editor index sel.last] @@ -610,7 +647,7 @@ public method indent {} { # indent each line in the block if {$spaces_no_tabs} { set indent_char [string repeat { } $number_of_spaces] - } { + } else { set indent_char "\t" } for {set line $start} {$line <= $end} {incr line} { @@ -635,7 +672,7 @@ public method unindent {} { set restore_sel 0 set start [expr {int([$editor index insert])}] set end [expr {int([$editor index insert])}] - } { + } else { set restore_sel 1 set start [expr {int([$editor index sel.first])}] set end_o [$editor index sel.last] @@ -655,7 +692,7 @@ public method unindent {} { } elseif {[regexp {^\t} $line_data]} { detete_text_in_editor $line.0 $line.1 } - } { + } else { if {[regexp {^[\t( )]} $line_data]} { detete_text_in_editor $line.0 $line.1 } @@ -717,15 +754,15 @@ public method get_md5 {} { ## Add/Remove bookmark to/from current line # Directly depends on variable "bookmarks" (managed by proc. recalc_left_frame) - # @parm Int = NULL - target text index + # @parm Int idx=NULL - target text index # @return bool - 0: bookmark removed; 1: bookmark created -public method Bookmark args { +public method Bookmark {{idx {}}} { if {$editor_to_use} {return} # Determinate line number - if {$args != {}} { - set lineNumber [expr {int($args)}] - } { + if {$idx != {}} { + set lineNumber [expr {int($idx)}] + } else { set lineNumber [expr {int([$editor index insert])}] } @@ -758,10 +795,10 @@ public method Bookmark args { $iconBorder image create $lineNumber_i.0 \ -image ::ICONS::16::dot \ -align center - } { + } else { if {[llength [$editor tag nextrange tag_error $lineNumber.0 [list $lineNumber.0 lineend]]]} { set image {bm_ex} - } { + } else { set image {bookmark} } $iconBorder image create $lineNumber_i.0 \ @@ -769,7 +806,7 @@ public method Bookmark args { -align center } # Remove icon - } { + } else { $iconBorder delete $lineNumber_i.0 $lineNumber_i.2 if { [llength [$editor tag nextrange tag_error $lineNumber.0 [list $lineNumber.0 lineend]]] @@ -794,14 +831,14 @@ public method Bookmark args { $parentObject rightPanel_add_bookmark $lineNumber $parentObject rightPanel_bm_select $lineNumber # Remove the tag - } { + } else { $editor tag remove tag_bookmark $lineNumber.0 $tmp.0 $parentObject rightPanel_remove_bookmark $lineNumber $parentObject rightPanel_bm_unselect } # Enable scrolling - update idle + update idletasks set scroll_in_progress 0 # Done ... @@ -810,14 +847,14 @@ public method Bookmark args { ## Add/Remove breapoint to/from current line # Directly depends on variable "breakpoints" (managed by proc. recalc_left_frame) - # @parm Int = NULL - target text index + # @parm Int idx=NULL - target text index # @return bool - 0: breakpoint removed; 1: breakpoint created; or {} -public method Breakpoint args { +public method Breakpoint {{idx {}}} { # Determinate line number - if {$args != {}} { - set lineNumber [expr {int($args)}] - } { + if {$idx != {}} { + set lineNumber [expr {int($idx)}] + } else { set lineNumber [expr {int([$editor index insert])}] } @@ -844,12 +881,21 @@ public method Breakpoint args { # Add the tag if {$make} { - $lineNumbers tag add tag_breakpoint $lineNumber_i.0 $tmp.0 + # Detereminate whether the breakpoint will be valid or not + if {[is_breakpoint_valid $lineNumber]} { + set tag {tag_breakpoint} + } else { + set tag {tag_breakpoint_INVALID} + } + + $lineNumbers tag add $tag $lineNumber_i.0 $tmp.0 $parentObject rightPanel_add_breakpoint $lineNumber $parentObject rightPanel_bp_select $lineNumber + # Remove the tag - } { + } else { $lineNumbers tag remove tag_breakpoint $lineNumber_i.0 $tmp.0 + $lineNumbers tag remove tag_breakpoint_INVALID $lineNumber_i.0 $tmp.0 $parentObject rightPanel_remove_breakpoint $lineNumber $parentObject rightPanel_bp_unselect } @@ -863,7 +909,7 @@ public method Breakpoint args { } # Enable scrolling - update idle + update idletasks set scroll_in_progress 0 # done ... @@ -910,6 +956,7 @@ public method clear_all_breakpoints {} { # Clear breakpoint tags from line numbers $lineNumbers tag remove tag_breakpoint 1.0 end + $lineNumbers tag remove tag_breakpoint_INVALID 1.0 end # Clear right panel $parentObject rightPanel_clear_all_breakpoints @@ -991,7 +1038,7 @@ public method insertData {data position} { # Insert data $editor insert $position [regsub -all {[\u0000-\u0008\u000B-\u000C\u000E-\u001F\u007F-\u009F]} $data {}] # Highlight - update idle + update idletasks parseAll } @@ -1065,7 +1112,7 @@ private method get_count_of_lines {index0 index1} { # Translate tabulators to spaces set idx -1 set cor 0 - while 1 { + while {1} { set idx [string first "\t" $lineText [expr {$idx + 1}]] if {$idx == -1} {break} @@ -1076,7 +1123,7 @@ private method get_count_of_lines {index0 index1} { set line_width [font measure $defaultFont_bold -displayof $editor $lineText] incr line_width [expr {$cor * $defaultCharWidth}] # Line doesn't contain tabulators - } { + } else { set line_width [font measure $defaultFont_bold -displayof $editor $lineText] } @@ -1090,14 +1137,6 @@ private method get_count_of_lines {index0 index1} { return $new_wrap } -## Get data of bookmarks and breapoints - # @return List - {bookmarks breakpoints} (eg. {00011 10100}) -public method export_line_markers_data {} { - set result [join $bookmarks {}] - lappend result [join $breakpoints {}] - return $result -} - ## Get total number of lines in editor # @return Int - result public method getLinesCount {} { @@ -1107,28 +1146,66 @@ public method getLinesCount {} { return [expr {int($result) - 1}] } +## Get data of bookmarks and breapoints + # @return List - {bookmarks breakpoints} (eg. {{1 15 96} {2 45}}) +public method export_line_markers_data {} { + set foo [lsearch -ascii -exact -all $bookmarks 1] + if {![llength $foo]} { + set foo 0 + } + set bar [lsearch -ascii -exact -all $breakpoints 1] + if {![llength $bar]} { + set bar 0 + } + return [list $foo $bar] +} + ## Import list of bookmarks and breapoints # This function also validates given input data # This function does not do anything with the right panel - # @parm String Bookmarks - bookmakrs (eg. 00011010) - # @parm String Breakpoints - breakpoints (eg. 011010000000) + # @parm String Bookmarks - bookmakrs (eg. {1 15 96}) + # @parm String Breakpoints - breakpoints (eg. {2 45}) # @return void public method import_line_markers_data {Bookmarks Breakpoints} { if {$editor_to_use} {return} + # Determinate number of the last line in the editor + set lastEnd [expr {int([$editor index end])}] + # Check validity of the given data - if {![regexp {^[01]*$} $Bookmarks]} { - puts stderr [mc "Invalid list of bookmarks -- bookmarks discarded"] + if {[string index $Bookmarks 0] == {0}} { + if {![regexp {^[01]*$} $Bookmarks]} { + puts stderr [mc "Invalid list of bookmarks -- bookmarks discarded"] + set Bookmarks {} + } + } else { + set foo $Bookmarks set Bookmarks {} + for {set i 0} {$i <= $lastEnd} {incr i} { + if {[lsearch -ascii -exact $foo $i] != -1} { + append Bookmarks 1 + } else { + append Bookmarks 0 + } + } } - if {![regexp {^[01]*$} $Breakpoints]} { - puts stderr [mc "Invalid list of breakpoints -- bookmarks discarded"] + if {[string index $Breakpoints 0] == {0}} { + if {![regexp {^[01]*$} $Breakpoints]} { + puts stderr [mc "Invalid list of breakpoints -- bookmarks discarded"] + set Breakpoints {} + } + } else { + set foo $Breakpoints set Breakpoints {} + for {set i 0} {$i <= $lastEnd} {incr i} { + if {[lsearch -ascii -exact $foo $i] != -1} { + append Breakpoints 1 + } else { + append Breakpoints 0 + } + } } - # Determinate number of the last line in the editor - set lastEnd [expr {int([$editor index end])}] - # Initialize list of highlighted lines set highlighted_lines [string repeat 0 $lastEnd] @@ -1164,7 +1241,7 @@ public method import_line_markers_data {Bookmarks Breakpoints} { $iconBorder image create $line.0 \ -image ::ICONS::16::dot \ -align center - } { + } else { $iconBorder image create $line.0 \ -image ::ICONS::16::bookmark \ -align center @@ -1269,7 +1346,7 @@ public method set_lock {bool} { DynamicHelp::add $Sbar_lock_file -text [mc "Unlock file switching"] $Sbar_lock_file configure \ -image ::ICONS::16::lock - } { + } else { setStatusTip -widget $Sbar_lock_file -text [mc "File switching unlocked"] Sbar -freeze [mc "File switching unlocked"] DynamicHelp::add $Sbar_lock_file -text [mc "Lock file switching"] @@ -1280,12 +1357,18 @@ public method set_lock {bool} { } ## Invert simulator lock - # @retunr void + # @return void public method invert_lock {} { set_lock [expr {!$auto_switching_lock}] $parentObject set_editor_lock $this $auto_switching_lock } +## Get value of internal flag "frozen" + # @return Bool - True if the editor is in simulator mode, or disabled mode +public method get_flag_frozen {} { + return $frozen +} + ## Switch from editor mode to simulator mode # This operation will cause error if editor is in mode disabled # @return void @@ -1309,7 +1392,7 @@ public method freeze {} { if {!$frozen} { pack $Sbar_ssim_mode -side right pack $Sbar_lock_file -side left - } { + } else { pack $Sbar_sim_mode -side right } # Disable some popup menu items @@ -1357,7 +1440,6 @@ public method thaw {} { if {!$ro_mode} { $editor configure -state normal } - focus -force $editor set idx [$editor index "insert linestart"] $editor tag add tag_current_line $idx "$idx + 1 line" pack $Sbar_CRT_frame @@ -1379,6 +1461,11 @@ public method thaw {} { } # Recalculate counters recalc_status_counter {} 0 + + # Check the flag "file_change_notif_flg" and if set, inform the user + #+ about modification to the currently opened file done by another + #+ program. + check_file_change_notif } ## Move simulator line (line representing current position in simulator engine) @@ -1442,12 +1529,15 @@ public method highlight_visible_area {} { # Highlight the current view for {set line $start} {$line <= $end} {incr line} { if {[string index $highlighted_lines $line] == 0} { - if {![parse $line]} { + if {![parse $line 1]} { if {$line != $start} {break} } } } + # Ensure that the current line is also checked for correct spelling + spellcheck_check_all [expr {int([$editor index insert])}] 1 + # Restore previous editor state if {$frozen} {$editor configure -state disabled} } @@ -1458,6 +1548,7 @@ public method highlight_visible_area {} { # if it is not then invoke procedure 'X::__save_as' # @return Bool - result public method save {} { + if {$ro_mode} {return 1} if {$editor_to_use} {return 1} if {$save_in_progress} {return 1} set save_in_progress 1 @@ -1474,9 +1565,13 @@ public method save {} { catch { file rename -force $fullFileName "$fullFileName~" } + + # Stop watching for modification of this file on disk (we will reenable it later) + FSnotifications::forget $fullFileName } + if {[catch { - set chanel [open $fullFileName w 420] + set chanel [open $fullFileName w 0640] }]} then { tk_messageBox \ -parent . \ @@ -1485,6 +1580,10 @@ public method save {} { -title [mc "Permission denied"] \ -message [mc "Unable to open file:\n\"%s\"\nfor writing" $fullFileName] set save_in_progress 0 + + # Again start watching for modification of this file on disk + FSnotifications::watch $fullFileName [list ::Editor::file_change_notif $this] + return 0 } fconfigure $chanel -translation $eol -encoding $encoding @@ -1494,6 +1593,9 @@ public method save {} { $editor edit modified 0 set modified 0 + # Again start watching for modification of this file on disk + FSnotifications::watch $fullFileName [list ::Editor::file_change_notif $this] + # Stop autosave timer catch { after cancel $autosave_timer @@ -1501,17 +1603,174 @@ public method save {} { } # Change application status - Sbar [mc "File %s saved" $fullFileName] ::X::adjust_title set save_in_progress 0 if {$fullFileName == {}} { return 0 - } { + } else { + if {$::MICROSOFT_WINDOWS} { ;# "/" --> "\" + regsub -all {/} $fullFileName "\\" fullFileName_win + } else { + set fullFileName_win $fullFileName + } + Sbar [mc "File %s saved" $fullFileName_win] return 1 } } +## Set internal flag "file_change_notif_flg" to true + # + # The flag indicates that the file opened in this editor was modified on disk + # by another program. The flag is automatically cleared when the user is + # informed about the modification to the file. + # + # @return void +public method set_file_change_notif_flg {} { + set file_change_notif_flg 1 +} + +## Check flag "file_change_notif_flg" and if set, inform the user about this. + # + # The flag file_change_notif_flg indicates that the file opened in this editor + # was modified on disk by another program. The flag is automatically cleared by + # this method. The user is informed via a dialog window giving him three + # options, reload the file, overwrite it on disk, and ignore it. + # + # @return void +public method check_file_change_notif {} { + # Check the flag, and clear it if it was set + if {!$file_change_notif_flg} { + return + } + set file_change_notif_flg 0 + + # Create the dialog window + set dialog [toplevel .file_change_notif_dlg] + + # Create top frame (dialog icon and text of the message) + set dlg_top_frame [frame $dialog.top_frame] + pack [label $dlg_top_frame.image -image ::ICONS::32::messagebox_warning] -side left -padx 5 + pack [label $dlg_top_frame.label \ + -justify left \ + -text [mc "The file '%s' was modified from outside of this program.\n\nWhat do you want to do with the modified file?" [file tail $fullFileName]] \ + ] -side left -fill x -expand 1 -padx 5 + + # Create bottom bar with dialog buttons + set button_frame [frame $dialog.button_frame] + pack [ttk::button $button_frame.button_reload \ + -text [mc "Reload in editor"] \ + -compound left \ + -image ::ICONS::16::reload \ + -command " + $parentObject filelist_reload_file $this 1 + grab release $dialog + destroy $dialog + " \ + ] -side left -padx 2 + pack [ttk::button $button_frame.button_overwrt \ + -text [mc "Overwrite on disk"] \ + -compound left \ + -image ::ICONS::16::filesave \ + -command " + $this save + grab release $dialog + destroy $dialog + " \ + ] -side left -padx 2 + pack [ttk::button $button_frame.button_cancel \ + -text [mc "Do nothing"] \ + -compound left \ + -image ::ICONS::16::cancel \ + -command " + grab release $dialog + destroy $dialog + " \ + ] -side left -padx 2 + + # Pack window frames + pack $dlg_top_frame -side top -fill x -expand 1 -padx 5 -pady 10 + pack $button_frame -side bottom -side right -padx 5 -pady 5 + + bind $dialog <Escape> " + grab release $dialog + destroy $dialog + " + + # Set dialog attributes (modal window) + wm iconphoto $dialog ::ICONS::16::status_unknown + wm title $dialog [mc "File changed on disk"] + wm state $dialog normal + wm minsize $dialog 400 110 + wm transient $dialog . + wm protocol $dialog WM_DELETE_WINDOW " + grab release $dialog + destroy $dialog + " + update + catch { + grab $dialog + } + raise $dialog + focus -force $button_frame.button_cancel + tkwait window $dialog +} + +## File change notification callback + # + # This function is supposed to be called by the FSnotifications component when + # a modification to the currently opened file was made by another program. + # + # @return void +proc file_change_notif {editor_ref filename} { + # This call is invalid if there are no projects opened + if {![llength ${::X::openedProjects}]} { + return + } + + # Attempt to find the corresponding project and editor index number + foreach project ${::X::openedProjects} { + set list_of_editors [$project cget -editors] + set actual_editor [$project cget -actualEditor] + set actual_editor2 [$project cget -actualEditor2] + set editor_idx [lsearch -ascii -exact $list_of_editors $editor_ref] + + if {$editor_idx == -1} { + # Editor editor index number not found, move on to another project + continue + } + + # Try to get the "frozen" flag from the editor + if {[catch { + set editor_frozen [$editor_ref get_flag_frozen] + }]} then { + # Unable to comply, that probably means that the editor + # does not exist any more + return + } + + # Set the "file_change_notif_flg" flag + $project editor_procedure $editor_idx set_file_change_notif_flg {} + + # Check the "file_change_notif_flg" flag right away, if the + #+ editor is currently visible to the user + if { + ($project == ${::X::actualProject}) + && + ($editor_idx == $actual_editor || $editor_idx == $actual_editor2) + } then { + # If the editor is in frozen state, i.e. the MCU + # simulator is engaged, then don't annoy with nonsense + # messages, and instead inform the user later. + if {!$editor_frozen} { + $project editor_procedure $editor_idx check_file_change_notif {} + } + } + + break + } +} + ## Set variable 'fullFileName' for later file save (method 'save') # note: also change editors status bar # @parm String full_filename - the full filename (including path) @@ -1520,6 +1779,16 @@ public method save {} { public method set_FileName {full_filename rootName} { if {$editor_to_use} {return} + # Start watching for changes in the file (on disk) + if {$fullFileName != {}} { + # Stop watching the old file + FSnotifications::watch forget $fullFileName + } + if {$full_filename != {}} { + # Start watching the new file + FSnotifications::watch $full_filename [list ::Editor::file_change_notif $this] + } + # set variables set fullFileName $full_filename set filename $rootName @@ -1535,7 +1804,7 @@ public method getFileName {} { return [list [file dirname $fullFileName] $filename] } -## Change letter case acording to the given options +## Change letter case according to the given options # @parm List options - list of 21 values, each must be one of {- L -U} # '-' - keep case # 'U' - Uppercase @@ -1563,13 +1832,13 @@ public method change_letter_case {options} { tag_imm_dec tag_imm_bin tag_imm_constant tag_imm_unknown tag_macro - } \ + } \ { # Evaluate option if {$option == {-}} {continue} if {$option == {U}} { set option {toupper} - } { + } else { set option {tolower} } @@ -1744,7 +2013,7 @@ public method copy {} { Sbar [mc "Unable to execute: nothing selected"] return 0 # Adjust clipboard content - } { + } else { clipboard clear clipboard append $data return 1 @@ -1752,11 +2021,11 @@ public method copy {} { } ## Paste clipboard content to the text at the cursor position - # @parm Bool = 0 - Use X selection instead of the clipboard - # @ - # @ + # @parm Bool use_X_sel=0 - Use X selection instead of the clipboard + # @parm Int x - X coordinate + # @parm Int y - Y coordinate # @return bool - 1: successful; 0: failed -public method paste args { +public method paste {{use_X_sel 0} {x {}} {y {}}} { if {$critical_edit_proc} {return} set critical_edit_proc 1 @@ -1765,9 +2034,9 @@ public method paste args { set original_cur_pos [$editor index insert] } - if {[lindex $args 0] == {1}} { + if {$use_X_sel} { set cmd {selection} - } { + } else { set cmd {clipboard} } @@ -1780,9 +2049,7 @@ public method paste args { return 0 } - if {[lindex $args 0] == {1}} { - set x [lindex $args 1] - set y [lindex $args 2] + if {$use_X_sel} { $editor mark set insert @$x,$y catch { $editor tag remove sel 0.0 end @@ -1793,15 +2060,16 @@ public method paste args { $editor configure -autoseparators 0 deleteselection recalc_left_frame - # insert data to the text, restore syntax hightlight and return 1 + # insert data to the text, restore syntax highlight $editor insert [$editor index insert] $data recalc_left_frame recalc_status_counter {} $editor see [$editor index insert] - update idle + update idletasks set line [expr {int([$editor index insert])}] rightPanel_adjust $line parse $line + spellcheck_check_all $line 2 ;# Perform spell check for the current line highlight_visible_area $editor edit separator $editor configure -autoseparators 1 @@ -1895,7 +2163,7 @@ public method cut {} { set critical_edit_proc 0 return 0 # Cut - } { + } else { # Adjust clipboard content deleteselection clipboard clear @@ -1957,8 +2225,10 @@ public method kill_childern {} { if {$editor_to_use} { bind $top_frame <Destroy> {} if {!$::MICROSOFT_WINDOWS} { ;# There is no kill command on Microsoft Windows - catch { - exec -- kill $pid + if {$pid != [pid] && $pid != 0} { + catch { + exec -- kill $pid + } } } catch { @@ -1967,7 +2237,7 @@ public method kill_childern {} { } } -## Get ID of file type (programing language used) +## Get ID of file type (programming language used) # @return Int - 0 == Assembly language; 1 == C language public method get_language {} { if {$prog_language == -1} { @@ -1979,12 +2249,12 @@ public method get_language {} { } else { return 0 } - } { + } else { return $prog_language } } -## Set file type (programing language used) +## Set file type (programming language used) # @parm Int lang - -1 == unknown; 0 == Assembly language; 1 == C language # @return void public method force_language {lang} { @@ -2173,7 +2443,7 @@ public method getFileStatistics {} { if {$found} {continue} if {[string is wordchar -strict $char]} { incr words_and_numbers - } { + } else { incr others } } @@ -2181,7 +2451,7 @@ public method getFileStatistics {} { # Determinate line type excluding empty lines if {$last_words == $words && $last_keywords == $keywords && $last_comments < $comments} { incr commented_lines - } { + } else { incr normal_lines } } @@ -2200,12 +2470,22 @@ public method getFileStatistics {} { } ## Set read only mode - # @parm Bool mode_frag - 1 == Read only; 0 = Read and write - # @return void + # @parm Bool mode_frag - 1 == Read only; 0 == Read and write + # @return Bool - true == ok; false == cannot comply! public method change_RO_MODE {mode_frag} { if {$editor_to_use} {return} set ro_mode $mode_frag + if {!$ro_mode && [$parentObject cget -S_flag_read_only]} { + tk_messageBox \ + -parent . \ + -type ok \ + -icon warning \ + -title [mc "Read-only project"] \ + -message [mc "This project has a special purpose, modifications to this project are not allowed."] + return 0 + } + # Set to read only if {$ro_mode} { $editor configure -state disabled @@ -2220,7 +2500,7 @@ public method change_RO_MODE {mode_frag} { set state {disabled} # Set to normal mode - } { + } else { $editor configure -state normal $ins_mode_lbl configure \ -bg {#DDDDDD} \ @@ -2237,6 +2517,7 @@ public method change_RO_MODE {mode_frag} { $menu entryconfigure [::mc $entry] -state $state } ::X::adjust_mainmenu_and_toolbar_to_editor $ro_mode {} + return 1 } ## Perform program jump @@ -2257,7 +2538,7 @@ public method ljmp_this_line {} { set lineNum [$parentObject simulator_getCurrentLine] if {$lineNum != {}} { $parentObject move_simulator_line $lineNum - } { + } else { $parentObject editor_procedure {} unset_simulator_line {} } $parentObject Simulator_sync_PC_etc @@ -2268,8 +2549,8 @@ public method ljmp_this_line {} { public method lcall_this_line {} { if {$editor_to_use} {return} # Determinate target address - set address [$parentObject simulator_line2address \ - [expr {int([$editor index insert])}] \ + set address [$parentObject simulator_line2address \ + [expr {int([$editor index insert])}] \ [$parentObject simulator_get_filenumber $fullFileName] \ ] if {$address == {}} { @@ -2281,8 +2562,12 @@ public method lcall_this_line {} { set lineNum [$parentObject simulator_getCurrentLine] if {$lineNum != {}} { $parentObject move_simulator_line $lineNum - } { + } else { $parentObject editor_procedure {} unset_simulator_line {} } $parentObject Simulator_sync_PC_etc -}
\ No newline at end of file +} + +# >>> File inclusion guard +} +# <<< File inclusion guard |