Java tutorial
/* * Copyright 2010, 2011 Renaud Brub * * This file is part of PIGE. * * PIGE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * PIGE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PIGE. If not, see <http://www.gnu.org/licenses/>. */ package ca.qc.cegepoutaouais.tge.pige.client.ui.view; import ca.qc.cegepoutaouais.tge.pige.client.HTMLLoanFormatter; import ca.qc.cegepoutaouais.tge.pige.client.LoanStatus; import ca.qc.cegepoutaouais.tge.pige.client.LoanStatus.LoanStatusModel; import ca.qc.cegepoutaouais.tge.pige.client.services.ManagementServiceAsync; import ca.qc.cegepoutaouais.tge.pige.client.ui.AppEvents; import ca.qc.cegepoutaouais.tge.pige.client.ui.AppWidgets; import ca.qc.cegepoutaouais.tge.pige.client.ui.widget.LoanAdvancedSearchBox; import ca.qc.cegepoutaouais.tge.pige.client.ui.widget.LoanManagementSearchBox; import ca.qc.cegepoutaouais.tge.pige.client.ui.widget.LoanStateFilterBox; import ca.qc.cegepoutaouais.tge.pige.client.PIGE; import ca.qc.cegepoutaouais.tge.pige.client.PigeUtil; import ca.qc.cegepoutaouais.tge.pige.client.PrintViewer; import ca.qc.cegepoutaouais.tge.pige.client.resources.Resources; import ca.qc.cegepoutaouais.tge.pige.client.ui.dialog.AbstractCEVDialog.CEV; import ca.qc.cegepoutaouais.tge.pige.client.ui.dialog.ItemCEVDialog; import ca.qc.cegepoutaouais.tge.pige.client.ui.widget.AbstractFieldListener; import ca.qc.cegepoutaouais.tge.pige.client.ui.widget.AbstractFieldListener.FieldUpdater; import ca.qc.cegepoutaouais.tge.pige.client.ui.widget.StatusBar; import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Item; import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Loan; import ca.qc.cegepoutaouais.tge.pige.dao.pojos.User; import com.extjs.gxt.ui.client.Registry; import com.extjs.gxt.ui.client.core.Template; import com.extjs.gxt.ui.client.data.BaseFilterConfig; import com.extjs.gxt.ui.client.data.BaseListFilterConfig; import com.extjs.gxt.ui.client.data.BasePagingLoadConfig; import com.extjs.gxt.ui.client.data.BasePagingLoader; import com.extjs.gxt.ui.client.data.BaseStringFilterConfig; import com.extjs.gxt.ui.client.data.BeanModel; import com.extjs.gxt.ui.client.data.BeanModelReader; import com.extjs.gxt.ui.client.data.FilterConfig; import com.extjs.gxt.ui.client.data.LoadConfig; import com.extjs.gxt.ui.client.data.LoadEvent; import com.extjs.gxt.ui.client.data.ModelData; import com.extjs.gxt.ui.client.data.PagingLoadConfig; import com.extjs.gxt.ui.client.data.PagingLoadResult; import com.extjs.gxt.ui.client.data.RpcProxy; import com.extjs.gxt.ui.client.event.ButtonEvent; import com.extjs.gxt.ui.client.event.ComponentEvent; import com.extjs.gxt.ui.client.event.EventType; import com.extjs.gxt.ui.client.event.Events; import com.extjs.gxt.ui.client.event.FieldEvent; import com.extjs.gxt.ui.client.event.GridEvent; import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.event.MenuEvent; import com.extjs.gxt.ui.client.event.MessageBoxEvent; import com.extjs.gxt.ui.client.event.SelectionListener; import com.extjs.gxt.ui.client.mvc.AppEvent; import com.extjs.gxt.ui.client.mvc.Controller; import com.extjs.gxt.ui.client.store.GroupingStore; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.store.Store; import com.extjs.gxt.ui.client.store.StoreSorter; import com.extjs.gxt.ui.client.util.Params; import com.extjs.gxt.ui.client.widget.ContentPanel; import com.extjs.gxt.ui.client.widget.Html; import com.extjs.gxt.ui.client.widget.LayoutContainer; import com.extjs.gxt.ui.client.widget.MessageBox; import com.extjs.gxt.ui.client.widget.button.Button; import com.extjs.gxt.ui.client.widget.button.ButtonBar; import com.extjs.gxt.ui.client.widget.button.ToggleButton; import com.extjs.gxt.ui.client.widget.form.CheckBox; import com.extjs.gxt.ui.client.widget.form.ComboBox; import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction; import com.extjs.gxt.ui.client.widget.form.DateField; import com.extjs.gxt.ui.client.widget.form.NumberField; import com.extjs.gxt.ui.client.widget.form.TextField; import com.extjs.gxt.ui.client.widget.grid.CellEditor; import com.extjs.gxt.ui.client.widget.grid.ColumnConfig; import com.extjs.gxt.ui.client.widget.grid.ColumnData; import com.extjs.gxt.ui.client.widget.grid.ColumnModel; import com.extjs.gxt.ui.client.widget.grid.EditorGrid; import com.extjs.gxt.ui.client.widget.grid.Grid; import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer; import com.extjs.gxt.ui.client.widget.grid.GridGroupRenderer; import com.extjs.gxt.ui.client.widget.grid.GroupColumnData; import com.extjs.gxt.ui.client.widget.grid.GroupingView; import com.extjs.gxt.ui.client.widget.grid.filters.DateFilter; import com.extjs.gxt.ui.client.widget.grid.filters.GridFilters; import com.extjs.gxt.ui.client.widget.grid.filters.NumericFilter; import com.extjs.gxt.ui.client.widget.grid.filters.StringFilter; import com.extjs.gxt.ui.client.widget.layout.RowData; import com.extjs.gxt.ui.client.widget.layout.RowLayout; import com.extjs.gxt.ui.client.widget.menu.AdapterMenuItem; import com.extjs.gxt.ui.client.widget.menu.HeaderMenuItem; import com.extjs.gxt.ui.client.widget.menu.Menu; import com.extjs.gxt.ui.client.widget.menu.MenuItem; import com.extjs.gxt.ui.client.widget.menu.SeparatorMenuItem; import com.extjs.gxt.ui.client.widget.toolbar.PagingToolBar; import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem; import com.extjs.gxt.ui.client.widget.toolbar.ToolBar; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.i18n.client.NumberFormat; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.AbstractImagePrototype; import com.google.gwt.user.client.ui.Widget; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.LinkedList; import java.util.List; /** * Vue permettant d'effectuer la gestions des emprunts. * Cette mme vue peut tre visualise de trois diffrentes manires. * Ces diffrentes perspectives permettent chacune d'effectuer une tche * de faon optimale (Prt, retour, recherche). * * @author Renaud Brub */ public class LoanManagementView extends BaseView { private static Integer buttonGroupId = 0; private final String BUTTON_GROUP_TAG = "lmbg-"; private class ApprovalButtonGridCellRenderer implements GridCellRenderer<BeanModel> { public ApprovalButtonGridCellRenderer() { } @Override public Object render(final BeanModel model, String property, ColumnData config, final int rowIndex, final int colIndex, ListStore<BeanModel> store, Grid<BeanModel> grid) { String groupId = (++buttonGroupId).toString(); String toggleGroup = BUTTON_GROUP_TAG + groupId; final Loan loan = model.getBean(); ButtonBar buttonBar = new ButtonBar(); final ToggleButton acceptBtn = new ToggleButton(messages.acceptedAbbr()); final ToggleButton refuseBtn = new ToggleButton(messages.refusedAbbr()); final ToggleButton postponeBtn = new ToggleButton(messages.postponeAbbr()); acceptBtn.setWidth(50); refuseBtn.setWidth(50); postponeBtn.setWidth(50); acceptBtn.setHeight(20); refuseBtn.setHeight(20); postponeBtn.setHeight(20); acceptBtn.setToggleGroup(toggleGroup); refuseBtn.setToggleGroup(toggleGroup); postponeBtn.setToggleGroup(toggleGroup); if (loan.getStatus().equals(LoanStatus.STATUS_POSTPONED)) { postponeBtn.toggle(Boolean.TRUE); } acceptBtn.addListener(Events.Toggle, new Listener<ButtonEvent>() { @Override public void handleEvent(ButtonEvent event) { if (acceptBtn.isPressed()) { loan.setStatus(LoanStatus.STATUS_LENT); } else { loan.setStatus(LoanStatus.STATUS_PENDING); } loan.setStartDate(new Date()); setLoanDirty(model, Boolean.TRUE); } }); refuseBtn.addListener(Events.Toggle, new Listener<ButtonEvent>() { @Override public void handleEvent(ButtonEvent event) { if (refuseBtn.isPressed()) { loan.setStatus(LoanStatus.STATUS_REFUSED); } else { loan.setStatus(LoanStatus.STATUS_PENDING); } loan.setStartDate(new Date()); setLoanDirty(model, Boolean.TRUE); } }); postponeBtn.addListener(Events.Toggle, new Listener<ButtonEvent>() { @Override public void handleEvent(ButtonEvent event) { if (postponeBtn.isPressed()) { loan.setStatus(LoanStatus.STATUS_POSTPONED); } else { loan.setStatus(LoanStatus.STATUS_PENDING); } loan.setStartDate(new Date()); setLoanDirty(model, Boolean.TRUE); } }); buttonBar.add(acceptBtn); buttonBar.add(refuseBtn); buttonBar.add(postponeBtn); buttonBar.setWidth(grid.getColumnModel().getColumnWidth(colIndex) - 10); return buttonBar; } }; private class ReturnButtonGridCellRenderer implements GridCellRenderer<BeanModel> { public ReturnButtonGridCellRenderer() { } @Override public Object render(final BeanModel model, String property, ColumnData config, final int rowIndex, final int colIndex, ListStore<BeanModel> store, Grid<BeanModel> grid) { final Loan loan = model.getBean(); ButtonBar buttonBar = new ButtonBar(); final ToggleButton returnBtn = new ToggleButton(messages.returnAbbr()); returnBtn.setWidth(50); returnBtn.setHeight(20); returnBtn.addListener(Events.Toggle, new Listener<ButtonEvent>() { @Override public void handleEvent(ButtonEvent event) { if (returnBtn.isPressed()) { loan.setStatus(LoanStatus.STATUS_RETURNED); } else { loan.setStatus(LoanStatus.STATUS_LENT); } setLoanDirty(model, Boolean.TRUE); } }); buttonBar.add(returnBtn); buttonBar.setWidth(grid.getColumnModel().getColumnWidth(colIndex) - 10); return buttonBar; } }; class LoanStatusChooser extends ComboBox<LoanStatusModel> { public LoanStatusChooser() { ListStore<LoanStatusModel> listStore = new ListStore(); listStore.add(LoanStatus.getInstance().getModelList()); listStore.remove(listStore.findModel("value", LoanStatus.STATUS_SAVED)); listStore.remove(listStore.findModel("value", LoanStatus.STATUS_LATE)); setStore(listStore); setWidth(100); setDisplayField("label"); setTriggerAction(TriggerAction.ALL); setEditable(Boolean.FALSE); setForceSelection(Boolean.TRUE); } } private interface IStoreUpdater { public void updateStore(ListStore store, BeanModel model); } private class ApprovalStoreUpdater implements IStoreUpdater { @Override public void updateStore(ListStore store, BeanModel model) { if (store != null && model != null) { Loan loan = model.getBean(); String status = loan.getStatus(); if (status.equals(LoanStatus.STATUS_PENDING)) { return; } if (status.equals(LoanStatus.STATUS_POSTPONED) && showPostponedLoanCbx.getValue()) { return; } store.remove(model); } } } private class ReturnStoreUpdater implements IStoreUpdater { @Override public void updateStore(ListStore store, BeanModel model) { if (store != null && model != null) { Loan loan = model.getBean(); if (loan.getStatus().equals(LoanStatus.STATUS_RETURNED)) { store.remove(model); } } } } // 1.5.1 private final class FieldListener extends AbstractFieldListener { public FieldListener(Menu rootMenu, FieldUpdater updater) { super(rootMenu, updater); } @Override protected void fireModelsUpdate() { if (selectedLoans == null || selectedLoans.isEmpty()) { MessageBox.info(messages.information(), messages.noLoanSelected(), null); return; } //super.fireModelsUpdate(); doFireModelsUpdate(); } @Override protected void doFireModelsUpdate() { List<BeanModel> models = selectedLoans; for (BeanModel bm : models) { bm.set(updater.getProperty(), updater.getValue()); setLoanDirty(bm, Boolean.TRUE); loanStore.update(bm); } updater.getField().clear(); rootMenu.hide(); } } private int PAGE_SIZE = 25; private int SEARCH_PAGE_SIZE = 50; final String DATE_CHANGED = "dateChanged"; private LayoutContainer toolBarPanel = null; private ToolBar mainTB = null; private ToolBar secondaryTB = null; private CheckBox showPostponedLoanCbx = null; private Button updateBtn = null; private Button searchBtn = null; private Button resetBtn = null; private Button printBtn = null; // 1.5.1 private Button batchEditBtn = null; private MenuItem clearSelectedLoansMenuItem = null; private LoanStateFilterBox loanStateFilterBox = null; private LoanAdvancedSearchBox loanAdvancedSearchBox = null; private LoanManagementSearchBox loanManagementSearchBox = null; private List<FilterConfig> searchConfigList = null; private List<FilterConfig> filterConfigList = null; private List<FilterConfig> userConfigList = null; private RpcProxy<PagingLoadResult<Loan>> proxy = null; private BasePagingLoader<PagingLoadResult<ModelData>> storeLoader = null; private BasePagingLoadConfig loadConfigs = null; private Grid<BeanModel> grid = null; private GroupingStore<BeanModel> loanStore = null; private ColumnModel columnModel = null; private PagingToolBar pagingTB = null; final StatusBar statusBar = Registry.get(AppWidgets.APP_STATUS_BAR); private List<BeanModel> dirtyLoans = new ArrayList<BeanModel>(); private IStoreUpdater storeUpdater = null; private BeanModel selectedLoan = null; private String descTemplateStr = "<div class=\"pige-description-column {icon} \">" + "<span class=\"pige-description-column-text \">{desc}</span>" + "</div>"; private Boolean isPrintButtonPresent = Boolean.FALSE; // 1.5.1 private List<BeanModel> selectedLoans = new LinkedList<BeanModel>(); public LoanManagementView(Controller controller) { super(controller, ""); } @Override protected void handleEvent(AppEvent event) { super.handleEvent(event); EventType type = event.getType(); if (type == AppEvents.LOAN_APPROVAL_VIEW_EVENT) { setApprovalMode(); } else if (type == AppEvents.LOAN_RETURN_VIEW_EVENT) { setReturnMode(); } else if (type == AppEvents.LOAN_SEARCH_VIEW_EVENT) { setSearchMode(); } // 1.5.1 selectedLoans.clear(); onActivateView(); } @Override protected void initialize() { super.initialize(); proxy = new RpcProxy<PagingLoadResult<Loan>>() { @Override protected void load(Object loadConfig, final AsyncCallback<PagingLoadResult<Loan>> callback) { statusBar.setBusyText(messages.loading()); // Obtenir le nombre de rle demand partir du service RPC. ManagementServiceAsync rpcService = Registry.get(PIGE.MANAGEMENT_SERVICE); rpcService.getLoans((PagingLoadConfig) loadConfig, new AsyncCallback<PagingLoadResult<Loan>>() { @Override public void onSuccess(PagingLoadResult result) { statusBar.getStatus().clearStatus(messages.loadDone()); callback.onSuccess(result); } @Override public void onFailure(Throwable caught) { callback.onFailure(caught); } }); // getLoans() } // load() }; // new RpcProxy loadConfigs = new BasePagingLoadConfig(); storeLoader = new BasePagingLoader<PagingLoadResult<ModelData>>(proxy, new BeanModelReader()) { @Override protected LoadConfig newLoadConfig() { return loadConfigs; } }; storeLoader.setRemoteSort(false); loanStore = new GroupingStore<BeanModel>(storeLoader) { /** * Permet de retirer les emprunts sauvegards de la liste afficher. */ @Override protected void onLoad(LoadEvent event) { PigeUtil.filterSavedLoans(event); selectedLoans.clear();// 1.5.1 super.onLoad(event); } }; pagingTB = new PagingToolBar(PAGE_SIZE); pagingTB.bind(storeLoader); List<ColumnConfig> configs = new ArrayList<ColumnConfig>(); // 1.5.1 ColumnConfig selectorCC = new ColumnConfig(null, "", 25); selectorCC.setRenderer(new GridCellRenderer() { @Override public Object render(final ModelData model, String property, ColumnData config, int rowIndex, int colIndex, ListStore store, Grid grid) { final CheckBox cbox = new CheckBox(); cbox.addListener(Events.Change, new Listener<FieldEvent>() { @Override public void handleEvent(FieldEvent be) { BeanModel bm = (BeanModel) model; if (cbox.getValue() && !selectedLoans.contains(bm)) { selectedLoans.add(bm); } else if (!cbox.getValue()) { selectedLoans.remove(bm); } } }); BeanModel bm = (BeanModel) model; if (selectedLoans.contains(bm)) { cbox.setValue(Boolean.TRUE); } return cbox; } }); ColumnConfig ownerCC = new ColumnConfig(Loan.USER_REF, "user", 50); ColumnConfig statusCC = new ColumnConfig(Loan.STATUS_REF, messages.accepted() + " / " + messages.refused() + " / " + messages.postponed(), 150); ColumnConfig quantityCC = new ColumnConfig(Loan.QUANTITY_REF, messages.quantity(), 50); NumberFormat nf = NumberFormat.getFormat(PIGE.QUANTITY_FORMAT); quantityCC.setNumberFormat(nf); ColumnConfig descriptionCC = new ColumnConfig(Loan.DESCRIPTION_REF, messages.description(), 250); final Template descTemplate = new Template(descTemplateStr); descTemplate.compile(); descriptionCC.setRenderer(new GridCellRenderer() { @Override public Object render(ModelData model, String property, ColumnData config, int rowIndex, int colIndex, ListStore store, Grid grid) { Loan loan = (Loan) ((BeanModel) model).getBean(); Params p = new Params(); p.set("desc", model.get(property)); if (loan.getItemId() != null) { p.set("icon", "pige-icon-visible"); } else { p.set("icon", "pige-icon-hidden"); } return descTemplate.applyTemplate(p); } }); ColumnConfig startDateCC = new ColumnConfig(Loan.START_DATE_REF, messages.loanDate(), 100); DateTimeFormat dtf = DateTimeFormat.getFormat(PIGE.TERM_DATE_FORMAT); startDateCC.setDateTimeFormat(dtf); ColumnConfig termCC = new ColumnConfig(Loan.TERM_REF, messages.term(), 100); termCC.setDateTimeFormat(dtf); ColumnConfig tagCC = new ColumnConfig(Loan.TAG_REF, messages.tag(), 100); ColumnConfig noteCC = new ColumnConfig(Loan.NOTE_REF, messages.note(), 100); // 1.5.1 configs.add(selectorCC); configs.add(ownerCC); configs.add(statusCC); configs.add(quantityCC); configs.add(descriptionCC); configs.add(startDateCC); configs.add(termCC); configs.add(tagCC); configs.add(noteCC); columnModel = new ColumnModel(configs); GroupingView view = new GroupingView(); view.setShowGroupedColumn(false); view.setForceFit(true); view.setGroupRenderer(new GridGroupRenderer() { @Override public String render(GroupColumnData data) { BeanModel model = (BeanModel) loanStore.getAt(data.startRow); Loan loan = model.getBean(); User user = loan.getUser(); String id = (user.getLoanNo() != null ? user.getLoanNo() : user.getIdentifier()); return "[" + id + "] " + user.getLastname() + ", " + user.getFirstname(); } }); loanStore.setStoreSorter(new StoreSorter<BeanModel>() { @Override public int compare(Store<BeanModel> store, BeanModel m1, BeanModel m2, String property) { if (property.equals(User.LOAN_NO_REF)) { Loan l1 = m1.getBean(); Loan l2 = m2.getBean(); User u1 = l1.getUser(); User u2 = l2.getUser(); return u1.getLoanNo().compareTo(u2.getLoanNo()); } else { return super.compare(store, m1, m2, property); } } }); loanStore.groupBy(Loan.USER_REF); GridFilters filters = new GridFilters(); filters.setLocal(true); NumericFilter qtyFilter = new NumericFilter(Loan.QUANTITY_REF); StringFilter descFilter = new StringFilter(Loan.DESCRIPTION_REF); DateFilter startDateFilter = new DateFilter(Loan.START_DATE_REF); DateFilter termFilter = new DateFilter(Loan.TERM_REF); StringFilter tagFilter = new StringFilter(Loan.TAG_REF); StringFilter noteFilter = new StringFilter(Loan.NOTE_REF); filters.addFilter(qtyFilter); filters.addFilter(descFilter); filters.addFilter(startDateFilter); filters.addFilter(termFilter); filters.addFilter(tagFilter); filters.addFilter(noteFilter); grid = new EditorGrid<BeanModel>(loanStore, columnModel); grid.setView(view); grid.setLoadMask(true); grid.setBorders(false); grid.setAutoExpandColumn(Loan.DESCRIPTION_REF); grid.getView().setAutoFill(true); grid.getView().setEmptyText(messages.noLoanToShow()); grid.setTrackMouseOver(true); grid.addListener(Events.AfterEdit, new GridEditListener()); grid.addPlugin(filters); grid.setContextMenu(createContextMenu()); grid.addListener(Events.ContextMenu, new Listener<GridEvent>() { @Override public void handleEvent(GridEvent be) { selectedLoan = (BeanModel) be.getModel(); } }); toolBarPanel = new LayoutContainer(); toolBarPanel.setLayout(new RowLayout()); mainTB = new ToolBar(); secondaryTB = new ToolBar(); toolBarPanel.add(mainTB, new RowData(1, -1)); contentPanel.setLayout(new RowLayout()); contentPanel.setBottomComponent(pagingTB); RowData data = new RowData(1, -1); contentPanel.add(toolBarPanel, data); data = new RowData(1, 1); contentPanel.add(grid, data); ContentPanel panel = Registry.get(AppWidgets.APP_CONTENT_PANEL); panel.add(contentPanel); panel.layout(); searchConfigList = new ArrayList<FilterConfig>(); filterConfigList = new ArrayList<FilterConfig>(); loadConfigs.set(PIGE.SEARCH_CONFIGS, searchConfigList); loadConfigs.set(PIGE.FILTER_CONFIGS, filterConfigList); userConfigList = new ArrayList<FilterConfig>(); } private void setApprovalMode() { setViewTitle(messages.loanApprobation()); configureCellEditors(true); columnModel.setEditor(columnModel.getIndexById(Loan.STATUS_REF), null); configureToolBar(); toolBarPanel.remove(secondaryTB); resetLoadConfigs(); BaseFilterConfig params = new BaseListFilterConfig(); params.setField("params"); params.set(PIGE.USER_CONFIGS, userConfigList); searchConfigList.add(params); FilterConfig fc = new BaseStringFilterConfig(); fc.setField(Loan.STATUS_REF); fc.setValue(LoanStatus.STATUS_PENDING); filterConfigList.add(fc); if (loanManagementSearchBox == null) { loanManagementSearchBox = new LoanManagementSearchBox(userConfigList) { @Override public void load() { storeLoader.load(0, PAGE_SIZE); } }; } else { loanManagementSearchBox.reset(); } mainTB.add(PigeUtil.createVerticalSeparator()); mainTB.add(loanManagementSearchBox); mainTB.add(PigeUtil.createVerticalSeparator()); showPostponedLoanCbx = new CheckBox(); showPostponedLoanCbx.setStyleAttribute("margin-left", "5px"); Html postponedCbxLabel = new Html(messages.showPostponedLoans()); postponedCbxLabel.setStyleName("pige-tb-cb-label"); final FilterConfig postponedLoanStatusFC = new BaseStringFilterConfig(); postponedLoanStatusFC.setField(Loan.STATUS_REF); postponedLoanStatusFC.setValue(LoanStatus.STATUS_POSTPONED); showPostponedLoanCbx.addListener(Events.Change, new Listener<FieldEvent>() { @Override public void handleEvent(FieldEvent event) { if (showPostponedLoanCbx.getValue()) { filterConfigList.add(postponedLoanStatusFC); } else { filterConfigList.remove(postponedLoanStatusFC); } storeLoader.load(0, PAGE_SIZE); } }); mainTB.add(showPostponedLoanCbx); mainTB.add(postponedCbxLabel); mainTB.add(new SeparatorToolItem()); mainTB.add(batchEditBtn); mainTB.add(new SeparatorToolItem()); mainTB.add(printBtn); mainTB.add(new SeparatorToolItem()); mainTB.layout(); storeUpdater = new ApprovalStoreUpdater(); ColumnConfig cc = columnModel.getColumnById(Loan.STATUS_REF); cc.setRenderer(new ApprovalButtonGridCellRenderer()); columnModel.setColumnHeader(columnModel.getIndexById(Loan.STATUS_REF), messages.accepted() + " / " + messages.refused() + " / " + messages.postponed()); pagingTB.setPageSize(PAGE_SIZE); storeLoader.load(0, PAGE_SIZE); } private void setReturnMode() { setViewTitle(messages.loansReturn()); configureCellEditors(true); columnModel.setEditor(columnModel.getIndexById(Loan.STATUS_REF), null); configureToolBar(); toolBarPanel.remove(secondaryTB); resetLoadConfigs(); BaseFilterConfig params = new BaseListFilterConfig(); params.setField("params"); params.set(PIGE.USER_CONFIGS, userConfigList); searchConfigList.add(params); FilterConfig fc = new BaseStringFilterConfig(); fc.setField(Loan.STATUS_REF); fc.setValue(LoanStatus.STATUS_LENT); filterConfigList.add(fc); fc = new BaseStringFilterConfig(); fc.setField(Loan.STATUS_REF); fc.setValue(LoanStatus.STATUS_LATE); filterConfigList.add(fc); if (loanManagementSearchBox == null) { loanManagementSearchBox = new LoanManagementSearchBox(userConfigList) { @Override public void load() { storeLoader.load(0, PAGE_SIZE); } }; } else { loanManagementSearchBox.reset(); } mainTB.add(PigeUtil.createVerticalSeparator()); mainTB.add(loanManagementSearchBox); mainTB.add(new SeparatorToolItem()); mainTB.add(batchEditBtn); mainTB.add(new SeparatorToolItem()); mainTB.add(printBtn); mainTB.add(new SeparatorToolItem()); mainTB.layout(); storeUpdater = new ReturnStoreUpdater(); ColumnConfig cc = columnModel.getColumnById(Loan.STATUS_REF); cc.setRenderer(new ReturnButtonGridCellRenderer()); columnModel.setColumnHeader(columnModel.getIndexById(Loan.STATUS_REF), messages.returned()); pagingTB.setPageSize(PAGE_SIZE); loanStore.removeAll(); } private void setSearchMode() { setViewTitle(messages.search()); configureCellEditors(Boolean.TRUE); configureToolBar(); toolBarPanel.add(secondaryTB, new RowData(1, -1)); updateBtn.setVisible(Boolean.TRUE); resetLoadConfigs(); if (loanAdvancedSearchBox == null) { loanAdvancedSearchBox = new LoanAdvancedSearchBox(null, searchConfigList) { @Override public void load() { storeLoader.load(0, SEARCH_PAGE_SIZE); } }; } mainTB.add(PigeUtil.createVerticalSeparator()); mainTB.add(loanAdvancedSearchBox); mainTB.layout(); if (loanStateFilterBox == null) { loanStateFilterBox = new LoanStateFilterBox(storeLoader, filterConfigList) { @Override public void load() { storeLoader.load(0, SEARCH_PAGE_SIZE); contentPanel.layout(); } }; secondaryTB.add(loanStateFilterBox); } if (searchBtn == null) { searchBtn = new Button(messages.doSearch()); searchBtn.setWidth(100); searchBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.searchIcon())); searchBtn.addSelectionListener(loanAdvancedSearchBox.getStartSearchListener()); secondaryTB.add(PigeUtil.createVerticalSeparator()); secondaryTB.add(searchBtn); } if (resetBtn == null) { resetBtn = new Button(messages.reset()); resetBtn.setWidth(100); resetBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.redXIcon())); resetBtn.addSelectionListener(loanAdvancedSearchBox.getResetSearchListener()); resetBtn.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent event) { loanStateFilterBox.resetStates(); } }); secondaryTB.add(PigeUtil.createVerticalSeparator()); secondaryTB.add(resetBtn); secondaryTB.add(PigeUtil.createVerticalSeparator()); } if (!isPrintButtonPresent) { secondaryTB.add(batchEditBtn); secondaryTB.add(new SeparatorToolItem()); secondaryTB.add(printBtn); secondaryTB.add(new SeparatorToolItem()); isPrintButtonPresent = Boolean.TRUE; } storeUpdater = null; ColumnConfig cc = columnModel.getColumnById(Loan.STATUS_REF); cc.setRenderer(new GridCellRenderer<BeanModel>() { @Override public Object render(BeanModel model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<BeanModel> store, Grid<BeanModel> grid) { return (String) LoanStatus.getInstance().get((String) model.get(property)); } }); loanStateFilterBox.resetStates(); columnModel.setColumnHeader(columnModel.getIndexById(Loan.STATUS_REF), messages.status()); pagingTB.setPageSize(SEARCH_PAGE_SIZE); loanStore.removeAll(); } private void resetLoadConfigs() { this.searchConfigList.clear(); this.filterConfigList.clear(); } private void setLoanDirty(BeanModel bm, Boolean dirty) { if (bm != null) { if (dirty && !dirtyLoans.contains(bm)) { dirtyLoans.add(bm); } else if (!dirty && dirtyLoans.contains(bm)) { dirtyLoans.remove(bm); } } } private class GridEditListener implements Listener<GridEvent> { @Override public void handleEvent(GridEvent event) { setLoanDirty((BeanModel) event.getModel(), Boolean.TRUE); } } private void configureToolBar() { mainTB.removeAll(); updateBtn = new Button(messages.update()); updateBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.saveIcon())); updateBtn.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent event) { final StatusBar sb = Registry.get(AppWidgets.APP_STATUS_BAR); if (dirtyLoans.size() == 0) { sb.setTimedText(messages.noUpdateToDo()); return; } List<Loan> loans = new ArrayList(); Loan loan = null; for (BeanModel bm : dirtyLoans) { loan = bm.getBean(); // Si on modifie un emprunt en retard (exemple: on change la // date de retour), on remet cet emprunt dans l'tat 'Prt'. if (loan.getStatus().equals(LoanStatus.STATUS_LATE)) { loan.setStatus(LoanStatus.STATUS_LENT); } loans.add(loan); } ManagementServiceAsync rpcService = Registry.get(PIGE.MANAGEMENT_SERVICE); rpcService.updateLoans(loans, new AsyncCallback() { @Override public void onSuccess(Object o) { StatusBar sb = Registry.get(AppWidgets.APP_STATUS_BAR); sb.setTimedText(messages.updateSuccessful()); for (BeanModel bm : dirtyLoans) { if (storeUpdater != null) { storeUpdater.updateStore(loanStore, bm); } } dirtyLoans.clear(); } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); } }); updateBtn.setVisible(Boolean.TRUE); mainTB.add(updateBtn); mainTB.layout(); printBtn = new Button(messages.print() + PIGE.DIALOG_OPENER_INDICATOR); printBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.printerIcon())); printBtn.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { printSearchResult(); } }); batchEditBtn = new Button(messages.batchEdit()); batchEditBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.batchEditIcon())); Menu batchEditMenu = new Menu(); batchEditBtn.setMenu(batchEditMenu); configureBatchEditMenu(batchEditMenu, batchEditMenu); } private void configureCellEditors(Boolean isEditable) { NumberFormat nf = NumberFormat.getFormat(PIGE.QUANTITY_FORMAT); NumberField numberFieldEditor = new NumberField(); numberFieldEditor.setPropertyEditorType(Integer.class); numberFieldEditor.setFormat(nf); numberFieldEditor.setMinValue(new Integer(0)); numberFieldEditor.setMaxLength(6); columnModel.setEditor(columnModel.getIndexById(Loan.QUANTITY_REF), isEditable ? new CellEditor(numberFieldEditor) : null); TextField<String> descriptionEditor = new TextField<String>(); descriptionEditor.setMaxLength(100); columnModel.setEditor(columnModel.getIndexById(Loan.DESCRIPTION_REF), isEditable ? new CellEditor(descriptionEditor) : null); DateTimeFormat dtf = DateTimeFormat.getFormat(PIGE.TERM_DATE_FORMAT); DateField dateField = new DateField(); dateField.setMinValue(new Date()); dateField.setEditable(false); dateField.setFormatValue(true); dateField.getPropertyEditor().setFormat(dtf); CellEditor termDateEditor = new CellEditor(dateField); columnModel.setEditor(columnModel.getIndexById(Loan.TERM_REF), isEditable ? termDateEditor : null); TextField<String> tagEditor = new TextField<String>(); tagEditor.setMaxLength(50); columnModel.setEditor(columnModel.getIndexById(Loan.TAG_REF), isEditable ? new CellEditor(tagEditor) : null); TextField<String> noteEditor = new TextField<String>(); noteEditor.setMaxLength(150); columnModel.setEditor(columnModel.getIndexById(Loan.NOTE_REF), isEditable ? new CellEditor(noteEditor) : null); LoanStatusChooser LoanStatusEditor = new LoanStatusChooser(); CellEditor editor = new CellEditor(LoanStatusEditor) { @Override public Object preProcessValue(Object value) { List<LoanStatusModel> list = LoanStatus.getInstance().getModelList(); for (LoanStatusModel model : list) { if (model.getValue().equals(value)) { return model; } } return null; } @Override public Object postProcessValue(Object value) { LoanStatusModel model = (LoanStatusModel) value; return model.getValue(); } }; columnModel.setEditor(columnModel.getIndexById(Loan.STATUS_REF), isEditable ? editor : null); } protected BeanModel getSelectedLoan() { return selectedLoan; } protected Boolean validateLoanSelection() { if (selectedLoan != null) { return Boolean.TRUE; } MessageBox.info(messages.information(), messages.noLoanSelected(), null); return Boolean.FALSE; } protected void viewLoanItem() { if (!validateLoanSelection()) { return; } Loan loan = (Loan) getSelectedLoan().getBean(); Integer itemId = loan.getItemId(); if (itemId == null) { MessageBox.info(messages.information(), messages.noAssociatedItem(), null); return; } doViewLoanItem(itemId); } protected void doViewLoanItem(Integer itemId) { PIGE.__assert(itemId != null, "itemId == null", this.getClass(), "doViewLoanItem"); ManagementServiceAsync rpcService = (ManagementServiceAsync) Registry.get(PIGE.MANAGEMENT_SERVICE); rpcService.getItemById(itemId, new AsyncCallback<Item>() { @Override public void onSuccess(Item item) { if (item != null) { ItemCEVDialog dialog = new ItemCEVDialog(CEV.VIEW); dialog.setData("item", item); dialog.showDialog(); } } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); } protected void unbindItem() { if (!validateLoanSelection()) { return; } final Loan loan = (Loan) getSelectedLoan().getBean(); Integer itemId = loan.getItemId(); if (itemId == null) { MessageBox.info(messages.information(), messages.noAssociatedItem(), null); return; } Listener listener = new Listener<MessageBoxEvent>() { @Override public void handleEvent(MessageBoxEvent event) { if (event.getButtonClicked().getHtml().equals(messages.yes())) { doUnbindItem(loan); } } }; MessageBox.confirm(messages.warning(), messages.unbindLoanItemConfirmation(), listener) .setIcon(MessageBox.WARNING); } protected void doUnbindItem(final Loan loan) { PIGE.__assert(loan != null, "loan == null", getClass(), "doUnbindItem"); loan.setItemId(null); ManagementServiceAsync rpcService = (ManagementServiceAsync) Registry.get(PIGE.MANAGEMENT_SERVICE); rpcService.updateLoans(Arrays.asList(loan), new AsyncCallback() { @Override public void onSuccess(Object o) { loanStore.update(getSelectedLoan()); } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); } protected Menu createContextMenu() { Menu contextMenu = new Menu(); contextMenu.add(new HeaderMenuItem(messages.loanMenu())); MenuItem viewItemMenu = new MenuItem(messages.viewItem()); viewItemMenu.addSelectionListener(new SelectionListener<MenuEvent>() { @Override public void componentSelected(MenuEvent e) { viewLoanItem(); } }); MenuItem unbindItemMenu = new MenuItem(messages.unbind()); unbindItemMenu.addSelectionListener(new SelectionListener<MenuEvent>() { @Override public void componentSelected(MenuEvent e) { unbindItem(); } }); MenuItem printMenu = new MenuItem(messages.print()); printMenu.addSelectionListener(new SelectionListener<MenuEvent>() { @Override public void componentSelected(MenuEvent e) { printSearchResult(); } }); // 1.5.1 MenuItem batchEditMenuItem = new MenuItem(messages.batchEdit()); Menu batchEditMenu = new Menu(); batchEditMenuItem.setSubMenu(batchEditMenu); configureBatchEditMenu(batchEditMenu, contextMenu); contextMenu.add(viewItemMenu); contextMenu.add(unbindItemMenu); contextMenu.add(batchEditMenuItem); contextMenu.add(createClearSelectedLoansMenuItem()); contextMenu.add(new SeparatorMenuItem()); contextMenu.add(printMenu); return contextMenu; } private void printSearchResult() { if (loanStore.getCount() <= 0) { MessageBox.info(messages.information(), messages.noDataToPrint(), null); return; } doPrintSearchResult(); } private void doPrintSearchResult() { BasePagingLoadConfig config = new BasePagingLoadConfig(); config.setProperties(loadConfigs.getProperties()); config.setLimit(0); // Pas de limite. config.setOffset(0); final MessageBox progressBar = MessageBox.wait(messages.fetchingData(), null, null); ManagementServiceAsync rpcService = (ManagementServiceAsync) Registry.get(PIGE.MANAGEMENT_SERVICE); rpcService.getLoans(config, new AsyncCallback<PagingLoadResult<Loan>>() { @Override public void onSuccess(PagingLoadResult<Loan> result) { HTMLLoanFormatter formatter = new HTMLLoanFormatter(); formatter.setTitle(messages.loan() + "s - " + messages.searchResults()); String data = formatter.format(result.getData()); PrintViewer viewer = new PrintViewer(); viewer.setContent(data); progressBar.close(); viewer.show(); } @Override public void onFailure(Throwable caught) { PIGE.handleException(caught); } }); } // 1.5.1 protected void configureBatchEditMenu(Menu menu, final Menu rootMenu) { MenuItem statusEditMenuItem = new MenuItem(messages.status()); MenuItem quantityEditMenuItem = new MenuItem(messages.quantity()); MenuItem descriptionEditMenuItem = new MenuItem(messages.description()); MenuItem dueDateEditMenuItem = new MenuItem(messages.term()); MenuItem tagEditMenuItem = new MenuItem(messages.tag()); MenuItem noteEditMenuItem = new MenuItem(messages.note()); menu.add(quantityEditMenuItem); // Doit seulement tre visible dans la vue Recherche. if (getViewTitle().equals(messages.search())) { menu.add(statusEditMenuItem); } menu.add(descriptionEditMenuItem); menu.add(dueDateEditMenuItem); menu.add(tagEditMenuItem); menu.add(noteEditMenuItem); menu.add(createClearSelectedLoansMenuItem()); // Proprit quantit. NumberField quantityNF = new NumberField(); quantityNF.setFormat(NumberFormat.getFormat(PIGE.QUANTITY_FORMAT)); quantityNF.setPropertyEditorType(Integer.class); quantityNF.setAllowDecimals(Boolean.FALSE); quantityNF.setAllowNegative(Boolean.FALSE); quantityNF.setMaxLength(9); quantityNF.addListener(Events.KeyUp, new FieldListener(rootMenu, new FieldUpdater(Loan.QUANTITY_REF, quantityNF))); AdapterMenuItem quantityTFMenuAdapter = new AdapterMenuItem(quantityNF); quantityTFMenuAdapter.setManageFocus(true); quantityTFMenuAdapter.setCanActivate(true); Menu quantityEditMenu = new Menu(); quantityEditMenu.add(quantityTFMenuAdapter); quantityEditMenuItem.setSubMenu(quantityEditMenu); // Proprit tat ListStore statusListStore = new ListStore<LoanStatusModel>(); statusListStore.add(LoanStatus.getInstance().getModelList()); ComboBox statusCBx = new ComboBox<LoanStatusModel>(); statusCBx.setStore(statusListStore); statusCBx.setForceSelection(true); statusCBx.setEditable(false); statusCBx.setDisplayField("label"); statusCBx.setTriggerAction(TriggerAction.ALL); statusCBx.addListener(Events.Select, new FieldListener(rootMenu, new FieldUpdater(Loan.STATUS_REF, statusCBx))); AdapterMenuItem statusTFMenuAdapter = new AdapterMenuItem(statusCBx); statusTFMenuAdapter.setManageFocus(true); statusTFMenuAdapter.setCanActivate(true); Menu statusEditMenu = new Menu(); statusEditMenu.add(statusTFMenuAdapter); statusEditMenuItem.setSubMenu(statusEditMenu); // Proprit description. final TextField descriptionTF = new TextField<String>(); descriptionTF.addListener(Events.KeyUp, new FieldListener(rootMenu, new FieldUpdater(Loan.DESCRIPTION_REF, descriptionTF))); AdapterMenuItem descriptionTFMenuAdapter = new AdapterMenuItem(descriptionTF); descriptionTFMenuAdapter.setManageFocus(true); descriptionTFMenuAdapter.setCanActivate(true); Menu descriptionEditMenu = new Menu(); descriptionEditMenu.add(descriptionTFMenuAdapter); descriptionEditMenuItem.setSubMenu(descriptionEditMenu); // Proprit chance. DateTimeFormat dtf = DateTimeFormat.getFormat(PIGE.TERM_DATE_FORMAT); final DateField dateField = new DateField(); dateField.setMinValue(new Date()); dateField.setEditable(false); dateField.setFormatValue(true); dateField.getPropertyEditor().setFormat(dtf); dateField.getDatePicker().addListener(Events.Select, new FieldListener(rootMenu, new FieldUpdater(Loan.TERM_REF, dateField))); AdapterMenuItem dueDateTFMenuAdapter = new AdapterMenuItem(dateField); dueDateTFMenuAdapter.setManageFocus(true); dueDateTFMenuAdapter.setCanActivate(true); Menu dueDateEditMenu = new Menu(); dueDateEditMenu.add(dueDateTFMenuAdapter); dueDateEditMenuItem.setSubMenu(dueDateEditMenu); // Proprit libell. final TextField tagTF = new TextField<String>(); tagTF.addListener(Events.KeyUp, new FieldListener(rootMenu, new FieldUpdater(Loan.TAG_REF, tagTF))); AdapterMenuItem tagTFMenuAdapter = new AdapterMenuItem(tagTF); tagTFMenuAdapter.setManageFocus(true); tagTFMenuAdapter.setCanActivate(true); Menu tagEditMenu = new Menu(); tagEditMenu.add(tagTFMenuAdapter); tagEditMenuItem.setSubMenu(tagEditMenu); // Proprit note. final TextField noteTF = new TextField<String>(); noteTF.addListener(Events.KeyUp, new FieldListener(rootMenu, new FieldUpdater(Loan.NOTE_REF, noteTF))); AdapterMenuItem noteTFMenuAdapter = new AdapterMenuItem(noteTF); noteTFMenuAdapter.setManageFocus(true); noteTFMenuAdapter.setCanActivate(true); Menu noteEditMenu = new Menu(); noteEditMenu.add(noteTFMenuAdapter); noteEditMenuItem.setSubMenu(noteEditMenu); } // 1.5.1 private void uncheckAll() { for (BeanModel bm : selectedLoans) { int idx = grid.getStore().indexOf(bm); Widget w = grid.getView().getWidget(idx, 0); if (w != null && w instanceof CheckBox) { ((CheckBox) w).setValue(false); } } selectedLoans.clear(); } // 1.5.1 private MenuItem createClearSelectedLoansMenuItem() { MenuItem menuItem = new MenuItem(messages.clearSelection()); menuItem.addSelectionListener(new SelectionListener<MenuEvent>() { @Override public void componentSelected(MenuEvent event) { uncheckAll(); } }); return menuItem; } }