creatorextension/com.nokia.s60tools.creator/src/com/nokia/s60tools/creator/editors/CreatorScriptEditor.java
changeset 0 61163b28edca
equal deleted inserted replaced
-1:000000000000 0:61163b28edca
       
     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 }