001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.gwt.client.ui.input;
029
030import org.opencms.util.CmsPair;
031import org.opencms.util.CmsStringUtil;
032
033import java.util.ArrayList;
034import java.util.HashSet;
035import java.util.LinkedHashMap;
036import java.util.List;
037import java.util.Map;
038import java.util.Set;
039
040import com.google.gwt.user.client.ui.Grid;
041
042/**
043 * Implements a select cell that can contain multiple entries.
044 * And its value is a list of all selected entry values.
045 * The {@link #getValue()} returns the parsed String
046 * representation of the selected values, using a pipe
047 * '|' as separator.<p>
048 *
049 * @since 8.5.0
050 */
051public class CmsMultiSelectCell extends A_CmsSelectCell {
052
053    /** The list of checkboxes. */
054    private List<CmsCheckBox> m_checkboxes = new ArrayList<CmsCheckBox>();
055
056    /** The Grid panel. */
057    private Grid m_checkboxWrapper = new Grid();
058
059    /** The select options of the multi check box. */
060    private Map<String, String> m_items = new LinkedHashMap<String, String>();
061
062    /** The value of the selection text. */
063    private String m_openerText;
064
065    /**
066     * Creates a CmsMultiSelectCell.<p>
067     *
068     * @param optins the values witch should be shown
069     */
070    @SuppressWarnings("boxing")
071    public CmsMultiSelectCell(Map<String, CmsPair<String, Boolean>> optins) {
072
073        int count = optins.size();
074        int i = 0, y = 0;
075        Map<String, String> items = new LinkedHashMap<String, String>();
076        m_checkboxWrapper = getGridLayout(count);
077        int modolo = m_checkboxWrapper.getColumnCount();
078        for (Map.Entry<String, CmsPair<String, Boolean>> entry : optins.entrySet()) {
079            String value = entry.getKey();
080            items.put(value, entry.getValue().getFirst());
081            CmsCheckBox checkbox = new CmsCheckBox(value);
082            // wrap the check boxes in FlowPanels to arrange them vertically
083            m_checkboxWrapper.setWidget(y, i % modolo, checkbox);
084            i++;
085            if ((i % modolo) == 0) {
086                y++;
087            }
088            checkbox.setChecked(Boolean.valueOf(entry.getValue().getSecond()));
089            m_checkboxes.add(checkbox);
090        }
091        m_items = new LinkedHashMap<String, String>(items);
092        initWidget(m_checkboxWrapper);
093    }
094
095    /**
096     * Returns the selected CmsCheckBox.<p>
097     *
098     * @param i the value of the selected CmsCheckBox
099     * @return CmsCheckBox Returns the selected CmsCheckBox
100     */
101    public CmsCheckBox get(int i) {
102
103        return m_checkboxes.get(i);
104    }
105
106    /**
107     * Returns all CmsSelectBoxes.<p>
108     *
109     * @return a list of CmsCheckBox
110     */
111    public List<CmsCheckBox> getCheckbox() {
112
113        return m_checkboxes;
114    }
115
116    /**
117     * Returns the opener text.<p>
118     *
119     * @return the opener text
120     */
121    public String getOpenerText() {
122
123        return m_openerText;
124    }
125
126    /**
127     * Returns the set of values of the selected checkboxes.<p>
128     *
129     * @return a set of strings
130     */
131    public Set<String> getSelected() {
132
133        Set<String> result = new HashSet<String>();
134        int i = 0;
135        for (Map.Entry<String, String> entry : m_items.entrySet()) {
136            String key = entry.getKey();
137            CmsCheckBox checkBox = m_checkboxes.get(i);
138            if (checkBox.isChecked()) {
139                result.add(key);
140            }
141            i += 1;
142        }
143        return result;
144    }
145
146    /**
147     * @see org.opencms.gwt.client.ui.input.A_CmsSelectCell#getValue()
148     */
149    @Override
150    public String getValue() {
151
152        List<String> selected = new ArrayList<String>(getSelected());
153        return CmsStringUtil.listAsString(selected, "|");
154    }
155
156    /**
157    * Sets the opener text.<p>
158    *
159    * @param openerText the new opener text
160    */
161    public void setOpenerText(String openerText) {
162
163        if (openerText != null) {
164            m_openerText = openerText;
165        }
166    }
167
168    /**
169     * Helper function to generate the grid layout.<p>
170     * @param count
171     *
172     *@return the new grid
173     * */
174    private Grid getGridLayout(int count) {
175
176        Grid grid = new Grid();
177        int x, y, z, modolo = 0;
178        x = count % 3;
179        y = count % 5;
180        z = count % 7;
181        if ((z <= y) && (z <= x)) {
182            modolo = 7;
183        } else if ((y <= z) && (y <= x)) {
184            modolo = 5;
185        } else if ((x <= z) && (x <= y)) {
186            modolo = 3;
187        }
188
189        if (count < modolo) {
190            grid = new Grid(count, 1);
191        } else if ((count % modolo) == 0) {
192            grid = new Grid(count / modolo, modolo);
193        } else {
194            grid = new Grid((count / modolo) + 1, modolo);
195        }
196        return grid;
197    }
198
199}