BaseContact

Weitere Teile der UI fertig.

git-svn-id: https://svn.libreccm.org/ccm/trunk@212 8810af33-2d31-482b-a856-94f89814c4df
master
quasi 2009-07-15 09:35:29 +00:00
parent 6009b2e14e
commit eeb54a874c
3 changed files with 618 additions and 0 deletions

View File

@ -0,0 +1,264 @@
/*
* Copyright (C) 2008 Sören Bernstein 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.category;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.ControlLink;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.event.TableActionListener;
import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.table.TableColumn;
import com.arsdigita.bebop.table.TableColumnModel;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.categorization.Category;
import com.arsdigita.categorization.CategoryLocalization;
import com.arsdigita.categorization.CategoryLocalizationCollection;
import com.arsdigita.cms.SecurityManager;
import com.arsdigita.cms.dispatcher.Utilities;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.util.LockableImpl;
import java.math.BigDecimal;
import java.util.Locale;
/**
* Lists all existing contact entries for a selected contact.
*
* @author Sören Bernstein (quasimodo) quasi@barkhof.uni-bremen.de
*/
public class BaseContactEntriesTable extends Table {
private final String TABLE_COL_EDIT = "table_col_lang";
private final String TABLE_COL_DEL = "table_col_del";
/**
* Creates a new instance of BaseContactEntriesTable
*/
public BaseContactEntriesTable(final ItemSelectionModel itemModel, AuthoringKitWizard parent) {
super();
this.m_itemModel = itemModel;
// if table is empty:
setEmptyView(new Label(GlobalizationUtil.globalize("cms.contenttypes.ui.baseContact.contactentries.none")));
TableColumnModel tab_model = getColumnModel();
// define columns
// XXX globalize
tab_model.add(new TableColumn(0, GlobalizationUtil.globalize("cms.contenttypes.ui.baseContact.contactentries.key").localize(), TABLE_COL_EDIT));
tab_model.add(new TableColumn(1, GlobalizationUtil.globalize("cms.contenttypes.ui.baseContact.contactentries.value").localize()));
tab_model.add(new TableColumn(2, GlobalizationUtil.globalize("cms.contenttypes.ui.baseContact.contactentries.delete").localize(), TABLE_COL_DEL));
setModelBuilder(new BaseContactTableModelBuilder());
tab_model.get(0).setCellRenderer(new EditCellRenderer());
tab_model.get(2).setCellRenderer(new DeleteCellRenderer());
addTableActionListener(this);
}
/**
* XXXX
*
*/
private class BaseContactTableModelBuilder extends LockableImpl implements TableModelBuilder {
public TableModel makeModel(Table table, PageState state) {
//XXX
final BaseContact baseContact = m_category.getCategory(state);
if (baseContact != null && baseContact.hasContactEntries()) {
return new BaseContactTableModel(table, state, category);
} else {
return Table.EMPTY_MODEL;
}
}
}
/**
* XXX
*
*/
private class BaseContactTableModel implements TableModel {
final private int MAX_DESC_LENGTH = 25;
private Table m_table;
private BaseContactEntryCollection m_baseContactEntryCollection;
private BaseContactEntry m_baseContactEntry;
private BaseContactTableModel(Table t, PageState ps, BaseContact baseContact) {
m_table = t;
m_baseContactEntryColletion = new BaseContactEntryCollection(baseContact);
}
public int getColumnCount() {
return m_table.getColumnModel().size();
}
/**
* Check collection for the existence of another row.
*
* If exists, fetch the value of current BaseContactEntryCollection object
* into m_baseContactEntry class variable.
*/
public boolean nextRow() {
if(m_baseContactEntryCollection != null && m_baseContactEntryCollection.next()){
m_baseContactEntry = m_baseContactEntryCollection.getBaseContactEntry();
return true;
} else {
return false;
}
}
/**
* Return the
* @see com.arsdigita.bebop.table.TableModel#getElementAt(int)
*/
public Object getElementAt(int columnIndex) {
switch (columnIndex){
case 0:
return m_baseContactEntry.getKey();
case 1:
return m_baseContactEntry.getValue();
case 2:
return GlobalizationUtil.globalize("cms.ui.delete").localize();
default:
return null;
}
}
/**
*
* @see com.arsdigita.bebop.table.TableModel#getKeyAt(int)
*/
public Object getKeyAt(int columnIndex) {
return m_baseContactEntry.getID();
}
}
/**
* Check for the permissions to edit item and put either a Label or
* a ControlLink accordingly.
*/
private class EditCellRenderer extends LockableImpl implements TableCellRenderer {
public Component getComponent(Table table, PageState state, Object value,
boolean isSelected, Object key,
int row, int column) {
SecurityManager sm = Utilities.getSecurityManager(state);
// CategoryLocalization cl =
// (CategoryLocalization) m_clSel.getSelectedObject(state);
// boolean canEdit = sm.canAccess(state.getRequest(),
// SecurityManager.DELETE_ITEM,
// cl);
// if(canEdit) {
if(true) {
ControlLink link = new ControlLink(value.toString());
return link;
} else {
return new Label(value.toString());
}
}
}
/**
* Check for the permissions to delete item and put either a Label or
* a ControlLink accordingly.
*/
private class DeleteCellRenderer extends LockableImpl implements TableCellRenderer {
public Component getComponent(Table table, PageState state, Object value,
boolean isSelected, Object key,
int row, int column) {
// SecurityManager sm = Utilities.getSecurityManager(state);
// CategoryLocalization categoryLocalization =
// new CategoryLocalization(new BigDecimal(evt.getRowKey().toString()));
// boolean canDelete = sm.canAccess(state.getRequest(),
// SecurityManager.DELETE_ITEM,
// categoryLocalization);
// if(canDelete) {
if(true) {
ControlLink link = new ControlLink(value.toString());
link.setConfirmation((String) GlobalizationUtil.globalize(
"cms.ui.category.localization.confirm_delete").localize());
return link;
} else {
return new Label(value.toString());
}
}
}
/**
* Provide implementation to TableActionListener method.
* Code that comes into picture when a link on the table is clicked.
* Handles edit and delete event.
*/
public void cellSelected(TableActionEvent evt) {
PageState state = evt.getPageState();
// Get selected BaseContactEntry
BaseContactEntry baseContactEntry =
new BaseContactEntry(new BigDecimal(evt.getRowKey().toString()));
// Get BaseContact
// XXX
BaseContact baseContact = m_baseContact.getCategory(state);
// Get selected column
TableColumn col = getColumnModel().get(evt.getColumn().intValue());
// Edit
if(col.getHeaderKey().toString().equals(TABLE_COL_EDIT)) {
}
// Delete
if(col.getHeaderKey().toString().equals(TABLE_COL_DEL)) {
baseContact.delContactEntry(baseContactEntry.getID());
}
}
/**
* provide Implementation to TableActionListener method.
* Does nothing in our case.
*/
public void headSelected(TableActionEvent e) {
throw new UnsupportedOperationException("Not Implemented");
}
}

