0001: /*
0002: * File : $Source: /usr/local/cvs/opencms/src/org/opencms/workplace/list/CmsHtmlList.java,v $
0003: * Date : $Date: 2008-02-27 12:05:28 $
0004: * Version: $Revision: 1.38 $
0005: *
0006: * This library is part of OpenCms -
0007: * the Open Source Content Management System
0008: *
0009: * Copyright (c) 2002 - 2008 Alkacon Software GmbH (http://www.alkacon.com)
0010: *
0011: * This library is free software; you can redistribute it and/or
0012: * modify it under the terms of the GNU Lesser General Public
0013: * License as published by the Free Software Foundation; either
0014: * version 2.1 of the License, or (at your option) any later version.
0015: *
0016: * This library is distributed in the hope that it will be useful,
0017: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0018: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0019: * Lesser General Public License for more details.
0020: *
0021: * For further information about Alkacon Software GmbH, please see the
0022: * company website: http://www.alkacon.com
0023: *
0024: * For further information about OpenCms, please see the
0025: * project website: http://www.opencms.org
0026: *
0027: * You should have received a copy of the GNU Lesser General Public
0028: * License along with this library; if not, write to the Free Software
0029: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0030: */
0031:
0032: package org.opencms.workplace.list;
0033:
0034: import org.opencms.i18n.CmsMessageContainer;
0035: import org.opencms.i18n.CmsMessages;
0036: import org.opencms.main.CmsIllegalArgumentException;
0037: import org.opencms.main.CmsIllegalStateException;
0038: import org.opencms.util.CmsStringUtil;
0039: import org.opencms.workplace.CmsWorkplace;
0040: import org.opencms.workplace.commons.CmsProgressThread;
0041: import org.opencms.workplace.tools.A_CmsHtmlIconButton;
0042: import org.opencms.workplace.tools.CmsHtmlIconButtonStyleEnum;
0043:
0044: import java.util.ArrayList;
0045: import java.util.Collection;
0046: import java.util.Collections;
0047: import java.util.Iterator;
0048: import java.util.List;
0049: import java.util.Locale;
0050:
0051: /**
0052: * The main class of the html list widget.<p>
0053: *
0054: * @author Michael Moossen
0055: *
0056: * @version $Revision: 1.38 $
0057: *
0058: * @since 6.0.0
0059: */
0060: public class CmsHtmlList {
0061:
0062: /** Standard list button location. */
0063: public static final String ICON_LEFT = "list/leftarrow.png";
0064:
0065: /** Standard list button location. */
0066: public static final String ICON_RIGHT = "list/rightarrow.png";
0067:
0068: /** Constant for item separator char used for coding/encoding multiselection. */
0069: public static final String ITEM_SEPARATOR = "|";
0070:
0071: /** Var name for error message if no item has been selected. */
0072: public static final String NO_SELECTION_HELP_VAR = "noSelHelp";
0073:
0074: /** Var name for error message if number of selected items does not match. */
0075: public static final String NO_SELECTION_MATCH_HELP_VAR = "noSelMatchHelp";
0076:
0077: /** Current displayed page number. */
0078: private int m_currentPage;
0079:
0080: /** Current sort order. */
0081: private CmsListOrderEnum m_currentSortOrder;
0082:
0083: /** Filtered list of items or <code>null</code> if no filter is set and not sorted. */
0084: private List m_filteredItems;
0085:
0086: /** Dhtml id. */
0087: private final String m_id;
0088:
0089: /** If this flag is set the list will be surrounded by a box. */
0090: private boolean m_isBoxed = true;
0091:
0092: /** Maximum number of items per page. */
0093: private int m_maxItemsPerPage = 20;
0094:
0095: /** Metadata for building the list. */
0096: private CmsListMetadata m_metadata;
0097:
0098: /** Display Name of the list. */
0099: private CmsMessageContainer m_name;
0100:
0101: /** Really content of the list. */
0102: private List m_originalItems = new ArrayList();
0103:
0104: /** printable flag. */
0105: private boolean m_printable;
0106:
0107: /** Search filter text. */
0108: private String m_searchFilter;
0109:
0110: /** Show the title of the list. */
0111: private boolean m_showTitle;
0112:
0113: /** The filtered content size, only used if data self managed. */
0114: private int m_size;
0115:
0116: /** Column name to be sorted. */
0117: private String m_sortedColumn;
0118:
0119: /** The total size, only used is data self managed. */
0120: private int m_totalSize;
0121:
0122: /** Items currently displayed. */
0123: private List m_visibleItems;
0124:
0125: /** The related workplace dialog object. */
0126: private transient A_CmsListDialog m_wp;
0127:
0128: /**
0129: * Default Constructor.<p>
0130: *
0131: * @param id unique id of the list, is used as name for controls and js functions and vars
0132: * @param name the display name
0133: * @param metadata the list's metadata
0134: */
0135: public CmsHtmlList(String id, CmsMessageContainer name,
0136: CmsListMetadata metadata) {
0137:
0138: m_id = id;
0139: m_name = name;
0140: m_metadata = metadata;
0141: m_currentPage = 1;
0142: m_showTitle = true;
0143: }
0144:
0145: /**
0146: * Generates the list of html option elements for a html select control to select a page of a list.<p>
0147: *
0148: * @param nrPages the total number of pages
0149: * @param itemsPage the maximum number of items per page
0150: * @param nrItems the total number of items
0151: * @param curPage the current page
0152: * @param locale the locale
0153: *
0154: * @return html code
0155: */
0156: public static String htmlPageSelector(int nrPages, int itemsPage,
0157: int nrItems, int curPage, Locale locale) {
0158:
0159: StringBuffer html = new StringBuffer(256);
0160: for (int i = 0; i < nrPages; i++) {
0161: int displayedFrom = i * itemsPage + 1;
0162: int displayedTo = (i + 1) * itemsPage < nrItems ? (i + 1)
0163: * itemsPage : nrItems;
0164: html.append("\t\t\t\t<option value='");
0165: html.append(i + 1);
0166: html.append("'");
0167: html.append((i + 1) == curPage ? " selected" : "");
0168: html.append(">");
0169: html.append(Messages.get().getBundle(locale).key(
0170: Messages.GUI_LIST_PAGE_ENTRY_3, new Integer(i + 1),
0171: new Integer(displayedFrom),
0172: new Integer(displayedTo)));
0173: html.append("</option>\n");
0174: }
0175: return html.toString();
0176: }
0177:
0178: /**
0179: * This method resets the content of the list (no the metadata).<p>
0180: */
0181: public void clear() {
0182:
0183: if (m_originalItems != null) {
0184: m_originalItems.clear();
0185: }
0186: m_filteredItems = null;
0187: synchronized (this ) {
0188: if (m_visibleItems != null) {
0189: m_visibleItems.clear();
0190: }
0191: }
0192: setSearchFilter("");
0193: m_sortedColumn = null;
0194: }
0195:
0196: /**
0197: * Returns all list items in the list, may be not visible and sorted.<p>
0198: *
0199: * @return all list items
0200: */
0201: public List getAllContent() {
0202:
0203: if (m_metadata.isSelfManaged()) {
0204: if (m_filteredItems != null) {
0205: return Collections.unmodifiableList(m_filteredItems);
0206: } else {
0207: return Collections.EMPTY_LIST;
0208: }
0209: } else {
0210: if (m_originalItems != null) {
0211: return Collections.unmodifiableList(m_originalItems);
0212: } else {
0213: return Collections.EMPTY_LIST;
0214: }
0215: }
0216: }
0217:
0218: /**
0219: * Returns the filtered list of list items.<p>
0220: *
0221: * Equals to <code>{@link #getAllContent()}</code> if no filter is set.<p>
0222: *
0223: * @return the filtered list of list items
0224: */
0225: public List getContent() {
0226:
0227: if (m_filteredItems == null) {
0228: return getAllContent();
0229: } else {
0230: return Collections.unmodifiableList(m_filteredItems);
0231: }
0232: }
0233:
0234: /**
0235: * returns the number of the current page.<p>
0236: *
0237: * @return the number of the current page
0238: */
0239: public int getCurrentPage() {
0240:
0241: return m_currentPage;
0242: }
0243:
0244: /**
0245: * Returns all items of the current page.<p>
0246: *
0247: * @return all items of the current page, a list of {@link CmsListItem} objects
0248: */
0249: public List getCurrentPageItems() {
0250:
0251: if (getSize() == 0) {
0252: return Collections.EMPTY_LIST;
0253: }
0254: if (m_metadata.isSelfManaged()) {
0255: return getContent();
0256: }
0257: return Collections.unmodifiableList(getContent().subList(
0258: displayedFrom() - 1, displayedTo()));
0259: }
0260:
0261: /**
0262: * Returns the current used sort order.<p>
0263: *
0264: * @return the current used sort order
0265: */
0266: public CmsListOrderEnum getCurrentSortOrder() {
0267:
0268: return m_currentSortOrder;
0269: }
0270:
0271: /**
0272: * Returns the id.<p>
0273: *
0274: * @return the id
0275: */
0276: public String getId() {
0277:
0278: return m_id;
0279: }
0280:
0281: /**
0282: * This method returns the item identified by the parameter id.<p>
0283: *
0284: * Only current visible item can be retrieved using this method.<p>
0285: *
0286: * @param id the id of the item to look for
0287: *
0288: * @return the requested item or <code>null</code> if not found
0289: */
0290: public CmsListItem getItem(String id) {
0291:
0292: Iterator it = getAllContent().iterator();
0293: while (it.hasNext()) {
0294: CmsListItem item = (CmsListItem) it.next();
0295: if (item.getId().equals(id)) {
0296: return item;
0297: }
0298: }
0299: return null;
0300: }
0301:
0302: /**
0303: * Returns the maximum number of items per page.<p>
0304: *
0305: * @return the maximum number of items per page
0306: */
0307: public int getMaxItemsPerPage() {
0308:
0309: return m_maxItemsPerPage;
0310: }
0311:
0312: /**
0313: * Returns the metadata.<p>
0314: *
0315: * @return the metadata
0316: */
0317: public CmsListMetadata getMetadata() {
0318:
0319: return m_metadata;
0320: }
0321:
0322: /**
0323: * Returns the name of the list.<p>
0324: *
0325: * @return the list's name
0326: */
0327: public CmsMessageContainer getName() {
0328:
0329: return m_name;
0330: }
0331:
0332: /**
0333: * Returns the filtered number of pages.<p>
0334: *
0335: * Equals to <code>{@link #getTotalNumberOfPages()}</code> if no filter is set.<p>
0336: *
0337: * @return the filtered of pages
0338: */
0339: public int getNumberOfPages() {
0340:
0341: return (int) Math.ceil((double) getSize()
0342: / getMaxItemsPerPage());
0343: }
0344:
0345: /**
0346: * Returns the search filter.<p>
0347: *
0348: * @return the search filter
0349: */
0350: public String getSearchFilter() {
0351:
0352: return m_searchFilter;
0353: }
0354:
0355: /**
0356: * Return the filtered number of items.<p>
0357: *
0358: * Equals to <code>{@link #getTotalSize()}</code> if no filter is set.<p>
0359: *
0360: * @return the filtered number of items
0361: */
0362: public int getSize() {
0363:
0364: if (m_metadata.isSelfManaged() && (m_size != 0)) {
0365: return m_size;
0366: }
0367: return getContent().size();
0368: }
0369:
0370: /**
0371: * Returns the sorted column's name.<p>
0372: *
0373: * @return the sorted column's name
0374: */
0375: public String getSortedColumn() {
0376:
0377: return m_sortedColumn;
0378: }
0379:
0380: /**
0381: * Returns a filled list state.<p>
0382: *
0383: * @return the state of the list
0384: */
0385: public CmsListState getState() {
0386:
0387: return new CmsListState(this );
0388: }
0389:
0390: /**
0391: * Returns the total number of pages.<p>
0392: *
0393: * @return the total number of pages
0394: */
0395: public int getTotalNumberOfPages() {
0396:
0397: return (int) Math.ceil((double) getTotalSize()
0398: / getMaxItemsPerPage());
0399: }
0400:
0401: /**
0402: * Return the total number of items.<p>
0403: *
0404: * @return the total number of items
0405: */
0406: public int getTotalSize() {
0407:
0408: if (m_metadata.isSelfManaged() && (m_totalSize != 0)) {
0409: return m_totalSize;
0410: }
0411: return getAllContent().size();
0412: }
0413:
0414: /**
0415: * Returns the workplace dialog object.<p>
0416: *
0417: * @return the workplace dialog object
0418: */
0419: public A_CmsListDialog getWp() {
0420:
0421: return m_wp;
0422: }
0423:
0424: /**
0425: * Returns the isBoxed flag.<p>
0426: *
0427: * If this flag is set the list will be surrounded by a box.<p>
0428: *
0429: * @return the isBoxed flag
0430: */
0431: public boolean isBoxed() {
0432:
0433: return m_isBoxed;
0434: }
0435:
0436: /**
0437: * Returns the printable flag.<p>
0438: *
0439: * @return the printable flag
0440: */
0441: public boolean isPrintable() {
0442:
0443: return m_printable;
0444: }
0445:
0446: /**
0447: * Returns if the list title is shown.<p>
0448: *
0449: * @return true if the list title is shown, otherwise false
0450: */
0451: public boolean isShowTitle() {
0452:
0453: return m_showTitle;
0454: }
0455:
0456: /**
0457: * Generates the csv output for the list.<p>
0458: *
0459: * @return csv output
0460: */
0461: public String listCsv() {
0462:
0463: StringBuffer csv = new StringBuffer(5120);
0464: csv.append(m_metadata.csvHeader());
0465: if (getContent().isEmpty()) {
0466: csv.append(m_metadata.csvEmptyList());
0467: } else {
0468: Iterator itItems = getContent().iterator();
0469: while (itItems.hasNext()) {
0470: CmsListItem item = (CmsListItem) itItems.next();
0471: csv.append(m_metadata.csvItem(item));
0472: }
0473: }
0474: return getWp().resolveMacros(csv.toString());
0475: }
0476:
0477: /**
0478: * Generates the html code for the list.<p>
0479: *
0480: * @return html code
0481: */
0482: public synchronized String listHtml() {
0483:
0484: // check if progress should be set in the thread
0485: CmsProgressThread thread = null;
0486: int progressOffset = 0;
0487: if (Thread.currentThread() instanceof CmsProgressThread) {
0488: thread = (CmsProgressThread) Thread.currentThread();
0489: progressOffset = thread.getProgress();
0490: }
0491:
0492: // this block has to be executed before calling htmlBegin()
0493: if (isPrintable()) {
0494: m_visibleItems = new ArrayList(getContent());
0495: } else {
0496: m_visibleItems = new ArrayList(getCurrentPageItems());
0497: }
0498:
0499: StringBuffer html = new StringBuffer(5120);
0500: html.append(htmlBegin());
0501: if (!isPrintable()) {
0502: html.append(htmlTitle());
0503: html.append(htmlToolBar());
0504: } else {
0505: html.append("<style type='text/css'>\n");
0506: html.append("td.listdetailitem, \n");
0507: html.append(".linkdisabled {\n");
0508: html.append("\tcolor: black;\n");
0509: html.append("}\n");
0510: html.append(".list th {\n");
0511: html.append("\tborder: 1px solid black;\n");
0512: html.append("}\n");
0513: html.append(".list {\n");
0514: html.append("\tborder: 1px solid black;\n");
0515: html.append("}\n");
0516: html.append("</style>");
0517: }
0518: html
0519: .append("<table width='100%' cellpadding='1' cellspacing='0' class='list'>\n");
0520: html.append(m_metadata.htmlHeader(this ));
0521: if (m_visibleItems.isEmpty()) {
0522: html.append(m_metadata.htmlEmptyTable());
0523: } else {
0524: Iterator itItems = m_visibleItems.iterator();
0525: boolean odd = true;
0526: int count = 0;
0527: while (itItems.hasNext()) {
0528:
0529: // set progress in thread
0530: count++;
0531: if (thread != null) {
0532:
0533: if (thread.isInterrupted()) {
0534: throw new CmsIllegalStateException(
0535: org.opencms.workplace.commons.Messages
0536: .get()
0537: .container(
0538: org.opencms.workplace.commons.Messages.ERR_PROGRESS_INTERRUPTED_0));
0539: }
0540: thread
0541: .setProgress((count
0542: * (100 - progressOffset) / m_visibleItems
0543: .size())
0544: + progressOffset);
0545: thread
0546: .setDescription(org.opencms.workplace.commons.Messages
0547: .get()
0548: .getBundle(thread.getLocale())
0549: .key(
0550: org.opencms.workplace.commons.Messages.GUI_PROGRESS_PUBLISH_STEP4_2,
0551: new Integer(count),
0552: new Integer(m_visibleItems
0553: .size())));
0554: }
0555:
0556: CmsListItem item = (CmsListItem) itItems.next();
0557: html.append(m_metadata.htmlItem(item, odd,
0558: isPrintable()));
0559: odd = !odd;
0560: }
0561: }
0562:
0563: html.append("</table>\n");
0564: if (!isPrintable()) {
0565: html.append(htmlPagingBar());
0566: }
0567: html.append(htmlEnd());
0568: return getWp().resolveMacros(html.toString());
0569: }
0570:
0571: /**
0572: * Generate the need js code for the list.<p>
0573: *
0574: * @return js code
0575: */
0576: public String listJs() {
0577:
0578: StringBuffer js = new StringBuffer(1024);
0579: CmsMessages messages = Messages.get().getBundle(
0580: getWp().getLocale());
0581: js.append("<script type='text/javascript' src='");
0582: js.append(CmsWorkplace.getSkinUri());
0583: js.append("admin/javascript/list.js'></script>\n");
0584: if (!m_metadata.getMultiActions().isEmpty()) {
0585: js.append("<script type='text/javascript'>\n");
0586: js.append("\tvar ");
0587: js.append(NO_SELECTION_HELP_VAR);
0588: js.append(" = '");
0589: js.append(CmsStringUtil.escapeJavaScript(messages
0590: .key(Messages.GUI_LIST_ACTION_NO_SELECTION_0)));
0591: js.append("';\n");
0592: Iterator it = m_metadata.getMultiActions().iterator();
0593: while (it.hasNext()) {
0594: CmsListMultiAction action = (CmsListMultiAction) it
0595: .next();
0596: if (action instanceof CmsListRadioMultiAction) {
0597: CmsListRadioMultiAction rAction = (CmsListRadioMultiAction) action;
0598: js.append("\tvar ");
0599: js.append(NO_SELECTION_MATCH_HELP_VAR);
0600: js.append(rAction.getId());
0601: js.append(" = '");
0602: js
0603: .append(CmsStringUtil
0604: .escapeJavaScript(messages
0605: .key(
0606: Messages.GUI_LIST_ACTION_NO_SELECTION_MATCH_1,
0607: new Integer(
0608: rAction
0609: .getSelections()))));
0610: js.append("';\n");
0611: }
0612: }
0613: js.append("</script>\n");
0614: }
0615: return js.toString();
0616: }
0617:
0618: /**
0619: * Returns a new list item for this list.<p>
0620: *
0621: * @param id the id of the item has to be unique
0622: * @return a new list item
0623: */
0624: public CmsListItem newItem(String id) {
0625:
0626: return new CmsListItem(getMetadata(), id);
0627: }
0628:
0629: /**
0630: * Returns html code for printing the list.<p>
0631: *
0632: * @return html code
0633: */
0634: public String printableHtml() {
0635:
0636: m_printable = true;
0637: String html = listHtml();
0638: m_printable = false;
0639: return html;
0640: }
0641:
0642: /**
0643: * Sets the isBoxed flag.<p>
0644: *
0645: * If this flag is set, the list will be surrounded by a box.<p>
0646: *
0647: * @param isBoxed the isBoxed flag to set
0648: */
0649: public void setBoxed(boolean isBoxed) {
0650:
0651: m_isBoxed = isBoxed;
0652: }
0653:
0654: /**
0655: * Sets the list item to display in the list.<p>
0656: *
0657: * @param listItems a collection of {@link CmsListItem} objects
0658: */
0659: public void setContent(Collection listItems) {
0660:
0661: if (m_metadata.isSelfManaged()) {
0662: m_filteredItems = new ArrayList(listItems);
0663: m_originalItems = null;
0664: } else {
0665: m_filteredItems = null;
0666: m_originalItems = new ArrayList(listItems);
0667: }
0668: }
0669:
0670: /**
0671: * Sets the current page.<p>
0672: *
0673: * @param currentPage the current page to set
0674: *
0675: * @throws CmsIllegalArgumentException if the argument is invalid
0676: */
0677: public void setCurrentPage(int currentPage)
0678: throws CmsIllegalArgumentException {
0679:
0680: if (getSize() != 0) {
0681: if ((currentPage < 1) || (currentPage > getNumberOfPages())) {
0682: throw new CmsIllegalArgumentException(Messages.get()
0683: .container(Messages.ERR_LIST_INVALID_PAGE_1,
0684: new Integer(currentPage)));
0685: }
0686: }
0687: m_currentPage = currentPage;
0688: }
0689:
0690: /**
0691: * Sets the maximum number of items per page.<p>
0692: *
0693: * @param maxItemsPerPage the maximum number of items per page to set
0694: */
0695: public void setMaxItemsPerPage(int maxItemsPerPage) {
0696:
0697: this .m_maxItemsPerPage = maxItemsPerPage;
0698: }
0699:
0700: /**
0701: * Sets the name of the list.<p>
0702: *
0703: * @param name the name of the list
0704: */
0705: public void setName(CmsMessageContainer name) {
0706:
0707: m_name = name;
0708: }
0709:
0710: /**
0711: * Sets the search filter.<p>
0712: *
0713: * @param searchFilter the search filter to set
0714: */
0715: public void setSearchFilter(String searchFilter) {
0716:
0717: if (!m_metadata.isSearchable()) {
0718: return;
0719: }
0720: if (CmsStringUtil.isEmptyOrWhitespaceOnly(searchFilter)) {
0721: // reset content if filter is empty
0722: if (!m_metadata.isSelfManaged()) {
0723: m_filteredItems = null;
0724: }
0725: m_searchFilter = "";
0726: getMetadata().getSearchAction().getShowAllAction()
0727: .setVisible(false);
0728: } else {
0729: if (!m_metadata.isSelfManaged()) {
0730: m_filteredItems = getMetadata().getSearchAction()
0731: .filter(getAllContent(), searchFilter);
0732: }
0733: m_searchFilter = searchFilter;
0734: getMetadata().getSearchAction().getShowAllAction()
0735: .setVisible(true);
0736: }
0737: String sCol = m_sortedColumn;
0738: m_sortedColumn = "";
0739: if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(sCol)) {
0740: CmsListOrderEnum order = getCurrentSortOrder();
0741: setSortedColumn(sCol);
0742: if (order == CmsListOrderEnum.ORDER_DESCENDING) {
0743: setSortedColumn(sCol);
0744: }
0745: }
0746: setCurrentPage(1);
0747: }
0748:
0749: /**
0750: * Sets if the list title is shown.<p>
0751: *
0752: * @param showTitle true if the list title is shown, otherwise false
0753: */
0754: public void setShowTitle(boolean showTitle) {
0755:
0756: m_showTitle = showTitle;
0757: }
0758:
0759: /**
0760: * Sets the current filtered size, only used if data self managed.<p>
0761: *
0762: * @param size the size to set
0763: */
0764: public void setSize(int size) {
0765:
0766: m_size = size;
0767: }
0768:
0769: /**
0770: * Sets the sorted column.<p>
0771: *
0772: * @param sortedColumn the sorted column to set
0773: *
0774: * @throws CmsIllegalArgumentException if the <code>sortedColumn</code> argument is invalid
0775: */
0776: public void setSortedColumn(String sortedColumn)
0777: throws CmsIllegalArgumentException {
0778:
0779: if ((getMetadata().getColumnDefinition(sortedColumn) == null)
0780: || !getMetadata().getColumnDefinition(sortedColumn)
0781: .isSorteable()) {
0782: return;
0783: }
0784: // check if the parameter is valid
0785: if (m_metadata.getColumnDefinition(sortedColumn) == null) {
0786: throw new CmsIllegalArgumentException(Messages.get()
0787: .container(Messages.ERR_LIST_INVALID_COLUMN_1,
0788: sortedColumn));
0789: }
0790: // reset view
0791: setCurrentPage(1);
0792: // only reverse order if the column to sort is already sorted
0793: if (sortedColumn.equals(m_sortedColumn)) {
0794: if (m_currentSortOrder == CmsListOrderEnum.ORDER_ASCENDING) {
0795: m_currentSortOrder = CmsListOrderEnum.ORDER_DESCENDING;
0796: } else {
0797: m_currentSortOrder = CmsListOrderEnum.ORDER_ASCENDING;
0798: }
0799: if (!m_metadata.isSelfManaged()) {
0800: if (m_filteredItems == null) {
0801: m_filteredItems = new ArrayList(getAllContent());
0802: }
0803: Collections.reverse(m_filteredItems);
0804: }
0805: return;
0806: }
0807: // sort new column
0808: m_sortedColumn = sortedColumn;
0809: m_currentSortOrder = CmsListOrderEnum.ORDER_ASCENDING;
0810: if (!m_metadata.isSelfManaged()) {
0811: if (m_filteredItems == null) {
0812: m_filteredItems = new ArrayList(getAllContent());
0813: }
0814: I_CmsListItemComparator c = getMetadata()
0815: .getColumnDefinition(sortedColumn)
0816: .getListItemComparator();
0817: Collections.sort(m_filteredItems, c.getComparator(
0818: sortedColumn, getWp().getLocale()));
0819: }
0820: }
0821:
0822: /**
0823: * Sets the list state.<p>
0824: *
0825: * This may involve sorting, filtering and paging.<p>
0826: *
0827: * @param listState the state to be set
0828: */
0829: public void setState(CmsListState listState) {
0830:
0831: if (!m_metadata.isSelfManaged()) {
0832: m_filteredItems = null;
0833: }
0834: synchronized (this ) {
0835: if (m_visibleItems != null) {
0836: m_visibleItems.clear();
0837: }
0838: }
0839: setSearchFilter(listState.getFilter());
0840: setSortedColumn(listState.getColumn());
0841: if (listState.getOrder() == CmsListOrderEnum.ORDER_DESCENDING) {
0842: setSortedColumn(listState.getColumn());
0843: }
0844: if (listState.getPage() > 0) {
0845: if (listState.getPage() <= getNumberOfPages()) {
0846: setCurrentPage(listState.getPage());
0847: } else {
0848: setCurrentPage(1);
0849: }
0850: }
0851: }
0852:
0853: /**
0854: * Sets the total Size, only used if data self managed.<p>
0855: *
0856: * @param totalSize the total Size to set
0857: */
0858: public void setTotalSize(int totalSize) {
0859:
0860: m_totalSize = totalSize;
0861: }
0862:
0863: /**
0864: * Sets the workplace dialog object.<p>
0865: *
0866: * @param wp the workplace dialog object to set
0867: */
0868: public void setWp(A_CmsListDialog wp) {
0869:
0870: m_wp = wp;
0871: m_metadata.setWp(wp);
0872: }
0873:
0874: /**
0875: * Sets the metadata for this list.<p>
0876: *
0877: * Should only be used by the <code>{@link A_CmsListDialog}</code> class
0878: * for temporaly removing the metadata object while the list is saved in the
0879: * <code>{@link org.opencms.workplace.CmsWorkplaceSettings}</code>.<p>
0880: *
0881: * @param metadata the list metadata
0882: */
0883: void setMetadata(CmsListMetadata metadata) {
0884:
0885: m_metadata = metadata;
0886: }
0887:
0888: /**
0889: * Returns the number (from 1) of the first displayed item.<p>
0890: *
0891: * @return the number (from 1) of the first displayed item, or zero if the list is empty
0892: */
0893: private int displayedFrom() {
0894:
0895: if (getSize() != 0) {
0896: if (isPrintable()) {
0897: return 1;
0898: } else {
0899: return (getCurrentPage() - 1) * getMaxItemsPerPage()
0900: + 1;
0901: }
0902: }
0903: return 0;
0904: }
0905:
0906: /**
0907: * Returns the number (from 1) of the last displayed item.<p>
0908: *
0909: * @return the number (from 1) of the last displayed item, or zero if the list is empty
0910: */
0911: private int displayedTo() {
0912:
0913: if (getSize() != 0) {
0914: if (!isPrintable()) {
0915: if (getCurrentPage() * getMaxItemsPerPage() < getSize()) {
0916: return getCurrentPage() * getMaxItemsPerPage();
0917: }
0918: }
0919: }
0920: return getSize();
0921: }
0922:
0923: /**
0924: * Generates the initial html code.<p>
0925: *
0926: * @return html code
0927: */
0928: private String htmlBegin() {
0929:
0930: StringBuffer html = new StringBuffer(512);
0931: // help & confirmation text for actions if needed
0932: if (!isPrintable() && (m_visibleItems != null)
0933: && !m_visibleItems.isEmpty()) {
0934: Iterator cols = getMetadata().getColumnDefinitions()
0935: .iterator();
0936: while (cols.hasNext()) {
0937: CmsListColumnDefinition col = (CmsListColumnDefinition) cols
0938: .next();
0939: Iterator actions = col.getDirectActions().iterator();
0940: while (actions.hasNext()) {
0941: I_CmsListDirectAction action = (I_CmsListDirectAction) actions
0942: .next();
0943: action.setItem((CmsListItem) m_visibleItems.get(0));
0944: html.append(action.helpTextHtml());
0945: html.append(action.confirmationTextHtml());
0946: }
0947: Iterator defActions = col.getDefaultActions()
0948: .iterator();
0949: while (defActions.hasNext()) {
0950: I_CmsListDirectAction action = (I_CmsListDirectAction) defActions
0951: .next();
0952: action.setItem((CmsListItem) m_visibleItems.get(0));
0953: html.append(action.helpTextHtml());
0954: html.append(action.confirmationTextHtml());
0955: }
0956: }
0957: }
0958: // start list code
0959: html.append("<div class='listArea'>\n");
0960: if (isBoxed()) {
0961: html.append(getWp().dialogBlock(CmsWorkplace.HTML_START,
0962: m_name.key(getWp().getLocale()), false));
0963: }
0964: html
0965: .append("\t\t<table width='100%' cellspacing='0' cellpadding='0' border='0'>\n");
0966: html.append("\t\t\t<tr><td>\n");
0967: return html.toString();
0968: }
0969:
0970: /**
0971: * Generates the need html code for ending a list.<p>
0972: *
0973: * @return html code
0974: */
0975: private String htmlEnd() {
0976:
0977: StringBuffer html = new StringBuffer(512);
0978: html.append("\t\t\t</td></tr>\n");
0979: html.append("\t\t</table>\n");
0980: if (isBoxed()) {
0981: html.append(getWp().dialogBlock(CmsWorkplace.HTML_END,
0982: m_name.key(getWp().getLocale()), false));
0983: }
0984: html.append("</div>\n");
0985: if (!isPrintable() && getMetadata().isSearchable()) {
0986: html.append("<script type='text/javascript'>\n");
0987: html.append("\tvar form = document.forms['");
0988: html.append(getId());
0989: html.append("-form'];\n");
0990: html.append("\tform.listSearchFilter.value='");
0991: html.append(getSearchFilter() != null ? CmsStringUtil
0992: .escapeJavaScript(getSearchFilter()) : "");
0993: html.append("';\n");
0994: html.append("</script>\n");
0995: }
0996: return html.toString();
0997: }
0998:
0999: /**
1000: * Generates the needed html code for the paging bar.<p>
1001: *
1002: * @return html code
1003: */
1004: private String htmlPagingBar() {
1005:
1006: if (getNumberOfPages() < 2) {
1007: return "";
1008: }
1009: StringBuffer html = new StringBuffer(1024);
1010: CmsMessages messages = Messages.get().getBundle(
1011: getWp().getLocale());
1012: html
1013: .append("<table width='100%' cellspacing='0' style='margin-top: 5px;'>\n");
1014: html.append("\t<tr>\n");
1015: html.append("\t\t<td class='main'>\n");
1016: // prev button
1017: String id = "listPrev";
1018: String name = messages
1019: .key(Messages.GUI_LIST_PAGING_PREVIOUS_NAME_0);
1020: String iconPath = ICON_LEFT;
1021: boolean enabled = getCurrentPage() > 1;
1022: String helpText = messages
1023: .key(Messages.GUI_LIST_PAGING_PREVIOUS_HELP_0);
1024: if (!enabled) {
1025: helpText = messages
1026: .key(Messages.GUI_LIST_PAGING_PREVIOUS_HELPDIS_0);
1027: }
1028: String onClic = "listSetPage('" + getId() + "', "
1029: + (getCurrentPage() - 1) + ")";
1030: html.append(A_CmsHtmlIconButton.defaultButtonHtml(
1031: CmsHtmlIconButtonStyleEnum.SMALL_ICON_TEXT, id, name,
1032: helpText, enabled, iconPath, null, onClic));
1033: html.append("\n");
1034: // next button
1035: id = "listNext";
1036: name = messages.key(Messages.GUI_LIST_PAGING_NEXT_NAME_0);
1037: iconPath = ICON_RIGHT;
1038: enabled = getCurrentPage() < getNumberOfPages();
1039: helpText = messages.key(Messages.GUI_LIST_PAGING_NEXT_HELP_0);
1040: if (!enabled) {
1041: helpText = messages
1042: .key(Messages.GUI_LIST_PAGING_NEXT_HELPDIS_0);
1043: }
1044: onClic = "listSetPage('" + getId() + "', "
1045: + (getCurrentPage() + 1) + ")";
1046: html.append(A_CmsHtmlIconButton.defaultButtonHtml(
1047: CmsHtmlIconButtonStyleEnum.SMALL_ICON_TEXT, id, name,
1048: helpText, enabled, iconPath, null, onClic));
1049: html.append("\n");
1050: // page selection list
1051: html.append("\t\t\t ");
1052: html
1053: .append("\t\t\t<select name='listPageSet' id='id-page_set' onChange =\"listSetPage('");
1054: html.append(getId());
1055: html
1056: .append("', this.value);\" style='vertical-align: bottom;'>\n");
1057: html.append(htmlPageSelector(getNumberOfPages(),
1058: getMaxItemsPerPage(), getSize(), getCurrentPage(),
1059: getWp().getLocale()));
1060: html.append("\t\t\t</select>\n");
1061: html.append("\t\t\t ");
1062: if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_searchFilter)) {
1063: html.append(messages.key(Messages.GUI_LIST_PAGING_TEXT_2,
1064: new Object[] { m_name.key(getWp().getLocale()),
1065: new Integer(getTotalSize()) }));
1066: } else {
1067: html.append(messages.key(
1068: Messages.GUI_LIST_PAGING_FILTER_TEXT_3,
1069: new Object[] { m_name.key(getWp().getLocale()),
1070: new Integer(getSize()),
1071: new Integer(getTotalSize()) }));
1072: }
1073: html.append("\t\t</td>\n");
1074: html.append("\t</tr>\n");
1075: html.append("</table>\n");
1076: return html.toString();
1077: }
1078:
1079: /**
1080: * Returns the html for the title of the list.<p>
1081: *
1082: * @return html code
1083: */
1084: private String htmlTitle() {
1085:
1086: boolean showTitle = isShowTitle();
1087: Iterator itIndepActions = getMetadata().getIndependentActions()
1088: .iterator();
1089: while (!showTitle && itIndepActions.hasNext()) {
1090: CmsListIndependentAction indepAction = (CmsListIndependentAction) itIndepActions
1091: .next();
1092: showTitle = showTitle || indepAction.isVisible();
1093: }
1094: Iterator itItemDetails = getMetadata()
1095: .getItemDetailDefinitions().iterator();
1096: while (!showTitle && itItemDetails.hasNext()) {
1097: CmsListItemDetails itemDetail = (CmsListItemDetails) itItemDetails
1098: .next();
1099: showTitle = showTitle || itemDetail.getAction().isVisible();
1100: }
1101: if (!showTitle) {
1102: // prevent empty table if there is nothing to display
1103: return "";
1104: }
1105: StringBuffer html = new StringBuffer(512);
1106: CmsMessages messages = Messages.get().getBundle(
1107: getWp().getLocale());
1108: html.append("<table width='100%' cellspacing='0'>");
1109: html.append("\t<tr>\n");
1110: if (isShowTitle()) {
1111: html.append("\t\t<td align='left'>\n");
1112: html.append("\t\t\t");
1113: if (getTotalNumberOfPages() > 1) {
1114: if (CmsStringUtil
1115: .isEmptyOrWhitespaceOnly(m_searchFilter)) {
1116: html.append(messages.key(
1117: Messages.GUI_LIST_TITLE_TEXT_4,
1118: new Object[] {
1119: m_name.key(getWp().getLocale()),
1120: new Integer(displayedFrom()),
1121: new Integer(displayedTo()),
1122: new Integer(getTotalSize()) }));
1123: } else {
1124: html.append(messages.key(
1125: Messages.GUI_LIST_TITLE_FILTERED_TEXT_5,
1126: new Object[] {
1127: m_name.key(getWp().getLocale()),
1128: new Integer(displayedFrom()),
1129: new Integer(displayedTo()),
1130: new Integer(getSize()),
1131: new Integer(getTotalSize()) }));
1132: }
1133: } else {
1134: if (CmsStringUtil
1135: .isEmptyOrWhitespaceOnly(m_searchFilter)) {
1136: html.append(messages.key(
1137: Messages.GUI_LIST_SINGLE_TITLE_TEXT_2,
1138: new Object[] {
1139: m_name.key(getWp().getLocale()),
1140: new Integer(getTotalSize()) }));
1141: } else {
1142: html
1143: .append(messages
1144: .key(
1145: Messages.GUI_LIST_SINGLE_TITLE_FILTERED_TEXT_3,
1146: new Object[] {
1147: m_name
1148: .key(getWp()
1149: .getLocale()),
1150: new Integer(
1151: getSize()),
1152: new Integer(
1153: getTotalSize()) }));
1154: }
1155: }
1156: html.append("\n");
1157: html.append("\t\t</td>\n\t\t");
1158: }
1159: html.append(getMetadata().htmlActionBar());
1160: html.append("\n\t</tr>\n");
1161: html.append("</table>\n");
1162: return html.toString();
1163: }
1164:
1165: /**
1166: * Returns the html code for the toolbar (search bar + multiactions bar).<p>
1167: *
1168: * @return html code
1169: */
1170: private String htmlToolBar() {
1171:
1172: boolean showToolBar = getMetadata().isSearchable();
1173: Iterator itMultiActions = getMetadata().getMultiActions()
1174: .iterator();
1175: while (!showToolBar && itMultiActions.hasNext()) {
1176: CmsListMultiAction multiAction = (CmsListMultiAction) itMultiActions
1177: .next();
1178: showToolBar = showToolBar || multiAction.isVisible();
1179: }
1180: if (!showToolBar) {
1181: // prevent empty table if there is nothing to display
1182: return "";
1183: }
1184: StringBuffer html = new StringBuffer(512);
1185: html
1186: .append("<table width='100%' cellspacing='0' style='margin-bottom: 5px'>\n");
1187: html.append("\t<tr>\n");
1188: html.append(m_metadata.htmlSearchBar());
1189: html.append(m_metadata.htmlMultiActionBar());
1190: html.append("\t</tr>\n");
1191: html.append("</table>\n");
1192: return html.toString();
1193: }
1194: }
|