home *** CD-ROM | disk | FTP | other *** search
- # -*- tcl -*-
- # Main installation script for ActiveTcl
- # --------------------------------------
- #
- # Copyright 2001, ActiveState Corp.
- # All Rights Reserved.
-
- package require ActiveTcl 8.3.3.3
- package require Tk
- package require BWidget
-
- option add *Button.highlightthickness 1
- option add *Scrollbar.highlightthickness 1
- option add *Text.highlightthickness 1
- option add *Label.highlightthickness 0
- option add *Label.borderWidth 0
-
- proc main {} {
- wm protocol . WM_DELETE_WINDOW cancel
- wm title . "$::AT(NAME) $::AT(VERSION) Installer"
-
- # Read the logo and create an image from it.
-
- set logo [image create photo -file \
- [file join $::tk_library images ActiveTclSplash.gif]]
-
- set left [frame .left]
- set ::BASE [PagesManager .right]
- set sep [frame .sep -height 2 -bd 2 -relief sunken]
- set ::BTNS [frame .btns]
-
- label $left.logo -image $logo
- pack $left.logo -expand 1 -fill both
-
- grid $left $::BASE -sticky news
- grid $sep -columnspan 2 -sticky ew
- grid $::BTNS -columnspan 2 -sticky ew
- grid columnconfig $::BTNS 0 -weight 1
- grid columnconfig . 1 -weight 1
- grid rowconfigure . 0 -weight 1
-
- set ::CANCEL [button $::BTNS.cncl -text "Cancel" -command { cancel }]
- set ::NEXT [button $::BTNS.next -text "Next >" -command {set ::WAIT 1}]
- set ::BACK [button $::BTNS.back -text "< Back" -command {set ::WAIT -1}]
-
- grid $::BACK $::NEXT $::CANCEL -sticky e -padx 4 -pady 8
- #grid remove $::BACK
-
- # By default, invoke the Next button on <Return>
- bind . <Key-Return> { next }
-
- # Magic debug console invocation
- bind . <Triple-3> { catch {console show} }
-
- # Initial license acceptance parameter
- set ::ACCEPT 0
- # Default install directory
- set ::INSTALL_DIR [default_installdir]
- # Default install error message
- set ::ERRMSG ""
-
- # Note: The procedures open and manipulate the user interface.
- # They use [vwait] to enter the eventloop where needed so that
- # sequencing control is not taken from [main].
-
- set state 1
- while {$state} {
- switch -exact $state {
- 1 { incr state [intro $::BASE] }
- 2 { incr state [license $::BASE] }
- 3 { incr state [check_previous_install $::BASE] }
- 4 { incr state [get_installdir $::BASE] }
- 5 { incr state [overinstall $::BASE] }
- 6 { incr state [get_demodir $::BASE] }
- 7 { incr state [install_ready $::BASE] }
- 8 { exit 0 }
- default {
- return -code error "Unknow run state \"$state\""
- }
- }
- }
- }
-
- # ----------------------------------------------
-
- proc intro {pages} {
- set pname intro
- set page [$pages getframe $pname]
- if {![winfo exists $page]} {
- set page [$pages add $pname]
- label $page.msg -anchor nw -justify left -width 70 -text $::WELCOME
- grid $page.msg -sticky new -padx 8 -pady 4
- grid rowconfigure $page 0 -weight 1
- grid columnconfigure $page 0 -weight 1
- }
- $pages raise $pname
-
- # Return value to move to next state, no BACK button for this one
- return [wait_next 0]
- }
-
- proc license_ok {} {
- $::NEXT configure -state [expr {$::ACCEPT ? "normal" : "disabled"}]
- }
-
- proc license {pages} {
- set pname license
- set page [$pages getframe $pname]
- if {![winfo exists $page]} {
- set page [$pages add $pname]
- grid [ScrolledWindow $page.s -auto both] -sticky news -padx 4 -pady 4
- set tw [text $page.s.t -width 20 -height 8]
- $page.s setwidget $tw
-
- radiobutton $page.ok -variable ::ACCEPT -value 1 -anchor w \
- -command license_ok \
- -text "I accept the terms in the License Agreement"
- radiobutton $page.no -variable ::ACCEPT -value 0 -anchor w \
- -command license_ok \
- -text "I do not accept the terms in the License Agreement"
- grid $page.ok -stick we
- grid $page.no -stick we
-
- grid columnconfigure $page 0 -weight 1
- grid rowconfigure $page 0 -weight 1
-
- $tw insert end [license_text]
- $tw configure -state disabled
-
- # Accept focus even when disabled
- bind $tw <1> { focus %W }
- bind $tw <Key-Return> { next }
- }
- after idle license_ok
- $pages raise $pname
-
- # Return value to move to next state
- return [wait_next]
- }
-
- # ----------------------------------------------
- # INSTALLATION CHECK ROUTINES
- # ----------------------------------------------
-
- proc check_previous_install {pages} {
- # The purpose of this is to verify how we will interact with
- # previous installations. At this point, it only helps uninstall
- # ActiveTcl 8.3.3.2 since that had no uninstaller.
-
- if {![string equal "windows" $::tcl_platform(platform)]} { return 1 }
-
- package require registry
-
- set msg ""
- set key {HKEY_LOCAL_MACHINE\SOFTWARE\ActiveState\ActiveTcl}
- if {![catch {registry get $key "CurrentVersion"} ver]} {
- if {[catch {registry get "$key\\$ver" ""} verdir]} {
- set msg "Previously installed version \"$ver\"\
- partially uninstalled."
- } elseif {[string match "8.3.3.2" $ver]} {
- set msg "You are currently using a previous install\
- of ActiveTcl $ver.\
- \n\t(installed in $verdir)\
- \n\nDo you want to uninstall this before continuing?"
-
- button $::BTNS.unst -text "Uninstall 8.3.3.2" \
- -command [subst {
- uninstall-8.3.3.2 [list [file join $verdir]]
- # We restart this screen to start the process over.
- destroy $::BTNS.unst
- # The value one means continue after finishing uninstall
- set ::WAIT 1
- }
- ]
- grid $::BTNS.unst -row 0
- } elseif {
- ([regexp -all {\.} $ver] == 3) &&
- [package vsatisfies $ver 8.3.3.2]
- } {
- # It is of type M.m.p.build and is >= 8.3.3.2
- #
- set msg "You are currently using a previous install\
- of ActiveTcl $ver.\
- \n\t(installed in $verdir)\
- \n\It is recommended that you uninstall this before\
- continuing."
- } else {
- set msg "Unrecognized installed ActiveTcl version \"$ver\"."
- }
- }
-
- if {[string length $msg]} {
- set page [$pages getframe cinst]
- if {![winfo exists $page]} {
- set page [$pages add cinst]
- label $page.msg -anchor nw -justify left -width 70
- grid $page.msg -sticky new -padx 8 -pady 4
- grid rowconfigure $page 0 -weight 1
- grid columnconfig $page 0 -weight 1
- }
- $page.msg configure -text $msg
- $pages raise cinst
-
- set res [wait_next]
- catch {destroy $::BTNS.unst}
- return $res
- }
-
- return 1
- }
-
- # ----------------------------------------------
-
- proc browse_dir {e} {
- set dir [tk_chooseDirectory]
- if {[string length $dir]} {
- $e delete 0 end
- $e insert end $dir
- }
- }
-
- proc install_ok {dir} {
- $::NEXT configure -state [expr {($dir == "")?"disabled":"normal"}]
- return 1
- }
-
- proc get_installdir {pages} {
- set pname query
- set page [$pages getframe $pname]
- if {![winfo exists $page]} {
- set page [$pages add $pname]
- label $page.msg -anchor nw -justify left -width 70 \
- -text "Please specify the installation directory."
- label $page.errmsg -anchor nw -justify left -fg red
- grid $page.msg -columnspan 2 -sticky new -padx 4 -pady 4
- grid $page.errmsg -columnspan 2 -sticky new -padx 8
-
- entry $page.ent -width 40 -validate key -vcmd { install_ok %P }
- button $page.browse -image [Bitmap::get open] \
- -command [list browse_dir $page.ent]
- grid $page.ent $page.browse -sticky news
-
- grid rowconfigure $page 0 -weight 1
- grid columnconfig $page 0 -weight 1
-
- bind $page.ent <Key-Return> { next }
- }
- $pages raise $pname
- focus $page.ent
-
- $page.ent delete 0 end
- $page.ent insert end $::INSTALL_DIR
- after idle [list $page.ent validate]
-
- if {[string length $::ERRMSG]} {
- $page.errmsg configure -text $::ERRMSG
- }
-
- # -2 means skip over check_previous_install when going back
- set res [wait_next -2]
- set ::INSTALL_DIR [$page.ent get]
- if {$res < 0} { return $res }
-
- foreach {::INSTALL_DIR ::ERRMSG} [check_installdir $::INSTALL_DIR] {break}
- if {[string length $::ERRMSG]} {
- # Something wrong with dir, do this again
- return 0
- } elseif {[string length $::AT(InstVersion)]} {
- # That we are here means that overinstallation was/is allowed.
- # Moved to next step (overinstall check).
- set ::ERRMSG ""
- return 1
- } else {
- # Skip the overinstall check
- set ::ERRMSG ""
- return 2
- }
- }
-
- # ----------------------------------------------
-
- proc overinstall {pages} {
- set page [$pages getframe overinstall]
- if {![winfo exists $page]} {
- set page [$pages add overinstall]
- label $page.msg -anchor nw -justify left -width 70 \
- -text [overinstall_warning]
- grid $page.msg -sticky new -padx 8 -pady 4
- grid rowconfigure $page 0 -weight 1
- grid columnconfig $page 0 -weight 1
- }
- $pages raise overinstall
-
- return [wait_next]
- }
-
- # ----------------------------------------------
-
- proc get_demodir {pages} {
- set pname demos
- set page [$pages getframe $pname]
- if {![winfo exists $page]} {
- set page [$pages add $pname]
- label $page.msg -anchor nw -justify left -width 70 \
- -text "Please specify the demos directory."
- label $page.errmsg -anchor nw -justify left -fg red
- grid $page.msg -columnspan 2 -sticky new -padx 4 -pady 4
- grid $page.errmsg -columnspan 2 -sticky new -padx 8
-
- entry $page.ent -width 40 -validate key -vcmd { install_ok %P }
- button $page.browse -image [Bitmap::get open] \
- -command [list browse_dir $page.ent]
- grid $page.ent $page.browse -sticky news
-
- grid rowconfigure $page 0 -weight 1
- grid columnconfig $page 0 -weight 1
-
- bind $page.ent <Key-Return> { next }
- }
- $pages raise $pname
- focus $page.ent
-
- $page.ent delete 0 end
- $page.ent insert end [default_demodir $::INSTALL_DIR]
- after idle [list $page.ent validate]
-
- if {[string length $::ERRMSG]} {
- $page.errmsg configure -text $::ERRMSG
- }
-
- # -2 means skip over overinstall warning when going back
- set res [wait_next -2]
- set ::DEMO_DIR [$page.ent get]
- if {$res < 0} { return $res }
-
- foreach {::DEMO_DIR ::ERRMSG} [check_demodir $::DEMO_DIR] {break}
- if {[string length $::ERRMSG]} {
- # Something wrong with dir, do this again
- return 0
- } else {
- return 1
- }
- }
-
- # ----------------------------------------------
-
- proc install_ready {pages} {
- set pname ready
- set page [$pages getframe $pname]
- set firsttime 0
- if {![winfo exists $page]} {
- set firsttime 1
- set page [$pages add $pname]
- grid [ScrolledWindow $page.s -auto both] -sticky news -padx 4 -pady 4
- set tw [text $page.s.t -width 20 -height 8]
- $page.s setwidget $tw
-
- grid columnconfigure $page 0 -weight 1
- grid rowconfigure $page 0 -weight 1
-
- $tw insert 1.0 "Press 'Next' to begin installation\n" "" \
- " Installation Directory:\t$::INSTALL_DIR\n" "" \
- " Demos Directory:\t$::DEMO_DIR\n\n"
- $tw configure -state disabled
- $tw tag configure error -background #CC4444
-
- # Accept focus even when disabled
- bind $tw <1> { focus %W }
- bind $tw <Key-Return> { next }
- }
- after idle license_ok
- $pages raise $pname
- set ::LOGWIN $page.s.t
-
- set res [wait_next]
- if {$res < 0} { return $res }
-
- # At this point, there is no going back
- grid remove $::BACK $::NEXT
-
- # Install all the files
- do_install_modules $::SCRIPT_DIR $::INSTALL_DIR $::DEMO_DIR
- # Patch files or add registry stuff
- do_finish $::SCRIPT_DIR $::INSTALL_DIR
-
- log "\n[parting_message]"
-
- # This only allows exit
- wait_next 0 0 "Exit"
- }
-
- # ----------------------------------------------
- # LOGGING ROUTINE
- # ----------------------------------------------
-
- proc log {msg {type ok}} {
- if {[string length $msg]} {
- $::LOGWIN configure -state normal
- $::LOGWIN insert end "$msg\n" $type
- $::LOGWIN see end
- $::LOGWIN configure -state disabled
- update
- }
- }
-
- # ----------------------------------------------
- # WAIT ROUTINES
- # ----------------------------------------------
-
- proc next {} { $::NEXT invoke }
- proc cancel {} { exit 0 }
-
- proc wait_next {{back -1} {next 1} {cancel "Cancel"}} {
- if {$back} { grid $::BACK } else { grid remove $::BACK }
- if {$next} { grid $::NEXT } else { grid remove $::NEXT }
- $::BACK configure -state normal -command [list set ::WAIT $back]
- $::NEXT configure -state normal -command [list set ::WAIT $next]
- $::CANCEL configure -text $cancel -state normal -command cancel
-
- vwait ::WAIT
- return $::WAIT
- }
-
- # ----------------------------------------------
- # SPECIAL UNINSTALLER FOR 8.3.3.2
- # ----------------------------------------------
-
- proc uninstall-8.3.3.2 {dir} {
- # This version came without an INSTALL.LOG
- # Just be a little brutal in getting rid of it
- foreach file [list \
- $dir/bin/itcl32.dll \
- $dir/bin/itk32.dll \
- $dir/bin/tcl83.dll \
- $dir/bin/tclpip83.dll \
- $dir/bin/tclsh83.exe \
- $dir/bin/tclx83.dll \
- $dir/bin/tk83.dll \
- $dir/bin/tkcon.tcl \
- $dir/bin/tkx83.dll \
- $dir/bin/wish83.exe \
- $dir/doc/ActiveTclHelp.chm \
- $dir/include \
- $dir/lib/bwidget1.3.0 \
- $dir/lib/dde1.1 \
- $dir/lib/itcl3.2 \
- $dir/lib/itk3.2 \
- $dir/lib/iwidgets \
- $dir/lib/iwidgets3.0.2 \
- $dir/lib/reg1.0 \
- $dir/lib/tcl8.3 \
- $dir/lib/tcllib1.0 \
- $dir/lib/tclX8.3 \
- $dir/lib/tk8.3 \
- $dir/lib/Tktable2.7 \
- $dir/lib/tkX8.3 \
- $dir/license.terms \
- $dir/README.txt \
- ] {
- file delete -force $file
- }
- catch {eval file delete -force [glob -nocomplain $dir/lib/*.{sh,lib}]}
- foreach subdir {bin doc include lib} {
- if {[llength [glob -nocomplain $dir/$subdir/*]] == 0} {
- file delete -force $dir/$subdir
- }
- }
- if {[llength [glob -nocomplain $dir/*]] == 0} {
- file delete -force $dir
- }
- package require registry
- catch {
- registry delete \
- {HKEY_LOCAL_MACHINE\SOFTWARE\ActiveState\ActiveTcl} \
- "CurrentVersion"
- }
- catch {
- registry delete \
- {HKEY_LOCAL_MACHINE\SOFTWARE\ActiveState\ActiveTcl\8.3.3.2}
- }
- catch {
- package require dde
- dde execute progman progman {[DeleteGroup(ActiveState ActiveTcl)]}
- }
- }
-
- # ----------------------------------------------
- # GO TO IT
- # ----------------------------------------------
-
- set ::SCRIPT_DIR [file dirname [info script]]
- set here [pwd] ; cd $::SCRIPT_DIR ; set ::SCRIPT_DIR [pwd] ; cd $here
-
- if {[catch {
- source [file join $SCRIPT_DIR install_lib.tcl]
- main
- } err]} {
- catch {bgerror $err}
- }
- exit
-