View File

@ -0,0 +1,137 @@
/*
* Copyright (C) 2008 Sören Bernstein 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.category;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.form.Option;
import com.arsdigita.categorization.CategorizationConfig;
import com.arsdigita.categorization.Category;
import com.arsdigita.dispatcher.AccessDeniedException;
import com.arsdigita.cms.util.GlobalizationUtil;
import java.util.Locale;
import java.util.StringTokenizer;
import org.apache.log4j.Logger;
/**
* Generates a form for creating new localisations for the given category.
*
* This class is part of the admin GUI of CCM and extends the standard form
* in order to present forms for managing the multi-language categories.
*
* @author Sören Bernstein (quasimodo) quasi@zes.uni-bremen.de
*/
public class CategoryLocalizationAddForm extends CategoryLocalizationForm {
public static final String versionId =
"$Id: CategoryLocalizationAddForm.java 287 2005-02-22 00:29:02Z sskracic $" +
"$Author: sskracic $" +
"$DateTime: 2004/08/17 23:15:09 $";
private static final Logger s_log = Logger.getLogger
(CategoryAddForm.class);
/** Creates a new instance of CategoryLocalizationAddForm */
public CategoryLocalizationAddForm(final CategoryRequestLocal category) {
super("AddCategoryLocalization",
gz("cms.ui.category.localization.add"), category);
addInitListener(new InitListener());
addProcessListener(new ProcessListener());
}
// Deaktivate this widget, if category is root
// public boolean isVisible(PageState state) {
// return !m_category.getCategory(state).isRoot();
// }
private class InitListener implements FormInitListener {
public final void init(final FormSectionEvent e)
throws FormProcessException {
final PageState state = e.getPageState();
final Category category = m_category.getCategory(state);
// Select one entry
m_locale.addOption(new Option("",
new Label((String) GlobalizationUtil.globalize(
"cms.ui.select_one").localize())), state);
// all supported languages (by registry entry)
CategorizationConfig catConfig = new CategorizationConfig();
StringTokenizer strTok = catConfig.getSupportedLanguages();
while(strTok.hasMoreTokens()) {
String code = strTok.nextToken();
// If lanuage exists, remove it from the selection list
if(!category.getCategoryLocalizationCollection().
localizationExists(code)) {
m_locale.addOption(new Option(code,
new Locale(code).getDisplayLanguage()), state);
}
}
}
}
private final class ProcessListener implements FormProcessListener {
public final void process(final FormSectionEvent e)
throws FormProcessException {
s_log.debug("Adding a categoryLocalization to category " + m_category);
final PageState state = e.getPageState();
final Category category = m_category.getCategory(state);
final String locale = (String) m_locale.getValue(state);
final String name = (String) m_name.getValue(state);
final String description = (String) m_description.getValue(state);
final String url = (String) m_url.getValue(state);
final String isEnabled = (String) m_isEnabled.getValue(state);
// Was soll das??
//Assert.assertNotNull(parent, "Category parent");
if (s_log.isDebugEnabled()) {
s_log.debug("Adding localization for locale " + locale +
" to category " + category);
}
if (category.canEdit()) {
category.addLanguage(locale, name, description, url);
category.setEnabled("yes".equals(isEnabled), locale);
category.save();
} else {
// XXX user a better exception here.
// PermissionException doesn't work for this case.
throw new AccessDeniedException();
}
}
}
}

