aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/SectionHelper.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/SectionHelper.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/SectionHelper.java364
1 files changed, 364 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/SectionHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/SectionHelper.java
new file mode 100644
index 000000000..fdb5d8292
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/SectionHelper.java
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.internal.editors.ui;
+
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
+
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseTrackListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.SectionPart;
+import org.eclipse.ui.forms.widgets.FormText;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.forms.widgets.TableWrapData;
+import org.eclipse.ui.forms.widgets.TableWrapLayout;
+
+import java.lang.reflect.Method;
+
+/**
+ * Helper for the AndroidManifest form editor.
+ *
+ * Helps create a new SectionPart with sensible default parameters,
+ * create default layout or add typical widgets.
+ *
+ * IMPORTANT: This is NOT a generic class. It makes a lot of assumptions on the
+ * UI as used by the form editor for the AndroidManifest.
+ *
+ * TODO: Consider moving to a common package.
+ */
+public final class SectionHelper {
+
+ /**
+ * Utility class that derives from SectionPart, constructs the Section with
+ * sensible defaults (with a title and a description) and provide some shorthand
+ * methods for creating typically UI (label and text, form text.)
+ */
+ static public class ManifestSectionPart extends SectionPart {
+
+ /**
+ * Construct a SectionPart that uses a title bar and a description.
+ * It's up to the caller to call setText() and setDescription().
+ * <p/>
+ * The section style includes a description and a title bar by default.
+ *
+ * @param body The parent (e.g. FormPage body)
+ * @param toolkit Form Toolkit
+ */
+ public ManifestSectionPart(Composite body, FormToolkit toolkit) {
+ this(body, toolkit, 0, false);
+ }
+
+ /**
+ * Construct a SectionPart that uses a title bar and a description.
+ * It's up to the caller to call setText() and setDescription().
+ * <p/>
+ * The section style includes a description and a title bar by default.
+ * You can add extra styles, like Section.TWISTIE.
+ *
+ * @param body The parent (e.g. FormPage body).
+ * @param toolkit Form Toolkit.
+ * @param extra_style Extra styles (on top of description and title bar).
+ * @param use_description True if the Section.DESCRIPTION style should be added.
+ */
+ public ManifestSectionPart(Composite body, FormToolkit toolkit,
+ int extra_style, boolean use_description) {
+ super(body, toolkit, extra_style |
+ Section.TITLE_BAR |
+ (use_description ? Section.DESCRIPTION : 0));
+ }
+
+ // Create non-static methods of helpers just for convenience
+
+ /**
+ * Creates a new composite with a TableWrapLayout set with a given number of columns.
+ *
+ * If the parent composite is a Section, the new composite is set as a client.
+ *
+ * @param toolkit Form Toolkit
+ * @param numColumns Desired number of columns.
+ * @return The new composite.
+ */
+ public Composite createTableLayout(FormToolkit toolkit, int numColumns) {
+ return SectionHelper.createTableLayout(getSection(), toolkit, numColumns);
+ }
+
+ /**
+ * Creates a label widget.
+ * If the parent layout if a TableWrapLayout, maximize it to span over all columns.
+ *
+ * @param parent The parent (e.g. composite from CreateTableLayout())
+ * @param toolkit Form Toolkit
+ * @param label The string for the label.
+ * @param tooltip An optional tooltip for the label and text. Can be null.
+ * @return The new created label
+ */
+ public Label createLabel(Composite parent, FormToolkit toolkit, String label,
+ String tooltip) {
+ return SectionHelper.createLabel(parent, toolkit, label, tooltip);
+ }
+
+ /**
+ * Creates two widgets: a label and a text field.
+ *
+ * This expects the parent composite to have a TableWrapLayout with 2 columns.
+ *
+ * @param parent The parent (e.g. composite from CreateTableLayout())
+ * @param toolkit Form Toolkit
+ * @param label The string for the label.
+ * @param value The initial value of the text field. Can be null.
+ * @param tooltip An optional tooltip for the label and text. Can be null.
+ * @return The new created Text field (the label is not returned)
+ */
+ public Text createLabelAndText(Composite parent, FormToolkit toolkit, String label,
+ String value, String tooltip) {
+ return SectionHelper.createLabelAndText(parent, toolkit, label, value, tooltip);
+ }
+
+ /**
+ * Creates a FormText widget.
+ *
+ * This expects the parent composite to have a TableWrapLayout with 2 columns.
+ *
+ * @param parent The parent (e.g. composite from CreateTableLayout())
+ * @param toolkit Form Toolkit
+ * @param isHtml True if the form text will contain HTML that must be interpreted as
+ * rich text (i.e. parse tags & expand URLs).
+ * @param label The string for the label.
+ * @param setupLayoutData indicates whether the created form text receives a TableWrapData
+ * through the setLayoutData method. In some case, creating it will make the table parent
+ * huge, which we don't want.
+ * @return The new created FormText.
+ */
+ public FormText createFormText(Composite parent, FormToolkit toolkit, boolean isHtml,
+ String label, boolean setupLayoutData) {
+ return SectionHelper.createFormText(parent, toolkit, isHtml, label, setupLayoutData);
+ }
+
+ /**
+ * Forces the section to recompute its layout and redraw.
+ * This is needed after the content of the section has been changed at runtime.
+ */
+ public void layoutChanged() {
+ Section section = getSection();
+
+ // Calls getSection().reflow(), which is the same that Section calls
+ // when the expandable state is changed and the height changes.
+ // Since this is protected, some reflection is needed to invoke it.
+ try {
+ Method reflow;
+ reflow = section.getClass().getDeclaredMethod("reflow", (Class<?>[])null);
+ reflow.setAccessible(true);
+ reflow.invoke(section);
+ } catch (Exception e) {
+ AdtPlugin.log(e, "Error when invoking Section.reflow");
+ }
+
+ section.layout(true /* changed */, true /* all */);
+ }
+ }
+
+ /**
+ * Creates a new composite with a TableWrapLayout set with a given number of columns.
+ *
+ * If the parent composite is a Section, the new composite is set as a client.
+ *
+ * @param composite The parent (e.g. a Section or SectionPart)
+ * @param toolkit Form Toolkit
+ * @param numColumns Desired number of columns.
+ * @return The new composite.
+ */
+ static public Composite createTableLayout(Composite composite, FormToolkit toolkit,
+ int numColumns) {
+ Composite table = toolkit.createComposite(composite);
+ TableWrapLayout layout = new TableWrapLayout();
+ layout.numColumns = numColumns;
+ table.setLayout(layout);
+ toolkit.paintBordersFor(table);
+ if (composite instanceof Section) {
+ ((Section) composite).setClient(table);
+ }
+ return table;
+ }
+
+ /**
+ * Creates a new composite with a GridLayout set with a given number of columns.
+ *
+ * If the parent composite is a Section, the new composite is set as a client.
+ *
+ * @param composite The parent (e.g. a Section or SectionPart)
+ * @param toolkit Form Toolkit
+ * @param numColumns Desired number of columns.
+ * @return The new composite.
+ */
+ static public Composite createGridLayout(Composite composite, FormToolkit toolkit,
+ int numColumns) {
+ Composite grid = toolkit.createComposite(composite);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = numColumns;
+ grid.setLayout(layout);
+ toolkit.paintBordersFor(grid);
+ if (composite instanceof Section) {
+ ((Section) composite).setClient(grid);
+ }
+ return grid;
+ }
+
+ /**
+ * Creates two widgets: a label and a text field.
+ *
+ * This expects the parent composite to have a TableWrapLayout with 2 columns.
+ *
+ * @param parent The parent (e.g. composite from CreateTableLayout())
+ * @param toolkit Form Toolkit
+ * @param label_text The string for the label.
+ * @param value The initial value of the text field. Can be null.
+ * @param tooltip An optional tooltip for the label and text. Can be null.
+ * @return The new created Text field (the label is not returned)
+ */
+ static public Text createLabelAndText(Composite parent, FormToolkit toolkit, String label_text,
+ String value, String tooltip) {
+ Label label = toolkit.createLabel(parent, label_text);
+ label.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE));
+ Text text = toolkit.createText(parent, value);
+ text.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE));
+
+ addControlTooltip(label, tooltip);
+ return text;
+ }
+
+ /**
+ * Creates a label widget.
+ * If the parent layout if a TableWrapLayout, maximize it to span over all columns.
+ *
+ * @param parent The parent (e.g. composite from CreateTableLayout())
+ * @param toolkit Form Toolkit
+ * @param label_text The string for the label.
+ * @param tooltip An optional tooltip for the label and text. Can be null.
+ * @return The new created label
+ */
+ static public Label createLabel(Composite parent, FormToolkit toolkit, String label_text,
+ String tooltip) {
+ Label label = toolkit.createLabel(parent, label_text);
+
+ TableWrapData twd = new TableWrapData(TableWrapData.FILL_GRAB);
+ if (parent.getLayout() instanceof TableWrapLayout) {
+ twd.colspan = ((TableWrapLayout) parent.getLayout()).numColumns;
+ }
+ label.setLayoutData(twd);
+
+ addControlTooltip(label, tooltip);
+ return label;
+ }
+
+ /**
+ * Associates a tooltip with a control.
+ *
+ * This mirrors the behavior from org.eclipse.pde.internal.ui.editor.text.PDETextHover
+ *
+ * @param control The control to which associate the tooltip.
+ * @param tooltip The tooltip string. Can use \n for multi-lines. Will not display if null.
+ */
+ static public void addControlTooltip(final Control control, String tooltip) {
+ if (control == null || tooltip == null || tooltip.length() == 0) {
+ return;
+ }
+
+ // Some kinds of controls already properly implement tooltip display.
+ if (control instanceof Button) {
+ control.setToolTipText(tooltip);
+ return;
+ }
+
+ control.setToolTipText(null);
+
+ final DefaultInformationControl ic = new DefaultInformationControl(control.getShell());
+ ic.setInformation(tooltip);
+ Point sz = ic.computeSizeHint();
+ ic.setSize(sz.x, sz.y);
+ ic.setVisible(false); // initially hidden
+
+ control.addMouseTrackListener(new MouseTrackListener() {
+ @Override
+ public void mouseEnter(MouseEvent e) {
+ }
+
+ @Override
+ public void mouseExit(MouseEvent e) {
+ ic.setVisible(false);
+ }
+
+ @Override
+ public void mouseHover(MouseEvent e) {
+ ic.setLocation(control.toDisplay(10, 25)); // same offset as in PDETextHover
+ ic.setVisible(true);
+ }
+ });
+ control.addDisposeListener(new DisposeListener() {
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ ic.dispose();
+ }
+ });
+ }
+
+ /**
+ * Creates a FormText widget.
+ *
+ * This expects the parent composite to have a TableWrapLayout with 2 columns.
+ *
+ * @param parent The parent (e.g. composite from CreateTableLayout())
+ * @param toolkit Form Toolkit
+ * @param isHtml True if the form text will contain HTML that must be interpreted as
+ * rich text (i.e. parse tags & expand URLs).
+ * @param label The string for the label.
+ * @param setupLayoutData indicates whether the created form text receives a TableWrapData
+ * through the setLayoutData method. In some case, creating it will make the table parent
+ * huge, which we don't want.
+ * @return The new created FormText.
+ */
+ static public FormText createFormText(Composite parent, FormToolkit toolkit,
+ boolean isHtml, String label, boolean setupLayoutData) {
+ FormText text = toolkit.createFormText(parent, true /* track focus */);
+ if (setupLayoutData) {
+ TableWrapData twd = new TableWrapData(TableWrapData.FILL_GRAB);
+ twd.maxWidth = AndroidXmlEditor.TEXT_WIDTH_HINT;
+ if (parent.getLayout() instanceof TableWrapLayout) {
+ twd.colspan = ((TableWrapLayout) parent.getLayout()).numColumns;
+ }
+ text.setLayoutData(twd);
+ }
+ text.setWhitespaceNormalized(true);
+ if (isHtml && !label.startsWith("<form>")) { //$NON-NLS-1$
+ // This assertion is violated, for example by the Class attribute for an activity
+ //assert label.startsWith("<form>") : "HTML for FormText must be wrapped in <form>...</form>"; //$NON-NLS-1$
+ label = "<form>" + label + "</form>"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ text.setText(label, isHtml /* parseTags */, isHtml /* expandURLs */);
+ return text;
+ }
+}