|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 package com.nokia.s60tools.creator.editors; |
|
18 |
|
19 |
|
20 import java.io.BufferedReader; |
|
21 import java.io.ByteArrayInputStream; |
|
22 import java.io.FileInputStream; |
|
23 import java.io.IOException; |
|
24 import java.io.InputStream; |
|
25 import java.io.InputStreamReader; |
|
26 import java.io.PushbackInputStream; |
|
27 import java.io.UnsupportedEncodingException; |
|
28 import java.net.URI; |
|
29 import java.util.Iterator; |
|
30 import java.util.Set; |
|
31 import java.util.Vector; |
|
32 |
|
33 import org.eclipse.core.resources.IContainer; |
|
34 import org.eclipse.core.resources.IFile; |
|
35 import org.eclipse.core.resources.IMarker; |
|
36 import org.eclipse.core.resources.IResource; |
|
37 import org.eclipse.core.resources.IResourceChangeEvent; |
|
38 import org.eclipse.core.resources.IResourceChangeListener; |
|
39 import org.eclipse.core.resources.IWorkspaceRoot; |
|
40 import org.eclipse.core.resources.ResourcesPlugin; |
|
41 import org.eclipse.core.runtime.CoreException; |
|
42 import org.eclipse.core.runtime.IPath; |
|
43 import org.eclipse.core.runtime.IProgressMonitor; |
|
44 import org.eclipse.core.runtime.IStatus; |
|
45 import org.eclipse.core.runtime.Path; |
|
46 import org.eclipse.core.runtime.Status; |
|
47 import org.eclipse.jface.dialogs.ErrorDialog; |
|
48 import org.eclipse.jface.dialogs.IDialogConstants; |
|
49 import org.eclipse.jface.dialogs.MessageDialog; |
|
50 import org.eclipse.jface.wizard.ProgressMonitorPart; |
|
51 import org.eclipse.swt.SWT; |
|
52 import org.eclipse.swt.SWTException; |
|
53 import org.eclipse.swt.events.SelectionAdapter; |
|
54 import org.eclipse.swt.events.SelectionEvent; |
|
55 import org.eclipse.swt.events.SelectionListener; |
|
56 import org.eclipse.swt.graphics.Color; |
|
57 import org.eclipse.swt.graphics.Font; |
|
58 import org.eclipse.swt.graphics.FontData; |
|
59 import org.eclipse.swt.graphics.RGB; |
|
60 import org.eclipse.swt.graphics.Rectangle; |
|
61 import org.eclipse.swt.layout.GridData; |
|
62 import org.eclipse.swt.layout.GridLayout; |
|
63 import org.eclipse.swt.widgets.Button; |
|
64 import org.eclipse.swt.widgets.Combo; |
|
65 import org.eclipse.swt.widgets.Composite; |
|
66 import org.eclipse.swt.widgets.Display; |
|
67 import org.eclipse.swt.widgets.Group; |
|
68 import org.eclipse.swt.widgets.Label; |
|
69 import org.eclipse.swt.widgets.List; |
|
70 import org.eclipse.swt.widgets.Shell; |
|
71 import org.eclipse.ui.IEditorInput; |
|
72 import org.eclipse.ui.IEditorPart; |
|
73 import org.eclipse.ui.IEditorSite; |
|
74 import org.eclipse.ui.IFileEditorInput; |
|
75 import org.eclipse.ui.IPathEditorInput; |
|
76 import org.eclipse.ui.IWorkbenchPage; |
|
77 import org.eclipse.ui.PartInitException; |
|
78 import org.eclipse.ui.PlatformUI; |
|
79 import org.eclipse.ui.dialogs.SaveAsDialog; |
|
80 import org.eclipse.ui.editors.text.TextEditor; |
|
81 import org.eclipse.ui.ide.FileStoreEditorInput; |
|
82 import org.eclipse.ui.ide.IDE; |
|
83 import org.eclipse.ui.part.FileEditorInput; |
|
84 import org.eclipse.ui.part.MultiPageEditorPart; |
|
85 |
|
86 import com.nokia.s60tools.creator.CreatorActivator; |
|
87 import com.nokia.s60tools.creator.CreatorHelpContextIDs; |
|
88 import com.nokia.s60tools.creator.components.AbstractComponent; |
|
89 import com.nokia.s60tools.creator.components.Components; |
|
90 import com.nokia.s60tools.creator.components.contact.ContactSetVariables; |
|
91 import com.nokia.s60tools.creator.core.CreatorEditorSettings; |
|
92 import com.nokia.s60tools.creator.dialogs.AbstractDialog; |
|
93 import com.nokia.s60tools.creator.dialogs.DialogLauncher; |
|
94 import com.nokia.s60tools.creator.util.CreatorEditorConsole; |
|
95 import com.nokia.s60tools.creator.xml.CreatorScriptNotValidException; |
|
96 import com.nokia.s60tools.creator.xml.CreatorXML; |
|
97 import com.nokia.s60tools.creator.xml.CreatorXMLParser; |
|
98 import com.nokia.s60tools.hticonnection.services.HTIServiceFactory; |
|
99 import com.nokia.s60tools.util.resource.FileUtils; |
|
100 |
|
101 /** |
|
102 * Creator script editor - Editor area. Stores all components and handles adding, removing and editing a Script. |
|
103 */ |
|
104 public class CreatorScriptEditor extends MultiPageEditorPart implements IResourceChangeListener, IComponentProvider{ |
|
105 |
|
106 private static final String ADD_TXT = " Add "; |
|
107 |
|
108 |
|
109 public static final int COMPONENT_LIST_WIDTH = 500; |
|
110 |
|
111 public static final int EDITOR_DEFAULT_WIDTH = 600; |
|
112 |
|
113 /** |
|
114 * Fixed Width and height parameters to set UI components |
|
115 * precisely |
|
116 */ |
|
117 private static final int COMPONENT_LIST_ITEMS_HEIGHT_HINT = 8; |
|
118 |
|
119 /** The text editor used in page 0. */ |
|
120 private TextEditor editor; |
|
121 |
|
122 /** |
|
123 * All components |
|
124 */ |
|
125 private Components components; |
|
126 |
|
127 |
|
128 |
|
129 //Editor window widgets |
|
130 |
|
131 private List componentsList; |
|
132 |
|
133 private Combo componentCombo; |
|
134 |
|
135 private Button removeBtn; |
|
136 |
|
137 private Button editBtn; |
|
138 |
|
139 private boolean isDirty; |
|
140 |
|
141 private Color white; |
|
142 |
|
143 private boolean isEditLaunched = false; |
|
144 |
|
145 private Button addComponentButton; |
|
146 |
|
147 private Button addContactSetButton; |
|
148 |
|
149 private Button runInDeviceButton = null; |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 |
|
155 /** |
|
156 * Creates a multi-page editor example. |
|
157 */ |
|
158 public CreatorScriptEditor() { |
|
159 super(); |
|
160 ResourcesPlugin.getWorkspace().addResourceChangeListener(this); |
|
161 } |
|
162 |
|
163 private void setContextSensitiveHelpIDs(){ |
|
164 PlatformUI.getWorkbench().getHelpSystem().setHelp(componentCombo, |
|
165 CreatorHelpContextIDs.CREATOR_HELP_ADD_COMPONENT); |
|
166 PlatformUI.getWorkbench().getHelpSystem().setHelp(addComponentButton, |
|
167 CreatorHelpContextIDs.CREATOR_HELP_ADD_COMPONENT); |
|
168 |
|
169 PlatformUI.getWorkbench().getHelpSystem().setHelp(editBtn, |
|
170 CreatorHelpContextIDs.CREATOR_HELP_MODIFY_COMPONENT); |
|
171 PlatformUI.getWorkbench().getHelpSystem().setHelp(removeBtn, |
|
172 CreatorHelpContextIDs.CREATOR_HELP_MODIFY_COMPONENT); |
|
173 PlatformUI.getWorkbench().getHelpSystem().setHelp(componentsList, |
|
174 CreatorHelpContextIDs.CREATOR_HELP_MODIFY_COMPONENT); |
|
175 |
|
176 if(runInDeviceButton != null){ |
|
177 PlatformUI.getWorkbench().getHelpSystem().setHelp(runInDeviceButton, |
|
178 CreatorHelpContextIDs.RUN_IN_DEVICE_PAGE); |
|
179 } |
|
180 |
|
181 } |
|
182 |
|
183 /** |
|
184 * Create Creator Editor page. |
|
185 * |
|
186 * Creating all Widgets and setting data from this.xml to them. |
|
187 * Creating listeners for selected Widgets. |
|
188 * |
|
189 */ |
|
190 private void createCreatorScriptEditorPage() { |
|
191 |
|
192 |
|
193 final Composite composite = new Composite(getContainer(), SWT.SIMPLE); |
|
194 final Shell shell = composite.getShell(); |
|
195 |
|
196 GridLayout gridLayout = new GridLayout();//2, false |
|
197 composite.setLayout(gridLayout); |
|
198 |
|
199 GridData gridData = new GridData(); |
|
200 gridData.horizontalAlignment = GridData.FILL; |
|
201 gridData.grabExcessHorizontalSpace = true; |
|
202 composite.setLayoutData(gridData); |
|
203 |
|
204 RGB rgbWhite = new RGB(255, 255, 255); |
|
205 white = new Color(null, rgbWhite); |
|
206 composite.setBackground(white); |
|
207 |
|
208 //Create part of UI where is components to add, contact set adding button and run in device button |
|
209 createButtonsPart(composite, shell); |
|
210 |
|
211 |
|
212 //COMPONENTS |
|
213 Group componentsGroup = new Group(composite, SWT.SHADOW_NONE); |
|
214 componentsGroup.setText("Components added:"); |
|
215 GridLayout componentsGrid = new GridLayout(2, false); |
|
216 componentsGroup.setBackground(white); |
|
217 GridData componentsGridData = new GridData(EDITOR_DEFAULT_WIDTH, SWT.DEFAULT/*GridData.HORIZONTAL_ALIGN_FILL*/); |
|
218 componentsGridData.horizontalAlignment = GridData.FILL; |
|
219 componentsGridData.grabExcessHorizontalSpace = true; |
|
220 componentsGridData.verticalAlignment = GridData.FILL; |
|
221 componentsGridData.grabExcessVerticalSpace = true; |
|
222 |
|
223 componentsGroup.setLayout(componentsGrid); |
|
224 componentsGroup.setLayoutData(componentsGridData); |
|
225 |
|
226 |
|
227 final int listBoxStyleBits = SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL; |
|
228 componentsList = new List(componentsGroup,listBoxStyleBits); |
|
229 //If font not found or something else unexpected occur, don't fail whole program |
|
230 try { |
|
231 componentsList.setFont(getUnicodeFont()); |
|
232 } catch (Exception e) { |
|
233 e.printStackTrace(); |
|
234 CreatorEditorConsole.getInstance().println("Could not set list font to Unicode, reason: " +e.getMessage(), CreatorEditorConsole.MSG_ERROR); |
|
235 } |
|
236 GridData listData = new GridData(COMPONENT_LIST_WIDTH, SWT.DEFAULT); |
|
237 listData.horizontalAlignment = GridData.FILL; |
|
238 listData.grabExcessHorizontalSpace = true; |
|
239 listData.verticalAlignment = GridData.FILL; |
|
240 listData.grabExcessVerticalSpace = true; |
|
241 |
|
242 int listHeight = componentsList.getItemHeight() * COMPONENT_LIST_ITEMS_HEIGHT_HINT; |
|
243 Rectangle trim = componentsList.computeTrim(0, 0, 0, listHeight); |
|
244 listData.heightHint = trim.height; |
|
245 componentsList.setLayoutData(listData); |
|
246 |
|
247 componentsList.addSelectionListener(getEnableButtonsListener()); |
|
248 |
|
249 |
|
250 // |
|
251 //Setting components data to selection box |
|
252 // |
|
253 |
|
254 |
|
255 redrawComponentList(); |
|
256 |
|
257 Composite btnComp = new Composite(componentsGroup, SWT.SIMPLE); |
|
258 btnComp.setLayout(new GridLayout(1, false)); |
|
259 GridData btnGrid = new GridData(); |
|
260 btnGrid.verticalAlignment = SWT.BEGINNING; |
|
261 btnGrid.horizontalAlignment = SWT.BEGINNING; |
|
262 btnComp.setLayoutData(btnGrid);//GridData.FILL_BOTH |
|
263 btnComp.setBackground(white); |
|
264 |
|
265 removeBtn = new Button(btnComp,SWT.PUSH); |
|
266 removeBtn.setText("Remove"); |
|
267 removeBtn.setEnabled(false); |
|
268 |
|
269 editBtn = new Button(btnComp,SWT.PUSH); |
|
270 editBtn.setText(" Edit "); |
|
271 editBtn.setEnabled(false);//By Default edit is not available, but when a component is selected, its enabled |
|
272 |
|
273 //Open Edit Dialog when Edit button has been pushed |
|
274 editBtn.addSelectionListener(getEditButtonListener(this, shell)); |
|
275 |
|
276 //Adding action to remove Button |
|
277 removeBtn.addSelectionListener(getRemoveComponentListener()); |
|
278 |
|
279 |
|
280 |
|
281 int pageIndex = addPage(composite); |
|
282 composite.pack(); |
|
283 setPageText(pageIndex, "Creator Script Editor"); |
|
284 } |
|
285 |
|
286 private void createButtonsPart(final Composite composite, final Shell shell) { |
|
287 //ADD COMPONENT GROUP |
|
288 Group addComponentGroup = new Group(composite, SWT.SHADOW_NONE); |
|
289 addComponentGroup.setText("Add a component to script:"); |
|
290 GridLayout componentGrid = new GridLayout(7, false); |
|
291 addComponentGroup.setBackground(white); |
|
292 GridData componentGridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL); |
|
293 componentGridData.horizontalAlignment = GridData.FILL; |
|
294 componentGridData.grabExcessHorizontalSpace = true; |
|
295 addComponentGroup.setLayout(componentGrid); |
|
296 addComponentGroup.setLayoutData(componentGridData); |
|
297 |
|
298 //SELECT COMPONENT LABEL |
|
299 Label compoenentLabel = new Label(addComponentGroup, SWT.HORIZONTAL); |
|
300 compoenentLabel.setText("Select component to add:"); |
|
301 compoenentLabel.setLayoutData(new GridData()); |
|
302 compoenentLabel.setBackground(white); |
|
303 |
|
304 //Components to select |
|
305 componentCombo = new Combo(addComponentGroup, SWT.READ_ONLY | SWT.DROP_DOWN); |
|
306 componentCombo.setVisibleItemCount(CreatorEditorSettings.getInstance().getComponents().length); |
|
307 componentCombo.setItems(CreatorEditorSettings.getInstance().getComponents()); |
|
308 componentCombo.setLayoutData(new GridData()); |
|
309 |
|
310 |
|
311 addComponentButton = new Button(addComponentGroup, SWT.PUSH); |
|
312 addComponentButton.setText(ADD_TXT); |
|
313 |
|
314 //add button listener |
|
315 addComponentButton.addSelectionListener(getAddComponentButtonListener(shell, this)); |
|
316 |
|
317 |
|
318 //Create own button for contact-set:s |
|
319 Label nullText = new Label(addComponentGroup, SWT.HORIZONTAL); |
|
320 nullText.setBackground(white); |
|
321 nullText.setText(" ");//Just for making some space between buttons. |
|
322 addContactSetButton = new Button(addComponentGroup, SWT.PUSH); |
|
323 addContactSetButton.setText(ContactSetVariables.ADD_CONTACT_SET_TXT); |
|
324 |
|
325 //add button listener |
|
326 addContactSetButton.addSelectionListener(getAddNewContactSetComponentListener(shell, this)); |
|
327 |
|
328 |
|
329 //create button for run in device |
|
330 Label nullText2 = new Label(addComponentGroup, SWT.HORIZONTAL); |
|
331 nullText2.setBackground(white); |
|
332 nullText2.setText(" ");//Just for making some space between buttons. |
|
333 //Checking if HTI is supported at all, if not, not creating button at all. |
|
334 if(isHTIAvailable()){ |
|
335 runInDeviceButton = new Button(addComponentGroup, SWT.PUSH); |
|
336 runInDeviceButton.setText("Run in device via HTI"); |
|
337 runInDeviceButton.addSelectionListener(new RunInDeviceSelectionListener(components.getFileName(), components.getFilePath())); |
|
338 } |
|
339 } |
|
340 |
|
341 |
|
342 /** |
|
343 * Checking if HTI connection package is available. |
|
344 * @return <code>true</code> if HTI is available, <code>false</code> otherwise. |
|
345 */ |
|
346 private boolean isHTIAvailable() { |
|
347 |
|
348 try { |
|
349 //If HTI is not available, Class HTIServiceFactory does not found and NoClassDefFoundError is thrown. |
|
350 //There are different deliverables available and with all, HTI is not bundled with Carbide. |
|
351 HTIServiceFactory |
|
352 .createFTPService(CreatorEditorConsole.getInstance()); |
|
353 } catch (NoClassDefFoundError e) { |
|
354 CreatorEditorConsole.getInstance().println("HTI Connection is not available, Run in Device via HTI functionality is disabled."); |
|
355 return false; |
|
356 } |
|
357 return true; |
|
358 } |
|
359 |
|
360 /* (non-Javadoc) |
|
361 * @see com.nokia.s60tools.creator.editors.IComponentProvider#getAddNewContactSetComponentListener(org.eclipse.swt.widgets.Shell, com.nokia.s60tools.creator.editors.IComponentProvider) |
|
362 */ |
|
363 public SelectionListener getAddNewContactSetComponentListener(final Shell shell, |
|
364 final IComponentProvider provider) { |
|
365 |
|
366 return new SelectionAdapter() { |
|
367 public void widgetSelected(SelectionEvent event) { |
|
368 |
|
369 //tell listeners that a component was added to list |
|
370 IAddComponentListener listener = null; |
|
371 if(event.widget != null){ |
|
372 Object o = event.widget.getData(); |
|
373 if(o instanceof IAddComponentListener){ |
|
374 //if listener was provided, passing it through to compont adding |
|
375 listener = (IAddComponentListener)o; |
|
376 } |
|
377 } |
|
378 |
|
379 isEditLaunched = false; |
|
380 |
|
381 // Get a dialog by selection type |
|
382 final AbstractDialog aComponentAddDialog = DialogLauncher |
|
383 .getDialog(CreatorEditorSettings.TYPE_CONTACT_SET, shell, provider); |
|
384 // Open dialog |
|
385 openAddNewComponentDialog(aComponentAddDialog, listener); |
|
386 } |
|
387 }; |
|
388 } |
|
389 |
|
390 /** |
|
391 * Get listener for Add button |
|
392 * @param shell |
|
393 * @return Listener |
|
394 */ |
|
395 private SelectionAdapter getAddComponentButtonListener(final Shell shell, final IComponentProvider provider) { |
|
396 return new SelectionAdapter() { |
|
397 public void widgetSelected(SelectionEvent event) { |
|
398 |
|
399 isEditLaunched = false; |
|
400 |
|
401 // Get a dialog by selection type |
|
402 final AbstractDialog aComponentAddDialog = DialogLauncher |
|
403 .getDialog(componentCombo.getText(), shell, provider); |
|
404 openAddNewComponentDialog(aComponentAddDialog, null); |
|
405 } |
|
406 |
|
407 }; |
|
408 } |
|
409 /** |
|
410 * Open a dialog |
|
411 * @param aComponentAddDialog |
|
412 */ |
|
413 private void openAddNewComponentDialog( |
|
414 final AbstractDialog aComponentAddDialog, IAddComponentListener listener) { |
|
415 // Open dialog |
|
416 aComponentAddDialog.open(); |
|
417 if (aComponentAddDialog.getReturnCode() == IDialogConstants.OK_ID) { |
|
418 // After dialog closed, get component(s) created |
|
419 AbstractComponent comp = aComponentAddDialog.getComponent(); |
|
420 addComponent(comp, listener); |
|
421 |
|
422 }// else, cancel is pushed |
|
423 } |
|
424 |
|
425 |
|
426 /** |
|
427 * Get Listener for enabling buttons or not |
|
428 * @return Listener |
|
429 */ |
|
430 private SelectionAdapter getEnableButtonsListener() { |
|
431 return new SelectionAdapter() { |
|
432 public void widgetSelected(SelectionEvent event) { |
|
433 |
|
434 boolean buttonsEnabled = componentsList.getSelectionIndex() != -1 ? true : false ; |
|
435 removeBtn.setEnabled(buttonsEnabled); |
|
436 |
|
437 //Edit only enabled when one row is selected |
|
438 if(buttonsEnabled && componentsList.getSelection().length == 1){ |
|
439 editBtn.setEnabled(buttonsEnabled); |
|
440 }else{ |
|
441 editBtn.setEnabled(false); |
|
442 } |
|
443 |
|
444 } |
|
445 }; |
|
446 } |
|
447 |
|
448 |
|
449 /** |
|
450 * Get Listener for Edit button |
|
451 * @param shell |
|
452 * @return Listener |
|
453 */ |
|
454 private SelectionAdapter getEditButtonListener(final IComponentProvider provider, final Shell shell) { |
|
455 return new SelectionAdapter() { |
|
456 public void widgetSelected(SelectionEvent event) { |
|
457 |
|
458 isEditLaunched = true; |
|
459 |
|
460 //Get a dialog by selection type |
|
461 int compIndex = componentsList.getSelectionIndex(); |
|
462 AbstractComponent comp = provider.getEditable(); |
|
463 |
|
464 final AbstractDialog aComponentEditDialog = DialogLauncher.getDialog(provider, shell) ;//new AddContactDialog(shell); |
|
465 //Open dialog |
|
466 aComponentEditDialog.open(); |
|
467 if (aComponentEditDialog.getReturnCode() == IDialogConstants.OK_ID) { |
|
468 //After dialog closed, get component(s) created |
|
469 //AbstractComponent editedComp= aComponentEditDialog.getComponent(); |
|
470 AbstractComponent editedComp= aComponentEditDialog.getComponent(); |
|
471 |
|
472 //Add component to list and check if its valid |
|
473 if(editedComp.isValid()){ |
|
474 getComponents().updateComponent(comp, editedComp); |
|
475 componentsList.setItem(compIndex, editedComp.toString()); |
|
476 setDirty(true); |
|
477 } |
|
478 else{ |
|
479 //set error message |
|
480 showErrorDialog("Component is not valid", "Component edited is not valid", "Please edit valid values to component."); |
|
481 } |
|
482 }//else, cancel is pushed |
|
483 } |
|
484 }; |
|
485 } |
|
486 |
|
487 |
|
488 /** |
|
489 * Handle component(s) removal |
|
490 * |
|
491 * @return Listener |
|
492 */ |
|
493 private SelectionAdapter getRemoveComponentListener() { |
|
494 return new SelectionAdapter() { |
|
495 public void widgetSelected(SelectionEvent event) { |
|
496 |
|
497 int[] indexes = componentsList.getSelectionIndices(); |
|
498 Vector<AbstractComponent> componentsToBeRemoved = new Vector<AbstractComponent>(indexes.length); |
|
499 |
|
500 //First just collecting components to be removed, because when Contact-set is removed a |
|
501 //components referenced to that will be changed, and seeking components left requires |
|
502 //component list update to be found after that |
|
503 for (int i = 0; i < indexes.length; i++) { |
|
504 AbstractComponent comp = getComponentBySelection(indexes[i]); |
|
505 componentsToBeRemoved.add(comp); |
|
506 } |
|
507 |
|
508 //actually removing components and references to component to be removed |
|
509 for (Iterator<AbstractComponent> iterator = componentsToBeRemoved.iterator(); iterator.hasNext();) { |
|
510 AbstractComponent comp = (AbstractComponent) iterator.next(); |
|
511 //remove references to that component |
|
512 getComponents().removeReferencesToComponent(comp); |
|
513 //remove component |
|
514 getComponents().remove(comp); |
|
515 } |
|
516 |
|
517 componentsList.remove(indexes); |
|
518 |
|
519 //Update component list, because many components may changed |
|
520 redrawComponentList(); |
|
521 setDirty(true); |
|
522 } |
|
523 |
|
524 }; |
|
525 } |
|
526 |
|
527 private void addComponentToList(AbstractComponent aComponent, List componentsList) { |
|
528 componentsList.add( aComponent.toString()); |
|
529 } |
|
530 |
|
531 private void redrawComponentList() { |
|
532 componentsList.removeAll(); |
|
533 //Get all component types (Contacts, Connection methods, messages...) |
|
534 Set<String> allComponentTypes = getComponents().getComponentTypes(); |
|
535 //Looping through all component types one by one |
|
536 for (Iterator<String> allCompKeysIt = allComponentTypes.iterator(); allCompKeysIt.hasNext();) { |
|
537 String compType = (String) allCompKeysIt.next(); |
|
538 Vector<AbstractComponent> allComponentsByType = getComponents().getComponents(compType); |
|
539 |
|
540 //Looping through all components in one component type |
|
541 for (Iterator<AbstractComponent> iterator = allComponentsByType.iterator(); iterator.hasNext();) { |
|
542 AbstractComponent aComponent = (AbstractComponent) iterator.next(); |
|
543 addComponentToList(aComponent, componentsList); |
|
544 } |
|
545 } |
|
546 } |
|
547 |
|
548 |
|
549 /** |
|
550 * Creates the pages of the multi-page editor. |
|
551 */ |
|
552 protected void createPages() { |
|
553 |
|
554 try { |
|
555 createCreatorScriptEditorPage(); |
|
556 setContextSensitiveHelpIDs(); |
|
557 } catch (Exception e) { |
|
558 CreatorEditorConsole.getInstance().println("Unexpected error occurs: " + e, CreatorEditorConsole.MSG_ERROR); |
|
559 e.printStackTrace(); |
|
560 } |
|
561 |
|
562 } |
|
563 /** |
|
564 * The <code>MultiPageEditorPart</code> implementation of this |
|
565 * <code>IWorkbenchPart</code> method disposes all nested editors. |
|
566 * Subclasses may extend. |
|
567 */ |
|
568 public void dispose() { |
|
569 ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); |
|
570 super.dispose(); |
|
571 } |
|
572 /** |
|
573 * Saves the multi-page editor's document. |
|
574 */ |
|
575 public void doSave(IProgressMonitor monitor) { |
|
576 //getEditor(0).doSave(monitor); |
|
577 |
|
578 InputStream stream = null; |
|
579 try { |
|
580 IEditorInput editorInput = getEditorInput(); |
|
581 //Type is IFileEditorInput allways when file is opened from project |
|
582 //If file opened outside project, editor type is IPathEditorInput |
|
583 if (editorInput instanceof IFileEditorInput) { |
|
584 IFile file; |
|
585 //Just making sure that stream is closed before renaming file |
|
586 try { |
|
587 stream = openUTF8ContentStream(getComponents().toXMLString()); |
|
588 |
|
589 IFileEditorInput iFile = (IFileEditorInput) editorInput; |
|
590 file = iFile.getFile(); |
|
591 |
|
592 if (file.exists()) { |
|
593 file.setContents(stream, true, true, monitor); |
|
594 file.setCharset(FileUtils.ENCODING_TYPE_UTF_8, monitor); |
|
595 } else { |
|
596 file.create(stream, true, monitor); |
|
597 file.setCharset(FileUtils.ENCODING_TYPE_UTF_8, monitor); |
|
598 } |
|
599 } finally { |
|
600 stream.close(); |
|
601 } |
|
602 } |
|
603 //Else file is opened outside of Carbide project |
|
604 else if (editorInput instanceof IPathEditorInput) { |
|
605 IPathEditorInput javaInput = (IPathEditorInput) editorInput; |
|
606 IPath path = javaInput.getPath(); |
|
607 String fileLocation = path.toOSString(); |
|
608 FileUtils.writeToFile(fileLocation, getComponents().toXMLString(), FileUtils.ENCODING_TYPE_UTF_8); |
|
609 }else{// if (editorInput instanceof FileStoreEditorInput) { |
|
610 FileStoreEditorInput inp = ((FileStoreEditorInput) editorInput); |
|
611 URI uri = inp.getURI(); |
|
612 java.io.File fi = new java.io.File(uri); |
|
613 String fileLocation = fi.getAbsolutePath(); |
|
614 FileUtils.writeToFile(fileLocation, getComponents().toXMLString(), FileUtils.ENCODING_TYPE_UTF_8); |
|
615 } |
|
616 |
|
617 setDirty(false); |
|
618 |
|
619 } catch (Exception e) { |
|
620 showErrorDialog("Errors on save", "Save was not compleate.", |
|
621 e.getMessage()); |
|
622 e.printStackTrace(); |
|
623 } |
|
624 |
|
625 } |
|
626 /** |
|
627 * Saves the multi-page editor's document as another file. |
|
628 * Also updates the text for page 0's tab, and updates this multi-page editor's input |
|
629 * to correspond to the nested editor's. |
|
630 */ |
|
631 public void doSaveAs() { |
|
632 |
|
633 |
|
634 try { |
|
635 IEditorInput editorInput = getEditorInput(); |
|
636 SaveAsDialog saveas = new SaveAsDialog(getContainer().getShell()); |
|
637 //Setting default saveasdialog file name and location |
|
638 //If API name is changed IFileEditorInput is still the same |
|
639 //and if orginal file is not saved yet (xml.isAPINameChanged()) |
|
640 //Setting default name to UI as new generated file name instead of old filename and path |
|
641 if (editorInput instanceof IFileEditorInput ) { |
|
642 IFileEditorInput iFile = (IFileEditorInput) editorInput; |
|
643 saveas.setOriginalFile(iFile.getFile()); |
|
644 } |
|
645 //Else file is opened outside of Carbide project |
|
646 else if (editorInput instanceof IPathEditorInput) { |
|
647 IPathEditorInput javaInput = (IPathEditorInput) editorInput; |
|
648 IPath path = javaInput.getPath(); |
|
649 saveas.setOriginalName(path.lastSegment()); |
|
650 }else{// if (editorInput instanceof FileStoreEditorInput) { |
|
651 FileStoreEditorInput inp = ((FileStoreEditorInput) editorInput); |
|
652 saveas.setOriginalName(inp.getName()); |
|
653 } |
|
654 |
|
655 saveas.open(); |
|
656 |
|
657 if (SaveAsDialog.CANCEL == saveas.getReturnCode()) { |
|
658 return; |
|
659 } |
|
660 |
|
661 if (saveas.getResult() == null |
|
662 || !saveas.getResult().toString().endsWith(".creatorxml") |
|
663 || !saveas.getResult().getFileExtension().equals("creatorxml")) { |
|
664 showErrorDialog("Wrong file type", |
|
665 "Save as was not complete. Please correct file type.", |
|
666 "File type must be .creatorxml"); |
|
667 return; |
|
668 } |
|
669 |
|
670 String containerName = saveas.getResult().removeLastSegments(1) |
|
671 .toOSString(); |
|
672 String fileName = saveas.getResult().lastSegment(); |
|
673 |
|
674 IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); |
|
675 IResource resource = root.findMember(new Path(containerName)); |
|
676 |
|
677 //This is also check by SaveAsDialog, double check |
|
678 if (resource == null || !resource.exists() |
|
679 || !(resource instanceof IContainer)) { |
|
680 showErrorDialog( |
|
681 "Container must exist", |
|
682 "Save as was not complete, container must exist. Please select existing container.", |
|
683 "Conteiner does not exist"); |
|
684 return; |
|
685 } |
|
686 IContainer container = (IContainer) resource; |
|
687 final IFile file = container.getFile(new Path(fileName)); |
|
688 //Creating temp file because given API name must be found |
|
689 InputStream stream = openUTF8ContentStream(getComponents().toXMLString()); |
|
690 ProgressMonitorPart monitor = new ProgressMonitorPart( |
|
691 getContainer(), new GridLayout()); |
|
692 file.create(stream, true, monitor); |
|
693 file.setCharset(FileUtils.ENCODING_TYPE_UTF_8, null); |
|
694 stream.close(); |
|
695 |
|
696 |
|
697 } catch (Exception e) { |
|
698 showErrorDialog("Errors on save as", "Save as was not compleate.", |
|
699 e.getMessage()); |
|
700 e.printStackTrace(); |
|
701 } |
|
702 } |
|
703 |
|
704 /** |
|
705 * Open a stream from components in UTF-8 format |
|
706 * Client must close the opened stream. |
|
707 * @return components XML as stream |
|
708 * @throws UnsupportedEncodingException |
|
709 */ |
|
710 private InputStream openUTF8ContentStream(String string) throws UnsupportedEncodingException { |
|
711 return openContentStream(string, FileUtils.ENCODING_TYPE_UTF_8); |
|
712 } |
|
713 /** |
|
714 * Open a stream from components in specified character set format |
|
715 * Client must close the opened stream. |
|
716 * @return components XML as stream |
|
717 * @throws UnsupportedEncodingException |
|
718 */ |
|
719 private InputStream openContentStream(String string, String charset) throws UnsupportedEncodingException { |
|
720 if(charset == null){ |
|
721 charset = FileUtils.ENCODING_TYPE_UTF_8; |
|
722 } |
|
723 InputStream in = new ByteArrayInputStream(string.getBytes(charset)); |
|
724 return in; |
|
725 } |
|
726 |
|
727 /* (non-Javadoc) |
|
728 * Method declared on IEditorPart |
|
729 */ |
|
730 public void gotoMarker(IMarker marker) { |
|
731 setActivePage(0); |
|
732 IDE.gotoMarker(getEditor(0), marker); |
|
733 } |
|
734 /** |
|
735 * Checks that the input is an instance of <code>IFileEditorInput, IPathEditorInput or FileStoreEditorInput</code>. |
|
736 * And sets Title and content of file. |
|
737 */ |
|
738 public void init(IEditorSite site, IEditorInput editorInput) |
|
739 throws PartInitException { |
|
740 if (!(editorInput instanceof IFileEditorInput) |
|
741 && !(editorInput instanceof IPathEditorInput) |
|
742 && !(editorInput instanceof FileStoreEditorInput) ){ |
|
743 throw new PartInitException( |
|
744 "Invalid Input: Must be IFileEditorInput or IPathEditorInput, was: " |
|
745 + editorInput.getClass().getName()); |
|
746 } |
|
747 setTitle(editorInput); |
|
748 setTitleImage(CreatorActivator |
|
749 .getImageForKey(CreatorActivator.CREATOR_SCRIPT_EDITOR_ICON)); |
|
750 |
|
751 parseXMLAndSetComponents(editorInput); |
|
752 super.init(site, editorInput); |
|
753 |
|
754 } |
|
755 |
|
756 /** |
|
757 * When open a file, setting this.xml from file. |
|
758 * If file was old existing file, parsing file and set it to this.xml |
|
759 * if file was new just created file, creating new xml object and setting |
|
760 * it to this.xml |
|
761 * @param input |
|
762 */ |
|
763 private void parseXMLAndSetComponents(IEditorInput input) { |
|
764 |
|
765 String fileName = ""; |
|
766 String filePath = ""; |
|
767 try { |
|
768 |
|
769 String xmlString; |
|
770 String charSet = null; |
|
771 //Type is IFileEditorInput allways when file is opened from project |
|
772 //If file opened outside project in Carbide 1.2 editor type is IPathEditorInput |
|
773 //and in Carbide 1.3 its FileStoreEditorInput |
|
774 if (input instanceof IFileEditorInput) { |
|
775 IFileEditorInput iFile = (IFileEditorInput) input; |
|
776 IFile file = iFile.getFile(); |
|
777 fileName = file.getName(); |
|
778 filePath = file.getLocation().toOSString(); |
|
779 InputStream in = file.getContents(); |
|
780 //Found out file charset, and opening file contents by that. So also non UTF-8 files is working |
|
781 //Note! If e.g. file is edited in Windows, and charset is cp1252, then "official" (windows-1252) charset name must be in XML file |
|
782 //e.g. <?xml version="1.0" encoding="windows-1252"?>, otherwise parsing XML file will fail. |
|
783 charSet = file.getCharset(); |
|
784 xmlString = getFileContentsWithCharSet(in, charSet); |
|
785 in.close(); |
|
786 in = null; |
|
787 |
|
788 } else if(input instanceof IPathEditorInput){ |
|
789 IPath path = ((IPathEditorInput) input).getPath(); |
|
790 fileName = path.lastSegment(); |
|
791 filePath = path.toOSString(); |
|
792 java.io.File fi = path.toFile(); |
|
793 FileInputStream in = new FileInputStream(fi); |
|
794 xmlString = getFileContentsAsUTF8(in); |
|
795 in.close(); |
|
796 in = null; |
|
797 }else{ |
|
798 FileStoreEditorInput inp = ((FileStoreEditorInput) input); |
|
799 URI uri = inp.getURI(); |
|
800 java.io.File fi = new java.io.File(uri); |
|
801 fileName = fi.getName(); |
|
802 filePath = fi.getAbsolutePath(); |
|
803 FileInputStream in = new FileInputStream(fi); |
|
804 xmlString = getFileContentsAsUTF8(in); |
|
805 in.close(); |
|
806 in = null; |
|
807 |
|
808 } |
|
809 |
|
810 //if file is just created new API metadatafile with wizard |
|
811 //creating new xml object and opening it |
|
812 if (xmlString.startsWith(CreatorXML.NEW_API_CREATOR_FILE_UID)) { |
|
813 components = new Components(); |
|
814 setDirty(true); |
|
815 } |
|
816 //Otherwise file is old existing metadata file, parsing it and setting |
|
817 //xml to this.xml |
|
818 else { |
|
819 components = parseXML(fileName, openContentStream(xmlString, charSet)); |
|
820 setDirty(false); |
|
821 CreatorEditorConsole.getInstance().println( |
|
822 "Creator Script XML file: '" + fileName |
|
823 + "' opened."); |
|
824 } |
|
825 |
|
826 components.setFileName(fileName); |
|
827 components.setFilePath(filePath); |
|
828 |
|
829 } catch (CreatorScriptNotValidException e) { |
|
830 //If parsing was ok, but xml was not walid setting xml so user can correct errors |
|
831 CreatorEditorConsole.getInstance().println( |
|
832 "CreatorScriptNotValidException on init: " + e.toString()); |
|
833 showErrorDialog("Errors on Creator Script XML", "Creator XML file " |
|
834 + fileName + " could not be parsed.", e.getMessage()); |
|
835 } catch (Exception e) { |
|
836 e.printStackTrace(); |
|
837 CreatorEditorConsole.getInstance().println( |
|
838 "Exception on init: " + e.toString()); |
|
839 showErrorDialog("Error", |
|
840 "Creator editor could not be opened. Errors on " |
|
841 + fileName, e.getMessage()); |
|
842 } |
|
843 |
|
844 } |
|
845 |
|
846 /** |
|
847 * Get xml String from stream |
|
848 * @param is |
|
849 * @return |
|
850 * @throws CoreException |
|
851 * @throws IOException |
|
852 */ |
|
853 private String getFileContentsAsUTF8(InputStream is) throws CoreException, |
|
854 IOException { |
|
855 |
|
856 int READ_BYTES = 3; |
|
857 |
|
858 StringBuffer buf = new StringBuffer(); |
|
859 PushbackInputStream pushIn = new PushbackInputStream(is, READ_BYTES); |
|
860 |
|
861 byte[] bomBytes = new byte[READ_BYTES];//for reading 3 first bytes |
|
862 pushIn.read(bomBytes,0, READ_BYTES);//read 3 bytes |
|
863 |
|
864 boolean isBomFile = false; |
|
865 |
|
866 //BOM Files starts with 0xEF, 0xBB, 0xBF |
|
867 if(bomBytes[0] == (byte)0xEF && bomBytes[1] == (byte)0xBB && bomBytes[2] == (byte)0xBF){ |
|
868 isBomFile = true; |
|
869 } |
|
870 |
|
871 //If file was not started with BOM, must put first characters to buffer |
|
872 if (!isBomFile) { |
|
873 pushIn.unread(bomBytes, 0, READ_BYTES); |
|
874 } |
|
875 |
|
876 InputStreamReader isr = new InputStreamReader(pushIn, FileUtils.ENCODING_TYPE_UTF_8); |
|
877 BufferedReader br = new BufferedReader(isr); |
|
878 |
|
879 String line; |
|
880 while ((line = br.readLine()) != null) { |
|
881 buf.append(line); |
|
882 } |
|
883 String xmlString = buf.toString(); |
|
884 // Closing streams |
|
885 pushIn.close(); |
|
886 br.close(); |
|
887 isr.close(); |
|
888 return xmlString; |
|
889 } |
|
890 |
|
891 /** |
|
892 * Get xml String from stream |
|
893 * @param is |
|
894 * @param character set |
|
895 * @return |
|
896 * @throws CoreException |
|
897 * @throws IOException |
|
898 */ |
|
899 private String getFileContentsWithCharSet(InputStream is, String charset) throws CoreException, |
|
900 IOException { |
|
901 |
|
902 if(charset == null){ |
|
903 charset = FileUtils.ENCODING_TYPE_UTF_8; |
|
904 } |
|
905 if(charset.equalsIgnoreCase(FileUtils.ENCODING_TYPE_UTF_8)){ |
|
906 return getFileContentsAsUTF8(is); |
|
907 } |
|
908 |
|
909 StringBuffer buf = new StringBuffer(); |
|
910 InputStreamReader isr = new InputStreamReader(is, charset); |
|
911 BufferedReader br = new BufferedReader(isr); |
|
912 |
|
913 String line; |
|
914 while ((line = br.readLine()) != null) { |
|
915 buf.append(line); |
|
916 } |
|
917 String xmlString = buf.toString(); |
|
918 // Closing streams |
|
919 is.close(); |
|
920 br.close(); |
|
921 isr.close(); |
|
922 return xmlString; |
|
923 |
|
924 } |
|
925 |
|
926 /** |
|
927 * Setting editor title as file name |
|
928 * @param editorInput |
|
929 */ |
|
930 private void setTitle(IEditorInput editorInput) { |
|
931 |
|
932 if (editorInput instanceof IFileEditorInput) { |
|
933 IFileEditorInput iFile = (IFileEditorInput) editorInput; |
|
934 IFile file = iFile.getFile(); |
|
935 setPartName(file.getName()); |
|
936 } else if (editorInput instanceof IPathEditorInput) { |
|
937 IPath path = ((IPathEditorInput) editorInput).getPath(); |
|
938 String filename = path.lastSegment(); |
|
939 setPartName(filename); |
|
940 }else if (editorInput instanceof FileStoreEditorInput) { |
|
941 FileStoreEditorInput inp = ((FileStoreEditorInput) editorInput); |
|
942 String filename = inp.getName(); |
|
943 setPartName(filename); |
|
944 } |
|
945 } |
|
946 |
|
947 /* (non-Javadoc) |
|
948 * Method declared on IEditorPart. |
|
949 */ |
|
950 public boolean isSaveAsAllowed() { |
|
951 return true; |
|
952 } |
|
953 /** |
|
954 * Calculates the contents of page 2 when the it is activated. |
|
955 */ |
|
956 protected void pageChange(int newPageIndex) { |
|
957 super.pageChange(newPageIndex); |
|
958 } |
|
959 /** |
|
960 * Closes all project files on project close. |
|
961 */ |
|
962 public void resourceChanged(final IResourceChangeEvent event){ |
|
963 if(event.getType() == IResourceChangeEvent.PRE_CLOSE){ |
|
964 Display.getDefault().asyncExec(new Runnable(){ |
|
965 public void run(){ |
|
966 IWorkbenchPage[] pages = getSite().getWorkbenchWindow().getPages(); |
|
967 for (int i = 0; i<pages.length; i++){ |
|
968 if(((FileEditorInput)editor.getEditorInput()).getFile().getProject().equals(event.getResource())){ |
|
969 IEditorPart editorPart = pages[i].findEditor(editor.getEditorInput()); |
|
970 pages[i].closeEditor(editorPart,true); |
|
971 } |
|
972 } |
|
973 } |
|
974 }); |
|
975 } |
|
976 } |
|
977 |
|
978 |
|
979 /** |
|
980 * Get Arial Unicode MS font |
|
981 * @return |
|
982 */ |
|
983 private Font getUnicodeFont() { |
|
984 Font defaultFont = componentsList.getFont(); |
|
985 FontData defaulFD [] = defaultFont.getFontData(); |
|
986 //Font Arial Unicode MS is Supplied with Microsoft Office 2002 (XP) and Microsoft Office 2003. |
|
987 //@see http://www.alanwood.net/unicode/fonts.html |
|
988 FontData fd = new FontData("Arial Unicode MS", defaulFD[0].getHeight(), defaulFD[0].getStyle()); |
|
989 return new Font(Display.getCurrent(), fd); |
|
990 } |
|
991 |
|
992 /** |
|
993 * Parse xml String to XML object |
|
994 * @param fileName |
|
995 * @return |
|
996 * @throws MetadataNotValidException |
|
997 */ |
|
998 private Components parseXML(String fileName, InputStream inUTF8) |
|
999 throws CreatorScriptNotValidException { |
|
1000 CreatorXMLParser parser = new CreatorXMLParser(); |
|
1001 //This can be optimized by sending Reader as parameter instead of Stream, |
|
1002 //That will also require logic update when opening file and checking how file was opened |
|
1003 //(was it a new file, project file or outside of the project file) |
|
1004 Components comps = parser.parse(inUTF8); |
|
1005 |
|
1006 if(parser.wasErrors()){ |
|
1007 showErrorDialog("Errors on parsing", |
|
1008 "There was some errors when parsing file: " +fileName, |
|
1009 parser.getErrors()); |
|
1010 } |
|
1011 |
|
1012 return comps; |
|
1013 } |
|
1014 |
|
1015 |
|
1016 /* (non-Javadoc) |
|
1017 * @see com.nokia.s60tools.creator.editors.IComponentProvider#getComponents() |
|
1018 */ |
|
1019 public Components getComponents() { |
|
1020 return components; |
|
1021 } |
|
1022 |
|
1023 /** |
|
1024 * Get selected component |
|
1025 * @param selectionIndex |
|
1026 * @return Component |
|
1027 */ |
|
1028 private AbstractComponent getComponentBySelection(int selectionIndex) { |
|
1029 String componentToString = componentsList.getItem(selectionIndex); |
|
1030 |
|
1031 // AbstractComponent comp = (AbstractComponent)componentsList.getData("" +selectionIndex); |
|
1032 AbstractComponent comp = getComponents().getComponentByComponentString(componentToString); |
|
1033 return comp; |
|
1034 } |
|
1035 |
|
1036 /** |
|
1037 * Show an error dialog |
|
1038 * @param title |
|
1039 * @param message |
|
1040 * @param errors |
|
1041 */ |
|
1042 private void showErrorDialog(String title, String message, String errors) { |
|
1043 Status status = new Status(IStatus.ERROR, |
|
1044 "com.nokia.s60tools.metadataeditor", 0, errors, null); |
|
1045 Shell sh; |
|
1046 if (getContainer() != null) { |
|
1047 try { |
|
1048 sh = getContainer().getShell(); |
|
1049 } catch (SWTException e) { |
|
1050 sh = CreatorActivator.getCurrentlyActiveWbWindowShell(); |
|
1051 } |
|
1052 } else { |
|
1053 sh = CreatorActivator.getCurrentlyActiveWbWindowShell(); |
|
1054 } |
|
1055 |
|
1056 ErrorDialog.openError(sh, title, message, status); |
|
1057 } |
|
1058 |
|
1059 /** |
|
1060 * Show an information dialog |
|
1061 * @param title |
|
1062 * @param message |
|
1063 */ |
|
1064 @SuppressWarnings("unused") |
|
1065 private void showInformationDialog(String title, String message) { |
|
1066 Shell sh; |
|
1067 if (getContainer() != null) { |
|
1068 try { |
|
1069 sh = getContainer().getShell(); |
|
1070 } catch (SWTException e) { |
|
1071 sh = CreatorActivator.getCurrentlyActiveWbWindowShell(); |
|
1072 } |
|
1073 |
|
1074 } else { |
|
1075 sh = CreatorActivator.getCurrentlyActiveWbWindowShell(); |
|
1076 } |
|
1077 |
|
1078 MessageDialog.openInformation(sh, title, message); |
|
1079 } |
|
1080 |
|
1081 /** |
|
1082 * If data is modified, editor is dirty and can be saved |
|
1083 * NOTE: If editor data is changed and then changed back to original |
|
1084 * data contents, status still remain as dirty |
|
1085 */ |
|
1086 public boolean isDirty() { |
|
1087 return this.isDirty; |
|
1088 } |
|
1089 |
|
1090 /** |
|
1091 * If editor contents is modified, save is allowed |
|
1092 * @param isDirty |
|
1093 */ |
|
1094 private void setDirty(boolean isDirty) { |
|
1095 this.isDirty = isDirty; |
|
1096 if(runInDeviceButton!=null){ |
|
1097 runInDeviceButton.setEnabled(!isDirty); |
|
1098 } |
|
1099 if (isDirty) { |
|
1100 firePropertyChange(PROP_DIRTY); |
|
1101 } else { |
|
1102 firePropertyChange(PROP_INPUT); |
|
1103 } |
|
1104 } |
|
1105 |
|
1106 |
|
1107 |
|
1108 |
|
1109 /* (non-Javadoc) |
|
1110 * @see com.nokia.s60tools.creator.editors.IComponentProvider#getComponents(java.lang.String) |
|
1111 */ |
|
1112 public Vector<AbstractComponent> getComponents(String type) { |
|
1113 return getComponents().getComponents(type); |
|
1114 } |
|
1115 |
|
1116 |
|
1117 /* (non-Javadoc) |
|
1118 * @see com.nokia.s60tools.creator.editors.IComponentProvider#getEditable() |
|
1119 */ |
|
1120 public AbstractComponent getEditable() { |
|
1121 //Get a dialog by selection type |
|
1122 int compIndex = componentsList.getSelectionIndex(); |
|
1123 AbstractComponent comp = null; |
|
1124 if(compIndex != -1){ |
|
1125 comp = getComponentBySelection(compIndex); |
|
1126 } |
|
1127 return comp; |
|
1128 } |
|
1129 |
|
1130 |
|
1131 public boolean isInEditMode() { |
|
1132 return isEditLaunched ; |
|
1133 } |
|
1134 |
|
1135 |
|
1136 /* (non-Javadoc) |
|
1137 * @see com.nokia.s60tools.creator.editors.IComponentProvider#addComponent(com.nokia.s60tools.creator.components.AbstractComponent) |
|
1138 */ |
|
1139 public void addComponent(AbstractComponent comp, IAddComponentListener listener) { |
|
1140 |
|
1141 //Adding a component to list, currently using outside of editor only when a contact set is created by dialog, not by editor |
|
1142 |
|
1143 if (comp.isValid()) { |
|
1144 getComponents().addComponent(comp); |
|
1145 addComponentToList(comp, componentsList); |
|
1146 setDirty(true); |
|
1147 if(listener != null){ |
|
1148 // tell listeners that a component was added to list |
|
1149 listener.componentAdded(comp); |
|
1150 } |
|
1151 } else { |
|
1152 // Error handling |
|
1153 showErrorDialog("Component is not valid", |
|
1154 "Component added is not valid", |
|
1155 "Not valid component"); |
|
1156 } |
|
1157 |
|
1158 } |
|
1159 |
|
1160 } |