source: tol/tolbase/lib/toltk/bystext.tcl

devel
Last change on this file was 935c832, checked in by Pedro Gea <pgea@…>, 10 years ago

Refs #1933
Se corrige [7379]. Se comentaron dos líneas que no eran trazas!

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@7381 be4846ae-f051-483a-831f-b64e7d08527f

  • Property mode set to 100644
File size: 35.7 KB
Line 
1#/////////////////////////////////////////////////////////////////////////////
2# FILE    : bystext.tol
3# PURPOSE :
4#/////////////////////////////////////////////////////////////////////////////
5
6#/////////////////////////////////////////////////////////////////////////////
7# TESTING
8#/////////////////////////////////////////////////////////////////////////////
9# Put if {1} for testing this file.
10
11package require snit
12
13if {0} {
14  package require Tk
15  package require BWidget
16  set toltk_script_path [file dirname [info script]]
17  package require msgcat
18  namespace import ::msgcat::*
19  ::msgcat::mclocale es
20  ::msgcat::mcload [file join $toltk_script_path msgs]
21 
22}
23
24::snit::widgetadaptor rotext {
25
26  constructor {args} {
27    # Turn off the insert cursor
28    #installhull using text $self -insertwidth 0
29    # DDG the $self gaves an error at least with 0.97 onwards
30    installhull using text -insertwidth 0
31   
32    # Apply an options passed at creation time.
33    $self configurelist $args
34  }
35 
36  # Disable the insert and delete methods, to make this readonly.
37  method insert {args} {}
38  method delete {args} {}
39 
40  # Enable ins and del as synonyms, so the program can insert and
41  # delete.
42  delegate method ins to hull as insert
43  delegate method del to hull as delete
44 
45  # Pass all other methods and options to the real text widget, so
46  # that the remaining behavior is as expected.
47  delegate method * to hull
48  delegate option * to hull
49}
50
51#/////////////////////////////////////////////////////////////////////////////
52# NAMESPACE
53#/////////////////////////////////////////////////////////////////////////////
54
55namespace eval ::BayesText {
56  variable options
57}
58
59
60#/////////////////////////////////////////////////////////////////////////////
61# PROCEDURES
62#/////////////////////////////////////////////////////////////////////////////
63
64#/////////////////////////////////////////////////////////////////////////////
65   proc ::BayesText::FindShow {editor {next 0} {txt ""} {regexp 0}} {
66
67#
68# PURPOSE: This proc mades bla, bla, bla,
69#          and bla, bla, bla, ...
70#
71# ALGORITHM:
72#   Xxx xxxx xx:
73#     Xxxxx xxx xxx.
74#     Xxxxx xxx xxx.
75#   Xxxxx.
76#
77# PARAMETERS:
78#   editor -> text widget where text has to be found
79#   next   ->
80#   txt    ->
81#
82# RETURN:
83#
84#/////////////////////////////////////////////////////////////////////////////
85  variable options
86 
87  ::BayesText::ReadIni
88 
89  set Instance ::BayesText::Find$editor
90  if { [lsearch [namespace children ::BayesText] $Instance] != -1 } {
91     
92  } else  {
93    namespace eval $Instance {
94      variable data
95     
96      #data(find,text) --> texto a buscar
97      #data(find,dir)  --> dirección de búsqueda
98      #data(start)     --> indica desde donde se empieza a buscar
99      #data(find,case) -->
100      #data(editor)    --> el path del widget text en el q buscar
101      #data(path)      --> el path del toplevel que muestra el cuado de búsqueda
102      #data(frm,cad)   --> entry donde se inserta el texto a buscar
103    }
104  }
105  upvar \#0 ${Instance}::data data
106
107  # exists data(find,temp) ?
108  if {!([info exists data(find,temp)])} {
109    set data(find,temp) ""
110  }
111 
112  set data(editor) $editor
113  set data(path)   ${editor}.tFind
114  if [winfo exist $data(path)] {
115    raise $data(path)
116    focus $data(frm,cad)
117  # $data(frm,cad) selection range 0 end
118    $data(frm,cad).e selection range 0 end
119    return
120  }
121 
122  # inizialization values
123  set data(find,dir)    $options(find,dir)
124  set data(find,case)   $options(find,case) 
125  set data(find,regexp) $regexp
126  # text find ?
127  if {[string length $txt]} {
128    set data(find,text) $txt
129  } else {
130    set idxs [$editor tag ranges sel]
131   
132    # next find ?
133    if { $next eq 1 } {
134      set data(find,text) $data(find,temp)
135    } else {
136      # text selected ?
137      if {!(([llength [lindex $idxs 0]] eq 0) && \
138            ([llength [lindex $idxs 1]] eq 0))} {
139        set txt [$editor get [lindex $idxs 0] [lindex $idxs 1]]
140        if {!($txt eq "")} {
141          set txt [lindex [split $txt "\n"] 0]
142          set data(find,text) $txt
143        }
144      }
145    }
146  }
147  # type of find ?
148  if {$next && [info exists ${Instance}::data(find,text)] && ($data(find,text) !="") } {
149    FindNext $Instance
150  } else {
151    FindCreate $Instance
152  }
153  # save teh last search
154  set data(find,temp) $data(find,text)
155}
156
157
158#/////////////////////////////////////////////////////////////////////////////
159proc ::BayesText::SearchShow {instance } {
160#
161# PURPOSE: Shows the form of function search with the first word selected
162#
163# PARAMETERS:
164#   editor -> text widget where text has to be found
165#
166#
167#/////////////////////////////////////////////////////////////////////////////
168  # show find dialog
169  set dialog [::funcSearch::Show]
170  # function find ?
171  set idxs [$instance tag ranges sel]
172  if {!(([llength [lindex $idxs 0]] eq 0) && \
173        ([llength [lindex $idxs 1]] eq 0))} {     
174    set txt [$instance get [lindex $idxs 0] [lindex $idxs 1]]
175    if {!($txt eq "")} {
176      set txt [lindex [split $txt " "] 0]   
177      ::funcSearch::SearchWord $txt
178    }
179  }   
180} 
181
182
183#/////////////////////////////////////////////////////////////////////////////   
184proc ::BayesText::FindPosText { Instance } {
185#
186# PURPOSE: find the next position of text
187#
188#/////////////////////////////////////////////////////////////////////////////     
189  upvar \#0 ${Instance}::data data
190  set start [$data(editor) index insert]
191  if [string equal $data(find,dir) "forward"] {
192    set end [$data(editor) index end]
193  } else {
194    set end "1.0"
195  }
196  set ::_len 0
197  if $data(find,case) {
198    if {[info exist data(find,regexp)] && $data(find,regexp)} {
199      set pos [$data(editor) search -regexp -count ::_len -$data(find,dir) --\
200              $data(find,text) $start $end]
201    } else {
202      set pos [$data(editor) search -count ::_len -$data(find,dir) --\
203              $data(find,text) $start $end]
204    }
205  } else  {
206    set pos [$data(editor) search -count ::_len -nocase -$data(find,dir) --\
207            $data(find,text) $start $end]
208  }
209  #Tolcon_Trace "Devuelvo pos=$pos, len=$::_len"
210  return [list $pos $::_len]
211}
212
213
214#/////////////////////////////////////////////////////////////////////////////
215proc ::BayesText::FindNext { Instance } {
216#
217# PURPOSE: Make the next find in editor
218#
219#///////////////////////////////////////////////////////////////////////////// 
220  upvar \#0 ${Instance}::data data
221  #  Coger la posición actual del cursor en el text y buscar desde ahí,
222  set posOrig [$data(editor) index insert]
223 
224  set res [FindPosText $Instance]
225  set pos [lindex $res 0]
226  set len [lindex $res 1]
227  # comprobamos si ha encontrado algo
228  if { $pos != "" } {
229    if [string equal $data(find,dir) "forward"] {
230        set start "$pos + $len char"
231    } elseif [string equal $data(find,dir) "backward"] {
232        set start "$pos - $len char"
233    }
234    tk::TextSetCursor $data(editor) $start
235    $data(editor) see $pos
236    # Intamos un tag found ya que sel parece no funcionar correctamente en
237    # windows cuando el text pierde el foco
238    $data(editor) tag delete found
239    set fore [$data(editor) tag cget sel -foreground]
240    set back [$data(editor) tag cget sel -background]
241    set bord [$data(editor) tag cget sel -borderwidth]
242    $data(editor) tag configure found -foreground $fore -background $back -borderwidth $bord
243    $data(editor) tag add sel $pos "$pos + $len char"
244    $data(editor) tag add found $pos "$pos + $len char"
245  } else {
246    tk::TextSetCursor $data(editor) $posOrig
247    $data(editor) tag delete sel
248    $data(editor) tag delete found
249    if [string equal $data(find,dir) "forward"] {
250      set msg "[mc SearchUpEndDoc].\n[mc FindFromBegin]"
251    } else {
252      set msg "[mc SearchUpBeginDoc].\n[mc FindFromEnd]"
253    }
254    if [winfo exists $data(path)] {
255      set parent $data(path)
256    } else  {
257      set parent $data(editor)
258    }
259    set rq [tk_messageBox -type okcancel -icon info -parent $parent\
260            -title [mc "Editor"] -message $msg]
261    if {$rq == "ok"} {
262      if [string equal $data(find,dir) "forward"] {
263        tk::TextSetCursor $data(editor) "1.0"
264      } else {
265        tk::TextSetCursor $data(editor) [$data(editor) index end]
266      }
267      FindNext $Instance
268    }
269  }
270  # Debo quedarme yo con el foco, no el editor
271
272  #focus $data(editor)
273}
274
275#/////////////////////////////////////////////////////////////////////////////
276   proc ::BayesText::FindCreate {Instance } {
277#
278# PURPOSE: Creates a Find Dialog given a Instance
279#
280#/////////////////////////////////////////////////////////////////////////////
281  upvar \#0 ${Instance}::data data
282
283  set dialog [Dialog $data(path) -title [mc "Find"]\
284          -default 0 -modal none -parent $data(editor)]
285  wm protocol $dialog WM_DELETE_WINDOW \
286    [list ::BayesText::FindDestroy $Instance $dialog] 
287  set w [$dialog getframe]
288  wm resizable $data(path) 0 0
289 
290  set data(frm,cad) [LabelEntry  $w.eTxt -label "[mc "Find"]: " \
291          -textvariable ${Instance}::data(find,text)]
292  checkbutton $w.case  -text [mc "Case sensitive"] \
293          -variable ${Instance}::data(find,case) -pady 0
294  TitleFrame $w.dir -bd 2 -relief groove -text [mc "Direction"]
295  set f [$w.dir getframe]
296  radiobutton $f.forward -text [mc "Forward"] -value forward \
297          -variable ${Instance}::data(find,dir)\
298          -highlightthickness 0 -pady 0
299  radiobutton $f.backward -text [mc "Backward"] -value backward \
300          -variable ${Instance}::data(find,dir)\
301          -highlightthickness 0 -pady 0
302  Button $w.findNext -text [mc "Find next"] -width 16 \
303          -command [list ::BayesText::FindNext $Instance] \
304          -helptext [mc "Find next"]
305  Button $w.cancelar -text [mc "Cancel"] -width 16 -helptext "" \
306    -command [list ::BayesText::FindDestroy $Instance $dialog]
307 
308  bind $dialog <Return> [list ::BayesText::FindNext $Instance]
309  bind $dialog <F3>     [list ::BayesText::FindNext $Instance]
310  bind $dialog <Escape> [list ::BayesText::FindDestroy $Instance $dialog]
311
312  # Hemos añadido un tag para la selección, hay que quitarle como el tag sel
313  bind $data(editor) <ButtonPress> +[list $data(editor) tag delete found]
314 
315  grid $f.forward  $f.backward -sticky nw
316 
317  grid $w.eTxt  -       $w.findNext -sticky news -padx 5 -pady 2
318  grid $w.case  $w.dir  $w.cancelar -sticky new  -padx 5
319 
320  grid columnconfigure $w  0 -weight 1
321  grid columnconfigure $w  1 -weight 0
322  grid rowconfigure    $w  0 -weight 0
323  grid rowconfigure    $w  1 -weight 0
324  grid rowconfigure    $w  2 -weight 0
325  grid rowconfigure    $w 10 -weight 1
326 
327  wm geometry $dialog 360x90
328  $dialog draw
329  update
330  focus $data(frm,cad)
331  $data(frm,cad).e selection range 0 end
332}
333
334
335#/////////////////////////////////////////////////////////////////////////////
336proc ::BayesText::FindDestroy {Instance dialog} {
337#
338# PURPOSE: Replace text in editor
339#
340#/////////////////////////////////////////////////////////////////////////////
341  variable options
342
343  upvar \#0 ${Instance}::data data
344  # inizialization values
345  set options(find,dir)  $data(find,dir)
346  set options(find,case) $data(find,case)
347  ::BayesText::WriteIni
348  # destroy
349  destroy $dialog
350}   
351
352
353#/////////////////////////////////////////////////////////////////////////////
354proc ::BayesText::ReplaceShow {editor {next 0}} {
355#
356# PURPOSE: Replace text in editor
357#
358#///////////////////////////////////////////////////////////////////////////// 
359  variable options
360 
361  ::BayesText::ReadIni
362 
363  set Instance ::BayesText::Replace$editor
364  if { [lsearch [namespace children ::BayesText] $Instance] != -1 } {
365     
366  } else  {
367    namespace eval $Instance {
368      variable data
369      #data(find,text)    --> texto a buscar
370      #data(replace,text) --> texto a por el que remplazar
371      #data(replace,dir)  --> dirección de búsqueda
372      #data(replace,case) -->
373      #data(editor)       --> el path del widget text en el q buscar
374      #data(path)         --> el path del toplevel que muestra el cuado de búsqueda
375      #data(frm,cad)      --> entry donde se inserta el texto a buscar
376    }
377  }
378 
379  upvar \#0 ${Instance}::data data
380
381  # inizialization values
382  #set data(replace,dir)    $options(replace,dir)
383  set data(find,dir)       $options(replace,dir)
384  #set data(replace,case)   $options(replace,case)
385  set data(find,case) $options(replace,case)
386 
387  set data(editor) $editor
388  set data(path)   ${editor}.tReplace
389  if [winfo exist $data(path)] {
390    raise $data(path)
391    focus $data(frm,cad)
392    return
393  }
394  if {$next && [info exists ${Instance}::data(find,text)] && \
395     [info exists ${Instance}::data(replace,text)] && ($data(find,text) !="") } {
396    ReplaceNext $Instance
397  } else {
398    ReplaceCreate $Instance
399  }
400}
401
402
403#/////////////////////////////////////////////////////////////////////////////
404proc ::BayesText::ReplaceCreate { Instance } {
405#
406# PURPOSE: Creates a Replace Dialog given a Instance
407#
408#/////////////////////////////////////////////////////////////////////////////   
409  upvar \#0 ${Instance}::data data
410  # opciones de remplazado
411
412  set dialog [Dialog $data(path) -title [mc "Replace"]\
413          -default 0 -modal none -parent $data(editor)]
414  wm protocol $dialog WM_DELETE_WINDOW \
415    [list ::BayesText::ReplaceDestroy $Instance $dialog]   
416 
417  set w [$dialog getframe]
418  wm resizable $data(path) 0 0
419 
420  set data(replace,cad) [LabelEntry  $w.eTxt -width 35 \
421          -label "[mc "Find"]: " -labelwidth 15 \
422          -textvariable ${Instance}::data(find,text)]
423  set data(replace,rem) [LabelEntry  $w.eRem -width 35 -labelwidth 15 \
424          -label "[mc "Replace with"]: " \
425          -textvariable ${Instance}::data(replace,text)]
426  checkbutton $w.case  -text [mc "Case sensitive"] \
427          -variable ${Instance}::data(replace,case) -pady 0
428  Button $w.findNext -text [mc "Find next"] -width 16 \
429          -command [list ::BayesText::FindNext $Instance] \
430          -helptext [mc "Find next"]
431  Button $w.replaceNext -text [mc "Replace"] -width 16 \
432          -command [list ::BayesText::ReplaceNext $Instance] \
433          -helptext [mc "Replace next"]
434  Button $w.replaceAll -text [mc "Replace all"] -width 16 \
435          -command [list ::BayesText::ReplaceAll $Instance] \
436          -helptext [mc "Replace all"]
437  Button $w.cancelar -text [mc "Cancel"] -width 16 -helptext "" \
438    -command [list ::BayesText::ReplaceDestroy $Instance $dialog]
439 
440  bind $dialog <Return> [list ::BayesText::FindNext $Instance]
441  bind $dialog <Escape> [list ::BayesText::ReplaceDestroy $Instance $dialog]
442 
443  grid $w.eTxt   $w.findNext     -sticky nw -padx 5 -pady 2
444  grid $w.eRem   $w.replaceNext  -sticky nw -padx 5 -pady 2
445  grid $w.case   $w.replaceAll   -sticky nw -padx 5 -pady 2
446  grid ^         $w.cancelar     -sticky nw -padx 5 -pady 2
447 
448  wm geometry $dialog 360x90
449  $dialog draw
450  update
451  focus $data(replace,cad)
452}
453
454
455#/////////////////////////////////////////////////////////////////////////////
456proc ::BayesText::ReplaceDestroy {Instance dialog} {
457#
458# PURPOSE: Replace text in editor
459#
460#/////////////////////////////////////////////////////////////////////////////
461  variable options
462
463  upvar \#0 ${Instance}::data data
464  # inizialization values
465  #set options(replace,dir)  $data(replace,dir)
466  #set options(replace,case) $data(replace,case)
467  set options(replace,dir)  $data(find,dir)
468  set options(replace,case) $data(find,case)
469  ::BayesText::WriteIni 
470  # destroy
471  destroy $dialog
472}   
473
474#/////////////////////////////////////////////////////////////////////////////
475proc ::BayesText::ReplaceNext { Instance } {
476#
477# PURPOSE: Replace next ocurrence
478#
479#/////////////////////////////////////////////////////////////////////////////   
480  upvar \#0 ${Instance}::data data
481  # comprobamos que este lleno entry de buscar
482  if {$data(find,text) != ""} {
483    if {[catch "$data(editor) index sel.first" pos] == 0} {
484      set lon    [string length $data(find,text)]
485      set lonRem [string length $data(replace,text)]
486      set posFin "$pos + $lon char"
487      # reemplazamos caracteres seleccionados
488      $data(editor) delete $pos $posFin
489      $data(editor) insert $pos $data(replace,text)
490      #tk::TextSetCursor $data(editor) $pos
491      #tk::TextSetCursor $data(editor) $posFin
492    }
493  }
494  FindNext $Instance
495}
496
497
498#/////////////////////////////////////////////////////////////////////////////
499proc ::BayesText::ReplaceAll { Instance } {
500#
501# PURPOSE: Replace all
502#
503#/////////////////////////////////////////////////////////////////////////////   
504  upvar \#0 ${Instance}::data data
505  # guardamos la posición actual
506  set posOrig [$data(editor) index insert]
507  # nos posicionamos en el principio del texto
508  tk::TextSetCursor $data(editor) "1.0"
509  # mientras posicion actual menor que fin repetimos busqueda
510  set lon    [string length $data(find,text)]
511  set lonRem [string length $data(replace,text)]
512  set res    [FindPosText $Instance]
513  set pos    [lindex $res 0]
514  set lon    [lindex $res 1]
515  set posFin "$pos + $lon char"
516  while {[string length $pos]} {
517    # reemplazamos caracteres seleccionados
518    $data(editor) delete $pos $posFin
519    $data(editor) insert $pos $data(replace,text)
520    tk::TextSetCursor $data(editor) "$pos + $lonRem char"
521    set res [FindPosText $Instance]
522    set pos [lindex $res 0]
523    set lon [lindex $res 1]
524    set posFin "$pos + $lon char"
525  }
526  # recuperamos posicion, si es mayor que fin, ponemos fin
527  set end [$data(editor) index end]
528  if {[$data(editor) compare $posOrig > $end]} {
529    tk::TextSetCursor $data(editor) $end
530  } else  {
531    tk::TextSetCursor $data(editor) $posOrig
532  }
533}
534
535
536#/////////////////////////////////////////////////////////////////////////////
537proc ::BayesText::Open {editor path {pos 1.0}} {
538#
539# PURPOSE:
540#
541#/////////////////////////////////////////////////////////////////////////////   
542  if { ![catch {set fd [open $path r] } msgerr] } {
543    $editor insert $pos [read -nonewline $fd]
544    close $fd
545    $editor mark set insert 1.0
546    return 1
547  }
548  error $msgerr
549}
550
551
552#/////////////////////////////////////////////////////////////////////////////
553proc ::BayesText::SaveTxt {texto path} {
554#
555# PURPOSE: Save text editor
556#
557#/////////////////////////////////////////////////////////////////////////////   
558  if { ![ catch { set fd [open $path w] } msgerr] } {
559    puts -nonewline $fd $texto
560    close $fd
561    return 1
562  }
563  error $msgerr
564}
565
566
567#/////////////////////////////////////////////////////////////////////////////
568proc ::BayesText::Save {editor path} {
569#
570# PURPOSE: Save
571#
572#/////////////////////////////////////////////////////////////////////////////   
573  set texto [$editor get 1.0 end]
574  SaveTxt $texto $path
575}
576
577
578#/////////////////////////////////////////////////////////////////////////////
579proc ::BayesText::Cut {editor} {
580#
581# PURPOSE: Cut text
582#
583#/////////////////////////////////////////////////////////////////////////////   
584  #clipboard clear
585  tk_textCut $editor
586}
587
588
589#/////////////////////////////////////////////////////////////////////////////
590proc ::BayesText::Copy {editor} {
591#
592# PURPOSE: Copy text
593#
594#/////////////////////////////////////////////////////////////////////////////   
595  #clipboard clear
596  tk_textCopy $editor
597}
598
599
600#/////////////////////////////////////////////////////////////////////////////
601proc ::BayesText::Paste {editor} {
602#
603# PURPOSE: Paste text
604#
605#/////////////////////////////////////////////////////////////////////////////   
606  # a partir de la version 8.4
607  tk_textPaste $editor
608  #catch {$editor insert insert [selection get -selection CLIPBOARD]}
609}
610
611
612#/////////////////////////////////////////////////////////////////////////////
613proc ::BayesText::SelectAll {editor} {
614#
615# PURPOSE: Select all text
616#
617#/////////////////////////////////////////////////////////////////////////////   
618  $editor tag add sel 1.0 end
619}
620
621
622#/////////////////////////////////////////////////////////////////////////////
623proc ::BayesText::Delete {editor} {
624#
625# PURPOSE: Delete text selected
626#
627#/////////////////////////////////////////////////////////////////////////////   
628  set state [$editor cget -state]
629  $editor configure -state normal
630 
631  if ![catch {set ini [$editor index sel.first]}] {
632    set fin [$editor index sel.last]
633    $editor delete $ini $fin
634  }
635  $editor configure -state $state
636}
637
638
639#/////////////////////////////////////////////////////////////////////////////
640proc ::BayesText::DeleteAll {editor} {
641#
642# PURPOSE: Delete all
643#
644#/////////////////////////////////////////////////////////////////////////////   
645  set state [$editor cget -state]
646  $editor configure -state normal
647  $editor delete 1.0 end
648  $editor configure -state $state
649}
650
651#/////////////////////////////////////////////////////////////////////////////
652proc ::BayesText::Refresh {editor} {
653#
654# PURPOSE: Refresh highlight
655#
656# PARAMETERS:
657#  editor -> text widget to refresh highlight
658#
659#/////////////////////////////////////////////////////////////////////////////
660  $editor highlight 1.0 end
661}
662
663
664#/////////////////////////////////////////////////////////////////////////////
665proc ::BayesText::Indent {editor chars} {
666#
667# PURPOSE: Indent text
668#
669#/////////////////////////////////////////////////////////////////////////////   
670  if ![catch {set ini [$editor index sel.first]}] {
671    set fin [$editor index sel.last]
672    set lineIni [lindex [split $ini .] 0]
673    set lineFin [lindex [split $fin .] 0]
674     
675    for {set i $lineIni} {$i<= $lineFin} {incr i} {
676      $editor insert $i.0 [string repeat " " $chars]
677    }
678    $editor tag add sel $ini $fin
679  } else {
680    $editor insert {insert linestart} [string repeat " " $chars]
681  }
682}
683
684
685#/////////////////////////////////////////////////////////////////////////////
686proc ::BayesText::UnIndent {editor chars} {
687#
688# PURPOSE: UnIndent text
689#
690#/////////////////////////////////////////////////////////////////////////////   
691  if ![catch {set ini [$editor index sel.first]}] {
692    set fin [$editor index sel.last]
693    set lineIni [lindex [split $ini .] 0]
694    set lineFin [lindex [split $fin .] 0]
695   
696    for {set i $lineIni} {$i<= $lineFin} {incr i} {
697      if [string equal [$editor get $i.0 $i.$chars] [string repeat " " $chars]] {
698        $editor delete $i.0 $i.$chars
699      }
700    }
701    $editor tag add sel $ini $fin
702  } else {
703    if [string equal [$editor get {insert linestart} "insert linestart + $chars c"]\
704       [string repeat " " $chars]] {
705      $editor delete {insert linestart} "insert linestart + $chars c"
706    }
707  }
708}
709
710
711#/////////////////////////////////////////////////////////////////////////////
712proc ::BayesText::GetSelectionOrAll {w} {
713#
714# PURPOSE: Returns selected text in text widget w (or all text if nothing
715#          is selected)
716#
717# PARAMETERS:
718#  w -> text widget to refresh highlight
719#
720#/////////////////////////////////////////////////////////////////////////////
721  set idxs [$w tag ranges sel]
722  if [llength $idxs] {
723    set txt [$w get [lindex $idxs 0] [lindex $idxs 1]]
724  } else {
725    set txt [$w get 0.0 end]
726  }
727  return $txt
728}
729
730
731#/////////////////////////////////////////////////////////////////////////////   
732proc ::BayesText::FontChange {editor} {
733#
734# PURPOSE: Change font text
735#
736#/////////////////////////////////////////////////////////////////////////////     
737  set fnt [SelectFont .sf -title [mc "Select font"] \
738          -parent $editor -font [$editor cget -font]\
739          -sampletext "Bayes Forecast"]
740  if {($fnt != "") && ($editor != "")} {
741    $editor configure -font $fnt
742  }
743  return $fnt
744}
745
746
747#/////////////////////////////////////////////////////////////////////////////   
748proc ::BayesText::MenuCreate {editor} {
749#
750# PURPOSE: Create menu
751#
752#/////////////////////////////////////////////////////////////////////////////     
753  set m [menu $editor.m -tearoff 0 ]
754  set state [$editor cget -state]
755  $m add command -label "[mc Find]..." -accelerator CTRL+F \
756          -command [list ::BayesText::FindShow $editor]
757  $m add command -label "[mc Replace]..." -accelerator CTRL+R -state $state\
758          -command [list ::BayesText::ReplaceShow $editor]
759  $m add command -label [mc "Find next"] -accelerator F3 \
760          -command [list ::BayesText::FindShow $editor 1]
761  $m add command -label [mc "Search function"] -accelerator CTRL+G \
762          -command [list ::BayesText::SearchShow $editor]   
763  $m add separator
764  $m add command -label [mc "Cut"] -accelerator CTRL+X -state $state\
765          -command [list ::BayesText::Cut $editor]
766  $m add command -label [mc "Copy"] -accelerator CTRL+C \
767          -command [list ::BayesText::Copy $editor]
768  $m add command -label [mc "Paste"] -accelerator CTRL+V -state $state \
769          -command [list ::BayesText::Paste $editor]
770  $m add separator
771  $m add command -label [mc "Select all"] -accelerator CTRL+E \
772          -command [list ::BayesText::SelectAll $editor]
773  $m add command -label [mc "Delete"] -accelerator SUPR -state $state\
774          -command [list ::BayesText::Delete $editor]
775  $m add command -label "[mc Font]..." -accelerator CTRL+T \
776          -command [list ::BayesText::FontChange $editor]
777 
778  bind $editor <F3>        [list ::BayesText::FindShow $editor 1]
779  if {[string equal $state "normal"]} {
780    #bind $editor <Delete>    [list ::BayesText::Delete $editor]
781  }
782 
783  bind $editor <Control-KeyRelease> \
784    [list ::BayesText::OnControlKey $editor %K %k]
785 
786  #Por si el text esta desabilitado (para poder seleccionar)
787  bind $editor <Button-1> {focus %W}
788  bind $editor <Button-3> "tk_popup $m %X %Y"
789  #Retornar el menu por si el que lo llama quiere añadir opciones
790  return $m
791}
792
793
794#/////////////////////////////////////////////////////////////////////////////   
795proc ::BayesText::OnControlKey {editor keysym keycode} {
796#
797# PURPOSE: Call of bind associate of letter
798#
799#/////////////////////////////////////////////////////////////////////////////     
800  set state [$editor cget -state]
801  switch [string toupper $keysym] {
802    E { SelectAll $editor}
803    F { FindShow $editor}
804    R { if [string equal $state "normal"] { ReplaceShow $editor }  }
805    T { FontChange $editor}
806    C { if { [string equal $::tcl_platform(platform) "unix"] ||
807             [string equal $keysym "C"] } {
808          Copy $editor
809      }
810    }
811    V { if { ([string equal $::tcl_platform(platform) "unix"] &&
812              [string equal $state "normal"]) ||
813              [string equal $keysym "V"]} {
814          Paste $editor
815      }
816    }
817    X { if { [string equal $keysym "X"] } {
818          Cut $editor
819      }
820    }
821  }
822}
823
824proc ::BayesText::TolEscape { buffer } {
825  return [ string map [ list \n \\n \t \\t \" \\\" \\ \\\\ ] $buffer ]
826}
827
828proc ::BayesText::DlgEscapeTextApply { editor } {
829  set w .dlgescape
830
831  set idxs [ $editor tag ranges sel ]
832  if { [ llength $idxs ] } {
833    foreach {i0 i1} $idxs break
834    $editor configure -undo 0
835    $editor delete $i0 $i1
836    $editor configure -undo 1
837    set f [ $w getframe ]
838    set buffer [ $f.t get 1.0 "end -1 char" ]
839    set len [ string length $buffer ]
840    $editor insert $i0 $buffer
841    $editor tag add sel $i0 "$i0 + $len char"
842  }
843}
844
845proc ::BayesText::DlgEscapeTextIdle { w } {
846  variable DlgEscapeTextData
847
848  if { [ winfo exists $w ] } {
849    set f [ $w getframe ]
850    set buffer [ $f.o get 1.0 "end -1 char" ]
851    if { $buffer ne $DlgEscapeTextData(buffer) } {
852      $f.t del 1.0 end
853      $f.t ins end [ ::BayesText::TolEscape $buffer ]
854      set DlgEscapeTextData(buffer) $buffer
855    }
856    update
857    after idle [ list ::BayesText::DlgEscapeTextIdle $w ]
858  }
859}
860
861proc ::BayesText::DlgEscapeText { editor } {
862  variable DlgEscapeTextData
863
864  set w .dlgescape
865  if { [ winfo exists $w ] } {
866    set f [ $w getframe ]
867    raise $w
868    focus $f.o
869  } else {
870    Dialog $w -title [ mc "Escape text" ] \
871        -default 2 -modal none -parent $editor -separator 1
872    $w add -text [ mc "Close" ] -command "destroy $w"
873    $w add -text [ mc "Apply" ]
874    set f [ $w getframe ]
875    label $f.lo -text [ mc "Original:" ]
876    text $f.o -width 40 -height 4
877    label $f.lt -text [ mc "Transformed:" ]
878    rotext $f.t -width 40 -height 4
879    grid $f.lo -row 0 -column 0 -sticky w
880    grid $f.o -row 1 -column 0 -sticky snew
881    grid $f.lt -row 0 -column 1 -sticky w
882    grid $f.t -row 1 -column 1 -sticky snew
883    foreach c {0 1} {
884      grid columnconfigure $f $c -weight 1
885    }
886    grid rowconfigure $f 1 -weight 1
887    $w draw
888  }
889  $f.o delete 1.0 end
890  $f.t del 1.0 end
891  set DlgEscapeTextData(buffer) ""
892  set idxs [ $editor tag ranges sel ]
893  if { [ llength $idxs ] } {
894    $f.o insert end [ $editor get [ lindex $idxs 0 ] [ lindex $idxs 1 ] ]
895  }
896  $w itemconfigure 1 -command [ list ::BayesText::DlgEscapeTextApply $editor ]
897  update
898  after idle [ list ::BayesText::DlgEscapeTextIdle $w ]
899}
900
901#/////////////////////////////////////////////////////////////////////////////
902proc ::BayesText::TolSyntaxCheck { editor {dir ""} } {
903#/////////////////////////////////////////////////////////////////////////////
904  global toltk_script_path
905
906  set buffer [ GetSelectionOrAll $editor ]
907  if { $dir ne "" } {
908    set cwd [ pwd ]
909    cd $dir
910  }
911
912  if { [ catch { tol::checksyntax $buffer } check ] } {
913    Tolcon_Trace "within ::BayesText::TolSyntaxCheck($editor,$dir): $check"
914    return 0
915  }
916  set check [ string trim $check ]
917  if { $check eq "" } {
918    tk_messageBox -type ok -icon info -title [mc "Syntax Check"] \
919        -parent $editor -message [mc "Syntax check done successfully"]
920  } else {
921    ShowSyntaxErrors $editor $check
922  }
923  return 1
924}
925
926
927#/////////////////////////////////////////////////////////////////////////////
928  proc ::BayesText::ShowSyntaxErrors {parent error} {
929#
930# PURPOSE: Shows syntax errors in a dialog window with a monospaced font
931#
932# PARAMETERS:
933#   parent -> path of dialog parent
934#   error  -> Syntax error to display
935#
936#/////////////////////////////////////////////////////////////////////////////
937  global toltk_options
938
939  set title "[mc "Syntax Check"]. [mc {Syntax errors in file}]"
940  set dialog [Dialog $parent.dsc -title $title -modal local -parent $parent]
941  set w [$dialog getframe]
942 
943  bind $dialog <Escape> [list destroy $dialog] 
944
945  ScrolledWindow $w.sw
946  text $w.sw.t -font $toltk_options(fonts,Fixed) -state normal
947  $w.sw.t insert end $error
948  $w.sw.t configure -state disabled
949  $w.sw setwidget $w.sw.t
950 
951  set w_bbox \
952    [ButtonBox $w.bb -orient horizontal -spacing 10 -padx 0 -pady 0 \
953     -homogeneous false]
954  $w_bbox add -text [mc "Accept"] -relief link \
955          -helptext [mc "OK"] \
956          -image [::Bitmap::get accept] -compound left -padx 5 -pady 1 \
957           -command "destroy $dialog"
958   
959  pack $w_bbox -fill x -expand false -side bottom
960  pack $w.sw -fill both -expand yes
961 
962  $dialog draw
963}
964
965
966#/////////////////////////////////////////////////////////////////////////////
967proc ::BayesText::TolFileSyntaxCheck {path} {
968#/////////////////////////////////////////////////////////////////////////////
969  set ok 0
970  # evaluamos el archivo
971  set tolCheck "Text __EditorCheck = ParseError(ReadFile(\"$path\"))"
972  #puts "TolFileSyntaxCheck: tolCheck = $tolCheck"
973  if {[catch {::tol::console eval $tolCheck}]} {
974    Tolcon_Trace "Falla porque TOL está ocupado"
975  } else  {
976    # comprobamos si ha dado algun error
977    if {![catch { set objInfo [::tol::info variable [list Text __EditorCheck]]}]} {
978          #puts "TolFileSyntaxCheck: objInfo = $objInfo"
979      # destruimos la variable creada en TOL
980      ::tol::console stack release __EditorCheck
981      #Tolcon_Trace "ParseError devuelve: [lindex $objInfo 0]"
982      set ok [string equal [lindex $objInfo 2] "\"\""]
983      if !$ok {
984        set ok [list $ok [lindex $objInfo 2]]
985      }
986    }
987  }
988  return $ok
989}
990
991#/////////////////////////////////////////////////////////////////////////////
992proc ::BayesText::CreateHLText {path lang args} {
993#
994# PURSPOSE: Creates a highlighted text.
995#
996# PARAMETERS:
997#    path -> path where text has to be created
998#    lang -> languaje to highlight (TOL, SQL, MSQ)
999#         TOL -> Time Oriented Language
1000#         SQL -> SQL ansii 92
1001#         MSQ -> SQL for Microsoft SQL Server
1002#         ORA -> SQL for Oracle
1003#
1004#/////////////////////////////////////////////////////////////////////////////
1005  global toltk_options   
1006
1007  array set opts [list \
1008    -background    white \
1009    -wrap          none  \
1010    -font          $toltk_options(fonts,Fixed) \
1011    -linemap       0 ]
1012  array set opts $args
1013
1014  set w  [eval ctext $path [array get opts]]
1015  switch [string toupper $lang] {
1016    TOL {
1017          init_tolctext $w
1018        }
1019    SQL {
1020          init_sqlctext $w
1021          init_msqctext $w
1022        }
1023    MSQ {
1024          init_sqlctext $w
1025          init_msqctext $w
1026        }
1027    default {}
1028  }
1029  return $w
1030}
1031
1032
1033
1034#/////////////////////////////////////////////////////////////////////////////
1035proc ::BayesText::init_sqlctext { w } {
1036#/////////////////////////////////////////////////////////////////////////////
1037  set lstSQL1 {\
1038     alter as by cascade commit connect create else end\
1039     from group having max min\
1040     insert into is primary select set table union update when where\
1041  }
1042  set lstSQL2 {and or not null in between outer join}
1043  set lstTypes {\
1044    int integer real float decimal char varchar nvarchar bit varbinary text\
1045    date datetime smalldatetime\
1046  }
1047
1048  set lstSQL1upper {}
1049  foreach it $lstSQL1 {
1050    lappend lstSQL1upper [string toupper $it]
1051  }
1052  set lstSQL2upper {}
1053  foreach it $lstSQL2 {
1054    lappend lstSQL2upper [string toupper $it]
1055  }
1056  set lstTypesUpper {}
1057  foreach it $lstTypes {
1058    lappend lstTypesUpper [string toupper $it]
1059  }
1060
1061  ctext::addHighlightClass $w sql1 blue $lstSQL1
1062  ctext::addHighlightClass $w sql1 blue $lstSQL1upper
1063  ctext::addHighlightClass $w sql2 #777777 $lstSQL2
1064  ctext::addHighlightClass $w sql2 #777777 $lstSQL2upper
1065  ctext::addHighlightClass $w sqlTypes blue $lstTypes
1066  ctext::addHighlightClass $w sqlTypes blue $lstTypesUpper
1067  # Line comments:
1068  ctext::addHighlightClassForRegexp $w comments #558855 {--[^\n^\r]+}
1069}
1070
1071
1072#/////////////////////////////////////////////////////////////////////////////
1073proc ::BayesText::init_msqctext { w } {
1074#/////////////////////////////////////////////////////////////////////////////
1075  set lst {\
1076    avg case cast convert count sum var varp checksum stdev stdevp checksum checksum_agg\
1077    dateadd datediff datename datepart day getdate getutcdate month year\
1078    ascii charindex difference left len lower ltrim  patindex quotename\
1079    replace replicate reverse right rtrim soundex space str stuff substring unicode upper\
1080    abs acos asin atan atn2 ceiling cos cot degrees exp floor\
1081    log log10 pi power radians rand round sign sin square sqrt tan\
1082  }
1083
1084  set lstUpper {}
1085  foreach it $lst {
1086    lappend lstUpper [string toupper $it]
1087  }
1088  ctext::addHighlightClass $w specialMSQ #FF00AA $lst
1089  ctext::addHighlightClass $w specialMSQ #FF00AA $lstUpper
1090
1091}
1092
1093#/////////////////////////////////////////////////////////////////////////////
1094proc ::BayesText::init_tolctext { w } {
1095#/////////////////////////////////////////////////////////////////////////////
1096  ctext::addHighlightClass $w grammars black [list Anything Code Complex \
1097    CDate CTimeSet Date Matrix NameBlock Polyn Ration Real Serie Set Special Struct \
1098    Text TimeSet VMatrix PolMatrix Class \#Embed \#Require Static ] 
1099
1100  ctext::addHighlightClass $w stackControl purple {BinGroup Case Copy Dating\
1101    Do Element Eval EvalArg Field Find Group IF If MakeGlobal PutDescription\
1102    PutName PutValue ReCalc TOLPath While Write WriteLn False True For\
1103    EvalSet \? }
1104
1105  # Line comments:
1106  ctext::addHighlightClassForRegexp $w comments blue {//[^\n^\r]+}
1107}
1108
1109
1110#/////////////////////////////////////////////////////////////////////////////
1111proc ::BayesText::ReadIni {} {
1112#///////////////////////////////////////////////////////////////////////////// 
1113  variable options
1114
1115  set rini ::iniFile::Read
1116  # find and replace dialog
1117  set options(find,dir)     [$rini BayesText FindDir     forward]
1118  set options(find,case)    [$rini BayesText FindCase    1]
1119  set options(replace,dir)  [$rini BayesText ReplaceDir  forward]
1120  set options(replace,case) [$rini BayesText ReplaceCase 1]   
1121}
1122
1123
1124#/////////////////////////////////////////////////////////////////////////////
1125  proc ::BayesText::WriteIni {} {
1126#
1127# PURPOSE: Write common Editor options to .ini file
1128#
1129# PARAMETERS:
1130#   this  -> Instance of editor
1131#
1132#/////////////////////////////////////////////////////////////////////////////
1133  variable options
1134  set wini ::iniFile::Write
1135
1136  # find and replace dialog
1137  $wini BayesText FindDir      $options(find,dir)
1138  $wini BayesText FindCase     $options(find,case)
1139  $wini BayesText ReplaceDir   $options(replace,dir)
1140  $wini BayesText ReplaceCase  $options(replace,case) 
1141  ::iniFile::Flush
1142}
Note: See TracBrowser for help on using the repository browser.