gmtree.tcl 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. ###############################################################
  2. # gmtree.tcl - GRASS GIS Manager procedures for creating and managing
  3. # layer tree
  4. # March 2006 Michael Barton, Arizona State University
  5. # COPYRIGHT: (C) 1999 - 2006 by the GRASS Development Team
  6. #
  7. # This program is free software under the GNU General Public
  8. # License (>=v2). Read the file COPYING that comes with GRASS
  9. # for details.
  10. #
  11. ##########################################################################
  12. namespace eval GmTree {
  13. variable count
  14. variable node
  15. variable selected ""
  16. variable dblclick
  17. variable legend_height 20
  18. variable legend_width 30
  19. variable treeht 6
  20. global array tree ;# mon
  21. global array filename ;# mon
  22. variable array pg ;# mon
  23. }
  24. ###############################################################################
  25. # redraw tree
  26. proc GmTree::redraw { mon } {
  27. variable tree
  28. Tree::_update_scrollregion $tree($mon)
  29. }
  30. ###############################################################################
  31. # create new layer tree
  32. proc GmTree::create { mon } {
  33. variable tree
  34. variable legend_height
  35. variable legend_width
  36. variable treeht
  37. variable pg
  38. variable page
  39. variable node
  40. global pgs
  41. global options
  42. global filename
  43. global keycontrol
  44. global bolddefault
  45. set currpg ""
  46. set pth ""
  47. set node 0
  48. set filename($mon) ""
  49. # add new page
  50. set pg($mon) [$pgs add page_$mon]
  51. $pgs raise page_$mon
  52. # destroy old panel with options
  53. destroy $options.fr
  54. set pgtitle [label $pg($mon).title -text [format [G_msg "Map Layers for Display %s"] $mon] \
  55. -font bolddefault -fg mediumblue -bg grey95]
  56. pack $pgtitle -side top -expand 0 -fill x -anchor n
  57. Separator $pg($mon).sep -orient horizontal
  58. pack $pg($mon).sep -side top -expand 0 -fill x -anchor n
  59. set sw [ScrolledWindow $pg($mon).sw \
  60. -relief flat -borderwidth 0 ]
  61. set lw [expr {$legend_width + 27}]
  62. set lh [expr {$legend_height + 6}]
  63. set tree($mon) [Tree $sw.tree_$mon \
  64. -relief flat -borderwidth 0 -highlightthickness 0 \
  65. -redraw 1 -dropenabled 1 -dragenabled 1 \
  66. -dragevent 1 -dropcmd "GmTree::drop" \
  67. -opencmd "GmTree::open_node $sw.tree_$mon" \
  68. -closecmd "GmTree::close_node $sw.tree_$mon" \
  69. -deltay $lh -padx $lw ]
  70. # this height setting is needed to make adding new layers look nice when they
  71. # scroll off the pane at the bottom (at least in the x11 interface).
  72. $tree($mon) configure -height $treeht
  73. $pgs configure -height [expr {$treeht * $lh} + {$legend_height}]
  74. $sw setwidget $tree($mon)
  75. bind_scroll $tree($mon)
  76. pack $sw -side top -expand yes -fill both
  77. pack $tree($mon) -side top -expand yes -fill both
  78. $tree($mon) configure -redraw 1
  79. $tree($mon) bindText <ButtonPress-1> "GmTree::selectn $tree($mon)"
  80. $tree($mon) bindImage <ButtonPress-1> "GmTree::selectn $tree($mon)"
  81. $tree($mon) bindText <Double-ButtonPress-1> "GmTree::edit $tree($mon)"
  82. $tree($mon) bindText <$keycontrol-Key-x> "GmTree::delete"
  83. return $tree($mon)
  84. }
  85. ###############################################################################
  86. # switch page when monitor selected
  87. proc GmTree::switchpage { mon } {
  88. global pgs
  89. global options
  90. global opt
  91. variable tree
  92. if {[info exists options]} {
  93. destroy $options.fr
  94. }
  95. $pgs raise "page_$mon"
  96. pack $tree($mon) -side top -expand yes -fill both
  97. set sel [ lindex [$tree($mon) selection get] 0 ]
  98. if { $sel == "" } { return }
  99. GmTree::selectn $tree($mon) $sel
  100. update
  101. }
  102. ###############################################################################
  103. # ScrollView
  104. proc GmTree::scrollview { mon } {
  105. variable tree
  106. toplevel .top -relief raised -borderwidth 2
  107. wm protocol .top WM_DELETE_WINDOW {
  108. # don't kill me
  109. }
  110. wm overrideredirect .top 1
  111. wm withdraw .top
  112. wm transient .top .
  113. ScrollView .top.sv -window $tree($mon) -fill black
  114. pack .top.sv -fill both -expand yes
  115. }
  116. ###############################################################################
  117. proc GmTree::drop { from to where operation type data } {
  118. variable tree
  119. global mon
  120. set old_parent [$from parent $data]
  121. set old_index [$from index $data]
  122. if { [lindex $where 0] == "position" } {
  123. set new_parent [lindex $where 1]
  124. set new_index [lindex $where 2]
  125. } elseif { [lindex $where 0] == "widget" } {
  126. set new_parent "root"
  127. set new_index [llength [$from nodes "root"] ]
  128. } else {
  129. set node [lindex $where 1]
  130. if { [GmTree::node_type $node] == "group" } {
  131. set new_parent $node
  132. set new_index 0
  133. } else {
  134. set new_parent [$from parent $node]
  135. set new_index [$from index $node]
  136. incr new_index
  137. }
  138. }
  139. # test if new is not in childrens
  140. set parent $new_parent
  141. while { $parent != "root" } {
  142. if { $parent == $data } { return }
  143. set parent [$from parent $parent]
  144. }
  145. if { ($old_parent == $new_parent) && ($new_index > $old_index) } {
  146. set new_index [expr {$new_index - 1}]
  147. }
  148. $from move $new_parent $data $new_index
  149. }
  150. ###############################################################################
  151. proc GmTree::open_node { tree node } {
  152. global mon
  153. GmGroup::open [GmTree::node_id $node]
  154. }
  155. ###############################################################################
  156. proc GmTree::close_node { tree node } {
  157. global mon
  158. GmGroup::close [GmTree::node_id $node]
  159. }
  160. ###############################################################################
  161. proc GmTree::selectn { tree node } {
  162. variable selected
  163. $tree selection set $node
  164. update
  165. set selected $node
  166. GmTree::select $node
  167. }
  168. ###############################################################################
  169. proc GmTree::edit { tree node } {
  170. #global mon
  171. #global tree
  172. set res [$tree edit $node [$tree itemcget $node -text]]
  173. if { $res != "" } {
  174. $tree itemconfigure $node -text $res
  175. }
  176. }
  177. ###############################################################################
  178. proc GmTree::autoname { tree node name} {
  179. $tree itemconfigure $node -text $name
  180. }
  181. ###############################################################################
  182. # create new empty
  183. proc GmTree::new { } {
  184. variable tree
  185. global options
  186. global new_root_node
  187. global mon
  188. global filename
  189. $tree($mon) delete [$tree($mon) nodes root]
  190. destroy $options.fr
  191. catch {unset filename($mon)}
  192. #GmPrint::init
  193. # What are those lines doing? IMHO we can live without new group "UNTITLED". MarisN.
  194. #set new_root_node [GmGroup::create $tree($mon) "root"]
  195. #$tree($mon) itemconfigure $new_root_node -text "UNTITLED_$mon"
  196. set filename($mon) Untitled_$mon.grc
  197. }
  198. ###############################################################################
  199. #Ctrl-W to close file
  200. proc GmTree::FileClose { stay_alive} {
  201. variable tree
  202. global options
  203. global mon
  204. global filename
  205. $tree($mon) delete [$tree($mon) nodes root]
  206. destroy $options.fr
  207. if { $stay_alive == ""} {
  208. catch {unset filename($mon)}
  209. }
  210. }
  211. ###############################################################################
  212. # add new group/layer to tree
  213. proc GmTree::add { type } {
  214. variable tree
  215. global new_root_node
  216. global mon
  217. # Create new tree, if none exists
  218. if { [array size GmTree::tree] < 1 } {
  219. Gm::startmon
  220. }
  221. if { [catch {match string {} $new_root_node}] } {
  222. set new_root_node root
  223. }
  224. # selected node
  225. catch {set parent_node [ lindex [$tree($mon) selection get] 0]} error
  226. if {[string first "invalid command name" $error] != -1} {
  227. tk_messageBox -type ok -icon error \
  228. -message [G_msg "You must open a display before adding map layers"]
  229. return
  230. }
  231. if { $parent_node == "" } {
  232. set parent_node $new_root_node
  233. }
  234. set parent_type [GmTree::node_type $parent_node]
  235. if { $parent_type != "group" } {
  236. set parent_node [$tree($mon) parent $parent_node]
  237. }
  238. switch $type {
  239. group {
  240. GmTree::selectn $tree($mon) [GmGroup::create $tree($mon) $parent_node]
  241. }
  242. raster {
  243. GmTree::selectn $tree($mon) [GmRaster::create $tree($mon) $parent_node]
  244. }
  245. vector {
  246. GmTree::selectn $tree($mon) [GmVector::create $tree($mon) $parent_node]
  247. }
  248. labels {
  249. GmTree::selectn $tree($mon) [GmLabels::create $tree($mon) $parent_node]
  250. }
  251. cmd {
  252. GmTree::selectn $tree($mon) [GmCmd::create $tree($mon) $parent_node]
  253. }
  254. gridline {
  255. GmTree::selectn $tree($mon) [GmGridline::create $tree($mon) $parent_node]
  256. }
  257. rgbhis {
  258. GmTree::selectn $tree($mon) [GmRgbhis::create $tree($mon) $parent_node]
  259. }
  260. hist {
  261. GmTree::selectn $tree($mon) [GmHist::create $tree($mon) $parent_node]
  262. }
  263. rnums {
  264. GmTree::selectn $tree($mon) [GmRnums::create $tree($mon) $parent_node]
  265. }
  266. arrows {
  267. GmTree::selectn $tree($mon) [GmArrows::create $tree($mon) $parent_node]
  268. }
  269. legend {
  270. GmTree::selectn $tree($mon) [GmLegend::create $tree($mon) $parent_node]
  271. }
  272. dframe {
  273. GmTree::selectn $tree($mon) [GmDframe::create $tree($mon) $parent_node]
  274. }
  275. barscale {
  276. GmTree::selectn $tree($mon) [GmBarscale::create $tree($mon) $parent_node]
  277. }
  278. chart {
  279. GmTree::selectn $tree($mon) [GmChart::create $tree($mon) $parent_node]
  280. }
  281. thematic {
  282. GmTree::selectn $tree($mon) [GmThematic::create $tree($mon) $parent_node]
  283. }
  284. dtext {
  285. GmTree::selectn $tree($mon) [GmDtext::create $tree($mon) $parent_node]
  286. }
  287. ctext {
  288. GmTree::selectn $tree($mon) [GmCtext::create $tree($mon) $parent_node]
  289. }
  290. clabels {
  291. GmTree::selectn $tree($mon) [GmCLabels::create $tree($mon) $parent_node]
  292. }
  293. }
  294. }
  295. ###############################################################################
  296. # autoname layer when a map is selected
  297. proc GmTree::autonamel { name } {
  298. variable tree
  299. variable node
  300. global mon
  301. set node [ lindex [$tree($mon) selection get] 0 ]
  302. GmTree::autoname $tree($mon) $node $name
  303. }
  304. ###############################################################################
  305. # selected node ( show options )
  306. proc GmTree::select { node } {
  307. variable tree
  308. global options
  309. set type [GmTree::node_type $node]
  310. set id [GmTree::node_id $node]
  311. # destroy old panel with options
  312. destroy $options.fr
  313. set opt [frame $options.fr ]
  314. pack $opt -fill both -expand yes
  315. switch $type {
  316. raster {
  317. GmRaster::options $id $opt
  318. }
  319. vector {
  320. GmVector::options $id $opt
  321. }
  322. labels {
  323. GmLabels::options $id $opt
  324. }
  325. cmd {
  326. GmCmd::options $id $opt
  327. }
  328. gridline {
  329. GmGridline::options $id $opt
  330. }
  331. rgbhis {
  332. GmRgbhis::options $id $opt
  333. }
  334. hist {
  335. GmHist::options $id $opt
  336. }
  337. rnums {
  338. GmRnums::options $id $opt
  339. }
  340. arrows {
  341. GmArrows::options $id $opt
  342. }
  343. legend {
  344. GmLegend::options $id $opt
  345. }
  346. dframe {
  347. GmDframe::options $id $opt
  348. }
  349. barscale {
  350. GmBarscale::options $id $opt
  351. }
  352. chart {
  353. GmChart::options $id $opt
  354. }
  355. thematic {
  356. GmThematic::options $id $opt
  357. }
  358. dtext {
  359. GmDtext::options $id $opt
  360. }
  361. ctext {
  362. GmCtext::options $id $opt
  363. }
  364. clabels {
  365. GmCLabels::options $id $opt
  366. }
  367. }
  368. }
  369. ###############################################################################
  370. # deselect ( hide options )
  371. proc GmTree::deselect { node } {
  372. variable tree
  373. global options
  374. global mon
  375. destroy $options.fr
  376. }
  377. ###############################################################################
  378. # delete selected node
  379. proc GmTree::delete { } {
  380. variable tree
  381. global options
  382. global mon
  383. if { [array size GmTree::tree] < 1 } {
  384. GmLib::errmsg $error [G_msg "No layer selected"]
  385. }
  386. set sel [ lindex [$tree($mon) selection get] 0 ]
  387. if { $sel == "" } { return }
  388. $tree($mon) delete $sel
  389. destroy $options.fr
  390. }
  391. ###############################################################################
  392. # return selected node
  393. proc GmTree::getnode { } {
  394. variable tree
  395. global mon
  396. set sel [ lindex [$tree($mon) selection get] 0 ]
  397. return $sel
  398. }
  399. ###############################################################################
  400. # display nodes for GRASS display modules
  401. proc GmTree::display_node { node mod } {
  402. global mon
  403. variable tree
  404. set type [GmTree::node_type $node]
  405. switch $type {
  406. group {
  407. GmGroup::display $node $mod
  408. }
  409. raster {
  410. GmRaster::display $node $mod
  411. }
  412. labels {
  413. GmLabels::display $node $mod
  414. }
  415. vector {
  416. GmVector::display $node $mod
  417. }
  418. cmd {
  419. GmCmd::display $node $mod
  420. }
  421. gridline {
  422. GmGridline::display $node $mod
  423. }
  424. rgbhis {
  425. GmRgbhis::display $node $mod
  426. }
  427. hist {
  428. GmHist::display $node $mod
  429. }
  430. rnums {
  431. GmRnums::display $node $mod
  432. }
  433. arrows {
  434. GmArrows::display $node $mod
  435. }
  436. legend {
  437. GmLegend::display $node $mod
  438. }
  439. dframe {
  440. GmDframe::display $node $mod
  441. }
  442. barscale {
  443. GmBarscale::display $node $mod
  444. }
  445. chart {
  446. GmChart::display $node $mod
  447. }
  448. thematic {
  449. GmThematic::display $node $mod
  450. }
  451. dtext {
  452. GmDtext::display $node $mod
  453. }
  454. }
  455. }
  456. ###############################################################################
  457. # display nodes for canvas graphics
  458. proc GmTree::display_cvnode { node} {
  459. variable tree
  460. set type [GmTree::node_type $node]
  461. switch $type {
  462. clabels {
  463. GmCLabels::display $node
  464. }
  465. cgrid {
  466. GmcGridl::display $node
  467. }
  468. cframe {
  469. GmCframe::display $node
  470. }
  471. cbarscale {
  472. GmCbarscale::display $node
  473. }
  474. ctext {
  475. GmCtext::display $node
  476. }
  477. }
  478. }
  479. ###############################################################################
  480. # display nodes for GRASS display modules
  481. proc GmTree::nvdisplay_node { node nvelev nvcolor} {
  482. variable tree
  483. set type [GmTree::node_type $node]
  484. switch $type {
  485. group {
  486. GmGroup::nvdisplay $node
  487. }
  488. raster {
  489. if {$nvelev == "" } {
  490. set nvelev [GmRaster::addelev $node $nvelev]
  491. } else {
  492. append nvelev ", [GmRaster::addelev $node $nvelev]"
  493. }
  494. if {$nvcolor == "" } {
  495. set nvcolor [GmRaster::addcolor $node $nvcolor]
  496. } else {
  497. append nvcolor ", [GmRaster::addcolor $node $nvcolor]"
  498. }
  499. }
  500. }
  501. }
  502. ###############################################################################
  503. # duplicate selected layer
  504. proc GmTree::duplicate { } {
  505. variable tree
  506. global options
  507. variable id
  508. global new_root_node mon
  509. if { [array size GmTree::tree] < 1 } {
  510. GmLib::errmsg $error [G_msg "No layer selected"]
  511. }
  512. if { [catch {match string {} $new_root_node}] } {
  513. set new_root_node root
  514. }
  515. # selected node
  516. set parent_node [ lindex [$tree($mon) selection get] 0 ]
  517. if { $parent_node == "" } {
  518. set parent_node $new_root_node
  519. }
  520. set parent_type [GmTree::node_type $parent_node]
  521. if { $parent_type != "group" } {
  522. set parent_node [$tree($mon) parent $parent_node]
  523. }
  524. set sel [ lindex [$tree($mon) selection get] 0 ]
  525. if { $sel == "" } { return }
  526. set type [GmTree::node_type $sel]
  527. set id [GmTree::node_id $sel]
  528. switch $type {
  529. raster {
  530. GmRaster::duplicate $tree($mon) $parent_node $sel $id
  531. }
  532. labels {
  533. GmLabels::duplicate $tree($mon) $parent_node $sel $id
  534. }
  535. vector {
  536. GmVector::duplicate $tree($mon) $parent_node $sel $id
  537. }
  538. cmd {
  539. GmCmd::duplicate $tree($mon) $parent_node $sel $id
  540. }
  541. gridline {
  542. GmGridline::duplicate $tree($mon) $parent_node $sel $id
  543. }
  544. rgbhis {
  545. GmRgbhis::duplicate $tree($mon) $parent_node $sel $id
  546. }
  547. hist {
  548. GmHist::duplicate $tree($mon) $parent_node $sel $id
  549. }
  550. rnums {
  551. GmRnums::duplicate $tree($mon) $parent_node $sel $id
  552. }
  553. arrows {
  554. GmArrows::duplicate $tree($mon) $parent_node $sel $id
  555. }
  556. legend {
  557. GmLegend::duplicate $tree($mon) $parent_node $sel $id
  558. }
  559. dframe {
  560. GmDframe::duplicate $tree($mon) $parent_node $sel $id
  561. }
  562. barscale {
  563. GmBarscale::duplicate $tree($mon) $parent_node $sel $id
  564. }
  565. chart {
  566. GmChart::duplicate $tree($mon) $parent_node $sel $id
  567. }
  568. thematic {
  569. GmThematic::duplicate $tree($mon) $parent_node $sel $id
  570. }
  571. dtext {
  572. GmDtext::duplicate $tree($mon) $parent_node $sel $id
  573. }
  574. ctext {
  575. GmCtext::duplicate $tree($mon) $parent_node $sel $id
  576. }
  577. clabels {
  578. GmCLabels::duplicate $tree($mon) $parent_node $sel $id
  579. }
  580. group {
  581. GmGroup::duplicate $tree($mon) $parent_node $sel $id
  582. }
  583. }
  584. }
  585. ###############################################################################
  586. # save tree/options to file
  587. proc GmTree::save { spth } {
  588. global gisdbase location_name mapset
  589. global env mon
  590. variable rcfile
  591. variable tree
  592. set fpath $spth
  593. if {[catch {set rcfile [open $fpath w]} error]} {
  594. GmLib::errmsg $error [G_msg [format "Could not open file for writing.\n%s" $fpath]]
  595. return
  596. }
  597. GmGroup::save $tree($mon) 0 "root"
  598. if {[catch {close $rcfile} error]} {
  599. GmLib::errmsg $error
  600. }
  601. }
  602. ###############################################################################
  603. # save node to file
  604. proc GmTree::save_node { depth node } {
  605. variable rcfile
  606. variable tree
  607. global mon
  608. global filename
  609. set type [GmTree::node_type $node]
  610. set name [$tree($mon) itemcget $node -text]
  611. if { $type == "group" && $name == "UNTITLED_$mon" } {
  612. set name "File $filename($mon)"
  613. }
  614. switch $type {
  615. group {
  616. GmTree::rc_write $depth Group $name
  617. incr depth
  618. GmGroup::save $tree($mon) $depth $node
  619. }
  620. raster {
  621. GmTree::rc_write $depth Raster $name
  622. incr depth
  623. GmRaster::save $tree($mon) $depth $node
  624. }
  625. labels {
  626. GmTree::rc_write $depth Labels $name
  627. incr depth
  628. GmLabels::save $tree($mon) $depth $node
  629. }
  630. vector {
  631. GmTree::rc_write $depth Vector $name
  632. incr depth
  633. GmVector::save $tree($mon) $depth $node
  634. }
  635. cmd {
  636. GmTree::rc_write $depth Cmd $name
  637. incr depth
  638. GmCmd::save $tree($mon) $depth $node
  639. }
  640. gridline {
  641. GmTree::rc_write $depth gridline $name
  642. incr depth
  643. GmGridline::save $tree($mon) $depth $node
  644. }
  645. rgbhis {
  646. GmTree::rc_write $depth rgbhis $name
  647. incr depth
  648. GmRgbhis::save $tree($mon) $depth $node
  649. }
  650. hist {
  651. GmTree::rc_write $depth hist $name
  652. incr depth
  653. GmHist::save $tree($mon) $depth $node
  654. }
  655. rnums {
  656. GmTree::rc_write $depth rnums $name
  657. incr depth
  658. GmRnums::save $tree($mon) $depth $node
  659. }
  660. arrows {
  661. GmTree::rc_write $depth arrows $name
  662. incr depth
  663. GmArrows::save $tree($mon) $depth $node
  664. }
  665. legend {
  666. GmTree::rc_write $depth legend $name
  667. incr depth
  668. GmLegend::save $tree($mon) $depth $node
  669. }
  670. dframe {
  671. GmTree::rc_write $depth dframe $name
  672. incr depth
  673. GmDframe::save $tree($mon) $depth $node
  674. }
  675. barscale {
  676. GmTree::rc_write $depth barscale $name
  677. incr depth
  678. GmBarscale::save $tree($mon) $depth $node
  679. }
  680. chart {
  681. GmTree::rc_write $depth chart $name
  682. incr depth
  683. GmChart::save $tree($mon) $depth $node
  684. }
  685. thematic {
  686. GmTree::rc_write $depth thematic $name
  687. incr depth
  688. GmThematic::save $tree($mon) $depth $node
  689. }
  690. dtext {
  691. GmTree::rc_write $depth dtext $name
  692. incr depth
  693. GmDtext::save $tree($mon) $depth $node
  694. }
  695. ctext {
  696. GmTree::rc_write $depth ctext $name
  697. incr depth
  698. GmCtext::save $tree($mon) $depth $node
  699. }
  700. clabels {
  701. GmTree::rc_write $depth clabels $name
  702. incr depth
  703. GmCLabels::save $tree($mon) $depth $node
  704. }
  705. }
  706. set depth [expr {$depth - 1}]
  707. GmTree::rc_write $depth End
  708. }
  709. ###############################################################################
  710. # load tree/options from file
  711. proc GmTree::load { lpth } {
  712. global gisdbase location_name mapset
  713. global env mon
  714. global max_prgindic
  715. global prgtext
  716. global prgindic
  717. global filename
  718. global mon
  719. variable rcfile
  720. variable tree
  721. set prgtext [G_msg "Loading layers..."]
  722. set fpath $lpth
  723. if { ![file exist $fpath] || ![file readable $fpath] } {
  724. return
  725. }
  726. # Clean up before add workspace
  727. GmTree::new
  728. set filename($mon) $fpath
  729. catch {set rcfile [open $fpath r]}
  730. set file_size [file size $fpath]
  731. set nrows [expr {$file_size / 16}]
  732. set parent root
  733. set row 0
  734. while { [gets $rcfile in] > -1 } {
  735. set key ""
  736. set val ""
  737. set in [string trim $in " "]
  738. if { $in == "" } { continue }
  739. if { ![regexp -- {([^ ]+) (.+)$} $in r key val] } {set key $in}
  740. # Tree of layers
  741. switch $key {
  742. Group {
  743. if {[regexp -- {^File (.+)} $val r leftover] && ($leftover != $filename($mon))} {
  744. set val "<-- $leftover"
  745. }
  746. set current_node [GmGroup::create $tree($mon) $parent]
  747. $tree($mon) itemconfigure $current_node -text $val
  748. set parent $current_node
  749. }
  750. Raster {
  751. set current_node [GmRaster::create $tree($mon) $parent]
  752. $tree($mon) itemconfigure $current_node -text $val
  753. }
  754. Labels {
  755. set current_node [GmLabels::create $tree($mon) $parent]
  756. $tree($mon) itemconfigure $current_node -text $val
  757. }
  758. Vector {
  759. set current_node [GmVector::create $tree($mon) $parent]
  760. $tree($mon) itemconfigure $current_node -text $val
  761. }
  762. Cmd {
  763. set current_node [GmCmd::create $tree($mon) $parent]
  764. $tree($mon) itemconfigure $current_node -text $val
  765. }
  766. gridline {
  767. set current_node [GmGridline::create $tree($mon) $parent]
  768. $tree($mon) itemconfigure $current_node -text $val
  769. }
  770. rgbhis {
  771. set current_node [GmRgbhis::create $tree($mon) $parent]
  772. $tree($mon) itemconfigure $current_node -text $val
  773. }
  774. hist {
  775. set current_node [GmHist::create $tree($mon) $parent]
  776. $tree($mon) itemconfigure $current_node -text $val
  777. }
  778. rnums {
  779. set current_node [GmRnums::create $tree($mon) $parent]
  780. $tree($mon) itemconfigure $current_node -text $val
  781. }
  782. arrows {
  783. set current_node [GmArrows::create $tree($mon) $parent]
  784. $tree($mon) itemconfigure $current_node -text $val
  785. }
  786. legend {
  787. set current_node [GmLegend::create $tree($mon) $parent]
  788. $tree($mon) itemconfigure $current_node -text $val
  789. }
  790. dframe {
  791. set current_node [GmDframe::create $tree($mon) $parent]
  792. $tree($mon) itemconfigure $current_node -text $val
  793. }
  794. barscale {
  795. set current_node [GmBarscale::create $tree($mon) $parent]
  796. $tree($mon) itemconfigure $current_node -text $val
  797. }
  798. chart {
  799. set current_node [GmChart::create $tree($mon) $parent]
  800. $tree($mon) itemconfigure $current_node -text $val
  801. }
  802. thematic {
  803. set current_node [GmThematic::create $tree($mon) $parent]
  804. $tree($mon) itemconfigure $current_node -text $val
  805. }
  806. dtext {
  807. set current_node [GmDtext::create $tree($mon) $parent]
  808. $tree($mon) itemconfigure $current_node -text $val
  809. }
  810. ctext {
  811. set current_node [GmCtext::create $tree($mon) $parent]
  812. $tree($mon) itemconfigure $current_node -text $val
  813. }
  814. clabels {
  815. set current_node [GmCLabels::create $tree($mon) $parent]
  816. $tree($mon) itemconfigure $current_node -text $val
  817. }
  818. End {
  819. set type [GmTree::node_type $current_node]
  820. if { $type == "group" } {
  821. set parent [$tree($mon) parent $parent]
  822. }
  823. set current_node [$tree($mon) parent $current_node]
  824. }
  825. default {
  826. if {[catch {GmTree::node_type $current_node} error]} {
  827. GmLib::errmsg $error [G_msg [format "Could not open %s - bad file format" $fpath]]
  828. break
  829. } else {
  830. set type [GmTree::node_type $current_node]
  831. switch $type {
  832. group {
  833. GmGroup::set_option $current_node $key $val
  834. }
  835. raster {
  836. GmRaster::set_option $current_node $key $val
  837. }
  838. labels {
  839. GmLabels::set_option $current_node $key $val
  840. }
  841. vector {
  842. GmVector::set_option $current_node $key $val
  843. }
  844. cmd {
  845. GmCmd::set_option $current_node $key $val
  846. }
  847. gridline {
  848. GmGridline::set_option $current_node $key $val
  849. }
  850. rgbhis {
  851. GmRgbhis::set_option $current_node $key $val
  852. }
  853. hist {
  854. GmHist::set_option $current_node $key $val
  855. }
  856. rnums {
  857. GmRnums::set_option $current_node $key $val
  858. }
  859. arrows {
  860. GmArrows::set_option $current_node $key $val
  861. }
  862. legend {
  863. GmLegend::set_option $current_node $key $val
  864. }
  865. dframe {
  866. GmDframe::set_option $current_node $key $val
  867. }
  868. barscale {
  869. GmBarscale::set_option $current_node $key $val
  870. }
  871. chart {
  872. GmChart::set_option $current_node $key $val
  873. }
  874. thematic {
  875. GmThematic::set_option $current_node $key $val
  876. }
  877. dtext {
  878. GmDtext::set_option $current_node $key $val
  879. }
  880. ctext {
  881. GmCtext::set_option $current_node $key $val
  882. }
  883. clabels {
  884. GmCLabels::set_option $current_node $key $val
  885. }
  886. }
  887. }
  888. }
  889. }
  890. incr row
  891. set prg [expr {$max_prgindic * $row / $nrows}]
  892. if { $prg > $max_prgindic } { set prg $max_prgindic }
  893. set Gm::prgindic $prg
  894. }
  895. if {[catch {close $rcfile} error]} {
  896. GmLib::errmsg $error
  897. }
  898. set Gm::prgindic $max_prgindic
  899. set prgtext [G_msg "Layers loaded"]
  900. }
  901. ###############################################################################
  902. # write one row
  903. proc GmTree::rc_write { depth args } {
  904. variable rcfile
  905. set offset [string repeat " " $depth]
  906. set key [lindex $args 0]
  907. if { [llength $args] > 1 } {
  908. set value [lindex $args 1]
  909. set row "$offset$key $value"
  910. } else {
  911. set row "$offset$key"
  912. }
  913. puts $rcfile $row
  914. }
  915. ###############################################################################
  916. # returns node type
  917. proc GmTree::node_type { node } {
  918. variable tree
  919. global mon
  920. global type
  921. if { [string compare $node "root"] == 0 } {
  922. return "group"
  923. }
  924. if { [string match group* $node] } {
  925. return "group"
  926. }
  927. if { [string match raster* $node] } {
  928. return "raster"
  929. }
  930. if { [string match labels* $node] } {
  931. return "labels"
  932. }
  933. if { [string match vector* $node] } {
  934. return "vector"
  935. }
  936. if { [string match cmd* $node] } {
  937. return "cmd"
  938. }
  939. if { [string match gridline* $node] } {
  940. return "gridline"
  941. }
  942. if { [string match rgbhis* $node] } {
  943. return "rgbhis"
  944. }
  945. if { [string match hist* $node] } {
  946. return "hist"
  947. }
  948. if { [string match rnums* $node] } {
  949. return "rnums"
  950. }
  951. if { [string match arrows* $node] } {
  952. return "arrows"
  953. }
  954. if { [string match legend* $node] } {
  955. return "legend"
  956. }
  957. if { [string match dframe* $node] } {
  958. return "dframe"
  959. }
  960. if { [string match barscale* $node] } {
  961. return "barscale"
  962. }
  963. if { [string match chart* $node] } {
  964. return "chart"
  965. }
  966. if { [string match thematic* $node] } {
  967. return "thematic"
  968. }
  969. if { [string match dtext* $node] } {
  970. return "dtext"
  971. }
  972. if { [string match ctext* $node] } {
  973. return "ctext"
  974. }
  975. if { [string match clabels* $node] } {
  976. return "clabels"
  977. }
  978. return ""
  979. }
  980. ###############################################################################
  981. #digitize
  982. proc GmTree::vedit { } {
  983. variable tree
  984. global options env
  985. global mon
  986. if { [array size GmTree::tree] < 1 } {
  987. tk_messageBox -type ok -icon warning -message [G_msg "No layer selected"]
  988. return
  989. }
  990. set sel [ lindex [$tree($mon) selection get] 0 ]
  991. if { $sel == "" } {
  992. tk_messageBox -type ok -icon warning -message [G_msg "No layer selected"]
  993. return
  994. }
  995. set type [GmTree::node_type $sel]
  996. set id [GmTree::node_id $sel]
  997. switch $type {
  998. raster {
  999. if { $GmRaster::opt($id,1,map) == "" } {
  1000. tk_messageBox -type ok -icon warning -message [G_msg "Selected raster layer is empty"]
  1001. return
  1002. }
  1003. unset env(GRASS_RENDER_IMMEDIATE)
  1004. guarantee_xmon
  1005. term r.digit
  1006. set env(GRASS_RENDER_IMMEDIATE) "TRUE"
  1007. return
  1008. }
  1009. vector {
  1010. if { $GmVector::opt($id,1,vect) == "" } {
  1011. tk_messageBox -type ok -icon warning -message [G_msg "Selected vector layer is empty"]
  1012. return
  1013. }
  1014. GmVector::WorkOnVector $sel 0
  1015. }
  1016. default {
  1017. tk_messageBox -type ok -icon warning -message [G_msg "You can digitize raster or vector maps only"]
  1018. return
  1019. }
  1020. }
  1021. }
  1022. ###############################################################################
  1023. # returns node id
  1024. proc GmTree::node_id { node } {
  1025. variable tree
  1026. global mon
  1027. if { ![regexp {[^:]+:(.+)$} $node x id] } {
  1028. return 0
  1029. } else {
  1030. return $id
  1031. }
  1032. }
  1033. ###############################################################################
  1034. proc GmTree::cvdisplay { node } {
  1035. variable opt
  1036. variable tree
  1037. global mon
  1038. global drawprog
  1039. foreach n [$tree($mon) nodes $node] {
  1040. GmTree::display_cvnode $n
  1041. incr drawprog
  1042. }
  1043. }