View File

@ -0,0 +1,217 @@
/*
* Copyright (C) 2008 Sören Bernstein 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.category;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.ParameterEvent;
import com.arsdigita.bebop.event.ParameterListener;
import com.arsdigita.bebop.form.Option;
import com.arsdigita.bebop.form.RadioGroup;
import com.arsdigita.bebop.form.SingleSelect;
import com.arsdigita.bebop.form.TextArea;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.bebop.form.Widget;
import com.arsdigita.bebop.parameters.NotNullValidationListener;
import com.arsdigita.bebop.parameters.ParameterData;
import com.arsdigita.bebop.parameters.ParameterModel;
import com.arsdigita.bebop.parameters.StringInRangeValidationListener;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.bebop.parameters.TrimmedStringParameter;
import com.arsdigita.categorization.Category;
import com.arsdigita.categorization.CategoryCollection;
import com.arsdigita.cms.ui.BaseForm;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.xml.Element;
/**
* Base class for CategoryLocalizationAddForm and CategoryLocalizationEditForm.
*
* This class is part of the admin GUI of CCM and extends the standard form
* in order to present forms for managing the multi-language categories.
*
* @author Sören Bernstein (quasimodo) quasi@zes.uni-bremen.de
*/
public class CategoryLocalizationForm extends BaseForm {
final CategoryRequestLocal m_category;
final SingleSelect m_locale;
final TextField m_name;
final TextArea m_description;
final TextField m_url;
final RadioGroup m_isEnabled;
private Label m_script = new Label(
"<script language=\"javascript\" src=\"/javascript/manipulate-input.js\">"+
"</script>", false);
private final static String LOCALE = "locale";
private final static String NAME = "name";
private final static String DESCRIPTION = "description";
private final static String URL = "url";
private final static String IS_ENABLED = "isEnabled";
/**
* Creates a new instance of CategoryLocalizationForm.
*
*/
public CategoryLocalizationForm(final String key,
final GlobalizedMessage heading,
final CategoryRequestLocal category) {
super(key, heading);
m_category = category;
// Parameter-Model for SingleSelect
ParameterModel localeParam = new StringParameter(LOCALE);
localeParam.addParameterListener(new StringInRangeValidationListener(0, 2));
m_locale = new SingleSelect(localeParam);
m_locale.addValidationListener(new ParameterListener() {
public void validate(ParameterEvent e) throws FormProcessException {
// the --select one-- option is not allowed
ParameterData data = e.getParameterData();
String code = (String) data.getValue() ;
if (code == null || code.length() == 0) {
data.addError(
(String)GlobalizationUtil.globalize(
"cms.ui.category.localization.error_locale").localize());
}
}
});
addField(gz("cms.ui.category.localization.locale"), m_locale);
m_name = new TextField(new TrimmedStringParameter(NAME));
addField(gz("cms.ui.name"), m_name);
m_name.setSize(30);
m_name.setMaxLength(200);
m_name.addValidationListener(new NotNullValidationListener());
m_name.setOnFocus("if (this.form." + URL + ".value == '') { " +
" defaulting = true; this.form." + URL +
".value = urlize(this.value); }");
m_name.setOnKeyUp("if (defaulting) { this.form." + URL +
".value = urlize(this.value) }");
// is enabled?
m_isEnabled = new RadioGroup(IS_ENABLED);
m_isEnabled.addOption(new Option("no", new Label(gz("cms.ui.no"))));
m_isEnabled.addOption(new Option("yes", new Label(gz("cms.ui.yes"))));
addField(gz("cms.ui.category.is_enabled"),m_isEnabled);
m_description = new TextArea
(new TrimmedStringParameter(DESCRIPTION));
addField(gz("cms.ui.description"), m_description);
m_description.setWrap(TextArea.SOFT);
m_description.setRows(5);
m_description.setCols(40);
// URL
// JavaScript auto-url generation is off by default.
// It is turned on under the following circumstances
//
// * If the url is null, upon starting edit of the title
// * If the url is null, upon finishing edit of name
//
// The rationale is that, auto-url generation is useful
// if the url is currently null, but once a name has been
// created you don't want to subsequently change it since
// it breaks URLs & potentially overwrites the user's
// customizations.
m_url = new TextField(new TrimmedStringParameter(URL));
m_url.setSize(30);
m_url.setMaxLength(200);
m_url.addValidationListener(new NotNullValidationListener());
m_url.setOnFocus("defaulting = false");
m_url.setOnBlur("if (this.value == '') " +
"{ defaulting = true; this.value = urlize(this.form." + NAME +
".value) }");
addField(gz("cms.ui.category.url"),m_url);
addAction(new Finish());
addAction(new Cancel());
}
public void generateXML(PageState ps, Element parent) {
m_script.generateXML(ps, parent);
super.generateXML(ps, parent);
}
/**
* Purpose:
*
* XXXToDo: Should be extended with the function:
* Names have to be unambiguous in the selected language
*/
class NameUniqueListener implements ParameterListener {
private final CategoryRequestLocal m_category;
private final Widget m_widget;
private final int m_type;
public final static int NAME_FIELD = 1;
public final static int URL_FIELD = 2;
NameUniqueListener(final CategoryRequestLocal category) {
this(category,m_name,NAME_FIELD);
}
NameUniqueListener(final CategoryRequestLocal category,
Widget widget, int type) {
m_category = category;
m_widget = widget;
m_type = type;
}
/**
* Purpose:
*
* XXX provisional, has to be adapted
*
* @param e
* @throws com.arsdigita.bebop.FormProcessException
*/
public final void validate(final ParameterEvent e)
throws FormProcessException {
final PageState state = e.getPageState();
final String title = (String) m_widget.getValue(state);
final Category category = m_category.getCategory(state);
final CategoryCollection children = category.getChildren();
while (children.next()) {
final Category child = children.getCategory();
String compField =
(m_type == URL_FIELD) ? child.getURL() : child.getName();
if (compField.equalsIgnoreCase(title)
&& (m_category == null
|| !m_category.getCategory(state).equals(child))) {
throw new FormProcessException
(lz("cms.ui.category.name_not_unique"));
}
}
}
}
}