1#**************************************************************
2#
3#  Licensed to the Apache Software Foundation (ASF) under one
4#  or more contributor license agreements.  See the NOTICE file
5#  distributed with this work for additional information
6#  regarding copyright ownership.  The ASF licenses this file
7#  to you under the Apache License, Version 2.0 (the
8#  "License"); you may not use this file except in compliance
9#  with the License.  You may obtain a copy of the License at
10#
11#    http://www.apache.org/licenses/LICENSE-2.0
12#
13#  Unless required by applicable law or agreed to in writing,
14#  software distributed under the License is distributed on an
15#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16#  KIND, either express or implied.  See the License for the
17#  specific language governing permissions and limitations
18#  under the License.
19#
20#**************************************************************
21
22
23
24package installer::windows::shortcut;
25
26use installer::existence;
27use installer::exiter;
28use installer::files;
29use installer::globals;
30use installer::windows::idtglobal;
31
32##############################################################
33# Returning the file object for the msiassembly table.
34##############################################################
35
36sub get_file_by_name
37{
38	my ( $filesref, $filename ) = @_;
39
40	my $foundfile = 0;
41	my $onefile;
42
43	for ( my $i = 0; $i <= $#{$filesref}; $i++ )
44	{
45		$onefile = ${$filesref}[$i];
46		my $name = $onefile->{'Name'};
47
48		if ( $name eq $filename )
49		{
50			$foundfile = 1;
51			last;
52		}
53	}
54
55	if (! $foundfile ) { $onefile  = ""; }
56
57	return $onefile;
58}
59
60##############################################################
61# Returning identifier for shortcut table.
62##############################################################
63
64sub get_shortcut_identifier
65{
66	my ($shortcut) = @_;
67
68	my $identifier = $shortcut->{'gid'};
69
70	return $identifier;
71}
72
73##############################################################
74# Returning directory for shortcut table.
75##############################################################
76
77sub get_shortcut_directory
78{
79	my ($shortcut, $dirref) = @_;
80
81	# For shortcuts it is easy to convert the gid_Dir_Abc into the unique name in
82	# the directory table, for instance help_en_simpressidx.
83	# For files (components) this is not so easy, because files can be included
84	# in zip files with subdirectories that are not defined in scp.
85
86	my $onedir;
87	my $shortcutdirectory = $shortcut->{'Dir'};
88	my $directory = "";
89	my $found = 0;
90
91	for ( my $i = 0; $i <= $#{$dirref}; $i++ )
92	{
93		$onedir = ${$dirref}[$i];
94		my $directorygid = $onedir->{'Dir'};
95
96		if ( $directorygid eq $shortcutdirectory )
97		{
98			$found = 1;
99			last;
100		}
101	}
102
103	if (!($found))
104	{
105		installer::exiter::exit_program("ERROR: Did not find DirectoryID $shortcutdirectory in directory collection for shortcut", "get_shortcut_directory");
106	}
107
108	$directory = $onedir->{'uniquename'};
109
110	if ($directory eq "") { $directory = "INSTALLLOCATION"; }		# Shortcuts in the root directory
111
112	return $directory;
113}
114
115##############################################################
116# Returning name for shortcut table.
117##############################################################
118
119sub get_shortcut_name
120{
121	my ($shortcut, $shortnamesref, $onelanguage) = @_;
122
123	my $returnstring;
124
125	my $name = $shortcut->{'Name'};
126
127	my $shortstring = installer::windows::idtglobal::make_eight_three_conform($name, "shortcut", $shortnamesref);
128	$shortstring =~ s/\s/\_/g;	# replacing white spaces with underline
129
130	if ( $shortstring eq $name ) { $returnstring = $name; }	# nothing changed
131	else {$returnstring = $shortstring . "\|" . $name; }
132
133	return $returnstring;
134}
135
136##############################################################
137# Returning component for shortcut table.
138##############################################################
139
140sub get_shortcut_component
141{
142	my ($shortcut, $filesref) = @_;
143
144	my $onefile;
145	my $component = "";
146	my $found = 0;
147	my $shortcut_fileid = $shortcut->{'FileID'};
148
149	my $absolute_filename = 0;
150	if ( $shortcut->{'Styles'} ) { $styles = $shortcut->{'Styles'}; }
151	if ( $styles =~ /\bABSOLUTE_FILENAME\b/ ) { $absolute_filename = 1; }	# FileID contains an absolute filename
152	if ( $styles =~ /\bUSE_HELPER_FILENAME\b/ ) { $absolute_filename = 1; }	# ComponentIDFile contains id of a helper file
153
154	# if the FileID contains an absolute filename, therefore the entry for "ComponentIDFile" has to be used.
155	if ( $absolute_filename ) { $shortcut_fileid = $shortcut->{'ComponentIDFile'}; }
156
157	for ( my $i = 0; $i <= $#{$filesref}; $i++ )
158	{
159		$onefile = ${$filesref}[$i];
160		my $filegid = $onefile->{'gid'};
161
162		if ( $filegid eq $shortcut_fileid )
163		{
164			$found = 1;
165			last;
166		}
167	}
168
169	if (!($found))
170	{
171		installer::exiter::exit_program("ERROR: Did not find FileID $shortcut_fileid in file collection for shortcut", "get_shortcut_component");
172	}
173
174	$component = $onefile->{'componentname'};
175
176	# finally saving the componentname in the folderitem collector
177
178	$shortcut->{'component'} = $component;
179
180	return $component;
181}
182
183##############################################################
184# Returning target for shortcut table.
185##############################################################
186
187sub get_shortcut_target
188{
189	my ($shortcut, $filesref) = @_;
190
191	my $target = "";
192	my $found = 0;
193	my $shortcut_fileid = $shortcut->{'FileID'};
194	my $onefile;
195
196	for ( my $i = 0; $i <= $#{$filesref}; $i++ )
197	{
198		$onefile = ${$filesref}[$i];
199		my $filegid = $onefile->{'gid'};
200
201		if ( $filegid eq $shortcut_fileid )
202		{
203			$found = 1;
204			last;
205		}
206	}
207
208	if (!($found))
209	{
210		installer::exiter::exit_program("ERROR: Did not find FileID $shortcut_fileid in file collection for shortcut", "get_shortcut_target");
211	}
212
213	if ( $onefile->{'Name'} )
214	{
215		$target = $onefile->{'Name'};
216	}
217
218	$target = "\[\#" . $target . "\]";	# format for Non-Advertised shortcuts
219
220	return $target;
221}
222
223##############################################################
224# Returning arguments for shortcut table.
225##############################################################
226
227sub get_shortcut_arguments
228{
229	my ($shortcut) = @_;
230
231	return "";
232}
233
234##############################################################
235# Returning the localized description for shortcut table.
236##############################################################
237
238sub get_shortcut_description
239{
240	my ($shortcut, $onelanguage) = @_;
241
242	my $description = "";
243	if ( $shortcut->{'Tooltip'} ) { $description = $shortcut->{'Tooltip'}; }
244
245	return $description;
246}
247
248##############################################################
249# Returning hotkey for shortcut table.
250##############################################################
251
252sub get_shortcut_hotkey
253{
254	my ($shortcut) = @_;
255
256	return "";
257}
258
259##############################################################
260# Returning icon for shortcut table.
261##############################################################
262
263sub get_shortcut_icon
264{
265	my ($shortcut) = @_;
266
267	return "";
268}
269
270##############################################################
271# Returning iconindex for shortcut table.
272##############################################################
273
274sub get_shortcut_iconindex
275{
276	my ($shortcut) = @_;
277
278	return "";
279}
280
281##############################################################
282# Returning show command for shortcut table.
283##############################################################
284
285sub get_shortcut_showcmd
286{
287	my ($shortcut) = @_;
288
289	return "";
290}
291
292##############################################################
293# Returning working directory for shortcut table.
294##############################################################
295
296sub get_shortcut_wkdir
297{
298	my ($shortcut) = @_;
299
300	return "";
301}
302
303####################################################################
304# Returning working directory for shortcut table for FolderItems.
305####################################################################
306
307sub get_folderitem_wkdir
308{
309	my ($onelink, $dirref) = @_;
310
311	# For shortcuts it is easy to convert the gid_Dir_Abc into the unique name in
312	# the directory table, for instance help_en_simpressidx.
313
314	my $onedir;
315	my $workingdirectory = "";
316	if ( $onelink->{'WkDir'} ) { $workingdirectory = $onelink->{'WkDir'}; }
317	my $directory = "";
318
319	if ( $workingdirectory )
320	{
321		my $found = 0;
322
323		for ( my $i = 0; $i <= $#{$dirref}; $i++ )
324		{
325			$onedir = ${$dirref}[$i];
326			my $directorygid = $onedir->{'Dir'};
327
328			if ( $directorygid eq $workingdirectory )
329			{
330				$found = 1;
331				last;
332			}
333		}
334
335		if (!($found))
336		{
337			installer::exiter::exit_program("ERROR: Did not find DirectoryID $workingdirectory in directory collection for FolderItem", "get_folderitem_wkdir");
338		}
339
340		$directory = $onedir->{'uniquename'};
341
342		if ($directory eq "") { $directory = "INSTALLLOCATION"; }
343	}
344
345	return $directory;
346}
347
348###################################################################
349# Returning the directory for a folderitem for shortcut table.
350###################################################################
351
352sub get_folderitem_directory
353{
354	my ($shortcut) = @_;
355
356	# my $directory = "$installer::globals::programmenufolder";	 # default
357	my $directory = "$installer::globals::officemenufolder";	 # default
358
359	# The value $installer::globals::programmenufolder is not correct for the
360	# PREDEFINED folders, like PREDEFINED_AUTOSTART
361
362	if ( $shortcut->{'FolderID'} eq "PREDEFINED_AUTOSTART" )
363	{
364		$directory = $installer::globals::startupfolder;
365	}
366
367	if ( $shortcut->{'FolderID'} eq "PREDEFINED_DESKTOP" )
368	{
369		$directory = $installer::globals::desktopfolder;
370		$installer::globals::desktoplinkexists = 1;
371	}
372
373	if ( $shortcut->{'FolderID'} eq "PREDEFINED_STARTMENU" )
374	{
375		$directory = $installer::globals::startmenufolder;
376	}
377
378	# saving the directory in the folderitems collector
379
380	$shortcut->{'directory'} = $directory;
381
382	return $directory;
383}
384
385########################################################################
386# Returning the target (feature) for a folderitem for shortcut table.
387# For non-advertised shortcuts this is a formatted string.
388########################################################################
389
390sub get_folderitem_target
391{
392	my ($shortcut, $filesref) = @_;
393
394	my $onefile;
395	my $target = "";
396	my $found = 0;
397	my $shortcut_fileid = $shortcut->{'FileID'};
398
399	my $styles = "";
400	my $nonadvertised = 0;
401	my $absolute_filename = 0;
402	if ( $shortcut->{'Styles'} ) { $styles = $shortcut->{'Styles'}; }
403	if ( $styles =~ /\bNON_ADVERTISED\b/ ) { $nonadvertised = 1; }	# this is a non-advertised shortcut
404	if ( $styles =~ /\bABSOLUTE_FILENAME\b/ ) { $absolute_filename = 1; }	# FileID contains an absolute filename
405
406	# if the FileID contains an absolute filename this can simply be returned as target for the shortcut table.
407	if ( $absolute_filename )
408	{
409		$shortcut->{'target'} = $shortcut_fileid;
410		return $shortcut_fileid;
411	}
412
413	for ( my $i = 0; $i <= $#{$filesref}; $i++ )
414	{
415		$onefile = ${$filesref}[$i];
416		my $filegid = $onefile->{'gid'};
417
418		if ( $filegid eq $shortcut_fileid )
419		{
420			$found = 1;
421			last;
422		}
423	}
424
425	if (!($found))
426	{
427		installer::exiter::exit_program("ERROR: Did not find FileID $shortcut_fileid in file collection for folderitem", "get_folderitem_target");
428	}
429
430	# Non advertised shortcuts do not return the feature, but the path to the file
431	if ( $nonadvertised )
432	{
433		$target = "\[" . $onefile->{'uniquedirname'} . "\]" . "\\" . $onefile->{'Name'};
434		$shortcut->{'target'} = $target;
435		return $target;
436	}
437
438	# the rest only for advertised shortcuts, which contain the feature in the shortcut table.
439
440	if ( $onefile->{'modules'} ) { $target = $onefile->{'modules'}; }
441
442	# If modules contains a list of modules, only taking the first one.
443	# But this should never be needed
444
445	if ( $target =~ /^\s*(.*?)\,/ ) { $target = $1; }
446
447	# Attention: Maximum feature length is 38!
448	installer::windows::idtglobal::shorten_feature_gid(\$target);
449
450	# and finally saving the target in the folderitems collector
451
452	$shortcut->{'target'} = $target;
453
454	return $target;
455}
456
457########################################################################
458# Returning the arguments for a folderitem for shortcut table.
459########################################################################
460
461sub get_folderitem_arguments
462{
463	my ($shortcut) = @_;
464
465	my $parameter = "";
466
467	if ( $shortcut->{'Parameter'} ) { $parameter = $shortcut->{'Parameter'}; }
468
469	return $parameter;
470}
471
472########################################################################
473# Returning the icon for a folderitem for shortcut table.
474# The returned value has to be defined in the icon table.
475########################################################################
476
477sub get_folderitem_icon
478{
479	my ($shortcut, $filesref, $iconfilecollector) = @_;
480
481	my $styles = "";
482	if ( $shortcut->{'Styles'} ) { $styles = $shortcut->{'Styles'}; }
483	if ( $styles =~ /\bNON_ADVERTISED\b/ ) { return ""; }	# no icon for non-advertised shortcuts
484
485	my $iconfilegid = "";
486
487	if ( $shortcut->{'IconFile'} ) { $iconfilegid = $shortcut->{'IconFile'}; }
488	else { $iconfilegid = $shortcut->{'FileID'}; }
489
490	my $onefile;
491	my $found = 0;
492
493	for ( my $i = 0; $i <= $#{$filesref}; $i++ )
494	{
495		$onefile = ${$filesref}[$i];
496		my $filegid = $onefile->{'gid'};
497
498		if ( $filegid eq $iconfilegid )
499		{
500			$found = 1;
501			last;
502		}
503	}
504
505	if (!($found))
506	{
507		installer::exiter::exit_program("ERROR: Did not find FileID $iconfilegid in file collection", "get_folderitem_icon");
508	}
509
510	$iconfile = $onefile->{'Name'};
511
512	# collecting all icon files to copy them into the icon directory
513
514	my $sourcepath = $onefile->{'sourcepath'};
515
516	if (! installer::existence::exists_in_array($sourcepath, $iconfilecollector))
517	{
518		push(@{$iconfilecollector}, $sourcepath);
519	}
520
521	return $iconfile;
522}
523
524########################################################################
525# Returning the iconindex for a folderitem for shortcut table.
526########################################################################
527
528sub get_folderitem_iconindex
529{
530	my ($shortcut) = @_;
531
532	my $styles = "";
533	if ( $shortcut->{'Styles'} ) { $styles = $shortcut->{'Styles'}; }
534	if ( $styles =~ /\bNON_ADVERTISED\b/ ) { return ""; }	# no iconindex for non-advertised shortcuts
535
536	my $iconid = 0;
537
538	if ( $shortcut->{'IconID'} ) { $iconid = $shortcut->{'IconID'}; }
539
540	return $iconid;
541}
542
543########################################################################
544# Returning the show command for a folderitem for shortcut table.
545########################################################################
546
547sub get_folderitem_showcmd
548{
549	my ($shortcut) = @_;
550
551	return "1";
552}
553
554###########################################################################################################
555# Creating the file Shortcut.idt dynamically
556# Content:
557# Shortcut Directory_ Name Component_ Target Arguments Description Hotkey Icon_ IconIndex ShowCmd WkDir
558###########################################################################################################
559
560sub create_shortcut_table
561{
562	my ($filesref, $linksref, $folderref, $folderitemsref, $dirref, $basedir, $languagesarrayref, $includepatharrayref, $iconfilecollector) = @_;
563
564	for ( my $m = 0; $m <= $#{$languagesarrayref}; $m++ )
565	{
566		my $onelanguage = ${$languagesarrayref}[$m];
567
568		my @shortcuttable = ();
569
570		my @shortnames = ();	# to collect all short names
571
572		installer::windows::idtglobal::write_idt_header(\@shortcuttable, "shortcut");
573
574		# First the links, defined in scp as ShortCut
575
576		for ( my $i = 0; $i <= $#{$linksref}; $i++ )
577		{
578			my $onelink = ${$linksref}[$i];
579
580			# Controlling the language!
581			# Only language independent folderitems or folderitems with the correct language
582			# will be included into the table
583
584			if (! (!(( $onelink->{'ismultilingual'} )) || ( $onelink->{'specificlanguage'} eq $onelanguage )) )  { next; }
585
586			my %shortcut = ();
587
588			$shortcut{'Shortcut'} = get_shortcut_identifier($onelink);
589			$shortcut{'Directory_'} = get_shortcut_directory($onelink, $dirref);
590			$shortcut{'Name'} = get_shortcut_name($onelink, \@shortnames, $onelanguage);	# localized name
591			$shortcut{'Component_'} = get_shortcut_component($onelink, $filesref);
592			$shortcut{'Target'} = get_shortcut_target($onelink, $filesref);
593			$shortcut{'Arguments'} = get_shortcut_arguments($onelink);
594			$shortcut{'Description'} = get_shortcut_description($onelink, $onelanguage); 	# localized description
595			$shortcut{'Hotkey'} = get_shortcut_hotkey($onelink);
596			$shortcut{'Icon_'} = get_shortcut_icon($onelink);
597			$shortcut{'IconIndex'} = get_shortcut_iconindex($onelink);
598			$shortcut{'ShowCmd'} = get_shortcut_showcmd($onelink);
599			$shortcut{'WkDir'} = get_shortcut_wkdir($onelink);
600
601			my $oneline = $shortcut{'Shortcut'} . "\t" . $shortcut{'Directory_'} . "\t" . $shortcut{'Name'} . "\t"
602						. $shortcut{'Component_'} . "\t" . $shortcut{'Target'} . "\t" . $shortcut{'Arguments'} . "\t"
603						. $shortcut{'Description'} . "\t" . $shortcut{'Hotkey'} . "\t" . $shortcut{'Icon_'} . "\t"
604						. $shortcut{'IconIndex'} . "\t" . $shortcut{'ShowCmd'} . "\t" . $shortcut{'WkDir'} . "\n";
605
606			push(@shortcuttable, $oneline);
607		}
608
609		# Second the entries into the start menu, defined in scp as Folder and Folderitem
610		# These shortcuts will fill the icons table.
611
612		for ( my $i = 0; $i <= $#{$folderref}; $i++ )
613		{
614			my $foldergid = ${$folderref}[$i]->{'gid'};
615
616			# iterating over all folderitems for this folder
617
618			for ( my $j = 0; $j <= $#{$folderitemsref}; $j++ )
619			{
620				my $onelink = ${$folderitemsref}[$j];
621
622				# Controlling the language!
623				# Only language independent folderitems or folderitems with the correct language
624				# will be included into the table
625
626				if (! (!(( $onelink->{'ismultilingual'} )) || ( $onelink->{'specificlanguage'} eq $onelanguage )) )  { next; }
627
628				# controlling the folder
629
630				my $localused = 0;
631
632				if ( $onelink->{'used'} ) { $localused = $onelink->{'used'}; }
633
634				if (!($localused == 1)) { $onelink->{'used'} = "0"; }		# no resetting
635
636				if (!( $onelink->{'FolderID'} eq $foldergid )) { next; }
637
638				$onelink->{'used'} = "1";
639
640				my %shortcut = ();
641
642				$shortcut{'Shortcut'} = get_shortcut_identifier($onelink);
643				$shortcut{'Directory_'} = get_folderitem_directory($onelink);
644				$shortcut{'Name'} = get_shortcut_name($onelink, \@shortnames, $onelanguage);	# localized name
645				$shortcut{'Component_'} = get_shortcut_component($onelink, $filesref);
646				$shortcut{'Target'} = get_folderitem_target($onelink, $filesref);
647				$shortcut{'Arguments'} = get_folderitem_arguments($onelink);
648				$shortcut{'Description'} = get_shortcut_description($onelink, $onelanguage);	# localized description
649				$shortcut{'Hotkey'} = get_shortcut_hotkey($onelink);
650				$shortcut{'Icon_'} = get_folderitem_icon($onelink, $filesref, $iconfilecollector);
651				$shortcut{'IconIndex'} = get_folderitem_iconindex($onelink);
652				$shortcut{'ShowCmd'} = get_folderitem_showcmd($onelink);
653				$shortcut{'WkDir'} = get_folderitem_wkdir($onelink, $dirref);
654
655				my $oneline = $shortcut{'Shortcut'} . "\t" . $shortcut{'Directory_'} . "\t" . $shortcut{'Name'} . "\t"
656							. $shortcut{'Component_'} . "\t" . $shortcut{'Target'} . "\t" . $shortcut{'Arguments'} . "\t"
657							. $shortcut{'Description'} . "\t" . $shortcut{'Hotkey'} . "\t" . $shortcut{'Icon_'} . "\t"
658							. $shortcut{'IconIndex'} . "\t" . $shortcut{'ShowCmd'} . "\t" . $shortcut{'WkDir'} . "\n";
659
660				push(@shortcuttable, $oneline);
661			}
662		}
663
664		# The soffice.ico has to be included into the icon table
665		# as icon for the ARP applet
666
667		my $onefile = "";
668		my $sofficefile = "soffice.ico";
669
670		my $sourcepathref = installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic(\$sofficefile, $includepatharrayref, 0);
671
672		if ($$sourcepathref eq "") { installer::exiter::exit_program("ERROR: Could not find $sofficefile as icon!", "create_shortcut_table"); }
673
674		if (! installer::existence::exists_in_array($$sourcepathref, $iconfilecollector))
675		{
676			unshift(@{$iconfilecollector}, $$sourcepathref);
677			$installer::globals::sofficeiconadded = 1;
678		}
679
680        $installer::logger::Lang->printf(
681            "Added icon file %s for language pack into icon file collector.\n", $$sourcepathref);
682
683		# Saving the file
684
685		my $shortcuttablename = $basedir . $installer::globals::separator . "Shortcut.idt" . "." . $onelanguage;
686		installer::files::save_file($shortcuttablename ,\@shortcuttable);
687        $installer::logger::Lang->printf("Created idt file: %s\n", $shortcuttablename);
688	}
689}
690
691
6921;
693