001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://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: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://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 103 setMargin(true); 104 addComponent(m_label); 105 addComponent(m_fastBack); 106 addComponent(m_back); 107 addComponent(m_forward); 108 addComponent(m_fastForward); 109 addComponent(m_resultsLabel); 110 m_resultsLabel.setWidthUndefined(); 111 m_label.setWidthUndefined(); 112 setExpandRatio(m_resultsLabel, 1.0f); 113 setComponentAlignment(m_resultsLabel, Alignment.TOP_RIGHT); 114 setSpacing(true); 115 116 m_forward.addClickListener(new ClickListener() { 117 118 private static final long serialVersionUID = 1L; 119 120 @SuppressWarnings("synthetic-access") 121 public void buttonClick(ClickEvent event) { 122 123 setPage(Math.min(m_lastPage, m_page + 1), true); 124 updateButtons(); 125 } 126 }); 127 128 m_fastForward.addClickListener(new ClickListener() { 129 130 private static final long serialVersionUID = 1L; 131 132 @SuppressWarnings("synthetic-access") 133 public void buttonClick(ClickEvent event) { 134 135 setPage(m_lastPage, true); 136 updateButtons(); 137 138 } 139 }); 140 m_back.addClickListener(new ClickListener() { 141 142 private static final long serialVersionUID = 1L; 143 144 @SuppressWarnings("synthetic-access") 145 public void buttonClick(ClickEvent event) { 146 147 setPage(Math.max(0, m_page - 1), true); 148 updateButtons(); 149 150 } 151 152 }); 153 154 m_fastBack.addClickListener(new ClickListener() { 155 156 private static final long serialVersionUID = 1L; 157 158 public void buttonClick(ClickEvent event) { 159 160 setPage(0, true); 161 updateButtons(); 162 163 } 164 }); 165 } 166 167 /** 168 * Adds a new page change callback.<p> 169 * 170 * @param callback the callback 171 */ 172 public void addCallback(I_PagingCallback callback) { 173 174 m_callbacks.add(callback); 175 } 176 177 /** 178 * Notifies the registered listeners of a page change.<p> 179 * 180 * @param pageNum the page index 181 */ 182 public void firePageChanged(int pageNum) { 183 184 for (I_PagingCallback callback : m_callbacks) { 185 callback.pageChanged(pageNum); 186 } 187 } 188 189 /** 190 * Gets the current page number.<p> 191 * 192 * @return the current page number 193 */ 194 public int getPage() { 195 196 return m_page; 197 } 198 199 /** 200 * Removes a registered callback.<p> 201 * 202 * @param callback the callback to remove 203 */ 204 public void removeCallback(I_PagingCallback callback) { 205 206 m_callbacks.remove(callback); 207 } 208 209 /** 210 * Resets the paging controls (used when the size of the underlying list changes).<p> 211 * 212 * @param resultCount total number of results 213 * @param pageSize size of a page 214 * @param fireChanged true if the listeners should be notified 215 */ 216 public void reset(int resultCount, int pageSize, boolean fireChanged) { 217 218 m_lastPage = resultCount == 0 ? 0 : (resultCount - 1) / pageSize; 219 m_resultCount = resultCount; 220 m_pageSize = pageSize; 221 setPage(0, false); 222 updateButtons(); 223 if (fireChanged) { 224 firePageChanged(0); 225 } 226 } 227 228 /** 229 * Sets the page index.<p> 230 * 231 * @param page the page index 232 * @param fireChanged true if the registered listeners should be notified 233 */ 234 public void setPage(int page, boolean fireChanged) { 235 236 m_page = page; 237 m_label.setValue("( " + (1 + m_page) + " / " + (m_lastPage + 1) + " )"); 238 int start = (m_page * m_pageSize) + 1; 239 int end = Math.min((start + m_pageSize) - 1, m_resultCount); 240 String resultsMsg = CmsVaadinUtils.getMessageText( 241 Messages.GUI_DATAVIEW_RESULTS_3, 242 "" + start, 243 "" + end, 244 "" + m_resultCount); 245 m_resultsLabel.setValue(start <= end ? resultsMsg : ""); 246 if (fireChanged) { 247 firePageChanged(page); 248 } 249 } 250 251 /** 252 * Updates the button state, i.e. enables/disables the buttons depending on whether we are on the first or last page or not.<p> 253 */ 254 public void updateButtons() { 255 256 for (Button button : new Button[] {m_forward, m_fastForward}) { 257 button.setEnabled(m_page < m_lastPage); 258 } 259 for (Button button : new Button[] {m_back, m_fastBack}) { 260 button.setEnabled(m_page > 0); 261 } 262 } 263 264}