Author: yradtsevich
Date: 2009-03-19 09:36:13 -0400 (Thu, 19 Mar 2009)
New Revision: 14263
Modified:
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/CSSClassDialog.java
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/common/CSSModel.java
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/common/CSSValidator.java
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/events/StyleAttributes.java
Log:
RESOLVED - issue JBIDE-3910: Need extended validator for CSS class name
https://jira.jboss.org/jira/browse/JBIDE-3910
- validator has been added.
- now css dialog does not format CSS before save
Modified:
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/CSSClassDialog.java
===================================================================
---
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/CSSClassDialog.java 2009-03-19
09:19:53 UTC (rev 14262)
+++
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/CSSClassDialog.java 2009-03-19
13:36:13 UTC (rev 14263)
@@ -1,878 +1,879 @@
-/*******************************************************************************
- * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc.
- * Distributed under license by Red Hat, Inc. All rights reserved.
- * This program is made available under the terms of the
- * Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at
http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Exadel, Inc. and Red Hat, Inc. - initial API and implementation
- ******************************************************************************/
-package org.jboss.tools.jst.jsp.outline.cssdialog;
-
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.IInputValidator;
-import org.eclipse.jface.dialogs.InputDialog;
-import org.eclipse.jface.dialogs.TitleAreaDialog;
-import org.eclipse.jface.fieldassist.SimpleContentProposalProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.window.Window;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.events.FocusAdapter;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-import org.jboss.tools.common.model.ui.widgets.Split;
-import org.jboss.tools.jst.jsp.messages.JstUIMessages;
-import org.jboss.tools.jst.jsp.outline.cssdialog.common.CSSModel;
-import org.jboss.tools.jst.jsp.outline.cssdialog.common.CSSValidator;
-import org.jboss.tools.jst.jsp.outline.cssdialog.common.Constants;
-import org.jboss.tools.jst.jsp.outline.cssdialog.common.Util;
-import org.jboss.tools.jst.jsp.outline.cssdialog.events.ChangeStyleEvent;
-import org.jboss.tools.jst.jsp.outline.cssdialog.events.ChangeStyleListener;
-import org.jboss.tools.jst.jsp.outline.cssdialog.events.ManualChangeStyleListener;
-import org.jboss.tools.jst.jsp.outline.cssdialog.events.MessageDialogEvent;
-import org.jboss.tools.jst.jsp.outline.cssdialog.events.MessageDialogListener;
-import org.jboss.tools.jst.jsp.outline.cssdialog.events.StyleAttributes;
-
-/**
- * This dialog represents CSSClass dialog.
- *
- * @author Igor Zhukov (izhukov(a)exadel.com)
- */
-public class CSSClassDialog extends TitleAreaDialog implements ChangeStyleListener {
-
- public static final String ID =
"org.jboss.tools.jst.jsp.outline.cssdialog.CSSClassDialog"; //$NON-NLS-1$
-
- private static String notUsed = "not_used"; //$NON-NLS-1$
-// private final static String[] fileExtensions = { Util.CSS_FILE_EXTENTION };
-
- private Composite browserContainer = null;
- private Browser browser = null;
- private Text textBrowser = null;
- private String previewBrowserValue = JstUIMessages.DEFAULT_TEXT_FOR_BROWSER_PREVIEW;
-
- private StyleComposite styleComposite = null;
- private StyleAttributes styleAttributes = null;
- // css file path
- private Text text;
- // css style classes
- private Combo classCombo;
- // combo box content assist
-// private ContentAssistCommandAdapter contentAssistAdapter = null;
- // apply button
- private Button applyButton;
-
- // model is the core of the CSS Class Dialog, it manages style attributes
- private CSSModel cssModel;
-
- // file is "current" in case of the following priority order:
- // 1 - this is selected css file in eclipse project tree
- // 2 - this is opened and active css file
- private IFile currentFile;
- private String currentClassStyle = null;
-
- // workbench selection when the wizard was started
- protected IStructuredSelection selection;
-
- private boolean styleChanged = false;
-
-// private boolean keyInputSelector = false;
-
- // Status variables for the possible errors on this page.
- // 1. timeStatus holds an error if CSS file is not specified
- private IStatus filePathStatus = null;
- // 2. holds an error if the destination class style is empty
- private IStatus classNameStatus = null;
- // 3. holds an error if inccorrect property was specified
- private IStatus cssValueStatus =null;
-
- // an array of subscribed message dialog listener
- private ArrayList<MessageDialogListener> errorListeners = new
ArrayList<MessageDialogListener>();
-
- // parameter indicates if dialog was opened from Wizard
- private final boolean callFromWizard;
-
- private Button addNewClass;
-
-
- /**
- * Constructor.
- *
- * @param parentShell Shell object
- * @param allProject (if allProject is true - browse css file in all projects, else
only in current project)
- * @param callFromWizard indicates if CSS dialog is created within Wizard page
- */
- public CSSClassDialog(Shell parentShell, IStructuredSelection selection, boolean
callFromWizard) {
- super(parentShell);
-
- setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX | SWT.APPLICATION_MODAL);
-
- filePathStatus = new Status(IStatus.ERROR, notUsed, 0,
JstUIMessages.CSS_EMPTY_FILE_PATH_MESSAGE, null);
- classNameStatus = new Status(IStatus.ERROR, notUsed, 0,
JstUIMessages.CSS_EMPTY_STYLE_CLASS_MESSAGE, null);
-
- styleAttributes = new StyleAttributes();
- styleAttributes.addChangeStyleListener(this);
- this.callFromWizard = callFromWizard;
- this.selection = selection;
- init();
- }
-
- /**
- * Initialize method.
- */
- private void init() {
- if (selection != null && !selection.isEmpty()) {
- for (Iterator<?> iterator = selection.iterator(); iterator.hasNext();) {
- Object element = iterator.next();
- if (element instanceof IResource) {
- if (element instanceof IFile) {
- if (((IFile) element).getName().toLowerCase().endsWith(Util.CSS_FILE_EXTENTION)) {
- currentFile = (IFile)element;
- }
- }
- }
- }
- }
- // if any CSS file is currently opened and has active page status this method should
return style class
- // within this file where cursor is located
- if (currentFile == null) {
- currentFile = Util.getActiveCssFile();
- }
- }
-
- /**
- * Sets current style class value.
- *
- * @param currentClassStyle String value
- */
- public void setCurrentStyleClass(String currentClassStyle) {
- this.currentClassStyle = Util.formatStyleClassToCSSView(currentClassStyle);
- }
-
- /**
- * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(Composite)
- */
- @Override
- protected Control createDialogArea(final Composite parent) {
- final Composite composite = (Composite) super.createDialogArea(parent);
- if(composite.getLayoutData()!=null && composite.getLayoutData()
instanceof GridData) {
- ((GridData)composite.getLayoutData()).widthHint=500;
- ((GridData)composite.getLayoutData()).heightHint=500;
- }
- final Control control = createDialogComposite(composite);
- return control;
- }
-
- public Control createDialog(final Composite parent) {
- return createDialogArea(parent);
- }
-
- /**
- * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(Composite)
- */
- @Override
- protected void createButtonsForButtonBar(Composite parent) {
- super.createButtonsForButtonBar(parent);
- updateOKButtonState();
-
- }
- private Split split;
- /**
- * Create the dialog itself.
- *
- * @param composite parent window
- * @return eclipse Control object
- */
- private Control createDialogComposite(Composite composite) {
- if (!this.callFromWizard) {
- setTitle(JstUIMessages.CSS_STYLE_CLASS_EDITOR_TITLE);
- setMessage(JstUIMessages.CSS_STYLE_CLASS_EDITOR_DESCRIPTION);
- }
- composite.setLayout(new GridLayout());
-
- //
===============================================================================
- // Create split component that separates dialog on 2 parts
- //
===============================================================================
- split = new Split(composite, SWT.VERTICAL);
-
- //
===============================================================================
- // Create browser container
- //
===============================================================================
- browserContainer = getCompositeElement(split);
- // create browser component
- createBrowserComponent();
-
- //
===============================================================================
- // Create down splitter container
- //
===============================================================================
- Composite downSplitPane = getCompositeElement(split);
-
- Composite classComposite = new Composite(downSplitPane, SWT.BORDER);
- classComposite.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING,
true, false));
- classComposite.setLayout(new GridLayout(3, false));
-
- //
===============================================================================
- // Create component that contains CSS file pass and it's selectors (style
classes combo box)
- //
===============================================================================
- createCSSFilePathComponent(classComposite);
- createStyleClassCombo(classComposite);
-
- //
===============================================================================
- // Create style composite component
- //
===============================================================================
- styleComposite = new StyleComposite(downSplitPane, styleAttributes,
Constants.EMPTY);
- styleComposite.addManualChangeStyleListener(new ManualChangeStyleListener() {
- public void styleChanged(ChangeStyleEvent event) {
- styleChanged = true;
- if (currentClassStyle != null &&
!currentClassStyle.equals(Constants.EMPTY)
- && currentFile != null &&
!currentFile.equals(Constants.EMPTY)) {
- updateApplyButton(true);
- }
- }
- });
-
- //
===============================================================================
- // Create custom button panel
- //
===============================================================================
- createCustomButtonPanel(downSplitPane);
-
- styleAttributes.addChangeStyleListener(new ChangeStyleListener() {
- public void styleChanged(ChangeStyleEvent event) {
- if (!browser.isDisposed()) {
- browser.setText(getTextForBrowser());
- }
- }
- });
-
- if (currentFile != null) {
- initCSSModel(currentFile, true, true);
- } else if (currentClassStyle != null) {
- classCombo.setText(currentClassStyle);
- styleAttributes.setCssSelector(currentClassStyle);
- }
-
- // add content assist to style COMBO component
- SimpleContentProposalProvider proposalProvider = new
SimpleContentProposalProvider(classCombo.getItems());
- proposalProvider.setFiltering(true);
-
- split.setWeights(new int[]{15, 85});
- split.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true,
true));
-
- return composite;
- }
-
- private void createCSSFilePathComponent(Composite parent) {
- Label label = new Label(parent, SWT.LEFT);
- label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false));
- label.setText(JstUIMessages.CSS_CLASS_DIALOG_FILE_LABEL);
-
- // Text field contains path to the CSS file
- text = new Text(parent, SWT.BORDER|SWT.READ_ONLY);
- GridData gridData =new GridData(GridData.FILL, GridData.CENTER, true, false);
- gridData.grabExcessHorizontalSpace=true;
- gridData.horizontalSpan=2;
- text.setLayoutData(gridData);
-// text.setEditable(false);
- text.addModifyListener(new ModifyListener() {
- public void modifyText(ModifyEvent e) {
- String cssFile = text.getText().trim();
- // Initialize a variable with the no error status
- filePathStatus = new Status(IStatus.ERROR, notUsed, 0,
JstUIMessages.CSS_EMPTY_FILE_PATH_MESSAGE, null);
- if (cssFile != null && !cssFile.equals(Constants.EMPTY)) {
- filePathStatus = new Status(IStatus.OK, notUsed, 0,
JstUIMessages.CSS_STYLE_CLASS_EDITOR_DESCRIPTION, null);
- }
- // show corresponding message
- IStatus status = findMostSevere();
- notifyListeners(text, status);
- applyToStatusLine(status);
- }
- });
- }
-
- /**
- * This method is used to create and initialize style class comboBox component.
- *
- * @param parent Composite component
- */
- private void createStyleClassCombo(final Composite parent) {
- Label label = new Label(parent, SWT.LEFT);
- label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false));
- label.setText(JstUIMessages.CSS_CLASS_DIALOG_STYLE_CLASS_LABEL);
-
- GridData gridData = new GridData(GridData.FILL, GridData.CENTER, true, false);
- gridData.horizontalSpan = 1;
-
- classCombo = new Combo(parent, SWT.BORDER|SWT.READ_ONLY);
- classCombo.setLayoutData(gridData);
- // this listener is responsible for processing dialog header message events
- classCombo.addModifyListener(new ModifyListener() {
- public void modifyText(ModifyEvent e) {
- String cssClass = classCombo.getText().trim();
- // Initialize a variable with the no error status
- classNameStatus = new Status(IStatus.ERROR, notUsed, 0,
JstUIMessages.CSS_EMPTY_STYLE_CLASS_MESSAGE, null);
- if (cssClass != null && !cssClass.equals(Constants.EMPTY)) {
- classNameStatus = new Status(IStatus.OK, notUsed, 0,
JstUIMessages.CSS_STYLE_CLASS_EDITOR_DESCRIPTION, null);
- }
- // show corresponding message
- IStatus status = findMostSevere();
- notifyListeners(classCombo, status);
- applyToStatusLine(status);
- // update CSS style cmposite if needed
- if ((currentClassStyle != null &&
currentClassStyle.equals(classCombo.getText().trim()))
- || (currentClassStyle == null &&
classCombo.getText().trim().equals(Constants.EMPTY))) {
- return;
- }
- cssStyleClassChanged();
- updateApplyButton(false);
- }
- });
- //creates a button for add new class
- addNewClass = new Button(parent, SWT.PUSH);
- addNewClass.setText(JstUIMessages.BUTTON_ADD_NEW_STYLE_CLASS);
- addNewClass.addSelectionListener(new SelectionAdapter() {
- public void widgetSelected(SelectionEvent event) {
- InputDialog dlg = new InputDialog(parent.getShell(),
- JstUIMessages.ENTER_CSS_CLASS_NAME,
JstUIMessages.ENTER_CSS_CLASS_NAME, classCombo.getText(),
- new IInputValidator(){
- /**
- * Simple validation of new CSS Class Name, now we just check that
it's not empty string
- */
- public String isValid(String newText) {
- if(newText==null || newText.trim().length()==0){
- return JstUIMessages.CSS_CLASS_NAME_NOT_VALID;
- }
- return null;
- }
-
- });
- if (dlg.open() == Window.OK) {
- addNewStyleClass(dlg.getValue().trim());
- }
- }
- });
- }
- /**
- * Add New Class to CSS Class Dialog
- * @param styleClassName - name of new style class
- */
- public void addNewStyleClass(String styleClassName) {
- updateApplyButton(true);
- styleChanged = true;
- currentClassStyle = styleClassName;
- updateStyleComposite();
- styleAttributes.setCssSelector(currentClassStyle);
- styleComposite.updatePreview(currentClassStyle);
- updateOKButtonState();
- // add new class to end of list
- if (classCombo.indexOf(currentClassStyle) == -1)
- classCombo.add(currentClassStyle);
- // end select it
- classCombo.select(classCombo.getItemCount() - 1);
- cssModel.setCSS(currentClassStyle, styleAttributes);
- }
-// /**
-// * This method is invoked to correctly process class style combo modify event.
-// */
-// private void notifyStyleClassChanged() {
-// Display display = null;
-// if (PlatformUI.isWorkbenchRunning()) {
-// display = PlatformUI.getWorkbench().getDisplay();
-// }
-// if (display != null && (Thread.currentThread() == display.getThread())) {
-// if (uiJob == null) {
-// uiJob = new UIJob(jobName) {
-// @Override
-// public IStatus runInUIThread(IProgressMonitor monitor) {
-// if (monitor.isCanceled()) {
-// return Status.CANCEL_STATUS;
-// }
-// monitor.beginTask(jobName, IProgressMonitor.UNKNOWN);
-//
-// // start operation
-// cssStyleClassChanged();
-// // end operation
-//
-// monitor.done();
-//
-// return Status.OK_STATUS;
-// }
-// };
-// }
-//
-// uiJob.setPriority(Job.SHORT);
-// uiJob.schedule(delay);
-//
-// return;
-// }
-// }
-
- /**
- * This method is used to create custom button panel.
- *
- * @param parent Composite component
- */
- private void createCustomButtonPanel(Composite parent) {
- Composite buttonComposite = new Composite(parent, SWT.NONE);
- buttonComposite.setLayoutData(new GridData(GridData.END, GridData.BEGINNING,
true, false));
- buttonComposite.setLayout(new GridLayout());
- // add APPLY button
- applyButton = createCustomButton(buttonComposite, JstUIMessages.BUTTON_APPLY);
- updateApplyButton(false);
- applyButton.setToolTipText(JstUIMessages.CSS_APPLY_CHANGES);
- applyButton.addSelectionListener(new SelectionAdapter() {
- public void widgetSelected(SelectionEvent event) {
- if (currentClassStyle != null &&
!currentClassStyle.equals(Constants.EMPTY)) {
- // update ComboBox element list
- if (classCombo.indexOf(currentClassStyle) == -1) {
- classCombo.add(currentClassStyle);
- }
- saveChanges(false);
- updateApplyButton(false);
- styleChanged = false;
- }
- }
- });
- // add CLEAR button
- Button clearButton = createCustomButton(buttonComposite,
JstUIMessages.BUTTON_CLEAR);
- clearButton.setToolTipText(JstUIMessages.CSS_CLEAR_STYLE_SHEET);
- clearButton.addSelectionListener(new SelectionAdapter() {
- public void widgetSelected(SelectionEvent event) {
- styleComposite.clearStyleComposite(currentClassStyle);
- styleComposite.updatePreview(currentClassStyle);
- styleComposite.updateStyle();
- updateApplyButton(true);
- styleChanged = true;
- }
- });
- }
-
- /**
- * This method is used to create custom button.
- *
- * @param parent Composite component
- * @param label Button label value
- */
- protected Button createCustomButton(Composite parent, String label) {
- // increment the number of columns in the button bar
- ((GridLayout) parent.getLayout()).numColumns++;
- Button button = new Button(parent, SWT.PUSH);
- button.setText(label);
-// setButtonLayoutData(button);
- return button;
- }
-
- /**
- * Method is used to correctly process style class change operation.
- */
- private void cssStyleClassChanged() {
- if (currentFile != null && !currentFile.equals(Constants.EMPTY)) {
-// if (styleChanged && currentClassStyle != null &&
!currentClassStyle.equals(Constants.EMPTY)) {
-// MessageBox messageBox = new MessageBox(getParentShell(), SWT.YES | SWT.NO |
SWT.ICON_QUESTION);
-// messageBox.setText(JstUIMessages.CSS_SAVE_DIALOG_TITLE);
-// messageBox.setMessage(CSSClassDialog.getMessageForSaveDialog(currentFile));
-// int result = messageBox.open();
-// if (result == SWT.YES) {
-// // update ComboBox element list
-// if (classCombo.indexOf(currentClassStyle) == -1) {
-// classCombo.add(currentClassStyle);
-// }
- cssModel.setCSS(currentClassStyle, styleAttributes);
-// // update content assist proposals
-// SimpleContentProposalProvider proposalProvider =
-//
(SimpleContentProposalProvider)contentAssistAdapter.getContentProposalProvider();
-// proposalProvider.setProposals(classCombo.getItems());
-// } else {
-// // FOR
https://jira.jboss.org/jira/browse/JBIDE-3542
-// // cssModel.init(currentFile);
-// // styleComposite.revertPreview();
-// }
-// }
- // update current class style value
- currentClassStyle = classCombo.getText().trim();
-
- // if new css was added
-// if (classCombo.indexOf(currentClassStyle) == -1) {
-// classCombo.add(currentClassStyle);
-// styleChanged = true;
-// } else {
-// styleChanged = false;
-// }
- updateApplyButton(true);
- styleChanged = true;
-
- updateStyleComposite();
- styleAttributes.setCssSelector(currentClassStyle);
- styleComposite.updatePreview(currentClassStyle);
- updateOKButtonState();
- } else {
- currentClassStyle = classCombo.getText().trim();
- styleAttributes.setCssSelector(currentClassStyle);
- styleChanged = false;
- }
-
- }
-
- /**
- * Initialize CSS model with active opened CSS file.
- *
- * @param file IFile object
- * @param useRelativePathPath
- */
- private void initCSSModel(IFile file, boolean useRelativePathPath, boolean
updateCSSModel) {
- if (file != null) {
- // create CSS Model
- cssModel = new CSSModel(file);
- currentClassStyle = null;
- classCombo.removeAll();
- classCombo.setEnabled(true);
- // set file path to corresponding text field
- if (useRelativePathPath) {
- text.setText(file.getProjectRelativePath().toOSString());
- } else {
- text.setText(file.getFullPath().toOSString());
- }
-
- Point selectionInFile = Util.getSelectionInFile(file);
-
- currentClassStyle = cssModel.getSelectorByPosition(selectionInFile);
-
- // fill in ComboBox component with CSS model selectors
-// List<Selector> selectors = cssModel.getSelectors();
- List<String> selectors = cssModel.getSelectorLabels();
- for (int i = 0; i < selectors.size(); i++) {
-// Selector value = selectors.get(i);
- String label = selectors.get(i);
- classCombo.add(/*value.getValue()*/ label);
-
- }
- /*
- *
- */
- if (currentClassStyle != null) {
- classCombo.setText(currentClassStyle);
- } else {
- classCombo.select(0);
- }
- classCombo.setToolTipText(cssModel.getCSSText(currentClassStyle));
-
- styleComposite.setShowPreviewTab(true);
- styleComposite.setCSSModel(cssModel);
- // update style composite component with the values from new CSS file
- if (updateCSSModel) {
- updateStyleComposite();
- }
- styleComposite.initPreview(cssModel);
- }
- }
-
- /**
- * This method takes affect to OK button when dialog is opened in "dialog"
mode and not in "wizard".
- * In case of "wizard" mode OK button is not available.
- */
- private void updateOKButtonState() {
- Button okButton = getButton(IDialogConstants.OK_ID);
- if (okButton != null) {
- if (findMostSevere()!=null&&findMostSevere().getSeverity()==IStatus.ERROR)
{
- okButton.setEnabled(false);
- } else {
- okButton.setEnabled(true);
- }
- }
- }
-
- /**
- * Method is used to create browser component to display preview HTML.
- */
- private void createBrowserComponent() {
- GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, true);
- browser = new Browser(browserContainer, SWT.BORDER | SWT.MOZILLA);
- browser.setText(getTextForBrowser());
- browser.addMouseListener(new MouseAdapter() {
- public void mouseDoubleClick(MouseEvent e) {
- if (e.widget == browser) {
- browser.removeMouseListener(this);
- browser.dispose();
- // create Text area component instead of HTML Browser
- GridData gridData = new GridData(GridData.FILL, GridData.FILL, true,
true);
-// textBrowser = new Text(browserContainer, SWT.MULTI | SWT.V_SCROLL |
SWT.H_SCROLL);
- textBrowser = new Text(browserContainer, SWT.NONE | SWT.H_SCROLL);
- textBrowser.setText(previewBrowserValue);
- textBrowser.addFocusListener(new FocusAdapter() {
- public void focusLost(FocusEvent e) {
- if (e.widget == textBrowser) {
- String text = textBrowser.getText();
- if (text == null || text.equals(Constants.EMPTY)) {
- previewBrowserValue =
JstUIMessages.DEFAULT_TEXT_FOR_BROWSER_PREVIEW;
- } else {
- previewBrowserValue = text;
- }
- textBrowser.dispose();
- // create Browse component instead of text area
- createBrowserComponent();
- }
- browserContainer.layout();
- }
- });
- textBrowser.setLayoutData(gridData);
- textBrowser.setEditable(true);
- textBrowser.setFocus();
- }
- browserContainer.layout();
- }
- });
- browser.setLayoutData(gridData);
- }
-
- /**
- * Update style composite component in accordance with the attributes of selected CSS
selector.
- */
- private void updateStyleComposite() {
- String style = cssModel.getStyle(currentClassStyle);
- styleComposite.recreateStyleComposite(style, currentClassStyle);
- }
-
- /**
- * Method is used to build html body that is appropriate to browse.
- *
- * @return String html text representation
- */
- private String getTextForBrowser() {
- String styleForSpan = Constants.EMPTY;
- Set<String> keySet = styleAttributes.keySet();
- for (String key : keySet) {
- styleForSpan += (key + Constants.COLON + styleAttributes.getAttribute(key) +
Constants.SEMICOLON);
- }
- String html = Constants.OPEN_DIV_TAG + styleForSpan + "\">" +
previewBrowserValue + Constants.CLOSE_DIV_TAG; //$NON-NLS-1$
-
- return html;
- }
-
- /**
- * Create container that take up 2 cells and contains fontSizeCombo and
extFontSizeCombo elements.
- */
- private Composite getCompositeElement(Composite parent) {
- GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, true);
- GridLayout gridLayoutTmp = new GridLayout();
- gridLayoutTmp.marginHeight = 0;
- gridLayoutTmp.marginWidth = 0;
- Composite classComposite = new Composite(parent, SWT.FILL);
- classComposite.setLayout(gridLayoutTmp);
- classComposite.setLayoutData(gridData);
-
- return classComposite;
- }
-
- public void releaseResources() {
-
- if (cssModel != null){
- cssModel.releaseModel();
- cssModel = null;
- }
- }
-
- /**
- * Method should be called in case of dialog closure operation.
- */
- public void saveChanges(boolean close) {
- styleComposite.updateStyle();
- cssModel.setCSS(currentClassStyle, styleAttributes);
- cssModel.saveModel();
- }
-
- /**
- * Gets current selected style class value.
- *
- * @return selector name
- */
- public String getSelectorName() {
- return Util.formatCSSSelectorToStyleClassView(currentClassStyle);
- }
-
- /**
- * Method for setting title for dialog
- *
- * @param newShell Shell object
- * @see org.eclipse.jface.window.Window#configureShell(Shell)
- */
- @Override
- protected void configureShell(Shell newShell) {
- super.configureShell(newShell);
- newShell.setText(JstUIMessages.CSS_STYLE_CLASS_EDITOR_TITLE);
- }
-
- /**
- * This method close the dialog.
- *
- * @return true if dialog was closed, false - otherwise
- */
- public boolean closeDialog() {
- setReturnCode(Window.CANCEL);
- return close();
- }
-
- /**
- * @see org.eclipse.jface.dialogs.Dialog#close()
- */
- @Override
- public boolean close() {
- int code = getReturnCode();
- switch (code) {
- case OK:
- if (styleChanged || classCombo.indexOf(currentClassStyle) == -1) {
- saveChanges(true);
- }
- break;
- case CANCEL:
- default:
- // make some closure operation
- }
- releaseResources();
- return super.close();
- }
-
- /**
- * Add MessageDialogListener object.
- *
- * @param listener MessageDialogListener object to be added
- */
- public void addMessageDialogListener(MessageDialogListener listener) {
- errorListeners.add(listener);
- }
-
- /**
- * Method is used to notify all subscribed listeners about possible any errors on the
page.
- */
- private void notifyListeners(Object source, IStatus operationStatus) {
- MessageDialogEvent event = new MessageDialogEvent(source, operationStatus);
- for (MessageDialogListener listener : errorListeners) {
- listener.throwMessage(event);
- }
- }
-
- /**
- * Method return the most serious error occurs on the page and that should be
displayed.
- *
- * @return IStatus object
- */
- private IStatus findMostSevere() {
- if (filePathStatus.matches(IStatus.ERROR)) {
- return filePathStatus;
- }
- if (classNameStatus.matches(IStatus.ERROR)) {
- return classNameStatus;
- }
- if(cssValueStatus!=null && cssValueStatus.matches(IStatus.ERROR)){
- return cssValueStatus;
- }
- if(cssValueStatus!=null && cssValueStatus.matches(IStatus.ERROR)){
- return cssValueStatus;
- } else {
- return classNameStatus;
- }
-
- }
-
- /**
- * Applies the status to the status line of a dialog page.
- */
- private void applyToStatusLine(IStatus status) {
- if (!callFromWizard) {
- String message= status.getMessage();
- if (message.length() == 0) {
- message = null;
- }
- switch (status.getSeverity()) {
- case IStatus.OK:
- setErrorMessage(null);
- setMessage(message);
- break;
- case IStatus.WARNING:
- setErrorMessage(null);
- setMessage(message, WizardPage.WARNING);
- break;
- case IStatus.INFO:
- setErrorMessage(null);
- setMessage(message, WizardPage.INFORMATION);
- break;
- default:
- setErrorMessage(message);
- setMessage(null);
- break;
- }
- }
- }
-
- public void reinit(){
- releaseResources();
- initCSSModel(currentFile, true,true);
- }
-
- public void setCurrentFile(IFile currentFile) {
- this.currentFile = currentFile;
- }
-
- /* (non-Javadoc)
- * @see
org.jboss.tools.jst.jsp.outline.cssdialog.events.ChangeStyleListener#styleChanged(org.jboss.tools.jst.jsp.outline.cssdialog.events.ChangeStyleEvent)
- */
- public void styleChanged(ChangeStyleEvent event) {
- if (!this.styleAttributes.isValid()) {
- cssValueStatus = new Status(IStatus.ERROR, notUsed, 0,
- JstUIMessages.CSS_INVALID_STYLE_PROPERTY, null);
- notifyListeners(event, cssValueStatus);
- addNewClass.setEnabled(false);
- } else {
- cssValueStatus = null;
- addNewClass.setEnabled(true);
- notifyListeners(event, new Status(IStatus.OK, notUsed, 0,
- JstUIMessages.CSS_STYLE_CLASS_EDITOR_DESCRIPTION, null));
- }
- if (cssValueStatus != null && classCombo != null) {
- classCombo.setEnabled(false);
- } else {
- classCombo.setEnabled(true);
-
- }
- updateApplyButton(true);
- updateOKButtonState();
- applyToStatusLine(findMostSevere());
- }
- /**
- * Update upplyButtonState
- * @param available
- */
- private void updateApplyButton(boolean enabled){
- if(cssValueStatus!=null
- &&cssValueStatus.matches(IStatus.ERROR)) {
- applyButton.setEnabled(false);
- }else {
- applyButton.setEnabled(enabled);
- }
-
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc.
+ * Distributed under license by Red Hat, Inc. All rights reserved.
+ * This program is made available under the terms of the
+ * Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at
http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Exadel, Inc. and Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.jst.jsp.outline.cssdialog;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.fieldassist.SimpleContentProposalProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.jboss.tools.common.model.ui.widgets.Split;
+import org.jboss.tools.jst.jsp.messages.JstUIMessages;
+import org.jboss.tools.jst.jsp.outline.cssdialog.common.CSSModel;
+import org.jboss.tools.jst.jsp.outline.cssdialog.common.CSSValidator;
+import org.jboss.tools.jst.jsp.outline.cssdialog.common.Constants;
+import org.jboss.tools.jst.jsp.outline.cssdialog.common.Util;
+import org.jboss.tools.jst.jsp.outline.cssdialog.events.ChangeStyleEvent;
+import org.jboss.tools.jst.jsp.outline.cssdialog.events.ChangeStyleListener;
+import org.jboss.tools.jst.jsp.outline.cssdialog.events.ManualChangeStyleListener;
+import org.jboss.tools.jst.jsp.outline.cssdialog.events.MessageDialogEvent;
+import org.jboss.tools.jst.jsp.outline.cssdialog.events.MessageDialogListener;
+import org.jboss.tools.jst.jsp.outline.cssdialog.events.StyleAttributes;
+
+/**
+ * This dialog represents CSSClass dialog.
+ *
+ * @author Igor Zhukov (izhukov(a)exadel.com)
+ */
+public class CSSClassDialog extends TitleAreaDialog implements ChangeStyleListener {
+
+ public static final String ID =
"org.jboss.tools.jst.jsp.outline.cssdialog.CSSClassDialog"; //$NON-NLS-1$
+
+ private static String notUsed = "not_used"; //$NON-NLS-1$
+// private final static String[] fileExtensions = { Util.CSS_FILE_EXTENTION };
+
+ private Composite browserContainer = null;
+ private Browser browser = null;
+ private Text textBrowser = null;
+ private String previewBrowserValue = JstUIMessages.DEFAULT_TEXT_FOR_BROWSER_PREVIEW;
+
+ private StyleComposite styleComposite = null;
+ private StyleAttributes styleAttributes = null;
+ // css file path
+ private Text text;
+ // css style classes
+ private Combo classCombo;
+ // combo box content assist
+// private ContentAssistCommandAdapter contentAssistAdapter = null;
+ // apply button
+ private Button applyButton;
+
+ // model is the core of the CSS Class Dialog, it manages style attributes
+ private CSSModel cssModel;
+
+ // file is "current" in case of the following priority order:
+ // 1 - this is selected css file in eclipse project tree
+ // 2 - this is opened and active css file
+ private IFile currentFile;
+ private String currentClassStyle = null;
+
+ // workbench selection when the wizard was started
+ protected IStructuredSelection selection;
+
+ private boolean styleChanged = false;
+
+// private boolean keyInputSelector = false;
+
+ // Status variables for the possible errors on this page.
+ // 1. timeStatus holds an error if CSS file is not specified
+ private IStatus filePathStatus = null;
+ // 2. holds an error if the destination class style is empty
+ private IStatus classNameStatus = null;
+ // 3. holds an error if inccorrect property was specified
+ private IStatus cssValueStatus =null;
+
+ // an array of subscribed message dialog listener
+ private ArrayList<MessageDialogListener> errorListeners = new
ArrayList<MessageDialogListener>();
+
+ // parameter indicates if dialog was opened from Wizard
+ private final boolean callFromWizard;
+
+ private Button addNewClass;
+
+
+ /**
+ * Constructor.
+ *
+ * @param parentShell Shell object
+ * @param allProject (if allProject is true - browse css file in all projects, else
only in current project)
+ * @param callFromWizard indicates if CSS dialog is created within Wizard page
+ */
+ public CSSClassDialog(Shell parentShell, IStructuredSelection selection, boolean
callFromWizard) {
+ super(parentShell);
+
+ setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX | SWT.APPLICATION_MODAL);
+
+ filePathStatus = new Status(IStatus.ERROR, notUsed, 0,
JstUIMessages.CSS_EMPTY_FILE_PATH_MESSAGE, null);
+ classNameStatus = new Status(IStatus.ERROR, notUsed, 0,
JstUIMessages.CSS_EMPTY_STYLE_CLASS_MESSAGE, null);
+
+ styleAttributes = new StyleAttributes();
+ styleAttributes.addChangeStyleListener(this);
+ this.callFromWizard = callFromWizard;
+ this.selection = selection;
+ init();
+ }
+
+ /**
+ * Initialize method.
+ */
+ private void init() {
+ if (selection != null && !selection.isEmpty()) {
+ for (Iterator<?> iterator = selection.iterator(); iterator.hasNext();) {
+ Object element = iterator.next();
+ if (element instanceof IResource) {
+ if (element instanceof IFile) {
+ if (((IFile) element).getName().toLowerCase().endsWith(Util.CSS_FILE_EXTENTION)) {
+ currentFile = (IFile)element;
+ }
+ }
+ }
+ }
+ }
+ // if any CSS file is currently opened and has active page status this method should
return style class
+ // within this file where cursor is located
+ if (currentFile == null) {
+ currentFile = Util.getActiveCssFile();
+ }
+ }
+
+ /**
+ * Sets current style class value.
+ *
+ * @param currentClassStyle String value
+ */
+ public void setCurrentStyleClass(String currentClassStyle) {
+ this.currentClassStyle = Util.formatStyleClassToCSSView(currentClassStyle);
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(Composite)
+ */
+ @Override
+ protected Control createDialogArea(final Composite parent) {
+ final Composite composite = (Composite) super.createDialogArea(parent);
+ if(composite.getLayoutData()!=null && composite.getLayoutData()
instanceof GridData) {
+ ((GridData)composite.getLayoutData()).widthHint=500;
+ ((GridData)composite.getLayoutData()).heightHint=500;
+ }
+ final Control control = createDialogComposite(composite);
+ return control;
+ }
+
+ public Control createDialog(final Composite parent) {
+ return createDialogArea(parent);
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(Composite)
+ */
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ super.createButtonsForButtonBar(parent);
+ updateOKButtonState();
+
+ }
+ private Split split;
+ /**
+ * Create the dialog itself.
+ *
+ * @param composite parent window
+ * @return eclipse Control object
+ */
+ private Control createDialogComposite(Composite composite) {
+ if (!this.callFromWizard) {
+ setTitle(JstUIMessages.CSS_STYLE_CLASS_EDITOR_TITLE);
+ setMessage(JstUIMessages.CSS_STYLE_CLASS_EDITOR_DESCRIPTION);
+ }
+ composite.setLayout(new GridLayout());
+
+ //
===============================================================================
+ // Create split component that separates dialog on 2 parts
+ //
===============================================================================
+ split = new Split(composite, SWT.VERTICAL);
+
+ //
===============================================================================
+ // Create browser container
+ //
===============================================================================
+ browserContainer = getCompositeElement(split);
+ // create browser component
+ createBrowserComponent();
+
+ //
===============================================================================
+ // Create down splitter container
+ //
===============================================================================
+ Composite downSplitPane = getCompositeElement(split);
+
+ Composite classComposite = new Composite(downSplitPane, SWT.BORDER);
+ classComposite.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING,
true, false));
+ classComposite.setLayout(new GridLayout(3, false));
+
+ //
===============================================================================
+ // Create component that contains CSS file pass and it's selectors (style
classes combo box)
+ //
===============================================================================
+ createCSSFilePathComponent(classComposite);
+ createStyleClassCombo(classComposite);
+
+ //
===============================================================================
+ // Create style composite component
+ //
===============================================================================
+ styleComposite = new StyleComposite(downSplitPane, styleAttributes,
Constants.EMPTY);
+ styleComposite.addManualChangeStyleListener(new ManualChangeStyleListener() {
+ public void styleChanged(ChangeStyleEvent event) {
+ styleChanged = true;
+ if (currentClassStyle != null &&
!currentClassStyle.equals(Constants.EMPTY)
+ && currentFile != null &&
!currentFile.equals(Constants.EMPTY)) {
+ updateApplyButton(true);
+ }
+ }
+ });
+
+ //
===============================================================================
+ // Create custom button panel
+ //
===============================================================================
+ createCustomButtonPanel(downSplitPane);
+
+ styleAttributes.addChangeStyleListener(new ChangeStyleListener() {
+ public void styleChanged(ChangeStyleEvent event) {
+ if (!browser.isDisposed()) {
+ browser.setText(getTextForBrowser());
+ }
+ }
+ });
+
+ if (currentFile != null) {
+ initCSSModel(currentFile, true, true);
+ } else if (currentClassStyle != null) {
+ classCombo.setText(currentClassStyle);
+ styleAttributes.setCssSelector(currentClassStyle);
+ }
+
+ // add content assist to style COMBO component
+ SimpleContentProposalProvider proposalProvider = new
SimpleContentProposalProvider(classCombo.getItems());
+ proposalProvider.setFiltering(true);
+
+ split.setWeights(new int[]{15, 85});
+ split.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true,
true));
+
+ return composite;
+ }
+
+ private void createCSSFilePathComponent(Composite parent) {
+ Label label = new Label(parent, SWT.LEFT);
+ label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false));
+ label.setText(JstUIMessages.CSS_CLASS_DIALOG_FILE_LABEL);
+
+ // Text field contains path to the CSS file
+ text = new Text(parent, SWT.BORDER|SWT.READ_ONLY);
+ GridData gridData =new GridData(GridData.FILL, GridData.CENTER, true, false);
+ gridData.grabExcessHorizontalSpace=true;
+ gridData.horizontalSpan=2;
+ text.setLayoutData(gridData);
+// text.setEditable(false);
+ text.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String cssFile = text.getText().trim();
+ // Initialize a variable with the no error status
+ filePathStatus = new Status(IStatus.ERROR, notUsed, 0,
JstUIMessages.CSS_EMPTY_FILE_PATH_MESSAGE, null);
+ if (cssFile != null && !cssFile.equals(Constants.EMPTY)) {
+ filePathStatus = new Status(IStatus.OK, notUsed, 0,
JstUIMessages.CSS_STYLE_CLASS_EDITOR_DESCRIPTION, null);
+ }
+ // show corresponding message
+ IStatus status = findMostSevere();
+ notifyListeners(text, status);
+ applyToStatusLine(status);
+ }
+ });
+ }
+
+ /**
+ * This method is used to create and initialize style class comboBox component.
+ *
+ * @param parent Composite component
+ */
+ private void createStyleClassCombo(final Composite parent) {
+ Label label = new Label(parent, SWT.LEFT);
+ label.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false));
+ label.setText(JstUIMessages.CSS_CLASS_DIALOG_STYLE_CLASS_LABEL);
+
+ GridData gridData = new GridData(GridData.FILL, GridData.CENTER, true, false);
+ gridData.horizontalSpan = 1;
+
+ classCombo = new Combo(parent, SWT.BORDER|SWT.READ_ONLY);
+ classCombo.setLayoutData(gridData);
+ // this listener is responsible for processing dialog header message events
+ classCombo.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String cssClass = classCombo.getText().trim();
+ // Initialize a variable with the no error status
+ classNameStatus = new Status(IStatus.ERROR, notUsed, 0,
JstUIMessages.CSS_EMPTY_STYLE_CLASS_MESSAGE, null);
+ if (cssClass != null && !cssClass.equals(Constants.EMPTY)) {
+ classNameStatus = new Status(IStatus.OK, notUsed, 0,
JstUIMessages.CSS_STYLE_CLASS_EDITOR_DESCRIPTION, null);
+ }
+ // show corresponding message
+ IStatus status = findMostSevere();
+ notifyListeners(classCombo, status);
+ applyToStatusLine(status);
+ // update CSS style cmposite if needed
+ if ((currentClassStyle != null &&
currentClassStyle.equals(classCombo.getText().trim()))
+ || (currentClassStyle == null &&
classCombo.getText().trim().equals(Constants.EMPTY))) {
+ return;
+ }
+ cssStyleClassChanged();
+ updateApplyButton(false);
+ }
+ });
+ //creates a button for add new class
+ addNewClass = new Button(parent, SWT.PUSH);
+ addNewClass.setText(JstUIMessages.BUTTON_ADD_NEW_STYLE_CLASS);
+ addNewClass.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ InputDialog dlg = new InputDialog(parent.getShell(),
+ JstUIMessages.ENTER_CSS_CLASS_NAME,
JstUIMessages.ENTER_CSS_CLASS_NAME, classCombo.getText(),
+ new IInputValidator(){
+ private CSSValidator cssValidator = CSSValidator.getInstance();
+ /**
+ * Validation of new CSS Class Name
+ */
+ public String isValid(String newText) {
+ if (cssValidator.isValidSelector(newText)) {
+ return null;
+ } else {
+ return JstUIMessages.CSS_CLASS_NAME_NOT_VALID;
+ }
+ }
+ });
+ if (dlg.open() == Window.OK) {
+ addNewStyleClass(dlg.getValue().trim());
+ }
+ }
+ });
+ }
+ /**
+ * Add New Class to CSS Class Dialog
+ * @param styleClassName - name of new style class
+ */
+ public void addNewStyleClass(String styleClassName) {
+ updateApplyButton(true);
+ styleChanged = true;
+ currentClassStyle = styleClassName;
+ updateStyleComposite();
+ styleAttributes.setCssSelector(currentClassStyle);
+ styleComposite.updatePreview(currentClassStyle);
+ updateOKButtonState();
+ // add new class to end of list
+ if (classCombo.indexOf(currentClassStyle) == -1)
+ classCombo.add(currentClassStyle);
+ // end select it
+ classCombo.select(classCombo.getItemCount() - 1);
+ cssModel.setCSS(currentClassStyle, styleAttributes);
+ }
+// /**
+// * This method is invoked to correctly process class style combo modify event.
+// */
+// private void notifyStyleClassChanged() {
+// Display display = null;
+// if (PlatformUI.isWorkbenchRunning()) {
+// display = PlatformUI.getWorkbench().getDisplay();
+// }
+// if (display != null && (Thread.currentThread() == display.getThread())) {
+// if (uiJob == null) {
+// uiJob = new UIJob(jobName) {
+// @Override
+// public IStatus runInUIThread(IProgressMonitor monitor) {
+// if (monitor.isCanceled()) {
+// return Status.CANCEL_STATUS;
+// }
+// monitor.beginTask(jobName, IProgressMonitor.UNKNOWN);
+//
+// // start operation
+// cssStyleClassChanged();
+// // end operation
+//
+// monitor.done();
+//
+// return Status.OK_STATUS;
+// }
+// };
+// }
+//
+// uiJob.setPriority(Job.SHORT);
+// uiJob.schedule(delay);
+//
+// return;
+// }
+// }
+
+ /**
+ * This method is used to create custom button panel.
+ *
+ * @param parent Composite component
+ */
+ private void createCustomButtonPanel(Composite parent) {
+ Composite buttonComposite = new Composite(parent, SWT.NONE);
+ buttonComposite.setLayoutData(new GridData(GridData.END, GridData.BEGINNING,
true, false));
+ buttonComposite.setLayout(new GridLayout());
+ // add APPLY button
+ applyButton = createCustomButton(buttonComposite, JstUIMessages.BUTTON_APPLY);
+ updateApplyButton(false);
+ applyButton.setToolTipText(JstUIMessages.CSS_APPLY_CHANGES);
+ applyButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ if (currentClassStyle != null &&
!currentClassStyle.equals(Constants.EMPTY)) {
+ // update ComboBox element list
+ if (classCombo.indexOf(currentClassStyle) == -1) {
+ classCombo.add(currentClassStyle);
+ }
+ saveChanges(false);
+ updateApplyButton(false);
+ styleChanged = false;
+ }
+ }
+ });
+ // add CLEAR button
+ Button clearButton = createCustomButton(buttonComposite,
JstUIMessages.BUTTON_CLEAR);
+ clearButton.setToolTipText(JstUIMessages.CSS_CLEAR_STYLE_SHEET);
+ clearButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ styleComposite.clearStyleComposite(currentClassStyle);
+ styleComposite.updatePreview(currentClassStyle);
+ styleComposite.updateStyle();
+ updateApplyButton(true);
+ styleChanged = true;
+ }
+ });
+ }
+
+ /**
+ * This method is used to create custom button.
+ *
+ * @param parent Composite component
+ * @param label Button label value
+ */
+ protected Button createCustomButton(Composite parent, String label) {
+ // increment the number of columns in the button bar
+ ((GridLayout) parent.getLayout()).numColumns++;
+ Button button = new Button(parent, SWT.PUSH);
+ button.setText(label);
+// setButtonLayoutData(button);
+ return button;
+ }
+
+ /**
+ * Method is used to correctly process style class change operation.
+ */
+ private void cssStyleClassChanged() {
+ if (currentFile != null && !currentFile.equals(Constants.EMPTY)) {
+// if (styleChanged && currentClassStyle != null &&
!currentClassStyle.equals(Constants.EMPTY)) {
+// MessageBox messageBox = new MessageBox(getParentShell(), SWT.YES | SWT.NO |
SWT.ICON_QUESTION);
+// messageBox.setText(JstUIMessages.CSS_SAVE_DIALOG_TITLE);
+// messageBox.setMessage(CSSClassDialog.getMessageForSaveDialog(currentFile));
+// int result = messageBox.open();
+// if (result == SWT.YES) {
+// // update ComboBox element list
+// if (classCombo.indexOf(currentClassStyle) == -1) {
+// classCombo.add(currentClassStyle);
+// }
+ cssModel.setCSS(currentClassStyle, styleAttributes);
+// // update content assist proposals
+// SimpleContentProposalProvider proposalProvider =
+//
(SimpleContentProposalProvider)contentAssistAdapter.getContentProposalProvider();
+// proposalProvider.setProposals(classCombo.getItems());
+// } else {
+// // FOR
https://jira.jboss.org/jira/browse/JBIDE-3542
+// // cssModel.init(currentFile);
+// // styleComposite.revertPreview();
+// }
+// }
+ // update current class style value
+ currentClassStyle = classCombo.getText().trim();
+
+ // if new css was added
+// if (classCombo.indexOf(currentClassStyle) == -1) {
+// classCombo.add(currentClassStyle);
+// styleChanged = true;
+// } else {
+// styleChanged = false;
+// }
+ updateApplyButton(true);
+ styleChanged = true;
+
+ updateStyleComposite();
+ styleAttributes.setCssSelector(currentClassStyle);
+ styleComposite.updatePreview(currentClassStyle);
+ updateOKButtonState();
+ } else {
+ currentClassStyle = classCombo.getText().trim();
+ styleAttributes.setCssSelector(currentClassStyle);
+ styleChanged = false;
+ }
+
+ }
+
+ /**
+ * Initialize CSS model with active opened CSS file.
+ *
+ * @param file IFile object
+ * @param useRelativePathPath
+ */
+ private void initCSSModel(IFile file, boolean useRelativePathPath, boolean
updateCSSModel) {
+ if (file != null) {
+ // create CSS Model
+ cssModel = new CSSModel(file);
+ currentClassStyle = null;
+ classCombo.removeAll();
+ classCombo.setEnabled(true);
+ // set file path to corresponding text field
+ if (useRelativePathPath) {
+ text.setText(file.getProjectRelativePath().toOSString());
+ } else {
+ text.setText(file.getFullPath().toOSString());
+ }
+
+ Point selectionInFile = Util.getSelectionInFile(file);
+
+ currentClassStyle = cssModel.getSelectorByPosition(selectionInFile);
+
+ // fill in ComboBox component with CSS model selectors
+// List<Selector> selectors = cssModel.getSelectors();
+ List<String> selectors = cssModel.getSelectorLabels();
+ for (int i = 0; i < selectors.size(); i++) {
+// Selector value = selectors.get(i);
+ String label = selectors.get(i);
+ classCombo.add(/*value.getValue()*/ label);
+
+ }
+ /*
+ *
+ */
+ if (currentClassStyle != null) {
+ classCombo.setText(currentClassStyle);
+ } else {
+ classCombo.select(0);
+ }
+ classCombo.setToolTipText(cssModel.getCSSText(currentClassStyle));
+
+ styleComposite.setShowPreviewTab(true);
+ styleComposite.setCSSModel(cssModel);
+ // update style composite component with the values from new CSS file
+ if (updateCSSModel) {
+ updateStyleComposite();
+ }
+ styleComposite.initPreview(cssModel);
+ }
+ }
+
+ /**
+ * This method takes affect to OK button when dialog is opened in "dialog"
mode and not in "wizard".
+ * In case of "wizard" mode OK button is not available.
+ */
+ private void updateOKButtonState() {
+ Button okButton = getButton(IDialogConstants.OK_ID);
+ if (okButton != null) {
+ if (findMostSevere()!=null&&findMostSevere().getSeverity()==IStatus.ERROR)
{
+ okButton.setEnabled(false);
+ } else {
+ okButton.setEnabled(true);
+ }
+ }
+ }
+
+ /**
+ * Method is used to create browser component to display preview HTML.
+ */
+ private void createBrowserComponent() {
+ GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, true);
+ browser = new Browser(browserContainer, SWT.BORDER | SWT.MOZILLA);
+ browser.setText(getTextForBrowser());
+ browser.addMouseListener(new MouseAdapter() {
+ public void mouseDoubleClick(MouseEvent e) {
+ if (e.widget == browser) {
+ browser.removeMouseListener(this);
+ browser.dispose();
+ // create Text area component instead of HTML Browser
+ GridData gridData = new GridData(GridData.FILL, GridData.FILL, true,
true);
+// textBrowser = new Text(browserContainer, SWT.MULTI | SWT.V_SCROLL |
SWT.H_SCROLL);
+ textBrowser = new Text(browserContainer, SWT.NONE | SWT.H_SCROLL);
+ textBrowser.setText(previewBrowserValue);
+ textBrowser.addFocusListener(new FocusAdapter() {
+ public void focusLost(FocusEvent e) {
+ if (e.widget == textBrowser) {
+ String text = textBrowser.getText();
+ if (text == null || text.equals(Constants.EMPTY)) {
+ previewBrowserValue =
JstUIMessages.DEFAULT_TEXT_FOR_BROWSER_PREVIEW;
+ } else {
+ previewBrowserValue = text;
+ }
+ textBrowser.dispose();
+ // create Browse component instead of text area
+ createBrowserComponent();
+ }
+ browserContainer.layout();
+ }
+ });
+ textBrowser.setLayoutData(gridData);
+ textBrowser.setEditable(true);
+ textBrowser.setFocus();
+ }
+ browserContainer.layout();
+ }
+ });
+ browser.setLayoutData(gridData);
+ }
+
+ /**
+ * Update style composite component in accordance with the attributes of selected CSS
selector.
+ */
+ private void updateStyleComposite() {
+ String style = cssModel.getStyle(currentClassStyle);
+ styleComposite.recreateStyleComposite(style, currentClassStyle);
+ }
+
+ /**
+ * Method is used to build html body that is appropriate to browse.
+ *
+ * @return String html text representation
+ */
+ private String getTextForBrowser() {
+ String styleForSpan = Constants.EMPTY;
+ Set<String> keySet = styleAttributes.keySet();
+ for (String key : keySet) {
+ styleForSpan += (key + Constants.COLON + styleAttributes.getAttribute(key) +
Constants.SEMICOLON);
+ }
+ String html = Constants.OPEN_DIV_TAG + styleForSpan + "\">" +
previewBrowserValue + Constants.CLOSE_DIV_TAG; //$NON-NLS-1$
+
+ return html;
+ }
+
+ /**
+ * Create container that take up 2 cells and contains fontSizeCombo and
extFontSizeCombo elements.
+ */
+ private Composite getCompositeElement(Composite parent) {
+ GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, true);
+ GridLayout gridLayoutTmp = new GridLayout();
+ gridLayoutTmp.marginHeight = 0;
+ gridLayoutTmp.marginWidth = 0;
+ Composite classComposite = new Composite(parent, SWT.FILL);
+ classComposite.setLayout(gridLayoutTmp);
+ classComposite.setLayoutData(gridData);
+
+ return classComposite;
+ }
+
+ public void releaseResources() {
+
+ if (cssModel != null){
+ cssModel.releaseModel();
+ cssModel = null;
+ }
+ }
+
+ /**
+ * Method should be called in case of dialog closure operation.
+ */
+ public void saveChanges(boolean close) {
+ styleComposite.updateStyle();
+ cssModel.setCSS(currentClassStyle, styleAttributes);
+ cssModel.saveModel();
+ }
+
+ /**
+ * Gets current selected style class value.
+ *
+ * @return selector name
+ */
+ public String getSelectorName() {
+ return Util.formatCSSSelectorToStyleClassView(currentClassStyle);
+ }
+
+ /**
+ * Method for setting title for dialog
+ *
+ * @param newShell Shell object
+ * @see org.eclipse.jface.window.Window#configureShell(Shell)
+ */
+ @Override
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(JstUIMessages.CSS_STYLE_CLASS_EDITOR_TITLE);
+ }
+
+ /**
+ * This method close the dialog.
+ *
+ * @return true if dialog was closed, false - otherwise
+ */
+ public boolean closeDialog() {
+ setReturnCode(Window.CANCEL);
+ return close();
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.Dialog#close()
+ */
+ @Override
+ public boolean close() {
+ int code = getReturnCode();
+ switch (code) {
+ case OK:
+ if (styleChanged || classCombo.indexOf(currentClassStyle) == -1) {
+ saveChanges(true);
+ }
+ break;
+ case CANCEL:
+ default:
+ // make some closure operation
+ }
+ releaseResources();
+ return super.close();
+ }
+
+ /**
+ * Add MessageDialogListener object.
+ *
+ * @param listener MessageDialogListener object to be added
+ */
+ public void addMessageDialogListener(MessageDialogListener listener) {
+ errorListeners.add(listener);
+ }
+
+ /**
+ * Method is used to notify all subscribed listeners about possible any errors on the
page.
+ */
+ private void notifyListeners(Object source, IStatus operationStatus) {
+ MessageDialogEvent event = new MessageDialogEvent(source, operationStatus);
+ for (MessageDialogListener listener : errorListeners) {
+ listener.throwMessage(event);
+ }
+ }
+
+ /**
+ * Method return the most serious error occurs on the page and that should be
displayed.
+ *
+ * @return IStatus object
+ */
+ private IStatus findMostSevere() {
+ if (filePathStatus.matches(IStatus.ERROR)) {
+ return filePathStatus;
+ }
+ if (classNameStatus.matches(IStatus.ERROR)) {
+ return classNameStatus;
+ }
+ if(cssValueStatus!=null && cssValueStatus.matches(IStatus.ERROR)){
+ return cssValueStatus;
+ }
+ if(cssValueStatus!=null && cssValueStatus.matches(IStatus.ERROR)){
+ return cssValueStatus;
+ } else {
+ return classNameStatus;
+ }
+
+ }
+
+ /**
+ * Applies the status to the status line of a dialog page.
+ */
+ private void applyToStatusLine(IStatus status) {
+ if (!callFromWizard) {
+ String message= status.getMessage();
+ if (message.length() == 0) {
+ message = null;
+ }
+ switch (status.getSeverity()) {
+ case IStatus.OK:
+ setErrorMessage(null);
+ setMessage(message);
+ break;
+ case IStatus.WARNING:
+ setErrorMessage(null);
+ setMessage(message, WizardPage.WARNING);
+ break;
+ case IStatus.INFO:
+ setErrorMessage(null);
+ setMessage(message, WizardPage.INFORMATION);
+ break;
+ default:
+ setErrorMessage(message);
+ setMessage(null);
+ break;
+ }
+ }
+ }
+
+ public void reinit(){
+ releaseResources();
+ initCSSModel(currentFile, true,true);
+ }
+
+ public void setCurrentFile(IFile currentFile) {
+ this.currentFile = currentFile;
+ }
+
+ /* (non-Javadoc)
+ * @see
org.jboss.tools.jst.jsp.outline.cssdialog.events.ChangeStyleListener#styleChanged(org.jboss.tools.jst.jsp.outline.cssdialog.events.ChangeStyleEvent)
+ */
+ public void styleChanged(ChangeStyleEvent event) {
+ if (!this.styleAttributes.isValid()) {
+ cssValueStatus = new Status(IStatus.ERROR, notUsed, 0,
+ JstUIMessages.CSS_INVALID_STYLE_PROPERTY, null);
+ notifyListeners(event, cssValueStatus);
+ addNewClass.setEnabled(false);
+ } else {
+ cssValueStatus = null;
+ addNewClass.setEnabled(true);
+ notifyListeners(event, new Status(IStatus.OK, notUsed, 0,
+ JstUIMessages.CSS_STYLE_CLASS_EDITOR_DESCRIPTION, null));
+ }
+ if (cssValueStatus != null && classCombo != null) {
+ classCombo.setEnabled(false);
+ } else {
+ classCombo.setEnabled(true);
+
+ }
+ updateApplyButton(true);
+ updateOKButtonState();
+ applyToStatusLine(findMostSevere());
+ }
+ /**
+ * Update upplyButtonState
+ * @param available
+ */
+ private void updateApplyButton(boolean enabled){
+ if(cssValueStatus!=null
+ &&cssValueStatus.matches(IStatus.ERROR)) {
+ applyButton.setEnabled(false);
+ }else {
+ applyButton.setEnabled(enabled);
+ }
+
+ }
+}
Modified:
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/common/CSSModel.java
===================================================================
---
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/common/CSSModel.java 2009-03-19
09:19:53 UTC (rev 14262)
+++
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/common/CSSModel.java 2009-03-19
13:36:13 UTC (rev 14263)
@@ -1,432 +1,430 @@
-/*******************************************************************************
- * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc.
- * Distributed under license by Red Hat, Inc. All rights reserved.
- * This program is made available under the terms of the
- * Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at
http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Exadel, Inc. and Red Hat, Inc. - initial API and implementation
- ******************************************************************************/
-package org.jboss.tools.jst.jsp.outline.cssdialog.common;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-import org.eclipse.core.filebuffers.FileBuffers;
-import org.eclipse.core.filebuffers.IFileBuffer;
-import org.eclipse.core.filebuffers.LocationKind;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IDocumentExtension3;
-import org.eclipse.jface.text.IDocumentPartitioner;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.wst.css.core.internal.format.FormatProcessorCSS;
-import org.eclipse.wst.css.core.internal.provisional.document.ICSSDocument;
-import org.eclipse.wst.css.core.internal.provisional.document.ICSSModel;
-import org.eclipse.wst.css.core.internal.provisional.document.ICSSNode;
-import org.eclipse.wst.css.core.internal.provisional.document.ICSSStyleSheet;
-import org.eclipse.wst.css.core.internal.text.StructuredTextPartitionerForCSS;
-import org.eclipse.wst.sse.core.StructuredModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
-import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
-import org.eclipse.wst.sse.core.internal.provisional.exceptions.ResourceInUse;
-import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredPartitioning;
-import org.jboss.tools.jst.jsp.JspEditorPlugin;
-import org.jboss.tools.jst.jsp.outline.cssdialog.events.StyleAttributes;
-import org.w3c.dom.css.CSSRuleList;
-import org.w3c.dom.css.CSSStyleDeclaration;
-import org.w3c.dom.css.CSSStyleRule;
-import org.w3c.dom.css.CSSStyleSheet;
-
-/**
- * CSS class model.
- *
- *
- */
-public class CSSModel {
-
- private static String startBraces = "{"; //$NON-NLS-1$
- private static String endBraces = "}"; //$NON-NLS-1$
-
- private FormatProcessorCSS formatProcessorCSS = null;
- private IStructuredModel model = null;
- private IFile styleFile = null;
-
- private CSSStyleSheet styleSheet = null;
- private ICSSStyleSheet eclipseStyleSheet = null;
- private String COPY_SUFFIX = "_copy";
- private boolean copy = false;
-
-
- /**
- * Constructor.
- *
- * @param styleFile CSS style class that should initialize CSS model
- */
- public CSSModel(IFile styleFile) {
- init(styleFile);
- }
-
- public void init(IFile styleFile) {
- try {
- this.styleFile = styleFile;
- if (model != null) {
- releaseModel();
- }
- copy = false;
- formatProcessorCSS = new FormatProcessorCSS();
- IModelManager modelManager = StructuredModelManager.getModelManager();
- model = modelManager.getExistingModelForEdit(styleFile);
-
-
- if (model == null)
- model = modelManager.getModelForEdit(styleFile);
- else {
-
- copy = true;
- // copy the model
- model = modelManager.copyModelForEdit(model.getId(), model
- .getId()
- + COPY_SUFFIX);
-
- // set the correct location
- model.setBaseLocation(styleFile.getLocation().toString());
-
- // some steps to prepare document ( it is necessary to correct
- // work of highlight in preview tab )
- IDocumentPartitioner partitioner = new StructuredTextPartitionerForCSS();
- ((IDocumentExtension3) model.getStructuredDocument())
- .setDocumentPartitioner(
- IStructuredPartitioning.DEFAULT_STRUCTURED_PARTITIONING,
- partitioner);
- partitioner.connect(model.getStructuredDocument());
-
- }
- if (model instanceof ICSSModel) {
- ICSSModel cssModel = (ICSSModel) model;
- ICSSDocument document = cssModel.getDocument();
- if (document instanceof CSSStyleSheet) {
- styleSheet = (CSSStyleSheet) document;
- }
- if (document instanceof ICSSStyleSheet) {
- eclipseStyleSheet = (ICSSStyleSheet) document;
- }
-
-
- }
- } catch (IOException e) {
- JspEditorPlugin.getPluginLog().logError(e.getMessage());
- } catch (CoreException e) {
- JspEditorPlugin.getPluginLog().logError(e.getMessage());
- } catch (ResourceInUse e) {
- JspEditorPlugin.getPluginLog().logError(e.getMessage());
- }
- }
-
- /**
- * Method is used to select area that corresponds to specific selector.
- *
- * @param selector the selector that should be selected in editor area
- * @param index if CSS file contains more then one elements with the same selector
name,
- * then index is serial number of this selector
- */
- public IndexedRegion getSelectorRegion(String selector, int index) {
- //FIXED by sdzmitrovich - JBIDE-3148
-// if (eclipseStyleSheet != null) {
-// if (selector != null && !selector.equals(Constants.EMPTY)) {
-// ICSSStyleRule styleRule = Util.getSelector(eclipseStyleSheet, selector, index);
-// if (styleRule != null) {
-// if (styleRule instanceof IndexedRegion) {
-// return (IndexedRegion) styleRule;
-// }
-// }
-// }
-// }
-
- if ( selector != null) {
- CSSStyleRule rule = getRulesMapping().get(selector);
- if (rule != null)
- if (rule instanceof IndexedRegion) {
- return (IndexedRegion) rule;
- }
-
- }
- return null;
- }
-
-
- public List<String> getSelectorLabels() {
-
- List<String> selectorLabels;
-
- selectorLabels = new ArrayList<String>(getRulesMapping().keySet());
-
- Collections.sort(selectorLabels);
-
- return selectorLabels;
- }
-
- /**
- * Gets CSS attributes for the given selector in string representation.
- *
- * @param selector CSS selector value
- * @return CSS attributes string representation
- */
- public String getCSSText(String selector) {
- //FIXED by sdzmitrovich - JBIDE-3148
-// if (styleSheet != null && selector != null) {
-// CSSRuleList list = styleSheet.getCssRules();
-//
-// if (list != null) {
-// for (int i = 0; i < list.getLength(); i++) {
-// if (list.item(i) instanceof CSSStyleRule &&
-// ((CSSStyleRule)
list.item(i)).getSelectorText().equals(selector)) {
-// return ((CSSStyleRule) list.item(i)).getCssText();
-// }
-// }
-// }
-// }
- if ( selector != null) {
- CSSStyleRule rule = getRulesMapping().get(selector);
- if (rule != null)
- return rule.getCssText();
-
- }
-
- return null;
- }
-
- /**
- * Get style by selectorName
- *
- * @param selectorName
- * @return style
- */
- public String getStyle(String selectorName) {
- //FIXED by sdzmitrovich - JBIDE-3148
-// if (styleSheet != null) {
-// CSSRuleList list = styleSheet.getCssRules();
-//
-// if (list != null) {
-// for (int i = 0; i < list.getLength(); i++) {
-// if (list.item(i) instanceof CSSStyleRule &&
-// ((CSSStyleRule)
list.item(i)).getSelectorText().equals(selectorName)) {
-// return ((CSSStyleRule) list.item(i)).getStyle().getCssText();
-// }
-// }
-// }
-// }
- if (selectorName != null) {
- CSSStyleRule rule = getRulesMapping().get(selectorName);
- if (rule != null)
- return rule.getStyle().getCssText();
-
- }
-
- return null;
- }
-
- /**
- * Sets CSS style for the given selector.
- *
- * @param selector CSS selector value
- * @param styleAttribute the style to be set
- */
- public void setCSS(String selector, StyleAttributes styleAttributes) {
- if (styleSheet != null && selector != null &&
!selector.equals(Constants.EMPTY)) {
- CSSRuleList list = styleSheet.getCssRules();
- //FIXED by sdzmitrovich - JBIDE-3148
-// if (list != null) {
-// // check if selector passed by parameter already exists in CSS
-// for (int i = 0; i < list.getLength(); i++) {
-// if (list.item(i) instanceof CSSStyleRule &&
-// ((CSSStyleRule)
list.item(i)).getSelectorText().equals(selector)) {
-//
-// CSSStyleRule rule = (CSSStyleRule) list.item(i);
-// styleSheet.deleteRule(i);
-//
-// i = styleSheet.insertRule(selector + startBraces +
styleAttributes.getStyle() + endBraces, i);
-// rule = (CSSStyleRule) list.item(i);
-// CSSStyleDeclaration declaration = rule.getStyle();
-// // set properties
-// Set<Entry<String, String>> set =
styleAttributes.entrySet();
-// for (Map.Entry<String, String> me : set) {
-// declaration.setProperty(me.getKey(), me.getValue(),
Constants.EMPTY);
-// }
-//
-// formatProcessorCSS.formatModel(model);
-// return;
-// }
-// }
-// // insert NEW selector to style sheet
-// styleSheet.insertRule(selector + startBraces +
styleAttributes.getStyle() + endBraces, list.getLength());
-// formatProcessorCSS.formatModel(model);
- CSSStyleRule rule = getRulesMapping().get(selector);
- if (rule == null) {
- styleSheet.insertRule(selector + startBraces
- + styleAttributes.getStyle() + endBraces, list
- .getLength());
- } else {
-
- CSSStyleDeclaration declaration = rule.getStyle();
- // set properties
- Set<Entry<String, String>> set = styleAttributes.entrySet();
-
- if ((set.size() == 0) && (declaration.getLength()>0))
- declaration.setCssText(Constants.EMPTY);
- else
- for (Map.Entry<String, String> me : set) {
- declaration.setProperty(me.getKey(), me.getValue(),
- Constants.EMPTY);
- }
- }
-
- formatProcessorCSS.formatModel(model);
-
- }
- }
-
- /**
- * Gets file associated with current model.
- *
- * @return the styleFile
- */
- public IFile getStyleFile() {
- return this.styleFile;
- }
-
- /**
- * Release CSS model correctly from editing.
- */
- public void releaseModel() {
- IModelManager modelManager = StructuredModelManager.getModelManager();
- if (model != null && !modelManager.isShared(model.getId()))
- model.releaseFromEdit();
- model = null;
- }
-
- /**
- * Save model. Associate file will be saved automatically.
- */
- public void saveModel() {
- try {
-
- /*
- * it is necessary not to dialog appears when "dirty" css file is
- * being saved ( test case : 1) open css file 2) make same changes
- * 3) open css dialog 4) make some changes 5)press ok )
- *
- *
- * it is necessary to distinguish real model from copy. For real
- * model next step reject all changes
- */
- if (copy) {
- IFileBuffer buffer = FileBuffers.getTextFileBufferManager()
- .getFileBuffer(styleFile.getFullPath(),
- LocationKind.NORMALIZE);
- buffer.setDirty(false);
- }
-
- model.save();
- } catch (IOException e) {
- JspEditorPlugin.getPluginLog().logError(e.getMessage());
- } catch (CoreException e) {
- JspEditorPlugin.getPluginLog().logError(e.getMessage());
- }
- }
-
- /**
- * get mapping key is label ( label = class name + sequence number of such
- * css class ) value is CSSStyleRule
- *
- * now rule mapping is generated always ... keeping of ruleMapping is more
- * right but it demands more complex synchronization data
- *
- */
- private Map<String, CSSStyleRule> getRulesMapping() {
-
- Map<String, CSSStyleRule> rulesMapping = new HashMap<String,
CSSStyleRule>();
- if (styleSheet != null) {
- CSSRuleList list = styleSheet.getCssRules();
-
- Map<String, Integer> frequencyMap = new HashMap<String, Integer>();
-
- if (list != null) {
- for (int i = 0; i < list.getLength(); i++) {
- if (list.item(i) instanceof CSSStyleRule) {
-
- CSSStyleRule rule = ((CSSStyleRule) list.item(i));
-
- Integer freq = frequencyMap.get(rule.getSelectorText());
-
- freq = freq == null ? 1 : freq + 1;
-
- frequencyMap.put(rule.getSelectorText(), freq);
-
- String ruleLabel = rule.getSelectorText()
- + (freq > 1 ? Constants.START_BRACKET + freq
- + Constants.END_BRACKET
- : Constants.EMPTY);
-
- rulesMapping.put(ruleLabel, rule);
-
- }
- }
- }
-
- }
-
- return rulesMapping;
- }
-
- public IDocument getStructuredDocument() {
- return model.getStructuredDocument();
- }
-
- public void reload() {
- try {
- if(model.isDirty()) {
- model.reload(new FileInputStream(styleFile.getLocation().toFile()));
- }
- } catch (Exception e) {
- JspEditorPlugin.getPluginLog().logError(e.getMessage());
- }
-
- }
-
- public String getSelectorByPosition(Point selectionInFile) {
-
- ICSSNode node = (ICSSNode) model.getIndexedRegion(selectionInFile.x);
-
- while (node != null) {
-
- if (node.getNodeType() == ICSSNode.STYLERULE_NODE) {
- break;
- } else if (node.getNodeType() == ICSSNode.STYLESHEET_NODE) {
- node = ((ICSSStyleSheet) node).getFirstChild();
- break;
- }
-
- node = node.getParentNode();
- }
-
- Object rules= getRulesMapping();
- if (node != null)
- for (Entry<String, CSSStyleRule> rule : getRulesMapping()
- .entrySet()) {
- if (node.equals(rule.getValue()))
- return rule.getKey();
- }
- return null;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc.
+ * Distributed under license by Red Hat, Inc. All rights reserved.
+ * This program is made available under the terms of the
+ * Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at
http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Exadel, Inc. and Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.jst.jsp.outline.cssdialog.common;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.IFileBuffer;
+import org.eclipse.core.filebuffers.LocationKind;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.wst.css.core.internal.format.FormatProcessorCSS;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSDocument;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSModel;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSNode;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSRuleContainer;
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSStyleSheet;
+import org.eclipse.wst.css.core.internal.text.StructuredTextPartitionerForCSS;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
+import org.eclipse.wst.sse.core.internal.provisional.exceptions.ResourceInUse;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredPartitioning;
+import org.jboss.tools.jst.jsp.JspEditorPlugin;
+import org.jboss.tools.jst.jsp.outline.cssdialog.events.StyleAttributes;
+import org.w3c.dom.css.CSSRuleList;
+import org.w3c.dom.css.CSSStyleDeclaration;
+import org.w3c.dom.css.CSSStyleRule;
+import org.w3c.dom.css.CSSStyleSheet;
+
+/**
+ * CSS class model.
+ *
+ *
+ */
+public class CSSModel {
+
+ private static String startBraces = "{"; //$NON-NLS-1$
+ private static String endBraces = "}"; //$NON-NLS-1$
+
+ private FormatProcessorCSS formatProcessorCSS = null;
+ private IStructuredModel model = null;
+ private IFile styleFile = null;
+
+ private CSSStyleSheet styleSheet = null;
+ private ICSSStyleSheet eclipseStyleSheet = null;
+ private String COPY_SUFFIX = "_copy";
+ private boolean copy = false;
+
+
+ /**
+ * Constructor.
+ *
+ * @param styleFile CSS style class that should initialize CSS model
+ */
+ public CSSModel(IFile styleFile) {
+ init(styleFile);
+ }
+
+ public void init(IFile styleFile) {
+ try {
+ this.styleFile = styleFile;
+ if (model != null) {
+ releaseModel();
+ }
+ copy = false;
+ formatProcessorCSS = new FormatProcessorCSS();
+ IModelManager modelManager = StructuredModelManager.getModelManager();
+ model = modelManager.getExistingModelForEdit(styleFile);
+
+
+ if (model == null)
+ model = modelManager.getModelForEdit(styleFile);
+ else {
+
+ copy = true;
+ // copy the model
+ model = modelManager.copyModelForEdit(model.getId(), model
+ .getId()
+ + COPY_SUFFIX);
+
+ // set the correct location
+ model.setBaseLocation(styleFile.getLocation().toString());
+
+ // some steps to prepare document ( it is necessary to correct
+ // work of highlight in preview tab )
+ IDocumentPartitioner partitioner = new StructuredTextPartitionerForCSS();
+ ((IDocumentExtension3) model.getStructuredDocument())
+ .setDocumentPartitioner(
+ IStructuredPartitioning.DEFAULT_STRUCTURED_PARTITIONING,
+ partitioner);
+ partitioner.connect(model.getStructuredDocument());
+
+ }
+ if (model instanceof ICSSModel) {
+ ICSSModel cssModel = (ICSSModel) model;
+ ICSSDocument document = cssModel.getDocument();
+ if (document instanceof CSSStyleSheet) {
+ styleSheet = (CSSStyleSheet) document;
+ }
+ if (document instanceof ICSSStyleSheet) {
+ eclipseStyleSheet = (ICSSStyleSheet) document;
+ }
+
+
+ }
+ } catch (IOException e) {
+ JspEditorPlugin.getPluginLog().logError(e.getMessage());
+ } catch (CoreException e) {
+ JspEditorPlugin.getPluginLog().logError(e.getMessage());
+ } catch (ResourceInUse e) {
+ JspEditorPlugin.getPluginLog().logError(e.getMessage());
+ }
+ }
+
+ /**
+ * Method is used to select area that corresponds to specific selector.
+ *
+ * @param selector the selector that should be selected in editor area
+ * @param index if CSS file contains more then one elements with the same selector
name,
+ * then index is serial number of this selector
+ */
+ public IndexedRegion getSelectorRegion(String selector, int index) {
+ //FIXED by sdzmitrovich - JBIDE-3148
+// if (eclipseStyleSheet != null) {
+// if (selector != null && !selector.equals(Constants.EMPTY)) {
+// ICSSStyleRule styleRule = Util.getSelector(eclipseStyleSheet, selector, index);
+// if (styleRule != null) {
+// if (styleRule instanceof IndexedRegion) {
+// return (IndexedRegion) styleRule;
+// }
+// }
+// }
+// }
+
+ if ( selector != null) {
+ CSSStyleRule rule = getRulesMapping().get(selector);
+ if (rule != null)
+ if (rule instanceof IndexedRegion) {
+ return (IndexedRegion) rule;
+ }
+
+ }
+ return null;
+ }
+
+
+ public List<String> getSelectorLabels() {
+
+ List<String> selectorLabels;
+
+ selectorLabels = new ArrayList<String>(getRulesMapping().keySet());
+
+ Collections.sort(selectorLabels);
+
+ return selectorLabels;
+ }
+
+ /**
+ * Gets CSS attributes for the given selector in string representation.
+ *
+ * @param selector CSS selector value
+ * @return CSS attributes string representation
+ */
+ public String getCSSText(String selector) {
+ //FIXED by sdzmitrovich - JBIDE-3148
+// if (styleSheet != null && selector != null) {
+// CSSRuleList list = styleSheet.getCssRules();
+//
+// if (list != null) {
+// for (int i = 0; i < list.getLength(); i++) {
+// if (list.item(i) instanceof CSSStyleRule &&
+// ((CSSStyleRule)
list.item(i)).getSelectorText().equals(selector)) {
+// return ((CSSStyleRule) list.item(i)).getCssText();
+// }
+// }
+// }
+// }
+ if ( selector != null) {
+ CSSStyleRule rule = getRulesMapping().get(selector);
+ if (rule != null)
+ return rule.getCssText();
+
+ }
+
+ return null;
+ }
+
+ /**
+ * Get style by selectorName
+ *
+ * @param selectorName
+ * @return style
+ */
+ public String getStyle(String selectorName) {
+ //FIXED by sdzmitrovich - JBIDE-3148
+// if (styleSheet != null) {
+// CSSRuleList list = styleSheet.getCssRules();
+//
+// if (list != null) {
+// for (int i = 0; i < list.getLength(); i++) {
+// if (list.item(i) instanceof CSSStyleRule &&
+// ((CSSStyleRule)
list.item(i)).getSelectorText().equals(selectorName)) {
+// return ((CSSStyleRule) list.item(i)).getStyle().getCssText();
+// }
+// }
+// }
+// }
+ if (selectorName != null) {
+ CSSStyleRule rule = getRulesMapping().get(selectorName);
+ if (rule != null)
+ return rule.getStyle().getCssText();
+
+ }
+
+ return null;
+ }
+
+ /**
+ * Sets CSS style for the given selector.
+ *
+ * @param selector CSS selector value
+ * @param styleAttribute the style to be set
+ */
+ public void setCSS(String selector, StyleAttributes styleAttributes) {
+ if (styleSheet != null && selector != null &&
!selector.equals(Constants.EMPTY)) {
+ CSSRuleList list = styleSheet.getCssRules();
+ //FIXED by sdzmitrovich - JBIDE-3148
+// if (list != null) {
+// // check if selector passed by parameter already exists in CSS
+// for (int i = 0; i < list.getLength(); i++) {
+// if (list.item(i) instanceof CSSStyleRule &&
+// ((CSSStyleRule)
list.item(i)).getSelectorText().equals(selector)) {
+//
+// CSSStyleRule rule = (CSSStyleRule) list.item(i);
+// styleSheet.deleteRule(i);
+//
+// i = styleSheet.insertRule(selector + startBraces +
styleAttributes.getStyle() + endBraces, i);
+// rule = (CSSStyleRule) list.item(i);
+// CSSStyleDeclaration declaration = rule.getStyle();
+// // set properties
+// Set<Entry<String, String>> set =
styleAttributes.entrySet();
+// for (Map.Entry<String, String> me : set) {
+// declaration.setProperty(me.getKey(), me.getValue(),
Constants.EMPTY);
+// }
+//
+// formatProcessorCSS.formatModel(model);
+// return;
+// }
+// }
+// // insert NEW selector to style sheet
+// styleSheet.insertRule(selector + startBraces +
styleAttributes.getStyle() + endBraces, list.getLength());
+// formatProcessorCSS.formatModel(model);
+ CSSStyleRule rule = getRulesMapping().get(selector);
+ if (rule == null) {
+ rule = (CSSStyleRule)((ICSSDocument)styleSheet).createCSSRule(
+ selector + startBraces + styleAttributes.getStyle() + endBraces);
+ ((ICSSStyleSheet)styleSheet).appendRule(rule);
+ } else {
+
+ CSSStyleDeclaration declaration = rule.getStyle();
+ // set properties
+ Set<Entry<String, String>> set = styleAttributes.entrySet();
+
+ if ((set.size() == 0) && (declaration.getLength()>0))
+ declaration.setCssText(Constants.EMPTY);
+ else
+ for (Map.Entry<String, String> me : set) {
+ declaration.setProperty(me.getKey(), me.getValue(),
+ Constants.EMPTY);
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets file associated with current model.
+ *
+ * @return the styleFile
+ */
+ public IFile getStyleFile() {
+ return this.styleFile;
+ }
+
+ /**
+ * Release CSS model correctly from editing.
+ */
+ public void releaseModel() {
+ IModelManager modelManager = StructuredModelManager.getModelManager();
+ if (model != null && !modelManager.isShared(model.getId()))
+ model.releaseFromEdit();
+ model = null;
+ }
+
+ /**
+ * Save model. Associate file will be saved automatically.
+ */
+ public void saveModel() {
+ try {
+
+ /*
+ * it is necessary not to dialog appears when "dirty" css file is
+ * being saved ( test case : 1) open css file 2) make same changes
+ * 3) open css dialog 4) make some changes 5)press ok )
+ *
+ *
+ * it is necessary to distinguish real model from copy. For real
+ * model next step reject all changes
+ */
+ if (copy) {
+ IFileBuffer buffer = FileBuffers.getTextFileBufferManager()
+ .getFileBuffer(styleFile.getFullPath(),
+ LocationKind.NORMALIZE);
+ buffer.setDirty(false);
+ }
+
+ model.save();
+ } catch (IOException e) {
+ JspEditorPlugin.getPluginLog().logError(e.getMessage());
+ } catch (CoreException e) {
+ JspEditorPlugin.getPluginLog().logError(e.getMessage());
+ }
+ }
+
+ /**
+ * get mapping key is label ( label = class name + sequence number of such
+ * css class ) value is CSSStyleRule
+ *
+ * now rule mapping is generated always ... keeping of ruleMapping is more
+ * right but it demands more complex synchronization data
+ *
+ */
+ private Map<String, CSSStyleRule> getRulesMapping() {
+
+ Map<String, CSSStyleRule> rulesMapping = new HashMap<String,
CSSStyleRule>();
+ if (styleSheet != null) {
+ CSSRuleList list = styleSheet.getCssRules();
+
+ Map<String, Integer> frequencyMap = new HashMap<String, Integer>();
+
+ if (list != null) {
+ for (int i = 0; i < list.getLength(); i++) {
+ if (list.item(i) instanceof CSSStyleRule) {
+
+ CSSStyleRule rule = ((CSSStyleRule) list.item(i));
+
+ Integer freq = frequencyMap.get(rule.getSelectorText());
+
+ freq = freq == null ? 1 : freq + 1;
+
+ frequencyMap.put(rule.getSelectorText(), freq);
+
+ String ruleLabel = rule.getSelectorText()
+ + (freq > 1 ? Constants.START_BRACKET + freq
+ + Constants.END_BRACKET
+ : Constants.EMPTY);
+
+ rulesMapping.put(ruleLabel, rule);
+
+ }
+ }
+ }
+
+ }
+
+ return rulesMapping;
+ }
+
+ public IDocument getStructuredDocument() {
+ return model.getStructuredDocument();
+ }
+
+ public void reload() {
+ try {
+ if(model.isDirty()) {
+ model.reload(new FileInputStream(styleFile.getLocation().toFile()));
+ }
+ } catch (Exception e) {
+ JspEditorPlugin.getPluginLog().logError(e.getMessage());
+ }
+
+ }
+
+ public String getSelectorByPosition(Point selectionInFile) {
+
+ ICSSNode node = (ICSSNode) model.getIndexedRegion(selectionInFile.x);
+
+ while (node != null) {
+
+ if (node.getNodeType() == ICSSNode.STYLERULE_NODE) {
+ break;
+ } else if (node.getNodeType() == ICSSNode.STYLESHEET_NODE) {
+ node = ((ICSSStyleSheet) node).getFirstChild();
+ break;
+ }
+
+ node = node.getParentNode();
+ }
+
+ Object rules= getRulesMapping();
+ if (node != null)
+ for (Entry<String, CSSStyleRule> rule : getRulesMapping()
+ .entrySet()) {
+ if (node.equals(rule.getValue()))
+ return rule.getKey();
+ }
+ return null;
+ }
+}
Modified:
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/common/CSSValidator.java
===================================================================
---
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/common/CSSValidator.java 2009-03-19
09:19:53 UTC (rev 14262)
+++
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/common/CSSValidator.java 2009-03-19
13:36:13 UTC (rev 14263)
@@ -1,135 +1,159 @@
-/*******************************************************************************
- * Copyright (c) 2007-2009 Exadel, Inc. and Red Hat, Inc.
- * Distributed under license by Red Hat, Inc. All rights reserved.
- * This program is made available under the terms of the
- * Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at
http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Exadel, Inc. and Red Hat, Inc. - initial API and implementation
- ******************************************************************************/
-package org.jboss.tools.jst.jsp.outline.cssdialog.common;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-
-import org.eclipse.wst.css.core.internal.provisional.document.ICSSModel;
-import org.eclipse.wst.sse.core.StructuredModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
-import org.jboss.tools.jst.jsp.JspEditorPlugin;
-import org.w3c.dom.css.CSSStyleDeclaration;
-import org.w3c.dom.css.CSSStyleRule;
-import org.w3c.dom.css.CSSStyleSheet;
-
-/**
- * CSS Validator
- *
- * @author yradtsevich
- *
- */
-public class CSSValidator {
- // FIXME: this hard-coded string have to be replaced by reference
- private static final String CSS_CONTENT_TYPE_IDENTIFIER =
"org.eclipse.wst.css.core.csssource"; //$NON-NLS-1$
- private final CSSStyleSheet validatingCSS;
- private final LogHacker logHacker = new LogHacker();
-
- @SuppressWarnings("restriction")
- public CSSValidator() {
- IModelManager modelManager = StructuredModelManager.getModelManager();
- ICSSModel validatingModel = (ICSSModel)
modelManager.createUnManagedStructuredModelFor(CSS_CONTENT_TYPE_IDENTIFIER);
-
- validatingCSS = (CSSStyleSheet) validatingModel.getDocument();
- }
-
- private void cleanValidatingCSS() {
- int ruleNumber;
-
- while ((ruleNumber = validatingCSS.getCssRules().getLength()) > 0) {
- validatingCSS.deleteRule(ruleNumber - 1);
- }
- }
-
- /**
- * Validates value of a CSS attribute.
- *
- * @param value the
- * @return {@code true} if the attribute is valid, {@code false} otherwise
- */
- public boolean isValidValue(String value) {
- logHacker.disableLogging();
- boolean valid = true;
- try {
- validatingCSS.insertRule(".testSelector {}", 0); //$NON-NLS-1$
- CSSStyleRule cssRule = ((CSSStyleRule) validatingCSS.getCssRules().item(0));
- CSSStyleDeclaration declaration = cssRule.getStyle();
- declaration.setProperty("background", value, Constants.EMPTY);
//$NON-NLS-1$
- } catch (Throwable e) {
- valid = false;
- } finally {
- logHacker.enableLogging();
- cleanValidatingCSS();
- }
-
- return valid;
- }
-
- /**
- * Validates CSS selector value.
- *
- * @param selector the selector value
- * @return {@code true} if the selector is valid, {@code false} otherwise
- */
- public boolean isValidSelector(String selector) {
- boolean valid = true;
- try {
- validatingCSS.insertRule(selector + " {}", 0); //$NON-NLS-1$
- } catch (Throwable e) {
- valid = false;
- } finally {
- cleanValidatingCSS();
- }
-
- return valid;
- }
-
- /**
- * Gives opportunity to delete all loggers from {@link
org.eclipse.core.internal.runtime.RuntimeLog}
- *
- * @author yradtsevich
- *
- */
- private class LogHacker {
- private Field logListeners = null;
- private Object oldValue = null;
-
- public LogHacker() {
- try {
- logListeners =
org.eclipse.core.internal.runtime.RuntimeLog.class.getDeclaredField("logListeners");
- logListeners.setAccessible(true);
- } catch (Throwable e) {
- JspEditorPlugin.getPluginLog().logError(e);
- }
- }
-
- public void disableLogging() {
- try {
- oldValue = logListeners.get(null);
- logListeners.set(null, new ArrayList(0));
- } catch (Throwable e) {
- JspEditorPlugin.getPluginLog().logError(e);
- }
- }
-
- public void enableLogging() {
- try {
- if (oldValue != null) {
- logListeners.set(null, oldValue);
- }
- } catch (Throwable e) {
- JspEditorPlugin.getPluginLog().logError(e);
- } finally {
- oldValue = null;
- }
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2007-2009 Exadel, Inc. and Red Hat, Inc.
+ * Distributed under license by Red Hat, Inc. All rights reserved.
+ * This program is made available under the terms of the
+ * Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at
http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Exadel, Inc. and Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.jst.jsp.outline.cssdialog.common;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+
+import org.eclipse.wst.css.core.internal.provisional.document.ICSSModel;
+import org.eclipse.wst.sse.core.StructuredModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
+import org.jboss.tools.jst.jsp.JspEditorPlugin;
+import org.w3c.dom.css.CSSRuleList;
+import org.w3c.dom.css.CSSStyleDeclaration;
+import org.w3c.dom.css.CSSStyleRule;
+import org.w3c.dom.css.CSSStyleSheet;
+
+/**
+ * CSS Validator
+ *
+ * @author yradtsevich
+ *
+ */
+@SuppressWarnings("restriction")
+public class CSSValidator {
+ // FIXME: this hard-coded string have to be replaced by reference
+ private static final String CSS_CONTENT_TYPE_IDENTIFIER =
"org.eclipse.wst.css.core.csssource"; //$NON-NLS-1$
+ private final CSSStyleSheet validatingCSS;
+ private final IStructuredDocument validatingDocument;
+ private final LogHacker logHacker = new LogHacker();
+ private static Reference<CSSValidator> instanceCache;
+
+ public static CSSValidator getInstance() {
+ CSSValidator instance = null;
+ if (instanceCache != null) {
+ instance = instanceCache.get();
+ }
+ if (instance == null) {
+ instance = new CSSValidator();
+ instanceCache = new SoftReference<CSSValidator>(instance);
+ }
+ return instance;
+ }
+
+ private CSSValidator() {
+ IModelManager modelManager = StructuredModelManager.getModelManager();
+ ICSSModel validatingModel = (ICSSModel) modelManager
+ .createUnManagedStructuredModelFor(CSS_CONTENT_TYPE_IDENTIFIER);
+ validatingDocument = validatingModel.getStructuredDocument();
+ validatingCSS = (CSSStyleSheet) validatingModel.getDocument();
+ }
+
+ private void cleanValidatingDocument() {
+ validatingDocument.set(""); //$NON-NLS-1$
+ }
+
+ /**
+ * Validates value of a CSS attribute.
+ *
+ * @param value the value of a CSS attribute
+ * @return {@code true} if the attribute is valid, {@code false} otherwise
+ */
+ public boolean isValidValue(String value) {
+ logHacker.disableLogging();
+ boolean valid = true;
+ try {
+ validatingCSS.insertRule(".testSelector {}", 0); //$NON-NLS-1$
+ CSSStyleRule cssRule = ((CSSStyleRule) validatingCSS.getCssRules().item(0));
+ CSSStyleDeclaration declaration = cssRule.getStyle();
+ declaration.setProperty("background", value, Constants.EMPTY);
//$NON-NLS-1$
+ } catch (Throwable e) {
+ valid = false;
+ } finally {
+ logHacker.enableLogging();
+ cleanValidatingDocument();
+ }
+
+ return valid;
+ }
+
+ /**
+ * Validates CSS selector value.
+ *
+ * @param selector the selector value
+ * @return {@code true} if the selector is valid, {@code false} otherwise
+ */
+ public boolean isValidSelector(String selector) {
+ validatingDocument.set(selector + "{}"); //$NON-NLS-1$
+
+ CSSRuleList cssRules = validatingCSS.getCssRules();
+ if (cssRules.getLength() != 1) {
+ // if the selector is like 'a{} b', or it is empty, or the rule cannot be
created
+ return false;
+ }
+
+ CSSStyleRule cssRule = (CSSStyleRule) cssRules.item(0);
+ if (!selector.equals(cssRule.getSelectorText())) {
+ // if the selector is like 'a{{{'
+ return false;
+ }
+
+ cleanValidatingDocument();
+
+ return true;
+ }
+
+ /**
+ * Provides a way to temporarily delete all loggers from
+ * {@link org.eclipse.core.internal.runtime.RuntimeLog}
+ *
+ * @author yradtsevich
+ *
+ */
+ private class LogHacker {
+ private Field logListeners = null;
+ private Object oldValue = null;
+
+ public LogHacker() {
+ try {
+ logListeners = org.eclipse.core.internal.runtime.RuntimeLog.class
+ .getDeclaredField("logListeners");
+ logListeners.setAccessible(true);
+ } catch (Throwable e) {
+ JspEditorPlugin.getPluginLog().logError(e);
+ }
+ }
+
+ public void disableLogging() {
+ try {
+ oldValue = logListeners.get(null);
+ logListeners.set(null, new ArrayList<Object>(0));
+ } catch (Throwable e) {
+ JspEditorPlugin.getPluginLog().logError(e);
+ }
+ }
+
+ public void enableLogging() {
+ try {
+ if (oldValue != null) {
+ logListeners.set(null, oldValue);
+ }
+ } catch (Throwable e) {
+ JspEditorPlugin.getPluginLog().logError(e);
+ } finally {
+ oldValue = null;
+ }
+ }
+ }
+}
Modified:
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/events/StyleAttributes.java
===================================================================
---
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/events/StyleAttributes.java 2009-03-19
09:19:53 UTC (rev 14262)
+++
branches/jbosstools-3.0.x/jst/plugins/org.jboss.tools.jst.jsp/src/org/jboss/tools/jst/jsp/outline/cssdialog/events/StyleAttributes.java 2009-03-19
13:36:13 UTC (rev 14263)
@@ -33,7 +33,7 @@
*/
public StyleAttributes() {
this.attributeMap = new HashMap<String, String>();
- cssValidator = new CSSValidator();
+ cssValidator = CSSValidator.getInstance();
}
/**