/* * This file is part of the OpenSCADA project * Copyright (C) 2006-2010 TH4 SYSTEMS GmbH (http://th4-systems.com) * * OpenSCADA is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenSCADA is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenSCADA. If not, see * <http://opensource.org/licenses/lgpl-3.0.html> for a copy of the LGPLv3 License. */ package org.openscada.da.client.signalgenerator; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.IMemento; import org.eclipse.ui.IViewSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.ViewPart; import org.openscada.core.Variant; import org.openscada.da.client.DataItemValue; import org.openscada.da.client.signalgenerator.page.GeneratorPage; import org.openscada.da.ui.connection.data.DataSourceListener; import org.openscada.da.ui.connection.data.Item; public class GeneratorView extends ViewPart implements SimulationTarget { public static final String VIEW_ID = "org.openscada.da.client.signalGenerator.GeneratorView"; //$NON-NLS-1$ private CTabFolder tabFolder; private final List<GeneratorPageInformation> pages = new LinkedList<GeneratorPageInformation> (); private GeneratorPageInformation activePage; private org.openscada.da.ui.connection.data.DataItemHolder item; private Composite header; private Button startButton; private Label errorLabel; public GeneratorView () { } @Override public void createPartControl ( final Composite parent ) { createPages (); applyParentLayout ( parent ); createHeader ( parent ); createTabFolder ( parent ); updateState (); } private void createTabFolder ( final Composite parent ) { this.tabFolder = new CTabFolder ( parent, SWT.BOTTOM ); this.tabFolder.setLayoutData ( new GridData ( GridData.FILL, GridData.FILL, true, true ) ); for ( final GeneratorPageInformation page : this.pages ) { final CTabItem tabItem = new CTabItem ( this.tabFolder, SWT.NONE ); final Composite tabComposite = new Composite ( this.tabFolder, SWT.NONE ); tabComposite.setLayout ( new FillLayout () ); page.getGeneratorPage ().createPage ( tabComposite ); tabItem.setText ( page.getLabel () ); tabItem.setControl ( tabComposite ); page.getGeneratorPage ().setTarget ( this ); } this.tabFolder.setSelection ( 0 ); } private void applyParentLayout ( final Composite parent ) { final GridLayout layout = new GridLayout ( 1, false ); layout.horizontalSpacing = layout.verticalSpacing = 0; layout.marginWidth = layout.marginHeight = 0; parent.setLayout ( layout ); } private void createHeader ( final Composite parent ) { this.header = new Composite ( parent, SWT.NONE ); this.header.setLayoutData ( new GridData ( GridData.BEGINNING, GridData.BEGINNING, true, false ) ); this.header.setLayout ( new RowLayout () ); this.startButton = new Button ( this.header, SWT.TOGGLE ); this.startButton.setText ( Messages.getString ( "GeneratorView.ButtonGo" ) ); this.startButton.addSelectionListener ( new SelectionAdapter () { @Override public void widgetSelected ( final SelectionEvent e ) { GeneratorView.this.toggleButton ( GeneratorView.this.startButton.getSelection () ); } } ); this.errorLabel = new Label ( this.header, SWT.NONE ); } protected void toggleButton ( final boolean selection ) { if ( selection ) { handleStart (); } else { handleStop (); } } protected GeneratorPageInformation getSelection () { try { return this.pages.get ( this.tabFolder.getSelectionIndex () ); } catch ( final Throwable e ) { return null; } } private void handleStop () { if ( this.activePage != null ) { this.activePage.getGeneratorPage ().stop (); this.activePage = null; updateState (); } } private void handleStart () { handleStop (); this.activePage = getSelection (); if ( this.activePage != null ) { this.activePage.getGeneratorPage ().start (); } updateState (); } private void updateState () { final boolean state = this.activePage == null; if ( this.startButton != null ) { this.startButton.setEnabled ( this.item != null ); this.startButton.setSelection ( !state ); this.tabFolder.setEnabled ( state ); } } private void createPages () { try { for ( final GeneratorPageInformation info : getPageInformation () ) { this.pages.add ( info ); } } catch ( final CoreException e ) { ErrorDialog.openError ( this.getSite ().getShell (), Messages.getString ( "GeneratorView.createPages.error" ), Messages.getString ( "GeneratorView.createPages.errorMessage" ), e.getStatus () ); } } @Override public void dispose () { for ( final GeneratorPageInformation page : this.pages ) { page.getGeneratorPage ().dispose (); } this.pages.clear (); super.dispose (); } @Override public void setFocus () { this.tabFolder.setFocus (); } public void setDataItem ( final Item item ) { if ( item != null ) { this.item = new org.openscada.da.ui.connection.data.DataItemHolder ( Activator.getDefault ().getBundle ().getBundleContext (), item, new DataSourceListener () { public void updateData ( final DataItemValue value ) { GeneratorView.this.updateData (); } } ); setPartName ( String.format ( Messages.getString ( "GeneratorView.partName" ), item.getId (), item.getConnectionString () ) ); } else { setPartName ( Messages.getString ( "GeneratorView.emptyPartName" ) ); } updateState (); } protected void updateData () { // TODO Auto-generated method stub } private Collection<GeneratorPageInformation> getPageInformation () throws CoreException { final List<GeneratorPageInformation> result = new LinkedList<GeneratorPageInformation> (); for ( final IConfigurationElement element : Platform.getExtensionRegistry ().getConfigurationElementsFor ( Activator.EXTP_GENERATOR_PAGE ) ) { if ( !"generatorPage".equals ( element.getName () ) ) { continue; } Object o; o = element.createExecutableExtension ( "class" ); if ( ! ( o instanceof GeneratorPage ) ) { throw new CoreException ( new Status ( Status.ERROR, Activator.PLUGIN_ID, Messages.getString ( "GeneratorView.classTypeMismatchError" ) ) ); } final GeneratorPageInformation info = new GeneratorPageInformation (); info.setGeneratorPage ( (GeneratorPage)o ); info.setLabel ( element.getAttribute ( "label" ) ); //$NON-NLS-1$ info.setSortKey ( element.getAttribute ( "sortKey" ) ); result.add ( info ); } Collections.sort ( result, new Comparator<GeneratorPageInformation> () { public int compare ( final GeneratorPageInformation arg0, final GeneratorPageInformation arg1 ) { String key1 = arg0.getSortKey (); String key2 = arg1.getSortKey (); if ( key1 == null ) { key1 = ""; } if ( key2 == null ) { key2 = ""; } return key1.compareTo ( key2 ); } } ); return result; } @Override public void init ( final IViewSite site, final IMemento memento ) throws PartInitException { super.init ( site, memento ); setDataItem ( Item.loadFrom ( memento ) ); } @Override public void saveState ( final IMemento memento ) { super.saveState ( memento ); if ( this.item != null ) { this.item.getItem ().saveTo ( memento ); } } public void writeValue ( final Variant value ) { final org.openscada.da.ui.connection.data.DataItemHolder item = this.item; if ( item != null ) { item.write ( value ); } } protected void setFailure ( final String reason ) { if ( reason != null ) { triggerErrorLabel ( reason ); } else { triggerErrorLabel ( "" ); } } private void triggerErrorLabel ( final String string ) { final Display d = this.errorLabel.getDisplay (); if ( !d.isDisposed () ) { d.asyncExec ( new Runnable () { public void run () { if ( !GeneratorView.this.errorLabel.isDisposed () ) { GeneratorView.this.errorLabel.setText ( string ); } } } ); } } }