1765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye/******************************************************************************* 2765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Copyright (c) 2011 Google, Inc. 3765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * All rights reserved. This program and the accompanying materials 4765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * are made available under the terms of the Eclipse Public License v1.0 5765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * which accompanies this distribution, and is available at 6765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * http://www.eclipse.org/legal/epl-v10.html 7765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 8765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Contributors: 9765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Google, Inc. - initial API and implementation 10765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye *******************************************************************************/ 11765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyepackage org.eclipse.wb.internal.core.model.property.table; 12765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 13765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport com.google.common.collect.Lists; 14765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport com.google.common.collect.Sets; 15765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 16765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.jface.viewers.ISelection; 17765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.jface.viewers.ISelectionChangedListener; 18765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.jface.viewers.ISelectionProvider; 19765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.jface.viewers.SelectionChangedEvent; 20765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.jface.viewers.StructuredSelection; 21765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.SWT; 22765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.events.KeyAdapter; 23765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.events.KeyEvent; 24765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.events.MouseAdapter; 25765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.events.MouseEvent; 26765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.events.MouseMoveListener; 27765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.graphics.Color; 28765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.graphics.Font; 29765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.graphics.GC; 30765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.graphics.Image; 31765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.graphics.Point; 32765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.graphics.Rectangle; 33765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.Canvas; 34765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.Composite; 35765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.Event; 36765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.Listener; 37765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.ScrollBar; 38765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.draw2d.IColorConstants; 39765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.draw2d.ICursorConstants; 40765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.DesignerPlugin; 4162a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbyeimport org.eclipse.wb.internal.core.EnvironmentUtils; 42765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.model.property.Property; 43765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.model.property.category.PropertyCategory; 44765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.model.property.category.PropertyCategoryProvider; 45765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.model.property.category.PropertyCategoryProviders; 46765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.model.property.editor.PropertyEditor; 47765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.model.property.editor.complex.IComplexPropertyEditor; 4862a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbyeimport org.eclipse.wb.internal.core.model.property.editor.presentation.ButtonPropertyEditorPresentation; 49765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.model.property.editor.presentation.PropertyEditorPresentation; 50765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.utils.check.Assert; 51765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.utils.ui.DrawUtils; 52765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 53765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport java.util.Collection; 54765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport java.util.List; 55765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport java.util.Set; 56765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 57765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye/** 58765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Control that can display {@link Property}'s and edit them using {@link PropertyEditor}'s. 59765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 60765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @author scheglov_ke 61765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @author lobas_av 62765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @coverage core.model.property.table 63765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 64765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyepublic class PropertyTable extends Canvas implements ISelectionProvider { 65765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 66765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 67765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Colors 68765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 69765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 70765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final Color COLOR_BACKGROUND = IColorConstants.listBackground; 71765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final Color COLOR_NO_PROPERTIES = IColorConstants.gray; 72765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final Color COLOR_LINE = IColorConstants.lightGray; 73765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final Color COLOR_COMPLEX_LINE = DrawUtils.getShiftedColor( 74765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye IColorConstants.lightGray, 75765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye -32); 76765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final Color COLOR_PROPERTY_BG = DrawUtils.getShiftedColor(COLOR_BACKGROUND, -12); 77765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final Color COLOR_PROPERTY_BG_MODIFIED = COLOR_BACKGROUND; 78765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final Color COLOR_PROPERTY_FG_TITLE = IColorConstants.listForeground; 79765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final Color COLOR_PROPERTY_FG_VALUE = 80765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye DrawUtils.isDarkColor(IColorConstants.listBackground) 81765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye ? IColorConstants.lightBlue 82765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye : IColorConstants.darkBlue; 83765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final Color COLOR_PROPERTY_BG_SELECTED = IColorConstants.listSelection; 84765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final Color COLOR_PROPERTY_FG_SELECTED = IColorConstants.listSelectionText; 85765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final Color COLOR_PROPERTY_FG_ADVANCED = IColorConstants.gray; 86765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // BEGIN ADT MODIFICATIONS 87765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public static final Color COLOR_PROPERTY_FG_DEFAULT = IColorConstants.darkGray; 88765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // END ADT MODIFICATIONS 89765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 90765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 91765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Sizes 92765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 93765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 94765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final int MIN_COLUMN_WIDTH = 75; 95765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final int MARGIN_LEFT = 2; 96765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final int MARGIN_RIGHT = 1; 97765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final int STATE_IMAGE_MARGIN_RIGHT = 4; 98765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 99765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 100765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Images 101765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 102765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 103765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final Image m_plusImage = DesignerPlugin.getImage("properties/plus.gif"); 104765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static final Image m_minusImage = DesignerPlugin.getImage("properties/minus.gif"); 105765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static int m_stateWidth = 9; 106765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 107765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 108765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Instance fields 109765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 110765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 111765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private final PropertyTableTooltipHelper m_tooltipHelper; 112765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private boolean m_showAdvancedProperties; 113765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private Property[] m_rawProperties; 114765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private List<PropertyInfo> m_properties; 115765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private final Set<String> m_expandedIds = Sets.newTreeSet(); 116765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // BEGIN ADT MODIFICATIONS 117765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Add support for "expand by default" : If you specify ids to be collapsed by 118765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // default, then any *other* ids will be expanded by default. 119765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private Set<String> m_collapsedIds = null; 120765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 121765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 122765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Sets a set of ids that should be collapsed by default. Everything else 123765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * will be expanded by default. If this method is not called, ids are 124765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * collapsed by default instead. 125765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 126765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @param names set of ids to be collapsed 127765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 128765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void setDefaultCollapsedNames(Collection<String> names) { 129765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_collapsedIds = Sets.newTreeSet(); 130765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (String name : names) { 131765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_collapsedIds.add("|" + name); // See PropertyInfo constructor for id syntax 132765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 133765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 134765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // END ADT MODIFICATIONS 135765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 136765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private Image m_bufferedImage; 137765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private int m_rowHeight; 138765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private int m_selection; 139765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private int m_page; 140765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private int m_splitter = -1; 141765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 142765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 143765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 144765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Constructor 145765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 146765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 147765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public PropertyTable(Composite parent, int style) { 148765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye super(parent, style | SWT.V_SCROLL | SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE); 149765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye hookControlEvents(); 150765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // calculate sizes 151765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 152765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye GC gc = new GC(this); 153765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 154765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_rowHeight = 1 + gc.getFontMetrics().getHeight() + 1; 155765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } finally { 156765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.dispose(); 157765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 158765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 159765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // install tooltip helper 160765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_tooltipHelper = new PropertyTableTooltipHelper(this); 161765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 162765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 163765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 164765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 165765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Events 166765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 167765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 168765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 169765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Adds listeners for events. 170765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 171765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void hookControlEvents() { 172765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye addListener(SWT.Dispose, new Listener() { 173765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 174765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void handleEvent(Event event) { 175765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye disposeBufferedImage(); 176765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 177765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye }); 178765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye addListener(SWT.Resize, new Listener() { 179765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 180765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void handleEvent(Event event) { 181765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye handleResize(); 182765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 183765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye }); 184765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye addListener(SWT.Paint, new Listener() { 185765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 186765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void handleEvent(Event event) { 187765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye handlePaint(event.gc, event.x, event.y, event.width, event.height); 188765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 189765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye }); 190765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye getVerticalBar().addListener(SWT.Selection, new Listener() { 191765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 192765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void handleEvent(Event event) { 193765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye handleVerticalScrolling(); 194765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 195765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye }); 196765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye addMouseListener(new MouseAdapter() { 197765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 198765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void mouseDown(MouseEvent event) { 199765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye forceFocus(); 200765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye handleMouseDown(event); 201765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 202765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 203765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 204765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void mouseUp(MouseEvent event) { 205765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye handleMouseUp(event); 206765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 207765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 208765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 209765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void mouseDoubleClick(MouseEvent event) { 210765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye handleMouseDoubleClick(event); 211765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 212765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye }); 213765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye addMouseMoveListener(new MouseMoveListener() { 214765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 215765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void mouseMove(MouseEvent event) { 216765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye handleMouseMove(event); 217765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 218765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye }); 219765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // keyboard 220765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye addKeyListener(new KeyAdapter() { 221765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 222765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void keyPressed(KeyEvent e) { 223765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye handleKeyDown(e); 224765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 225765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye }); 226765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 227765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 228765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 229765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 230765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Events: dispose, resize, scroll 231765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 232765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 233765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 234765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Disposes image used for double buffered painting. 235765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 236765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void disposeBufferedImage() { 237765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_bufferedImage != null) { 238765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_bufferedImage.dispose(); 239765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_bufferedImage = null; 240765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 241765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 242765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 243765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 244765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Handles {@link SWT#Resize} event. 245765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 246765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void handleResize() { 247765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye disposeBufferedImage(); 248765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye configureScrolling(); 249765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // splitter 250765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 251765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // set default value for splitter 252765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_splitter <= MIN_COLUMN_WIDTH) { 253765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_splitter = Math.max((int) (getClientArea().width * 0.4), MIN_COLUMN_WIDTH); 254765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 255765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye configureSplitter(); 256765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 257765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 258765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 259765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 260765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Handles {@link SWT#Selection} event for vertical {@link ScrollBar}. 261765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 262765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void handleVerticalScrolling() { 263765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye ScrollBar verticalBar = getVerticalBar(); 264765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (verticalBar.getEnabled()) { 265765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // update selection 266765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_selection = verticalBar.getSelection(); 267765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // redraw (but not include vertical bar to avoid flashing) 268765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 269765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Rectangle clientArea = getClientArea(); 270765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye redraw(clientArea.x, clientArea.y, clientArea.width, clientArea.height, false); 271765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 272765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 273765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 274765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 275765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 276765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 277765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Keyboard 278765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 279765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 280765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 281765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Handles {@link SWT#KeyDown} event. 282765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 283765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void handleKeyDown(KeyEvent e) { 284765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_activePropertyInfo != null) { 285765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 286765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Property property = m_activePropertyInfo.getProperty(); 287765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // expand/collapse 288765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_activePropertyInfo.isComplex()) { 289765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!m_activePropertyInfo.isExpanded() 290765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye && (e.character == '+' || e.keyCode == SWT.ARROW_RIGHT)) { 291765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_activePropertyInfo.expand(); 292765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye configureScrolling(); 293765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return; 294765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 295765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_activePropertyInfo.isExpanded() 296765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye && (e.character == '-' || e.keyCode == SWT.ARROW_LEFT)) { 297765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_activePropertyInfo.collapse(); 298765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye configureScrolling(); 299765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return; 300765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 301765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 302765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // navigation 303765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (navigate(e)) { 304765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return; 305765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 306765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // editor activation 307765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (e.character == ' ' || e.character == SWT.CR) { 308765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye activateEditor(property, null); 309765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return; 310765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 311765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // DEL 312765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (e.keyCode == SWT.DEL) { 313765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye e.doit = false; 314765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye property.setValue(Property.UNKNOWN_VALUE); 315765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return; 316765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 317765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // send to editor 318765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye property.getEditor().keyDown(this, property, e); 319765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable ex) { 320765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye DesignerPlugin.log(ex); 321765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 322765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 323765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 324765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 325765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 326765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return <code>true</code> if given {@link KeyEvent} was navigation event, so new 327765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * {@link PropertyInfo} was selected. 328765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 329765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public boolean navigate(KeyEvent e) { 330765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int index = m_properties.indexOf(m_activePropertyInfo); 331765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Rectangle clientArea = getClientArea(); 332765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 333765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int newIndex = index; 334765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (e.keyCode == SWT.HOME) { 335765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye newIndex = 0; 336765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else if (e.keyCode == SWT.END) { 337765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye newIndex = m_properties.size() - 1; 338765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else if (e.keyCode == SWT.PAGE_UP) { 339765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye newIndex = Math.max(index - m_page + 1, 0); 340765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else if (e.keyCode == SWT.PAGE_DOWN) { 341765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye newIndex = Math.min(index + m_page - 1, m_properties.size() - 1); 342765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else if (e.keyCode == SWT.ARROW_UP) { 343765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye newIndex = Math.max(index - 1, 0); 344765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else if (e.keyCode == SWT.ARROW_DOWN) { 345765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye newIndex = Math.min(index + 1, m_properties.size() - 1); 346765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 347765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // activate new property 348765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (newIndex != index && newIndex < m_properties.size()) { 349765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye setActivePropertyInfo(m_properties.get(newIndex)); 350765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // check for scrolling 351765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int y = m_rowHeight * (newIndex - m_selection); 352765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (y < 0) { 353765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_selection = newIndex; 354765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye configureScrolling(); 355765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else if (y + m_rowHeight > clientArea.height) { 356765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_selection = newIndex - m_page + 1; 357765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye configureScrolling(); 358765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 359765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // repaint 360765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye redraw(); 361765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return true; 362765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 363765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // no navigation change 364765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return false; 365765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 366765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 367765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 368765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 369765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Events: mouse 370765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 371765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 372765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private boolean m_splitterResizing; 373765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 374765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * We do expand/collapse on to events: click on state sign and on double click. But when we double 375765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * click on state sign, we will have <em>two</em> events, so we should ignore double click. 376765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 377765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private long m_lastExpandCollapseTime; 378765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 379765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 380765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Handles {@link SWT#MouseDown} event. 381765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 382765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void handleMouseDown(MouseEvent event) { 383765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_splitterResizing = event.button == 1 && m_properties != null && isLocationSplitter(event.x); 384765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // click in property 385765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!m_splitterResizing && m_properties != null) { 386765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int propertyIndex = getPropertyIndex(event.y); 387765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (propertyIndex >= m_properties.size()) { 388765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return; 389765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 390765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // prepare property 391765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye setActivePropertyInfo(m_properties.get(propertyIndex)); 392765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Property property = m_activePropertyInfo.getProperty(); 393765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // de-activate current editor 394765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye deactivateEditor(true); 395765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye redraw(); 396765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // activate editor 397765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (isLocationValue(event.x)) { 398765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye activateEditor(property, getValueRelativeLocation(event.x, event.y)); 399765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 400765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 401765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 402765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 403765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 404765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Handles {@link SWT#MouseUp} event. 405765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 406765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void handleMouseUp(MouseEvent event) { 407765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (event.button == 1) { 408765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // resize splitter 409765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_splitterResizing) { 410765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_splitterResizing = false; 411765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return; 412765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 413765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // if out of bounds, then ignore 414765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!getClientArea().contains(event.x, event.y)) { 415765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return; 416765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 417765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // update 418765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_properties != null) { 419765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int index = getPropertyIndex(event.y); 420765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (index < m_properties.size()) { 421765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyInfo propertyInfo = m_properties.get(index); 422765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // check for expand/collapse 423765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (isLocationState(propertyInfo, event.x)) { 424765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 425765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_lastExpandCollapseTime = System.currentTimeMillis(); 426765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye propertyInfo.flip(); 427765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye configureScrolling(); 428765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable e) { 429765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye DesignerPlugin.log(e); 430765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 431765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 432765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 433765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 434765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 435765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 436765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 437765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 438765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Handles {@link SWT#MouseDoubleClick} event. 439765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 440765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void handleMouseDoubleClick(MouseEvent event) { 441765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (System.currentTimeMillis() - m_lastExpandCollapseTime > getDisplay().getDoubleClickTime()) { 442765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 443765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_activePropertyInfo != null) { 444765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_activePropertyInfo.isComplex()) { 445765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_activePropertyInfo.flip(); 446765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye configureScrolling(); 447765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else { 448765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Property property = m_activePropertyInfo.getProperty(); 449765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye property.getEditor().doubleClick(property, getValueRelativeLocation(event.x, event.y)); 450765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 451765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 452765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable e) { 453765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye handleException(e); 454765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 455765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 456765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 457765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 458765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 459765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Handles {@link SWT#MouseMove} event. 460765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 461765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void handleMouseMove(MouseEvent event) { 462765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int x = event.x; 463765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // resize splitter 464765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_splitterResizing) { 465765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_splitter = x; 466765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye configureSplitter(); 467765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye redraw(); 468765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return; 469765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 470765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // if out of bounds, then ignore 471765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!getClientArea().contains(event.x, event.y)) { 472765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return; 473765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 474765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // update 475765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_properties != null) { 476765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // update cursor 477765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (isLocationSplitter(x)) { 478765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye setCursor(ICursorConstants.SIZEWE); 479765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else { 480765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye setCursor(null); 481765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 482765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // update tooltip helper 483765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye updateTooltip(event); 484765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else { 485765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye updateTooltipNoProperty(); 486765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 487765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 488765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 489765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 490765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Updates {@link PropertyTableTooltipHelper}. 491765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 492765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void updateTooltip(MouseEvent event) { 493765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int x = event.x; 494765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int propertyIndex = getPropertyIndex(event.y); 495765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 496765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (propertyIndex < m_properties.size()) { 497765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyInfo propertyInfo = m_properties.get(propertyIndex); 498765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Property property = propertyInfo.getProperty(); 499765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int y = (propertyIndex - m_selection) * m_rowHeight; 500765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // check for title 501765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 502765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int titleX = getTitleTextX(propertyInfo); 503765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int titleRight = m_splitter - 2; 504765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (titleX <= x && x < titleRight) { 505765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_tooltipHelper.update(property, true, false, titleX, titleRight, y, m_rowHeight); 506765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return; 507765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 508765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 509765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // check for value 510765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 511765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int valueX = m_splitter + 3; 512765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (x > valueX) { 513765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_tooltipHelper.update( 514765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye property, 515765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye false, 516765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye true, 517765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye valueX, 518765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye getClientArea().width, 519765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye y, 520765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_rowHeight); 521765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 522765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 523765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else { 524765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye updateTooltipNoProperty(); 525765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 526765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 527765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 528765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void updateTooltipNoProperty() { 529765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_tooltipHelper.update(null, false, false, 0, 0, 0, 0); 530765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 531765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 532765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 533765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 534765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Editor 535765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 536765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 537765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private PropertyInfo m_activePropertyInfo; 538765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private String m_activePropertyId; 539765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private PropertyEditor m_activeEditor; 540765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 541765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 542765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Tries to activate editor for {@link PropertyInfo} under cursor. 543765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 544765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @param location 545765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * the mouse location, if editor is activated using mouse click, or <code>null</code> if 546765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * it is activated using keyboard. 547765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 548765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void activateEditor(Property property, Point location) { 549765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 550765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // de-activate old editor 551765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye deactivateEditor(true); 552765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // activate editor 553765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyEditor editor = property.getEditor(); 554765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 555765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (editor.activate(this, property, location)) { 556765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_activeEditor = editor; 557765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 558765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable e) { 559765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye handleException(e); 560765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 561765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // set bounds 562765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye setActiveEditorBounds(); 56362a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye } catch (NullPointerException e) { 56462a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye if (EnvironmentUtils.IS_MAC) { 56562a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye // Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=388574 56662a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye PropertyEditor editor = property.getEditor(); 56762a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye PropertyEditorPresentation presentation = editor.getPresentation(); 56862a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye if (presentation instanceof ButtonPropertyEditorPresentation) { 56962a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye ButtonPropertyEditorPresentation button = 57062a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye (ButtonPropertyEditorPresentation) presentation; 57162a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye try { 57262a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye button.click(this, property); 57362a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye } catch (Exception ex) { 57462a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye deactivateEditor(false); 57562a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye handleException(e); 57662a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye } 57762a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye return; 57862a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye } 57962a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye } 58062a54a64746b33b65f33c9e71bf8dc54e96a37b6Tor Norbye DesignerPlugin.log(e); 581765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable e) { 582765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye DesignerPlugin.log(e); 583765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 584765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 585765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 586765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 587765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Deactivates current {@link PropertyEditor}. 588765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 589765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void deactivateEditor(boolean save) { 590765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_activeEditor != null) { 591765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyEditor activeEditor = m_activeEditor; 592765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_activeEditor = null; 593765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_activePropertyInfo != null && m_activePropertyInfo.m_property != null) { 594765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye activeEditor.deactivate(this, m_activePropertyInfo.m_property, save); 595765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 596765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 597765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 598765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 599765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 600765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Sets correct bounds for active editor, for example we need update bounds after scrolling. 601765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 602765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void setActiveEditorBounds() { 603765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_activeEditor != null) { 604765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int index = m_properties.indexOf(m_activePropertyInfo); 605765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (index == -1) { 606765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // it is possible that active property was hidden because its parent was collapsed 607765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye deactivateEditor(true); 608765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else { 609765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // prepare bounds for editor 610765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Rectangle bounds; 611765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 612765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Rectangle clientArea = getClientArea(); 613765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int x = m_splitter + 1; 614765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int width = clientArea.width - x - MARGIN_RIGHT; 615765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int y = m_rowHeight * (index - m_selection) + 1; 616765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int height = m_rowHeight - 1; 617765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bounds = new Rectangle(x, y, width, height); 618765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 619765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // update bounds using presentation 620765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 621765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyEditorPresentation presentation = m_activeEditor.getPresentation(); 622765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (presentation != null) { 623765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int presentationWidth = 624765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye presentation.show( 625765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye this, 626765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_activePropertyInfo.m_property, 627765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bounds.x, 628765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bounds.y, 629765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bounds.width, 630765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bounds.height); 631765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bounds.width -= presentationWidth; 632765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 633765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 634765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // set editor bounds 635765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_activeEditor.setBounds(bounds); 636765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 637765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 638765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 639765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 640765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 641765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 642765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Exceptions 643765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 644765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 645765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private IPropertyExceptionHandler m_exceptionHandler; 646765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 647765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 648765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Sets {@link IPropertyExceptionHandler} for handling all exceptions. 649765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 650765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void setExceptionHandler(IPropertyExceptionHandler exceptionHandler) { 651765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_exceptionHandler = exceptionHandler; 652765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 653765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 654765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 655765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Handles given {@link Throwable}.<br> 656765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Right now it just logs it, but in future we can open some dialog here. 657765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 658765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void handleException(Throwable e) { 659765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_exceptionHandler.handle(e); 660765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 661765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 662765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 663765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 664765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Scrolling 665765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 666765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 667765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 668765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Configures vertical {@link ScrollBar}. 669765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 670765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void configureScrolling() { 671765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye ScrollBar verticalBar = getVerticalBar(); 672765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_properties == null) { 673765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye verticalBar.setEnabled(false); 674765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else { 675765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_page = getClientArea().height / m_rowHeight; 676765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_selection = Math.max(0, Math.min(m_properties.size() - m_page, m_selection)); 677765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye verticalBar.setValues(m_selection, 0, m_properties.size(), m_page, 1, m_page); 678765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // enable/disable scrolling 679765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_properties.size() <= m_page) { 680765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye verticalBar.setEnabled(false); 681765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else { 682765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye verticalBar.setEnabled(true); 683765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 684765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 685765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // redraw, we reconfigure scrolling only if list of properties was changed, so we should redraw 686765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye redraw(); 687765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 688765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 689765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 690765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 691765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Location/size utils 692765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 693765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 694765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 695765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the <code>X</code> position for first pixel of {@link PropertyInfo} title (location of 696765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * state image). 697765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 698765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private int getTitleX(PropertyInfo propertyInfo) { 699765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return MARGIN_LEFT + getLevelIndent() * propertyInfo.getLevel(); 700765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 701765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 702765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 703765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the <code>X</code> position for first pixel of {@link PropertyInfo} title text. 704765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 705765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private int getTitleTextX(PropertyInfo propertyInfo) { 706765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return getTitleX(propertyInfo) + getLevelIndent(); 707765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 708765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 709765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 710765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the indentation for single level. 711765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 712765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private int getLevelIndent() { 713765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return m_stateWidth + STATE_IMAGE_MARGIN_RIGHT; 714765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 715765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 716765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 717765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Checks horizontal splitter value to boundary values. 718765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 719765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void configureSplitter() { 720765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Rectangle clientArea = getClientArea(); 721765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // check title width 722765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_splitter < MIN_COLUMN_WIDTH) { 723765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_splitter = MIN_COLUMN_WIDTH; 724765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 725765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // check value width 726765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (clientArea.width - m_splitter < MIN_COLUMN_WIDTH) { 727765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_splitter = clientArea.width - MIN_COLUMN_WIDTH; 728765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 729765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 730765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 731765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 732765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the index in {@link #m_properties} corresponding given <code>y</code> location. 733765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 734765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private int getPropertyIndex(int y) { 735765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return m_selection + y / m_rowHeight; 736765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 737765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 738765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 739765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return <code>true</code> if given <code>x</code> coordinate is on state (plus/minus) image. 740765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 741765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private boolean isLocationState(PropertyInfo propertyInfo, int x) { 742765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int levelX = getTitleX(propertyInfo); 743765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return propertyInfo.isComplex() && levelX <= x && x <= levelX + m_stateWidth; 744765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 745765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 746765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 747765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Returns <code>true</code> if <code>x</code> coordinate is on splitter. 748765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 749765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private boolean isLocationSplitter(int x) { 750765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return Math.abs(m_splitter - x) < 2; 751765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 752765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 753765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 754765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return <code>true</code> if given <code>x</code> is on value part of property. 755765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 756765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private boolean isLocationValue(int x) { 757765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return x > m_splitter + 2; 758765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 759765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 760765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 761765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @param x 762765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * the {@link PropertyTable} relative coordinate. 763765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @param y 764765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * the {@link PropertyTable} relative coordinate. 765765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 766765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the location relative to the value part of property. 767765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 768765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private Point getValueRelativeLocation(int x, int y) { 769765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return new Point(x - (m_splitter + 2), y - m_rowHeight * getPropertyIndex(y)); 770765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 771765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 772765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 773765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 774765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Access 775765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 776765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 777765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 778765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Shows or hides {@link Property}-s with {@link PropertyCategory#ADVANCED}. 779765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 780765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void setShowAdvancedProperties(boolean showAdvancedProperties) { 781765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_showAdvancedProperties = showAdvancedProperties; 782765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye setInput0(); 783765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 784765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 785765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 786765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Sets the array of {@link Property}'s to display/edit. 787765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 788765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void setInput(Property[] properties) { 789765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_rawProperties = properties; 790765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye setInput0(); 791765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 792765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 793765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void setInput0() { 794765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // send "hide" to all PropertyEditorPresentation's 795765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_properties != null) { 796765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (PropertyInfo propertyInfo : m_properties) { 797765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Property property = propertyInfo.getProperty(); 798765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // hide presentation 799765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 800765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyEditorPresentation presentation = property.getEditor().getPresentation(); 801765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (presentation != null) { 802765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye presentation.hide(this, property); 803765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 804765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 805765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 806765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 807765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // set new properties 808765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_rawProperties == null || m_rawProperties.length == 0) { 809765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye deactivateEditor(false); 810765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_properties = Lists.newArrayList(); 811765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else { 812765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 813765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // add PropertyInfo for each Property 814765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_properties = Lists.newArrayList(); 815765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (Property property : m_rawProperties) { 816765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (rawProperties_shouldShow(property)) { 817765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyInfo propertyInfo = new PropertyInfo(property); 818765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_properties.add(propertyInfo); 819765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 820765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 821765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // expand properties using history 822765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye while (true) { 823765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye boolean expanded = false; 824765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye List<PropertyInfo> currentProperties = Lists.newArrayList(m_properties); 825765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (PropertyInfo propertyInfo : currentProperties) { 826765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye expanded |= propertyInfo.expandFromHistory(); 827765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 828765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // stop 829765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!expanded) { 830765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye break; 831765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 832765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 833765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable e) { 834765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye DesignerPlugin.log(e); 835765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 836765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 837765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // update active property 838765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_activePropertyId != null) { 839765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyInfo newActivePropertyInfo = null; 840765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // try to find corresponding PropertyInfo 841765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_properties != null) { 842765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (PropertyInfo propertyInfo : m_properties) { 843765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (propertyInfo.m_id.equals(m_activePropertyId)) { 844765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye newActivePropertyInfo = propertyInfo; 845765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye break; 846765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 847765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 848765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 849765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // set new PropertyInfo 850765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye setActivePropertyInfo(newActivePropertyInfo); 851765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 852765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // update scroll bar 853765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye configureScrolling(); 854765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 855765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 856765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 857765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return <code>true</code> if given {@link Property} should be displayed. 858765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 859765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private boolean rawProperties_shouldShow(Property property) throws Exception { 860765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyCategory category = getCategory(property); 861765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // filter out hidden properties 862765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (category.isHidden()) { 863765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return false; 864765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 865765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // filter out advanced properties 866765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (category.isAdvanced()) { 867765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!m_showAdvancedProperties && !property.isModified()) { 868765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return false; 869765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 870765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 871765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (category.isAdvancedReally()) { 872765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return m_showAdvancedProperties; 873765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 874765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // OK 875765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return true; 876765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 877765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 878765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 879765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Activates given {@link Property}. 880765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 881765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void setActiveProperty(Property property) { 882765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (PropertyInfo propertyInfo : m_properties) { 883765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (propertyInfo.m_property == property) { 884765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye setActivePropertyInfo(propertyInfo); 885765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye break; 886765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 887765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 888765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 889765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 890765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 891765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 892765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Access: only for testing 893765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 894765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 895765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 896765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the count of properties in "expanded" list. 897765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 898765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public int forTests_getPropertiesCount() { 899765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return m_properties.size(); 900765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 901765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 902765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 903765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the {@link Property} from "expanded" list. 904765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 905765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public Property forTests_getProperty(int index) { 906765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return m_properties.get(index).getProperty(); 907765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 908765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 909765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 910765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Expands the {@link PropertyInfo} with given index. 911765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 912765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void forTests_expand(int index) throws Exception { 913765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_properties.get(index).expand(); 914765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 915765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 916765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 917765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the position of splitter. 918765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 919765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public int forTests_getSplitter() { 920765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return m_splitter; 921765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 922765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 923765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 924765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the location of state image (plus/minus) for given {@link Property}. 925765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 926765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public Point forTests_getStateLocation(Property property) { 927765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyInfo propertyInfo = getPropertyInfo(property); 928765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (propertyInfo != null) { 929765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int index = m_properties.indexOf(propertyInfo); 930765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int x = getTitleX(propertyInfo); 931765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int y = m_rowHeight * (index - m_selection) + 1; 932765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return new Point(x, y); 933765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 934765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return null; 935765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 936765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 937765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 938765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the location of state image (plus/minus) for given {@link Property}. 939765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 940765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public Point forTests_getValueLocation(Property property) { 941765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyInfo propertyInfo = getPropertyInfo(property); 942765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (propertyInfo != null) { 943765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int index = m_properties.indexOf(propertyInfo); 944765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int x = m_splitter + 5; 945765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int y = m_rowHeight * (index - m_selection) + 1; 946765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return new Point(x, y); 947765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 948765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return null; 949765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 950765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 951765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 952765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the active {@link PropertyEditor}. 953765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 954765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public PropertyEditor forTests_getActiveEditor() { 955765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return m_activeEditor; 956765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 957765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 958765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 959765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the {@link PropertyCategory} that is used by this {@link PropertyTable} to display. 960765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 961765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public PropertyCategory forTests_getCategory(Property property) { 962765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return getCategory(property); 963765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 964765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 965765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 966765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the {@link PropertyInfo}for given {@link Property}. 967765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 968765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private PropertyInfo getPropertyInfo(Property property) { 969765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (PropertyInfo propertyInfo : m_properties) { 970765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (propertyInfo.getProperty() == property) { 971765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return propertyInfo; 972765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 973765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 974765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return null; 975765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 976765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 977765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 978765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 979765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // ISelectionProvider 980765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 981765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 982765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private final List<ISelectionChangedListener> m_selectionListeners = Lists.newArrayList(); 983765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 984765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 985765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyepublic void addSelectionChangedListener(ISelectionChangedListener listener) { 986765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!m_selectionListeners.contains(listener)) { 987765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_selectionListeners.add(listener); 988765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 989765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 990765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 991765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 992765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyepublic void removeSelectionChangedListener(ISelectionChangedListener listener) { 993765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_selectionListeners.add(listener); 994765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 995765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 996765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 997765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyepublic ISelection getSelection() { 998765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_activePropertyInfo != null) { 999765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return new StructuredSelection(m_activePropertyInfo.getProperty()); 1000765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else { 1001765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return StructuredSelection.EMPTY; 1002765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1003765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1004765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1005765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 1006765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void setSelection(ISelection selection) { 1007765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye throw new UnsupportedOperationException(); 1008765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1009765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1010765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1011765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Sets the new active {@link PropertyInfo} and sends event to {@link ISelectionChangedListener} 1012765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 's. 1013765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1014765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void setActivePropertyInfo(PropertyInfo activePropertyInfo) { 1015765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_activePropertyInfo = activePropertyInfo; 1016765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // update m_activePropertyId only when really select property, 1017765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // not just remove selection because there are no corresponding property for old active 1018765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // so, later for some other component, if we don't select other property, old active will be selected 1019765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_activePropertyInfo != null) { 1020765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_activePropertyId = m_activePropertyInfo.m_id; 1021765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1022765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // make sure that active property is visible 1023765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_activePropertyInfo != null) { 1024765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int row = m_properties.indexOf(m_activePropertyInfo); 1025765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_selection <= row && row < m_selection + m_page) { 1026765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else { 1027765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_selection = row; 1028765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye configureScrolling(); 1029765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1030765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1031765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // send events 1032765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye SelectionChangedEvent selectionEvent = new SelectionChangedEvent(this, getSelection()); 1033765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (ISelectionChangedListener listener : m_selectionListeners) { 1034765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye listener.selectionChanged(selectionEvent); 1035765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1036765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // re-draw 1037765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye redraw(); 1038765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1039765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1040765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1041765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1042765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Painting 1043765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1044765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1045765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private boolean m_painting; 1046765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private Font m_baseFont; 1047765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private Font m_boldFont; 1048765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private Font m_italicFont; 1049765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1050765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1051765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Handles {@link SWT#Paint} event. 1052765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1053765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void handlePaint(GC gc, int x, int y, int width, int height) { 1054765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // sometimes we disable Eclipse Shell to prevent user actions, but we do this for short time 1055765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!isEnabled()) { 1056765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return; 1057765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1058765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // prevent recursion 1059765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_painting) { 1060765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return; 1061765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1062765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_painting = true; 1063765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1064765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 1065765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye setActiveEditorBounds(); 1066765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // prepare buffered image 1067765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_bufferedImage == null || m_bufferedImage.isDisposed()) { 1068765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Point size = getSize(); 1069765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_bufferedImage = new Image(DesignerPlugin.getStandardDisplay(), size.x, size.y); 1070765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1071765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // prepare buffered GC 1072765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye GC bufferedGC = null; 1073765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 1074765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // perform some drawing 1075765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 1076765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bufferedGC = new GC(m_bufferedImage); 1077765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bufferedGC.setClipping(x, y, width, height); 1078765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bufferedGC.setBackground(gc.getBackground()); 1079765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bufferedGC.setForeground(gc.getForeground()); 1080765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bufferedGC.setFont(gc.getFont()); 1081765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bufferedGC.setLineStyle(gc.getLineStyle()); 1082765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bufferedGC.setLineWidth(gc.getLineWidth()); 1083765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1084765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // fill client area 1085765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 1086765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Rectangle clientArea = getClientArea(); 1087765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bufferedGC.setBackground(COLOR_BACKGROUND); 1088765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bufferedGC.fillRectangle(clientArea); 1089765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1090765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // draw content 1091765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_properties == null || m_properties.size() == 0) { 1092765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye drawEmptyContent(bufferedGC); 1093765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else { 1094765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye drawContent(bufferedGC); 1095765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1096765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } finally { 1097765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // flush image 1098765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (bufferedGC != null) { 1099765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye bufferedGC.dispose(); 1100765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1101765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1102765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.drawImage(m_bufferedImage, 0, 0); 1103765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } finally { 1104765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_painting = false; 1105765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1106765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1107765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1108765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1109765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Draws content when there are no properties. 1110765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1111765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void drawEmptyContent(GC gc) { 1112765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Rectangle area = getClientArea(); 1113765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // draw message 1114765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setForeground(COLOR_NO_PROPERTIES); 1115765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye DrawUtils.drawStringCHCV( 1116765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc, 1117765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye "<No properties>", 1118765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 0, 1119765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 0, 1120765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye area.width, 1121765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye area.height); 1122765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1123765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1124765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1125765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Draws all {@link PropertyInfo}'s, separators, etc. 1126765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1127765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void drawContent(GC gc) { 1128765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Rectangle clientArea = getClientArea(); 1129765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // prepare fonts 1130765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_baseFont = gc.getFont(); 1131765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_boldFont = DrawUtils.getBoldFont(m_baseFont); 1132765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_italicFont = DrawUtils.getItalicFont(m_baseFont); 1133765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // show presentations 1134765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int[] presentationsWidth = showPresentations(clientArea); 1135765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // draw properties 1136765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 1137765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int y = clientArea.y - m_rowHeight * m_selection; 1138765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (int i = 0; i < m_properties.size(); i++) { 1139765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // skip, if not visible yet 1140765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (y + m_rowHeight < 0) { 1141765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye y += m_rowHeight; 1142765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye continue; 1143765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1144765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // stop, if already invisible 1145765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (y > clientArea.height) { 1146765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye break; 1147765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1148765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // draw single property 1149765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 1150765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyInfo propertyInfo = m_properties.get(i); 1151765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye drawProperty(gc, propertyInfo, y + 1, m_rowHeight - 1, clientArea.width 1152765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye - presentationsWidth[i]); 1153765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye y += m_rowHeight; 1154765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1155765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // draw row separator 1156765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setForeground(COLOR_LINE); 1157765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.drawLine(0, y, clientArea.width, y); 1158765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1159765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1160765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // draw expand line 1161765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye drawExpandLines(gc, clientArea); 1162765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // draw rectangle around table 1163765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setForeground(COLOR_LINE); 1164765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.drawRectangle(0, 0, clientArea.width - 1, clientArea.height - 1); 1165765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // draw splitter 1166765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setForeground(COLOR_LINE); 1167765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.drawLine(m_splitter, 0, m_splitter, clientArea.height); 1168765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // dispose font 1169765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_boldFont.dispose(); 1170765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_italicFont.dispose(); 1171765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1172765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1173765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1174765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Shows {@link PropertyEditorPresentation}'s for all {@link Property}'s, i.e. updates also their 1175765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * bounds. So, some {@link PropertyEditorPresentation}'s become invisible because they are moved 1176765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * above or below visible client area. 1177765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 1178765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the array of width for each {@link PropertyEditorPresentation}'s, consumed on the 1179765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * right. 1180765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1181765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private int[] showPresentations(Rectangle clientArea) { 1182765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int[] presentationsWidth = new int[m_properties.size()]; 1183765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // prepare value rectangle 1184765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int x = m_splitter + 4; 1185765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int w = clientArea.width - x - MARGIN_RIGHT; 1186765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // show presentation's for all properties 1187765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int y = clientArea.y - m_rowHeight * m_selection; 1188765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (int i = 0; i < m_properties.size(); i++) { 1189765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyInfo propertyInfo = m_properties.get(i); 1190765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Property property = propertyInfo.getProperty(); 1191765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyEditorPresentation presentation = property.getEditor().getPresentation(); 1192765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (presentation != null) { 1193765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye presentationsWidth[i] = presentation.show(this, property, x, y + 1, w, m_rowHeight - 1); 1194765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1195765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye y += m_rowHeight; 1196765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1197765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return presentationsWidth; 1198765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1199765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1200765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1201765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Draws lines from expanded complex property to its last sub-property. 1202765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1203765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void drawExpandLines(GC gc, Rectangle clientArea) { 1204765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int height = m_rowHeight - 1; 1205765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int xOffset = m_plusImage.getBounds().width / 2; 1206765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int yOffset = (height - m_plusImage.getBounds().width) / 2; 1207765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1208765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int y = clientArea.y - m_selection * m_rowHeight; 1209765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setForeground(COLOR_COMPLEX_LINE); 1210765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (int i = 0; i < m_properties.size(); i++) { 1211765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyInfo propertyInfo = m_properties.get(i); 1212765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1213765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (propertyInfo.isExpanded()) { 1214765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int index = m_properties.indexOf(propertyInfo); 1215765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // prepare index of last sub-property 1216765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int index2 = index; 1217765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (; index2 < m_properties.size(); index2++) { 1218765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyInfo nextPropertyInfo = m_properties.get(index2); 1219765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (nextPropertyInfo != propertyInfo 1220765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye && nextPropertyInfo.getLevel() <= propertyInfo.getLevel()) { 1221765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye break; 1222765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1223765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1224765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye index2--; 1225765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // draw line if there are children 1226765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (index2 > index) { 1227765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int x = getTitleX(propertyInfo) + xOffset; 1228765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int y1 = y + height - yOffset; 1229765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int y2 = y + m_rowHeight * (index2 - index) + m_rowHeight / 2; 1230765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.drawLine(x, y1, x, y2); 1231765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.drawLine(x, y2, x + m_rowHeight / 3, y2); 1232765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1233765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1234765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1235765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye y += m_rowHeight; 1236765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1237765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1238765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1239765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1240765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Draws single {@link PropertyInfo} in specified rectangle. 1241765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1242765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void drawProperty(GC gc, PropertyInfo propertyInfo, int y, int height, int width) { 1243765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // remember colors 1244765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Color oldBackground = gc.getBackground(); 1245765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Color oldForeground = gc.getForeground(); 1246765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // draw property 1247765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 1248765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Property property = propertyInfo.getProperty(); 1249765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye boolean isActiveProperty = 1250765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_activePropertyInfo != null && m_activePropertyInfo.getProperty() == property; 1251765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // set background 1252765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye boolean modified = property.isModified(); 1253765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 1254765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (isActiveProperty) { 1255765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setBackground(COLOR_PROPERTY_BG_SELECTED); 1256765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else { 1257765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (modified) { 1258765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setBackground(COLOR_PROPERTY_BG_MODIFIED); 1259765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else { 1260765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setBackground(COLOR_PROPERTY_BG); 1261765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1262765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1263765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.fillRectangle(0, y, width, height); 1264765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1265765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // draw state image 1266765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (propertyInfo.isShowComplex()) { 1267765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Image stateImage = propertyInfo.isExpanded() ? m_minusImage : m_plusImage; 1268765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye DrawUtils.drawImageCV(gc, stateImage, getTitleX(propertyInfo), y, height); 1269765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1270765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // draw title 1271765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 1272765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // configure GC 1273765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 1274765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setForeground(COLOR_PROPERTY_FG_TITLE); 1275765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // check category 1276765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (getCategory(property).isAdvanced()) { 1277765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setForeground(COLOR_PROPERTY_FG_ADVANCED); 1278765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setFont(m_italicFont); 1279765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else if (getCategory(property).isPreferred() || getCategory(property).isSystem()) { 1280765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setFont(m_boldFont); 1281765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1282765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // check for active 1283765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (isActiveProperty) { 1284765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setForeground(COLOR_PROPERTY_FG_SELECTED); 1285765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1286765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1287765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // paint title 1288765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int x = getTitleTextX(propertyInfo); 1289765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye DrawUtils.drawStringCV(gc, property.getTitle(), x, y, m_splitter - x, height); 1290765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1291765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // draw value 1292765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 1293765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // configure GC 1294765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setFont(m_baseFont); 1295765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!isActiveProperty) { 1296765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setForeground(COLOR_PROPERTY_FG_VALUE); 1297765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1298765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // prepare value rectangle 1299765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int x = m_splitter + 4; 1300765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int w = width - x - MARGIN_RIGHT; 1301765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // paint value 1302765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1303765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // BEGIN ADT MODIFICATIONS 1304765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!modified) { 1305765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setForeground(COLOR_PROPERTY_FG_DEFAULT); 1306765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1307765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // END ADT MODIFICATIONS 1308765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1309765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye property.getEditor().paint(property, gc, x, y, w, height); 1310765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1311765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable e) { 1312765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye DesignerPlugin.log(e); 1313765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } finally { 1314765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // restore colors 1315765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setBackground(oldBackground); 1316765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye gc.setForeground(oldForeground); 1317765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1318765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1319765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1320765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1321765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1322765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // PropertyCategory 1323765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1324765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1325765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private PropertyCategoryProvider m_propertyCategoryProvider = 1326765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyCategoryProviders.fromProperty(); 1327765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1328765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1329765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Sets the {@link PropertyCategoryProvider} that can be used to tweak usual 1330765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * {@link PropertyCategory}. 1331765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1332765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void setPropertyCategoryProvider(PropertyCategoryProvider propertyCategoryProvider) { 1333765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_propertyCategoryProvider = propertyCategoryProvider; 1334765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1335765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1336765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1337765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the {@link PropertyCategory} that is used by this {@link PropertyTable} to display. 1338765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1339765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private PropertyCategory getCategory(Property property) { 1340765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return m_propertyCategoryProvider.getCategory(property); 1341765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1342765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1343765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1344765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1345765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // PropertyInfo 1346765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1347765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1348765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1349765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Class with information about single {@link Property}. 1350765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 1351765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @author scheglov_ke 1352765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1353765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private final class PropertyInfo { 1354765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private final String m_id; 1355765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private final int m_level; 1356765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private final Property m_property; 1357765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private final boolean m_stateComplex; 1358765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private boolean m_stateExpanded; 1359765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private List<PropertyInfo> m_children; 1360765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1361765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1362765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1363765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Constructor 1364765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1365765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1366765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public PropertyInfo(Property property) { 1367765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye this(property, "", 0); 1368765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1369765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1370765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private PropertyInfo(Property property, String idPrefix, int level) { 1371765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // BEGIN ADT MODIFICATIONS 1372765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //m_id = idPrefix + "|" + property.getTitle(); 1373765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_id = idPrefix + "|" + property.getName(); 1374765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // END ADT MODIFICATIONS 1375765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_level = level; 1376765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_property = property; 1377765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_stateComplex = property.getEditor() instanceof IComplexPropertyEditor; 1378765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1379765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1380765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1381765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1382765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // State 1383765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1384765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1385765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1386765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return <code>true</code> if this property is complex. 1387765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1388765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public boolean isComplex() { 1389765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return m_stateComplex; 1390765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1391765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1392765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public boolean isShowComplex() throws Exception { 1393765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_stateComplex) { 1394765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye prepareChildren(); 1395765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return m_children != null && !m_children.isEmpty(); 1396765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1397765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return false; 1398765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1399765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1400765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1401765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return <code>true</code> if this complex property is expanded. 1402765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1403765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public boolean isExpanded() { 1404765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return m_stateExpanded; 1405765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1406765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1407765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1408765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1409765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Access 1410765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1411765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1412765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1413765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the level of this property, i.e. on which level of complex property it is located. 1414765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1415765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public int getLevel() { 1416765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return m_level; 1417765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1418765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1419765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1420765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the {@link Property}. 1421765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1422765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public Property getProperty() { 1423765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return m_property; 1424765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1425765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1426765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1427765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Flips collapsed/expanded state and adds/removes sub-properties. 1428765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1429765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void flip() throws Exception { 1430765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Assert.isTrue(m_stateComplex); 1431765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_stateExpanded) { 1432765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye collapse(); 1433765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else { 1434765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye expand(); 1435765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1436765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1437765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1438765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1439765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Expands this property. 1440765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1441765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void expand() throws Exception { 1442765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Assert.isTrue(m_stateComplex); 1443765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Assert.isTrue(!m_stateExpanded); 1444765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1445765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_stateExpanded = true; 1446765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_expandedIds.add(m_id); 1447765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // BEGIN ADT MODIFICATIONS 1448765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_collapsedIds != null) { 1449765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_collapsedIds.remove(m_id); 1450765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1451765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // END ADT MODIFICATIONS 1452765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye prepareChildren(); 1453765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1454765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int index = m_properties.indexOf(this); 1455765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye addChildren(index + 1); 1456765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1457765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1458765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1459765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Collapses this property. 1460765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1461765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void collapse() throws Exception { 1462765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Assert.isTrue(m_stateComplex); 1463765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Assert.isTrue(m_stateExpanded); 1464765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1465765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_stateExpanded = false; 1466765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_expandedIds.remove(m_id); 1467765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // BEGIN ADT MODIFICATIONS 1468765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_collapsedIds != null) { 1469765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_collapsedIds.add(m_id); 1470765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1471765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // END ADT MODIFICATIONS 1472765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye prepareChildren(); 1473765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1474765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye int index = m_properties.indexOf(this); 1475765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye removeChildren(index + 1); 1476765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1477765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1478765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1479765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1480765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Internal 1481765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1482765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1483765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1484765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Adds children properties. 1485765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 1486765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the index for new properties to add. 1487765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1488765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private int addChildren(int index) throws Exception { 1489765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye prepareChildren(); 1490765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (PropertyInfo child : m_children) { 1491765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // skip if should not display raw Property 1492765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!rawProperties_shouldShow(child.m_property)) { 1493765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye continue; 1494765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1495765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // add child 1496765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_properties.add(index++, child); 1497765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // add children of current child 1498765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (child.isExpanded()) { 1499765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye index = child.addChildren(index); 1500765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1501765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1502765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return index; 1503765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1504765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1505765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1506765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Removes children properties. 1507765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1508765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void removeChildren(int index) throws Exception { 1509765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye prepareChildren(); 1510765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (PropertyInfo child : m_children) { 1511765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // skip if should not display raw Property 1512765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!rawProperties_shouldShow(child.m_property)) { 1513765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye continue; 1514765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1515765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // hide presentation 1516765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 1517765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyEditorPresentation presentation = 1518765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye child.getProperty().getEditor().getPresentation(); 1519765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (presentation != null) { 1520765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye presentation.hide(PropertyTable.this, child.getProperty()); 1521765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1522765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1523765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // remove child 1524765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_properties.remove(index); 1525765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // remove children of current child 1526765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (child.isExpanded()) { 1527765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye child.removeChildren(index); 1528765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1529765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1530765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1531765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1532765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1533765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Prepares children {@link PropertyInfo}'s, for sub-properties. 1534765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1535765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void prepareChildren() throws Exception { 1536765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_children == null) { 1537765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_children = Lists.newArrayList(); 1538765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (Property subProperty : getSubProperties()) { 1539765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye PropertyInfo subPropertyInfo = createSubPropertyInfo(subProperty); 1540765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_children.add(subPropertyInfo); 1541765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1542765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1543765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1544765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1545765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private PropertyInfo createSubPropertyInfo(Property subProperty) { 1546765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return new PropertyInfo(subProperty, m_id, m_level + 1); 1547765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1548765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1549765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private Property[] getSubProperties() throws Exception { 1550765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye IComplexPropertyEditor complexEditor = (IComplexPropertyEditor) m_property.getEditor(); 1551765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye List<Property> subProperties = Lists.newArrayList(); 1552765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (Property subProperty : complexEditor.getProperties(m_property)) { 1553765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (getCategory(subProperty).isHidden() && !subProperty.isModified()) { 1554765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // skip hidden properties 1555765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye continue; 1556765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1557765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye subProperties.add(subProperty); 1558765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1559765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return subProperties.toArray(new Property[subProperties.size()]); 1560765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1561765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1562765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1563765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1564765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Persistent expanding support 1565765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 1566765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 1567765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 1568765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return <code>true</code> if this {@link PropertyInfo} was expanded from history. 1569765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 1570765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public boolean expandFromHistory() throws Exception { 1571765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (isComplex() && !isExpanded() && m_expandedIds.contains(m_id)) { 1572765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye expand(); 1573765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return true; 1574765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1575765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // BEGIN ADT MODIFICATIONS 1576765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_collapsedIds != null && isComplex() && !isExpanded() 1577765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye && !m_collapsedIds.contains(m_id)) { 1578765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye expand(); 1579765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return true; 1580765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1581765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // END ADT MODIFICATIONS 1582765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return false; 1583765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1584765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1585765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1586765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // BEGIN ADT MODIFICATIONS 1587765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** Collapse all top-level properties */ 1588765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void collapseAll() { 1589765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 1590765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_lastExpandCollapseTime = System.currentTimeMillis(); 1591765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_collapsedIds != null) { 1592765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_collapsedIds.addAll(m_expandedIds); 1593765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1594765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_expandedIds.clear(); 1595765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye setInput(m_rawProperties); 1596765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye redraw(); 1597765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable e) { 1598765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye DesignerPlugin.log(e); 1599765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1600765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1601765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 1602765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** Expand all top-level properties */ 1603765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void expandAll() { 1604765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 1605765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_lastExpandCollapseTime = System.currentTimeMillis(); 1606765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_collapsedIds != null) { 1607765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_collapsedIds.clear(); 1608765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1609765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_expandedIds.clear(); 1610765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye for (PropertyInfo info : m_properties) { 1611765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (info.m_stateComplex) { 1612765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_expandedIds.add(info.m_id); 1613765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1614765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1615765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye setInput(m_rawProperties); 1616765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye redraw(); 1617765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable e) { 1618765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye DesignerPlugin.log(e); 1619765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1620765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1621765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // END ADT MODIFICATIONS 1622765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye}