/******************************************************************************* * Copyright (C) 2011 Angelo Zerr <angelo.zerr@gmail.com>, Pascal Leclercq <pascal.leclercq@gmail.com> * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Angelo ZERR - initial API and implementation * Pascal Leclercq - initial API and implementation *******************************************************************************/ package org.eclipse.nebula.widgets.pagination; import java.util.Locale; import org.eclipse.nebula.widgets.pagination.renderers.ICompositeRendererFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Widget; /** * Abstract class SWT {@link Composite} which host a SWT {@link Widget} linked * to a pagination controller to display data with pagination. The * {@link AbstractPaginationWidget#refreshPage()} must be implemented to load * paginated data and update the total element of the controller. * * This composite is able to to add another {@link Composite} on the top and on * the bottom of the widget. For instance you can display navigation page links * on the top of the widget. * * @param<W> the widget linked to the pagination controller. * @param <T> * the pagination controller to observe to refresh paginated data in * the widget and update it with total elements. */ public abstract class AbstractPaginationWidget<W extends Widget> extends AbstractPageControllerComposite { /** the widget hosted by the composite (ex: table) **/ private W widget; /** * the page renderer factory to use to create a Composite on the top of the * widget. **/ private ICompositeRendererFactory pageRendererTopFactory; /** * the page renderer factory to use to create a Composite on the bottom of * the widget. **/ private ICompositeRendererFactory pageRendererBottomFactory; /** * The composite created by the pageRendererTopFactory on the top of the * widget (null if none Composite must be added) **/ private Composite compositeTop; /** * The composite created by the pageRendererBottomFactory on the bottom of * the widget (null if none Composite must be added) **/ private Composite compositeBottom; /** the page loader used to load paginated data list */ private IPageLoader pageLoader; /** * The page loader handler to observe before/after page loading process **/ private IPageLoaderHandler pageLoaderHandler; /** * Constructs a new instance of this class given its parent and a style * value describing its behavior and appearance. Default page size is used * here. * * @param parent * a widget which will be the parent of the new instance (cannot * be null) * @param style * the style of widget to construct * * @param pageRendererTopFactory * the page renderer factory used to create a SWT Composite on * the top of the widget. Null if none Composite must be created. * @param pageRendererBottomFactory * the page renderer factory used to create a SWT Composite on * the bottom of the widget. Null if none Composite must be * created. * */ public AbstractPaginationWidget(Composite parent, int style, IPageContentProvider pageContentProvider, ICompositeRendererFactory pageRendererTopFactory, ICompositeRendererFactory pageRendererBottomFactory) { this(parent, style, DEFAULT_PAGE_SIZE, pageContentProvider, pageRendererTopFactory, pageRendererBottomFactory, true); } /** * Constructs a new instance of this class given its parent and a style * value describing its behavior and appearance. * * @param parent * a widget which will be the parent of the new instance (cannot * be null) * @param style * the style of widget to construct * @param pageSize * size of the page (number items displayed per page). * * @param pageRendererTopFactory * the page renderer factory used to create a SWT Composite on * the top of the widget. Null if none Composite must be created. * @param pageRendererBottomFactory * the page renderer factory used to create a SWT Composite on * the bottom of the widget. Null if none Composite must be * created. * */ public AbstractPaginationWidget(Composite parent, int style, int pageSize, IPageContentProvider pageContentProvider, ICompositeRendererFactory pageRendererTopFactory, ICompositeRendererFactory pageRendererBottomFactory) { this(parent, style, pageSize, pageContentProvider, pageRendererTopFactory, pageRendererBottomFactory, true); } /** * Constructs a new instance of this class given its parent and a style * value describing its behavior and appearance. * * @param parent * a widget which will be the parent of the new instance (cannot * be null) * @param style * the style of widget to construct * @param pageSize * size of the page (number items displayed per page). * * @param pageRendererTopFactory * the page renderer factory used to create a SWT Composite on * the top of the widget. Null if none Composite must be created. * @param pageRendererBottomFactory * the page renderer factory used to create a SWT Composite on * the bottom of the widget. Null if none Composite must be * created. * * @param createUI * true if the UI must be created and false otherwise. * */ protected AbstractPaginationWidget(Composite parent, int style, int pageSize, IPageContentProvider pageContentProvider, ICompositeRendererFactory pageRendererTopFactory, ICompositeRendererFactory pageRendererBottomFactory, boolean createUI) { super(parent, style, null, pageSize, pageContentProvider, false); this.pageRendererTopFactory = pageRendererTopFactory; this.pageRendererBottomFactory = pageRendererBottomFactory; if (createUI) { createUI(this); } } @Override protected void createUI(Composite parent) { this.setLayout(new GridLayout()); // Create top composite if needed this.compositeTop = createCompositeTop(parent); // Create the widget linked to the controller. this.widget = createWidget(parent); PaginationHelper.setController(widget, getController()); // Create bottom composite if needed this.compositeBottom = createCompositeBottom(parent); // set default locale super.setLocale(Locale.getDefault()); } /** * Create top composite if needed. * * @param parent */ protected Composite createCompositeTop(Composite parent) { ICompositeRendererFactory pageRendererTopFactory = getPageRendererTopFactory(); if (pageRendererTopFactory != null) { Composite compositeTop = pageRendererTopFactory.createComposite( parent, SWT.NONE, getController()); if (compositeTop != null) { compositeTop.setLayoutData(new GridData( GridData.FILL_HORIZONTAL)); return compositeTop; } } return null; } /** * Create bottom composite if needed. * * @param parent */ protected Composite createCompositeBottom(Composite parent) { ICompositeRendererFactory pageRendererBottomFactory = getPageRendererBottomFactory(); if (pageRendererBottomFactory != null) { Composite compositeBottom = pageRendererBottomFactory .createComposite(parent, SWT.NONE, getController()); if (compositeBottom != null) { compositeBottom.setLayoutData(new GridData( GridData.FILL_HORIZONTAL)); } return compositeBottom; } return null; } /** * Returns the page renderer factory to use to create a Composite on the top * of the widget. * * @return */ public ICompositeRendererFactory getPageRendererTopFactory() { return pageRendererTopFactory; } /** * Returns the page renderer factory to use to create a Composite on the * bottom of the widget. * * @return */ public ICompositeRendererFactory getPageRendererBottomFactory() { return pageRendererBottomFactory; } /** * Returns the composite created by the pageRendererTopFactory on the top of * the widget (null if none Composite must be added) * * @return */ public Composite getCompositeTop() { return compositeTop; } /** * Returns the composite created by the pageRendererTopFactory on the bottom * of the widget (null if none Composite must be added) * * @return */ public Composite getCompositeBottom() { return compositeBottom; } /* * (non-Javadoc) * * @see * org.eclipse.nebula.widgets.pagination.PageChangedListener#pageIndexChanged * (int, int, org.eclipse.nebula.widgets.pagination.PaginationController) */ public void pageIndexChanged(int oldPageNumber, int newPageNumber, PageableController controller) { // when selected page changed, refresh the page internalRefreshPage(); } /* * (non-Javadoc) * * @see org.eclipse.nebula.widgets.pagination.PageChangedListener# * totalElementsChanged(long, long, * org.eclipse.nebula.widgets.pagination.PaginationController) */ public void totalElementsChanged(long oldTotalElements, long newTotalElements, PageableController controller) { } /* * (non-Javadoc) * * @see * org.eclipse.nebula.widgets.pagination.PageChangedListener#sortChanged * (java.lang.String, java.lang.String, int, int, * org.eclipse.nebula.widgets.pagination.PaginationController) */ public void sortChanged(String oldPopertyName, String propertyName, int oldSortDirection, int sortDirection, PageableController paginationController) { refreshPage(true); } /* * (non-Javadoc) * * @see * org.eclipse.nebula.widgets.pagination.PageChangedListener#pageSizeChanged * (int, int, org.eclipse.nebula.widgets.pagination.PaginationController) */ public void pageSizeChanged(int oldPageSize, int newPageSize, PageableController paginationController) { refreshPage(false); } /** * Refresh the page. * * @param reset * true if page index must be reseted to the first page index * before refresh page and false otherwise. */ public void refreshPage(boolean reset) { if (reset) { getController().reset(); } else { refreshPage(); } } @SuppressWarnings("rawtypes") @Override public void setLocale(Locale locale) { super.setLocale(locale); if (compositeTop != null && compositeTop instanceof AbstractPageControllerComposite) { ((AbstractPageControllerComposite) compositeTop).setLocale(locale); } if (compositeBottom != null && compositeBottom instanceof AbstractPageControllerComposite) { ((AbstractPageControllerComposite) compositeBottom) .setLocale(locale); } } /** * Refresh page by using page loader handler. * * @param reset */ private void internalRefreshPage() { if (pageLoaderHandler == null) { refreshPage(); } else { PageableController controller = getController(); pageLoaderHandler.onBeforePageLoad(controller); try { refreshPage(); pageLoaderHandler.onAfterPageLoad(controller, null); } catch (Throwable e) { pageLoaderHandler.onAfterPageLoad(controller, e); } } } /** * Set the page loader handler to observe before/after page loading process. * * @param pageLoaderHandler */ public void setPageLoaderHandler(IPageLoaderHandler pageLoaderHandler) { this.pageLoaderHandler = pageLoaderHandler; } /** * Returns the page loader handler to observe before/after page loading * process. * * @return */ public IPageLoaderHandler getPageLoaderHandler() { return pageLoaderHandler; } /** * Set the page loader to use to load paginated list. * * @param pageLoader */ public void setPageLoader(IPageLoader pageLoader) { this.pageLoader = pageLoader; } /** * Returns the page loader to use to load paginated list. * * @return */ public IPageLoader getPageLoader() { return pageLoader; } /** * Returns the widget. * * @return */ public W getWidget() { return widget; } /** * Create the widget linked to the pagination controller. * * @param parent * a widget which will be the parent of the new instance (cannot * be null) * @return */ protected abstract W createWidget(Composite parent); /** * Refresh the page. This method should load paginated list data, update the * viewer and update the pagination controller with total elements. */ public abstract void refreshPage(); }