cid#1607171 Data race condition
[LibreOffice.git] / solenv / bin / modules / installer / windows / shortcut.pm
blob0ba801b51f597ae9b5b8ccd6844377b718f4db34
2 # This file is part of the LibreOffice project.
4 # This Source Code Form is subject to the terms of the Mozilla Public
5 # License, v. 2.0. If a copy of the MPL was not distributed with this
6 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 # This file incorporates work covered by the following license notice:
10 # Licensed to the Apache Software Foundation (ASF) under one or more
11 # contributor license agreements. See the NOTICE file distributed
12 # with this work for additional information regarding copyright
13 # ownership. The ASF licenses this file to you under the Apache
14 # License, Version 2.0 (the "License"); you may not use this file
15 # except in compliance with the License. You may obtain a copy of
16 # the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 package installer::windows::shortcut;
21 use strict;
22 use warnings;
24 use installer::exiter;
25 use installer::files;
26 use installer::globals;
27 use installer::windows::idtglobal;
29 ##############################################################
30 # Returning identifier for shortcut table.
31 ##############################################################
33 sub get_shortcut_identifier
35 my ($shortcut) = @_;
37 my $identifier = $shortcut->{'gid'};
39 return $identifier;
42 ##############################################################
43 # Returning directory for shortcut table.
44 ##############################################################
46 sub get_shortcut_directory
48 my ($shortcut, $dirref) = @_;
50 # For shortcuts it is easy to convert the gid_Dir_Abc into the unique name in
51 # the directory table, for instance help_en_simpressidx.
52 # For files (components) this is not so easy, because files can be included
53 # in zip files with subdirectories that are not defined in scp.
55 my $onedir;
56 my $shortcutdirectory = $shortcut->{'Dir'};
57 my $directory = "";
58 my $found = 0;
60 for ( my $i = 0; $i <= $#{$dirref}; $i++ )
62 $onedir = ${$dirref}[$i];
63 my $directorygid = $onedir->{'Dir'};
65 if ( $directorygid eq $shortcutdirectory )
67 $found = 1;
68 last;
72 if (!($found))
74 installer::exiter::exit_program("ERROR: Did not find DirectoryID $shortcutdirectory in directory collection for shortcut", "get_shortcut_directory");
77 $directory = $onedir->{'uniquename'};
79 if ($directory eq "") { $directory = "INSTALLLOCATION"; } # Shortcuts in the root directory
81 return $directory;
84 ##############################################################
85 # Returning name for shortcut table.
86 ##############################################################
88 sub get_shortcut_name
90 my ($shortcut, $shortnamesref, $onelanguage) = @_;
92 my $returnstring;
94 my $name = $shortcut->{'Name'};
96 my $shortstring = installer::windows::idtglobal::make_eight_three_conform($name, "shortcut", $shortnamesref);
97 $shortstring =~ s/\s/\_/g; # replacing white spaces with underline
99 if ( $shortstring eq $name ) { $returnstring = $name; } # nothing changed
100 else {$returnstring = $shortstring . "\|" . $name; }
102 return $returnstring;
105 ##############################################################
106 # Returning component for shortcut table.
107 ##############################################################
109 sub get_shortcut_component
111 my ($shortcut, $filesref) = @_;
113 my $onefile;
114 my $component = "";
115 my $found = 0;
116 my $shortcut_fileid = $shortcut->{'FileID'};
118 my $absolute_filename = 0;
119 if ( $shortcut->{'Styles'} )
121 my $styles = $shortcut->{'Styles'};
122 if ( $styles =~ /\bABSOLUTE_FILENAME\b/ ) { $absolute_filename = 1; } # FileID contains an absolute filename
123 if ( $styles =~ /\bUSE_HELPER_FILENAME\b/ ) { $absolute_filename = 1; } # ComponentIDFile contains id of a helper file
126 # if the FileID contains an absolute filename, therefore the entry for "ComponentIDFile" has to be used.
127 if ( $absolute_filename ) { $shortcut_fileid = $shortcut->{'ComponentIDFile'}; }
129 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
131 $onefile = ${$filesref}[$i];
132 my $filegid = $onefile->{'gid'};
134 if ( $filegid eq $shortcut_fileid )
136 $found = 1;
137 last;
141 if (!($found))
143 installer::exiter::exit_program("ERROR: Did not find FileID $shortcut_fileid in file collection for shortcut", "get_shortcut_component");
146 $component = $onefile->{'componentname'};
148 # finally saving the componentname in the folderitem collector
150 $shortcut->{'component'} = $component;
152 return $component;
155 ##############################################################
156 # Returning target for shortcut table.
157 ##############################################################
159 sub get_shortcut_target
161 my ($shortcut, $filesref) = @_;
163 my $target = "";
164 my $found = 0;
165 my $shortcut_fileid = $shortcut->{'FileID'};
166 my $onefile;
168 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
170 $onefile = ${$filesref}[$i];
171 my $filegid = $onefile->{'gid'};
173 if ( $filegid eq $shortcut_fileid )
175 $found = 1;
176 last;
180 if (!($found))
182 installer::exiter::exit_program("ERROR: Did not find FileID $shortcut_fileid in file collection for shortcut", "get_shortcut_target");
185 if ( $onefile->{'Name'} )
187 $target = $onefile->{'Name'};
190 $target = "\[\#" . $target . "\]"; # format for Non-Advertised shortcuts
192 return $target;
195 ##############################################################
196 # Returning arguments for shortcut table.
197 ##############################################################
199 sub get_shortcut_arguments
201 my ($shortcut) = @_;
203 return "";
206 ##############################################################
207 # Returning the localized description for shortcut table.
208 ##############################################################
210 sub get_shortcut_description
212 my ($shortcut, $onelanguage) = @_;
214 my $description = "";
215 if ( $shortcut->{'Tooltip'} ) { $description = $shortcut->{'Tooltip'}; }
216 $description =~ s/\\\"/\"/g; # no more masquerading of '"'
218 return $description;
221 ##############################################################
222 # Returning hotkey for shortcut table.
223 ##############################################################
225 sub get_shortcut_hotkey
227 my ($shortcut) = @_;
229 return "";
232 ##############################################################
233 # Returning icon for shortcut table.
234 ##############################################################
236 sub get_shortcut_icon
238 my ($shortcut) = @_;
240 return "";
243 ##############################################################
244 # Returning iconindex for shortcut table.
245 ##############################################################
247 sub get_shortcut_iconindex
249 my ($shortcut) = @_;
251 return "";
254 ##############################################################
255 # Returning show command for shortcut table.
256 ##############################################################
258 sub get_shortcut_showcmd
260 my ($shortcut) = @_;
262 return "";
265 ##############################################################
266 # Returning working directory for shortcut table.
267 ##############################################################
269 sub get_shortcut_wkdir
271 my ($shortcut) = @_;
273 return "";
276 ####################################################################
277 # Returning working directory for shortcut table for FolderItems.
278 ####################################################################
280 sub get_folderitem_wkdir
282 my ($onelink, $dirref) = @_;
284 # For shortcuts it is easy to convert the gid_Dir_Abc into the unique name in
285 # the directory table, for instance help_en_simpressidx.
287 my $onedir;
288 my $workingdirectory = "";
289 if ( $onelink->{'WkDir'} ) { $workingdirectory = $onelink->{'WkDir'}; }
290 my $directory = "";
292 if ( $workingdirectory )
294 my $found = 0;
296 for ( my $i = 0; $i <= $#{$dirref}; $i++ )
298 $onedir = ${$dirref}[$i];
299 my $directorygid = $onedir->{'Dir'};
301 if ( $directorygid eq $workingdirectory )
303 $found = 1;
304 last;
308 if (!($found))
310 installer::exiter::exit_program("ERROR: Did not find DirectoryID $workingdirectory in directory collection for FolderItem", "get_folderitem_wkdir");
313 $directory = $onedir->{'uniquename'};
315 if ($directory eq "") { $directory = "INSTALLLOCATION"; }
318 return $directory;
321 ###################################################################
322 # Returning the directory for a folderitem for shortcut table.
323 ###################################################################
325 sub get_folderitem_directory
327 my ($shortcut) = @_;
329 my $directory = "$installer::globals::officemenufolder"; # default
331 # The default is not correct for the
332 # PREDEFINED folders, like PREDEFINED_AUTOSTART
334 if ( $shortcut->{'FolderID'} eq "PREDEFINED_AUTOSTART" )
336 $directory = $installer::globals::startupfolder;
339 if ( $shortcut->{'FolderID'} eq "PREDEFINED_DESKTOP" )
341 $directory = $installer::globals::desktopfolder;
342 $installer::globals::desktoplinkexists = 1;
345 if ( $shortcut->{'FolderID'} eq "PREDEFINED_STARTMENU" )
347 $directory = $installer::globals::programmenufolder;
350 # saving the directory in the folderitems collector
352 $shortcut->{'directory'} = $directory;
354 return $directory;
357 ########################################################################
358 # Returning the target (feature) for a folderitem for shortcut table.
359 # For non-advertised shortcuts this is a formatted string.
360 ########################################################################
362 sub get_folderitem_target
364 my ($shortcut, $filesref) = @_;
366 my $onefile;
367 my $target = "";
368 my $found = 0;
369 my $shortcut_fileid = $shortcut->{'FileID'};
371 my $styles = "";
372 my $nonadvertised = 0;
373 my $absolute_filename = 0;
374 if ( $shortcut->{'Styles'} ) { $styles = $shortcut->{'Styles'}; }
375 if ( $styles =~ /\bNON_ADVERTISED\b/ ) { $nonadvertised = 1; } # this is a non-advertised shortcut
376 if ( $styles =~ /\bABSOLUTE_FILENAME\b/ ) { $absolute_filename = 1; } # FileID contains an absolute filename
378 # if the FileID contains an absolute filename this can simply be returned as target for the shortcut table.
379 if ( $absolute_filename )
381 $shortcut->{'target'} = $shortcut_fileid;
382 return $shortcut_fileid;
385 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
387 $onefile = ${$filesref}[$i];
388 my $filegid = $onefile->{'gid'};
390 if ( $filegid eq $shortcut_fileid )
392 $found = 1;
393 last;
397 if (!($found))
399 installer::exiter::exit_program("ERROR: Did not find FileID $shortcut_fileid in file collection for folderitem", "get_folderitem_target");
402 # Non advertised shortcuts do not return the feature, but the path to the file
403 if ( $nonadvertised )
405 $target = "\[" . $onefile->{'uniquedirname'} . "\]" . "\\" . $onefile->{'Name'};
406 $shortcut->{'target'} = $target;
407 return $target;
410 # the rest only for advertised shortcuts, which contain the feature in the shortcut table.
412 if ( $onefile->{'modules'} ) { $target = $onefile->{'modules'}; }
414 # If modules contains a list of modules, only taking the first one.
415 # But this should never be needed
417 if ( $target =~ /^\s*(.*?)\,/ ) { $target = $1; }
419 # Attention: Maximum feature length is 38!
420 installer::windows::idtglobal::shorten_feature_gid(\$target);
422 # and finally saving the target in the folderitems collector
424 $shortcut->{'target'} = $target;
426 return $target;
429 ########################################################################
430 # Returning the arguments for a folderitem for shortcut table.
431 ########################################################################
433 sub get_folderitem_arguments
435 my ($shortcut) = @_;
437 my $parameter = "";
439 if ( $shortcut->{'Parameter'} ) { $parameter = $shortcut->{'Parameter'}; }
441 return $parameter;
444 ########################################################################
445 # Returning the icon for a folderitem for shortcut table.
446 # The returned value has to be defined in the icon table.
447 ########################################################################
449 sub get_folderitem_icon
451 my ($shortcut, $filesref, $iconfilecollector) = @_;
453 my $styles = "";
454 if ( $shortcut->{'Styles'} ) { $styles = $shortcut->{'Styles'}; }
455 if ( $styles =~ /\bNON_ADVERTISED\b/ ) { return ""; } # no icon for non-advertised shortcuts
457 my $iconfilegid = "";
459 if ( $shortcut->{'IconFile'} ) { $iconfilegid = $shortcut->{'IconFile'}; }
460 else { $iconfilegid = $shortcut->{'FileID'}; }
462 my $onefile;
463 my $found = 0;
465 for ( my $i = 0; $i <= $#{$filesref}; $i++ )
467 $onefile = ${$filesref}[$i];
468 my $filegid = $onefile->{'gid'};
470 if ( $filegid eq $iconfilegid )
472 $found = 1;
473 last;
477 if (!($found))
479 installer::exiter::exit_program("ERROR: Did not find FileID $iconfilegid in file collection", "get_folderitem_icon");
482 my $iconfile = $onefile->{'Name'};
484 # collecting all icon files to copy them into the icon directory
486 my $sourcepath = $onefile->{'sourcepath'};
488 if (! grep {$_ eq $sourcepath} @{$iconfilecollector})
490 push(@{$iconfilecollector}, $sourcepath);
493 return $iconfile;
496 ########################################################################
497 # Returning the iconindex for a folderitem for shortcut table.
498 ########################################################################
500 sub get_folderitem_iconindex
502 my ($shortcut) = @_;
504 my $styles = "";
505 if ( $shortcut->{'Styles'} ) { $styles = $shortcut->{'Styles'}; }
506 if ( $styles =~ /\bNON_ADVERTISED\b/ ) { return ""; } # no iconindex for non-advertised shortcuts
508 my $iconid = 0;
510 if ( $shortcut->{'IconID'} ) { $iconid = $shortcut->{'IconID'}; }
512 return $iconid;
515 ########################################################################
516 # Returning the show command for a folderitem for shortcut table.
517 ########################################################################
519 sub get_folderitem_showcmd
521 my ($shortcut) = @_;
523 return "1";
526 ###########################################################################################################
527 # Creating the file Shortcut.idt dynamically
528 # Content:
529 # Shortcut Directory_ Name Component_ Target Arguments Description Hotkey Icon_ IconIndex ShowCmd WkDir
530 ###########################################################################################################
532 sub create_shortcut_table
534 my ($filesref, $linksref, $folderref, $folderitemsref, $dirref, $basedir, $languagesarrayref, $includepatharrayref, $iconfilecollector) = @_;
536 for ( my $m = 0; $m <= $#{$languagesarrayref}; $m++ )
538 my $onelanguage = ${$languagesarrayref}[$m];
540 my @shortcuttable = ();
542 my @shortnames = (); # to collect all short names
544 installer::windows::idtglobal::write_idt_header(\@shortcuttable, "shortcut");
546 # First the links, defined in scp as ShortCut
548 for ( my $i = 0; $i <= $#{$linksref}; $i++ )
550 my $onelink = ${$linksref}[$i];
552 # Controlling the language!
553 # Only language independent folderitems or folderitems with the correct language
554 # will be included into the table
556 if (! (!(( $onelink->{'ismultilingual'} )) || ( $onelink->{'specificlanguage'} eq $onelanguage )) ) { next; }
558 my %shortcut = ();
560 $shortcut{'Shortcut'} = get_shortcut_identifier($onelink);
561 $shortcut{'Directory_'} = get_shortcut_directory($onelink, $dirref);
562 $shortcut{'Name'} = get_shortcut_name($onelink, \@shortnames, $onelanguage); # localized name
563 $shortcut{'Component_'} = get_shortcut_component($onelink, $filesref);
564 $shortcut{'Target'} = get_shortcut_target($onelink, $filesref);
565 $shortcut{'Arguments'} = get_shortcut_arguments($onelink);
566 $shortcut{'Description'} = get_shortcut_description($onelink, $onelanguage); # localized description
567 $shortcut{'Hotkey'} = get_shortcut_hotkey($onelink);
568 $shortcut{'Icon_'} = get_shortcut_icon($onelink);
569 $shortcut{'IconIndex'} = get_shortcut_iconindex($onelink);
570 $shortcut{'ShowCmd'} = get_shortcut_showcmd($onelink);
571 $shortcut{'WkDir'} = get_shortcut_wkdir($onelink);
573 my $oneline = $shortcut{'Shortcut'} . "\t" . $shortcut{'Directory_'} . "\t" . $shortcut{'Name'} . "\t"
574 . $shortcut{'Component_'} . "\t" . $shortcut{'Target'} . "\t" . $shortcut{'Arguments'} . "\t"
575 . $shortcut{'Description'} . "\t" . $shortcut{'Hotkey'} . "\t" . $shortcut{'Icon_'} . "\t"
576 . $shortcut{'IconIndex'} . "\t" . $shortcut{'ShowCmd'} . "\t" . $shortcut{'WkDir'} . "\n";
578 push(@shortcuttable, $oneline);
581 # Second the entries into the start menu, defined in scp as Folder and Folderitem
582 # These shortcuts will fill the icons table.
584 for ( my $i = 0; $i <= $#{$folderref}; $i++ )
586 my $foldergid = ${$folderref}[$i]->{'gid'};
588 # iterating over all folderitems for this folder
590 for ( my $j = 0; $j <= $#{$folderitemsref}; $j++ )
592 my $onelink = ${$folderitemsref}[$j];
594 # Controlling the language!
595 # Only language independent folderitems or folderitems with the correct language
596 # will be included into the table
598 if (! (!(( $onelink->{'ismultilingual'} )) || ( $onelink->{'specificlanguage'} eq $onelanguage )) ) { next; }
600 # controlling the folder
602 my $localused = 0;
604 if ( $onelink->{'used'} ) { $localused = $onelink->{'used'}; }
606 if (!($localused == 1)) { $onelink->{'used'} = "0"; } # no resetting
608 if (!( $onelink->{'FolderID'} eq $foldergid )) { next; }
610 $onelink->{'used'} = "1";
612 my %shortcut = ();
614 $shortcut{'Shortcut'} = get_shortcut_identifier($onelink);
615 $shortcut{'Directory_'} = get_folderitem_directory($onelink);
616 $shortcut{'Name'} = get_shortcut_name($onelink, \@shortnames, $onelanguage); # localized name
617 $shortcut{'Component_'} = get_shortcut_component($onelink, $filesref);
618 $shortcut{'Target'} = get_folderitem_target($onelink, $filesref);
619 $shortcut{'Arguments'} = get_folderitem_arguments($onelink);
620 $shortcut{'Description'} = get_shortcut_description($onelink, $onelanguage); # localized description
621 $shortcut{'Hotkey'} = get_shortcut_hotkey($onelink);
622 $shortcut{'Icon_'} = get_folderitem_icon($onelink, $filesref, $iconfilecollector);
623 $shortcut{'IconIndex'} = get_folderitem_iconindex($onelink);
624 $shortcut{'ShowCmd'} = get_folderitem_showcmd($onelink);
625 $shortcut{'WkDir'} = get_folderitem_wkdir($onelink, $dirref);
627 my $oneline = $shortcut{'Shortcut'} . "\t" . $shortcut{'Directory_'} . "\t" . $shortcut{'Name'} . "\t"
628 . $shortcut{'Component_'} . "\t" . $shortcut{'Target'} . "\t" . $shortcut{'Arguments'} . "\t"
629 . $shortcut{'Description'} . "\t" . $shortcut{'Hotkey'} . "\t" . $shortcut{'Icon_'} . "\t"
630 . $shortcut{'IconIndex'} . "\t" . $shortcut{'ShowCmd'} . "\t" . $shortcut{'WkDir'} . "\n";
632 push(@shortcuttable, $oneline);
636 # The soffice.ico has to be included into the icon table
637 # as icon for the ARP applet
639 my $onefile = "";
640 my $sofficefile = "soffice.ico";
642 my $sourcepathref = $ENV{'SRCDIR'} . "/sysui/desktop/icons/" . $sofficefile;
644 if (! -f $sourcepathref) { installer::exiter::exit_program("ERROR: Could not find $sofficefile ($sourcepathref) as icon!", "create_shortcut_table"); }
646 if (! grep {$_ eq $sourcepathref} @{$iconfilecollector})
648 unshift(@{$iconfilecollector}, $sourcepathref);
649 $installer::globals::sofficeiconadded = 1;
652 my $localinfoline = "Added icon file $sourcepathref for language pack into icon file collector.\n";
653 push(@installer::globals::logfileinfo, $localinfoline);
655 # Saving the file
657 my $shortcuttablename = $basedir . $installer::globals::separator . "Shortcut.idt" . "." . $onelanguage;
658 installer::files::save_file($shortcuttablename ,\@shortcuttable);
659 my $infoline = "Created idt file: $shortcuttablename\n";
660 push(@installer::globals::logfileinfo, $infoline);