MeasTextGui.itcl 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  1. #---------------------------------------------------------------------
  2. #
  3. #
  4. # MeasTextGui.itcl
  5. #
  6. # Graphical interface for lab applications using
  7. # SPPDG *measure.txt files.
  8. #
  9. # This is a incrTcl mega-wiget. It is completely contained within
  10. # a single frame; which can be placed inside a larger user-interface,
  11. # placed into a toplevel window, or placed inside the frame of a
  12. # dialog widget.
  13. #
  14. # This class is derived from the MeasText incrTcl class.
  15. # MeasTextGui only provides the graphical interface, all the
  16. # parsing work, and all the data is contained in the base class.
  17. #
  18. #
  19. # Eric Amundsen
  20. # May 28, 2004
  21. #
  22. # Copyright 2004 Mayo Foundation. All rights reserved.
  23. #
  24. #
  25. # $Id: MeasTextGui.itcl,v 1.5 2004/06/22 18:11:17 amundsen Exp $
  26. #
  27. #---------------------------------------------------------------------
  28. package provide MeasTextGui 1.0
  29. package require MeasText 1.0
  30. package require Tk
  31. package require Itcl
  32. package require Itk
  33. package require Iwidgets
  34. package require BWidget
  35. package require fileutil
  36. # option database stolen from Bob Techentin's tnt package
  37. if { [tk windowingsystem] == "x11" } {
  38. set highlightbg "#316AC5" ; # SystemHighlight
  39. set highlightfg "white" ; # SystemHighlightText
  40. set bg "white" ; # SystemWindow
  41. set fg "black" ; # SystemWindowText
  42. ## Fonts
  43. ##
  44. set size -12
  45. set family Helvetica
  46. set fsize -12
  47. set ffamily Courier
  48. font create ASfont -size $size -family $family
  49. font create ASfontBold -size $size -family $family -weight bold
  50. font create ASfontFixed -size $fsize -family $ffamily
  51. for {set i -2} {$i <= 4} {incr i} {
  52. set isize [expr {$size + ($i * (($size > 0) ? 1 : -1))}]
  53. set ifsize [expr {$fsize + ($i * (($fsize > 0) ? 1 : -1))}]
  54. font create ASfont$i -size $isize -family $family
  55. font create ASfontBold$i -size $isize -family $family -weight bold
  56. font create ASfontFixed$i -size $ifsize -family $ffamily
  57. }
  58. #---------------------------------------------------------------
  59. # Check for CDE - which overrides options at userDefault level.
  60. # Note that the CDE package at http://wiki.tcl.tk/cde has
  61. # a much more complex (and probably more correct) way to
  62. # determine if CDE is running - but this works for Mayo SPPDG.
  63. #---------------------------------------------------------------
  64. if { [info exists ::env(DTUSERSESSION)] } {
  65. set priority userDefault
  66. option add *background #d9d9d9 $priority
  67. } else {
  68. set priority widgetDefault
  69. }
  70. option add *Text.font ASfontFixed $priority
  71. option add *Button.font ASfont $priority
  72. option add *Canvas.font ASfont $priority
  73. option add *Checkbutton.font ASfont $priority
  74. option add *Entry.font ASfont $priority
  75. option add *Label.font ASfont $priority
  76. option add *Labelframe.font ASfont $priority
  77. option add *Listbox.font ASfont $priority
  78. option add *Menu.font ASfont $priority
  79. option add *Menubutton.font ASfont $priority
  80. option add *Message.font ASfont $priority
  81. option add *Radiobutton.font ASfont $priority
  82. option add *Spinbox.font ASfont $priority
  83. option add *Table.font ASfont $priority
  84. option add *TreeCtrl*font ASfont $priority
  85. ## Misc
  86. ##
  87. option add *ScrolledWindow.ipad 0 $priority
  88. ## Listbox
  89. ##
  90. option add *Listbox.background $bg $priority
  91. option add *Listbox.foreground $fg $priority
  92. option add *Listbox.selectBorderWidth 0 $priority
  93. option add *Listbox.selectForeground $highlightfg $priority
  94. option add *Listbox.selectBackground $highlightbg $priority
  95. option add *Listbox.activeStyle dotbox $priority
  96. ## Button
  97. ##
  98. option add *Button.padX 1 $priority
  99. option add *Button.padY 2 $priority
  100. ## Entry
  101. ##
  102. option add *Entry.background $bg $priority
  103. option add *Entry.foreground $fg $priority
  104. option add *Entry.selectBorderWidth 0 $priority
  105. option add *Entry.selectForeground $highlightfg $priority
  106. option add *Entry.selectBackground $highlightbg $priority
  107. option add *Entryfield.background $bg $priority
  108. option add *Entryfield.textBackground $bg $priority
  109. option add *Entryfield.foreground $fg $priority
  110. option add *Entryfield.selectBorderWidth 0 $priority
  111. option add *Entryfield.selectForeground $highlightfg $priority
  112. option add *Entryfield.selectBackground $highlightbg $priority
  113. ## Spinbox
  114. ##
  115. option add *Spinbox.background $bg $priority
  116. option add *Spinbox.foreground $fg $priority
  117. option add *Spinbox.selectBorderWidth 0 $priority
  118. option add *Spinbox.selectForeground $highlightfg $priority
  119. option add *Spinbox.selectBackground $highlightbg $priority
  120. ## Text
  121. ##
  122. option add *Text.background $bg $priority
  123. option add *Text.foreground $fg $priority
  124. option add *Text.selectBorderWidth 0 $priority
  125. option add *Text.selectForeground $highlightfg $priority
  126. option add *Text.selectBackground $highlightbg $priority
  127. option add *Scrolledtext.background $bg $priority
  128. option add *Scrolledtext.foreground $fg $priority
  129. option add *Scrolledtext.selectBorderWidth 0 $priority
  130. option add *Scrolledtext.selectForeground $highlightfg $priority
  131. option add *Scrolledtext.selectBackground $highlightbg $priority
  132. ## Menu
  133. ##
  134. option add *Menu.activeBackground $highlightbg $priority
  135. option add *Menu.activeForeground $highlightfg $priority
  136. option add *Menu.activeBorderWidth 0 $priority
  137. option add *Menu.highlightThickness 0 $priority
  138. option add *Menu.borderWidth 1 $priority
  139. ## Menubutton
  140. ##
  141. option add *Menubutton.activeBackground $highlightbg $priority
  142. option add *Menubutton.activeForeground $highlightfg $priority
  143. option add *Menubutton.activeBorderWidth 0 $priority
  144. option add *Menubutton.highlightThickness 0 $priority
  145. option add *Menubutton.borderWidth 0 $priority
  146. option add *Menubutton*padX 4 $priority
  147. option add *Menubutton*padY 2 $priority
  148. ## Scrollbar
  149. ##
  150. option add *Scrollbar.width 12 $priority
  151. option add *Scrollbar.troughColor #bdb6ad $priority
  152. option add *Scrollbar.borderWidth 1 $priority
  153. option add *Scrollbar.highlightThickness 0 $priority
  154. ## PanedWindow
  155. ##
  156. option add *Panedwindow.borderWidth 0 $priority
  157. option add *Panedwindow.sashwidth 3 $priority
  158. option add *Panedwindow.showhandle 0 $priority
  159. option add *Panedwindow.sashpad 0 $priority
  160. option add *Panedwindow.sashrelief flat $priority
  161. option add *Panedwindow.relief flat $priority
  162. }
  163. # need this to get around a bug in Iwidgets with using a BWidget
  164. # megawidget in an Itk megawidget
  165. itk::usual ComboBox {}
  166. itk::usual Tree {}
  167. # +-Class Name-------------------------------------------------------+
  168. # |
  169. # | itcl::class MeasTextGui
  170. # |
  171. # +-Base Classes-----------------------------------------------------+
  172. # |
  173. # | itk::Widget
  174. # | MeasText
  175. # |
  176. # +-Attributes-------------------------------------------------------+
  177. # |
  178. # | Public:
  179. # |
  180. # | Private:
  181. # | browseIcon
  182. # | pickFromListIcon
  183. # | designTree
  184. # | designTreeIndex
  185. # | result
  186. # | pathsFilename
  187. # | designTreeMeasTextList
  188. # |
  189. # +-Methods----------------------------------------------------------+
  190. # |
  191. # | Public:
  192. # | constructor
  193. # | destructor
  194. # |
  195. # | Private:
  196. # | browseMeasButtonCallback
  197. # | parseMeasFilename
  198. # | comboBoxCallback
  199. # | notesCallback
  200. # | measListDialogOKCallback
  201. # | buildMeasListDialog
  202. # | closeMeasListDialog
  203. # | pickMeasListButtonCallback
  204. # | scanCallback
  205. # | scanDesignTree
  206. # | scanningDesignTree
  207. # | updateScanningProgress
  208. # |
  209. # +------------------------------------------------------------------+
  210. itcl::class MeasTextGui {
  211. inherit itk::Widget MeasText
  212. public {
  213. method constructor {args}
  214. }
  215. private {
  216. method browseMeasButtonCallback {}
  217. method parseMeasFilename {}
  218. method comboBoxCallback {}
  219. method notesCallback {textWidget baseClassNotes}
  220. method measListDialogOKCallback {args}
  221. method buildMeasListDialog {}
  222. method closeMeasListDialog {}
  223. method pickMeasListButtonCallback {}
  224. method scanCallback {}
  225. method scanDesignTree {}
  226. method scanningDesignTree {}
  227. method updateScanningProgress {}
  228. }
  229. private {
  230. variable designTree [list]
  231. variable designTreeIndex 1
  232. variable result 0
  233. variable pathsFilename {//sppdgfs/lab/lib/paths/paths.txt}
  234. variable designTreeMeasTextList [list]
  235. variable pathArray
  236. variable browseIcon
  237. variable pickFromListIcon
  238. }
  239. }
  240. # +-Public Method----------------------------------------------------+
  241. # |
  242. # | MeasTextGui::constructor
  243. # |
  244. # +-Description------------------------------------------------------+
  245. # |
  246. # | Construct the GUI
  247. # |
  248. # +-Arguments--------------------------------------------------------+
  249. # |
  250. # | args - options list, passed down to itk::Widget
  251. # |
  252. # +-Return value-----------------------------------------------------+
  253. # |
  254. # | an instance of the GUI contained within a frame
  255. # |
  256. # +------------------------------------------------------------------+
  257. itcl::body MeasTextGui::constructor {args} {
  258. array set pathArray [list]
  259. image create photo browseIcon -data {
  260. R0lGODlhEAAQAIMAAPwCBASCBMyaBPzynPz6nJxmBPzunPz2nPz+nPzSBPzq
  261. nPzmnPzinPzenAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARTEMhJq724hp1n
  262. 8MDXeaJgYtsnDANhvkJRCcZxEEiOJDIlKLWDbtebCBaGGmwZEzCQKxxCSgQ4
  263. Gb/BbciTCBpOoFbX9X6fChYhUZYU3vB4cXTxRwAAIf5oQ3JlYXRlZCBieSBC
  264. TVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4
  265. LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5j
  266. b20AOw==
  267. }
  268. image create photo pickFromListIcon -data {
  269. R0lGODlhEAAQAIMAAAQCBPwCBAQC/AQCjPz+/KSipPzerMRaBEQCBAAAAAAA
  270. AAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARDEMhJaQhA6D1E
  271. /wDGeeRgDhOhruyatjBRSIRxxOsMEAdC0BUZDcfSEYvDo3Bn++2Cxt7RqFxW
  272. hZiCdsvdhjCVsMQfAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJz
  273. aW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVz
  274. ZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7
  275. }
  276. # and make it always expand to fill its container
  277. grid columnconfigure $itk_interior 0 -weight 1
  278. grid rowconfigure $itk_interior 0 -weight 1
  279. # create a frame for the measure.txt filename and associated widgets
  280. itk_component add measureTxtFilenameFrame {
  281. frame $itk_interior.measureTxtFilenameFrame \
  282. -padx 2 -pady 2 -borderwidth 3 -relief raised
  283. }
  284. # create widgets for measure.txt filename and browsing
  285. itk_component add pickMeasListButton {
  286. button $itk_component(measureTxtFilenameFrame).pickMeasListButton \
  287. -command [itcl::code $this pickMeasListButtonCallback] \
  288. -image pickFromListIcon \
  289. -highlightthickness 0 \
  290. -takefocus 0 \
  291. -relief flat \
  292. -borderwidth 1 \
  293. -padx 1 \
  294. -pady 1
  295. }
  296. itk_component add browseMeasButton {
  297. button $itk_component(measureTxtFilenameFrame).browseMeasButton \
  298. -command [itcl::code $this browseMeasButtonCallback] \
  299. -image browseIcon \
  300. -highlightthickness 0 \
  301. -takefocus 0 \
  302. -relief flat \
  303. -borderwidth 1 \
  304. -padx 1 \
  305. -pady 1
  306. }
  307. # and give them balloon help
  308. DynamicHelp::register $itk_component(pickMeasListButton) \
  309. balloon "Pick a measure.txt file from list"
  310. DynamicHelp::register $itk_component(browseMeasButton) \
  311. balloon "Browse for a measure.txt file"
  312. itk_component add measFilenameEntry {
  313. iwidgets::entryfield $itk_component(measureTxtFilenameFrame).measFilenameEntry \
  314. -command [itcl::code $this parseMeasFilename] \
  315. -textvariable [itcl::scope measFilename]
  316. }
  317. grid $itk_component(pickMeasListButton) \
  318. -column 0 -row 0
  319. grid $itk_component(browseMeasButton) \
  320. -column 1 -row 0
  321. grid $itk_component(measFilenameEntry) \
  322. -column 2 -row 0 -sticky ew
  323. grid rowconfigure $itk_component(measureTxtFilenameFrame) 0 -weight 0
  324. grid columnconfigure $itk_component(measureTxtFilenameFrame) 0 -weight 0
  325. grid columnconfigure $itk_component(measureTxtFilenameFrame) 1 -weight 0
  326. grid columnconfigure $itk_component(measureTxtFilenameFrame) 2 -weight 1
  327. # create a frame for test number vendor and serial number
  328. itk_component add numVendSNFrame {
  329. frame $itk_interior.numVendSNFrame \
  330. -padx 2 -pady 2 -borderwidth 3 -relief raised
  331. }
  332. # create widgets for test number vendor and serial number
  333. itk_component add testNumLabel {
  334. label $itk_component(numVendSNFrame).testNumComboLabel -text {Test Number}
  335. }
  336. itk_component add testNumComboBox {
  337. ComboBox $itk_component(numVendSNFrame).testNumComboBox \
  338. -modifycmd [itcl::code $this comboBoxCallback]
  339. }
  340. # bind to the test number, so the footer is automagically updated as the test number
  341. # is edited
  342. bind $itk_component(testNumComboBox).e \
  343. <KeyRelease> [itcl::code $this comboBoxCallback]
  344. itk_component add vendorLabel {
  345. label $itk_component(numVendSNFrame).vendorLabel -text {Vendor}
  346. }
  347. itk_component add vendorEntry {
  348. iwidgets::entryfield $itk_component(numVendSNFrame).vendorEntry \
  349. -textvariable [itcl::scope vendor]
  350. }
  351. itk_component add snLabel {
  352. label $itk_component(numVendSNFrame).snLabel -text {Serial Number}
  353. }
  354. itk_component add snEntry {
  355. iwidgets::entryfield $itk_component(numVendSNFrame).snEntry \
  356. -textvariable [itcl::scope serialNumber]
  357. }
  358. # kludge to get background and foreground the same as iwidget entries
  359. $itk_component(testNumComboBox) configure \
  360. -entrybg [$itk_component(vendorEntry) cget -textbackground] \
  361. -foreground [$itk_component(vendorEntry) cget -foreground]
  362. # and grid them
  363. set gridCols -1
  364. grid $itk_component(testNumLabel) \
  365. -column [incr gridCols] -row 0 -sticky nes
  366. grid $itk_component(testNumComboBox) \
  367. -column [incr gridCols] -row 0 -sticky news
  368. grid $itk_component(vendorLabel) \
  369. -column [incr gridCols] -row 0 -sticky nes
  370. grid $itk_component(vendorEntry) \
  371. -column [incr gridCols] -row 0 -sticky ew
  372. grid $itk_component(snLabel) \
  373. -column [incr gridCols] -row 0 -sticky nes
  374. grid $itk_component(snEntry) \
  375. -column [incr gridCols] -row 0 -sticky ew
  376. grid rowconfigure $itk_component(numVendSNFrame) 0 -weight 0
  377. grid columnconfigure $itk_component(numVendSNFrame) 0 -weight 0
  378. grid columnconfigure $itk_component(numVendSNFrame) 1 -weight 1
  379. grid columnconfigure $itk_component(numVendSNFrame) 2 -weight 0
  380. grid columnconfigure $itk_component(numVendSNFrame) 3 -weight 1
  381. grid columnconfigure $itk_component(numVendSNFrame) 4 -weight 0
  382. grid columnconfigure $itk_component(numVendSNFrame) 5 -weight 1
  383. # these are the common options for all my scrolledtext widgets
  384. set textOptions "-width 0 \
  385. -height 0 \
  386. -hscrollmode dynamic \
  387. -wrap none \
  388. -vscrollmode dynamic \
  389. -visibleitems 80x5"
  390. # create four scrolled text widgets with labels
  391. itk_component add headerLabel {
  392. label $itk_interior.headerLabel -text Header
  393. }
  394. itk_component add headerText {
  395. eval iwidgets::scrolledtext $itk_interior.headerText $textOptions -state disabled
  396. }
  397. itk_component add footerLabel {
  398. label $itk_interior.footerLabel -text Footer
  399. }
  400. itk_component add footerText {
  401. eval iwidgets::scrolledtext $itk_interior.footerText $textOptions -state disabled
  402. }
  403. itk_component add dispNotesLabel {
  404. label $itk_interior.dispNotesLabel -text {Displayed Notes}
  405. }
  406. itk_component add dispNotesText {
  407. eval iwidgets::scrolledtext $itk_interior.dispNotesText $textOptions
  408. }
  409. itk_component add nonDispNotesLabel {
  410. label $itk_interior.nonDispNotesLabel -text {Non-Displayed Notes}
  411. }
  412. itk_component add nonDispNotesText {
  413. eval iwidgets::scrolledtext $itk_interior.nonDispNotesText $textOptions
  414. }
  415. # bind to the displayed notes and non-displayed notes text widget and update the
  416. # base classes variables with the current text
  417. bind [$itk_component(dispNotesText) component text] \
  418. <KeyRelease> \
  419. [itcl::code $this notesCallback dispNotesText DisplayedNotes]
  420. bind [$itk_component(nonDispNotesText) component text] \
  421. <KeyRelease> \
  422. [itcl::code $this notesCallback nonDispNotesText NonDisplayedNotes]
  423. # and grid them
  424. set gridRows -1
  425. grid $itk_component(measureTxtFilenameFrame) \
  426. -column 0 -row [incr gridRows] -sticky news
  427. grid $itk_component(numVendSNFrame) \
  428. -column 0 -row [incr gridRows] -sticky news
  429. grid $itk_component(headerLabel) \
  430. -column 0 -row [incr gridRows] -sticky news
  431. grid $itk_component(headerText) \
  432. -column 0 -row [incr gridRows] -sticky news
  433. grid $itk_component(footerLabel) \
  434. -column 0 -row [incr gridRows] -sticky news
  435. grid $itk_component(footerText) \
  436. -column 0 -row [incr gridRows] -sticky news
  437. grid $itk_component(dispNotesLabel) \
  438. -column 0 -row [incr gridRows] -sticky news
  439. grid $itk_component(dispNotesText) \
  440. -column 0 -row [incr gridRows] -sticky news
  441. grid $itk_component(nonDispNotesLabel) \
  442. -column 0 -row [incr gridRows] -sticky news
  443. grid $itk_component(nonDispNotesText) \
  444. -column 0 -row [incr gridRows] -sticky news
  445. # have the text widgets expand, all others not
  446. grid columnconfigure $itk_interior 0 -weight 1
  447. grid rowconfigure $itk_interior 0 -weight 0
  448. grid rowconfigure $itk_interior 1 -weight 0
  449. grid rowconfigure $itk_interior 2 -weight 0
  450. grid rowconfigure $itk_interior 3 -weight 1
  451. grid rowconfigure $itk_interior 4 -weight 0
  452. grid rowconfigure $itk_interior 5 -weight 1
  453. grid rowconfigure $itk_interior 6 -weight 0
  454. grid rowconfigure $itk_interior 7 -weight 1
  455. grid rowconfigure $itk_interior 8 -weight 0
  456. grid rowconfigure $itk_interior 9 -weight 1
  457. buildMeasListDialog
  458. eval itk_initialize $args
  459. }
  460. # +-Private Method---------------------------------------------------+
  461. # |
  462. # | MeasTextGui::browseMeasButtonCallback
  463. # |
  464. # +-Description------------------------------------------------------+
  465. # |
  466. # | Prompt for file, and parse if dialog not cancelled
  467. # |
  468. # +-Arguments--------------------------------------------------------+
  469. # |
  470. # +-Return value-----------------------------------------------------+
  471. # |
  472. # +------------------------------------------------------------------+
  473. itcl::body MeasTextGui::browseMeasButtonCallback {} {
  474. set fn [tk_getOpenFile]
  475. if {$fn != ""} {
  476. set measFilename $fn
  477. parseMeasFilename
  478. }
  479. }
  480. # +-Private Method---------------------------------------------------+
  481. # |
  482. # | MeasTextGui::parseMeasFilename
  483. # |
  484. # +-Description------------------------------------------------------+
  485. # |
  486. # | Call base class parser. Put header text into header widget and
  487. # | populate test number combo box
  488. # |
  489. # +-Arguments--------------------------------------------------------+
  490. # |
  491. # +-Return value-----------------------------------------------------+
  492. # |
  493. # +------------------------------------------------------------------+
  494. itcl::body MeasTextGui::parseMeasFilename {} {
  495. # call the base class parser
  496. [itcl::code $this MeasText::parseMeasFilename]
  497. # and put the header into the header text area
  498. $itk_component(headerText) configure -state normal
  499. $itk_component(headerText) delete 0.0 end
  500. $itk_component(headerText) insert 0.0 [join $header "\n"]
  501. $itk_component(headerText) configure -state disabled
  502. # and the test numbers into the combo box
  503. $itk_component(testNumComboBox) configure -values [getTestNumbers]
  504. # and clear the entry and the current test
  505. $itk_component(testNumComboBox).e delete 0 end
  506. comboBoxCallback
  507. }
  508. # +-Private Method---------------------------------------------------+
  509. # |
  510. # | MeasTextGui::comboBoxCallback
  511. # |
  512. # +-Description------------------------------------------------------+
  513. # |
  514. # | Responds to changes in the test number combo box. Puts the test
  515. # | text corrersponding to the current test number in the combobox
  516. # | entry field into the footer text widget.
  517. # |
  518. # +-Arguments--------------------------------------------------------+
  519. # |
  520. # +-Return value-----------------------------------------------------+
  521. # |
  522. # +------------------------------------------------------------------+
  523. itcl::body MeasTextGui::comboBoxCallback {} {
  524. $itk_component(footerText) configure -state normal
  525. $itk_component(footerText) delete 0.0 end
  526. set selection [$itk_component(testNumComboBox) getvalue]
  527. set currentTest [lindex [$itk_component(testNumComboBox) cget -values] $selection]
  528. if {$selection >= 0} {
  529. $itk_component(footerText) insert 0.0 \
  530. [join [lindex [getCurrentTest] 1] "\n"]
  531. }
  532. $itk_component(footerText) configure -state disabled
  533. }
  534. # +-Private Method---------------------------------------------------+
  535. # |
  536. # | MeasTextGui::notesCallback
  537. # |
  538. # +-Description------------------------------------------------------+
  539. # |
  540. # | As user updates text in the text widget (either displayed or
  541. # | non-displayed) get the text out of the text widget
  542. # | and stick it in the base class variable
  543. # |
  544. # +-Arguments--------------------------------------------------------+
  545. # |
  546. # | textWidget - the text widget the user is typing in
  547. # |
  548. # | baseClassNotes - the type of notes the user is typing in
  549. # |
  550. # +-Return value-----------------------------------------------------+
  551. # |
  552. # +------------------------------------------------------------------+
  553. itcl::body MeasTextGui::notesCallback {textWidget baseClassNotes} {
  554. set$baseClassNotes \
  555. [split [string trim [[$itk_component($textWidget) component text] get 0.0 end] "\n"] "\n"]
  556. }
  557. # +-Private Method---------------------------------------------------+
  558. # |
  559. # | MeasTextGui::measListDialogOKCallback
  560. # |
  561. # +-Description------------------------------------------------------+
  562. # |
  563. # | The measure.txt list has been OK'd. Get the selection and parse
  564. # | that file
  565. # |
  566. # +-Arguments--------------------------------------------------------+
  567. # |
  568. # +-Return value-----------------------------------------------------+
  569. # |
  570. # +------------------------------------------------------------------+
  571. itcl::body MeasTextGui::measListDialogOKCallback {args} {
  572. set tree $itk_component(measListDialogTree)
  573. set selection [lindex [array get pathArray [$tree selection get]] 1]
  574. # if there is one
  575. if {$selection != ""} {
  576. set measFilename $selection
  577. parseMeasFilename
  578. closeMeasListDialog
  579. }
  580. }
  581. # +-Private Method---------------------------------------------------+
  582. # |
  583. # | MeasTextGui::buildMeasListDialog
  584. # |
  585. # +-Description------------------------------------------------------+
  586. # |
  587. # | Create the dialog for presenting a list of measure.txt files to
  588. # | the user. Also provides a scan button to examine the design
  589. # | tree and update the list.
  590. # |
  591. # +-Arguments--------------------------------------------------------+
  592. # |
  593. # +-Return value-----------------------------------------------------+
  594. # |
  595. # +------------------------------------------------------------------+
  596. itcl::body MeasTextGui::buildMeasListDialog {} {
  597. itk_component add measListDialog {
  598. iwidgets::dialogshell $itk_interior.measListDialog \
  599. -title "Pick a *measure.txt file" \
  600. -modality application
  601. }
  602. $itk_component(measListDialog) add OK \
  603. -text OK \
  604. -command [itcl::code $this measListDialogOKCallback]
  605. $itk_component(measListDialog) add SCAN \
  606. -text SCAN \
  607. -command [itcl::code $this scanCallback]
  608. $itk_component(measListDialog) add CANCEL \
  609. -text CANCEL \
  610. -command [itcl::code $this closeMeasListDialog]
  611. set cs [$itk_component(measListDialog) childsite]
  612. itk_component add measListDialogTree {
  613. Tree $cs.tree
  614. }
  615. itk_component add measListDialogVScrollbar {
  616. scrollbar $cs.measListDialogVScrollbar \
  617. -orient vertical \
  618. -command "$itk_component(measListDialogTree) yview"
  619. }
  620. itk_component add measListDialogHScrollbar {
  621. scrollbar $cs.measListDialogHScrollbar \
  622. -orient horizontal \
  623. -command "$itk_component(measListDialogTree) xview"
  624. }
  625. $itk_component(measListDialogTree) configure \
  626. -xscrollcommand "$itk_component(measListDialogHScrollbar) set" \
  627. -yscrollcommand "$itk_component(measListDialogVScrollbar) set"
  628. grid $itk_component(measListDialogTree) -column 0 -row 0 -sticky news
  629. grid $itk_component(measListDialogVScrollbar) -column 1 -row 0 -sticky news
  630. grid $itk_component(measListDialogHScrollbar) -column 0 -row 1 -sticky news
  631. grid columnconfigure $cs 0 -weight 1
  632. grid rowconfigure $cs 0 -weight 1
  633. $itk_component(measListDialogTree) \
  634. bindText <Double-ButtonPress-1> [itcl::code $this measListDialogOKCallback]
  635. }
  636. # +-Private Method---------------------------------------------------+
  637. # |
  638. # | MeasTextGui::closeMeasListDialog
  639. # |
  640. # +-Description------------------------------------------------------+
  641. # |
  642. # | Guess
  643. # |
  644. # +-Arguments--------------------------------------------------------+
  645. # |
  646. # +-Return value-----------------------------------------------------+
  647. # |
  648. # +------------------------------------------------------------------+
  649. itcl::body MeasTextGui::closeMeasListDialog {} {
  650. $itk_component(measListDialog) deactivate
  651. }
  652. # +-Private Method---------------------------------------------------+
  653. # |
  654. # | MeasTextGui::pickMeasListButtonCallback
  655. # |
  656. # +-Description------------------------------------------------------+
  657. # |
  658. # | The user clicked the measList button. Build the list dialog.
  659. # | Populate the list in the dialog with the contents of the
  660. # | pathsFilename. Show the dialog
  661. # |
  662. # +-Arguments--------------------------------------------------------+
  663. # |
  664. # +-Return value-----------------------------------------------------+
  665. # |
  666. # +------------------------------------------------------------------+
  667. itcl::body MeasTextGui::pickMeasListButtonCallback {} {
  668. if {![winfo exists $itk_component(measListDialog)]} {
  669. buildMeasListDialog
  670. }
  671. set tree $itk_component(measListDialogTree)
  672. $tree selection clear
  673. $tree delete [$tree nodes root]
  674. ::fileutil::foreachLine line $pathsFilename {
  675. set splitline [split [string trim $line "/"] "/"]
  676. set program [lindex $splitline 2]
  677. set project [lindex $splitline 3]
  678. set measFile [lindex $splitline 5]
  679. if {$program != "" && $project != ""} {
  680. if {[array get programs $program] == ""} {
  681. set programs($program) 1
  682. $tree insert end root $program -text $program
  683. }
  684. if {[array get projects [set program][set project]] == ""} {
  685. set projects([set program][set project]) 1
  686. $tree insert end $program [set program][set project] -text $project
  687. }
  688. set nodeName [set program][set project][set measFile]
  689. $tree insert end [set program][set project] $nodeName -text $measFile
  690. set pathArray($nodeName) $line
  691. }
  692. }
  693. $itk_component(measListDialog) activate
  694. }
  695. # +-Private Method---------------------------------------------------+
  696. # |
  697. # | MeasTextGui::scanCallback
  698. # |
  699. # +-Description------------------------------------------------------+
  700. # |
  701. # | The scan button has been clicked in the measure.txt list dialog.
  702. # | Create a dialog with a bit of text and a progress bar.
  703. # | Start scanning the design tree and updating the progress bar
  704. # |
  705. # +-Arguments--------------------------------------------------------+
  706. # |
  707. # +-Return value-----------------------------------------------------+
  708. # |
  709. # +------------------------------------------------------------------+
  710. itcl::body MeasTextGui::scanCallback {} {
  711. # A dialog with text and a progress bar
  712. iwidgets::dialogshell .scanDialog -separator 0
  713. set cs [.scanDialog childsite]
  714. pack [ProgressBar $cs.pb -variable [itcl::scope result]]
  715. pack [label $cs.l -text "Scanning the design tree\nfor measure.txt files"]
  716. .scanDialog center
  717. .scanDialog activate
  718. # start scanning the design tree
  719. after 1 [itcl::code $this scanDesignTree]
  720. # and updating the progress bar
  721. after 10 [itcl::code $this updateScanningProgress]
  722. }
  723. # +-Private Method---------------------------------------------------+
  724. # |
  725. # | MeasTextGui::scanDesignTree
  726. # |
  727. # +-Description------------------------------------------------------+
  728. # |
  729. # | Init the variables used for scanning and schedule the method
  730. # | used to do the scanning
  731. # |
  732. # +-Arguments--------------------------------------------------------+
  733. # |
  734. # +-Return value-----------------------------------------------------+
  735. # |
  736. # +------------------------------------------------------------------+
  737. itcl::body MeasTextGui::scanDesignTree {} {
  738. set designTreeIndex 0
  739. set designTreeMeasTextList [list]
  740. if {![catch {glob //sppdgfs/designs/*} {designTree}]} {
  741. after 10 [itcl::code $this scanningDesignTree]
  742. }
  743. }
  744. # +-Private Method---------------------------------------------------+
  745. # |
  746. # | MeasTextGui::scanningDesignTree
  747. # |
  748. # +-Description------------------------------------------------------+
  749. # |
  750. # | Go down one level into the design tree and scan for measure.txt
  751. # | files, schedule another iteration and then return to the event loop.
  752. # |
  753. # +-Arguments--------------------------------------------------------+
  754. # |
  755. # +-Return value-----------------------------------------------------+
  756. # |
  757. # +------------------------------------------------------------------+
  758. itcl::body MeasTextGui::scanningDesignTree {} {
  759. if {$designTreeIndex < [llength $designTree]} {
  760. if {![catch {glob [lindex $designTree $designTreeIndex]/*/docs/*measure.txt} {list}]} {
  761. foreach file $list {
  762. lappend designTreeMeasTextList $file
  763. }
  764. }
  765. incr designTreeIndex
  766. after 10 [itcl::code $this scanningDesignTree]
  767. }
  768. }
  769. # +-Private Method---------------------------------------------------+
  770. # |
  771. # | MeasTextGui::updateScanningProgress
  772. # |
  773. # +-Description------------------------------------------------------+
  774. # |
  775. # | Update the progress bar with how far through scanning the design
  776. # | tree we are
  777. # |
  778. # +-Arguments--------------------------------------------------------+
  779. # |
  780. # +-Return value-----------------------------------------------------+
  781. # |
  782. # +------------------------------------------------------------------+
  783. itcl::body MeasTextGui::updateScanningProgress {} {
  784. # Get % of scanning
  785. catch {expr {$designTreeIndex / ([llength $designTree] * 1.0) * 100}} {result}
  786. # if not done schedule another check
  787. if {$designTreeIndex < [llength $designTree]} {
  788. after 400 [itcl::code $this updateScanningProgress]
  789. } else {
  790. # done scanning, so nuke the progress dialog
  791. destroy .scanDialog
  792. # create a temp file
  793. set tmpFilename .measTextGui[clock format [clock seconds] -format "%Y%m%d%H%M%S"]
  794. # and write the measure.txt filenames there
  795. set tmpFile [open $tmpFilename w]
  796. foreach line [lsort $designTreeMeasTextList] {
  797. puts $tmpFile "\/[set line]"
  798. }
  799. close $tmpFile
  800. # move the temp file to the real file
  801. file rename -force $tmpFilename $pathsFilename
  802. # and simulate the user clicking the measList button
  803. pickMeasListButtonCallback
  804. }
  805. }
  806. # a procedure with the same name as the mega-widget class,
  807. # but with all lower-case letters, can be used to create mega-widgets.
  808. # This adheres to the Tk convention for widget creation commands
  809. proc meastextgui {pathName args} {
  810. uplevel MeasTextGui $pathName $args
  811. }
  812. itcl::class MeasTextGuiToplevel {
  813. inherit MeasTextGui
  814. method constructor {args} {
  815. set ds [iwidgets::Dialogshell .dialog_[string map {. ""} $itk_interior]_dialogShell]
  816. grid $itk_interior -in $ds -row 0 -column 0 -sticky news
  817. $ds activate
  818. }
  819. variable ds
  820. }
  821. proc exampleUsingMeasTextGui {} {
  822. # create a bwidget dialog
  823. Dialog .dialog -title "Measure Information" -default 1 -cancel 0 -modal none
  824. # get the frame and create a MeasTextGui in it
  825. MeasTextGui [.dialog getframe].measTextGui
  826. pack [.dialog getframe].measTextGui
  827. # Create a close button and show the dialog
  828. .dialog add -text Close -command {.dialog withdraw}
  829. .dialog draw
  830. }