View Javadoc
1   package fr.ifremer.dali.ui.swing.content.manage.filter.list;
2   
3   /*
4    * #%L
5    * Dali :: UI
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2014 - 2015 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  import com.google.common.collect.Maps;
27  import fr.ifremer.dali.dto.DaliBeans;
28  import fr.ifremer.dali.dto.configuration.filter.FilterDTO;
29  import fr.ifremer.dali.ui.swing.content.manage.filter.FilterUI;
30  import fr.ifremer.dali.ui.swing.content.manage.filter.element.AbstractFilterElementUIHandler;
31  import fr.ifremer.dali.ui.swing.util.DaliUIs;
32  import fr.ifremer.dali.ui.swing.util.table.AbstractDaliTableModel;
33  import fr.ifremer.dali.ui.swing.util.table.AbstractDaliTableUIHandler;
34  import fr.ifremer.quadrige3.core.dao.technical.Assert;
35  import fr.ifremer.quadrige3.ui.swing.ApplicationUIUtil;
36  import fr.ifremer.quadrige3.ui.swing.table.SwingTable;
37  import jaxx.runtime.swing.editor.bean.BeanFilterableComboBox;
38  import org.apache.commons.collections4.CollectionUtils;
39  import org.jdesktop.swingx.table.TableColumnExt;
40  
41  import javax.swing.SortOrder;
42  import javax.swing.SwingUtilities;
43  import java.util.List;
44  import java.util.Map;
45  
46  import static org.nuiton.i18n.I18n.t;
47  
48  /**
49   * Controller.
50   */
51  public class FilterListUIHandler extends AbstractDaliTableUIHandler<FilterListRowModel, FilterListUIModel, FilterListUI> {
52  
53      public FilterListUIHandler() {
54          super(FilterListRowModel.PROPERTY_NAME);
55      }
56  
57      /** {@inheritDoc} */
58      @Override
59      protected String[] getRowPropertiesToIgnore() {
60          return new String[]{FilterListRowModel.PROPERTY_ELEMENTS, FilterListRowModel.PROPERTY_FILTER_LOADED, FilterListRowModel.PROPERTY_DIRTY};
61      }
62  
63      /** {@inheritDoc} */
64      @Override
65      public void beforeInit(FilterListUI ui) {
66          super.beforeInit(ui);
67  
68          // Create model and register to the JAXX context
69          final FilterListUIModel model = new FilterListUIModel();
70          ui.setContextValue(model);
71  
72      }
73  
74      /** {@inheritDoc} */
75      @Override
76      public void afterInit(FilterListUI ui) {
77          initUI(ui);
78          initComboBox();
79          initTable();
80  
81          // Buttons not enabled
82          getUI().getDuplicateButton().setEnabled(false);
83          getUI().getDeleteButton().setEnabled(false);
84          getUI().getExportButton().setEnabled(false);
85  
86      }
87  
88      /**
89       * Init combobox
90       */
91      private void initComboBox() {
92  
93          // Init filters combo
94          initBeanFilterableComboBox(
95                  getUI().getFiltersCombo(),
96                  getContext().getContextService().getFiltersByType(getFilterTypeId()),
97                  null);
98  
99          // Combobox size
100         DaliUIs.forceComponentSize(getUI().getFiltersCombo());
101 
102         getUI().getFiltersCombo().getComboBoxModel().addWillChangeSelectedItemListener(event -> {
103             if (getModel().isLoading()) return;
104             if (event.getNextSelectedItem() != null) SwingUtilities.invokeLater(() -> getUI().getSearchButton().getAction().actionPerformed(null));
105         });
106     }
107 
108     /**
109      * <p>reloadComboBox.</p>
110      */
111     @SuppressWarnings("unchecked")
112     public void reloadComboBox() {
113         getModel().setLoading(true);
114         BeanFilterableComboBox cb = getUI().getFiltersCombo();
115         cb.setData(null);
116         List<FilterDTO> filterList = getContext().getContextService().getFiltersByType(getFilterTypeId());
117         cb.setData(filterList);
118 
119         // reach 'apply Filter' combobox
120         BeanFilterableComboBox afCombo = ((AbstractFilterElementUIHandler) getParentUI().getFilterElementUI().getHandler())
121                 .getReferentialMenuUI().getHandler().getApplyFilterUI().getApplyFilterCombo();
122         afCombo.setData(filterList);
123 
124         getModel().setLoading(false);
125     }
126 
127     /**
128      * Init table.
129      */
130     private void initTable() {
131 
132         // Tableau
133         final SwingTable table = getTable();
134 
135         // Name column
136         final TableColumnExt nameColumn = addColumn(FilterListTableModel.NAME);
137         nameColumn.setSortable(true);
138 
139         // Table model
140         final FilterListTableModel tableModel = new FilterListTableModel(getTable().getColumnModel());
141         table.setModel(tableModel);
142 
143         // Init table
144         initTable(table);
145 
146         // Default sort
147         table.setSortOrder(FilterListTableModel.NAME, SortOrder.ASCENDING);
148 
149         // Number rows visible
150         table.setVisibleRowCount(5);
151     }
152 
153     /**
154      * Load filters.
155      *
156      * @param filters Filters list
157      */
158     public void loadFilters(final List<FilterDTO> filters) {
159 
160         // Add filters
161         getModel().setBeans(filters);
162 
163         // Auto select if single row
164         if (getModel().getRowCount() == 1) {
165             FilterListRowModel rowModel = getModel().getRows().get(0);
166             SwingUtilities.invokeLater(() -> {
167                 selectRow(rowModel);
168                 getModel().setSingleSelectedRow(rowModel);
169             });
170         } else {
171             // Delete filters
172             getParentUI().getHandler().clearFilterElements();
173         }
174     }
175 
176     /** {@inheritDoc} */
177     @Override
178     @SuppressWarnings("unchecked")
179     public AbstractDaliTableModel<FilterListRowModel> getTableModel() {
180         return (AbstractDaliTableModel<FilterListRowModel>) getTable().getModel();
181     }
182 
183     /** {@inheritDoc} */
184     @Override
185     public SwingTable getTable() {
186         return getUI().getTable();
187     }
188 
189     /**
190      * <p>getParentUI.</p>
191      *
192      * @return a {@link fr.ifremer.dali.ui.swing.content.manage.filter.FilterUI} object.
193      */
194     public FilterUI getParentUI() {
195         return (FilterUI) ApplicationUIUtil.getParentUI(getUI());
196     }
197 
198     /**
199      * <p>getFilterTypeId.</p>
200      *
201      * @return a int.
202      */
203     public int getFilterTypeId() {
204         Integer filterTypeId = getParentUI().getFilterTypeId();
205         Assert.notNull(filterTypeId);
206         return filterTypeId;
207     }
208 
209     /** {@inheritDoc} */
210     @Override
211     protected void onRowsAdded(List<FilterListRowModel> addedRows) {
212         super.onRowsAdded(addedRows);
213 
214         // should be only one row
215         if (addedRows.size() == 1) {
216             FilterListRowModel row = addedRows.get(0);
217 
218             // affect filterTypeId
219             row.setFilterTypeId(getFilterTypeId());
220             getModel().setModify(true);
221             setFocusOnCell(row);
222         }
223 
224     }
225 
226     /** {@inheritDoc} */
227     @Override
228     protected void onRowModified(int rowIndex, FilterListRowModel row, String propertyName, Integer propertyIndex, Object oldValue, Object newValue) {
229         super.onRowModified(rowIndex, row, propertyName, propertyIndex, oldValue, newValue);
230         row.setDirty(true);
231         recomputeRowsValidState();
232     }
233 
234     /** {@inheritDoc} */
235     @Override
236     protected boolean isRowValid(FilterListRowModel row) {
237 
238         row.getErrors().clear();
239         return super.isRowValid(row) && isElementsValid(row);
240     }
241 
242     private boolean isElementsValid(FilterListRowModel row) {
243 
244         if (row.isFilterLoaded() && CollectionUtils.isEmpty(row.getElements())) {
245             DaliBeans.addError(row, t("dali.filter.filterList.noElement"), FilterListRowModel.PROPERTY_NAME);
246         }
247 
248         // check name uniqueness in ui
249         boolean duplicateFound = false;
250         for (FilterListRowModel otherRow : getModel().getRows()) {
251             if (row == otherRow) continue;
252             if (otherRow.getName() != null && otherRow.getName().equals(row.getName())) {
253                 DaliBeans.addError(row, t("dali.error.alreadyExists.label.ui", row.getName()), FilterListRowModel.PROPERTY_NAME);
254                 duplicateFound = true;
255                 break;
256             }
257         }
258 
259         // check name uniqueness in db
260         if (!duplicateFound) {
261             List<FilterDTO> allFilters = getContext().getContextService().getFiltersByType(row.getFilterTypeId());
262             Map<String, Integer> filterIdsByNames = Maps.newHashMap();
263             for (FilterDTO filter : allFilters) {
264                 filterIdsByNames.put(filter.getName(), filter.getId());
265             }
266             if (row.isDirty()) {
267                 Integer existingId = filterIdsByNames.get(row.getName());
268                 if (existingId != null && !existingId.equals(row.getId())) {
269                     // duplicate found
270                     DaliBeans.addError(row, t("dali.error.alreadyExists.label.db", row.getName()), FilterListRowModel.PROPERTY_NAME);
271                 }
272             }
273         }
274 
275         return row.getErrors().isEmpty();
276     }
277 }