/*
 * Copyright (c) 2008, 2009 Borland Software Corp.
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Artem Tikhomirov (Borland) - initial API and implementation
 */
«IMPORT 'http://www.eclipse.org/gmf/2008/Binding'»
«EXTENSION xpt::StringOperations»

«DEFINE Main FOR binding::Editor»
package «packageName»;

public class FormPage extends org.eclipse.ui.forms.editor.FormPage {

	public FormPage(org.eclipse.ui.forms.editor.FormEditor editor) {
		super(editor, "pageId", "page title"); //$NON-NLS-1$
		//mySectionStateSupport = editor.getSectionStateSupport();
	}

	@Override
	protected void createFormContent(IManagedForm managedForm) {
		super.createFormContent( managedForm );
		managedForm.getToolkit().decorateFormHeading(managedForm.getForm().getForm());
		managedForm.getMessageManager().setMessagePrefixProvider(new EmptyMessagePrefixProvider());
		managedForm.getForm().setText( Messages.UIPage_title );
		managedForm.getForm().getBody().setLayout(new VerticalLayout());
		//
		Composite topPane = managedForm.getToolkit().createComposite(managedForm.getForm().getBody());
		Composite bottomPane = managedForm.getToolkit().createComposite(managedForm.getForm().getBody());
		org.eclipse.jface.layout.GridLayoutFactory.fillDefaults().applyTo(bottomPane);
		topPane.setLayout(new FormPageLayout(0,0));
		//
		«FOREACH sections->asSequence() AS s-»
		«s.className» _«s.className.xpandToFirstLower()» = new «s.className»(bottomPane, managedForm);
		«ENDFOREACH»

		FormPageLayout.setMinimalWidth(uiProject.getSection(), 350);
		FormPageLayout.setMinimalWidth(uiWizard.getSection(), 350);
		org.eclipse.jface.layout.GridDataFactory.fillDefaults().grab(true, false).applyTo(actionsSection.getSection());
		//
		«FOREACH sections->asSequence() AS s-»
		managedForm.addPart(_«s.className.xpandToFirstLower()»);
		«ENDFOREACH»

//		if (mySectionStateSupport != null) {
//			mySectionStateSupport.restoreState(this);
//		}
		getManagedForm().setInput(((ProjectEditor) getEditor()).getProjectEditorInput());

//		PlatformUI.getWorkbench().getHelpSystem().setHelp(managedForm.getForm().getContent(), ID_HELP_CONTEXT);
	}

	@Override
	public void dispose() {
// TODO - add support for section states	
//		if (mySectionStateSupport != null) {
//			mySectionStateSupport.saveState(this);
//			mySectionStateSupport = null;
//		}
		super.dispose();
	}

}
«EXPAND Section::_class('') FOREACH sections»
«ENDDEFINE»