|
Lines 11-35
Link Here
|
| 11 |
package org.eclipse.debug.internal.ui.launchConfigurations; |
11 |
package org.eclipse.debug.internal.ui.launchConfigurations; |
| 12 |
|
12 |
|
| 13 |
|
13 |
|
|
|
14 |
import java.io.File; |
| 14 |
import java.text.MessageFormat; |
15 |
import java.text.MessageFormat; |
| 15 |
|
16 |
|
|
|
17 |
import org.eclipse.core.resources.IFile; |
| 16 |
import org.eclipse.core.resources.IResource; |
18 |
import org.eclipse.core.resources.IResource; |
| 17 |
import org.eclipse.core.resources.ResourcesPlugin; |
19 |
import org.eclipse.core.resources.ResourcesPlugin; |
| 18 |
import org.eclipse.core.runtime.CoreException; |
20 |
import org.eclipse.core.runtime.CoreException; |
| 19 |
import org.eclipse.core.runtime.IStatus; |
21 |
import org.eclipse.core.runtime.IStatus; |
| 20 |
import org.eclipse.core.runtime.Status; |
22 |
import org.eclipse.core.runtime.Status; |
|
|
23 |
import org.eclipse.core.variables.VariablesPlugin; |
| 21 |
import org.eclipse.debug.core.DebugPlugin; |
24 |
import org.eclipse.debug.core.DebugPlugin; |
| 22 |
import org.eclipse.debug.core.ILaunchConfiguration; |
25 |
import org.eclipse.debug.core.ILaunchConfiguration; |
| 23 |
import org.eclipse.debug.core.ILaunchConfigurationType; |
26 |
import org.eclipse.debug.core.ILaunchConfigurationType; |
| 24 |
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
27 |
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
|
|
28 |
import org.eclipse.debug.core.ILaunchManager; |
| 29 |
import org.eclipse.debug.internal.core.LaunchConfigurationWorkingCopy; |
| 30 |
import org.eclipse.debug.internal.ui.CustomImageRegistry; |
| 25 |
import org.eclipse.debug.internal.ui.DebugUIPlugin; |
31 |
import org.eclipse.debug.internal.ui.DebugUIPlugin; |
|
|
32 |
import org.eclipse.debug.internal.ui.DelegatingModelPresentation; |
| 33 |
import org.eclipse.debug.internal.ui.FileSelectionDialog; |
| 26 |
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; |
34 |
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; |
| 27 |
import org.eclipse.debug.internal.ui.SWTUtil; |
35 |
import org.eclipse.debug.internal.ui.SWTUtil; |
|
|
36 |
import org.eclipse.debug.internal.ui.elements.adapters.LauchManagerContentAdapter; |
| 28 |
import org.eclipse.debug.internal.ui.preferences.PerspectivePreferencePage; |
37 |
import org.eclipse.debug.internal.ui.preferences.PerspectivePreferencePage; |
| 29 |
import org.eclipse.debug.ui.DebugUITools; |
38 |
import org.eclipse.debug.ui.DebugUITools; |
|
|
39 |
import org.eclipse.debug.ui.IDebugModelPresentation; |
| 30 |
import org.eclipse.debug.ui.ILaunchConfigurationDialog; |
40 |
import org.eclipse.debug.ui.ILaunchConfigurationDialog; |
| 31 |
import org.eclipse.debug.ui.ILaunchConfigurationTab; |
41 |
import org.eclipse.debug.ui.ILaunchConfigurationTab; |
| 32 |
import org.eclipse.debug.ui.ILaunchConfigurationTabGroup; |
42 |
import org.eclipse.debug.ui.ILaunchConfigurationTabGroup; |
|
|
43 |
import org.eclipse.debug.ui.StringVariableSelectionDialog; |
| 33 |
import org.eclipse.jface.dialogs.Dialog; |
44 |
import org.eclipse.jface.dialogs.Dialog; |
| 34 |
import org.eclipse.jface.dialogs.ErrorDialog; |
45 |
import org.eclipse.jface.dialogs.ErrorDialog; |
| 35 |
import org.eclipse.jface.viewers.ISelection; |
46 |
import org.eclipse.jface.viewers.ISelection; |
|
Lines 57-62
Link Here
|
| 57 |
import org.eclipse.swt.widgets.Button; |
68 |
import org.eclipse.swt.widgets.Button; |
| 58 |
import org.eclipse.swt.widgets.Composite; |
69 |
import org.eclipse.swt.widgets.Composite; |
| 59 |
import org.eclipse.swt.widgets.Control; |
70 |
import org.eclipse.swt.widgets.Control; |
|
|
71 |
import org.eclipse.swt.widgets.FileDialog; |
| 72 |
import org.eclipse.swt.widgets.Group; |
| 60 |
import org.eclipse.swt.widgets.Label; |
73 |
import org.eclipse.swt.widgets.Label; |
| 61 |
import org.eclipse.swt.widgets.Link; |
74 |
import org.eclipse.swt.widgets.Link; |
| 62 |
import org.eclipse.swt.widgets.Shell; |
75 |
import org.eclipse.swt.widgets.Shell; |
|
Lines 69-74
Link Here
|
| 69 |
public class LaunchConfigurationTabGroupViewer extends Viewer { |
82 |
public class LaunchConfigurationTabGroupViewer extends Viewer { |
| 70 |
|
83 |
|
| 71 |
/** |
84 |
/** |
|
|
85 |
* Valid image extensions that are supported by the Image class. These are used to |
| 86 |
* validate the custom icons a user can define for any external tool action. |
| 87 |
*/ |
| 88 |
private final static String IMAGE_EXTENSION_JPG = ".jpg"; //$NON-NLS-1$ |
| 89 |
private final static String IMAGE_EXTENSION_BMP = ".bmp"; //$NON-NLS-1$ |
| 90 |
private final static String IMAGE_EXTENSION_ICO = ".ico"; //$NON-NLS-1$ |
| 91 |
private final static String IMAGE_EXTENSION_TIF = ".tif"; //$NON-NLS-1$ |
| 92 |
private final static String IMAGE_EXTENSION_PNG = ".png"; //$NON-NLS-1$ |
| 93 |
private final static String IMAGE_EXTENSION_GIF = ".gif"; //$NON-NLS-1$ |
| 94 |
|
| 95 |
/** |
| 72 |
* Containing launch dialog |
96 |
* Containing launch dialog |
| 73 |
*/ |
97 |
*/ |
| 74 |
private ILaunchConfigurationDialog fDialog; |
98 |
private ILaunchConfigurationDialog fDialog; |
|
Lines 109-114
Link Here
|
| 109 |
private Text fNameWidget; |
133 |
private Text fNameWidget; |
| 110 |
|
134 |
|
| 111 |
/** |
135 |
/** |
|
|
136 |
* Icon label widget |
| 137 |
*/ |
| 138 |
private Label fIconLabel; |
| 139 |
|
| 140 |
/** |
| 141 |
* Icon text widget |
| 142 |
*/ |
| 143 |
private Text fIconWidget; |
| 144 |
|
| 145 |
/** |
| 146 |
* Icon browse file system widget |
| 147 |
*/ |
| 148 |
private Button fBrowseFileSystem; |
| 149 |
|
| 150 |
/** |
| 151 |
* Icon browse workspace widget |
| 152 |
*/ |
| 153 |
private Button fBrowseWorkspace; |
| 154 |
|
| 155 |
/** |
| 156 |
* Icon variables widget |
| 157 |
*/ |
| 158 |
private Button fVariables; |
| 159 |
|
| 160 |
/** |
| 112 |
* Composite containing the launch config tab widgets |
161 |
* Composite containing the launch config tab widgets |
| 113 |
*/ |
162 |
*/ |
| 114 |
private Composite fTabComposite; |
163 |
private Composite fTabComposite; |
|
Lines 275-280
Link Here
|
| 275 |
} |
324 |
} |
| 276 |
); |
325 |
); |
| 277 |
|
326 |
|
|
|
327 |
//Area to attach custom icon |
| 328 |
|
| 329 |
Group iconGroup = new Group(fTabComposite, SWT.NONE ); |
| 330 |
GridData gData = new GridData(GridData.FILL_HORIZONTAL); |
| 331 |
gData.horizontalSpan = 2; |
| 332 |
iconGroup.setLayoutData(gData); |
| 333 |
GridLayout groupLayout = new GridLayout(); |
| 334 |
groupLayout.numColumns = 1; |
| 335 |
iconGroup.setLayout(groupLayout); |
| 336 |
iconGroup.setText(LaunchConfigurationsMessages.LaunchConfigurationDialog__Icon_18); |
| 337 |
|
| 338 |
fIconWidget = new Text(iconGroup, SWT.SINGLE | SWT.BORDER); |
| 339 |
gd = new GridData(GridData.FILL_HORIZONTAL); |
| 340 |
fIconWidget.setLayoutData(gd); |
| 341 |
|
| 342 |
fIconWidget.addModifyListener( |
| 343 |
new ModifyListener() { |
| 344 |
public void modifyText(ModifyEvent e) { |
| 345 |
handleIconModified(); |
| 346 |
} |
| 347 |
} |
| 348 |
); |
| 349 |
|
| 350 |
Composite buttonComposite = new Composite(iconGroup, SWT.NONE); |
| 351 |
GridLayout layout2 = new GridLayout(); |
| 352 |
layout2.marginHeight = 0; |
| 353 |
layout2.marginWidth = 0; |
| 354 |
layout2.numColumns = 3; |
| 355 |
GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_END); |
| 356 |
gridData.horizontalSpan = 1; |
| 357 |
buttonComposite.setLayout(layout2); |
| 358 |
buttonComposite.setLayoutData(gridData); |
| 359 |
buttonComposite.setFont(parent.getFont()); |
| 360 |
|
| 361 |
fBrowseWorkspace = new Button(buttonComposite,SWT.PUSH); |
| 362 |
fBrowseWorkspace.setText(LaunchConfigurationsMessages.CommonTab_12); |
| 363 |
fBrowseWorkspace.addSelectionListener(new SelectionListener() { |
| 364 |
|
| 365 |
public void widgetSelected(SelectionEvent e) { |
| 366 |
handleWorkspaceLocationButtonSelected(); |
| 367 |
} |
| 368 |
public void widgetDefaultSelected(SelectionEvent e) { |
| 369 |
} |
| 370 |
|
| 371 |
} |
| 372 |
); |
| 373 |
|
| 374 |
fBrowseFileSystem = new Button(buttonComposite,SWT.PUSH); |
| 375 |
fBrowseFileSystem.setText(LaunchConfigurationsMessages.CommonTab_7); |
| 376 |
fBrowseFileSystem.addSelectionListener(new SelectionListener() { |
| 377 |
|
| 378 |
public void widgetSelected(SelectionEvent e) { |
| 379 |
handleFileLocationButtonSelected(); |
| 380 |
} |
| 381 |
|
| 382 |
public void widgetDefaultSelected(SelectionEvent e) { |
| 383 |
} |
| 384 |
|
| 385 |
} |
| 386 |
); |
| 387 |
|
| 388 |
fVariables = new Button(buttonComposite,SWT.PUSH); |
| 389 |
fVariables.setText(LaunchConfigurationsMessages.CommonTab_9); |
| 390 |
|
| 391 |
fVariables.addSelectionListener(new SelectionListener() { |
| 392 |
|
| 393 |
public void widgetSelected(SelectionEvent e) { |
| 394 |
handleVariablesButtonSelected(fIconWidget); |
| 395 |
} |
| 396 |
public void widgetDefaultSelected(SelectionEvent e) { |
| 397 |
} |
| 398 |
|
| 399 |
}); |
| 278 |
createTabFolder(fTabComposite); |
400 |
createTabFolder(fTabComposite); |
| 279 |
|
401 |
|
| 280 |
Composite buttonComp = new Composite(mainComp, SWT.NONE); |
402 |
Composite buttonComp = new Composite(mainComp, SWT.NONE); |
|
Lines 421-426
Link Here
|
| 421 |
protected CTabFolder getTabFolder() { |
543 |
protected CTabFolder getTabFolder() { |
| 422 |
return fTabFolder; |
544 |
return fTabFolder; |
| 423 |
} |
545 |
} |
|
|
546 |
/** |
| 547 |
* Returns the icon widget |
| 548 |
*/ |
| 549 |
private Text getIconWidget() { |
| 550 |
return fIconWidget; |
| 551 |
} |
| 424 |
|
552 |
|
| 425 |
/** |
553 |
/** |
| 426 |
* Sets the current name |
554 |
* Sets the current name |
|
Lines 626-632
Link Here
|
| 626 |
updateVisibleControls(true); |
754 |
updateVisibleControls(true); |
| 627 |
// Update the name field before to avoid verify error |
755 |
// Update the name field before to avoid verify error |
| 628 |
fNameWidget.setText(getWorkingCopy().getName()); |
756 |
fNameWidget.setText(getWorkingCopy().getName()); |
| 629 |
|
757 |
|
|
|
758 |
// set the icon text |
| 759 |
try { |
| 760 |
getIconWidget().setText(getWorkingCopy().getAttribute(ILaunchManager.ATTR_LAUNCH_ICON_PATH, "")); |
| 761 |
} catch (CoreException e1) { |
| 762 |
} |
| 763 |
|
| 630 |
// Retrieve the current tab group. If there is none, clean up and leave |
764 |
// Retrieve the current tab group. If there is none, clean up and leave |
| 631 |
ILaunchConfigurationTabGroup tabGroup = getTabGroup(); |
765 |
ILaunchConfigurationTabGroup tabGroup = getTabGroup(); |
| 632 |
if (tabGroup == null) { |
766 |
if (tabGroup == null) { |
|
Lines 933-938
Link Here
|
| 933 |
// First make sure that name doesn't prevent saving the config |
1067 |
// First make sure that name doesn't prevent saving the config |
| 934 |
try { |
1068 |
try { |
| 935 |
verifyName(); |
1069 |
verifyName(); |
|
|
1070 |
//verify the Icon choice as well |
| 1071 |
verifyIconText(); |
| 936 |
} catch (CoreException ce) { |
1072 |
} catch (CoreException ce) { |
| 937 |
return false; |
1073 |
return false; |
| 938 |
} |
1074 |
} |
|
Lines 962-967
Link Here
|
| 962 |
} |
1098 |
} |
| 963 |
try { |
1099 |
try { |
| 964 |
verifyName(); |
1100 |
verifyName(); |
|
|
1101 |
//Don't let a launch config start without a valid icon file |
| 1102 |
verifyIconText(); |
| 965 |
} catch (CoreException e) { |
1103 |
} catch (CoreException e) { |
| 966 |
return false; |
1104 |
return false; |
| 967 |
} |
1105 |
} |
|
Lines 991-996
Link Here
|
| 991 |
} |
1129 |
} |
| 992 |
try { |
1130 |
try { |
| 993 |
verifyName(); |
1131 |
verifyName(); |
|
|
1132 |
//verify icon text here as well |
| 1133 |
verifyIconText(); |
| 994 |
} catch (CoreException ce) { |
1134 |
} catch (CoreException ce) { |
| 995 |
return ce.getStatus().getMessage(); |
1135 |
return ce.getStatus().getMessage(); |
| 996 |
} |
1136 |
} |
|
Lines 1173-1178
Link Here
|
| 1173 |
} |
1313 |
} |
| 1174 |
|
1314 |
|
| 1175 |
/** |
1315 |
/** |
|
|
1316 |
* Notification that the icon field has been modified |
| 1317 |
* |
| 1318 |
*/ |
| 1319 |
protected void handleIconModified() { |
| 1320 |
//need to update the launch configuration with the new image |
| 1321 |
ILaunchConfigurationWorkingCopy workingCopy = getWorkingCopy(); |
| 1322 |
if (workingCopy instanceof LaunchConfigurationWorkingCopy) { |
| 1323 |
if (getIconWidget() != null && !getIconWidget().isDisposed()) { |
| 1324 |
((LaunchConfigurationWorkingCopy)workingCopy).changeIconPath(getIconWidget().getText().trim()); |
| 1325 |
} |
| 1326 |
} |
| 1327 |
refreshStatus(); |
| 1328 |
|
| 1329 |
} |
| 1330 |
|
| 1331 |
/** |
| 1176 |
* Notification that the 'Apply' button has been pressed |
1332 |
* Notification that the 'Apply' button has been pressed |
| 1177 |
*/ |
1333 |
*/ |
| 1178 |
protected void handleApplyPressed() { |
1334 |
protected void handleApplyPressed() { |
|
Lines 1188-1198
Link Here
|
| 1188 |
widget.setText(trimmed); |
1344 |
widget.setText(trimmed); |
| 1189 |
} |
1345 |
} |
| 1190 |
getWorkingCopy().rename(trimmed); |
1346 |
getWorkingCopy().rename(trimmed); |
|
|
1347 |
if (getWorkingCopy() instanceof LaunchConfigurationWorkingCopy) { |
| 1348 |
if (getIconWidget() != null && !getIconWidget().isDisposed()) { |
| 1349 |
((LaunchConfigurationWorkingCopy)getWorkingCopy()). |
| 1350 |
changeIconPath(getIconWidget().getText().trim()); |
| 1351 |
} |
| 1352 |
} |
| 1353 |
|
| 1191 |
getTabGroup().performApply(getWorkingCopy()); |
1354 |
getTabGroup().performApply(getWorkingCopy()); |
| 1192 |
fInitializingTabs = false; |
1355 |
fInitializingTabs = false; |
| 1193 |
|
1356 |
|
| 1194 |
if (isDirty()) { |
1357 |
if (isDirty()) { |
| 1195 |
getWorkingCopy().doSave(); |
1358 |
getWorkingCopy().doSave(); |
|
|
1359 |
//update the custom image registry for this configuration |
| 1360 |
CustomImageRegistry.getInstance().updateCache(getWorkingCopy().getOriginal()); |
| 1196 |
} |
1361 |
} |
| 1197 |
updateButtons(); |
1362 |
updateButtons(); |
| 1198 |
} catch (CoreException e) { |
1363 |
} catch (CoreException e) { |
|
Lines 1256-1260
Link Here
|
| 1256 |
handleTabSelected(); |
1421 |
handleTabSelected(); |
| 1257 |
} |
1422 |
} |
| 1258 |
} |
1423 |
} |
| 1259 |
|
1424 |
|
|
|
1425 |
/** |
| 1426 |
* Prompts the user to choose a location from the filesystem and |
| 1427 |
* sets the location as the full path of the selected file. |
| 1428 |
*/ |
| 1429 |
protected void handleFileLocationButtonSelected() { |
| 1430 |
FileDialog fileDialog = new FileDialog(getShell(), SWT.NONE); |
| 1431 |
fileDialog.setFileName(getIconWidget().getText()); |
| 1432 |
fileDialog.setFilterExtensions(new String[] {"*"+ IMAGE_EXTENSION_JPG + |
| 1433 |
";*"+ IMAGE_EXTENSION_BMP + |
| 1434 |
";*"+ IMAGE_EXTENSION_GIF + |
| 1435 |
";*"+ IMAGE_EXTENSION_ICO + |
| 1436 |
";*"+ IMAGE_EXTENSION_PNG + |
| 1437 |
";*"+ IMAGE_EXTENSION_TIF |
| 1438 |
,"*.*"}); |
| 1439 |
|
| 1440 |
String text= fileDialog.open(); |
| 1441 |
if (text != null) { |
| 1442 |
getIconWidget().setText(text); |
| 1443 |
} |
| 1444 |
} |
| 1445 |
|
| 1446 |
/** |
| 1447 |
* Prompts the user for a workspace location within the workspace and sets |
| 1448 |
* the location as a String containing the workspace_loc variable or |
| 1449 |
* <code>null</code> if no location was obtained from the user. |
| 1450 |
*/ |
| 1451 |
protected void handleWorkspaceLocationButtonSelected() { |
| 1452 |
|
| 1453 |
FileSelectionDialog dialog; |
| 1454 |
dialog = new FileSelectionDialog(getShell(), ResourcesPlugin.getWorkspace().getRoot(), LaunchConfigurationsMessages.LaunchConfigurationDialog__Workspace_selection_dialog_title);//ExternalToolsLaunchConfigurationMessages.ExternalToolsMainTab_Select_a_resource_22); |
| 1455 |
dialog.open(); |
| 1456 |
IStructuredSelection result = dialog.getResult(); |
| 1457 |
if (result == null) { |
| 1458 |
return; |
| 1459 |
} |
| 1460 |
Object file= result.getFirstElement(); |
| 1461 |
if (file instanceof IFile) { |
| 1462 |
getIconWidget().setText(VariablesPlugin.getDefault(). |
| 1463 |
getStringVariableManager().generateVariableExpression("workspace_loc", ((IFile)file).getFullPath().toString())); //$NON-NLS-1$ |
| 1464 |
} |
| 1465 |
} |
| 1466 |
|
| 1467 |
/** |
| 1468 |
* A variable entry button has been pressed for the given text |
| 1469 |
* field. Prompt the user for a variable and enter the result |
| 1470 |
* in the given field. |
| 1471 |
*/ |
| 1472 |
private void handleVariablesButtonSelected(Text textField) { |
| 1473 |
|
| 1474 |
StringVariableSelectionDialog dialog = new StringVariableSelectionDialog(getShell()); |
| 1475 |
dialog.open(); |
| 1476 |
String variable = dialog.getVariableExpression(); |
| 1477 |
|
| 1478 |
if (variable != null) { |
| 1479 |
textField.insert(variable); |
| 1480 |
} |
| 1481 |
} |
| 1482 |
/** |
| 1483 |
* Verifies that the text entered in the Icon text field is valid. |
| 1484 |
* |
| 1485 |
* @throws CoreException |
| 1486 |
*/ |
| 1487 |
private void verifyIconText() throws CoreException { |
| 1488 |
|
| 1489 |
String enteredPath = null; |
| 1490 |
|
| 1491 |
if (getIconWidget() != null && !getIconWidget().isDisposed()) { |
| 1492 |
enteredPath = getIconWidget().getText().trim(); |
| 1493 |
} |
| 1494 |
else { |
| 1495 |
//This should not occur, just a redundancy check |
| 1496 |
throw new CoreException(new Status(IStatus.ERROR, |
| 1497 |
DebugUIPlugin.getUniqueIdentifier(), |
| 1498 |
0, |
| 1499 |
MessageFormat.format(LaunchConfigurationsMessages.LaunchConfigurationDialog__Internal_error_retrieving_input, |
| 1500 |
null), |
| 1501 |
null)); |
| 1502 |
} |
| 1503 |
|
| 1504 |
try { |
| 1505 |
String subbedString = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(enteredPath); |
| 1506 |
VariablesPlugin.getDefault().getStringVariableManager().validateStringVariables(enteredPath); |
| 1507 |
//if the variable can be substituted, don't validate. It might become valid later. |
| 1508 |
if (!subbedString.equals(enteredPath)) |
| 1509 |
return; |
| 1510 |
} |
| 1511 |
catch (CoreException e) { |
| 1512 |
VariablesPlugin.getDefault().getStringVariableManager().validateStringVariables(enteredPath); |
| 1513 |
return; |
| 1514 |
} |
| 1515 |
|
| 1516 |
File file = new File(VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(enteredPath)); |
| 1517 |
|
| 1518 |
//if a dynamic variable is used, don't validate, since it could be valid later |
| 1519 |
//except if it is the workspace dynamic variable... |
| 1520 |
|
| 1521 |
//don't verify if nothing is entered |
| 1522 |
if (getIconWidget().getText().length() > 0) { |
| 1523 |
|
| 1524 |
if (!file.exists()) { // The file does not exist. |
| 1525 |
throw new CoreException(new Status(IStatus.ERROR, |
| 1526 |
DebugUIPlugin.getUniqueIdentifier(), |
| 1527 |
0, |
| 1528 |
MessageFormat.format(LaunchConfigurationsMessages.LaunchConfigurationDialog__Icon_error_file_does_not_exist, |
| 1529 |
new String[] {file.toString()}), |
| 1530 |
null)); |
| 1531 |
} |
| 1532 |
if (!file.isFile()) { |
| 1533 |
throw new CoreException(new Status(IStatus.ERROR, |
| 1534 |
DebugUIPlugin.getUniqueIdentifier(), |
| 1535 |
0, |
| 1536 |
MessageFormat.format(LaunchConfigurationsMessages.LaunchConfigurationDialog__Icon_error_is_not_a_file, |
| 1537 |
new String[] {file.toString()}), |
| 1538 |
|
| 1539 |
null)); |
| 1540 |
} |
| 1541 |
|
| 1542 |
} |
| 1543 |
} |
| 1260 |
} |
1544 |
} |