FolderBrowser

Spalte im FolderBrowser hinzugefügt, die die vorhandenen Sprachvarianten eines Content Items anzeigt und sowohl die primäre Instance makiert (kursiv, class "primaryInstance) als auch den Status der Veröffentlichung (bold, class "live") der Sprachvariante ausgibt. Die hinterlegt Verlinkung führt auf die draft-Variante des Content Items in der angegebenen Sprache.

git-svn-id: https://svn.libreccm.org/ccm/trunk@1439 8810af33-2d31-482b-a856-94f89814c4df
master
quasi 2012-01-11 12:28:32 +00:00
parent 2e67f1bd21
commit 39ad6472b0
5 changed files with 188 additions and 95 deletions

View File

@ -408,7 +408,7 @@ public class ContentBundle extends ContentItem {
* @return A <code>Collection</code> of language 2-letter codes in * @return A <code>Collection</code> of language 2-letter codes in
* which this item is available * which this item is available
*/ */
public final Collection getLanguages() { public final Collection<String> getLanguages() {
// XXX For LIVE bundles, there might be several PENDING // XXX For LIVE bundles, there might be several PENDING
// instances with the same language. Maybe we should filter // instances with the same language. Maybe we should filter
// these out and return only one? // these out and return only one?

View File

@ -70,3 +70,4 @@ cms.ui.folder.no_such_item=Item ID supplied does not match an existing Content I
cms.ui.folder.filter.all=All cms.ui.folder.filter.all=All
cms.ui.folder.filter=Filter for work cms.ui.folder.filter=Filter for work
cms.ui.folder.filter_do=Filter cms.ui.folder.filter_do=Filter
cms.ui.folder.languages=

View File

@ -66,3 +66,4 @@ cms.ui.folder.remove_asset_link=Entfernen
cms.ui.folder.filter.all=Alle cms.ui.folder.filter.all=Alle
cms.ui.folder.filter=Nach Begriff filtern cms.ui.folder.filter=Nach Begriff filtern
cms.ui.folder.filter_do=Filtern cms.ui.folder.filter_do=Filtern
cms.ui.folder.languages=

View File

@ -65,3 +65,4 @@ cms.ui.folder.item_is_live=est en ligne ; Vous devez le d\u00e9-publier avant de
cms.ui.folder.no_permission_for_item=Vous n'avez pas l'autorisation de supprimer ou de d\u00e9placer cms.ui.folder.no_permission_for_item=Vous n'avez pas l'autorisation de supprimer ou de d\u00e9placer
cms.ui.folder.no_such_item=L'identifiant fourni pour l'\u00e9l\u00e9ment ne correspond pas \u00e0 un contenu existant. cms.ui.folder.no_such_item=L'identifiant fourni pour l'\u00e9l\u00e9ment ne correspond pas \u00e0 un contenu existant.
cms.ui.folder.filter.all= cms.ui.folder.filter.all=
cms.ui.folder.languages=

View File

@ -32,8 +32,6 @@ import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.Table; import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.event.ActionEvent; import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener; import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.ChangeEvent;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.event.TableActionAdapter; import com.arsdigita.bebop.event.TableActionAdapter;
import com.arsdigita.bebop.event.TableActionEvent; import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.event.TableActionListener; import com.arsdigita.bebop.event.TableActionListener;
@ -45,12 +43,7 @@ import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.table.TableColumn; import com.arsdigita.bebop.table.TableColumn;
import com.arsdigita.bebop.table.TableHeader; import com.arsdigita.bebop.table.TableHeader;
import com.arsdigita.bebop.table.TableModel; import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.cms.CMS; import com.arsdigita.cms.*;
import com.arsdigita.cms.ContentBundle;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.Folder;
import com.arsdigita.cms.ItemCollection;
import com.arsdigita.cms.SecurityManager; import com.arsdigita.cms.SecurityManager;
import com.arsdigita.cms.dispatcher.ItemResolver; import com.arsdigita.cms.dispatcher.ItemResolver;
import com.arsdigita.cms.dispatcher.Utilities; import com.arsdigita.cms.dispatcher.Utilities;
@ -68,12 +61,13 @@ import com.arsdigita.util.Assert;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Iterator;
import javax.servlet.ServletException; import javax.servlet.ServletException;
/** /**
* Browse folders and items. If the user clicks on a folder, the folder * Browse folders and items. If the user clicks on a folder, the folder
* selection model is updated. If the user clicks on any other item, an * selection model is updated. If the user clicks on any other item, an separate
* separate item selection model is updated. * item selection model is updated.
* *
* @author <a href="mailto:lutter@arsdigita.com">David Lutterkort</a> * @author <a href="mailto:lutter@arsdigita.com">David Lutterkort</a>
* @version $Id: FolderBrowser.java 2017 2009-10-04 09:03:45Z pboy $ * @version $Id: FolderBrowser.java 2017 2009-10-04 09:03:45Z pboy $
@ -82,18 +76,22 @@ public class FolderBrowser extends Table {
private static final Logger s_log = Logger.getLogger(FolderBrowser.class); private static final Logger s_log = Logger.getLogger(FolderBrowser.class);
private static GlobalizedMessage[] s_headers = { private static GlobalizedMessage[] s_headers = {
globalize("cms.ui.folder.name"), globalize("cms.ui.folder.title"), globalize("cms.ui.folder.name"),
globalize("cms.ui.folder.languages"),
globalize("cms.ui.folder.title"),
globalize("cms.ui.folder.type"), globalize("cms.ui.folder.type"),
globalize("cms.ui.folder.creation_date"), globalize("cms.ui.folder.creation_date"),
globalize("cms.ui.folder.last_modified"), globalize( globalize("cms.ui.folder.last_modified"),
"cms.ui.folder.action"), globalize("cms.ui.folder.action"),
globalize("cms.ui.folder.index")}; globalize("cms.ui.folder.index")};
private static GlobalizedMessage[] s_noIndexHeaders = { private static GlobalizedMessage[] s_noIndexHeaders = {
globalize("cms.ui.folder.name"), globalize("cms.ui.folder.title"), globalize("cms.ui.folder.name"),
globalize("cms.ui.folder.languages"),
globalize("cms.ui.folder.title"),
globalize("cms.ui.folder.type"), globalize("cms.ui.folder.type"),
globalize("cms.ui.folder.creation_date"), globalize("cms.ui.folder.creation_date"),
globalize("cms.ui.folder.last_modified"), globalize( globalize("cms.ui.folder.last_modified"),
"cms.ui.folder.action")}; globalize("cms.ui.folder.action")};
private static final String SORT_ACTION_UP = "sortActionUp"; private static final String SORT_ACTION_UP = "sortActionUp";
private static final String SORT_ACTION_DOWN = "sortActionDown"; private static final String SORT_ACTION_DOWN = "sortActionDown";
private FolderSelectionModel m_currentFolder; private FolderSelectionModel m_currentFolder;
@ -139,22 +137,22 @@ public class FolderBrowser extends Table {
m_currentFolder = currentFolder; m_currentFolder = currentFolder;
/* /*
*
This code should be uncommented if the desired behaviour is for a change * This code should be uncommented if the desired behaviour is for a
of folder to cause reversion to default ordering of contained items * change of folder to cause reversion to default ordering of contained
(by name ascending). Our feeling is that the user selected ordering * items (by name ascending). Our feeling is that the user selected
should be retained for the duration of the folder browsing session. If * ordering should be retained for the duration of the folder browsing
anyone wants this alternative behaviour it should be brought in under * session. If anyone wants this alternative behaviour it should be
the control of a config parameter. * brought in under the control of a config parameter.
*
m_currentFolder.addChangeListener(new ChangeListener() { * m_currentFolder.addChangeListener(new ChangeListener() {
*
public void stateChanged(ChangeEvent e) { * public void stateChanged(ChangeEvent e) { PageState state =
PageState state = e.getPageState(); * e.getPageState(); state.setValue(m_sortType,
state.setValue(m_sortType, m_sortType.getDefaultValue()); * m_sortType.getDefaultValue()); state.setValue(m_sortDirection,
state.setValue(m_sortDirection, m_sortDirection.getDefaultValue()); * m_sortDirection.getDefaultValue());
*
}}); * }});
*/ */
setClassAttr("dataTable"); setClassAttr("dataTable");
@ -164,16 +162,17 @@ public class FolderBrowser extends Table {
m_nameColumn = getColumn(0); m_nameColumn = getColumn(0);
m_nameColumn.setCellRenderer(new NameCellRenderer()); m_nameColumn.setCellRenderer(new NameCellRenderer());
m_nameColumn.setHeaderRenderer(new HeaderCellRenderer(SORT_KEY_NAME)); m_nameColumn.setHeaderRenderer(new HeaderCellRenderer(SORT_KEY_NAME));
getColumn(1).setHeaderRenderer(new HeaderCellRenderer(SORT_KEY_TITLE)); getColumn(1).setCellRenderer(new LanguagesCellRenderer());
getColumn(3).setHeaderRenderer(new HeaderCellRenderer( getColumn(2).setHeaderRenderer(new HeaderCellRenderer(SORT_KEY_TITLE));
SORT_KEY_CREATION_DATE));
getColumn(4).setHeaderRenderer(new HeaderCellRenderer( getColumn(4).setHeaderRenderer(new HeaderCellRenderer(
SORT_KEY_CREATION_DATE));
getColumn(5).setHeaderRenderer(new HeaderCellRenderer(
SORT_KEY_LAST_MODIFIED_DATE)); SORT_KEY_LAST_MODIFIED_DATE));
m_deleteColumn = getColumn(5); m_deleteColumn = getColumn(6);
m_deleteColumn.setCellRenderer(new ActionCellRenderer()); m_deleteColumn.setCellRenderer(new ActionCellRenderer());
m_deleteColumn.setAlign("center"); m_deleteColumn.setAlign("center");
if (!hideIndexColumn()) { if (!hideIndexColumn()) {
m_indexColumn = getColumn(6); m_indexColumn = getColumn(7);
m_indexColumn.setCellRenderer(new IndexToggleRenderer()); m_indexColumn.setCellRenderer(new IndexToggleRenderer());
m_indexColumn.setAlign("center"); m_indexColumn.setAlign("center");
@ -282,8 +281,7 @@ public class FolderBrowser extends Table {
} }
public TableModel makeModel(Table t, PageState s) { public TableModel makeModel(Table t, PageState s) {
FolderSelectionModel sel = ((FolderBrowser) t). FolderSelectionModel sel = ((FolderBrowser) t).getFolderSelectionModel();
getFolderSelectionModel();
Folder f = (Folder) sel.getSelectedObject(s); Folder f = (Folder) sel.getSelectedObject(s);
if (f == null) { if (f == null) {
return Table.EMPTY_MODEL; return Table.EMPTY_MODEL;
@ -397,11 +395,11 @@ public class FolderBrowser extends Table {
} }
/** /**
* Indicates whether the paginator should be visible, * Indicates whether the paginator should be visible, based on the
* based on the visibility of the folder browser itself. * visibility of the folder browser itself.
* *
* @return true if folder browser is visible, or if the * @return true if folder browser is visible, or if the associated
* associated folder browser is unknown. * folder browser is unknown.
*/ */
public boolean isVisible(PageState state) { public boolean isVisible(PageState state) {
return (m_fb != null) ? m_fb.isVisible(state) : true; return (m_fb != null) ? m_fb.isVisible(state) : true;
@ -470,8 +468,8 @@ public class FolderBrowser extends Table {
} }
/** /**
* Produce links to view an item or control links for folders * Produce links to view an item or control links for folders to change into
* to change into the folder. * the folder.
*/ */
private class NameCellRenderer extends DefaultTableCellRenderer { private class NameCellRenderer extends DefaultTableCellRenderer {
@ -498,9 +496,101 @@ public class FolderBrowser extends Table {
} else { } else {
ItemResolver resolver = section.getItemResolver(); ItemResolver resolver = section.getItemResolver();
return new Link(name, resolver.generateItemURL(state, id, return new Link(name, resolver.generateItemURL(state, id,
name, section, name, section, coll.getVersion()));
coll. }
getVersion())); }
}
}
/**
* Added by: Sören Bernstein <sbernstein@zes.uni-bremen.de>
*
* Produce links to view an item in a specific language and show all
* existing language version and the live status in the folder browser.
*/
private class LanguagesCellRenderer extends DefaultTableCellRenderer {
public LanguagesCellRenderer() {
super(true);
}
@Override
public Component getComponent(Table table, PageState state, Object value,
boolean isSelected, Object key,
int row, int column) {
Folder.ItemCollection coll = (Folder.ItemCollection) value;
String name = coll.getName();
if (coll.isFolder()) {
// Nothing to show on folders
return new Label();
} else {
ContentPage cp;
try {
cp = new ContentPage(coll.getID());
} catch (DataObjectNotFoundException ex) {
// Content item was not found, return nothing
return new Label();
}
ContentBundle bundle = cp.getContentBundle();
ContentSection section = CMS.getContext().getContentSection();
if (bundle != null
&& !(cp instanceof LanguageInvariantContentItem
&& ((LanguageInvariantContentItem) cp).isLanguageInvariant())) {
Iterator<String> languages = bundle.getLanguages().iterator();
StringBuilder temp = new StringBuilder(20);
SimpleContainer container = new SimpleContainer();
while (languages.hasNext()) {
String lang = languages.next();
ContentItem ci = bundle.getInstance(lang, false);
StringBuilder fontWeight = new StringBuilder(2);
StringBuilder classes = new StringBuilder(20);
if (ci.isLive()) {
fontWeight.append(Label.BOLD);
classes.append("live ");
}
if (bundle.getPrimaryInstance().equals(ci)) {
fontWeight.append(Label.ITALIC);
classes.append("primaryInstance");
}
Label langLabel = new Label(lang);
langLabel.setFontWeight(fontWeight.toString().trim());
langLabel.setClassAttr(classes.toString().trim());
if (section == null) {
container.add(langLabel);
} else {
ItemResolver resolver = section.getItemResolver();
container.add(
new Link(langLabel,
resolver.generateItemURL(state,
ci.getID(),
name,
section,
coll.getVersion())));
}
if (languages.hasNext()) {
container.add(new Label("&nbsp;", false));
}
}
return container;
} else {
return new Label();
} }
} }
} }
@ -596,12 +686,13 @@ public class FolderBrowser extends Table {
private static class FolderTableModel implements TableModel { private static class FolderTableModel implements TableModel {
private static final int NAME = 0; private static final int NAME = 0;
private static final int TITLE = 1; private static final int LANGUAGES = 1;
private static final int TYPE = 2; private static final int TITLE = 2;
private static final int CREATION_DATE = 3; private static final int TYPE = 3;
private static final int LAST_MODIFIED = 4; private static final int CREATION_DATE = 4;
private static final int DELETABLE = 5; private static final int LAST_MODIFIED = 5;
private static final int IS_INDEX = 6; private static final int DELETABLE = 6;
private static final int IS_INDEX = 7;
private PageState m_state; private PageState m_state;
private FolderBrowser m_table; private FolderBrowser m_table;
private Folder.ItemCollection m_itemColl; private Folder.ItemCollection m_itemColl;
@ -631,7 +722,7 @@ public class FolderBrowser extends Table {
} }
public int getColumnCount() { public int getColumnCount() {
return hideIndexColumn() ? 6 : 7; return hideIndexColumn() ? 7 : 8;
} }
public boolean nextRow() { public boolean nextRow() {
@ -642,6 +733,8 @@ public class FolderBrowser extends Table {
switch (columnIndex) { switch (columnIndex) {
case NAME: case NAME:
return m_itemColl; return m_itemColl;
case LANGUAGES:
return m_itemColl;
case TITLE: case TITLE:
return m_itemColl.getDisplayName(); return m_itemColl.getDisplayName();
case TYPE: case TYPE:
@ -675,8 +768,7 @@ public class FolderBrowser extends Table {
if (m_folIndexID == null) { if (m_folIndexID == null) {
return new Boolean(false); return new Boolean(false);
} }
return new Boolean(m_folIndexID.compareTo(m_itemColl. return new Boolean(m_folIndexID.compareTo(m_itemColl.getBundleID()) == 0);
getBundleID()) == 0);
} }
default: default:
throw new IndexOutOfBoundsException("Column index " throw new IndexOutOfBoundsException("Column index "
@ -767,8 +859,7 @@ public class FolderBrowser extends Table {
Folder folder = (Folder) m_fol.getSelectedObject(state); Folder folder = (Folder) m_fol.getSelectedObject(state);
ContentBundle currentIndexItem = (ContentBundle) folder. ContentBundle currentIndexItem = (ContentBundle) folder.getIndexItem();
getIndexItem();
if (currentIndexItem == null || (currentIndexItem.getID(). if (currentIndexItem == null || (currentIndexItem.getID().
compareTo(contentItem.getID()) compareTo(contentItem.getID())
!= 0)) { != 0)) {
@ -786,8 +877,7 @@ public class FolderBrowser extends Table {
/** /**
* Getting the GlobalizedMessage using a CMS Class targetBundle. * Getting the GlobalizedMessage using a CMS Class targetBundle.
* *
* @param key The resource key * @param key The resource key @pre ( key != null )
* @pre ( key != null )
*/ */
private static GlobalizedMessage globalize(String key) { private static GlobalizedMessage globalize(String key) {
return FolderManipulator.globalize(key); return FolderManipulator.globalize(key);