1############################################################################### 2############################################################################### 3##### Ventana.tcl 4############################################################################### 5##### Creates the window which will provide some information to the user 6##### while a file is being downloaded. 7############################################################################### 8##### Copyright 1999-2008 Andr�s Garc�a Garc�a - fandom@telefonica.net 9##### Distributed under the terms of the GPL v2 10############################################################################### 11 12namespace eval Ventana { 13 14source [file join $dirGetleft(scripts) Rizo.tcl] 15 16set family [font configure TkTextFont -family] 17set size [font configure TkTextFont -size] 18 19catch {font create labelFont -family $family -size $size -weight bold} 20 21############################################################################### 22# DefineButtonImages 23# Reads the images needed to create the 'downloading' window. 24############################################################################### 25proc DefineButtonImages {} { 26 global dirGetleft getleftState 27 variable images 28 29 set ext $getleftState(imgExt) 30 31 set images(url) [image create photo \ 32 -file [file join "$dirGetleft(icons)" html.$ext]] 33 set images(folder) [image create photo \ 34 -file [file join "$dirGetleft(icons)" folder.$ext]] 35 set images(files) [image create photo \ 36 -file [file join "$dirGetleft(icons)" files.$ext]] 37 set images(clock) [image create photo \ 38 -file [file join "$dirGetleft(icons)" clock.$ext]] 39 40 set images(pause) [image create photo \ 41 -file [file join "$dirGetleft(icons)" pauses.$ext]] 42 set images(resume) [image create photo \ 43 -file [file join "$dirGetleft(icons)" resumes.$ext]] 44 set images(stop) [image create photo \ 45 -file [file join "$dirGetleft(icons)" stops.$ext]] 46 set images(conf) [image create photo \ 47 -file [file join "$dirGetleft(icons)" confs.$ext]] 48 49 return 50} 51 52############################################################################### 53# ChangeProgressBar 54# During a download we need a determinate progress bar, but while 55# connecting or processing a file an indeterminate one is better. 56# 57# Parameter: 58# action: 'start' or 'stop'. 59############################################################################### 60proc ChangeProgressBar {action} { 61 variable window 62 63 if {$action=="start"} { 64 $window(bar) configure -mode indeterminate 65 $window(bar) start 66 } else { 67 $window(bar) stop 68 set Ventana::Rizo::curlReport(percentage) 0 69 $window(bar) configure -mode determinate 70 } 71 72 return 73} 74 75############################################################################### 76# ShowResumeButton 77# When the user pauses the download, the 'Pause' menu button is 78# subtituted by the 'Resume' button 79############################################################################### 80proc ShowResumeButton {} { 81 variable window 82 variable menus 83 global getleftState 84 85 $window(pause) configure -state disabled 86 place $window(resume) -in $window(pause) 87 $menus(stop) entryconfigure 3 -state disabled 88 89 return 90} 91 92############################################################################### 93# HideResumeButton 94# And when the download is resumed it is hidden again. 95############################################################################### 96proc HideResumeButton {} { 97 variable window 98 variable menus 99 100 place forget $window(resume) 101 $window(pause) configure -state normal 102 103 $menus(stop) entryconfigure 3 -state normal 104 105 return 106} 107 108############################################################################### 109# PauseDownloading 110# Pauses the downloading according to the menu entries. 111# 112# Parameter 113# which: either 'file' or 'page' 114############################################################################### 115proc Pause {which} { 116 global getleftOptions labelTitles labelMessages 117 variable window 118 119 set windowState [wm state $window(top)] 120 if {$windowState=="iconic"} { 121 wm deiconify $window(top) 122 } 123 124 ShowResumeButton 125 126 if {$which=="file"} { 127 tkwait variable getleftOptions(pauseFile) 128 } else { 129 tkwait variable getleftOptions(pausePage) 130 } 131 132 return 133} 134 135############################################################################### 136# CancelDownloading 137# This procedure is invoked from the downloading window when you click on 138# the 'cancel' button or you want to close the window 139# 140# Parameter: 141# parent: The window over which the asking dialog will appear. 142# skip: if skip is 'skip' the current file will be skipped and the next one 143# will begin to be downloaded. If there is no parameter, the downloading 144# will be stopped. 145# 146# Returns 147# '0' if we are not going to stop. 148# '1' if we are. 149############################################################################### 150proc CancelDownloading {parent {skip {} }} { 151 global labelTitles labelMessages 152 global getleftState getleftOptions 153 global ::Ventana::Rizo::curlReport 154 variable waitingPid 155 variable window 156 157 if {$getleftState(delayedDown)==0} { 158 set what [Dialogos::Dialogo $parent.error -type yesno -icon question \ 159 -title $labelTitles(confirm) \ 160 -message $labelMessages(stopDownload)] 161 if {$what=="no"} { 162 return 0 163 } 164 if {[info exists window(bar)]} { 165 $window(bar) configure -value 0 166 } 167 set Ventana::Rizo::curlReport(left) "" 168 } 169 catch {after cancel $waitingPid} 170 catch {Rizo::Lector stopNow} 171 172 set getleftOptions(cancelDown) 1 173 set Ventana::Rizo::curlReport(end) 1 174 set getleftState(autoDown) 0 175 176 if {($skip=="")||($getleftState(filesChosen)==0)} { 177 set getleftOptions(stopFile) 1 178 set getleftState(downloading) 0 179 catch {wm withdraw $window(top)} 180 } 181 182 incr curlReport(nextFile) 183 184 if {$getleftState(waiting)==1} { 185 set getleftState(waiting) 0 186 } 187 return 1 188} 189 190############################################################################### 191# TrimString 192# Trims the given string so that if it is longer than the available space 193# the middle of it gets substituted with '...', and puts the resulting 194# string in the given label. 195# 196# Par�metros 197# cadena: string to trim. 198# labelPath: the label in which the string is going to be shown 199############################################################################### 200proc TrimString {cadena labelPath} { 201 202 set font labelFont 203 set varName [$labelPath cget -textvariable] 204 205 upvar #0 $varName textVariable 206 207 set textVariable $cadena 208 set labelLength [expr {[winfo width $labelPath]-5}] 209 set strLength [font measure $font -displayof $labelPath $cadena] 210 211 if {$labelLength<=$strLength} { 212 set strChars [string length $cadena] 213 set middle [expr {round($strChars/2)-2}] 214 set primer [string range $cadena 0 $middle] 215 set segun [string range $cadena [expr {$middle+1}] end] 216 set textVariable "" 217 append textVariable $primer "..." $segun 218 while {[font measure $font -displayof $labelPath $textVariable]>$labelLength} { 219 regsub {(.)(\.\.\.)(.)} $textVariable {...} textVariable 220 } 221 BalloonHelp::set_balloon $labelPath $cadena 222 } else { 223 BalloonHelp::delete_balloon $labelPath 224 } 225 return 226} 227 228############################################################################### 229# FileStrings 230# Controls the strings that will be put in the downloading window, to 231# show the name and directory of the file being processed or downloaded 232# 233# Parameter: 234# url to be downloaded or preprocessed 235############################################################################### 236proc FileStrings {url} { 237 global directories labelMessages 238 variable window 239 240 set fileName [::Commands::UrlToFile $url $directories(base)] 241 set parsedUrl [HtmlParser::ParseUrl $url] 242 set domain [string tolower [lindex $parsedUrl 1]] 243 set domainTmp [string map {: ""} $domain] 244 if {[regexp -nocase "(?:$directories(base)/$domainTmp/)(.*)" \ 245 $fileName nada tmp]==0} { 246 set tmp "" 247 } 248 249 if {![regexp {(.*)(?:/)(.*)} $tmp nada tmpDir tmpFile]} { 250 set tmpDir "" 251 set tmpFile $tmp 252 } 253 254 TrimString $domain $window(url) 255 TrimString $tmpDir $window(dir) 256 TrimString $tmpFile $window(file) 257 258 update 259 260 return 261} 262 263############################################################################### 264# DownloadWindow 265# Creates the window, in which some info about the downloading will be 266# displayed. 267############################################################################### 268proc DownloadWindow {} { 269 global labelButtons labelDialogs labelMenus dirGetleft 270 global getleftOptions getleftState 271 variable window 272 variable menus 273 variable images 274 275 DefineButtonImages 276 277 set win [toplevel .bajando] 278 wm resizable $win 0 0 279 wm maxsize $win 299 200 280 281 if {$getleftState(os)=="mac"} { 282 set labelWidth 27 283 } else { 284 set labelWidth 35 285 } 286 287 set marco [ttk::frame $win.marco -class ExternalFrame] 288 set marco_in [ttk::frame $marco.marco_interno] 289 set marco_url [ttk::frame $marco_in.url] 290 set marco_dir [ttk::frame $marco_in.dir] 291 set marco_fil [ttk::frame $marco_in.fil] 292 set marco_que [ttk::frame $marco_in.que] 293 set marco_bar [ttk::frame $marco_in.bar] 294 set exButtons [ttk::frame $win.exButtons -class ExternalFrame] 295 set botones [ttk::frame $exButtons.botones] 296 297 set etq_url [ttk::label $marco_url.etq_url -image $images(url)] 298 set etq_dir [ttk::label $marco_dir.etq_dir -image $images(folder)] 299 set etq_file [ttk::label $marco_fil.etq_file -image $images(files)] 300 set etq_que [ttk::label $marco_que.etq_que -image $images(clock)] 301 302 BalloonHelp::set_balloon $etq_url $labelDialogs(url) 303 BalloonHelp::set_balloon $etq_dir $labelDialogs(dir) 304 BalloonHelp::set_balloon $etq_file $labelDialogs(file) 305 BalloonHelp::set_balloon $etq_que $labelDialogs(left) 306 307 set etq_url2 [ttk::label $marco_url.etq_url2 -width $labelWidth -anchor w \ 308 -relief sunken -textvariable Ventana::window(labelUrl) -font labelFont] 309 set etq_dir2 [ttk::label $marco_dir.etq_dir2 -width $labelWidth -anchor w \ 310 -textvariable Ventana::window(labelDir) -font labelFont] 311 set etq_file2 [ttk::label $marco_fil.etq_file2 -width $labelWidth -anchor w \ 312 -textvariable Ventana::window(labelFile) -font labelFont] 313 set etq_que2 [ttk::label $marco_que.etq_que2 -width $labelWidth -anchor w \ 314 -textvariable Ventana::Rizo::curlReport(left) -font labelFont] 315 316 set progressBar [ttk::progressbar $marco_bar.progress -orient horizontal \ 317 -length 275 -mode determinate \ 318 -variable Ventana::Rizo::curlReport(percentage)] 319 320 set window(top) $win 321 set window(url) $etq_url2 322 set window(dir) $etq_dir2 323 set window(file) $etq_file2 324 set window(left) $etq_que2 325 set window(bar) $progressBar 326 327 set config [ttk::button $botones.config -image $images(conf) \ 328 -command "mainWin::UrlListChangeOptions $window(top)" -style Toolbutton] 329 set pause [ttk::menubutton $botones.pause -menu $botones.pause.menu \ 330 -image $images(pause) -style Toolbutton] 331 set stop [ttk::menubutton $botones.stop -menu $botones.stop.menu \ 332 -image $images(stop) -style Toolbutton] 333 set resume [ttk::button $botones.resume -image $images(resume) \ 334 -command "::Ventana::ResumeDownloading" -style Toolbutton] 335 336 ::BalloonHelp::set_balloon $config $labelDialogs(options) 337 ::BalloonHelp::set_balloon $pause $labelDialogs(pause) 338 ::BalloonHelp::set_balloon $stop $labelDialogs(stop) 339 ::BalloonHelp::set_balloon $resume $labelDialogs(start) 340 341 set menus(pause) [menu $pause.menu -tearoff 0 -fg black -bg $getleftOptions(menus) \ 342 -postcommand " 343 BalloonHelp::kill_balloon 344 "] 345 $menus(pause) add command -label $labelMenus(stopNow) -command { 346 Ventana::PauseDownloading now 347 } 348 $menus(pause) add check -variable getleftOptions(pausePage) \ 349 -onvalue 1 -offvalue 0 -label $labelMenus(stopPage) 350 $menus(pause) add check -variable getleftOptions(pauseFile) \ 351 -onvalue 1 -offvalue 0 -label $labelMenus(stopFile) 352 353 set menus(stop) [menu $stop.menu -tearoff 0 -fg black -bg $getleftOptions(menus) \ 354 -postcommand " 355 BalloonHelp::kill_balloon 356 "] 357 $menus(stop) add command -label $labelMenus(stopNow) -command { 358 if {$getleftState(delayedDown)==1} Delay::DelayedCancelDelay 359 ::Ventana::CancelDownloading $Ventana::window(top) 360 } 361 $menus(stop) add check -variable getleftOptions(stopPage) \ 362 -onvalue 1 -offvalue 0 -label $labelMenus(stopPage) \ 363 -command { 364 set getleftState(autoDown) 0 365 if {$getleftState(delayedDown)==1} Delay::DelayedCancelDelay 366 } 367 $menus(stop) add check -variable getleftOptions(stopFile) \ 368 -onvalue 1 -offvalue 0 -label $labelMenus(stopFile) \ 369 -command { 370 set getleftState(autoDown) 0 371 if {$getleftState(delayedDown)==1} Delay::DelayedCancelDelay 372 } 373 $menus(stop) add command -label $labelButtons(skip) \ 374 -command "::Ventana::CancelDownloading $Ventana::window(top) skip" 375 376 set window(cancel) $stop 377 set window(pause) $pause 378 set window(resume) $resume 379 380 pack $marco -ipady 5 381 pack $exButtons -fill x 382 pack $botones -fill x -side right -padx 7 383 pack $marco_in -padx 10 -side bottom 384 pack $marco_url $marco_in $marco_dir $marco_fil $marco_que $marco_bar \ 385 -fill x 386 pack $etq_url $etq_url2 -side left -pady 2 -padx 2 387 pack $etq_dir $etq_dir2 -side left -pady 2 -padx 2 388 pack $etq_file $etq_file2 -side left -pady 2 -padx 2 389 pack $etq_que $etq_que2 -side left -pady 2 -padx 2 390 pack $progressBar 391 pack $stop $pause $config -side right -padx 3 -pady 5 392 393 wm protocol $win WM_DELETE_WINDOW "::Ventana::CancelDownloading $win" 394 395 return 396} 397 398############################################################################### 399# ShowWindow 400# If needed, maps the downloading window, and sets its title bar 401# 402# Parameter 403# which: either 'head', 'down', 'process' or 'wait' depending on the action 404# taking place. 405############################################################################### 406proc ShowWindow {which} { 407 global labelTitles labelButtons getleftState 408 variable window 409 410 if {$::getleftState(downloading)==0} { 411 if {$::DEBUG==1} { 412 Dialogos::Dialogo .error -title Error -icon error -type ok \ 413 -message "Pringamos en ShowWindow: $which" 414 } 415 return 416 } 417 418 if {![winfo exists .bajando]} { 419 DownloadWindow 420 } else { 421 set state [wm state $window(top)] 422 if {$state=="withdrawn"} { 423 wm deiconify $window(top) 424 } 425 } 426 427 switch -exact $which { 428 head { 429 wm title $window(top) $labelTitles(connect) 430 ChangeProgressBar start 431 } 432 down { 433 wm title $window(top) $labelTitles(download) 434 ChangeProgressBar stop 435 } 436 process { 437 wm title $window(top) $labelTitles(process) 438 ChangeProgressBar start 439 } 440 wait { 441 StartWaiting 10 442 } 443 } 444 445 update 446 447 return 448} 449 450############################################################################### 451# FileDownloading 452# Creates a nice window to show info about how the downloading goes 453# 454# Parameters: 455# fichero: file in which the link will be saved. 456# enlace: file url. 457# madre: referer page for the link 458############################################################################### 459proc FileDownloading {fichero enlace madre} { 460 global getleftState directories 461 global labelTitles 462 global Ventana::Rizo::meta 463 global Ventana::Rizo::curlReport 464 variable window 465 variable file 466 variable link 467 variable mother 468 variable action 469 470 if {$getleftState(downloading)==0} { 471 return 472 } 473 474 set file $fichero 475 set action body 476 477 ShowWindow down 478 FileStrings $enlace 479 480 set curlReport(end) 0 481 set curlReport(long) 1 482 set curlReport(pause) 0 483 484 if {([file exists $fichero])&&($meta(versionServer)>=1.1)} { 485 set size [file size $fichero] 486 if {($size>$meta(totalBytes))&&($meta(totalBytes)!=0)} { 487 file delete $fichero 488 } elseif {($size==$meta(totalBytes))&&($meta(totalBytes)!=0)} { 489 after 1000 "set ::Ventana::Rizo::curlReport(nextFile) 1" 490 return 491 } 492 Ventana::Rizo::DataRequest $fichero $enlace $madre 1 493 } else { 494 Ventana::Rizo::DataRequest $fichero $enlace $madre 495 } 496 CheckDownload 497 498 return 499} 500 501############################################################################### 502# HeadDownloading 503# Gets the headers of the url from the server. 504# 505# Parameters: 506# enlace: url to download 507# madre: referer page of the link 508############################################################################### 509proc HeadDownloading {enlace madre} { 510 global siteUrl getleftState 511 variable link 512 variable mother 513 variable action 514 variable window 515 516 set link $enlace 517 set mother $madre 518 set action head 519 520 ShowWindow head 521 FileStrings $enlace 522 523 HideResumeButton 524 525 if {[regexp {^ftp://} $enlace]} { 526 set ::Ventana::Rizo::meta(content) "nada" 527 set ::Ventana::Rizo::meta(totalBytes) 0 528 set ::Ventana::Rizo::meta(versionServer) 1.1 529 set ::Ventana::Rizo::meta(relocate) "" 530 set ::Ventana::Rizo::curlError 0 531 set ::Ventana::Rizo::errorMessage "" 532 return 533 } 534 535 set Ventana::Rizo::curlReport(end) 0 536 Ventana::Rizo::HeadRequest $enlace $madre 537 tkwait variable Ventana::Rizo::curlReport(end) 538 539 return 540} 541 542############################################################################### 543# PauseDownloading 544# Takes control when you click on the 'Pause' button. 545# 546# Parameter: 547# when: 'now' when we click on the 'Now' menu entry, usuful to pause 548# the downloading while a file is being process for links. 549############################################################################### 550proc PauseDownloading {{when ""}} { 551 global labelButtons getleftOptions 552 variable window 553 554 if {$when=="now"} { 555 set getleftOptions(pauseNow) 1 556 } 557 set Ventana::Rizo::curlReport(pause) 1 558 set ::Ventana::Rizo::curlReport(left) "" 559 ChangeProgressBar stop 560 catch {Rizo::Lector stopNow} 561 ShowResumeButton 562 563 return 564} 565 566############################################################################### 567# ResumeDownloading 568# Takes control when you click on the 'Resume' button 569############################################################################### 570proc ResumeDownloading {} { 571 global labelButtons getleftOptions 572 variable window 573 variable file 574 variable link 575 variable mother 576 variable action 577 578 HideResumeButton 579 580 if {($getleftOptions(pauseFile)==1)||($getleftOptions(pausePage)==1)} { 581 set getleftOptions(pauseFile) 0 582 set getleftOptions(pausePage) 0 583 return 584 } 585 set getleftOptions(pauseNow) 0 586 set Ventana::Rizo::curlReport(pause) 0 587 set Ventana::Rizo::curlReport(percentage) 0 588 589 if {$action=="body"} { 590 Ventana::Rizo::DataRequest "$file" "$link" "$mother" 1 591 Ventana::CheckDownload 592 } else { 593 HeadDownloading "$link" "$mother" 594 } 595 return 596} 597 598############################################################################### 599# StartWaiting 600# This procedure is invoked when a timeout has ocurred, to wait before 601# trying again. 602# 603# Parameter 604# seconds: The seconds yet to wait 605############################################################################### 606proc StartWaiting {seconds} { 607 global getleftState labelTitles 608 variable window 609 variable waitingPid 610 611 if {$seconds==0} { 612 InterruptWaiting 613 return 614 } 615 616 wm title $window(top) "$labelTitles(waiting) $seconds" 617 618 ShowResumeButton 619 $window(resume) configure -command ::Ventana::InterruptWaiting 620 621 set waitingPid [after 1000 ::Ventana::StartWaiting [expr $seconds -1]] 622 623 return 624} 625 626############################################################################### 627# InterruptWaiting 628# While waiting to retry after a timeout, if you click on resume 629# this procedure will be invoked. 630############################################################################### 631proc InterruptWaiting {} { 632 global getleftState 633 variable window 634 variable waitingPid 635 636 after cancel $waitingPid 637 638 HideResumeButton 639 $window(resume) configure -command ::Ventana::ResumeDownloading 640 641 set getleftState(waiting) 0 642 643 return 644} 645 646############################################################################### 647# CheckDownload 648# The procedure get invoked from time to time in order to check whether 649# the transfer has ended, with success or not. 650############################################################################### 651proc CheckDownload {} { 652 global Ventana::Rizo::curlReport 653 global Ventana::Rizo::curlError 654 global Ventana::Rizo::meta 655 global labelDialogs downOptions getleftOptions 656 variable file 657 variable link 658 variable mother 659 variable window 660 661 if {[string match $curlReport(percentage) ""]} return 662 if {$getleftOptions(pauseNow)==1} { 663 return 664 } 665 if {($curlReport(end)==0) && ($curlReport(stop)!=1) \ 666 && ($curlReport(pause)==0)} { 667 set afterId [after 750 Ventana::CheckDownload] 668 } else { 669 set curlReport(left) "" 670 if {($::DEBUG==1)&&($curlError!=0)} { 671 puts "Error $curlError en $file" 672 } 673 if {($curlError==18)||($curlError==28)} { 674 getLog::FileLogEnter $labelDialogs(fileIncom) \ 675 "$link" "$mother" 676 if {($downOptions(resume)==1)&&($curlReport(stop)!=1)} { 677 $window(bar) stop 678 set ::Ventana::Rizo::curlReport(percentage) 0 679 if {$curlError==18} { 680 FileDownloading "$file" "$link" "$mother" 681 } else { 682 incr curlReport(nextFile) 683 } 684 return 685 } 686 } 687 if {$curlError==0} { 688 $window(bar) configure -value 100 689 update 690 } 691 after 75 692 $window(bar) configure -value 0 693 set ::Ventana::Rizo::curlReport(percentage) 0 694 $window(dir) configure -text "" 695 $window(file) configure -text "" 696 incr curlReport(nextFile) 697 } 698 return 699} 700} 701