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.ui.dataview; 029 030import org.opencms.ui.CmsVaadinUtils; 031import org.opencms.ui.Messages; 032 033import java.util.List; 034 035import com.google.common.collect.Lists; 036import com.vaadin.server.FontAwesome; 037import com.vaadin.ui.Alignment; 038import com.vaadin.ui.Button; 039import com.vaadin.ui.Button.ClickEvent; 040import com.vaadin.ui.Button.ClickListener; 041import com.vaadin.v7.ui.HorizontalLayout; 042import com.vaadin.v7.ui.Label; 043 044/** 045 * Set of buttons allowing the user to navigate between pages in a paged list.<p> 046 */ 047public class CmsPagingControls extends HorizontalLayout { 048 049 /** 050 * Callback which is called when the user changes the page.<p> 051 */ 052 public static interface I_PagingCallback { 053 054 /** 055 * Method which is called when the user changes the page.<p> 056 * 057 * @param page the page number 058 */ 059 void pageChanged(int page); 060 } 061 062 /** Serial version id. */ 063 private static final long serialVersionUID = 1L; 064 065 /** The registered callback. */ 066 private List<I_PagingCallback> m_callbacks = Lists.newArrayList(); 067 068 /** The page number. */ 069 private int m_page; 070 071 /** Button to go to the next page. */ 072 private Button m_forward = new Button(FontAwesome.FORWARD); 073 074 /** Button to go to the last page. */ 075 private Button m_fastForward = new Button(FontAwesome.FAST_FORWARD); 076 077 /** Button to go to the previous page. */ 078 private Button m_back = new Button(FontAwesome.BACKWARD); 079 080 /** Button to go the first page. */ 081 private Button m_fastBack = new Button(FontAwesome.FAST_BACKWARD); 082 083 /** Label to show the current page number. */ 084 private Label m_label = new Label(); 085 086 /** The results label. */ 087 private Label m_resultsLabel = new Label(); 088 089 /** The index of the last page. */ 090 private int m_lastPage; 091 092 /** The page size. */ 093 private int m_pageSize; 094 095 /** The result count. */ 096 private int m_resultCount; 097 098 /** 099 * Creates a new instance.<p> 100 */ 101 public CmsPagingControls() { 102 setMargin(true); 103 addComponent(m_label); 104 addComponent(m_fastBack); 105 addComponent(m_back); 106 addComponent(m_forward); 107 addComponent(m_fastForward); 108 addComponent(m_resultsLabel); 109 m_resultsLabel.setWidthUndefined(); 110 m_label.setWidthUndefined(); 111 setExpandRatio(m_resultsLabel, 1.0f); 112 setComponentAlignment(m_resultsLabel, Alignment.TOP_RIGHT); 113 setSpacing(true); 114 115 m_forward.addClickListener(new ClickListener() { 116 117 private static final long serialVersionUID = 1L; 118 119 @SuppressWarnings("synthetic-access") 120 public void buttonClick(ClickEvent event) { 121 122 setPage(Math.min(m_lastPage, m_page + 1), true); 123 updateButtons(); 124 } 125 }); 126 127 m_fastForward.addClickListener(new ClickListener() { 128 129 private static final long serialVersionUID = 1L; 130 131 @SuppressWarnings("synthetic-access") 132 public void buttonClick(ClickEvent event) { 133 134 setPage(m_lastPage, true); 135 updateButtons(); 136 137 } 138 }); 139 m_back.addClickListener(new ClickListener() { 140 141 private static final long serialVersionUID = 1L; 142 143 @SuppressWarnings("synthetic-access") 144 public void buttonClick(ClickEvent event) { 145 146 setPage(Math.max(0, m_page - 1), true); 147 updateButtons(); 148 149 } 150 151 }); 152 153 m_fastBack.addClickListener(new ClickListener() { 154 155 private static final long serialVersionUID = 1L; 156 157 public void buttonClick(ClickEvent event) { 158 159 setPage(0, true); 160 updateButtons(); 161 162 } 163 }); 164 } 165 166 /** 167 * Adds a new page change callback.<p> 168 * 169 * @param callback the callback 170 */ 171 public void addCallback(I_PagingCallback callback) { 172 173 m_callbacks.add(callback); 174 } 175 176 /** 177 * Notifies the registered listeners of a page change.<p> 178 * 179 * @param pageNum the page index 180 */ 181 public void firePageChanged(int pageNum) { 182 183 for (I_PagingCallback callback : m_callbacks) { 184 callback.pageChanged(pageNum); 185 } 186 } 187 188 /** 189 * Gets the current page number.<p> 190 * 191 * @return the current page number 192 */ 193 public int getPage() { 194 195 return m_page; 196 } 197 198 /** 199 * Removes a registered callback.<p> 200 * 201 * @param callback the callback to remove 202 */ 203 public void removeCallback(I_PagingCallback callback) { 204 205 m_callbacks.remove(callback); 206 } 207 208 /** 209 * Resets the paging controls (used when the size of the underlying list changes).<p> 210 * 211 * @param resultCount total number of results 212 * @param pageSize size of a page 213 * @param fireChanged true if the listeners should be notified 214 */ 215 public void reset(int resultCount, int pageSize, boolean fireChanged) { 216 217 m_lastPage = resultCount == 0 ? 0 : (resultCount - 1) / pageSize; 218 m_resultCount = resultCount; 219 m_pageSize = pageSize; 220 setPage(0, false); 221 updateButtons(); 222 if (fireChanged) { 223 firePageChanged(0); 224 } 225 } 226 227 /** 228 * Sets the page index.<p> 229 * 230 * @param page the page index 231 * @param fireChanged true if the registered listeners should be notified 232 */ 233 public void setPage(int page, boolean fireChanged) { 234 235 m_page = page; 236 m_label.setValue("( " + (1 + m_page) + " / " + (m_lastPage + 1) + " )"); 237 int start = (m_page * m_pageSize) + 1; 238 int end = Math.min((start + m_pageSize) - 1, m_resultCount); 239 String resultsMsg = CmsVaadinUtils.getMessageText( 240 Messages.GUI_DATAVIEW_RESULTS_3, 241 "" + start, 242 "" + end, 243 "" + m_resultCount); 244 m_resultsLabel.setValue(start <= end ? resultsMsg : ""); 245 if (fireChanged) { 246 firePageChanged(page); 247 } 248 } 249 250 /** 251 * Updates the button state, i.e. enables/disables the buttons depending on whether we are on the first or last page or not.<p> 252 */ 253 public void updateButtons() { 254 255 for (Button button : new Button[] {m_forward, m_fastForward}) { 256 button.setEnabled(m_page < m_lastPage); 257 } 258 for (Button button : new Button[] {m_back, m_fastBack}) { 259 button.setEnabled(m_page > 0); 260 } 261 } 262 263}