433 lines
18 KiB
Java
Executable File
433 lines
18 KiB
Java
Executable File
/*
|
|
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public License
|
|
* as published by the Free Software Foundation; either version 2.1 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
*/
|
|
package com.arsdigita.cms.ui.authoring;
|
|
|
|
|
|
import com.arsdigita.bebop.ActionLink;
|
|
import com.arsdigita.bebop.FormProcessException;
|
|
import com.arsdigita.bebop.Label;
|
|
import com.arsdigita.bebop.Page;
|
|
import com.arsdigita.bebop.PageState;
|
|
import com.arsdigita.bebop.SimpleContainer;
|
|
import com.arsdigita.bebop.event.ActionEvent;
|
|
import com.arsdigita.bebop.event.ActionListener;
|
|
import com.arsdigita.bebop.event.FormProcessListener;
|
|
import com.arsdigita.bebop.event.FormSectionEvent;
|
|
import com.arsdigita.bebop.event.FormSubmissionListener;
|
|
import com.arsdigita.bebop.parameters.BigDecimalParameter;
|
|
import com.arsdigita.bebop.parameters.StringParameter;
|
|
import com.arsdigita.cms.contenttypes.GenericArticle;
|
|
import com.arsdigita.cms.ImageAsset;
|
|
import com.arsdigita.cms.ImageAssetCollection;
|
|
import com.arsdigita.cms.ItemSelectionModel;
|
|
import com.arsdigita.cms.dispatcher.Utilities;
|
|
import com.arsdigita.cms.ui.ArticleImageDisplay;
|
|
import com.arsdigita.cms.ui.CMSContainer;
|
|
import com.arsdigita.cms.ui.ContentItemPage;
|
|
import com.arsdigita.cms.ui.ImageChooser;
|
|
import com.arsdigita.cms.ui.SecurityPropertyEditor;
|
|
import com.arsdigita.cms.ui.SingleImageSelectionModel;
|
|
import com.arsdigita.cms.ui.workflow.WorkflowLockedComponentAccess;
|
|
import com.arsdigita.cms.ui.workflow.WorkflowLockedContainer;
|
|
import com.arsdigita.cms.util.GlobalizationUtil;
|
|
import com.arsdigita.util.Assert;
|
|
import com.arsdigita.xml.Element;
|
|
import org.apache.log4j.Logger;
|
|
|
|
|
|
/**
|
|
* Display the image associated with the article (if any),
|
|
* and present UI controls for associating a new image.
|
|
* This component contains two {@link PropertyEditor}
|
|
* instances: one instance that shows up when the article has
|
|
* no associated image, and another instance that shows up when
|
|
* the article has at least one image.
|
|
* <p>
|
|
* This class actually contains four inner classes:
|
|
* <ul>
|
|
* <li>ImageUploadForm: a form for uploading a new image</li>
|
|
* <li>ImagePropertiesForm: a form for editing width/height/caption</li>
|
|
* <li>ArticleImagePane: an {@link com.arsdigita.cms.ui.ItemPropertySheet}
|
|
* which displays the properties of an image</li>
|
|
* <li>ArticleImageChooser: a {@link SimpleComponent} that contains
|
|
* an {@link ImageChooser} and an <code>ImageSelectionForm</code> (which
|
|
* is another inner class). The <code>ArticleImageChooser</code>
|
|
* uses the {@link ImageChooser} to select an image, then shows the
|
|
* form in order to assign a caption to the image and complete the
|
|
* image selection process.
|
|
* </li>
|
|
* </ul>
|
|
*
|
|
* @author Stanislav Freidin (sfreidin@arsdigita.com)
|
|
* @author Michael Pih (pihman@arsdigita.com)
|
|
* @version $Revision: #20 $ $DateTime: 2004/08/17 23:15:09 $
|
|
* @version $Id: ArticleImage.java 754 2005-09-02 13:26:17Z sskracic $
|
|
*/
|
|
public class ArticleImage extends SimpleContainer implements AuthoringStepComponent {
|
|
|
|
private static final String IMAGE_ASSET = "image_asset";
|
|
|
|
private static Logger s_log = Logger.getLogger(ArticleImage.class);
|
|
|
|
private final ItemSelectionModel m_article;
|
|
private final AuthoringKitWizard m_parent;
|
|
private SingleImageSelectionModel m_assets;
|
|
private BigDecimalParameter m_assetParam;
|
|
|
|
private ArticleWithoutImage m_noImagePane;
|
|
private ArticleImageChooser m_noImageChooser;
|
|
|
|
private ArticleWithImage m_imagePane;
|
|
private ArticleImageChooser m_imageChooser;
|
|
|
|
private StringParameter m_streamlinedCreationParam;
|
|
private static final String STREAMLINED = "_streamlined";
|
|
private static final String STREAMLINED_DONE = "1";
|
|
|
|
|
|
public ArticleImage(ItemSelectionModel itemModel,
|
|
AuthoringKitWizard parent) {
|
|
super();
|
|
|
|
m_parent = parent;
|
|
m_article = itemModel;
|
|
|
|
m_streamlinedCreationParam =
|
|
new StringParameter(parent.getContentType().getAssociatedObjectType() + "_image_done");
|
|
|
|
// Add the asset selection model
|
|
m_assetParam = new BigDecimalParameter(IMAGE_ASSET);
|
|
m_assets = new SingleImageSelectionModel(m_assetParam, m_article);
|
|
|
|
|
|
// This panel will be shown if there is no image selected.
|
|
m_noImagePane = new ArticleWithoutImage(m_article, m_assets);
|
|
m_noImageChooser = m_noImagePane.getChooser();
|
|
final ImageSelectionForm noImageForm = m_noImageChooser.getImageSelectionForm();
|
|
noImageForm.addProcessListener(new FormProcessListener() {
|
|
public void process(FormSectionEvent event)
|
|
throws FormProcessException {
|
|
PageState state = event.getPageState();
|
|
m_imagePane.showDisplayPane(state);
|
|
maybeForwardToNextStep(state);
|
|
}
|
|
});
|
|
noImageForm.addSubmissionListener(new FormSubmissionListener() {
|
|
public void submitted(FormSectionEvent event) throws FormProcessException {
|
|
PageState state = event.getPageState();
|
|
if (noImageForm.getSaveCancelSection().getCancelButton()
|
|
.isSelected( state)) {
|
|
cancelStreamlinedCreation(state);
|
|
}
|
|
}
|
|
});
|
|
add(m_noImagePane);
|
|
|
|
m_imagePane = new ArticleWithImage(m_article, m_assets);
|
|
m_imageChooser = m_imagePane.getChooser();
|
|
final ImageSelectionForm imageForm = m_imageChooser.getImageSelectionForm();
|
|
imageForm.addProcessListener(new FormProcessListener() {
|
|
public void process(FormSectionEvent event)
|
|
throws FormProcessException {
|
|
PageState state = event.getPageState();
|
|
m_imagePane.showDisplayPane(state);
|
|
maybeForwardToNextStep(state);
|
|
}
|
|
});
|
|
|
|
|
|
// Reset state of all sub-components
|
|
m_imagePane.getList().addActionListener(new ActionListener() {
|
|
public void actionPerformed(ActionEvent e) {
|
|
PageState state = e.getPageState();
|
|
m_imageChooser.deselectImage(state);
|
|
m_imageChooser.getImageChooser().clearKeyword(state);
|
|
m_noImageChooser.deselectImage(state);
|
|
m_noImageChooser.getImageChooser().clearKeyword(state);
|
|
}
|
|
});
|
|
imageForm.addSubmissionListener(new FormSubmissionListener() {
|
|
public void submitted(FormSectionEvent event) throws FormProcessException {
|
|
PageState state = event.getPageState();
|
|
if (imageForm.getSaveCancelSection().getCancelButton()
|
|
.isSelected( state)) {
|
|
cancelStreamlinedCreation(state);
|
|
}
|
|
}
|
|
});
|
|
|
|
add(m_imagePane);
|
|
|
|
// Reset the editing when this component becomes visible
|
|
parent.getList().addActionListener(new ActionListener() {
|
|
public void actionPerformed(ActionEvent event) {
|
|
PageState state = event.getPageState();
|
|
// get the image fresh from the db each time this component displays;
|
|
// otherwise rollback doesn't appear to work on this pane
|
|
GenericArticle art = (GenericArticle)(m_article.getSelectedObject(state));
|
|
ImageAssetCollection col = art.getImages();
|
|
ImageAsset img = null;
|
|
if (col.next()) {
|
|
img = col.getImage();
|
|
}
|
|
col.close();
|
|
m_assets.setSelectedObject(state, img);
|
|
m_imagePane.showDisplayPane(state);
|
|
m_imageChooser.deselectImage(state);
|
|
m_noImageChooser.deselectImage(state);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Create the image chooser
|
|
private ArticleImageChooser addChooser(SecurityPropertyEditor e) {
|
|
ArticleImageChooser c = new ArticleImageChooser(m_article, m_assets);
|
|
c.getImageSelectionForm().addProcessListener(
|
|
new FormProcessListener() {
|
|
public void process(FormSectionEvent param_e) throws FormProcessException {
|
|
m_imagePane.showDisplayPane(param_e.getPageState());
|
|
}
|
|
});
|
|
ImageChooser ch = c.getImageChooser();
|
|
e.addCancelListener(ch.getForm(), ch.getFormCancelButton());
|
|
e.addComponent("browse", "Select existing image",
|
|
new WorkflowLockedComponentAccess(c,m_article));
|
|
|
|
return c;
|
|
}
|
|
|
|
// Register the image id
|
|
public void register(Page p) {
|
|
p.addComponentStateParam(this, m_assetParam);
|
|
p.addGlobalStateParam(m_streamlinedCreationParam);
|
|
}
|
|
|
|
// Generate XML: Show either the image pane or the no image pane
|
|
public void generateXML(PageState state, Element parent) {
|
|
if(m_assets.getSelectedObject(state) == null) {
|
|
m_noImagePane.generateXML(state, parent);
|
|
} else {
|
|
m_imagePane.generateXML(state, parent);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return the parent wizard
|
|
*/
|
|
public AuthoringKitWizard getParentWizard() {
|
|
return m_parent;
|
|
}
|
|
|
|
/**
|
|
* @return The item selection model
|
|
*/
|
|
public ItemSelectionModel getItemSelectionModel() {
|
|
return m_article;
|
|
}
|
|
|
|
|
|
/**
|
|
* Forward to the next step if the streamlined creation parameter
|
|
* is turned on _and_ the streamlined_creation global state param
|
|
* is set to 'active'
|
|
*
|
|
* @param state the PageState
|
|
*/
|
|
public void maybeForwardToNextStep(PageState state) {
|
|
if (ContentItemPage.isStreamlinedCreationActive(state) &&
|
|
!STREAMLINED_DONE.equals(state.getValue(m_streamlinedCreationParam))) {
|
|
state.setValue(m_streamlinedCreationParam, STREAMLINED_DONE);
|
|
fireCompletionEvent(state);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Cancel streamlined creation for this step if the streamlined
|
|
* creation parameter is turned on _and_ the streamlined_creation
|
|
* global state param is set to 'active'
|
|
*
|
|
* @param state the PageState
|
|
*/
|
|
public void cancelStreamlinedCreation(PageState state) {
|
|
if (ContentItemPage.isStreamlinedCreationActive(state)) {
|
|
state.setValue(m_streamlinedCreationParam, STREAMLINED_DONE);
|
|
}
|
|
}
|
|
|
|
private class ArticleWithoutImage extends SecurityPropertyEditor {
|
|
|
|
private final ItemSelectionModel m_articleWithoutImage;
|
|
private final ItemSelectionModel m_assetsWithoutImage;
|
|
|
|
private ImageUploadForm m_uploadFormWithoutImage;
|
|
private ArticleImageChooser m_chooserWithoutImage;
|
|
|
|
public ArticleWithoutImage(ItemSelectionModel article,
|
|
ItemSelectionModel assets) {
|
|
super();
|
|
|
|
m_articleWithoutImage = article;
|
|
m_assetsWithoutImage = assets;
|
|
|
|
Label l = new Label(GlobalizationUtil.globalize("cms.ui.authoring.this_article_does_not_have_an_image"));
|
|
l.setFontWeight(Label.ITALIC);
|
|
setDisplayComponent(l);
|
|
|
|
m_uploadFormWithoutImage = new ImageUploadForm(m_articleWithoutImage,
|
|
m_assetsWithoutImage,
|
|
ArticleImage.this);
|
|
add("upload", "Upload a new image",
|
|
new WorkflowLockedComponentAccess(m_uploadFormWithoutImage, m_articleWithoutImage),
|
|
m_uploadFormWithoutImage.getSaveCancelSection().getCancelButton());
|
|
|
|
|
|
m_chooserWithoutImage = new ArticleImageChooser(m_articleWithoutImage, m_assetsWithoutImage);
|
|
ImageChooser imgChooser = m_chooserWithoutImage.getImageChooser();
|
|
addCancelListener(imgChooser.getForm(),
|
|
imgChooser.getFormCancelButton());
|
|
addComponent("browse", "Select existing image",
|
|
new WorkflowLockedComponentAccess(m_chooserWithoutImage, m_articleWithoutImage));
|
|
}
|
|
|
|
public ArticleImageChooser getChooser() {
|
|
return m_chooserWithoutImage;
|
|
}
|
|
}
|
|
|
|
|
|
private class ArticleWithImage extends SecurityPropertyEditor {
|
|
|
|
private final ItemSelectionModel m_articleWithImage;
|
|
private final ItemSelectionModel m_assetsWithImage;
|
|
|
|
private CMSContainer m_display;
|
|
|
|
private ActionLink m_editLink;
|
|
private ActionLink m_uploadLink;
|
|
private ActionLink m_selectLink;
|
|
private ActionLink m_removeLink;
|
|
|
|
private ImageUploadForm m_uploadFormWithImage;
|
|
private ImagePropertiesForm m_editFormWithImage;
|
|
private ArticleImageChooser m_chooserWithImage;
|
|
|
|
public ArticleWithImage(ItemSelectionModel article,
|
|
ItemSelectionModel assets) {
|
|
super();
|
|
|
|
m_articleWithImage = article;
|
|
m_assetsWithImage = assets;
|
|
|
|
// This panel will be shown if there is an image.
|
|
m_display = new CMSContainer();
|
|
m_display.add(new ArticleImageDisplay(m_articleWithImage, m_assetsWithImage));
|
|
|
|
// The "edit caption" link.
|
|
m_editLink = new ActionLink( (String) GlobalizationUtil.globalize("cms.ui.authoring.edit_caption").localize());
|
|
m_editLink.setClassAttr("actionLink");
|
|
m_editLink.setIdAttr("edit_link");
|
|
m_display.add(new WorkflowLockedContainer(m_editLink, m_articleWithImage));
|
|
|
|
// The "upload image" link.
|
|
m_uploadLink = new ActionLink( (String) GlobalizationUtil.globalize("cms.ui.authoring.upload_a_new_image").localize());
|
|
m_uploadLink.setClassAttr("actionLink");
|
|
m_uploadLink.setIdAttr("upload_link");
|
|
m_display.add(new WorkflowLockedContainer(m_uploadLink, m_articleWithImage));
|
|
|
|
// The "select a new image" link.
|
|
m_selectLink = new ActionLink( (String) GlobalizationUtil.globalize("cms.ui.authoring.select_an_existing_image").localize());
|
|
m_selectLink.setClassAttr("actionLink");
|
|
m_selectLink.setIdAttr("select_link");
|
|
m_display.add(new WorkflowLockedContainer(m_selectLink, m_articleWithImage));
|
|
|
|
// The "remove image" link.
|
|
m_removeLink = new ActionLink( (String) GlobalizationUtil.globalize("cms.ui.authoring.remove_image").localize());
|
|
m_removeLink.setClassAttr("actionLink");
|
|
m_removeLink.setIdAttr("remove_image_link");
|
|
m_removeLink.setConfirmation("Are you sure you wish to " +
|
|
"remove this image from the article?");
|
|
m_removeLink.addActionListener(new ActionListener() {
|
|
public void actionPerformed(ActionEvent event) {
|
|
PageState state = event.getPageState();
|
|
ImageAsset img = getImageAsset(state);
|
|
GenericArticle articleTarget = getArticle(state);
|
|
articleTarget.removeImage(img);
|
|
articleTarget.save();
|
|
m_assetsWithImage.setSelectedObject(state, null);
|
|
m_imageChooser.deselectImage(state);
|
|
m_imageChooser.getImageChooser().clearKeyword(state);
|
|
m_noImageChooser.deselectImage(state);
|
|
m_noImageChooser.getImageChooser().clearKeyword(state);
|
|
m_noImagePane.showDisplayPane(event.getPageState());
|
|
Utilities.disableBrowserCache(state.getResponse());
|
|
}
|
|
});
|
|
m_display.add(new WorkflowLockedContainer(m_removeLink, m_articleWithImage));
|
|
setDisplayComponent(m_display);
|
|
|
|
// The edit form.
|
|
m_editFormWithImage = new ImagePropertiesForm(m_articleWithImage, m_assetsWithImage);
|
|
addComponent("edit",
|
|
new WorkflowLockedComponentAccess(m_editFormWithImage, m_articleWithImage));
|
|
addListeners(m_editFormWithImage,
|
|
m_editFormWithImage.getSaveCancelSection().getCancelButton());
|
|
addVisibilityListener(m_editLink, "edit");
|
|
|
|
// The upload form.
|
|
m_uploadFormWithImage = new ImageUploadForm(m_articleWithImage,
|
|
m_assetsWithImage,
|
|
ArticleImage.this);
|
|
addComponent("upload",
|
|
new WorkflowLockedComponentAccess(m_uploadFormWithImage, m_articleWithImage));
|
|
addListeners(m_uploadFormWithImage,
|
|
m_uploadFormWithImage.getSaveCancelSection().getCancelButton());
|
|
addVisibilityListener(m_uploadLink, "upload");
|
|
|
|
// The select form.
|
|
m_chooserWithImage = new ArticleImageChooser(m_articleWithImage, m_assetsWithImage);
|
|
ImageChooser imgChooser = m_chooserWithImage.getImageChooser();
|
|
addCancelListener(imgChooser.getForm(),
|
|
imgChooser.getFormCancelButton());
|
|
addComponent("browse",
|
|
new WorkflowLockedComponentAccess(m_chooserWithImage, m_articleWithImage));
|
|
addVisibilityListener(m_selectLink, "browse");
|
|
}
|
|
|
|
public ArticleImageChooser getChooser() {
|
|
return m_chooserWithImage;
|
|
}
|
|
|
|
private ImageAsset getImageAsset(PageState state) {
|
|
ImageAsset image = (ImageAsset) m_assetsWithImage.getSelectedObject(state);
|
|
Assert.exists(image, "Image asset");
|
|
return image;
|
|
}
|
|
|
|
private GenericArticle getArticle(PageState state) {
|
|
GenericArticle article = (GenericArticle) m_articleWithImage.getSelectedObject(state);
|
|
Assert.exists(article, "GenericArticle");
|
|
return article;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|