Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

visparses.tcl

00001 # Copyright (C) 1997-2004 The CDG Team <cdg@nats.informatik.uni-hamburg.de> 00002 # 00003 # This file is free software; as a special exception the author gives 00004 # unlimited permission to copy and/or distribute it, with or without 00005 # modifications, as long as this notice is preserved. 00006 # 00007 # This program is distributed in the hope that it will be useful, but 00008 # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 00009 # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00010 00011 ## ---------------------------------------------------------------------------- 00012 ## VisParses - the grafical tree editor. 00013 ## 00014 ## A VisParses object instanciate one toplevel window that embedds a set 00015 ## of ParseTree objects to be displayed. There are two common situations that 00016 ## determine the set of parses: (1) displaying annotations, (2) displaying 00017 ## parser solutions. In the first case one VisParses object can fetch all 00018 ## annotations loaded into the system. In the second case one VisParses object 00019 ## displays all solutions a specific parsing flavour has found for one wordgraph. 00020 ## So in the latter case another parser cannot reuse the same VisParses object 00021 ## to visualize its solution record also, but needs a new VisParses object of 00022 ## its own, giving you two separate toplevel windows. I think this is the best 00023 ## compromise here between lots of toplevel windows and embedded objects in 00024 ## separate tabs of one window. 00025 ## 00026 ## As you see below we don't provide a separate destructor to destruct 00027 ## embedded ParseTree objects but add ParseTree objects directly as itk-components 00028 ## to the VisParses widget. So they get destructed automatically. 00029 ## 00030 ## \author Michael Daum, Kilian A. Foth, Dietmar Fünning 00031 ## (see also AUTHORS and THANKS for more) 00032 ## 00033 ## $Id visparses.tcl $ 00034 ## ---------------------------------------------------------------------------- 00035 class VisParses { 00036 inherit itk::Toplevel 00037 00038 itk_option define -iconname iconName IconName "xcdg" 00039 itk_option define -interactive interactive Interactive 0 00040 00041 public method addParse {parse}; ## \type ParseTree 00042 public method highlight {parse which}; ## \type ParseTree, TclString 00043 public method removeParse {parse}; ## \type ParseTree 00044 public method view {no}; ## \type TclNumber 00045 public method center {} 00046 public method readWord {} 00047 public method getBadness {} 00048 public method update {} 00049 public method geometry {} 00050 00051 constructor {args} {}; ## \type TclList 00052 00053 00054 private method _print {} 00055 private method _loadAction {} 00056 private method _saveAction {} 00057 private method _saveAsAction {} 00058 private method _mirrorAction {} 00059 private method _verifyAction {} 00060 private method _showcycleAction {} 00061 private method _breakcycleAction {} 00062 private method _deleteParseAction {} 00063 private method _nextAction {} 00064 private method _previousAction {} 00065 private method _refresh {} 00066 private method _undo {} ; # mapped to edit-menu 00067 private method _redo {} ; # mapped to edit-menu 00068 private method _computeViolas {} 00069 private method _labelOfIndex {index}; ## \type TclNumber 00070 private method _spaceHandler {} 00071 private method _BackspaceHandler {} 00072 private method _zoomIn {} 00073 private method _zoomOut {} 00074 private method _setOrientation {} 00075 private method _getOrientation {} 00076 private method _updateVisual {} 00077 private method _switchLevel {x}; ## \type TclNumber 00078 00079 private variable _noPages 0 00080 private variable _userInput "" 00081 private variable _currentOrient "vertical" 00082 00083 ## array mapping Parses to page-numbers 00084 private variable _pageOfParse ;## \type TclArray 00085 }; 00086 00087 ## ---------------------------------------------------------------------------- 00088 ## constructor 00089 ## ---------------------------------------------------------------------------- 00090 body VisParses::constructor {args} { 00091 00092 global queue env 00093 set queue "" 00094 00095 wm withdraw $itk_interior 00096 00097 itk_component add menuframe { 00098 frame $itk_interior.menuframe 00099 } { 00100 keep -background -cursor 00101 rename -borderwidth -menuborderwidth menuBorderwidth Borderwidth 00102 } 00103 00104 # file menu 00105 itk_component add filebutton { 00106 menubutton $itk_component(menuframe).filebutton \ 00107 -text "File" \ 00108 -menu $itk_component(menuframe).filebutton.menu 00109 } { 00110 keep -background -cursor 00111 rename -borderwidth -menuborderwidth menuBorderwidth Borderwidth 00112 } 00113 00114 itk_component add filemenu { 00115 menu $itk_component(filebutton).menu 00116 } { 00117 keep -background -cursor 00118 rename -borderwidth -menuborderwidth menuBorderwidth Borderwidth 00119 } 00120 00121 00122 $itk_component(filemenu) add command \ 00123 -label "Load ..." \ 00124 -underline 0 \ 00125 -command [code $this _loadAction] 00126 $itk_component(filemenu) add command \ 00127 -label "Save" \ 00128 -underline 0 \ 00129 -command [code $this _saveAction] 00130 $itk_component(filemenu) add command \ 00131 -label "Save as..." \ 00132 -underline 0 \ 00133 -command [code $this _saveAsAction] 00134 $itk_component(filemenu) add command \ 00135 -label "Print ..." \ 00136 -underline 0 \ 00137 -command [code $this _print] 00138 $itk_component(filemenu) add separator 00139 $itk_component(filemenu) add command \ 00140 -label "Close" \ 00141 -underline 0 \ 00142 -command [list destroy $itk_interior] 00143 $itk_component(filemenu) add command \ 00144 -label "Quit" \ 00145 -underline 0 \ 00146 -command ::cmd::Quit 00147 00148 # editmenu 00149 itk_component add editbutton { 00150 menubutton $itk_component(menuframe).editbutton \ 00151 -text "Edit" \ 00152 -menu $itk_component(menuframe).editbutton.menu 00153 } { 00154 keep -background -cursor 00155 rename -borderwidth -menuborderwidth menuBorderwidth Borderwidth 00156 } 00157 00158 itk_component add editmenu { 00159 menu $itk_component(editbutton).menu 00160 } { 00161 keep -background -cursor 00162 rename -borderwidth -menuborderwidth menuBorderwidth Borderwidth 00163 } 00164 00165 ## Configure Edit-Menu with Undo-/Redo-Entries 00166 $itk_component(editmenu) add command \ 00167 -label "Undo" \ 00168 -command [code $this _undo]\ 00169 -accelerator <Ctrl-z> 00170 00171 00172 $itk_component(editmenu) add command \ 00173 -label "Redo" \ 00174 -command [code $this _redo]\ 00175 -accelerator <Ctrl-r> 00176 00177 $itk_component(editmenu) entryconfigure 0 -state disabled 00178 $itk_component(editmenu) entryconfigure 1 -state disabled 00179 00180 #$itk_component(editmenu) add separator 00181 00182 #$itk_component(editmenu) add command \ 00183 -label "New parse" \ 00184 -command ".cdgmain not_yet $itk_interior" 00185 #$itk_component(editmenu) add command \ 00186 -label "Delete parse" \ 00187 -command [code $this _deleteParseAction] 00188 #$itk_component(editmenu) add separator 00189 #$itk_component(editmenu) add command \ 00190 -label "New level" \ 00191 -command ".cdgmain not_yet $itk_interior" 00192 #$itk_component(editmenu) add command \ 00193 -label "Delete level" \ 00194 -command ".cdgmain not_yet $itk_interior" 00195 #$itk_component(editmenu) add separator 00196 #$itk_component(editmenu) add command \ 00197 -label "New Word" \ 00198 -command ".cdgmain not_yet $itk_interior" 00199 #$itk_component(editmenu) add command \ 00200 -label "Delete Word" \ 00201 -command ".cdgmain not_yet $itk_interior" 00202 #$itk_component(editmenu) add separator 00203 00204 # viewmenu 00205 itk_component add viewbutton { 00206 menubutton $itk_component(menuframe).viewbutton \ 00207 -text "View" \ 00208 -menu $itk_component(menuframe).viewbutton.menu 00209 } { 00210 keep -background -cursor 00211 rename -borderwidth -menuborderwidth menuBorderwidth Borderwidth 00212 } 00213 00214 itk_component add viewmenu { 00215 menu $itk_component(viewbutton).menu 00216 } { 00217 keep -background -cursor 00218 rename -borderwidth -menuborderwidth menuBorderwidth Borderwidth 00219 } 00220 00221 itk_component add zoommenu { 00222 menu $itk_component(viewmenu).zoommenu 00223 } { 00224 keep -background -cursor 00225 rename -borderwidth -menuborderwidth menuBorderwidth Borderwidth 00226 } 00227 00228 $itk_component(viewmenu) add command \ 00229 -label "Refresh" \ 00230 -command [code $this _refresh] 00231 $itk_component(viewmenu) add separator 00232 $itk_component(viewmenu) add command \ 00233 -label "Zoom in"\ 00234 -command [code $this _zoomIn] 00235 $itk_component(viewmenu) add command \ 00236 -label "Zoom out"\ 00237 -command [code $this _zoomOut] 00238 $itk_component(viewmenu) add separator 00239 $itk_component(viewmenu) add radiobutton \ 00240 -label "Horizontal" \ 00241 -variable [scope _currentOrient] \ 00242 -value "horizontal" \ 00243 -command [code $this _setOrientation] 00244 $itk_component(viewmenu) add radiobutton \ 00245 -label "Vertical" \ 00246 -variable [scope _currentOrient] \ 00247 -value "vertical" \ 00248 -command [code $this _setOrientation] 00249 00250 # parsemenu 00251 itk_component add parsebutton { 00252 menubutton $itk_component(menuframe).parsebutton \ 00253 -text "Parse" \ 00254 -menu $itk_component(menuframe).parsebutton.menu 00255 } { 00256 keep -background -cursor 00257 rename -borderwidth -menuborderwidth menuBorderwidth Borderwidth 00258 } 00259 itk_component add parsemenu { 00260 menu $itk_component(parsebutton).menu 00261 } { 00262 keep -background -cursor 00263 rename -borderwidth -menuborderwidth menuBorderwidth Borderwidth 00264 } 00265 $itk_component(parsemenu) add command \ 00266 -label "Mirror" \ 00267 -command [code $this _mirrorAction] 00268 $itk_component(parsemenu) add command \ 00269 -label "Show cycles" \ 00270 -command [code $this _showcycleAction] 00271 $itk_component(parsemenu) add command \ 00272 -label "Break cycles" \ 00273 -command [code $this _breakcycleAction] 00274 $itk_component(parsemenu) add command \ 00275 -label "Verify" \ 00276 -command [code $this _verifyAction] 00277 $itk_component(parsemenu) add separator 00278 $itk_component(parsemenu) add command \ 00279 -label "Next" \ 00280 -command [code $this _nextAction] 00281 $itk_component(parsemenu) add command \ 00282 -label "Previous" \ 00283 -command [code $this _previousAction] 00284 # toolbar 00285 itk_component add toolbar { 00286 frame $itk_interior.toolbar \ 00287 -borderwidth 0 \ 00288 -relief flat 00289 } {} 00290 set toolbar $itk_component(toolbar) 00291 00292 # prev button 00293 set allImages [image names] 00294 if {[lsearch -exact $allImages prevImage] < 0} { 00295 image create photo prevImage -file $env(XCDG_LIB)/back.gif 00296 } 00297 itk_component add prevButton { 00298 button $itk_component(toolbar).prevButton \ 00299 -image prevImage \ 00300 -command [code $this _previousAction] \ 00301 -borderwidth 0 \ 00302 -relief flat \ 00303 -activebackground gray90 \ 00304 } {} 00305 bind $itk_component(prevButton) <Enter> {%W configure -relief raised} 00306 bind $itk_component(prevButton) <Leave> {%W configure -relief flat} 00307 00308 # next button 00309 if {[lsearch -exact $allImages nextImage] < 0} { 00310 image create photo nextImage -file $env(XCDG_LIB)/forward.gif 00311 } 00312 itk_component add nextButton { 00313 button $itk_component(toolbar).nextButton \ 00314 -image nextImage \ 00315 -command [code $this _nextAction] \ 00316 -borderwidth 0 \ 00317 -relief flat \ 00318 -activebackground gray90 \ 00319 } {} 00320 bind $itk_component(nextButton) <Enter> {%W configure -relief raised} 00321 bind $itk_component(nextButton) <Leave> {%W configure -relief flat} 00322 00323 # save button 00324 if {[lsearch -exact $allImages saveImage] < 0} { 00325 image create photo saveImage -file $env(XCDG_LIB)/floppy.gif 00326 } 00327 itk_component add saveButton { 00328 button $itk_component(toolbar).saveButton \ 00329 -image saveImage \ 00330 -command [code $this _saveAction] \ 00331 -borderwidth 0 \ 00332 -relief flat \ 00333 -activebackground gray90 \ 00334 } {} 00335 bind $itk_component(saveButton) <Enter> {%W configure -relief raised} 00336 bind $itk_component(saveButton) <Leave> {%W configure -relief flat} 00337 00338 # mirror button 00339 if {[lsearch -exact $allImages mirrorImage] < 0} { 00340 image create photo mirrorImage -file $env(XCDG_LIB)/mirror.gif 00341 } 00342 itk_component add mirrorButton { 00343 button $itk_component(toolbar).mirrorButton \ 00344 -image mirrorImage \ 00345 -command [code $this _mirrorAction] \ 00346 -borderwidth 0 \ 00347 -relief flat \ 00348 -activebackground gray90 \ 00349 } {} 00350 bind $itk_component(mirrorButton) <Enter> {%W configure -relief raised} 00351 bind $itk_component(mirrorButton) <Leave> {%W configure -relief flat} 00352 00353 # zoom in button 00354 if {[lsearch -exact $allImages zoomInImage] < 0} { 00355 image create photo zoomInImage -file $env(XCDG_LIB)/zoom_in.gif 00356 } 00357 itk_component add zoomInButton { 00358 button $itk_component(toolbar).zoomInButton \ 00359 -image zoomInImage \ 00360 -command [code $this _zoomIn] \ 00361 -borderwidth 0 \ 00362 -relief flat \ 00363 -activebackground gray90 \ 00364 } {} 00365 bind $itk_component(zoomInButton) <Enter> {%W configure -relief raised} 00366 bind $itk_component(zoomInButton) <Leave> {%W configure -relief flat} 00367 00368 # zoom out button 00369 if {[lsearch -exact $allImages zoomOutImage] < 0} { 00370 image create photo zoomOutImage -file $env(XCDG_LIB)/zoom_out.gif 00371 } 00372 itk_component add zoomOutButton { 00373 button $itk_component(toolbar).zoomOutButton \ 00374 -image zoomOutImage \ 00375 -command [code $this _zoomOut] \ 00376 -borderwidth 0 \ 00377 -relief flat \ 00378 -activebackground gray90 \ 00379 } {} 00380 bind $itk_component(zoomOutButton) <Enter> {%W configure -relief raised} 00381 bind $itk_component(zoomOutButton) <Leave> {%W configure -relief flat} 00382 00383 # id label 00384 itk_component add idLabel { 00385 label $itk_component(toolbar).idLabel \ 00386 -text "Parse " 00387 } {} 00388 00389 # score label 00390 itk_component add scoreLabel { 00391 label $itk_component(toolbar).scoreLabel \ 00392 -text "Score: 00/00/0.0" 00393 } {} 00394 00395 # the tabnotebook containing the ParseTree objects 00396 itk_component add tbn { 00397 iwidgets::tabnotebook $itk_interior.tbn -auto true 00398 } { 00399 keep -width -height 00400 } 00401 00402 # text box for parsing of user input 00403 itk_component add textbox { 00404 iwidgets::entryfield $itk_interior.entry \ 00405 -textvariable [scope _userInput] \ 00406 -labeltext "Type here:" \ 00407 -labelpos w \ 00408 } 00409 set box [$itk_component(textbox) component entry] 00410 00411 # Take control of the textbox 00412 bind $box <space> [code "$this _spaceHandler; break"] 00413 bind $box <BackSpace> [code "$this _BackspaceHandler; break"] 00414 00415 bind $itk_interior <Shift-Tab> [code $this _switchLevel -1] 00416 bind $itk_interior <Tab> [code $this _switchLevel 1] 00417 bind $itk_interior <q> [list destroy $itk_interior] 00418 bind $itk_interior <c> [code $this _showcycleAction] 00419 bind $itk_interior <m> [code $this _mirrorAction] 00420 bind $itk_interior <v> [code $this _verifyAction] 00421 bind $itk_interior <n> [code $this _nextAction] 00422 bind $itk_interior <p> [code $this _previousAction] 00423 bind $itk_interior <s> [code $this _saveAction] 00424 bind $itk_interior <Control-z> [code $this _undo] 00425 bind $itk_interior <Control-r> [code $this _redo] 00426 00427 # packing 00428 pack $itk_component(menuframe) -fill x -side top 00429 pack $itk_component(toolbar) -fill x -side top -padx 5 00430 pack $itk_component(prevButton) \ 00431 $itk_component(nextButton) \ 00432 $itk_component(saveButton) \ 00433 $itk_component(mirrorButton) \ 00434 $itk_component(zoomInButton) \ 00435 $itk_component(zoomOutButton) \ 00436 -side left -padx 3 00437 pack $itk_component(scoreLabel) -side right -padx 3 00438 pack $itk_component(idLabel) -side right -padx 3 00439 00440 pack $itk_component(filebutton) \ 00441 $itk_component(editbutton) \ 00442 $itk_component(viewbutton) \ 00443 $itk_component(parsebutton) \ 00444 -side left -padx 5 -pady 5 00445 pack $itk_component(tbn) -fill both -side top -expand 1 00446 00447 00448 00449 eval itk_initialize $args 00450 00451 if {$itk_option(-interactive)} { 00452 pack $itk_component(textbox) -fill both -side top 00453 } 00454 00455 wm geometry $itk_interior [wm geometry .] 00456 wm deiconify $itk_interior 00457 } 00458 00459 ## ---------------------------------------------------------------------------- 00460 ## Confess to my geometry 00461 ## ---------------------------------------------------------------------------- 00462 body VisParses::geometry {} { 00463 return [wm geometry $itk_interior] 00464 } 00465 00466 ## ---------------------------------------------------------------------------- 00467 ## add a parse on a separate page. 00468 ## ---------------------------------------------------------------------------- 00469 body VisParses::addParse {parse} { 00470 00471 set method [$parse getSearchStrategy] 00472 set lattice [$parse getLatticeId] 00473 set newid "$method:$lattice" 00474 configure -title $newid 00475 00476 # check wether this Parse is already visible 00477 if {[lsearch -exact [array names _pageOfParse] $parse] != -1 } { 00478 return 00479 } 00480 00481 set tbn $itk_component(tbn) 00482 incr _noPages 00483 set page [$tbn add \ 00484 -label "$_noPages" \ 00485 -command [code $this _updateVisual]] 00486 00487 itk_component add parseTree$_noPages { 00488 ParseTree $page.parseTree$_noPages $parse $this 00489 } { 00490 keep -background -cursor 00491 } 00492 pack $page.parseTree$_noPages -fill both -side top -expand 1 00493 00494 $itk_component(parseTree$_noPages) addUndoListener $this ;# register for updating menu buttons 00495 set _pageOfParse($parse) $_noPages 00496 } 00497 00498 ## ---------------------------------------------------------------------------- 00499 ## make a ParseTree invisible. 00500 ## This does not destroy the underlying Parse. 00501 ## ---------------------------------------------------------------------------- 00502 body VisParses::removeParse {parse} { 00503 00504 if {![info exists _pageOfParse($parse)]} { 00505 error "parse $parse is not visualized here" 00506 } 00507 set page $_pageOfParse($parse) 00508 unset _pageOfParse($parse) 00509 if {[array names _pageOfParse] == ""} { 00510 destroy $itk_interior 00511 return 00512 } 00513 set parsetree $itk_component(parseTree$page) 00514 itk_component delete $parsetree 00515 $itk_component(tbn) next 00516 $itk_component(tbn) delete [expr $page -1] 00517 } 00518 00519 ## ---------------------------------------------------------------------------- 00520 ## delegate the view command to the \c tbn component 00521 ## ---------------------------------------------------------------------------- 00522 body VisParses::view {no} { 00523 $itk_component(tbn) view $no 00524 } 00525 00526 ## ---------------------------------------------------------------------------- 00527 ## _print the visible level. 00528 ## ---------------------------------------------------------------------------- 00529 body VisParses::_print {} { 00530 00531 set parseId "parseTree[_labelOfIndex select]" 00532 if {$parseId == "parseTree"} { 00533 return 00534 } 00535 set title [$this cget -title] 00536 regexp {:(.*)$} $title dummy id 00537 set fileName "[pwd]/$id.ps" 00538 00539 if {![.cdgmain question "Print to file $fileName?" $itk_interior]} { 00540 return 00541 } 00542 00543 set parseTree $itk_component($parseId) 00544 set mainlevel [$parseTree mainlevelname] 00545 set synCanvas [[$parseTree component $mainlevel] component canvas] 00546 00547 scan "[$synCanvas bbox all]" "%f %f %f %f" x1 y1 x2 y2 00548 00549 $synCanvas postscript -file $fileName -x $x1 -width $x2 -y $y1 -height $y2 \ 00550 -pagewidth 26c -pageheight 18c -rotate 1 00551 00552 ::cmd::Puts "INFO: written postscript to file '$fileName'\n"; 00553 } 00554 00555 ## ---------------------------------------------------------------------------- 00556 ## load a parse directly into the editor. 00557 ## \todo this is not implelented yet here, but in AllParses 00558 ## ---------------------------------------------------------------------------- 00559 body VisParses::_loadAction {} { 00560 .cdgmain not_yet $itk_interior 00561 } 00562 00563 ## ---------------------------------------------------------------------------- 00564 ## writes the tree to file as an annotation. 00565 ## \todo The name of the file to write to is determined by parsing the 00566 ## \c -title property. Actually this should be done better by paying a round 00567 ## of new properties. 00568 ## ---------------------------------------------------------------------------- 00569 body VisParses::_saveAction {} { 00570 set parseId "parseTree[_labelOfIndex select]" 00571 if {$parseId == "parseTree"} { 00572 return 00573 } 00574 00575 set title [$this cget -title] 00576 regexp {:(.*)$} $title dummy id 00577 set fileName "[pwd]/$id.cda" 00578 00579 set parse $itk_component($parseId) 00580 $parse writeToFile [$parse parse getId] 00581 } 00582 00583 ## ---------------------------------------------------------------------------- 00584 ## writes the tree to file under a new name. 00585 ## ---------------------------------------------------------------------------- 00586 body VisParses::_saveAsAction {} { 00587 set parseId "parseTree[_labelOfIndex select]" 00588 if {$parseId == "parseTree"} { 00589 return 00590 } 00591 00592 set parse $itk_component($parseId) 00593 set id [tk_getSaveFile \ 00594 -parent $itk_component(hull) \ 00595 -title "Save as new file" \ 00596 -defaultextension .cda \ 00597 -initialfile [$parse parse getId]] 00598 00599 regsub ".cda$" $id "" id 00600 00601 if {$id != ""} { 00602 $parse writeToFile $id 00603 } 00604 } 00605 00606 00607 ## ---------------------------------------------------------------------------- 00608 ## call parseMirror() eventually. 00609 ## ---------------------------------------------------------------------------- 00610 body VisParses::_mirrorAction {} { 00611 set parseId "parseTree[_labelOfIndex select]" 00612 if {$parseId == "parseTree"} { 00613 return 00614 } 00615 set parse $itk_component($parseId) 00616 $parse mirror 00617 } 00618 00619 ## ---------------------------------------------------------------------------- 00620 ## visual version of the `verify' command 00621 ## ---------------------------------------------------------------------------- 00622 body VisParses::_verifyAction {} { 00623 set parseId "parseTree[_labelOfIndex select]" 00624 if {$parseId == "parseTree"} { 00625 return 00626 } 00627 set parse $itk_component($parseId) 00628 $parse verify 00629 } 00630 00631 ## ---------------------------------------------------------------------------- 00632 ## Switch to next or previous level in the parsetree. 00633 ## ---------------------------------------------------------------------------- 00634 body VisParses::_switchLevel {x} { 00635 set parseId "parseTree[_labelOfIndex select]" 00636 if {$parseId == "parseTree"} { 00637 return 00638 } 00639 set parse $itk_component($parseId) 00640 00641 if {1 == $x} { 00642 $parse forwardLevel 00643 } elseif {-1 == $x} { 00644 $parse backwardLevel 00645 } 00646 } 00647 00648 ## ---------------------------------------------------------------------------- 00649 ## Display cycles on a level in red ink. 00650 ## ---------------------------------------------------------------------------- 00651 body VisParses::_showcycleAction {} { 00652 set parseId "parseTree[_labelOfIndex select]" 00653 if {$parseId == "parseTree"} { 00654 return 00655 } 00656 set parse $itk_component($parseId) 00657 $parse showcycles 00658 } 00659 00660 ## ---------------------------------------------------------------------------- 00661 ## Break cycles in a parse. 00662 ## ---------------------------------------------------------------------------- 00663 body VisParses::_breakcycleAction {} { 00664 set parseId "parseTree[_labelOfIndex select]" 00665 if {$parseId == "parseTree"} { 00666 return 00667 } 00668 set parse $itk_component($parseId) 00669 $parse breakcycles 00670 } 00671 00672 ## ---------------------------------------------------------------------------- 00673 ## switch to the next tab in the tree editor. 00674 ## Switching to a next tab means that we select the next tree in a set of 00675 ## trees loaded into the editor. In case of solution parses we simply 00676 ## switch to the next parse in the editor. In case of annotation parses 00677 ## we switch to the next annotation or generate new annotation parses for the 00678 ## next lattice in the set of annotated lattices. 00679 ## ---------------------------------------------------------------------------- 00680 body VisParses::_nextAction {} { 00681 00682 if {[$itk_component(tbn) index select] == [$itk_component(tbn) index end] && \ 00683 [regexp {anno2parse:(.*)$} $itk_option(-title) dummy latticeId]} { 00684 set nextLatticeId [.cdgmain wordgraphs getNext $latticeId] 00685 if {$nextLatticeId == ""} { 00686 return 00687 } 00688 set lat [findLattice $nextLatticeId] 00689 if {$lat == "NULL"} { 00690 ::cmd::Puts "ERROR: no lattice `$nextLatticeId' found." 00691 return 00692 } 00693 for {set l [findAnnotations $lat 1]} {$l != "NULL" } {set l [listNext $l]} { 00694 set id [AnnoEntryStruct_id_get [listElement $l]] 00695 set parse [.cdgmain parses getCData $id] 00696 addParse $parse 00697 } 00698 } 00699 $itk_component(tbn) next 00700 } 00701 00702 ## ---------------------------------------------------------------------------- 00703 ## display the previous annotation. 00704 ## ---------------------------------------------------------------------------- 00705 body VisParses::_previousAction {} { 00706 $itk_component(tbn) prev 00707 } 00708 00709 ## ---------------------------------------------------------------------------- 00710 ## compute the violations of the selected ParseTree. 00711 ## ---------------------------------------------------------------------------- 00712 body VisParses::_computeViolas {} { 00713 set parseId "parseTree[_labelOfIndex select]" 00714 if {$parseId == "parseTree"} { 00715 return 00716 } 00717 $itk_component($parseId) computeViolas 00718 } 00719 00720 ## ---------------------------------------------------------------------------- 00721 ## undo the last action of the selected page. 00722 ## ---------------------------------------------------------------------------- 00723 body VisParses::_undo {} { 00724 set parseId "parseTree[_labelOfIndex select]" 00725 if {$parseId == "parseTree"} { 00726 return 00727 } 00728 $itk_component($parseId) undo 00729 } 00730 00731 ## ---------------------------------------------------------------------------- 00732 ## undo the last action of the selected page. 00733 ## ---------------------------------------------------------------------------- 00734 body VisParses::_redo {} { 00735 set parseId "parseTree[_labelOfIndex select]" 00736 if {$parseId == "parseTree"} { 00737 return 00738 } 00739 $itk_component($parseId) redo 00740 } 00741 00742 ## ---------------------------------------------------------------------------- 00743 ## _refresh the display of the selected VisParses. 00744 ## ---------------------------------------------------------------------------- 00745 body VisParses::_refresh {} { 00746 set parseId "parseTree[_labelOfIndex select]" 00747 $itk_component($parseId) drawAll 00748 getBadness 00749 } 00750 00751 ## ---------------------------------------------------------------------------- 00752 ## option -iconname. 00753 ## ---------------------------------------------------------------------------- 00754 configbody VisParses::iconname { 00755 wm iconname $itk_interior $itk_option(-iconname) 00756 } 00757 00758 ## ---------------------------------------------------------------------------- 00759 ## center on the middle of the application. 00760 ## ---------------------------------------------------------------------------- 00761 body VisParses::center {} { 00762 scan [wm geometry .] "%dx%d+%d+%d" appwd appht appx appy 00763 set wd [expr $appwd - 80] 00764 set ht [expr $appht - 80 ] 00765 set x [expr ($appwd - $wd) / 2 + $appx] 00766 set y [expr ($appht - $ht) / 2 + $appy] 00767 wm geometry $itk_interior "$wd\x$ht+$x+$y" 00768 } 00769 00770 ## ---------------------------------------------------------------------------- 00771 ## gets another word of typed input. 00772 ## Hangs until the word is supplied. 00773 ## ---------------------------------------------------------------------------- 00774 body VisParses::readWord {} { 00775 global queue 00776 00777 # busy waiting for next input 00778 if {$queue == ""} { 00779 vwait queue 00780 } 00781 00782 set word [lindex $queue 0] 00783 set queue [lreplace $queue 0 0] 00784 00785 return $word 00786 } 00787 00788 ## ---------------------------------------------------------------------------- 00789 ## undisplay the selected ParseTree. 00790 ## ---------------------------------------------------------------------------- 00791 body VisParses::_deleteParseAction {} { 00792 00793 set page [_labelOfIndex select] 00794 if {$page == ""} { 00795 return 00796 } 00797 set found 0 00798 foreach parse [array names _pageOfParse] { 00799 if {$_pageOfParse($parse) == $page} { 00800 incr found 00801 break 00802 } 00803 } 00804 00805 # this should not happen in any case : 00806 if {!$found} { 00807 error "internal error: can't find parse of page $page" 00808 } 00809 removeParse $parse 00810 } 00811 00812 ## ---------------------------------------------------------------------------- 00813 ## returns the label of a page. 00814 ## ---------------------------------------------------------------------------- 00815 body VisParses::_labelOfIndex {index} { 00816 set tbn $itk_component(tbn) 00817 set pageIndex [$tbn index $index] 00818 if {$pageIndex < 0} { 00819 return "" 00820 } 00821 return [lindex [$tbn pageconfigure $pageIndex -label] 4] 00822 } 00823 00824 ## ---------------------------------------------------------------------------- 00825 ## invoked by space in the textbox. 00826 ## ---------------------------------------------------------------------------- 00827 body VisParses::_spaceHandler {} { 00828 00829 global queue 00830 set box $itk_component(textbox) 00831 00832 # Spaces are very special, since they trigger actions in the 00833 # background. But that only happens if the space 00834 # comes right after a word, not after another space. 00835 if {[regexp {[ ]$} $_userInput]} return 00836 00837 # And space at the beginning of a line doesn't make sense. 00838 if {$_userInput == ""} return 00839 00840 # get last space-delimited word from the text 00841 if {![regexp {([^ ]+)[ ]*$} $_userInput foo word]} { 00842 puts "WARNING: `$_userInput' doesn't match the regexp." 00843 } 00844 00845 # deliver word to the queue 00846 #puts "DEBUG: queueing `$word'" 00847 lappend queue $word 00848 00849 # finally insert the space 00850 $box insert end " " 00851 00852 } 00853 00854 ## ---------------------------------------------------------------------------- 00855 ## invoked by Backspace in the textbox. 00856 ## ---------------------------------------------------------------------------- 00857 body VisParses::_BackspaceHandler {} { 00858 00859 global queue 00860 set box $itk_component(textbox) 00861 00862 # backspace on an empty line is inoperable. 00863 if {$_userInput == ""} return 00864 00865 # If the last space after a word is erased, the previous word is 00866 # withdrawn from the parse (but it remains in the textbox for 00867 # further editing). 00868 if {[regexp {[^ ] $} $_userInput]} { 00869 00870 # if the queue has a word in it (not a take-back request), 00871 # we simply remove the last element (so strictly speaking, it 00872 # isn't really a queue...) 00873 00874 if {$queue != "" && ![regexp {\$\#\$} $queue]} { 00875 #puts "DEBUG: retracting `[lindex $queue end]'" 00876 set nextToLast [expr [llength $queue] - 2] 00877 set queue [lrange $queue 0 $nextToLast] 00878 } else { 00879 00880 # a special symbol is queued to denote `take back a word' 00881 set word "$\#$" 00882 #puts "DEBUG: queueing `$word'" 00883 lappend queue $word 00884 00885 # and we also switch to the previous tab in the notebook 00886 set tbn $itk_component(tbn) 00887 $tbn configure -auto true 00888 set previoustab [expr [$tbn view] -1] 00889 if {$previoustab >= 0} { 00890 $tbn view $previoustab 00891 } 00892 } 00893 00894 } 00895 00896 # process the backspace 00897 $box delete [expr [string length $_userInput] - 1] 00898 00899 } 00900 00901 ## ---------------------------------------------------------------------------- 00902 ## Display all canvases of the selected parse smaller. 00903 ## ---------------------------------------------------------------------------- 00904 body VisParses::_zoomIn {} { 00905 set parseId "parseTree[_labelOfIndex select]" 00906 if {$parseId == "parseTree"} { 00907 return 00908 } 00909 set parse $itk_component($parseId) 00910 $parse zoom 1 00911 } 00912 00913 ## ---------------------------------------------------------------------------- 00914 ## display all canvases of the selected parse bigger. 00915 ## ---------------------------------------------------------------------------- 00916 body VisParses::_zoomOut {} { 00917 set parseId "parseTree[_labelOfIndex select]" 00918 if {$parseId == "parseTree"} { 00919 return 00920 } 00921 set parse $itk_component($parseId) 00922 $parse zoom -1 00923 } 00924 00925 ## ---------------------------------------------------------------------------- 00926 ## set the orientation of the split of the current parsetree. 00927 ## ---------------------------------------------------------------------------- 00928 body VisParses::_setOrientation {} { 00929 set parseId "parseTree[_labelOfIndex select]" 00930 if {$parseId == "parseTree"} { 00931 return 00932 } 00933 set parse $itk_component($parseId) 00934 $parse setOrientation $_currentOrient 00935 } 00936 00937 ## ---------------------------------------------------------------------------- 00938 ## get the orientation of the split of the current parsetree. 00939 ## ---------------------------------------------------------------------------- 00940 body VisParses::_getOrientation {} { 00941 set parseId "parseTree[_labelOfIndex select]" 00942 if {$parseId == "parseTree"} { 00943 return 00944 } 00945 set parse $itk_component($parseId) 00946 set _currentOrient [$parse getOrientation] 00947 return $_currentOrient 00948 } 00949 00950 ## ---------------------------------------------------------------------------- 00951 ## get the score of current parsetree 00952 ## ---------------------------------------------------------------------------- 00953 body VisParses::getBadness {} { 00954 set parseId "parseTree[_labelOfIndex select]" 00955 if {$parseId == "parseTree"} { 00956 return 00957 } 00958 set parse $itk_component($parseId) 00959 if {[scan [$parse parse getBadness] "%d %d %f" hard soft score] > 0} { 00960 set badnessString [format "Score: %d/%d/%4.3e" $hard $soft $score] 00961 } else { 00962 set badnessString "Score: n.a." 00963 } 00964 $itk_component(scoreLabel) configure -text $badnessString 00965 00966 $itk_component(idLabel) configure -text "Parse: [$parse parse getId]" 00967 } 00968 00969 ## ---------------------------------------------------------------------------- 00970 ## update the visual parts which depends on the selected parsetree 00971 ## ---------------------------------------------------------------------------- 00972 body VisParses::_updateVisual {} { 00973 set parseId "parseTree[_labelOfIndex select]" 00974 if {$parseId == "parseTree"} { 00975 return 00976 } 00977 set parse $itk_component($parseId) 00978 set method [$parse parse getSearchStrategy] 00979 set lattice [$parse parse getLatticeId] 00980 configure -title "$method:$lattice" 00981 _getOrientation 00982 getBadness 00983 } 00984 00985 ## ---------------------------------------------------------------------------- 00986 ## Delegate a highlight action to the parsetree 00987 ## ---------------------------------------------------------------------------- 00988 body VisParses::highlight {parse which} { 00989 set parseId "parseTree$_pageOfParse($parse)" 00990 $itk_component($parseId) highlight $which 00991 } 00992 00993 ## ---------------------------------------------------------------------------- 00994 ## updates the editmenu. This method is registered to the CommandHistory to 00995 ## be called whenever the undo history changes. Depending on the current 00996 ## position in the undo history, things are redoable or undoable. 00997 ## \todo get a better name for this method: "update" is most generic and might 00998 ## be confusing as we have a VisParsees::_updateVisual() aswell. 00999 ## ---------------------------------------------------------------------------- 01000 body VisParses::update {} { 01001 set parseId "parseTree[_labelOfIndex select]" 01002 if {$parseId == "parseTree"} { 01003 return 01004 } 01005 01006 if { [$itk_component($parseId) canUndo] == 1} { 01007 $itk_component(editmenu) entryconfigure 0 -state normal 01008 } else { 01009 $itk_component(editmenu) entryconfigure 0 -state disabled 01010 } 01011 01012 if { [$itk_component($parseId) canRedo] == 1} { 01013 $itk_component(editmenu) entryconfigure 1 -state normal 01014 } else { 01015 $itk_component(editmenu) entryconfigure 1 -state disabled 01016 } 01017 }

XCDG 0.95 (20 Oct 2004)