1#************************************************************************* 2# 3# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4# 5# Copyright 2000, 2010 Oracle and/or its affiliates. 6# 7# OpenOffice.org - a multi-platform office productivity suite 8# 9# This file is part of OpenOffice.org. 10# 11# OpenOffice.org is free software: you can redistribute it and/or modify 12# it under the terms of the GNU Lesser General Public License version 3 13# only, as published by the Free Software Foundation. 14# 15# OpenOffice.org is distributed in the hope that it will be useful, 16# but WITHOUT ANY WARRANTY; without even the implied warranty of 17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18# GNU Lesser General Public License version 3 for more details 19# (a copy is included in the LICENSE file that accompanied this code). 20# 21# You should have received a copy of the GNU Lesser General Public License 22# version 3 along with OpenOffice.org. If not, see 23# <http://www.openoffice.org/license.html> 24# for a copy of the LGPLv3 License. 25# 26#************************************************************************* 27 28package installer::windows::idtglobal; 29 30use Cwd; 31use installer::converter; 32use installer::existence; 33use installer::exiter; 34use installer::files; 35use installer::globals; 36use installer::pathanalyzer; 37use installer::remover; 38use installer::scriptitems; 39use installer::systemactions; 40use installer::windows::language; 41 42############################################################## 43# Shorten the gid for a feature. 44# Attention: Maximum length is 38 45############################################################## 46 47sub shorten_feature_gid 48{ 49 my ($stringref) = @_; 50 51 $$stringref =~ s/gid_Module_/gm_/; 52 $$stringref =~ s/_Extension_/_ex_/; 53 $$stringref =~ s/_Root_/_r_/; 54 $$stringref =~ s/_Prg_/_p_/; 55 $$stringref =~ s/_Optional_/_o_/; 56 $$stringref =~ s/_Tools_/_tl_/; 57 $$stringref =~ s/_Wrt_Flt_/_w_f_/; 58 $$stringref =~ s/_Javafilter_/_jf_/; 59 $$stringref =~ s/_Productivity_/_pr_/; 60 $$stringref =~ s/_Replacement_/_rpl_/; 61} 62 63############################################ 64# Getting the next free number, that 65# can be added. 66# Sample: 01-44-~1.DAT, 01-44-~2.DAT, ... 67############################################ 68 69sub get_next_free_number 70{ 71 my ($name, $shortnamesref) = @_; 72 73 my $counter = 0; 74 my $dontsave = 0; 75 my $alreadyexists; 76 my ($newname, $shortname); 77 78 do 79 { 80 $alreadyexists = 0; 81 $counter++; 82 $newname = $name . $counter; 83 84 for ( my $i = 0; $i <= $#{$shortnamesref}; $i++ ) 85 { 86 $shortname = ${$shortnamesref}[$i]; 87 88 if ( uc($shortname) eq uc($newname) ) # case insensitive 89 { 90 $alreadyexists = 1; 91 last; 92 } 93 } 94 } 95 until (!($alreadyexists)); 96 97 if (( $counter > 9 ) && ( length($name) > 6 )) { $dontsave = 1; } 98 if (( $counter > 99 ) && ( length($name) > 5 )) { $dontsave = 1; } 99 100 if (!($dontsave)) 101 { 102 push(@{$shortnamesref}, $newname); # adding the new shortname to the array of shortnames 103 } 104 105 return $counter 106} 107 108############################################ 109# Getting the next free number, that 110# can be added. 111# Sample: 01-44-~1.DAT, 01-44-~2.DAT, ... 112############################################ 113 114sub get_next_free_number_with_hash 115{ 116 my ($name, $shortnamesref, $ext) = @_; 117 118 my $counter = 0; 119 my $dontsave = 0; 120 my $saved = 0; 121 my $alreadyexists; 122 my ($newname, $shortname); 123 124 do 125 { 126 $alreadyexists = 0; 127 $counter++; 128 $newname = $name . $counter; 129 $newname = uc($newname); # case insensitive, always upper case 130 if ( exists($shortnamesref->{$newname}) || 131 exists($installer::globals::savedrev83mapping{$newname.$ext}) ) 132 { 133 $alreadyexists = 1; 134 } 135 } 136 until (!($alreadyexists)); 137 138 if (( $counter > 9 ) && ( length($name) > 6 )) { $dontsave = 1; } 139 if (( $counter > 99 ) && ( length($name) > 5 )) { $dontsave = 1; } 140 141 if (!($dontsave)) 142 { 143 # push(@{$shortnamesref}, $newname); # adding the new shortname to the array of shortnames 144 $shortnamesref->{$newname} = 1; # adding the new shortname to the array of shortnames, always uppercase 145 $saved = 1; 146 } 147 148 return ( $counter, $saved ) 149} 150 151######################################### 152# 8.3 for filenames and directories 153######################################### 154 155sub make_eight_three_conform 156{ 157 my ($inputstring, $pattern, $shortnamesref) = @_; 158 159 # all shortnames are collected in $shortnamesref, because of uniqueness 160 161 my ($name, $namelength, $number); 162 my $conformstring = ""; 163 my $changed = 0; 164 165 if (( $inputstring =~ /^\s*(.*?)\.(.*?)\s*$/ ) && ( $pattern eq "file" )) # files with a dot 166 { 167 $name = $1; 168 my $extension = $2; 169 170 $namelength = length($name); 171 my $extensionlength = length($extension); 172 173 if ( $extensionlength > 3 ) 174 { 175 # simply taking the first three letters 176 $extension = substr($extension, 0, 3); # name, offset, length 177 } 178 179 # Attention: readme.html -> README~1.HTM 180 181 if (( $namelength > 8 ) || ( $extensionlength > 3 )) 182 { 183 # taking the first six letters 184 $name = substr($name, 0, 6); # name, offset, length 185 $name =~ s/\s*$//; # removing ending whitespaces 186 $name = $name . "\~"; 187 $number = get_next_free_number($name, $shortnamesref); 188 189 # if $number>9 the new name would be "abcdef~10.xyz", which is 9+3, and therefore not allowed 190 191 if ( $number > 9 ) 192 { 193 $name = substr($name, 0, 5); # name, offset, length 194 $name =~ s/\s*$//; # removing ending whitespaces 195 $name = $name . "\~"; 196 $number = get_next_free_number($name, $shortnamesref); 197 198 if ( $number > 99 ) 199 { 200 $name = substr($name, 0, 4); # name, offset, length 201 $name =~ s/\s*$//; # removing ending whitespaces 202 $name = $name . "\~"; 203 $number = get_next_free_number($name, $shortnamesref); 204 } 205 } 206 207 $name = $name . "$number"; 208 209 $changed = 1; 210 } 211 212 $conformstring = $name . "\." . $extension; 213 214 if ( $changed ) { $conformstring= uc($conformstring); } 215 } 216 else # no dot in filename or directory (also used for shortcuts) 217 { 218 $name = $inputstring; 219 $namelength = length($name); 220 221 if ( $namelength > 8 ) 222 { 223 # taking the first six letters 224 $name = substr($name, 0, 6); # name, offset, length 225 $name =~ s/\s*$//; # removing ending whitespaces 226 $name = $name . "\~"; 227 $number = get_next_free_number($name, $shortnamesref); 228 229 # if $number>9 the new name would be "abcdef~10.xyz", which is 9+3, and therefore not allowed 230 231 if ( $number > 9 ) 232 { 233 $name = substr($name, 0, 5); # name, offset, length 234 $name =~ s/\s*$//; # removing ending whitespaces 235 $name = $name . "\~"; 236 $number = get_next_free_number($name, $shortnamesref); 237 238 if ( $number > 99 ) 239 { 240 $name = substr($name, 0, 4); # name, offset, length 241 $name =~ s/\s*$//; # removing ending whitespaces 242 $name = $name . "\~"; 243 $number = get_next_free_number($name, $shortnamesref); 244 } 245 } 246 247 $name = $name . "$number"; 248 $changed = 1; 249 if ( $pattern eq "dir" ) { $name =~ s/\./\_/g; } # in directories replacing "." with "_" 250 } 251 252 $conformstring = $name; 253 254 if ( $changed ) { $conformstring = uc($name); } 255 } 256 257 return $conformstring; 258} 259 260######################################### 261# 8.3 for filenames and directories 262# $shortnamesref is a hash in this case 263# -> performance reasons 264######################################### 265 266sub make_eight_three_conform_with_hash 267{ 268 my ($inputstring, $pattern, $shortnamesref) = @_; 269 270 # all shortnames are collected in $shortnamesref, because of uniqueness (a hash!) 271 272 my ($name, $namelength, $number); 273 my $conformstring = ""; 274 my $changed = 0; 275 my $saved; 276 277 # if (( $inputstring =~ /^\s*(.*?)\.(.*?)\s*$/ ) && ( $pattern eq "file" )) # files with a dot 278 if (( $inputstring =~ /^\s*(.*)\.(.*?)\s*$/ ) && ( $pattern eq "file" )) # files with a dot 279 { 280 # extension has to be non-greedy, but name is. This is important to find the last dot in the filename 281 $name = $1; 282 my $extension = $2; 283 284 if ( $name =~ /^\s*(.*?)\s*$/ ) { $name = $1; } # now the name is also non-greedy 285 $name =~ s/\.//g; # no dots in 8+3 conform filename 286 287 $namelength = length($name); 288 my $extensionlength = length($extension); 289 290 if ( $extensionlength > 3 ) 291 { 292 # simply taking the first three letters 293 $extension = substr($extension, 0, 3); # name, offset, length 294 $changed = 1; 295 } 296 297 # Attention: readme.html -> README~1.HTM 298 299 if (( $namelength > 8 ) || ( $extensionlength > 3 )) 300 { 301 # taking the first six letters, if filename is longer than 6 characters 302 if ( $namelength > 6 ) 303 { 304 $name = substr($name, 0, 6); # name, offset, length 305 $name =~ s/\s*$//; # removing ending whitespaces 306 $name = $name . "\~"; 307 ($number, $saved) = get_next_free_number_with_hash($name, $shortnamesref, '.'.uc($extension)); 308 309 # if $number>9 the new name would be "abcdef~10.xyz", which is 9+3, and therefore not allowed 310 311 if ( ! $saved ) 312 { 313 $name = substr($name, 0, 5); # name, offset, length 314 $name =~ s/\s*$//; # removing ending whitespaces 315 $name = $name . "\~"; 316 ($number, $saved) = get_next_free_number_with_hash($name, $shortnamesref, '.'.uc($extension)); 317 318 # if $number>99 the new name would be "abcde~100.xyz", which is 9+3, and therefore not allowed 319 320 if ( ! $saved ) 321 { 322 $name = substr($name, 0, 4); # name, offset, length 323 $name =~ s/\s*$//; # removing ending whitespaces 324 $name = $name . "\~"; 325 ($number, $saved) = get_next_free_number_with_hash($name, $shortnamesref, '.'.uc($extension)); 326 327 if ( ! $saved ) 328 { 329 installer::exiter::exit_program("ERROR: Could not set 8+3 conform name for $inputstring !", "make_eight_three_conform_with_hash"); 330 } 331 } 332 } 333 334 $name = $name . "$number"; 335 $changed = 1; 336 } 337 } 338 339 $conformstring = $name . "\." . $extension; 340 341 if ( $changed ) { $conformstring= uc($conformstring); } 342 } 343 else # no dot in filename or directory (also used for shortcuts) 344 { 345 $name = $inputstring; 346 $namelength = length($name); 347 348 if ( $namelength > 8 ) 349 { 350 # taking the first six letters 351 $name = substr($name, 0, 6); # name, offset, length 352 $name =~ s/\s*$//; # removing ending whitespaces 353 $name = $name . "\~"; 354 ( $number, $saved ) = get_next_free_number_with_hash($name, $shortnamesref, ''); 355 356 # if $number>9 the new name would be "abcdef~10", which is 9+0, and therefore not allowed 357 358 if ( ! $saved ) 359 { 360 $name = substr($name, 0, 5); # name, offset, length 361 $name =~ s/\s*$//; # removing ending whitespaces 362 $name = $name . "\~"; 363 ( $number, $saved ) = get_next_free_number_with_hash($name, $shortnamesref, ''); 364 365 # if $number>99 the new name would be "abcde~100", which is 9+0, and therefore not allowed 366 367 if ( ! $saved ) 368 { 369 $name = substr($name, 0, 4); # name, offset, length 370 $name =~ s/\s*$//; # removing ending whitespaces 371 $name = $name . "\~"; 372 ( $number, $saved ) = get_next_free_number_with_hash($name, $shortnamesref, ''); 373 374 if ( ! $saved ) { installer::exiter::exit_program("ERROR: Could not set 8+3 conform name for $inputstring !", "make_eight_three_conform_with_hash"); } 375 } 376 } 377 378 $name = $name . "$number"; 379 $changed = 1; 380 if ( $pattern eq "dir" ) { $name =~ s/\./\_/g; } # in directories replacing "." with "_" 381 } 382 383 $conformstring = $name; 384 385 if ( $changed ) { $conformstring = uc($name); } 386 } 387 388 return $conformstring; 389} 390 391######################################### 392# Writing the header for idt files 393######################################### 394 395sub write_idt_header 396{ 397 my ($idtref, $definestring) = @_; 398 399 my $oneline; 400 401 if ( $definestring eq "file" ) 402 { 403 $oneline = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"; 404 push(@{$idtref}, $oneline); 405 $oneline = "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"; 406 push(@{$idtref}, $oneline); 407 $oneline = "File\tFile\n"; 408 push(@{$idtref}, $oneline); 409 } 410 411 if ( $definestring eq "filehash" ) 412 { 413 $oneline = "File_\tOptions\tHashPart1\tHashPart2\tHashPart3\tHashPart4\n"; 414 push(@{$idtref}, $oneline); 415 $oneline = "s72\ti2\ti4\ti4\ti4\ti4\n"; 416 push(@{$idtref}, $oneline); 417 $oneline = "MsiFileHash\tFile_\n"; 418 push(@{$idtref}, $oneline); 419 } 420 421 if ( $definestring eq "directory" ) 422 { 423 $oneline = "Directory\tDirectory_Parent\tDefaultDir\n"; 424 push(@{$idtref}, $oneline); 425 $oneline = "s72\tS72\tl255\n"; 426 push(@{$idtref}, $oneline); 427 $oneline = "Directory\tDirectory\n"; 428 push(@{$idtref}, $oneline); 429 } 430 431 if ( $definestring eq "component" ) 432 { 433 $oneline = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"; 434 push(@{$idtref}, $oneline); 435 $oneline = "s72\tS38\ts72\ti2\tS255\tS72\n"; 436 push(@{$idtref}, $oneline); 437 $oneline = "Component\tComponent\n"; 438 push(@{$idtref}, $oneline); 439 } 440 441 if ( $definestring eq "feature" ) 442 { 443 $oneline = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"; 444 push(@{$idtref}, $oneline); 445 $oneline = "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"; 446 push(@{$idtref}, $oneline); 447 $oneline = "WINDOWSENCODINGTEMPLATE\tFeature\tFeature\n"; 448 push(@{$idtref}, $oneline); 449 } 450 451 if ( $definestring eq "featurecomponent" ) 452 { 453 $oneline = "Feature_\tComponent_\n"; 454 push(@{$idtref}, $oneline); 455 $oneline = "s38\ts72\n"; 456 push(@{$idtref}, $oneline); 457 $oneline = "FeatureComponents\tFeature_\tComponent_\n"; 458 push(@{$idtref}, $oneline); 459 } 460 461 if ( $definestring eq "media" ) 462 { 463 $oneline = "DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"; 464 push(@{$idtref}, $oneline); 465 $oneline = "i2\ti2\tL64\tS255\tS32\tS72\n"; 466 push(@{$idtref}, $oneline); 467 $oneline = "Media\tDiskId\n"; 468 push(@{$idtref}, $oneline); 469 } 470 471 if ( $definestring eq "font" ) 472 { 473 $oneline = "File_\tFontTitle\n"; 474 push(@{$idtref}, $oneline); 475 $oneline = "s72\tS128\n"; 476 push(@{$idtref}, $oneline); 477 $oneline = "Font\tFile_\n"; 478 push(@{$idtref}, $oneline); 479 } 480 481 if ( $definestring eq "shortcut" ) 482 { 483 $oneline = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"; 484 push(@{$idtref}, $oneline); 485 $oneline = "s72\ts72\tl128\ts72\ts72\tS255\tL255\tI2\tS72\tI2\tI2\tS72\n"; 486 push(@{$idtref}, $oneline); 487 $oneline = "WINDOWSENCODINGTEMPLATE\tShortcut\tShortcut\n"; 488 push(@{$idtref}, $oneline); 489 } 490 491 if ( $definestring eq "registry" ) 492 { 493 $oneline = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"; 494 push(@{$idtref}, $oneline); 495 $oneline = "s72\ti2\tl255\tL255\tL0\ts72\n"; 496 push(@{$idtref}, $oneline); 497 $oneline = "Registry\tRegistry\n"; 498 push(@{$idtref}, $oneline); 499 } 500 501 if ( $definestring eq "reg64" ) 502 { 503 $oneline = "Registry\tRoot\tKey\tName\tValue\tComponent_\n"; 504 push(@{$idtref}, $oneline); 505 $oneline = "s72\ti2\tl255\tL255\tL0\ts72\n"; 506 push(@{$idtref}, $oneline); 507 $oneline = "Reg64\tRegistry\n"; 508 push(@{$idtref}, $oneline); 509 } 510 511 if ( $definestring eq "createfolder" ) 512 { 513 $oneline = "Directory_\tComponent_\n"; 514 push(@{$idtref}, $oneline); 515 $oneline = "s72\ts72\n"; 516 push(@{$idtref}, $oneline); 517 $oneline = "CreateFolder\tDirectory_\tComponent_\n"; 518 push(@{$idtref}, $oneline); 519 } 520 521 if ( $definestring eq "removefile" ) 522 { 523 $oneline = "FileKey\tComponent_\tFileName\tDirProperty\tInstallMode\n"; 524 push(@{$idtref}, $oneline); 525 $oneline = "s72\ts72\tL255\ts72\ti2\n"; 526 push(@{$idtref}, $oneline); 527 $oneline = "RemoveFile\tFileKey\n"; 528 push(@{$idtref}, $oneline); 529 } 530 531 if ( $definestring eq "upgrade" ) 532 { 533 $oneline = "UpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\tRemove\tActionProperty\n"; 534 push(@{$idtref}, $oneline); 535 $oneline = "s38\tS20\tS20\tS255\ti4\tS255\ts72\n"; 536 push(@{$idtref}, $oneline); 537 $oneline = "Upgrade\tUpgradeCode\tVersionMin\tVersionMax\tLanguage\tAttributes\n"; 538 push(@{$idtref}, $oneline); 539 } 540 541 if ( $definestring eq "icon" ) 542 { 543 $oneline = "Name\tData\n"; 544 push(@{$idtref}, $oneline); 545 $oneline = "s72\tv0\n"; 546 push(@{$idtref}, $oneline); 547 $oneline = "Icon\tName\n"; 548 push(@{$idtref}, $oneline); 549 } 550 551 if ( $definestring eq "inifile" ) 552 { 553 $oneline = "IniFile\tFileName\tDirProperty\tSection\tKey\tValue\tAction\tComponent_\n"; 554 push(@{$idtref}, $oneline); 555 $oneline = "s72\tl255\tS72\tl96\tl128\tl255\ti2\ts72\n"; 556 push(@{$idtref}, $oneline); 557 $oneline = "IniFile\tIniFile\n"; 558 push(@{$idtref}, $oneline); 559 } 560 561 if ( $definestring eq "selfreg" ) 562 { 563 $oneline = "File_\tCost\n"; 564 push(@{$idtref}, $oneline); 565 $oneline = "s72\tI2\n"; 566 push(@{$idtref}, $oneline); 567 $oneline = "SelfReg\tFile_\n"; 568 push(@{$idtref}, $oneline); 569 } 570 571 if ( $definestring eq "msiassembly" ) 572 { 573 $oneline = "Component_\tFeature_\tFile_Manifest\tFile_Application\tAttributes\n"; 574 push(@{$idtref}, $oneline); 575 $oneline = "s72\ts38\tS72\tS72\tI2\n"; 576 push(@{$idtref}, $oneline); 577 $oneline = "MsiAssembly\tComponent_\n"; 578 push(@{$idtref}, $oneline); 579 } 580 581 if ( $definestring eq "msiassemblyname" ) 582 { 583 $oneline = "Component_\tName\tValue\n"; 584 push(@{$idtref}, $oneline); 585 $oneline = "s72\ts255\ts255\n"; 586 push(@{$idtref}, $oneline); 587 $oneline = "MsiAssemblyName\tComponent_\tName\n"; 588 push(@{$idtref}, $oneline); 589 } 590 591 if ( $definestring eq "appsearch" ) 592 { 593 $oneline = "Property\tSignature_\n"; 594 push(@{$idtref}, $oneline); 595 $oneline = "s72\ts72\n"; 596 push(@{$idtref}, $oneline); 597 $oneline = "AppSearch\tProperty\tSignature_\n"; 598 push(@{$idtref}, $oneline); 599 } 600 601 if ( $definestring eq "reglocat" ) 602 { 603 $oneline = "Signature_\tRoot\tKey\tName\tType\n"; 604 push(@{$idtref}, $oneline); 605 $oneline = "s72\ti2\ts255\tS255\tI2\n"; 606 push(@{$idtref}, $oneline); 607 $oneline = "RegLocator\tSignature_\n"; 608 push(@{$idtref}, $oneline); 609 } 610 611 if ( $definestring eq "signatur" ) 612 { 613 $oneline = "Signature\tFileName\tMinVersion\tMaxVersion\tMinSize\tMaxSize\tMinDate\tMaxDate\tLanguages\n"; 614 push(@{$idtref}, $oneline); 615 $oneline = "s72\ts255\tS20\tS20\tI4\tI4\tI4\tI4\tS255\n"; 616 push(@{$idtref}, $oneline); 617 $oneline = "Signature\tSignature\n"; 618 push(@{$idtref}, $oneline); 619 } 620 621} 622 623############################################################## 624# Returning the name of the rranslation file for a 625# given language. 626# Sample: "01" oder "en-US" -> "1033.txt" 627############################################################## 628 629sub get_languagefilename 630{ 631 my ($idtfilename, $basedir) = @_; 632 633 # $idtfilename =~ s/\.idt/\.ulf/; 634 $idtfilename =~ s/\.idt/\.mlf/; 635 636 my $languagefilename = $basedir . $installer::globals::separator . $idtfilename; 637 638 return $languagefilename; 639} 640 641############################################################## 642# Returning the complete block in all languages 643# for a specified string 644############################################################## 645 646sub get_language_block_from_language_file 647{ 648 my ($searchstring, $languagefile) = @_; 649 650 my @language_block = (); 651 652 for ( my $i = 0; $i <= $#{$languagefile}; $i++ ) 653 { 654 if ( ${$languagefile}[$i] =~ /^\s*\[\s*$searchstring\s*\]\s*$/ ) 655 { 656 my $counter = $i; 657 658 push(@language_block, ${$languagefile}[$counter]); 659 $counter++; 660 661 while (( $counter <= $#{$languagefile} ) && (!( ${$languagefile}[$counter] =~ /^\s*\[/ ))) 662 { 663 push(@language_block, ${$languagefile}[$counter]); 664 $counter++; 665 } 666 667 last; 668 } 669 } 670 671 return \@language_block; 672} 673 674############################################################## 675# Returning a specific language string from the block 676# of all translations 677############################################################## 678 679sub get_language_string_from_language_block 680{ 681 my ($language_block, $language, $oldstring) = @_; 682 683 my $newstring = ""; 684 685 for ( my $i = 0; $i <= $#{$language_block}; $i++ ) 686 { 687 if ( ${$language_block}[$i] =~ /^\s*$language\s*\=\s*\"(.*)\"\s*$/ ) 688 { 689 $newstring = $1; 690 last; 691 } 692 } 693 694 if ( $newstring eq "" ) 695 { 696 $language = "en-US"; # defaulting to english 697 698 for ( my $i = 0; $i <= $#{$language_block}; $i++ ) 699 { 700 if ( ${$language_block}[$i] =~ /^\s*$language\s*\=\s*\"(.*)\"\s*$/ ) 701 { 702 $newstring = $1; 703 last; 704 } 705 } 706 } 707 708 return $newstring; 709} 710 711############################################################## 712# Returning a specific code from the block 713# of all codes. No defaulting to english! 714############################################################## 715 716sub get_code_from_code_block 717{ 718 my ($codeblock, $language) = @_; 719 720 my $newstring = ""; 721 722 for ( my $i = 0; $i <= $#{$codeblock}; $i++ ) 723 { 724 if ( ${$codeblock}[$i] =~ /^\s*$language\s*\=\s*\"(.*)\"\s*$/ ) 725 { 726 $newstring = $1; 727 last; 728 } 729 } 730 731 return $newstring; 732} 733 734############################################################## 735# Translating an idt file 736############################################################## 737 738sub translate_idtfile 739{ 740 my ($idtfile, $languagefile, $onelanguage) = @_; 741 742 for ( my $i = 0; $i <= $#{$idtfile}; $i++ ) 743 { 744 my @allstrings = (); 745 746 my $oneline = ${$idtfile}[$i]; 747 748 while ( $oneline =~ /\b(OOO_\w+)\b/ ) 749 { 750 my $replacestring = $1; 751 push(@allstrings, $replacestring); 752 $oneline =~ s/$replacestring//; 753 } 754 755 my $oldstring; 756 757 foreach $oldstring (@allstrings) 758 { 759 my $language_block = get_language_block_from_language_file($oldstring, $languagefile); 760 my $newstring = get_language_string_from_language_block($language_block, $onelanguage, $oldstring); 761 762 # if (!( $newstring eq "" )) { ${$idtfile}[$i] =~ s/$oldstring/$newstring/; } 763 ${$idtfile}[$i] =~ s/$oldstring/$newstring/; # always substitute, even if $newstring eq "" (there are empty strings for control.idt) 764 } 765 } 766} 767 768############################################################## 769# Copying all needed files to create a msi database 770# into one language specific directory 771############################################################## 772 773sub prepare_language_idt_directory 774{ 775 my ($destinationdir, $newidtdir, $onelanguage, $filesref, $iconfilecollector, $binarytablefiles, $allvariables) = @_; 776 777 # Copying all idt-files from the source $installer::globals::idttemplatepath to the destination $destinationdir 778 # Copying all files in the subdirectory "Binary" 779 # Copying all files in the subdirectory "Icon" 780 781 my $infoline = ""; 782 783 installer::systemactions::copy_directory($installer::globals::idttemplatepath, $destinationdir); 784 785 if ( -d $installer::globals::idttemplatepath . $installer::globals::separator . "Binary") 786 { 787 installer::systemactions::create_directory($destinationdir . $installer::globals::separator . "Binary"); 788 installer::systemactions::copy_directory($installer::globals::idttemplatepath . $installer::globals::separator . "Binary", $destinationdir . $installer::globals::separator . "Binary"); 789 790 if ((( $installer::globals::patch ) && ( $allvariables->{'WINDOWSPATCHBITMAPDIRECTORY'} )) || ( $allvariables->{'WINDOWSBITMAPDIRECTORY'} )) 791 { 792 my $bitmapdir = ""; 793 if ( $allvariables->{'WINDOWSPATCHBITMAPDIRECTORY'} ) { $bitmapdir = $allvariables->{'WINDOWSPATCHBITMAPDIRECTORY'}; } 794 if ( $allvariables->{'WINDOWSBITMAPDIRECTORY'} ) { $bitmapdir = $allvariables->{'WINDOWSBITMAPDIRECTORY'}; } 795 796 my $newsourcedir = $installer::globals::unpackpath . $installer::globals::separator . $bitmapdir; # path setting in list file dependent from unpackpath !? 797 $infoline = "\nOverwriting files in directory \"" . $destinationdir . $installer::globals::separator . "Binary" . "\" with files from directory \"" . $newsourcedir . "\".\n"; 798 push( @installer::globals::logfileinfo, $infoline); 799 if ( ! -d $newsourcedir ) 800 { 801 my $currentdir = cwd(); 802 installer::exiter::exit_program("ERROR: Directory $newsourcedir does not exist! Current directory is: $currentdir", "prepare_language_idt_directory"); 803 } 804 installer::systemactions::copy_directory($newsourcedir, $destinationdir . $installer::globals::separator . "Binary"); 805 } 806 } 807 808 installer::systemactions::create_directory($destinationdir . $installer::globals::separator . "Icon"); 809 810 if ( -d $installer::globals::idttemplatepath . $installer::globals::separator . "Icon") 811 { 812 installer::systemactions::copy_directory($installer::globals::idttemplatepath . $installer::globals::separator . "Icon", $destinationdir . $installer::globals::separator . "Icon"); 813 } 814 815 # Copying all files in $iconfilecollector, that describe icons of folderitems 816 817 for ( my $i = 0; $i <= $#{$iconfilecollector}; $i++ ) 818 { 819 my $iconfilename = ${$iconfilecollector}[$i]; 820 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$iconfilename); 821 installer::systemactions::copy_one_file(${$iconfilecollector}[$i], $destinationdir . $installer::globals::separator . "Icon" . $installer::globals::separator . $iconfilename); 822 } 823 824 # Copying all files in $binarytablefiles in the binary directory 825 826 for ( my $i = 0; $i <= $#{$binarytablefiles}; $i++ ) 827 { 828 my $binaryfile = ${$binarytablefiles}[$i]; 829 my $binaryfilepath = $binaryfile->{'sourcepath'}; 830 my $binaryfilename = $binaryfilepath; 831 installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$binaryfilename); 832 installer::systemactions::copy_one_file($binaryfilepath, $destinationdir . $installer::globals::separator . "Binary" . $installer::globals::separator . $binaryfilename); 833 } 834 835 # Copying all new created and language independent idt-files to the destination $destinationdir. 836 # Example: "File.idt" 837 838 installer::systemactions::copy_directory_with_fileextension($newidtdir, $destinationdir, "idt"); 839 840 # Copying all new created and language dependent idt-files to the destination $destinationdir. 841 # Example: "Feature.idt.01" 842 843 installer::systemactions::copy_directory_with_fileextension($newidtdir, $destinationdir, $onelanguage); 844 installer::systemactions::rename_files_with_fileextension($destinationdir, $onelanguage); 845 846} 847 848############################################################## 849# Returning the source path of the rtf licensefile for 850# a specified language 851############################################################## 852 853sub get_rtflicensefilesource 854{ 855 my ($language, $includepatharrayref) = @_; 856 857 my $licensefilename = "license_" . $language . ".rtf"; 858 859 my $sourcefileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$licensefilename, $includepatharrayref, 1); 860 861 if ($$sourcefileref eq "") { installer::exiter::exit_program("ERROR: Could not find $licensefilename!", "get_rtflicensefilesource"); } 862 863 my $infoline = "Using licensefile: $$sourcefileref\n"; 864 push( @installer::globals::logfileinfo, $infoline); 865 866 return $$sourcefileref; 867} 868 869############################################################## 870# Returning the source path of the licensefile for 871# a specified language 872############################################################## 873 874sub get_licensefilesource 875{ 876 my ($language, $filesref) = @_; 877 878 my $licensefilename = "license_" . $language . ".txt"; 879 my $sourcepath = ""; 880 my $foundlicensefile = 0; 881 882 for ( my $i = 0; $i <= $#{$filesref}; $i++ ) 883 { 884 my $onefile = ${$filesref}[$i]; 885 my $filename = $onefile->{'Name'}; 886 887 if ($filename eq $licensefilename) 888 { 889 $sourcepath = $onefile->{'sourcepath'}; 890 $foundlicensefile = 1; 891 last; 892 } 893 } 894 895 if ( ! $foundlicensefile ) { installer::exiter::exit_program("ERROR: Did not find file $licensefilename in file collector!", "get_licensefilesource"); } 896 897 return $sourcepath; 898} 899 900############################################################## 901# A simple converter to create the license text 902# in rtf format 903############################################################## 904 905sub get_rtf_licensetext 906{ 907 my ($licensefile) = @_; 908 909 # A very simple rtf converter 910 911 # The static header 912 913 my $rtf_licensetext = '{\rtf1\ansi\deff0'; 914 $rtf_licensetext = $rtf_licensetext . '{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}}'; 915 $rtf_licensetext = $rtf_licensetext . '{\colortbl\red0\green0\blue0;\red255\green255\blue255;\red128\green128\blue128;}'; 916 $rtf_licensetext = $rtf_licensetext . '{\stylesheet{\s1\snext1 Standard;}}'; 917 $rtf_licensetext = $rtf_licensetext . '{\info{\comment StarWriter}{\vern5690}}\deftab709'; 918 $rtf_licensetext = $rtf_licensetext . '{\*\pgdsctbl'; 919 $rtf_licensetext = $rtf_licensetext . '{\pgdsc0\pgdscuse195\pgwsxn11905\pghsxn16837\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\pgdscnxt0 Standard;}}'; 920 $rtf_licensetext = $rtf_licensetext . '\paperh16837\paperw11905\margl1134\margr1134\margt1134\margb1134\sectd\sbknone\pgwsxn11905\pghsxn16837\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc'; 921 $rtf_licensetext = $rtf_licensetext . '\pard\plain \s1'; 922 923 for ( my $i = 0; $i <= $#{$licensefile}; $i++ ) 924 { 925 my $oneline = ${$licensefile}[$i]; 926 # if ( $oneline =~ /^\s*$/ ) { $oneline = '\par'; } # empty lines 927 928 if ( $i == 0 ) { $oneline =~ s/^\W*//; } 929 930 $oneline =~ s/\t/ /g; # no tabs allowed, converting to four spaces 931 $oneline =~ s/\n$//g; # no newline at line end 932 933# $oneline =~ s/�/\\\'e4/g; # converting "�" 934# $oneline =~ s/�/\\\'f6/g; # converting "�" 935# $oneline =~ s/�/\\\'fc/g; # converting "�" 936# $oneline =~ s/�/\\\'df/g; # converting "�" 937 938 # german replacements 939 940 $oneline =~ s/\�\�/\\\'c4/g; # converting "�" 941 $oneline =~ s/\�\�/\\\'d6/g; # converting "�" 942 $oneline =~ s/\�\�/\\\'dc/g; # converting "�" 943 $oneline =~ s/\�\�/\\\'e4/g; # converting "�" 944 $oneline =~ s/\�\�/\\\'f6/g; # converting "�" 945 $oneline =~ s/\�\�/\\\'fc/g; # converting "�" 946 $oneline =~ s/\�\�/\\\'df/g; # converting "�" 947 948 # french replacements 949 950 $oneline =~ s/\�\�/\\\'c9/g; 951 $oneline =~ s/\�\�/\\\'c0/g; 952 $oneline =~ s/\�\�/\\\'ab/g; 953 $oneline =~ s/\�\�/\\\'bb/g; 954 $oneline =~ s/\�\�/\\\'e9/g; 955 $oneline =~ s/\�\�/\\\'e8/g; 956 $oneline =~ s/\�\�/\\\'e0/g; 957 $oneline =~ s/\�\�/\\\'f4/g; 958 $oneline =~ s/\�\�/\\\'e7/g; 959 $oneline =~ s/\�\�/\\\'ea/g; 960 $oneline =~ s/\�\�/\\\'ca/g; 961 $oneline =~ s/\�\�/\\\'fb/g; 962 $oneline =~ s/\�\�/\\\'f9/g; 963 $oneline =~ s/\�\�/\\\'ee/g; 964 965 # quotation marks 966 967 $oneline =~ s/\�\�\�/\\\'84/g; 968 $oneline =~ s/\�\�\�/\\ldblquote/g; 969 $oneline =~ s/\�\�\�/\\rquote/g; 970 971 972 $oneline =~ s/\�\�/\\\~/g; 973 974 $oneline = '\par ' . $oneline; 975 976 $rtf_licensetext = $rtf_licensetext . $oneline; 977 } 978 979 # and the end 980 981 $rtf_licensetext = $rtf_licensetext . '\par \par }'; 982 983 return $rtf_licensetext; 984} 985 986############################################################## 987# A simple converter to create a license txt string from 988# the rtf format 989############################################################## 990 991sub make_string_licensetext 992{ 993 my ($licensefile) = @_; 994 995 my $rtf_licensetext = ""; 996 997 for ( my $i = 0; $i <= $#{$licensefile}; $i++ ) 998 { 999 my $oneline = ${$licensefile}[$i]; 1000 $oneline =~ s/\s*$//g; # no whitespace at line end 1001 1002 $rtf_licensetext = $rtf_licensetext . $oneline . " "; 1003 } 1004 1005 return $rtf_licensetext; 1006} 1007 1008############################################################## 1009# Setting the path, where the soffice.exe is installed, into 1010# the CustomAction table 1011############################################################## 1012 1013sub add_officedir_to_database 1014{ 1015 my ($basedir, $allvariables) = @_; 1016 1017 my $customactionfilename = $basedir . $installer::globals::separator . "CustomAc.idt"; 1018 1019 my $customacfile = installer::files::read_file($customactionfilename); 1020 1021 my $found = 0; 1022 1023 # Updating the values 1024 1025 if ( $installer::globals::officeinstalldirectoryset ) 1026 { 1027 $found = 0; 1028 1029 for ( my $i = 0; $i <= $#{$customacfile}; $i++ ) 1030 { 1031 if ( ${$customacfile}[$i] =~ /\bOFFICEDIRECTORYGID\b/ ) 1032 { 1033 ${$customacfile}[$i] =~ s/\bOFFICEDIRECTORYGID\b/$installer::globals::officeinstalldirectory/; 1034 $found = 1; 1035 } 1036 } 1037 1038 if (( ! $found ) && ( ! $allvariables->{'IGNOREDIRECTORYLAYER'} )) 1039 { 1040 installer::exiter::exit_program("ERROR: \"OFFICEDIRECTORYGID\" not found in \"$customactionfilename\" !", "add_officedir_to_database"); 1041 } 1042 } 1043 1044 # Saving the file 1045 1046 installer::files::save_file($customactionfilename ,$customacfile); 1047 my $infoline = "Updated idt file: $customactionfilename\n"; 1048 push(@installer::globals::logfileinfo, $infoline); 1049 1050} 1051 1052############################################################## 1053# Including the license text into the table control.idt 1054############################################################## 1055 1056sub add_licensefile_to_database 1057{ 1058 my ($licensefile, $controltable) = @_; 1059 1060 # Nine tabs before the license text and two tabs after it 1061 # The license text has to be included into the dialog 1062 # LicenseAgreement into the control Memo. 1063 1064 my $foundlicenseline = 0; 1065 my ($number, $line); 1066 1067 for ( my $i = 0; $i <= $#{$controltable}; $i++ ) 1068 { 1069 $line = ${$controltable}[$i]; 1070 1071 if ( $line =~ /^\s*\bLicenseAgreement\b\t\bMemo\t/ ) 1072 { 1073 $foundlicenseline = 1; 1074 $number = $i; 1075 last; 1076 } 1077 } 1078 1079 if (!($foundlicenseline)) 1080 { 1081 installer::exiter::exit_program("ERROR: Line for license file in Control.idt not found!", "add_licensefile_to_database"); 1082 } 1083 else 1084 { 1085 my %control = (); 1086 1087 if ( $line =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ ) 1088 { 1089 $control{'Dialog_'} = $1; 1090 $control{'Control'} = $2; 1091 $control{'Type'} = $3; 1092 $control{'X'} = $4; 1093 $control{'Y'} = $5; 1094 $control{'Width'} = $6; 1095 $control{'Height'} = $7; 1096 $control{'Attributes'} = $8; 1097 $control{'Property'} = $9; 1098 $control{'Text'} = $10; 1099 $control{'Control_Next'} = $11; 1100 $control{'Help'} = $12; 1101 } 1102 else 1103 { 1104 installer::exiter::exit_program("ERROR: Could not split line correctly!", "add_licensefile_to_database"); 1105 } 1106 1107 # my $licensetext = get_rtf_licensetext($licensefile); 1108 my $licensetext = make_string_licensetext($licensefile); 1109 1110 $control{'Text'} = $licensetext; 1111 1112 my $newline = $control{'Dialog_'} . "\t" . $control{'Control'} . "\t" . $control{'Type'} . "\t" . 1113 $control{'X'} . "\t" . $control{'Y'} . "\t" . $control{'Width'} . "\t" . 1114 $control{'Height'} . "\t" . $control{'Attributes'} . "\t" . $control{'Property'} . "\t" . 1115 $control{'Text'} . "\t" . $control{'Control_Next'} . "\t" . $control{'Help'} . "\n"; 1116 1117 ${$controltable}[$number] = $newline 1118 } 1119} 1120 1121################################################################################################ 1122# Including the checkboxes for the language selection dialog 1123# into the table control.idt . This is only relevant for 1124# multilingual installation sets. 1125# 1126# old: 1127# LanguageSelection CheckBox1 CheckBox 22 60 15 24 3 IS1033 CheckBox2 1128# LanguageSelection Text1 Text 40 60 70 15 65539 OOO_CONTROL_LANG_1033 1129# LanguageSelection CheckBox2 CheckBox 22 90 15 24 3 IS1031 Next 1130# LanguageSelection Text2 Text 40 90 70 15 65539 OOO_CONTROL_LANG_1031 1131# new: 1132# LanguageSelection CheckBox1 CheckBox 22 60 15 24 3 IS1033 Text CheckBox2 1133# LanguageSelection CheckBox2 CheckBox 22 90 15 24 3 IS1031 Text Next 1134################################################################################################ 1135 1136sub add_language_checkboxes_to_database 1137{ 1138 my ($controltable, $languagesarrayref) = @_; 1139 1140 # for each language, two lines have to be inserted 1141 1142 for ( my $i = 0; $i <= $#{$languagesarrayref}; $i++ ) 1143 { 1144 my $last = 0; 1145 if ( $i == $#{$languagesarrayref} ) { $last = 1; } # special handling for the last 1146 1147 my $onelanguage = ${$languagesarrayref}[$i]; 1148 my $windowslanguage = installer::windows::language::get_windows_language($onelanguage); 1149 1150 # my $is_english = 0; 1151 # if ( $windowslanguage eq "1033" ) { $is_english = 1; } 1152 1153 my $checkboxattribute = "3"; 1154 # if ( $is_english ) { $checkboxattribute = "1"; } # english is not deselectable 1155 1156 my $count = $i + 1; 1157 my $nextcount = $i + 2; 1158 my $checkboxcount = "CheckBox" . $count; 1159 1160 my $multiplier = 20; 1161 my $offset = 60; 1162 if ( $#{$languagesarrayref} > 7 ) 1163 { 1164 $multiplier = 15; # smaller differences for more than 7 languages 1165 $offset = 50; # smaller offset for more than 7 languages 1166 } 1167 1168 my $yvalue = $offset + $i * $multiplier; 1169 1170 my $property = "IS" . $windowslanguage; 1171 # if ( ! exists($installer::globals::languageproperties{$property}) ) { installer::exiter::exit_program("ERROR: Could not find property \"$property\" in the list of language properties!", "add_language_checkboxes_to_database"); } 1172 1173 my $controlnext = ""; 1174 if ( $last ) { $controlnext = "Next"; } 1175 else { $controlnext = "CheckBox" . $nextcount; } 1176 1177 my $stringname = "OOO_CONTROL_LANG_" . $windowslanguage; 1178 1179 my $line1 = "LanguageSelection" . "\t" . $checkboxcount . "\t" . "CheckBox" . "\t" . 1180 "22" . "\t" . $yvalue . "\t" . "200" . "\t" . "15" . "\t" . $checkboxattribute . "\t" . 1181 $property . "\t" . $stringname . "\t" . $controlnext . "\t" . "\n"; 1182 1183 push(@{$controltable}, $line1); 1184 1185 # my $textcount = "Text" . $count; 1186 # my $stringname = "OOO_CONTROL_LANG_" . $windowslanguage; 1187 # 1188 # $yvalue = $yvalue + 2; # text 2 pixel lower than checkbox 1189 # 1190 # my $line2 = "LanguageSelection" . "\t" . $textcount . "\t" . "Text" . "\t" . 1191 # "40" . "\t" . $yvalue . "\t" . "70" . "\t" . "15" . "\t" . "65539" . "\t" . 1192 # "\t" . $stringname . "\t" . "\t" . "\n"; 1193 # 1194 # push(@{$controltable}, $line2); 1195 } 1196} 1197 1198################################################################### 1199# Determining the last position in a sequencetable 1200# into the tables CustomAc.idt and InstallE.idt. 1201################################################################### 1202 1203sub get_last_position_in_sequencetable 1204{ 1205 my ($sequencetable) = @_; 1206 1207 my $position = 0; 1208 1209 for ( my $i = 0; $i <= $#{$sequencetable}; $i++ ) 1210 { 1211 my $line = ${$sequencetable}[$i]; 1212 1213 if ( $line =~ /^\s*\w+\t.*\t\s*(\d+)\s$/ ) 1214 { 1215 my $newposition = $1; 1216 if ( $newposition > $position ) { $position = $newposition; } 1217 } 1218 } 1219 1220 return $position; 1221} 1222 1223######################################################################### 1224# Determining the position of a specified Action in the sequencetable 1225######################################################################### 1226 1227sub get_position_in_sequencetable 1228{ 1229 my ($action, $sequencetable) = @_; 1230 1231 my $position = 0; 1232 1233 $action =~ s/^\s*behind_//; 1234 1235 for ( my $i = 0; $i <= $#{$sequencetable}; $i++ ) 1236 { 1237 my $line = ${$sequencetable}[$i]; 1238 1239 if ( $line =~ /^\s*(\w+)\t.*\t\s*(\d+)\s$/ ) 1240 { 1241 my $compareaction = $1; 1242 $position = $2; 1243 if ( $compareaction eq $action ) { last; } 1244 } 1245 } 1246 1247 return $position; 1248} 1249 1250################################################################################################ 1251# Including the CustomAction for the configuration 1252# into the tables CustomAc.idt and InstallE.idt. 1253# 1254# CustomAc.idt: ExecutePkgchk 82 pkgchk.exe -s 1255# InstallE.idt: ExecutePkgchk Not REMOVE="ALL" 3175 1256# 1257# CustomAc.idt: ExecuteQuickstart 82 install_quickstart.exe 1258# InstallE.idt: ExecuteQuickstart &gm_o_Quickstart=3 3200 1259# 1260# CustomAc.idt: ExecuteInstallRegsvrex 82 regsvrex.exe shlxthdl.dll 1261# InstallE.idt: ExecuteInstallRegsvrex Not REMOVE="ALL" 3225 1262# 1263# CustomAc.idt: ExecuteUninstallRegsvrex 82 regsvrex.exe /u shlxthdl.dll 1264# InstallE.idt: ExecuteUninstallRegsvrex REMOVE="ALL" 690 1265# 1266# CustomAc.idt: Regmsdocmsidll1 1 reg4msdocmsidll Reg4MsDocEntry 1267# InstallU.idt: Regmsdocmsidll1 Not REMOVE="ALL" 610 1268# 1269# CustomAc.idt: Regmsdocmsidll2 1 reg4msdocmsidll Reg4MsDocEntry 1270# InstallE.idt: Regmsdocmsidll2 Not REMOVE="ALL" 3160 1271################################################################################################ 1272 1273sub set_custom_action 1274{ 1275 my ($customactionidttable, $actionname, $actionflags, $exefilename, $actionparameter, $inbinarytable, $filesref, $customactionidttablename, $styles) = @_; 1276 1277 my $included_customaction = 0; 1278 my $infoline = ""; 1279 my $customaction_exefilename = $exefilename; 1280 my $uniquename = ""; 1281 1282 # when the style NO_FILE is set, no searching for the file is needed, no filtering is done, we can add that custom action 1283 if ( $styles =~ /\bNO_FILE\b/ ) 1284 { 1285 my $line = $actionname . "\t" . $actionflags . "\t" . $customaction_exefilename . "\t" . $actionparameter . "\n"; 1286 push(@{$customactionidttable}, $line); 1287 1288 $infoline = "Added $actionname CustomAction into table $customactionidttablename (NO_FILE has been set)\n"; 1289 push(@installer::globals::logfileinfo, $infoline); 1290 1291 $included_customaction = 1; 1292 return $included_customaction; 1293 } 1294 1295 # is the $exefilename a library that is included into the binary table 1296 1297 if ( $inbinarytable ) { $customaction_exefilename =~ s/\.//; } # this is the entry in the binary table ("abc.dll" -> "abcdll") 1298 1299 # is the $exefilename included into the product? 1300 1301 my $contains_file = 0; 1302 1303 # All files are located in $filesref and in @installer::globals::binarytableonlyfiles. 1304 # Both must be added together 1305 my $localfilesref = installer::converter::combine_arrays_from_references(\@installer::globals::binarytableonlyfiles, $filesref); 1306 1307 for ( my $i = 0; $i <= $#{$localfilesref}; $i++ ) 1308 { 1309 my $onefile = ${$localfilesref}[$i]; 1310 my $filename = ""; 1311 if ( exists($onefile->{'Name'}) ) 1312 { 1313 $filename = $onefile->{'Name'}; 1314 1315 if ( $filename eq $exefilename ) 1316 { 1317 $contains_file = 1; 1318 $uniquename = ${$localfilesref}[$i]->{'uniquename'}; 1319 last; 1320 } 1321 } 1322 else 1323 { 1324 installer::exiter::exit_program("ERROR: Did not find \"Name\" for file \"$onefile->{'uniquename'}\" ($onefile->{'gid'})!", "set_custom_action"); 1325 } 1326 } 1327 1328 if ( $contains_file ) 1329 { 1330 # Now the CustomAction can be included into the CustomAc.idt 1331 1332 if ( ! $inbinarytable ) { $customaction_exefilename = $uniquename; } # the unique file name has to be added to the custom action table 1333 1334 my $line = $actionname . "\t" . $actionflags . "\t" . $customaction_exefilename . "\t" . $actionparameter . "\n"; 1335 push(@{$customactionidttable}, $line); 1336 1337 $included_customaction = 1; 1338 } 1339 1340 if ( $included_customaction ) { $infoline = "Added $actionname CustomAction into table $customactionidttablename\n"; } 1341 else { $infoline = "Did not add $actionname CustomAction into table $customactionidttablename\n"; } 1342 push(@installer::globals::logfileinfo, $infoline); 1343 1344 return $included_customaction; 1345} 1346 1347#################################################################### 1348# Adding a Custom Action to InstallExecuteTable or InstallUITable 1349#################################################################### 1350 1351sub add_custom_action_to_install_table 1352{ 1353 my ($installtable, $exefilename, $actionname, $actioncondition, $position, $filesref, $installtablename, $styles) = @_; 1354 1355 my $included_customaction = 0; 1356 my $feature = ""; 1357 my $infoline = ""; 1358 1359 # when the style NO_FILE is set, no searching for the file is needed, no filtering is done, we can add that custom action 1360 if ( $styles =~ /\bNO_FILE\b/ ) 1361 { 1362 # then the InstallE.idt.idt or InstallU.idt.idt 1363 $actioncondition =~ s/FEATURETEMPLATE/$feature/g; # only execute Custom Action, if feature of the file is installed 1364 1365 my $actionposition = 0; 1366 1367 if ( $position eq "end" ) { $actionposition = get_last_position_in_sequencetable($installtable) + 25; } 1368 elsif ( $position =~ /^\s*behind_/ ) { $actionposition = get_position_in_sequencetable($position, $installtable) + 2; } 1369 else { $actionposition = get_position_in_sequencetable($position, $installtable) - 2; } 1370 1371 my $line = $actionname . "\t" . $actioncondition . "\t" . $actionposition . "\n"; 1372 push(@{$installtable}, $line); 1373 1374 $infoline = "Added $actionname CustomAction into table $installtablename (NO_FILE has been set)\n"; 1375 push(@installer::globals::logfileinfo, $infoline); 1376 return; 1377 } 1378 1379 my $contains_file = 0; 1380 1381 # All files are located in $filesref and in @installer::globals::binarytableonlyfiles. 1382 # Both must be added together 1383 my $localfilesref = installer::converter::combine_arrays_from_references(\@installer::globals::binarytableonlyfiles, $filesref); 1384 1385 for ( my $i = 0; $i <= $#{$localfilesref}; $i++ ) 1386 { 1387 my $filename = ${$localfilesref}[$i]->{'Name'}; 1388 1389 if ( $filename eq $exefilename ) 1390 { 1391 $contains_file = 1; 1392 1393 # Determining the feature of the file 1394 1395 if ( ${$localfilesref}[$i] ) { $feature = ${$localfilesref}[$i]->{'modules'}; } 1396 1397 # If modules contains a list of modules, only taking the first one. 1398 if ( $feature =~ /^\s*(.*?)\,/ ) { $feature = $1; } 1399 # Attention: Maximum feature length is 38! 1400 shorten_feature_gid(\$feature); 1401 1402 last; 1403 } 1404 } 1405 1406 if ( $contains_file ) 1407 { 1408 # then the InstallE.idt.idt or InstallU.idt.idt 1409 1410 $actioncondition =~ s/FEATURETEMPLATE/$feature/g; # only execute Custom Action, if feature of the file is installed 1411 1412# my $actionposition = 0; 1413# if ( $position eq "end" ) { $actionposition = get_last_position_in_sequencetable($installtable) + 25; } 1414# elsif ( $position =~ /^\s*behind_/ ) { $actionposition = get_position_in_sequencetable($position, $installtable) + 2; } 1415# else { $actionposition = get_position_in_sequencetable($position, $installtable) - 2; } 1416# my $line = $actionname . "\t" . $actioncondition . "\t" . $actionposition . "\n"; 1417 1418 my $positiontemplate = ""; 1419 if ( $position =~ /^\s*\d+\s*$/ ) { $positiontemplate = $position; } # setting the position directly, number defined in scp2 1420 else { $positiontemplate = "POSITIONTEMPLATE_" . $position; } 1421 1422 my $line = $actionname . "\t" . $actioncondition . "\t" . $positiontemplate . "\n"; 1423 push(@{$installtable}, $line); 1424 1425 $included_customaction = 1; 1426 } 1427 1428 if ( $included_customaction ) { $infoline = "Added $actionname CustomAction into table $installtablename\n"; } 1429 else { $infoline = "Did not add $actionname CustomAction into table $installtablename\n"; } 1430 push(@installer::globals::logfileinfo, $infoline); 1431 1432} 1433 1434################################################################## 1435# A line in the table ControlEvent connects a Control 1436# with a Custom Action 1437################################################################# 1438 1439sub connect_custom_action_to_control 1440{ 1441 my ( $table, $tablename, $dialog, $control, $event, $argument, $condition, $ordering) = @_; 1442 1443 my $line = $dialog . "\t" . $control. "\t" . $event. "\t" . $argument. "\t" . $condition. "\t" . $ordering . "\n"; 1444 1445 push(@{$table}, $line); 1446 1447 $line =~ s/\s*$//g; 1448 1449 $infoline = "Added line \"$line\" into table $tablename\n"; 1450 push(@installer::globals::logfileinfo, $infoline); 1451} 1452 1453################################################################## 1454# A line in the table ControlCondition connects a Control state 1455# with a condition 1456################################################################## 1457 1458sub connect_condition_to_control 1459{ 1460 my ( $table, $tablename, $dialog, $control, $event, $condition) = @_; 1461 1462 my $line = $dialog . "\t" . $control. "\t" . $event. "\t" . $condition. "\n"; 1463 1464 push(@{$table}, $line); 1465 1466 $line =~ s/\s*$//g; 1467 1468 $infoline = "Added line \"$line\" into table $tablename\n"; 1469 push(@installer::globals::logfileinfo, $infoline); 1470} 1471 1472################################################################## 1473# Searching for a sequencenumber in InstallUISequence table 1474# "ExecuteAction" must be the last action 1475################################################################## 1476 1477sub get_free_number_in_uisequence_table 1478{ 1479 my ( $installuitable ) = @_; 1480 1481 # determining the sequence of "ExecuteAction" 1482 1483 my $executeactionnumber = 0; 1484 1485 for ( my $i = 0; $i <= $#{$installuitable}; $i++ ) 1486 { 1487 if ( ${$installuitable}[$i] =~ /^\s*(\w+)\t\w*\t(\d+)\s*$/ ) 1488 { 1489 my $actionname = $1; 1490 my $actionnumber = $2; 1491 1492 if ( $actionname eq "ExecuteAction" ) 1493 { 1494 $executeactionnumber = $actionnumber; 1495 last; 1496 } 1497 } 1498 } 1499 1500 if ( $executeactionnumber == 0 ) { installer::exiter::exit_program("ERROR: Did not find \"ExecuteAction\" in InstallUISequence table!", "get_free_number_in_uisequence_table"); } 1501 1502 # determining the sequence of the action before "ExecuteAction" 1503 1504 my $lastactionnumber = 0; 1505 1506 for ( my $i = 0; $i <= $#{$installuitable}; $i++ ) 1507 { 1508 if ( ${$installuitable}[$i] =~ /^\s*\w+\t\w*\t(\d+)\s*$/ ) 1509 { 1510 my $actionnumber = $1; 1511 1512 if (( $actionnumber > $lastactionnumber ) && ( $actionnumber != $executeactionnumber )) 1513 { 1514 $lastactionnumber = $actionnumber; 1515 } 1516 } 1517 } 1518 1519 # the new number can now be calculated 1520 1521 my $newnumber = 0; 1522 1523 if ((( $lastactionnumber + $executeactionnumber ) % 2 ) == 0 ) { $newnumber = ( $lastactionnumber + $executeactionnumber ) / 2; } 1524 else { $newnumber = ( $lastactionnumber + $executeactionnumber -1 ) / 2; } 1525 1526 return $newnumber; 1527} 1528 1529################################################################## 1530# Searching for a specified string in the feature table 1531################################################################## 1532 1533sub get_feature_name 1534{ 1535 my ( $string, $featuretable ) = @_; 1536 1537 my $featurename = ""; 1538 1539 for ( my $i = 0; $i <= $#{$featuretable}; $i++ ) 1540 { 1541 if ( ${$featuretable}[$i] =~ /^\s*(\w+$string)\t/ ) 1542 { 1543 $featurename = $1; 1544 last; 1545 } 1546 } 1547 1548 return $featurename; 1549} 1550 1551###################################################################### 1552# Returning the toplevel directory name of one specific file 1553###################################################################### 1554 1555sub get_directory_name_from_file 1556{ 1557 my ($onefile) = @_; 1558 1559 my $destination = $onefile->{'destination'}; 1560 my $name = $onefile->{'Name'}; 1561 1562 $destination =~ s/\Q$name\E\s*$//; 1563 $destination =~ s/\Q$installer::globals::separator\E\s*$//; 1564 1565 my $path = ""; 1566 1567 if ( $destination =~ /\Q$installer::globals::separator\E/ ) 1568 { 1569 if ( $destination =~ /^\s*(\S.*\S\Q$installer::globals::separator\E)(\S.+\S?)/ ) 1570 { 1571 $path = $2; 1572 } 1573 } 1574 else 1575 { 1576 $path = $destination; 1577 } 1578 1579 return $path; 1580} 1581 1582############################################################# 1583# Including the new subdir into the directory table 1584############################################################# 1585 1586sub include_subdirname_into_directory_table 1587{ 1588 my ($dirname, $directorytable, $directorytablename, $onefile) = @_; 1589 1590 my $subdir = ""; 1591 if ( $onefile->{'Subdir'} ) { $subdir = $onefile->{'Subdir'}; } 1592 if ( $subdir eq "" ) { installer::exiter::exit_program("ERROR: No \"Subdir\" defined for $onefile->{'Name'}", "include_subdirname_into_directory_table"); } 1593 1594 # program INSTALLLOCATION program -> subjava INSTALLLOCATION program:java 1595 1596 my $uniquename = ""; 1597 my $parent = ""; 1598 my $name = ""; 1599 1600 my $includedline = 0; 1601 1602 my $newdir = ""; 1603 1604 for ( my $i = 0; $i <= $#{$directorytable}; $i++ ) 1605 { 1606 1607 if ( ${$directorytable}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\s*$/ ) 1608 { 1609 $uniquename = $1; 1610 $parent = $2; 1611 $name = $3; 1612 1613 if ( $dirname eq $name ) 1614 { 1615 my $newuniquename = "sub" . $subdir; 1616 $newdir = $newuniquename; 1617 # my $newparent = $parent; 1618 my $newparent = "INSTALLLOCATION"; 1619 my $newname = $name . "\:" . $subdir; 1620 my $newline = 1621 $line = "$newuniquename\t$newparent\t$newname\n"; 1622 push(@{$directorytable}, $line); 1623 installer::remover::remove_leading_and_ending_whitespaces(\$line); 1624 $infoline = "Added $line into directory table $directorytablename\n"; 1625 push(@installer::globals::logfileinfo, $infoline); 1626 1627 $includedline = 1; 1628 last; 1629 } 1630 } 1631 } 1632 1633 if ( ! $includedline ) { installer::exiter::exit_program("ERROR: Could not include new subdirectory into directory table for file $onefile->{'Name'}!", "include_subdirname_into_directory_table"); } 1634 1635 return $newdir; 1636} 1637 1638################################################################## 1639# Including the new sub directory into the component table 1640################################################################## 1641 1642sub include_subdir_into_componenttable 1643{ 1644 my ($subdir, $onefile, $componenttable) = @_; 1645 1646 my $componentname = $onefile->{'componentname'}; 1647 1648 my $changeddirectory = 0; 1649 1650 for ( my $i = 0; $i <= $#{$componenttable}; $i++ ) 1651 { 1652 if ( ${$componenttable}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ ) 1653 { 1654 my $localcomponentname = $1; 1655 my $directory = $3; 1656 1657 if ( $componentname eq $localcomponentname ) 1658 { 1659 my $oldvalue = ${$componenttable}[$i]; 1660 ${$componenttable}[$i] =~ s/\b\Q$directory\E\b/$subdir/; 1661 my $newvalue = ${$componenttable}[$i]; 1662 1663 installer::remover::remove_leading_and_ending_whitespaces(\$oldvalue); 1664 installer::remover::remove_leading_and_ending_whitespaces(\$newvalue); 1665 $infoline = "Change in Component table: From \"$oldvalue\" to \"$newvalue\"\n"; 1666 push(@installer::globals::logfileinfo, $infoline); 1667 1668 $changeddirectory = 1; 1669 last; 1670 } 1671 } 1672 } 1673 1674 if ( ! $changeddirectory ) { installer::exiter::exit_program("ERROR: Could not change directory for component: $onefile->{'Name'}!", "include_subdir_into_componenttable"); } 1675 1676} 1677 1678################################################################################################ 1679# Including the content for the child installations 1680# into the tables: 1681# CustomAc.idt, InstallU.idt, Feature.idt 1682################################################################################################ 1683 1684sub add_childprojects 1685{ 1686 my ($languageidtdir, $filesref, $allvariables) = @_; 1687 1688 my $customactiontablename = $languageidtdir . $installer::globals::separator . "CustomAc.idt"; 1689 my $customactiontable = installer::files::read_file($customactiontablename); 1690 my $installuitablename = $languageidtdir . $installer::globals::separator . "InstallU.idt"; 1691 my $installuitable = installer::files::read_file($installuitablename); 1692 my $featuretablename = $languageidtdir . $installer::globals::separator . "Feature.idt"; 1693 my $featuretable = installer::files::read_file($featuretablename); 1694 my $directorytablename = $languageidtdir . $installer::globals::separator . "Director.idt"; 1695 my $directorytable = installer::files::read_file($directorytablename); 1696 my $componenttablename = $languageidtdir . $installer::globals::separator . "Componen.idt"; 1697 my $componenttable = installer::files::read_file($componenttablename); 1698 1699 my $infoline = ""; 1700 my $line = ""; 1701 1702 $installer::globals::javafile = installer::worker::return_first_item_with_special_flag($filesref ,"JAVAFILE"); 1703 $installer::globals::urefile = installer::worker::return_first_item_with_special_flag($filesref ,"UREFILE"); 1704 1705 if (( $installer::globals::javafile eq "" ) && ( $allvariables->{'JAVAPRODUCT'} )) { installer::exiter::exit_program("ERROR: No JAVAFILE found in files collector!", "add_childprojects"); } 1706 if (( $installer::globals::urefile eq "" ) && ( $allvariables->{'UREPRODUCT'} )) { installer::exiter::exit_program("ERROR: No UREFILE found in files collector!", "add_childprojects"); } 1707 1708 # Content for Directory table 1709 # SystemFolder TARGETDIR . 1710 1711 my $contains_systemfolder = 0; 1712 1713 for ( my $i = 0; $i <= $#{$directorytable}; $i++ ) 1714 { 1715 if ( ${$directorytable}[$i] =~ /^\s*SystemFolder\t/ ) 1716 { 1717 $contains_systemfolder = 1; 1718 last; 1719 } 1720 } 1721 1722 if ( ! $contains_systemfolder ) 1723 { 1724 $line = "SystemFolder\tTARGETDIR\t\.\n"; 1725 push(@{$directorytable}, $line); 1726 installer::remover::remove_leading_and_ending_whitespaces(\$line); 1727 $infoline = "Added $line into table $directorytablename\n"; 1728 } 1729 else 1730 { 1731 $infoline = "SystemFolder already exists in table $directorytablename\n"; 1732 } 1733 1734 push(@installer::globals::logfileinfo, $infoline); 1735 1736 # Additional content for the directory table 1737 # subjava INSTALLLOCATION program:java 1738 # subure INSTALLLOCATION program:ure 1739 1740 my $dirname = ""; 1741 my $subjavadir = ""; 1742 my $suburedir = ""; 1743 1744 if ( $allvariables->{'JAVAPRODUCT'} ) 1745 { 1746 $dirname = get_directory_name_from_file($installer::globals::javafile); 1747 $subjavadir = include_subdirname_into_directory_table($dirname, $directorytable, $directorytablename, $installer::globals::javafile); 1748 } 1749 1750 if ( $allvariables->{'UREPRODUCT'} ) 1751 { 1752 $dirname = get_directory_name_from_file($installer::globals::urefile); 1753 $suburedir = include_subdirname_into_directory_table($dirname, $directorytable, $directorytablename, $installer::globals::urefile); 1754 } 1755 1756 # Content for the Component table 1757 # The Java and Ada components have new directories 1758 1759 if ( $allvariables->{'JAVAPRODUCT'} ) { include_subdir_into_componenttable($subjavadir, $installer::globals::javafile, $componenttable); } 1760 if ( $allvariables->{'UREPRODUCT'} ) { include_subdir_into_componenttable($suburedir, $installer::globals::urefile, $componenttable); } 1761 1762 # Content for CustomAction table 1763 1764 if ( $allvariables->{'JAVAPRODUCT'} ) 1765 { 1766 $line = "InstallJava\t98\tSystemFolder\t[SourceDir]$installer::globals::javafile->{'Subdir'}\\$installer::globals::javafile->{'Name'} \/qb REBOOT=Suppress SPONSORS=0 DISABLEAD=1\n"; 1767 push(@{$customactiontable} ,$line); 1768 installer::remover::remove_leading_and_ending_whitespaces(\$line); 1769 $infoline = "Added $line into table $customactiontablename\n"; 1770 push(@installer::globals::logfileinfo, $infoline); 1771 } 1772 1773 if ( $allvariables->{'UREPRODUCT'} ) 1774 { 1775 $line = "InstallUre\t98\tSystemFolder\t$installer::globals::urefile->{'Subdir'}\\$installer::globals::urefile->{'Name'} /S\n"; 1776 push(@{$customactiontable} ,$line); 1777 installer::remover::remove_leading_and_ending_whitespaces(\$line); 1778 $infoline = "Added $line into table $customactiontablename\n"; 1779 push(@installer::globals::logfileinfo, $infoline); 1780 } 1781 1782 if ( $allvariables->{'JAVAPRODUCT'} ) 1783 { 1784 $line = "MaintenanceJava\t82\t$installer::globals::javafile->{'uniquename'}\t\/qb REBOOT=Suppress SPONSORS=0 DISABLEAD=1\n"; 1785 push(@{$customactiontable} ,$line); 1786 installer::remover::remove_leading_and_ending_whitespaces(\$line); 1787 $infoline = "Added $line into table $customactiontablename\n"; 1788 push(@installer::globals::logfileinfo, $infoline); 1789 } 1790 1791 if ( $allvariables->{'UREPRODUCT'} ) 1792 { 1793 $line = "MaintenanceUre\t82\t$installer::globals::urefile->{'uniquename'}\t\/S\n"; 1794 push(@{$customactiontable} ,$line); 1795 installer::remover::remove_leading_and_ending_whitespaces(\$line); 1796 $infoline = "Added $line into table $customactiontablename\n"; 1797 push(@installer::globals::logfileinfo, $infoline); 1798 } 1799 1800 # Content for InstallUISequence table 1801 # InstallAdabas &gm_o_Adabas=3 825 1802 # InstallJava &gm_o_Java=3 827 1803 1804 my $number = ""; 1805 my $featurename = ""; 1806 1807 if ( $allvariables->{'ADAPRODUCT'} ) 1808 { 1809 $number = get_free_number_in_uisequence_table($installuitable); 1810 $featurename = get_feature_name("_Adabas", $featuretable); 1811 $line = "InstallAdabas\t\&$featurename\=3 And Not Installed And Not PATCH\t$number\n"; 1812 push(@{$installuitable} ,$line); 1813 installer::remover::remove_leading_and_ending_whitespaces(\$line); 1814 $infoline = "Added $line into table $installuitablename\n"; 1815 push(@installer::globals::logfileinfo, $infoline); 1816 } 1817 1818 if ( $allvariables->{'JAVAPRODUCT'} ) 1819 { 1820 $number = get_free_number_in_uisequence_table($installuitable) + 2; 1821 $featurename = get_feature_name("_Java", $featuretable); 1822 if ( $featurename ) { $line = "InstallJava\t\&$featurename\=3 And Not Installed And JAVAPATH\=\"\" And Not PATCH\t$number\n"; } 1823 else { $line = "InstallJava\tNot Installed And JAVAPATH\=\"\" And Not PATCH\t$number\n"; } # feature belongs to root 1824 push(@{$installuitable} ,$line); 1825 installer::remover::remove_leading_and_ending_whitespaces(\$line); 1826 $infoline = "Added $line into table $installuitablename\n"; 1827 push(@installer::globals::logfileinfo, $infoline); 1828 } 1829 1830 if ( $allvariables->{'ADAPRODUCT'} ) 1831 { 1832 $number = get_free_number_in_uisequence_table($installuitable) + 4; 1833 $featurename = get_feature_name("_Adabas", $featuretable); 1834 $line = "MaintenanceAdabas\t\&$featurename\=3 And Installed And Not PATCH\t$number\n"; 1835 push(@{$installuitable} ,$line); 1836 installer::remover::remove_leading_and_ending_whitespaces(\$line); 1837 $infoline = "Added $line into table $installuitablename\n"; 1838 push(@installer::globals::logfileinfo, $infoline); 1839 } 1840 1841 if ( $allvariables->{'JAVAPRODUCT'} ) 1842 { 1843 $number = get_free_number_in_uisequence_table($installuitable) + 6; 1844 $featurename = get_feature_name("_Java", $featuretable); 1845 if ( $featurename ) { $line = "MaintenanceJava\t\&$featurename\=3 And Installed And JAVAPATH\=\"\" And Not PATCH\t$number\n"; } 1846 else { $line = "MaintenanceJava\tInstalled And JAVAPATH\=\"\" And Not PATCH\t$number\n"; } # feature belongs to root 1847 push(@{$installuitable} ,$line); 1848 installer::remover::remove_leading_and_ending_whitespaces(\$line); 1849 $infoline = "Added $line into table $installuitablename\n"; 1850 push(@installer::globals::logfileinfo, $infoline); 1851 } 1852 1853 if ( $allvariables->{'UREPRODUCT'} ) 1854 { 1855 $number = get_free_number_in_uisequence_table($installuitable) + 8; 1856 $featurename = get_feature_name("_Ure", $featuretable); 1857 if ( $featurename ) { $line = "InstallUre\t\&$featurename\=3 And Not Installed\t$number\n"; } 1858 else { $line = "InstallUre\tNot Installed\t$number\n"; } # feature belongs to root 1859 push(@{$installuitable} ,$line); 1860 installer::remover::remove_leading_and_ending_whitespaces(\$line); 1861 $infoline = "Added $line into table $installuitablename\n"; 1862 push(@installer::globals::logfileinfo, $infoline); 1863 } 1864 1865 if ( $allvariables->{'UREPRODUCT'} ) 1866 { 1867 $number = get_free_number_in_uisequence_table($installuitable) + 10; 1868 $featurename = get_feature_name("_Ure", $featuretable); 1869 if ( $featurename ) { $line = "MaintenanceUre\t\&$featurename\=3 And Installed\t$number\n"; } 1870 else { $line = "MaintenanceUre\tInstalled\t$number\n"; } # feature belongs to root 1871 push(@{$installuitable} ,$line); 1872 installer::remover::remove_leading_and_ending_whitespaces(\$line); 1873 $infoline = "Added $line into table $installuitablename\n"; 1874 push(@installer::globals::logfileinfo, $infoline); 1875 } 1876 1877 # Content for Feature table, better from scp (translation) 1878 # gm_o_java gm_optional Java 1.4.2 Description 2 200 1879 1880 installer::files::save_file($customactiontablename, $customactiontable); 1881 installer::files::save_file($installuitablename, $installuitable); 1882 installer::files::save_file($featuretablename, $featuretable); 1883 installer::files::save_file($directorytablename, $directorytable); 1884 installer::files::save_file($componenttablename, $componenttable); 1885} 1886 1887################################################################## 1888# Setting the encoding in all idt files. Replacing the 1889# variable WINDOWSENCODINGTEMPLATE 1890################################################################## 1891 1892sub setencoding 1893{ 1894 my ( $languageidtdir, $onelanguage ) = @_; 1895 1896 my $encoding = installer::windows::language::get_windows_encoding($onelanguage); 1897 1898 # collecting all idt files in the directory $languageidtdir and substituting the string 1899 1900 my $idtfiles = installer::systemactions::find_file_with_file_extension("idt", $languageidtdir); 1901 1902 for ( my $i = 0; $i <= $#{$idtfiles}; $i++ ) 1903 { 1904 my $onefilename = $languageidtdir . $installer::globals::separator . ${$idtfiles}[$i]; 1905 my $onefile = installer::files::read_file($onefilename); 1906 1907 for ( my $j = 0; $j <= $#{$onefile}; $j++ ) 1908 { 1909 ${$onefile}[$j] =~ s/WINDOWSENCODINGTEMPLATE/$encoding/g; 1910 } 1911 1912 installer::files::save_file($onefilename, $onefile); 1913 } 1914} 1915 1916################################################################## 1917# Setting the condition, that at least one module is selected. 1918# All modules with flag SHOW_MULTILINGUAL_ONLY were already 1919# collected. In table ControlE.idt, the string 1920# LANGUAGECONDITIONINSTALL needs to be replaced. 1921# Also for APPLICATIONCONDITIONINSTALL for the applications 1922# with flag APPLICATIONMODULE. 1923################################################################## 1924 1925sub set_multilanguageonly_condition 1926{ 1927 my ( $languageidtdir ) = @_; 1928 1929 my $onefilename = $languageidtdir . $installer::globals::separator . "ControlE.idt"; 1930 my $onefile = installer::files::read_file($onefilename); 1931 1932 # Language modules 1933 1934 my $condition = ""; 1935 1936 foreach my $module ( sort keys %installer::globals::multilingual_only_modules ) 1937 { 1938 $condition = $condition . " &$module=3 Or"; 1939 } 1940 1941 $condition =~ s/^\s*//; 1942 $condition =~ s/\s*Or\s*$//; # removing the ending "Or" 1943 1944 if ( $condition eq "" ) { $condition = "1"; } 1945 1946 for ( my $j = 0; $j <= $#{$onefile}; $j++ ) 1947 { 1948 ${$onefile}[$j] =~ s/LANGUAGECONDITIONINSTALL/$condition/; 1949 } 1950 1951 # Application modules 1952 1953 $condition = ""; 1954 1955 foreach my $module ( sort keys %installer::globals::application_modules ) 1956 { 1957 $condition = $condition . " &$module=3 Or"; 1958 } 1959 1960 $condition =~ s/^\s*//; 1961 $condition =~ s/\s*Or\s*$//; # removing the ending "Or" 1962 1963 if ( $condition eq "" ) { $condition = "1"; } 1964 1965 for ( my $j = 0; $j <= $#{$onefile}; $j++ ) 1966 { 1967 ${$onefile}[$j] =~ s/APPLICATIONCONDITIONINSTALL/$condition/; 1968 } 1969 1970 installer::files::save_file($onefilename, $onefile); 1971} 1972 1973############################################# 1974# Putting array values into hash 1975############################################# 1976 1977sub fill_assignment_hash 1978{ 1979 my ($gid, $name, $key, $assignmenthashref, $parameter, $tablename, $assignmentarray) = @_; 1980 1981 my $max = $parameter - 1; 1982 1983 if ( $max != $#{$assignmentarray} ) 1984 { 1985 my $definedparameter = $#{$assignmentarray} + 1; 1986 installer::exiter::exit_program("ERROR: gid: $gid, key: $key ! Wrong parameter in scp. For table $tablename $parameter parameter are required ! You defined: $definedparameter", "fill_assignment_hash"); 1987 } 1988 1989 for ( my $i = 0; $i <= $#{$assignmentarray}; $i++ ) 1990 { 1991 my $counter = $i + 1; 1992 my $key = "parameter". $counter; 1993 1994 my $localvalue = ${$assignmentarray}[$i]; 1995 installer::remover::remove_leading_and_ending_quotationmarks(\$localvalue); 1996 $localvalue =~ s/\\\"/\"/g; 1997 $localvalue =~ s/\\\!/\!/g; 1998 $localvalue =~ s/\\\&/\&/g; 1999 $localvalue =~ s/\\\</\</g; 2000 $localvalue =~ s/\\\>/\>/g; 2001 $assignmenthashref->{$key} = $localvalue; 2002 } 2003} 2004 2005########################################################################## 2006# Checking the assignment of a Windows CustomAction and putting it 2007# into a hash 2008########################################################################## 2009 2010sub create_customaction_assignment_hash 2011{ 2012 my ($gid, $name, $key, $assignmentarray) = @_; 2013 2014 my %assignment = (); 2015 my $assignmenthashref = \%assignment; 2016 2017 my $tablename = ${$assignmentarray}[0]; 2018 installer::remover::remove_leading_and_ending_quotationmarks(\$tablename); 2019 2020 my $tablename_defined = 0; 2021 my $parameter = 0; 2022 2023 if ( $tablename eq "InstallUISequence" ) 2024 { 2025 $tablename_defined = 1; 2026 $parameter = 3; 2027 fill_assignment_hash($gid, $name, $key, $assignmenthashref, $parameter, $tablename, $assignmentarray); 2028 } 2029 2030 if ( $tablename eq "InstallExecuteSequence" ) 2031 { 2032 $tablename_defined = 1; 2033 $parameter = 3; 2034 fill_assignment_hash($gid, $name, $key, $assignmenthashref, $parameter, $tablename, $assignmentarray); 2035 } 2036 2037 if ( $tablename eq "AdminExecuteSequence" ) 2038 { 2039 $tablename_defined = 1; 2040 $parameter = 3; 2041 fill_assignment_hash($gid, $name, $key, $assignmenthashref, $parameter, $tablename, $assignmentarray); 2042 } 2043 2044 if ( $tablename eq "ControlEvent" ) 2045 { 2046 $tablename_defined = 1; 2047 $parameter = 7; 2048 fill_assignment_hash($gid, $name, $key, $assignmenthashref, $parameter, $tablename, $assignmentarray); 2049 } 2050 2051 if ( $tablename eq "ControlCondition" ) 2052 { 2053 $tablename_defined = 1; 2054 $parameter = 5; 2055 fill_assignment_hash($gid, $name, $key, $assignmenthashref, $parameter, $tablename, $assignmentarray); 2056 } 2057 2058 if ( ! $tablename_defined ) 2059 { 2060 installer::exiter::exit_program("ERROR: gid: $gid, key: $key ! Unknown Windows CustomAction table: $tablename ! Currently supported: InstallUISequence, InstallExecuteSequence, ControlEvent, ControlCondition", "create_customaction_assignment_hash"); 2061 } 2062 2063 return $assignmenthashref; 2064} 2065 2066########################################################################## 2067# Finding the position of a specified CustomAction. 2068# If the CustomAction is not found, the return value is "-1". 2069# If the CustomAction position is not defined yet, 2070# the return value is also "-1". 2071########################################################################## 2072 2073sub get_customaction_position 2074{ 2075 my ($action, $sequencetable) = @_; 2076 2077 my $position = -1; 2078 2079 for ( my $i = 0; $i <= $#{$sequencetable}; $i++ ) 2080 { 2081 my $line = ${$sequencetable}[$i]; 2082 2083 if ( $line =~ /^\s*([\w\.]+)\t.*\t\s*(\d+)\s$/ ) # matching only, if position is a number! 2084 { 2085 my $compareaction = $1; 2086 my $localposition = $2; 2087 2088 if ( $compareaction eq $action ) 2089 { 2090 $position = $localposition; 2091 last; 2092 } 2093 } 2094 } 2095 2096 return $position; 2097} 2098 2099########################################################################## 2100# Setting the position of CustomActions in sequence tables. 2101# Replacing all occurences of "POSITIONTEMPLATE_" 2102########################################################################## 2103 2104sub set_positions_in_table 2105{ 2106 my ( $sequencetable, $tablename ) = @_; 2107 2108 my $infoline = "\nSetting positions in table \"$tablename\".\n"; 2109 push(@installer::globals::logfileinfo, $infoline); 2110 2111 # Step 1: Resolving all occurences of "POSITIONTEMPLATE_end" 2112 2113 my $lastposition = get_last_position_in_sequencetable($sequencetable); 2114 2115 for ( my $i = 0; $i <= $#{$sequencetable}; $i++ ) 2116 { 2117 if ( ${$sequencetable}[$i] =~ /^\s*([\w\.]+)\t.*\t\s*POSITIONTEMPLATE_end\s*$/ ) 2118 { 2119 my $customaction = $1; 2120 $lastposition = $lastposition + 25; 2121 ${$sequencetable}[$i] =~ s/POSITIONTEMPLATE_end/$lastposition/; 2122 $infoline = "Setting position \"$lastposition\" for custom action \"$customaction\".\n"; 2123 push(@installer::globals::logfileinfo, $infoline); 2124 } 2125 } 2126 2127 # Step 2: Resolving all occurences of "POSITIONTEMPLATE_abc" or "POSITIONTEMPLATE_behind_abc" 2128 # where abc is the name of the reference Custom Action. 2129 # This has to be done, until there is no more occurence of POSITIONTEMPLATE (success) 2130 # or there is no replacement in one circle (failure). 2131 2132 my $template_exists = 0; 2133 my $template_replaced = 0; 2134 my $counter = 0; 2135 2136 do 2137 { 2138 $template_exists = 0; 2139 $template_replaced = 0; 2140 $counter++; 2141 2142 for ( my $i = 0; $i <= $#{$sequencetable}; $i++ ) 2143 { 2144 if ( ${$sequencetable}[$i] =~ /^\s*([\w\.]+)\t.*\t\s*(POSITIONTEMPLATE_.*?)\s*$/ ) 2145 { 2146 my $onename = $1; 2147 my $templatename = $2; 2148 my $positionname = $templatename; 2149 my $customaction = $templatename; 2150 $customaction =~ s/POSITIONTEMPLATE_//; 2151 $template_exists = 1; 2152 2153 # Trying to find the correct number. 2154 # This can fail, if the custom action has no number 2155 2156 my $setbehind = 0; 2157 if ( $customaction =~ /^\s*behind_(.*?)\s*$/ ) 2158 { 2159 $customaction = $1; 2160 $setbehind = 1; 2161 } 2162 2163 my $position = get_customaction_position($customaction, $sequencetable); 2164 2165 if ( $position >= 0 ) # Found CustomAction and is has a position. Otherwise return value is "-1". 2166 { 2167 my $newposition = 0; 2168 if ( $setbehind ) { $newposition = $position + 2; } 2169 else { $newposition = $position - 2; } 2170 ${$sequencetable}[$i] =~ s/$templatename/$newposition/; 2171 $template_replaced = 1; 2172 $infoline = "Setting position \"$newposition\" for custom action \"$onename\" (scp: \"$positionname\" at position $position).\n"; 2173 push(@installer::globals::logfileinfo, $infoline); 2174 } 2175 else 2176 { 2177 $infoline = "Could not assign position for custom action \"$onename\" yet (scp: \"$positionname\").\n"; 2178 push(@installer::globals::logfileinfo, $infoline); 2179 } 2180 } 2181 } 2182 } while (( $template_exists ) && ( $template_replaced )); 2183 2184 # An error occured, because templates still exist, but could not be replaced. 2185 # Reason: 2186 # 1. Wrong name of CustomAction in scp2 (typo?) 2187 # 2. Circular dependencies of CustomActions (A after B and B after A) 2188 2189 # Problem: It is allowed, that a CustomAction is defined in scp2 in a library that is 2190 # part of product ABC, but this CustomAction is not used in this product 2191 # and the reference CustomAction is not part of this product. 2192 # Therefore this cannot be an error, but only produce a warning. The assigned number 2193 # must be the last sequence number. 2194 2195 if (( $template_exists ) && ( ! $template_replaced )) 2196 { 2197 # Giving a precise error message, collecting all unresolved templates 2198 # my $templatestring = ""; 2199 2200 for ( my $i = 0; $i <= $#{$sequencetable}; $i++ ) 2201 { 2202 if ( ${$sequencetable}[$i] =~ /^\s*([\w\.]+)\t.*\t\s*(POSITIONTEMPLATE_.*?)\s*$/ ) 2203 { 2204 my $customactionname = $1; 2205 my $fulltemplate = $2; 2206 my $template = $fulltemplate; 2207 $template =~ s/POSITIONTEMPLATE_//; 2208 # my $newstring = $customactionname . " (" . $template . ")"; 2209 # $templatestring = $templatestring . $newstring . ", "; 2210 # Setting at the end! 2211 $lastposition = $lastposition + 25; 2212 ${$sequencetable}[$i] =~ s/$fulltemplate/$lastposition/; 2213 $infoline = "WARNING: Setting position \"$lastposition\" for custom action \"$customactionname\". Could not find CustomAction \"$template\".\n"; 2214 push(@installer::globals::logfileinfo, $infoline); 2215 } 2216 } 2217 # $templatestring =~ s/,\s*$//; 2218 2219 # $infoline = "Error: Saving table \"$tablename\"\n"; 2220 # push(@installer::globals::logfileinfo, $infoline); 2221 # print $infoline; 2222 # installer::files::save_file($tablename, $sequencetable); 2223 # installer::exiter::exit_program("ERROR: Unresolved positions in CustomActions in scp2: $templatestring", "set_positions_in_table"); 2224 } 2225} 2226 2227########################################################################## 2228# Setting the Windows custom actions into different tables 2229# CustomAc.idt, InstallE.idt, InstallU.idt, ControlE.idt, ControlC.idt 2230########################################################################## 2231 2232sub addcustomactions 2233{ 2234 my ($languageidtdir, $customactions, $filesarray) = @_; 2235 2236 installer::logger::include_timestamp_into_logfile("\nPerformance Info: addcustomactions start\n"); 2237 2238 my $customactionidttablename = $languageidtdir . $installer::globals::separator . "CustomAc.idt"; 2239 my $customactionidttable = installer::files::read_file($customactionidttablename); 2240 my $installexecutetablename = $languageidtdir . $installer::globals::separator . "InstallE.idt"; 2241 my $installexecutetable = installer::files::read_file($installexecutetablename); 2242 my $adminexecutetablename = $languageidtdir . $installer::globals::separator . "AdminExe.idt"; 2243 my $adminexecutetable = installer::files::read_file($adminexecutetablename); 2244 my $installuitablename = $languageidtdir . $installer::globals::separator . "InstallU.idt"; 2245 my $installuitable = installer::files::read_file($installuitablename); 2246 my $controleventtablename = $languageidtdir . $installer::globals::separator . "ControlE.idt"; 2247 my $controleventtable = installer::files::read_file($controleventtablename); 2248 my $controlconditiontablename = $languageidtdir . $installer::globals::separator . "ControlC.idt"; 2249 my $controlconditiontable = installer::files::read_file($controlconditiontablename); 2250 2251 # Iterating over all Windows custom actions 2252 2253 for ( my $i = 0; $i <= $#{$customactions}; $i++ ) 2254 { 2255 my $customaction = ${$customactions}[$i]; 2256 my $name = $customaction->{'Name'}; 2257 my $typ = $customaction->{'Typ'}; 2258 my $source = $customaction->{'Source'}; 2259 my $target = $customaction->{'Target'}; 2260 my $inbinarytable = $customaction->{'Inbinarytable'}; 2261 my $gid = $customaction->{'gid'}; 2262 2263 my $styles = ""; 2264 if ( $customaction->{'Styles'} ) { $styles = $customaction->{'Styles'}; } 2265 2266 my $added_customaction = set_custom_action($customactionidttable, $name, $typ, $source, $target, $inbinarytable, $filesarray, $customactionidttablename, $styles); 2267 2268 if ( $added_customaction ) 2269 { 2270 # If the CustomAction was added into the CustomAc.idt, it can be connected to the installation. 2271 # There are currently two different ways for doing this: 2272 # 1. Using "add_custom_action_to_install_table", which adds the CustomAction to the install sequences, 2273 # which are saved in InstallE.idt and InstallU.idt 2274 # 2. Using "connect_custom_action_to_control" and "connect_custom_action_to_control". The first method 2275 # connects a CustomAction to a control in ControlE.idt. The second method sets a condition for a control, 2276 # which might be influenced by the CustomAction. This happens in ControlC.idt. 2277 2278 # Any Windows CustomAction can have a lot of different assignments. 2279 2280 for ( my $j = 1; $j <= 50; $j++ ) 2281 { 2282 my $key = "Assignment" . $j; 2283 my $value = ""; 2284 if ( $customaction->{$key} ) 2285 { 2286 $value = $customaction->{$key}; 2287 2288 # in a patch the Assignment can be overwritten by a PatchAssignment 2289 if ( $installer::globals::patch ) 2290 { 2291 $patchkey = "PatchAssignment" . $j; 2292 if ( $customaction->{$patchkey} ) 2293 { 2294 $value = $customaction->{$patchkey}; 2295 $key = $patchkey; 2296 } 2297 } 2298 2299 } 2300 else { last; } 2301 2302 # $value is now a comma separated list 2303 if ( $value =~ /^\s*\(\s*(.*)\s*\);?\s*$/ ) { $value = $1; } 2304 my $assignmentarray = installer::converter::convert_stringlist_into_array(\$value, ","); 2305 my $assignment = create_customaction_assignment_hash($gid, $name, $key, $assignmentarray); 2306 2307 if ( $assignment->{'parameter1'} eq "InstallExecuteSequence" ) 2308 { 2309 add_custom_action_to_install_table($installexecutetable, $source, $name, $assignment->{'parameter2'}, $assignment->{'parameter3'}, $filesarray, $installexecutetablename, $styles); 2310 } 2311 elsif ( $assignment->{'parameter1'} eq "AdminExecuteSequence" ) 2312 { 2313 add_custom_action_to_install_table($adminexecutetable, $source, $name, $assignment->{'parameter2'}, $assignment->{'parameter3'}, $filesarray, $adminexecutetablename, $styles); 2314 } 2315 elsif ( $assignment->{'parameter1'} eq "InstallUISequence" ) 2316 { 2317 add_custom_action_to_install_table($installuitable, $source, $name, $assignment->{'parameter2'}, $assignment->{'parameter3'}, $filesarray, $installuitablename, $styles); 2318 } 2319 elsif ( $assignment->{'parameter1'} eq "ControlEvent" ) 2320 { 2321 connect_custom_action_to_control($controleventtable, $controleventtablename, $assignment->{'parameter2'}, $assignment->{'parameter3'}, $assignment->{'parameter4'}, $assignment->{'parameter5'}, $assignment->{'parameter6'}, $assignment->{'parameter7'}); 2322 } 2323 elsif ( $assignment->{'parameter1'} eq "ControlCondition" ) 2324 { 2325 connect_condition_to_control($controlconditiontable, $controlconditiontablename, $assignment->{'parameter2'}, $assignment->{'parameter3'}, $assignment->{'parameter4'}, $assignment->{'parameter5'}); 2326 } 2327 else 2328 { 2329 installer::exiter::exit_program("ERROR: gid: $gid, key: $key ! Unknown Windows CustomAction table: $assignmenthashref->{'parameter1'} ! Currently supported: InstallUISequence, InstallESequence, ControlEvent, ControlCondition", "addcustomactions"); 2330 } 2331 } 2332 } 2333 } 2334 2335 # Setting the positions in the tables 2336 2337 set_positions_in_table($installexecutetable, $installexecutetablename); 2338 set_positions_in_table($installuitable, $installuitablename); 2339 set_positions_in_table($adminexecutetable, $adminexecutetablename); 2340 2341 # Saving the files 2342 2343 installer::files::save_file($customactionidttablename, $customactionidttable); 2344 installer::files::save_file($installexecutetablename, $installexecutetable); 2345 installer::files::save_file($adminexecutetablename, $adminexecutetable); 2346 installer::files::save_file($installuitablename, $installuitable); 2347 installer::files::save_file($controleventtablename, $controleventtable); 2348 installer::files::save_file($controlconditiontablename, $controlconditiontable); 2349 2350 my $infoline = "Updated idt file: $customactionidttablename\n"; 2351 push(@installer::globals::logfileinfo, $infoline); 2352 $infoline = "Updated idt file: $installexecutetablename\n"; 2353 push(@installer::globals::logfileinfo, $infoline); 2354 $infoline = "Updated idt file: $adminexecutetablename\n"; 2355 push(@installer::globals::logfileinfo, $infoline); 2356 $infoline = "Updated idt file: $installuitablename\n"; 2357 push(@installer::globals::logfileinfo, $infoline); 2358 $infoline = "Updated idt file: $controleventtablename\n"; 2359 push(@installer::globals::logfileinfo, $infoline); 2360 $infoline = "Updated idt file: $controlconditiontablename\n"; 2361 push(@installer::globals::logfileinfo, $infoline); 2362 2363 installer::logger::include_timestamp_into_logfile("\nPerformance Info: addcustomactions end\n"); 2364} 2365 2366########################################################################## 2367# Setting bidi attributes in idt tables 2368########################################################################## 2369 2370sub setbidiattributes 2371{ 2372 my ($languageidtdir, $onelanguage) = @_; 2373 2374 # Editing the files Dialog.idt and Control.idt 2375 2376 my $dialogfilename = $languageidtdir . $installer::globals::separator . "Dialog.idt"; 2377 my $controlfilename = $languageidtdir . $installer::globals::separator . "Control.idt"; 2378 2379 my $dialogfile = installer::files::read_file($dialogfilename); 2380 my $controlfile = installer::files::read_file($controlfilename); 2381 2382 # Searching attributes in Dialog.idt and adding "896". 2383 # Attributes are in column 6 (from 10). 2384 2385 my $bidiattribute = 896; 2386 for ( my $i = 0; $i <= $#{$dialogfile}; $i++ ) 2387 { 2388 if ( $i < 3 ) { next; } 2389 if ( ${$dialogfile}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ ) 2390 { 2391 my $one = $1; 2392 my $two = $2; 2393 my $three = $3; 2394 my $four = $4; 2395 my $five = $5; 2396 my $attribute = $6; 2397 my $seven = $7; 2398 my $eight = $8; 2399 $attribute = $attribute + $bidiattribute; 2400 ${$dialogfile}[$i] = "$one\t$two\t$three\t$four\t$five\t$attribute\t$seven\t$eight\n"; 2401 } 2402 } 2403 2404 # Searching attributes in Control.idt and adding "224". 2405 # Attributes are in column 8 (from 12). 2406 2407 $bidiattribute = 224; 2408 for ( my $i = 0; $i <= $#{$controlfile}; $i++ ) 2409 { 2410 if ( $i < 3 ) { next; } 2411 if ( ${$controlfile}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ ) 2412 { 2413 my $one = $1; 2414 my $two = $2; 2415 my $three = $3; 2416 my $four = $4; 2417 my $five = $5; 2418 my $six = $6; 2419 my $seven = $7; 2420 my $attribute = $8; 2421 my $nine = $9; 2422 my $ten = $10; 2423 my $eleven = $11; 2424 my $twelve = $12; 2425 $attribute = $attribute + $bidiattribute; 2426 ${$controlfile}[$i] = "$one\t$two\t$three\t$four\t$five\t$six\t$seven\t$attribute\t$nine\t$ten\t$eleven\t$twelve\n"; 2427 } 2428 } 2429 2430 # Saving the file 2431 2432 installer::files::save_file($dialogfilename, $dialogfile); 2433 $infoline = "Set bidi support in idt file \"$dialogfilename\" for language $onelanguage\n"; 2434 push(@installer::globals::logfileinfo, $infoline); 2435 2436 installer::files::save_file($controlfilename, $controlfile); 2437 $infoline = "Set bidi support in idt file \"$controlfilename\" for language $onelanguage\n"; 2438 push(@installer::globals::logfileinfo, $infoline); 2439} 2440 24411; 2442