gui.tcl 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832
  1. #!/usr/bin/env tclsh
  2. #
  3. # Copyright (c) 2015-2017 OpenIndex.de
  4. #
  5. # Permission is hereby granted, free of charge, to any person obtaining a copy
  6. # of this software and associated documentation files (the "Software"), to deal
  7. # in the Software without restriction, including without limitation the rights
  8. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. # copies of the Software, and to permit persons to whom the Software is
  10. # furnished to do so, subject to the following conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included in
  13. # all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. # THE SOFTWARE.
  22. #
  23. package require scrolledframe
  24. #
  25. # Main application window.
  26. #
  27. namespace eval ::support::ApplicationWindow {
  28. variable ID
  29. variable IMG_SIDEBAR
  30. variable IMG_STATUS_CONNECTING
  31. variable IMG_STATUS_CONNECTED
  32. variable IMG_STATUS_DISCONNECTED
  33. variable IMG_STATUS_WARNING
  34. variable ADDRESS
  35. variable PORT
  36. variable SSH
  37. # Create the window.
  38. proc open {} {
  39. variable ID "."
  40. variable ADDRESS $::support::session::VNC_HOST
  41. variable PORT $::support::session::VNC_PORT
  42. variable SSH $::support::session::SSH_ENABLED
  43. # Load images.
  44. variable IMG_SIDEBAR [::support::utils::load_image_file sidebar.png]
  45. variable IMG_STATUS_CONNECTING [::support::utils::load_image_file icon_connect_creating.png]
  46. variable IMG_STATUS_CONNECTED [::support::utils::load_image_file icon_connect_established.png]
  47. variable IMG_STATUS_DISCONNECTED [::support::utils::load_image_file icon_connect_no.png]
  48. variable IMG_STATUS_WARNING [::support::utils::load_image_file icon_warning.png]
  49. # Load settings.
  50. set windowWidth [::support::Config::getGuiValue "application-window-width" 500]
  51. set windowHeight [::support::Config::getGuiValue "application-window-height" 300]
  52. set windowMinWidth [::support::Config::getGuiValue "application-window-min-width" 450]
  53. set windowMinHeight [::support::Config::getGuiValue "application-window-min-height" 250]
  54. set background [::support::Config::getGuiValue "background" "white"]
  55. set statusBackground [::support::Config::getGuiValue "status-background" "#f0f0f0"]
  56. set buttonOptions [::support::Config::getGuiButtonOptions]
  57. set checkbuttonOptions [::support::Config::getGuiCheckbuttonOptions]
  58. set entryOptions [::support::Config::getGuiEntryOptions]
  59. set labelOptions [::support::Config::getGuiLabelOptions]
  60. set titleOptions [::support::Config::getGuiTitleOptions]
  61. set statusOptions [::support::Config::getGuiStatusOptions]
  62. set companyName [::support::Config::getAboutValue "company-name"]
  63. # Init window.
  64. wm title $ID $::support::TITLE
  65. wm iconphoto $ID $::support::ICON
  66. wm minsize $ID $windowMinWidth $windowMinHeight
  67. # Center the window on the screen.
  68. ::support::utils::center_window $ID $windowWidth $windowHeight
  69. # Create main frame.
  70. frame .frm -background $background
  71. pack .frm -fill both -expand 1
  72. grid rowconfigure .frm 3 -weight 1
  73. grid columnconfigure .frm 1 -weight 1
  74. # Create sidebar.
  75. canvas .frm.sidebar -borderwidth 0 -highlightthickness 0 -background $background -width [image width $IMG_SIDEBAR]
  76. .frm.sidebar create image 0 0 -image $IMG_SIDEBAR -anchor nw
  77. grid .frm.sidebar -in .frm -padx 0 -pady 0 -row 0 -column 0 -rowspan 4 -sticky nw
  78. # Create title label.
  79. label .frm.title -text "$::support::TITLE $::support::VERSION" -anchor w {*}$titleOptions
  80. grid .frm.title -in .frm -row 0 -column 1 -padx {10 10} -pady {10 10} -sticky nwe
  81. # Create description label.
  82. if {$companyName != ""} {
  83. set description [_ "This application provides access to your desktop for the support staff of %s." $companyName]
  84. } else {
  85. set description [_ "This application provides access to your desktop for our support staff."]
  86. }
  87. label .frm.description -text $description -justify left -anchor w {*}$labelOptions
  88. grid .frm.description -in .frm -row 1 -column 1 -padx {10 10} -pady {0 10} -sticky nwe
  89. bind .frm.description <Configure> { %W configure -wraplength [expr { %w - 4 }] }
  90. # Create options form.
  91. frame .frm.options -background $background
  92. grid .frm.options -in .frm -row 2 -column 1 -padx 10 -pady 10 -sticky nwe
  93. grid columnconfigure .frm.options 1 -weight 1
  94. # Create address field.
  95. label .frm.options.addressLabel -text [_ "Address"] -anchor w {*}$labelOptions
  96. entry .frm.options.address -width 10 -textvariable ::support::ApplicationWindow::ADDRESS {*}$entryOptions
  97. bind .frm.options.address <Return> "::support::ApplicationWindow::onConnect"
  98. grid .frm.options.addressLabel -in .frm.options -row 0 -column 0 -padx {0 5} -pady {0 5} -sticky e
  99. grid .frm.options.address -in .frm.options -row 0 -column 1 -padx {0 5} -pady {0 5} -sticky ew
  100. # Create port field.
  101. label .frm.options.portLabel -text [_ "Port"] -anchor w {*}$labelOptions
  102. entry .frm.options.port -width 5 -textvariable ::support::ApplicationWindow::PORT {*}$entryOptions
  103. grid .frm.options.portLabel -in .frm.options -row 0 -column 2 -padx {0 5} -pady {0 5} -sticky e
  104. grid .frm.options.port -in .frm.options -row 0 -column 3 -padx {0 0} -pady {0 5} -sticky ew
  105. # Create ssh checkbox.
  106. checkbutton .frm.options.ssh -text [_ "Enable SSH encryption."] -variable ::support::ApplicationWindow::SSH {*}$checkbuttonOptions
  107. grid .frm.options.ssh -in .frm.options -row 1 -column 0 -columnspan 2 -sticky w
  108. # Create options button.
  109. button .frm.options.extended -text [_ "Extended…"] -anchor w -command ::support::ApplicationWindow::onSettingsDialog {*}$buttonOptions
  110. grid .frm.options.extended -in .frm.options -row 1 -column 2 -columnspan 2 -sticky e
  111. # Create button bar.
  112. frame .frm.buttons -background $background
  113. grid .frm.buttons -in .frm -row 4 -column 0 -columnspan 2 -padx 10 -pady 10 -sticky nwe
  114. grid columnconfigure .frm.buttons 2 -weight 1
  115. # Create quit button.
  116. button .frm.buttons.quit -text [_ "Quit"] -anchor e -command ::support::ApplicationWindow::onClose {*}$buttonOptions
  117. grid .frm.buttons.quit -in .frm.buttons -row 0 -column 0 -sticky e
  118. # Create about button.
  119. button .frm.buttons.about -text [_ "About"] -anchor e -command ::support::ApplicationWindow::onAboutDialog {*}$buttonOptions
  120. grid .frm.buttons.about -in .frm.buttons -row 0 -column 1 -padx {5 0} -sticky e
  121. # Create connect button.
  122. button .frm.buttons.connect -text [_ "Connect"] -anchor w -command ::support::ApplicationWindow::onConnect {*}$buttonOptions
  123. grid .frm.buttons.connect -in .frm.buttons -row 0 -column 3 -sticky w
  124. # Create disconnect button.
  125. button .frm.buttons.disconnect -text [_ "Disconnect"] -anchor w -command ::support::ApplicationWindow::onDisconnect {*}$buttonOptions
  126. grid .frm.buttons.disconnect -in .frm.buttons -row 0 -column 4 -padx {5 0} -sticky w
  127. # Create status bar.
  128. frame .frm.statusBar -padx 5 -pady 5 -background $statusBackground
  129. grid .frm.statusBar -in .frm -row 5 -column 0 -columnspan 2 -sticky nwe
  130. grid columnconfigure .frm.statusBar 0 -weight 1
  131. # Create status label.
  132. label .frm.statusBar.statusLabel -anchor w {*}$statusOptions
  133. grid .frm.statusBar.statusLabel -in .frm.statusBar -row 0 -column 0 -sticky w
  134. # Create status icon.
  135. label .frm.statusBar.statusIcon -anchor e -background $statusBackground
  136. grid .frm.statusBar.statusIcon -in .frm.statusBar -row 0 -column 1 -sticky e
  137. # Register events.
  138. wm protocol $ID WM_DELETE_WINDOW "::support::ApplicationWindow::onClose"
  139. bind $ID <Escape> "::support::ApplicationWindow::onClose"
  140. # Set focus on the address field.
  141. focus .frm.options.address
  142. # Create an empty main menu for Mac OS X.
  143. if {[::support::utils::is_darwin]} {
  144. $ID configure -menu [menu .menubar]
  145. }
  146. # Do final initializations.
  147. setStatusWelcome
  148. }
  149. proc onAboutDialog {} {
  150. ::support::AboutWindow::open
  151. }
  152. proc onClose {} {
  153. ::support::shutdown
  154. }
  155. proc onConnect {} {
  156. variable ID
  157. variable ADDRESS
  158. variable PORT
  159. variable SSH
  160. # Put settings into the session.
  161. set ::support::session::VNC_HOST [string trim $ADDRESS]
  162. set ::support::session::VNC_PORT [string trim $PORT]
  163. set ::support::session::SSH_ENABLED $SSH
  164. # Validate settings before starting a VNC connection.
  165. set errors [::support::session::validate]
  166. if {[llength $errors] > 0} {
  167. tk_messageBox -parent $ID -type ok -icon error -title [_ "Error"] -message [_ "Can't open connection!"] -detail [join $errors "\n"]
  168. return
  169. }
  170. # Start VNC session.
  171. ::support::connect
  172. }
  173. proc onDisconnect {} {
  174. .frm.buttons.disconnect configure -state disabled
  175. ::support::disconnect
  176. }
  177. proc onSettingsDialog {} {
  178. ::support::SettingsWindow::open
  179. }
  180. proc setFormDisabled {} {
  181. .frm.options.addressLabel configure -state disabled
  182. .frm.options.address configure -state disabled
  183. .frm.options.portLabel configure -state disabled
  184. .frm.options.port configure -state disabled
  185. .frm.options.ssh configure -state disabled
  186. .frm.options.extended configure -state disabled
  187. }
  188. proc setFormEnabled {} {
  189. .frm.options.addressLabel configure -state normal
  190. .frm.options.address configure -state normal
  191. .frm.options.portLabel configure -state normal
  192. .frm.options.port configure -state normal
  193. .frm.options.ssh configure -state normal
  194. .frm.options.extended configure -state normal
  195. }
  196. proc setStatusConnected {{txt ""}} {
  197. variable IMG_STATUS_CONNECTED
  198. if {$txt == ""} {
  199. set txt [_ "Connection is established."]
  200. }
  201. .frm.statusBar.statusLabel configure -text $txt
  202. .frm.statusBar.statusIcon configure -image $IMG_STATUS_CONNECTED
  203. .frm.buttons.connect configure -state disabled
  204. .frm.buttons.disconnect configure -state normal
  205. setFormDisabled
  206. }
  207. proc setStatusConnecting {{txt ""}} {
  208. variable IMG_STATUS_CONNECTING
  209. if {$txt == ""} {
  210. set txt [_ "Establishing a connection…"]
  211. }
  212. .frm.statusBar.statusLabel configure -text $txt
  213. .frm.statusBar.statusIcon configure -image $IMG_STATUS_CONNECTING
  214. .frm.buttons.connect configure -state disabled
  215. .frm.buttons.disconnect configure -state normal
  216. setFormDisabled
  217. }
  218. proc setStatusDisconnected {{txt ""}} {
  219. variable IMG_STATUS_DISCONNECTED
  220. if {$txt == ""} {
  221. set txt [_ "The connection was closed."]
  222. }
  223. .frm.statusBar.statusLabel configure -text $txt
  224. .frm.statusBar.statusIcon configure -image $IMG_STATUS_DISCONNECTED
  225. .frm.buttons.connect configure -state normal
  226. .frm.buttons.disconnect configure -state disabled
  227. setFormEnabled
  228. }
  229. proc setStatusError {{txt ""}} {
  230. variable IMG_STATUS_WARNING
  231. if {$txt == ""} {
  232. set txt [_ "An error occured."]
  233. }
  234. .frm.statusBar.statusLabel configure -text $txt
  235. .frm.statusBar.statusIcon configure -image $IMG_STATUS_WARNING
  236. .frm.buttons.connect configure -state normal
  237. .frm.buttons.disconnect configure -state disabled
  238. setFormEnabled
  239. }
  240. proc setStatusWelcome {{txt ""}} {
  241. variable IMG_STATUS_DISCONNECTED
  242. if {$txt == ""} {
  243. set txt [_ "Welcome to remote maintenance."]
  244. }
  245. .frm.statusBar.statusLabel configure -text $txt
  246. .frm.statusBar.statusIcon configure -image $IMG_STATUS_DISCONNECTED
  247. .frm.buttons.connect configure -state normal
  248. .frm.buttons.disconnect configure -state disabled
  249. setFormEnabled
  250. }
  251. }
  252. #
  253. # About dialog window.
  254. #
  255. namespace eval ::support::AboutWindow {
  256. variable ID
  257. variable IMG_SIDEBAR ""
  258. # Create the window.
  259. proc open {} {
  260. variable ID ".about"
  261. # Load images.
  262. variable IMG_SIDEBAR
  263. if {$IMG_SIDEBAR == ""} {
  264. set IMG_SIDEBAR [::support::utils::load_image_file sidebar_about.png]
  265. }
  266. # Load settings.
  267. set windowWidth [::support::Config::getGuiValue "about-window-width" 550]
  268. set windowHeight [::support::Config::getGuiValue "about-window-height" 350]
  269. set windowMinWidth [::support::Config::getGuiValue "about-window-min-width" 450]
  270. set windowMinHeight [::support::Config::getGuiValue "about-window-min-height" 250]
  271. set background [::support::Config::getGuiValue "background" "white"]
  272. set companyName [::support::Config::getAboutValue "company-name"]
  273. set companyWebsite [::support::Config::getAboutValue "company-website"]
  274. set companyWebsiteTitle [::support::Config::getAboutValue "company-website-title" [_ "Company"]]
  275. set repository [::support::Config::getAboutValue "repository"]
  276. set authors [::support::Config::getAboutValue "authors"]
  277. set buttonOptions [::support::Config::getGuiButtonOptions]
  278. # Init window.
  279. toplevel $ID
  280. wm title $ID [_ "About this program"]
  281. wm iconphoto $ID $::support::ICON
  282. wm minsize $ID $windowMinWidth $windowMinHeight
  283. # Place the window below the application window.
  284. set x [expr {([winfo rootx $::support::ApplicationWindow::ID] + 20)}]
  285. set y [expr {([winfo rooty $::support::ApplicationWindow::ID] + 20)}]
  286. wm geometry $ID ${windowWidth}x${windowHeight}+${x}+${y}
  287. # Create main frame.
  288. frame .about.frm -background $background
  289. pack .about.frm -fill both -expand 1
  290. grid columnconfigure .about.frm 1 -weight 1
  291. grid rowconfigure .about.frm 0 -weight 1
  292. # Create sidebar.
  293. canvas .about.frm.sidebar -borderwidth 0 -highlightthickness 0 -background $background -width [image width $IMG_SIDEBAR]
  294. .about.frm.sidebar create image 0 0 -image $IMG_SIDEBAR -anchor nw
  295. grid .about.frm.sidebar -in .about.frm -padx 0 -pady 0 -row 0 -column 0 -rowspan 4 -sticky nw
  296. # Create text area.
  297. set txt ".about.frm.text"
  298. text $txt -height 20 -width 50 -background $background -padx 10 -pady 10 -highlightthickness 0 -relief flat -wrap word -yscrollcommand ".about.frm.textScroller set"
  299. grid $txt -in .about.frm -row 0 -column 1 -rowspan 2 -sticky nsew
  300. # Create text styles.
  301. $txt tag configure title -font [::support::Config::getGuiTitleFont]
  302. $txt tag configure subtitle -font [::support::Config::getGuiSubtitleFont]
  303. $txt tag configure default -font [::support::Config::getGuiLabelFont]
  304. $txt tag configure tiny -font "TkDefaultFont 4"
  305. # Insert text into text area.
  306. $txt insert end "$::support::TITLE $::support::VERSION" "title"
  307. $txt insert end "\n\n" "tiny"
  308. $txt insert end [_ "This application provides access to your desktop for our support staff."] "default"
  309. $txt insert end " " "default"
  310. $txt insert end [_ "Our support staff will tell you the required settings in order to build up a connection for remote maintenance."] "default"
  311. # Add notes about the company.
  312. if {$companyName != ""} {
  313. $txt insert end "\n\n" "tiny"
  314. $txt insert end [_ "This software is based on the free and open Remote Support Tool and was modified for %s." $companyName] "default"
  315. $txt insert end " " "default"
  316. $txt insert end [_ "Please contact %s for any questions or problems according to this software." $companyName] "default"
  317. }
  318. $txt insert end "\n\n\n" "tiny"
  319. $txt insert end [_ "Authors"] "subtitle"
  320. $txt insert end "\n\n" "tiny"
  321. $txt insert end "• Andreas Rudolph & Walter Wagner (OpenIndex.de)" "default"
  322. # Add further authors.
  323. if {$authors != ""} {
  324. foreach author [split $authors ";"] {
  325. $txt insert end "\n• [string trim $author]" "default"
  326. }
  327. }
  328. $txt insert end "\n\n\n" "tiny"
  329. $txt insert end [_ "Translators"] "subtitle"
  330. $txt insert end "\n\n" "tiny"
  331. $txt insert end [format "• %s: Andreas Rudolph & Walter Wagner" [_ "German"]] "default"
  332. $txt insert end "\n\n\n" "tiny"
  333. $txt insert end [_ "Internal components"] "subtitle"
  334. $txt insert end "\n\n" "tiny"
  335. $txt insert end [_ "The following third party components were integrated:"] "default"
  336. $txt insert end "\n\n" "tiny"
  337. $txt insert end [format "• Tcl/Tk %s (BSD)\n" [info patchlevel]] "default"
  338. $txt insert end [format "• %s %s (%s)\n" $::support::session::VNC_APP_NAME $::support::session::VNC_APP_VERSION $::support::session::VNC_APP_LICENSE] "default"
  339. if {$::support::session::SSH_APP_PROVIDED == 1} {
  340. $txt insert end [format "• %s %s (%s)\n" $::support::session::SSH_APP_NAME $::support::session::SSH_APP_VERSION $::support::session::SSH_APP_LICENSE] "default"
  341. }
  342. $txt insert end "• Crystal Clear Icons (LGPL)" "default"
  343. $txt insert end "\n\n\n" "tiny"
  344. $txt insert end [_ "Created with"] "subtitle"
  345. $txt insert end "\n\n" "tiny"
  346. $txt insert end [_ "The application was created with:"] "default"
  347. $txt insert end "\n\n" "tiny"
  348. $txt insert end "• TclKit\n" "default"
  349. if {[::support::utils::is_windows]} {
  350. $txt insert end "• Resource Hacker" "default"
  351. }
  352. $txt insert end "\n\n\n" "tiny"
  353. $txt insert end [_ "License"] "subtitle"
  354. $txt insert end "\n\n" "tiny"
  355. # Write LICENSE.txt into the text area.
  356. set fp [::open [file join $::support::DATA_DIR "LICENSE.txt"] r]
  357. set file_data [read $fp]
  358. close $fp
  359. set data [split $file_data "\n"]
  360. set prevLineEmpty 0
  361. foreach line $data {
  362. if {$prevLineEmpty == 1} {
  363. $txt insert end "\n\n" "tiny"
  364. }
  365. $txt insert end $line "default"
  366. $txt insert end " " "default"
  367. if {$line == ""} {
  368. set prevLineEmpty 1
  369. } else {
  370. set prevLineEmpty 0
  371. }
  372. }
  373. # Disable text area to avoid further modifications.
  374. $txt configure -state disabled
  375. # Create text scroller.
  376. scrollbar .about.frm.textScroller -command "$txt yview"
  377. grid .about.frm.textScroller -in .about.frm -row 0 -column 2 -rowspan 2 -sticky nsew
  378. # Create button bar.
  379. frame .about.frm.buttons -background $background
  380. grid .about.frm.buttons -in .about.frm -row 1 -column 0 -padx 10 -pady {0 10} -sticky swe
  381. grid columnconfigure .about.frm.buttons 0 -weight 1
  382. if {$companyWebsite != ""} {
  383. button .about.frm.buttons.company -text $companyWebsiteTitle -anchor center -command ::support::AboutWindow::onOpenCompany {*}$buttonOptions
  384. grid .about.frm.buttons.company -in .about.frm.buttons -row 0 -column 0 -sticky we
  385. }
  386. if {$repository != ""} {
  387. button .about.frm.buttons.repository -text [_ "Source code"] -anchor center -command ::support::AboutWindow::onOpenRepository {*}$buttonOptions
  388. grid .about.frm.buttons.repository -in .about.frm.buttons -row 1 -column 0 -pady {5 0} -sticky we
  389. }
  390. button .about.frm.buttons.close -text [_ "Close"] -anchor center -command ::support::AboutWindow::onClose {*}$buttonOptions
  391. grid .about.frm.buttons.close -in .about.frm.buttons -row 2 -column 0 -pady {5 0} -sticky we
  392. # Register events.
  393. wm protocol $ID WM_DELETE_WINDOW "::support::AboutWindow::onClose"
  394. bind $ID <Escape> "::support::AboutWindow::onClose"
  395. # Make modal window.
  396. ::support::utils::modal_init $ID
  397. }
  398. proc onClose {} {
  399. variable ID
  400. ::support::utils::modal_release $ID
  401. }
  402. proc onOpenCompany {} {
  403. set website [::support::Config::getAboutValue "company-website"]
  404. if {$website != ""} {
  405. ::support::utils::open_browser $website
  406. } else {
  407. puts "No company website was specified!"
  408. }
  409. }
  410. proc onOpenRepository {} {
  411. set website [::support::Config::getAboutValue "repository"]
  412. if {$website != ""} {
  413. ::support::utils::open_browser $website
  414. } else {
  415. puts "No repository website was specified!"
  416. }
  417. }
  418. }
  419. #
  420. # Settings dialog window.
  421. #
  422. namespace eval ::support::SettingsWindow {
  423. variable ID
  424. variable ID_OPTIONS
  425. variable IMG_SIDEBAR ""
  426. variable VNC_EXE
  427. variable VNC_PARAMETERS
  428. variable SSH_EXE
  429. variable SSH_PORT
  430. variable SSH_USER
  431. variable SSH_KEY
  432. variable USE_PROVIDED_SSH_APP
  433. variable USE_PROVIDED_SSH_KEY
  434. variable USE_PROVIDED_VNC_APP
  435. # Create the window.
  436. proc open {} {
  437. variable ID ".settings"
  438. variable VNC_EXE $::support::session::VNC_EXE
  439. variable VNC_PARAMETERS $::support::session::VNC_PARAMETERS
  440. variable SSH_EXE $::support::session::SSH_EXE
  441. variable SSH_PORT $::support::session::SSH_PORT
  442. variable SSH_USER $::support::session::SSH_USER
  443. variable SSH_KEY $::support::session::SSH_KEY
  444. variable USE_PROVIDED_SSH_APP $::support::session::USE_PROVIDED_SSH_APP
  445. variable USE_PROVIDED_SSH_KEY $::support::session::USE_PROVIDED_SSH_KEY
  446. variable USE_PROVIDED_VNC_APP $::support::session::USE_PROVIDED_VNC_APP
  447. # Load images.
  448. variable IMG_SIDEBAR
  449. if {$IMG_SIDEBAR == ""} {
  450. set IMG_SIDEBAR [::support::utils::load_image_file sidebar_settings.png]
  451. }
  452. # Load settings.
  453. set windowWidth [::support::Config::getGuiValue "settings-window-width" 550]
  454. set windowHeight [::support::Config::getGuiValue "settings-window-height" 350]
  455. set windowMinWidth [::support::Config::getGuiValue "settings-window-min-width" 450]
  456. set windowMinHeight [::support::Config::getGuiValue "settings-window-min-height" 250]
  457. set background [::support::Config::getGuiValue "background" "white"]
  458. set buttonOptions [::support::Config::getGuiButtonOptions]
  459. set checkbuttonOptions [::support::Config::getGuiCheckbuttonOptions]
  460. set entryOptions [::support::Config::getGuiEntryOptions]
  461. set labelOptions [::support::Config::getGuiLabelOptions]
  462. set subtitleOptions [::support::Config::getGuiSubtitleOptions]
  463. # Init window.
  464. toplevel $ID
  465. wm title $ID [_ "Extended Settings"]
  466. wm iconphoto $ID $::support::ICON
  467. wm minsize $ID $windowMinWidth $windowMinHeight
  468. # Place the window below the application window.
  469. set x [expr {([winfo rootx $::support::ApplicationWindow::ID] + 20)}]
  470. set y [expr {([winfo rooty $::support::ApplicationWindow::ID] + 20)}]
  471. wm geometry $ID ${windowWidth}x${windowHeight}+${x}+${y}
  472. # Create main frame.
  473. frame .settings.frm -background $background
  474. pack .settings.frm -fill both -expand 1
  475. grid columnconfigure .settings.frm 1 -weight 1
  476. grid rowconfigure .settings.frm 1 -weight 1
  477. # Create sidebar.
  478. canvas .settings.frm.sidebar -borderwidth 0 -highlightthickness 0 -background $background -width [image width $IMG_SIDEBAR]
  479. .settings.frm.sidebar create image 0 0 -image $IMG_SIDEBAR -anchor nw
  480. grid .settings.frm.sidebar -in .settings.frm -padx 0 -pady 0 -row 0 -column 0 -rowspan 4 -sticky nw
  481. # Create options frame.
  482. #variable ID_OPTIONS ".settings.frm.options"
  483. #frame $ID_OPTIONS -background $background
  484. #grid $ID_OPTIONS -in .settings.frm -row 0 -column 1 -rowspan 2 -padx {10 10} -pady {10 5} -sticky nsew
  485. #grid columnconfigure $ID_OPTIONS 1 -weight 1
  486. # Create scrolling options frame.
  487. ::scrolledframe::scrolledframe .settings.frm.options -height 150 -width 100 -background $background -yscrollcommand {.settings.frm.vs set} -fill x
  488. scrollbar .settings.frm.vs -command {.settings.frm.options yview}
  489. #scrollbar .settings.frm.hs -command {.settings.frm.options xview} -orient horizontal
  490. grid .settings.frm.options -in .settings.frm -row 0 -column 1 -rowspan 2 -padx {10 10} -pady {10 5} -sticky nsew
  491. grid .settings.frm.vs -in .settings.frm -row 0 -column 2 -rowspan 2 -sticky ns
  492. variable ID_OPTIONS .settings.frm.options.scrolled
  493. $ID_OPTIONS configure -background $background
  494. grid columnconfigure $ID_OPTIONS 1 -weight 1
  495. # Create VNC title.
  496. label $ID_OPTIONS.vncTitle -text [format "%s (%s)" [_ "Settings for VNC"] $::support::session::VNC_APP_NAME] -anchor w {*}$subtitleOptions
  497. grid $ID_OPTIONS.vncTitle -in $ID_OPTIONS -row 0 -column 0 -columnspan 3 -padx {0 0} -pady {0 5} -sticky nwe
  498. # Create VNC application field.
  499. label $ID_OPTIONS.vncAppLabel -text [_ "Application"] -anchor w {*}$labelOptions
  500. entry $ID_OPTIONS.vncApp -width 10 -state readonly -textvariable ::support::SettingsWindow::VNC_EXE {*}$entryOptions
  501. button $ID_OPTIONS.vncAppButton -text [_ "Select"] -padx 0 -pady 0 -anchor center -command ::support::SettingsWindow::onSelectVncPath {*}$buttonOptions
  502. grid $ID_OPTIONS.vncAppLabel -in $ID_OPTIONS -row 1 -column 0 -padx {0 5} -pady {0 3} -sticky e
  503. grid $ID_OPTIONS.vncApp -in $ID_OPTIONS -row 1 -column 1 -padx {0 5} -pady {0 3} -sticky ew
  504. grid $ID_OPTIONS.vncAppButton -in $ID_OPTIONS -row 1 -column 2 -padx {0 0} -pady {0 3} -sticky ew
  505. # Create VNC parameters field for non Windows systems.
  506. if {![::support::utils::is_windows]} {
  507. label $ID_OPTIONS.vncParamsLabel -text [_ "Parameters"] -anchor w {*}$labelOptions
  508. entry $ID_OPTIONS.vncParams -width 10 -textvariable ::support::SettingsWindow::VNC_PARAMETERS {*}$entryOptions
  509. grid $ID_OPTIONS.vncParamsLabel -in $ID_OPTIONS -row 2 -column 0 -padx {0 5} -pady {0 3} -sticky e
  510. grid $ID_OPTIONS.vncParams -in $ID_OPTIONS -row 2 -column 1 -columnspan 2 -padx {0 3} -pady {0 3} -sticky ew
  511. }
  512. # Create internal VNC application field.
  513. checkbutton $ID_OPTIONS.vncAppInternal -text [_ "Use provided VNC application."] -variable ::support::SettingsWindow::USE_PROVIDED_VNC_APP -command ::support::SettingsWindow::onUpdateVncPath {*}$checkbuttonOptions
  514. grid $ID_OPTIONS.vncAppInternal -in $ID_OPTIONS -row 3 -column 1 -columnspan 2 -padx {0 0} -pady {0 3} -sticky w
  515. # Create SSH title.
  516. label $ID_OPTIONS.sshTitle -text [format "%s (%s)" [_ "Settings for SSH"] $::support::session::SSH_APP_NAME] -anchor w {*}$subtitleOptions
  517. grid $ID_OPTIONS.sshTitle -in $ID_OPTIONS -row 4 -column 0 -columnspan 3 -padx {0 0} -pady {7 5} -sticky nwe
  518. # Create SSH application field.
  519. label $ID_OPTIONS.sshAppLabel -text [_ "Application"] -anchor w {*}$labelOptions
  520. entry $ID_OPTIONS.sshApp -width 10 -state readonly -textvariable ::support::SettingsWindow::SSH_EXE {*}$entryOptions
  521. button $ID_OPTIONS.sshAppButton -text [_ "Select"] -padx 3 -pady 0 -anchor center -command ::support::SettingsWindow::onSelectSshPath {*}$buttonOptions
  522. grid $ID_OPTIONS.sshAppLabel -in $ID_OPTIONS -row 5 -column 0 -padx {0 5} -pady {0 3} -sticky e
  523. grid $ID_OPTIONS.sshApp -in $ID_OPTIONS -row 5 -column 1 -padx {0 5} -pady {0 3} -sticky ew
  524. grid $ID_OPTIONS.sshAppButton -in $ID_OPTIONS -row 5 -column 2 -padx {0 0} -pady {0 3} -sticky ew
  525. # Create SSH key field.
  526. label $ID_OPTIONS.sshKeyLabel -text [_ "Key"] -anchor w {*}$labelOptions
  527. entry $ID_OPTIONS.sshKey -width 10 -state readonly -textvariable ::support::SettingsWindow::SSH_KEY {*}$entryOptions
  528. button $ID_OPTIONS.sshKeyButton -text [_ "Select"] -padx 3 -pady 0 -anchor center -command ::support::SettingsWindow::onSelectSshKey {*}$buttonOptions
  529. grid $ID_OPTIONS.sshKeyLabel -in $ID_OPTIONS -row 6 -column 0 -padx {0 5} -pady {0 3} -sticky e
  530. grid $ID_OPTIONS.sshKey -in $ID_OPTIONS -row 6 -column 1 -padx {0 5} -pady {0 3} -sticky ew
  531. grid $ID_OPTIONS.sshKeyButton -in $ID_OPTIONS -row 6 -column 2 -padx {0 0} -pady {0 3} -sticky ew
  532. # Create SSH user field.
  533. label $ID_OPTIONS.sshUserLabel -text [_ "User"] -anchor w {*}$labelOptions
  534. entry $ID_OPTIONS.sshUser -width 10 -textvariable ::support::SettingsWindow::SSH_USER {*}$entryOptions
  535. grid $ID_OPTIONS.sshUserLabel -in $ID_OPTIONS -row 7 -column 0 -padx {10 5} -pady {0 3} -sticky e
  536. grid $ID_OPTIONS.sshUser -in $ID_OPTIONS -row 7 -column 1 -columnspan 2 -padx {0 0} -pady {0 3} -sticky ew
  537. # Create SSH port field.
  538. label $ID_OPTIONS.sshPortLabel -text [_ "SSH Port"] -anchor w {*}$labelOptions
  539. entry $ID_OPTIONS.sshPort -width 10 -textvariable ::support::SettingsWindow::SSH_PORT {*}$entryOptions
  540. grid $ID_OPTIONS.sshPortLabel -in $ID_OPTIONS -row 8 -column 0 -padx {10 5} -pady {0 3} -sticky e
  541. grid $ID_OPTIONS.sshPort -in $ID_OPTIONS -row 8 -column 1 -columnspan 2 -padx {0 0} -pady {0 3} -sticky ew
  542. # Create internal SSH application field.
  543. if {$::support::session::SSH_APP_PROVIDED == 1} {
  544. checkbutton $ID_OPTIONS.sshAppInternal -text [_ "Use provided SSH application."] -variable ::support::SettingsWindow::USE_PROVIDED_SSH_APP -command ::support::SettingsWindow::onUpdateSshPath {*}$checkbuttonOptions
  545. grid $ID_OPTIONS.sshAppInternal -in $ID_OPTIONS -row 9 -column 1 -columnspan 2 -padx {0 0} -pady {0 3} -sticky w
  546. }
  547. # Create internal SSH key field.
  548. if {$::support::session::SSH_KEY_PROVIDED == 1} {
  549. checkbutton $ID_OPTIONS.sshKeyInternal -text [_ "Use provided key."] -variable ::support::SettingsWindow::USE_PROVIDED_SSH_KEY -command ::support::SettingsWindow::onUpdateSshKey {*}$checkbuttonOptions
  550. grid $ID_OPTIONS.sshKeyInternal -in $ID_OPTIONS -row 10 -column 1 -columnspan 2 -padx {0 0} -pady {0 3} -sticky w
  551. }
  552. # Create button bar.
  553. frame .settings.frm.buttons -background $background
  554. grid .settings.frm.buttons -in .settings.frm -row 1 -column 0 -padx {10 10} -pady {0 10} -sticky swe
  555. grid columnconfigure .settings.frm.buttons 0 -weight 1
  556. # Create submit button.
  557. button .settings.frm.buttons.submit -text [_ "Submit"] -anchor center -command ::support::SettingsWindow::onSubmit {*}$buttonOptions
  558. grid .settings.frm.buttons.submit -in .settings.frm.buttons -row 0 -column 0 -sticky we
  559. # Create cancel button.
  560. button .settings.frm.buttons.cancel -text [_ "Cancel"] -anchor center -command ::support::SettingsWindow::onClose {*}$buttonOptions
  561. grid .settings.frm.buttons.cancel -in .settings.frm.buttons -row 1 -column 0 -pady {5 0} -sticky we
  562. # Register events.
  563. wm protocol .settings WM_DELETE_WINDOW "::support::SettingsWindow::onClose"
  564. bind .settings <Escape> "::support::SettingsWindow::onClose"
  565. # Make modal window.
  566. ::support::utils::modal_init $ID
  567. # Do final initializations.
  568. onUpdateVncPath
  569. onUpdateSshPath
  570. onUpdateSshKey
  571. }
  572. proc onClose {} {
  573. variable ID
  574. ::support::utils::modal_release $ID
  575. }
  576. proc onSelectSshKey {} {
  577. variable ID
  578. variable SSH_KEY
  579. set name ""
  580. set dir $::env(HOME)
  581. if {$SSH_KEY != ""} {
  582. set name [file tail $SSH_KEY]
  583. set dir [file dirname $SSH_KEY]
  584. }
  585. set path [tk_getOpenFile -parent $ID -initialdir $dir -initialfile $name -title [_ "Select your SSH key."]]
  586. if {$path != ""} {
  587. if {![file isfile $path]} {
  588. tk_messageBox -parent $ID -type ok -icon error -title [_ "Error"] -message [_ "Can't select SSH key!"] -detail [_ "The selected file is invalid."]
  589. } else {
  590. set SSH_KEY $path
  591. }
  592. }
  593. }
  594. proc onSelectSshPath {} {
  595. variable ID
  596. variable SSH_EXE
  597. set name ""
  598. set dir $::env(HOME)
  599. if {$SSH_EXE != ""} {
  600. set name [file tail $SSH_EXE]
  601. set dir [file dirname $SSH_EXE]
  602. }
  603. set path [tk_getOpenFile -parent $ID -initialdir $dir -initialfile $name -title [_ "Select your SSH application."]]
  604. if {$path != ""} {
  605. if {![file isfile $path] || ![file executable $path]} {
  606. tk_messageBox -parent $ID -type ok -icon error -title [_ "Error"] -message [_ "Can't select SSH application!"] -detail [_ "The selected file is not an executable program."]
  607. } else {
  608. set SSH_EXE $path
  609. }
  610. }
  611. }
  612. proc onSelectVncPath {} {
  613. variable ID
  614. variable VNC_EXE
  615. set name ""
  616. set dir $::env(HOME)
  617. if {$VNC_EXE != ""} {
  618. set name [file tail $VNC_EXE]
  619. set dir [file dirname $VNC_EXE]
  620. }
  621. set path [tk_getOpenFile -parent $ID -initialdir $dir -initialfile $name -title [_ "Select your VNC application."]]
  622. if {$path != ""} {
  623. if {![file isfile $path] || ![file executable $path]} {
  624. tk_messageBox -parent $ID -type ok -icon error -title [_ "Error"] -message [_ "Can't select VNC application!"] -detail [_ "The selected file is not an executable program."]
  625. } else {
  626. set VNC_EXE $path
  627. }
  628. }
  629. }
  630. proc onSubmit {} {
  631. variable ID
  632. variable VNC_EXE
  633. variable VNC_PARAMETERS
  634. variable SSH_EXE
  635. variable SSH_PORT
  636. variable SSH_USER
  637. variable SSH_KEY
  638. variable USE_PROVIDED_SSH_APP
  639. variable USE_PROVIDED_SSH_KEY
  640. variable USE_PROVIDED_VNC_APP
  641. # Put settings into the session.
  642. set ::support::session::VNC_EXE $VNC_EXE
  643. set ::support::session::VNC_PARAMETERS [string trim $VNC_PARAMETERS]
  644. set ::support::session::SSH_EXE $SSH_EXE
  645. set ::support::session::SSH_PORT [string trim $SSH_PORT]
  646. set ::support::session::SSH_USER [string trim $SSH_USER]
  647. set ::support::session::SSH_KEY $SSH_KEY
  648. set ::support::session::USE_PROVIDED_SSH_APP $USE_PROVIDED_SSH_APP
  649. set ::support::session::USE_PROVIDED_SSH_KEY $USE_PROVIDED_SSH_KEY
  650. set ::support::session::USE_PROVIDED_VNC_APP $USE_PROVIDED_VNC_APP
  651. # Close settings dialog.
  652. onClose
  653. }
  654. proc onUpdateSshKey {} {
  655. variable ID_OPTIONS
  656. variable USE_PROVIDED_SSH_KEY
  657. if {$USE_PROVIDED_SSH_KEY == 1} {
  658. $ID_OPTIONS.sshKey configure -state disabled
  659. $ID_OPTIONS.sshKeyButton configure -state disabled
  660. } else {
  661. $ID_OPTIONS.sshKey configure -state readonly
  662. $ID_OPTIONS.sshKeyButton configure -state normal
  663. }
  664. if {$::support::session::SSH_KEY_PROVIDED == 1} {
  665. $ID_OPTIONS.sshKeyInternal configure -state normal
  666. }
  667. }
  668. proc onUpdateSshPath {} {
  669. variable ID_OPTIONS
  670. variable USE_PROVIDED_SSH_APP
  671. if {$USE_PROVIDED_SSH_APP == 1} {
  672. $ID_OPTIONS.sshApp configure -state disabled
  673. $ID_OPTIONS.sshAppButton configure -state disabled
  674. } else {
  675. $ID_OPTIONS.sshApp configure -state readonly
  676. $ID_OPTIONS.sshAppButton configure -state normal
  677. }
  678. }
  679. proc onUpdateVncPath {} {
  680. variable ID_OPTIONS
  681. variable USE_PROVIDED_VNC_APP
  682. if {$USE_PROVIDED_VNC_APP == 1} {
  683. $ID_OPTIONS.vncApp configure -state disabled
  684. $ID_OPTIONS.vncAppButton configure -state disabled
  685. } else {
  686. $ID_OPTIONS.vncApp configure -state readonly
  687. $ID_OPTIONS.vncAppButton configure -state normal
  688. }
  689. }
  690. }