/* * Copyright (C) 2011 4th Line GmbH, Switzerland * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.fourthline.konto.client.ledger.component; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.logical.shared.SelectionEvent; import com.google.gwt.event.logical.shared.SelectionHandler; import com.google.gwt.resources.client.CssResource; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.TreeItem; import com.google.gwt.user.client.ui.Widget; import org.fourthline.konto.client.bundle.Bundle; import org.seamless.gwt.component.client.widget.GhostedTextBox; import org.seamless.gwt.component.client.widget.ImageTextButton; import org.fourthline.konto.shared.AccountType; import org.fourthline.konto.shared.entity.Account; import org.fourthline.konto.shared.query.AccountsQueryCriteria; import org.seamless.gwt.theme.shared.client.ThemeBundle; import org.seamless.gwt.theme.shared.client.ThemeStyle; import javax.inject.Inject; import java.util.ArrayList; import java.util.List; /** * @author Christian Bauer */ public class AccountTreeSelectViewImpl extends Composite implements AccountTreeSelectView { interface UI extends UiBinder<Widget, AccountTreeSelectViewImpl> { } interface Style extends CssResource { } private static UI ui = GWT.create(UI.class); @UiField(provided = true) final Bundle bundle; @UiField(provided = true) final ThemeBundle themeBundle; @UiField Style style; @UiField ImageTextButton newButton; @UiField SimplePanel newPanel; @UiField(provided = true) GhostedTextBox filterTextBox; @UiField Button filterClearButton; @UiField(provided = true) AccountTree assetTree; @UiField(provided = true) AccountTree liabilityTree; @UiField(provided = true) AccountTree incomeTree; @UiField(provided = true) AccountTree expenseTree; @UiField Label noAssetsLabel; @UiField Label noLiabilitiesLabel; @UiField Label noIncomeLabel; @UiField Label noExpenseLabel; @UiField SimplePanel filterPanel; protected Presenter presenter; protected Option[] options; protected List<Account> accounts = new ArrayList(); protected Timer filterTimer; @Inject public AccountTreeSelectViewImpl(Bundle bundle) { this.bundle = bundle; this.themeBundle = bundle.themeBundle().create(); this.filterTextBox = new GhostedTextBox(getFilterLabel(), ThemeStyle.GhostedTextBox()) { @Override public void onKeyUp(KeyUpEvent event) { super.onKeyUp(event); final String enteredValue = getValue(); if (enteredValue.length() > 0) { filterClearButton.setEnabled(true); scheduleFilterReqest(new Timer() { public void run() { if (presenter != null) { presenter.onFilter(enteredValue); } } }); } else { filterClearButton.setEnabled(false); if (filterTimer != null) filterTimer.cancel(); if (presenter != null) { presenter.onFilter(null); } } } }; assetTree = new AccountTree(AccountType.Asset); liabilityTree = new AccountTree(AccountType.Liability); incomeTree = new AccountTree(AccountType.Income); expenseTree = new AccountTree(AccountType.Expense); addSelectionHandler(new AccountTree.AccountSelectionHandler() { @Override public void onSelection(SelectionEvent<TreeItem> event) { super.onSelection(event); if (Option.MULTISELECT.in(options)) presenter.onMultiSelectionChange(getSelectedAccounts()); } @Override public boolean onAccountGroupSelection(Long id, String name) { return !Option.MULTISELECT.in(options); } @Override public boolean onAccountSelection(Account account) { if (!Option.MULTISELECT.in(options)) presenter.onSingleSelectionChange(account); return !Option.MULTISELECT.in(options); } @Override public boolean onSelection(AccountType type) { return !Option.MULTISELECT.in(options); } }); initWidget(ui.createAndBindUi(this)); } @Override public void setPresenter(Presenter presenter) { this.presenter = presenter; } @Override public void setAccounts(List<Account> value, Option... options) { this.accounts = value; this.options = options; getWidget().setVisible(true); clearTrees(); updateTrees(true); applyCurrentOptions(); } public void addSelectionHandler(SelectionHandler handler) { assetTree.addSelectionHandler(handler); liabilityTree.addSelectionHandler(handler); incomeTree.addSelectionHandler(handler); expenseTree.addSelectionHandler(handler); } @Override public void setSelectedAccounts(AccountsQueryCriteria[] selectedAccounts) { AccountsQueryCriteria criteria; if ((criteria = AccountsQueryCriteria.get(selectedAccounts, AccountType.Asset)) != null) assetTree.setMultiSelected(criteria.getListOfIdentifiers()); else assetTree.setMultiSelected(false); if ((criteria = AccountsQueryCriteria.get(selectedAccounts, AccountType.Liability)) != null) liabilityTree.setMultiSelected(criteria.getListOfIdentifiers()); else liabilityTree.setMultiSelected(false); if ((criteria = AccountsQueryCriteria.get(selectedAccounts, AccountType.Income)) != null) incomeTree.setMultiSelected(criteria.getListOfIdentifiers()); else incomeTree.setMultiSelected(false); if ((criteria = AccountsQueryCriteria.get(selectedAccounts, AccountType.Expense)) != null) expenseTree.setMultiSelected(criteria.getListOfIdentifiers()); else expenseTree.setMultiSelected(false); } @Override public AccountsQueryCriteria[] getSelectedAccounts() { List<AccountsQueryCriteria> list = new ArrayList(); List<Long> ids; if (!Option.HIDE_ASSET.in(options)) { ids = assetTree.getSelectedAccounts(); if (ids.size() > 0) list.add(new AccountsQueryCriteria(ids, AccountType.Asset)); } if (!Option.HIDE_LIABILITY.in(options)) { ids = liabilityTree.getSelectedAccounts(); if (ids.size() > 0) list.add(new AccountsQueryCriteria(ids, AccountType.Liability)); } if (!Option.HIDE_INCOME.in(options)) { ids = incomeTree.getSelectedAccounts(); if (ids.size() > 0) list.add(new AccountsQueryCriteria(ids, AccountType.Income)); } if (!Option.HIDE_EXPENSE.in(options)) { ids = expenseTree.getSelectedAccounts(); if (ids.size() > 0) list.add(new AccountsQueryCriteria(ids, AccountType.Expense)); } return list.toArray(new AccountsQueryCriteria[list.size()]); } protected void applyCurrentOptions() { newPanel.setVisible(false); filterPanel.setVisible(false); setTreesMultiSelectEnabled(false); setTreesMultiSelected(false); assetTree.setVisible(true); liabilityTree.setVisible(true); incomeTree.setVisible(true); expenseTree.setVisible(true); if (options == null) return; for (Option option : options) { switch (option) { case NEW_BUTTON: newPanel.setVisible(true); break; case LABEL_FILTER: filterPanel.setVisible(true); break; case MULTISELECT: setTreesMultiSelectEnabled(true); break; case SELECT_ALL: setTreesMultiSelected(true); break; case SELECT_NONE: setTreesMultiSelected(false); break; case HIDE_ASSET: assetTree.setVisible(false); break; case HIDE_LIABILITY: liabilityTree.setVisible(false); break; case HIDE_INCOME: incomeTree.setVisible(false); break; case HIDE_EXPENSE: expenseTree.setVisible(false); break; } } } protected void clearTrees() { assetTree.clear(); liabilityTree.clear(); incomeTree.clear(); expenseTree.clear(); } protected void setTreesMultiSelectEnabled(boolean enabled) { assetTree.setMultiSelectEnabled(enabled); liabilityTree.setMultiSelectEnabled(enabled); incomeTree.setMultiSelectEnabled(enabled); expenseTree.setMultiSelectEnabled(enabled); } protected void setTreesMultiSelected(boolean selected) { assetTree.setMultiSelected(selected); liabilityTree.setMultiSelected(selected); incomeTree.setMultiSelected(selected); expenseTree.setMultiSelected(selected); } protected void updateTrees(boolean expandAll) { for (Account account : accounts) { switch (account.getType()) { case Asset: case BankAccount: assetTree.addAccount(account, expandAll); break; case Liability: liabilityTree.addAccount(account, expandAll); break; case Income: incomeTree.addAccount(account, expandAll); break; case Expense: expenseTree.addAccount(account, expandAll); break; } } if (!Option.HIDE_ASSET.in(options)) noAssetsLabel.setVisible(!assetTree.hasRootChildren()); if (!Option.HIDE_LIABILITY.in(options)) noLiabilitiesLabel.setVisible(!liabilityTree.hasRootChildren()); if (!Option.HIDE_INCOME.in(options)) noIncomeLabel.setVisible(!incomeTree.hasRootChildren()); if (!Option.HIDE_EXPENSE.in(options)) noExpenseLabel.setVisible(!expenseTree.hasRootChildren()); } @UiHandler("newButton") void onClickNewAccountButton(ClickEvent e) { presenter.onNewAccount(); } @UiHandler("filterClearButton") void onClickDescriptionFilterClear(ClickEvent e) { filterTextBox.clear(); filterClearButton.setEnabled(false); if (filterTimer != null) filterTimer.cancel(); if (presenter != null) { presenter.onFilter(null); } } protected void scheduleFilterReqest(Timer timer) { if (filterTimer != null) { filterTimer.cancel(); } filterTimer = timer; filterTimer.schedule(1000); } protected String getFilterLabel() { return "Filter Accounts..."; } }