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

devel
Last change on this file was 6d7779d, checked in by Jorge Pérez <josp.jorge@…>, 18 years ago

initial import

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

  • Property mode set to 100644
File size: 22.0 KB
Line 
1#/////////////////////////////////////////////////////////////////////////////
2# FILE    : editable.tcl
3# PURPOSE : This file contains a namespace called EditTable with its funcions.
4#           It's for managing table editors of .bst, .bdt, .bmt files or all
5#           kind of files with tabular estructure.
6#           It's a child of BayesTable so inherites all its functionalities.
7#/////////////////////////////////////////////////////////////////////////////
8
9
10#/////////////////////////////////////////////////////////////////////////////
11  namespace eval ::EditTable {
12#
13# PURPOSE: The purpose of this namespace is organize code and functions and
14#          manage common options for all table editors such as last edited
15#          files, last directory opened, etc.
16#          A special namespace is created for each instance of table editor.
17#
18# VARIABLES:
19#   options -> common options for all table editor windows:
20#     geometry  -> initial window table editor geometry
21#     wm,state  -> initial window table editor state
22#     lastDir   -> last directory used
23#     chEdited  -> boolen for saving last edited table files path
24#     numEdited -> number of last edited table files path to save
25#     edited    -> path of last edited table files
26#   num_Table -> incrementally number to identify each table editor window
27#   typelist   -> list of type files supported by table editor
28#   defExt     -> default extension for files managed by table editor
29#
30#/////////////////////////////////////////////////////////////////////////////
31  variable options
32  variable num_Table 0
33  variable typelist {{"Bayes Struct Table"  {".bst"}}
34                     {"Bayes Data Table"    {".bdt"}}
35                     {"Bayes Matrix Table"  {".bmt"}}
36                     {"All Files"           {"*"}   }}
37  variable defExt   .tol
38}
39
40
41#/////////////////////////////////////////////////////////////////////////////
42  proc ::EditTable::New {{path ""} } {
43#
44# PURPOSE: Creates a new table editor window and an instance of it. This also
45#          initializes the instance and register the window in the project.
46#
47# PARAMETERS:
48#   path  -> path of file to edit. If it isn't specified a new white table
49#            is created.
50#
51# RETURN: A instance of table editor.
52#
53#/////////////////////////////////////////////////////////////////////////////
54  variable num_Table
55  incr num_Table
56
57  set Instance [Create $path]
58  SetTraces $Instance
59  InitState $Instance new
60
61  #Tolcon_Trace "[::BayesTable::GetLocData $Instance labelWindow]"
62
63  if {$path == ""} {
64    CmdNew $Instance
65  }
66  return $Instance
67}
68
69
70#/////////////////////////////////////////////////////////////////////////////
71  proc ::EditTable::Open {{path ""}} {
72#
73# PURPOSE: Opens a file in a table editor window. If file is already opened
74#          it raises its window, else it creates a new table editor window and
75#          an instance of it.
76#
77# PARAMETERS:
78#   path  -> path of file to open. If it isn't specified it ask for it.
79#
80# RETURN: A instance of table editor.
81#
82#/////////////////////////////////////////////////////////////////////////////
83  if {$path != ""} {
84    #Comprobar si el archivo ya está abierto y si es así hacer un raise
85    if { ![ catch { set lst [namespace children ::BayesTable] } msgerr] } {
86      foreach ins $lst {
87        upvar \#0 ${ins}::data data
88        if {[string equal $data(namespace) "EditTable"] &&
89            [string equal $data(nameFile) $path]} {
90          #wm deiconify $data(f)
91          $data(f) raise
92          return $ins
93        }
94      }
95      update
96    }
97  }
98   
99  if {$path == ""} {
100    CmdOpen ""
101  } else  {
102    set this [New $path]
103    GetFromFile $this $path
104  } 
105
106  if {[info exists this]} {
107    return $this
108  } else  {
109    return ""
110  }
111}
112
113
114#/////////////////////////////////////////////////////////////////////////////
115  proc ::EditTable::postEdited {m {ord 0}} {
116#
117# PURPOSE: Fills a menu with the last table edited files, according to the
118#          information of 'options' variable.
119#
120# PARAMETERS:
121#   m   -> menu's path that will have the list of last table edited files
122#   ord -> flag that indicates if files must be shown sorted
123#
124#/////////////////////////////////////////////////////////////////////////////
125  variable options
126  $m delete 0 end
127  if $options(chEdited) {
128    set options(edited) [lrange $options(edited) 0 [expr $options(numEdited)-1]]
129    if $ord {
130      set lst [lsort -ascii $options(edited)]
131    } else {
132      set lst $options(edited)
133    }
134    foreach w $lst {
135      $m add command -label $w -command [list ::EditTable::Open $w]
136    }
137    if [llength $lst] {
138      $m add separator
139      $m add command -label [mc "Clear"]\
140            -command [list ::EditTable::clearEdited]
141    }
142  }
143}
144
145#/////////////////////////////////////////////////////////////////////////////
146  proc ::EditTable::clearEdited {} {
147#
148# PURPOSE: Clears the list of last edited files
149#
150#/////////////////////////////////////////////////////////////////////////////
151  variable options
152  set options(edited) ""
153  ::iniFile::Write EditTable recent       $options(edited)
154  ::iniFile::Flush
155}
156
157
158#/////////////////////////////////////////////////////////////////////////////
159  proc ::EditTable::OnDelete {this} {
160#
161# PURPOSE: Procedure to check things before destroying table editor window
162#
163# PARAMETERS:
164#   this  -> Instance of table editor
165#
166#/////////////////////////////////////////////////////////////////////////////
167  if {[string equal [CheckOpen $this] "cancel"]} {
168    return 0
169  }
170  destroy [::BayesTable::GetData $this f]
171  return 1
172}
173
174
175#/////////////////////////////////////////////////////////////////////////////
176  proc ::EditTable::InitState {this from} {
177#
178# PURPOSE: Initializes some table properties and variables according to the
179#          state of table editor.
180#
181# PARAMETERS:
182#   this  -> Instance of table editor
183#   from  -> State that defines values for the variables
184#
185#/////////////////////////////////////////////////////////////////////////////
186  switch $from {
187    new {
188      set table [::BayesTable::GetTkTable $this]
189      $table configure -rows 5 -cols 4
190      ::BayesTable::SetData $this isSaved 1
191      ::BayesTable::SetData $this nameFile ""
192      ::BayesTable::UpdateInfoRows $this
193    }
194    open {
195      ::BayesTable::SetData $this isSaved 1
196      ::BayesTable::UpdateInfoRows $this
197    }
198    save {
199      ::BayesTable::SetData $this isSaved 1
200    }
201  }
202}
203
204
205#/////////////////////////////////////////////////////////////////////////////
206  proc ::EditTable::SetTraces {this} {
207#
208# PURPOSE: Sets some traces of variables to control changes in table editor
209#          widget
210#
211# PARAMETERS:
212#   this  -> Instance of table editor
213#
214#/////////////////////////////////////////////////////////////////////////////
215  trace variable [::BayesTable::GetLocData $this nameFile] w\
216     [list ::EditTable::TraceNameFile $this]
217  trace variable [::BayesTable::GetLocData $this isSaved] w\
218     [list ::EditTable::TraceSaved $this]
219  #trace variable [::BayesTable::GetLocElements $this] w\
220  #   "::BayesTable::SetData $this isSaved 0;\
221  #    Tolcon_Trace {Ha cambiado la matriz};\
222  #    ::BayesTable::UpdateInfoRows $this ;\#"
223}
224
225
226#/////////////////////////////////////////////////////////////////////////////
227  proc ::EditTable::TraceNameFile {this name1 name2 op} {
228#
229# PURPOSE: Sets table file's name each time var 'nameFile' changes.
230#
231# PARAMETERS:
232#   this  -> Instance of tol project
233#   name1, name2, op ->
234#     Name1 and name2 give the name(s) for the variable being accessed: if the
235#     variable is a scalar then name1 gives the variable's name and name2 is
236#     an empty string; if the variable is an array element then name1 gives
237#     the name of the array and name2 gives the index into the array; if an
238#     entire array is being deleted and the trace was registered on the
239#     overall array, rather than a single element, then name1 gives the array
240#     name and name2 is an empty string. Name1 and name2 are not necessarily
241#     the same as the name used in the trace variable command: the upvar
242#     command allows a procedure to reference a variable under a different
243#     name. Op indicates what operation is being performed on the variable,
244#     and is one of r, w, or u.
245#
246#/////////////////////////////////////////////////////////////////////////////
247  if {[::BayesTable::GetData $this nameFile] != ""} {
248    ::BayesTable::SetData $this labelWindow [::BayesTable::GetData $this nameFile]
249  } else  {
250    ::BayesTable::SetData $this labelWindow "untitled.bst"
251  }
252  [::BayesTable::GetData $this f] configure -title \
253   "[::BayesTable::GetData $this labelWindow] - [mc [list Bayes Table Editor]]"
254}
255
256
257#/////////////////////////////////////////////////////////////////////////////
258  proc ::EditTable::TraceSaved {this name1 name2 op} {
259#
260# PURPOSE: Sets saved/not saved info in status bar each time var 'isSaved'
261#          changes.
262#
263# PARAMETERS:
264#   this  -> Instance of table editor
265#   name1, name2, op -> see above
266#
267#/////////////////////////////////////////////////////////////////////////////
268  #Tolcon_Trace "En TraceSaved, isSaved vale [::BayesTable::GetData $this isSaved]"
269  if [::BayesTable::GetData $this isSaved] {
270    ::BayesTable::WriteInfo $this [mc "Saved"]
271  } else  {
272    ::BayesTable::WriteInfo $this [mc "Not Saved"]
273  }
274}
275
276
277#/////////////////////////////////////////////////////////////////////////////
278  proc ::EditTable::Validate {this val} {
279#
280# PURPOSE: Procedure that is called each time something is writen in the
281#          table. Sets variable 'isSaved' to false.
282#
283# PARAMETERS:
284#   this -> Instance of table editor
285#   val  -> Potential new value of the cell being validated
286#
287# RETURN: Allways return 1 (validation OK), except when Return key is pressed
288#
289#/////////////////////////////////////////////////////////////////////////////
290  ::BayesTable::SetData $this isSaved 0
291  if [regexp {^[^\n]*\n$} $val] {
292    return 0
293  } else {
294    return 1
295  }
296}
297
298
299#/////////////////////////////////////////////////////////////////////////////
300  proc ::EditTable::Create {path} {
301#
302# PURPOSE: Creates a table editor instance
303#
304# PARAMETERS:
305#   path  -> table editor's path (toplevel)
306#
307# RETURN: Instance created.
308#
309#/////////////////////////////////////////////////////////////////////////////
310
311  set this ::Editor::$path
312  if { [lsearch [namespace children ::EditTable] $this] != -1 } {
313    error "$this already exists as a children of ::Editor"
314  }
315
316  # create
317  set tl [::project::CreateForm -type Tables \
318            -width 400 -height 180 \
319            -iniconfig Tables ]
320  set tlf [$tl getframe]
321 
322  set this [::BayesTable::Create $tlf.t -child EditTable \
323      -argsWidget {-state normal} -OnWriteIni "::EditTable::WriteIni"]
324  $tl configure -closecmd [list ::EditTable::OnDelete $this]
325  pack $tlf.t -fill both -expand yes
326  ::BayesTable::SetData $this f $tl
327
328  namespace eval $this {
329    variable data
330  }
331  upvar \#0 ${this}::data data
332  set data(f) $tl
333
334  ReadIni   $this
335  Configure $this
336
337  set t [::BayesTable::GetTkTable $this]
338  $t configure -validate 1 -vcmd [list ::EditTable::Validate $this %S]
339  bind $tl <<Paste>> [list ::EditTable::OnChangeRows $this]
340  bind $tl <<Cut>>   [list ::EditTable::OnChangeRows $this]
341
342  #Añadimos opciones específicas de EditTable
343  ::BayesTable::AddOptionCmd $this "sepSQL1" "--" -where both
344  ::BayesTable::AddOptionCmd $this "sepSQL2" "--"
345  ::BayesTable::AddOptionCmd $this "new"     "::EditTable::CmdNew"\
346      -where tool -icon new -hint "[mc [list New white table]] (CTRL+N)"
347  ::BayesTable::AddOptionCmd $this "open"    "::EditTable::CmdOpen"\
348      -where tool -icon open -hint "[mc Open] (CTRL+A)"
349  ::BayesTable::AddOptionCmd $this "save"    "::EditTable::CmdSave"\
350      -where tool -icon save -hint "[mc Save] (CTRL+S)"
351  $tl bind <Control-F4> [list $tl kill]
352  return $this
353}
354
355proc ::EditTable::OnChangeRows {this} {
356  Tolcon_Trace "Llamada a OnChangeRows"
357  #set this [::BayesTable::GetInstance $w]
358  ::BayesTable::SetData $this isSaved 0
359  ::BayesTable::UpdateInfoRows $this
360}
361
362
363#/////////////////////////////////////////////////////////////////////////////
364# File management commands (new, open, save, save as...)
365#/////////////////////////////////////////////////////////////////////////////
366
367#/////////////////////////////////////////////////////////////////////////////
368  proc ::EditTable::CmdNew {this} {
369#
370# PURPOSE: Cleans table editor to edit a new white table
371#
372# PARAMETERS:
373#   this  -> Instance of table editor
374#
375#/////////////////////////////////////////////////////////////////////////////
376  if [string equal [CheckOpen $this] "cancel"] return
377  ::BayesTable::CmdSelectAll $this
378  ::BayesTable::CmdDelete $this
379  InitState $this new
380}
381
382
383#/////////////////////////////////////////////////////////////////////////////
384  proc ::EditTable::UpdateListEdited {path} {
385#
386# PURPOSE: Updates list of last edited table files adding a new file path.
387#
388# PARAMETERS:
389#   path  -> path of the last edited table file
390#
391#/////////////////////////////////////////////////////////////////////////////
392  variable options
393  # guardamos el ultimo directorio abierto
394  set options(lastDir) [file dirname $path]
395  if { [set idx [lsearch $options(edited) $path]] == -1 } {
396    set options(edited) [linsert $options(edited) 0 $path]
397  } else {
398    set ll ""
399    lappend ll $path
400    set i 0
401    foreach f $options(edited) {
402      if  {$i != $idx} {
403        lappend ll $f
404      }
405      incr i
406    }
407    set options(edited) $ll
408  }
409  set options(edited) [lrange $options(edited) 0 [expr $options(numEdited)-1]]
410}
411
412
413#/////////////////////////////////////////////////////////////////////////////
414 proc ::EditTable::CmdOpen {{this ""}} {
415#
416# PURPOSE: Asks for a table file path and if it's given opens it into the
417#          table editor window.
418#
419# PARAMETERS:
420#   this -> Instance of table editor
421#
422#/////////////////////////////////////////////////////////////////////////////
423  variable options
424  variable typelist
425  variable defExt
426
427  if {$this == ""} {
428    set parent .
429  } else  {
430    set parent [::BayesTable::GetTkTable $this]
431    if [string equal [CheckOpen $this] "cancel"] return
432  }
433 
434  set path [tk_getOpenFile -title [mc "Open"] \
435                       -parent $parent\
436                       -initialdir $options(lastDir) \
437                       -defaultextension $defExt -filetypes $typelist]
438 
439  if { $path != "" } {
440    # abrimos solo si no esta ya abierto
441    if { [namespace exists ::BayesTable] } {
442      foreach ins [namespace children ::BayesTable::] {
443        upvar \#0 ${ins}::data data
444        if {[info exists data(nameFile)] && [string equal $data(nameFile) $path]} {
445          $data(f) raise
446                      set resp [tk_messageBox -type ok -icon warning \
447                        -message [mc "The table is allready opened!"] ]
448          return
449        }
450      }
451    }
452    if {$this == ""} {
453      set this [New $path]
454    }
455    GetFromFile $this $path
456  }
457
458}
459
460
461#/////////////////////////////////////////////////////////////////////////////
462  proc ::EditTable::GetFromFile {this path} {
463#
464# PURPOSE: Loads a table file into the table editor window.
465#
466# PARAMETERS:
467#   this -> Instance of table editor
468#   path -> table file's path
469#
470#/////////////////////////////////////////////////////////////////////////////
471  if [::BayesTable::Open $this $path] {
472    ::BayesTable::SetData $this nameFile $path
473    UpdateListEdited $path
474  } else {
475    ::BayesTable::SetData $this nameFile ""
476  }
477  upvar \#0 ${this}::data data
478  $data(f) raise
479  InitState $this open
480  ::BayesTable::AdjustTable $this
481}
482
483
484#/////////////////////////////////////////////////////////////////////////////
485  proc ::EditTable::CheckAll {} {
486#
487# PURPOSE: Checks for files opened if anyone has changed and asks for saving.
488#
489#/////////////////////////////////////////////////////////////////////////////
490  if { ![ catch { set lst [namespace children ::BayesTable] } msgerr] } {
491    foreach ins $lst {
492      upvar \#0 ${ins}::data data
493      if {[string equal $data(namespace) "EditTable"]} {
494        if {[CheckOpen $ins] eq "cancel"} {
495          return "cancel"
496        }
497      }
498    }
499  }
500  return "ok"
501}
502
503#/////////////////////////////////////////////////////////////////////////////
504  proc ::EditTable::CheckOpen {this {type "yesnocancel"}} {
505#
506# PURPOSE: Checks if a file has changed and asks for saving.
507#
508# PARAMETERS:
509#   this -> Instance of table editor
510#   type -> type of messageBox to ask. (yesnocancel by default)
511#
512# RETURN: Returns user answer for saving.
513#
514#/////////////////////////////////////////////////////////////////////////////
515  set nameFile [::BayesTable::GetData $this nameFile]
516  set isSaved  [::BayesTable::GetData $this isSaved]
517  # comprobamos si necesita ser guardado
518  if {!$isSaved} {
519    if {$nameFile != ""} {
520      set name $nameFile
521    } else  {
522      set name "untitled.bst"
523    }
524    # preguntamos por conformidad
525    set rq [tk_messageBox -type $type -icon warning -title [mc "Warning"]\
526            -parent [::BayesTable::GetTkTable $this]\
527            -message "[mc "Table %1\$s has changed!" $name].\n\
528            [mc "Do you want to save changes?"]"]
529    switch -exact $rq {
530      yes {
531        if {$nameFile != "" } {
532          FileSave $this $nameFile
533        } else {
534          CmdSaveAs $this $nameFile
535        }
536      }
537      cancel {return cancel}
538      default {return ok}
539    }
540  }
541  return ok
542}
543
544
545#/////////////////////////////////////////////////////////////////////////////
546  proc ::EditTable::CmdSave {this} {
547#
548# PURPOSE: Saves data table actually opened in the editor. If doesn't have
549#          name, asks for ti (CmdSaveAs).
550#
551# PARAMETERS:
552#   this -> Instance of table editor
553#
554# RETURN: Returns 1 if file has been saved correctly or 0 if not.
555#
556#/////////////////////////////////////////////////////////////////////////////
557  set nameFile [::BayesTable::GetData $this nameFile]
558
559  if {$nameFile == ""} {
560    set ok [CmdSaveAs $this]
561  } else  {
562    set ok [FileSave $this $nameFile]
563  }
564  return $ok
565}
566
567
568#/////////////////////////////////////////////////////////////////////////////
569  proc ::EditTable::CmdSaveAs {this {nf ""}} {
570#
571# PURPOSE: Saves table data actually opened in table editor asking for the
572#          user to select a file to save it.
573#
574# PARAMETERS:
575#   this -> Instance of table editor
576#   nf   -> name of file proposed
577#
578# RETURN: Returns 1 if file has been saved correctly or 0 if not.
579#
580#/////////////////////////////////////////////////////////////////////////////
581  variable options
582  variable typelist
583  variable defExt
584  set t [::BayesTable::GetTkTable $this]
585   
586  if {$nf == ""} {
587    set dir $options(lastDir)
588    set fil ""     
589  } else  {
590    set dir "[file dirname $nf]"
591    set fil "[file tail $nf]"   
592  }
593  set path [tk_getSaveFile -title [mc "Save as"] -initialdir $dir \
594       -initialfile $fil -parent [::BayesTable::GetTkTable $this] \
595       -defaultextension $defExt -filetypes $typelist]
596  if {![string equal $path ""] } {
597    set ok [FileSave $this $path]
598  } else {
599    set ok 0
600  }
601  return $ok
602}
603
604
605#/////////////////////////////////////////////////////////////////////////////
606  proc ::EditTable::FileSave { this path } {
607#
608# PURPOSE: Saves table data actually opened in table editor in a text file.
609#
610# PARAMETERS:
611#   this -> Instance of editor
612#   path -> name of file
613#
614# RETURN: Returns 1 if file has been saved correctly or 0 if not.
615#
616#/////////////////////////////////////////////////////////////////////////////
617  variable options
618
619  if [::BayesTable::Save $this $path] {
620    ::BayesTable::SetData $this nameFile $path
621    InitState $this save
622    # guardamos el ultimo directorio utilizado
623    set options(lastDir) [file dirname $path]
624    set ok 1
625  } else  {
626    set ok 0
627  }
628  return $ok
629}
630
631
632#/////////////////////////////////////////////////////////////////////////////
633# INIFILE
634#/////////////////////////////////////////////////////////////////////////////
635
636#/////////////////////////////////////////////////////////////////////////////
637  proc ::EditTable::ReadIni {this} {
638#
639# PURPOSE: Reads specific options from .ini file that are relative to table.
640#          First of all, reads options from BayesTable. Actually there isn't
641#          specific options. They are read for each instance.
642#
643# PARAMETERS:
644#   this  -> Instance of table editor
645#
646#/////////////////////////////////////////////////////////////////////////////
647  # Leer las opciones generales (del padre)
648  ::BayesTable::ReadIni $this
649  # Leer las opciones específicas
650}
651
652
653#/////////////////////////////////////////////////////////////////////////////
654  proc ::EditTable::ReadIniSpecial {} {
655#
656# PURPOSE: Reads common Edit Table options from .ini file. This options are
657#          common for all instances of Table Editor. They are read just one
658#          time.
659#
660#/////////////////////////////////////////////////////////////////////////////
661  variable options
662   
663  set rini ::iniFile::Read
664   
665  set options(chEdited)   [$rini EditTable saveRecent  1]
666  set options(numEdited)  [$rini EditTable numRecent   8]
667  set options(edited)     [$rini EditTable recent      {}]
668  set options(lastDir)    [$rini EditTable lastDir  ""]
669}
670
671
672#/////////////////////////////////////////////////////////////////////////////
673  proc ::EditTable::WriteIni {this} {
674#
675# PURPOSE: Writes specific options to .ini file. This procedure is called by
676#          parent BayesGraph. This options are common for all instances of
677#          Table Editor.
678#
679# PARAMETERS:
680#   this  -> Instance of table editor
681#
682#/////////////////////////////////////////////////////////////////////////////
683  variable options
684
685  set wini ::iniFile::Write
686  $wini EditTable saveRecent    $options(chEdited)
687  $wini EditTable numRecent     $options(numEdited)
688  $wini EditTable recent        $options(edited)
689  $wini EditTable lastDir       $options(lastDir)
690}
691
692
693#/////////////////////////////////////////////////////////////////////////////
694  proc ::EditTable::Configure {this} {
695#
696# PURPOSE: Configures some options of TableEditor. First of all, configures
697#          options from BayesTable. Actually there isn't specific options.
698#
699# PARAMETERS:
700#   this  -> Instance of table editor
701#
702#/////////////////////////////////////////////////////////////////////////////
703  # Configurar las opciones generales (del padre)
704  ::BayesTable::Configure $this
705  # Configurar las opciones específicas
706}
707
708
709#Read special initial options because are options relative with tolbase menu
710::EditTable::ReadIniSpecial
Note: See TracBrowser for help on using the repository browser.