| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.netbeans.modules.autoupdate.ui; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.logging.Level; |
| import javax.swing.SwingUtilities; |
| import javax.swing.table.AbstractTableModel; |
| import javax.swing.table.JTableHeader; |
| import org.netbeans.api.autoupdate.UpdateManager; |
| import org.netbeans.api.autoupdate.UpdateUnit; |
| import org.openide.util.NbBundle; |
| import org.openide.util.NbPreferences; |
| import org.openide.util.RequestProcessor; |
| |
| /** |
| * |
| * @author Jiri Rechtacek, Radek Matous |
| */ |
| public abstract class UnitCategoryTableModel extends AbstractTableModel { |
| private static final String EXPAND_STATE = "ExpandState";//NOI18N |
| private List<Unit> unitData = Collections.emptyList (); |
| private List<Unit> featuretData = Collections.emptyList (); |
| private List<Unit> standAloneModules = Collections.emptyList (); |
| |
| private List<UpdateUnitListener> listeners = new ArrayList<UpdateUnitListener> (); |
| private String filter = "";//NOI18N |
| private Comparator<Unit> unitCmp; |
| |
| //null == NOT_EXPANDABLE, true == EXPANDED, false == COLLAPSED |
| private Boolean isExpanded = null; |
| |
| public static enum Type { |
| INSTALLED,UPDATE,AVAILABLE,LOCAL |
| } |
| |
| /** Creates a new instance of CategoryTableModel */ |
| public UnitCategoryTableModel () { |
| } |
| |
| List<Unit> getUnits () { |
| return unitData; |
| } |
| |
| boolean supportsTwoViews() { |
| return false; |
| } |
| |
| static Map<String, Boolean> captureState(List<Unit> units) { |
| Map<String,Boolean> retval = new HashMap<String, Boolean>(); |
| for (Unit unit : units) { |
| retval.put(unit.updateUnit.getCodeName(), unit.isMarked()); |
| } |
| return retval; |
| } |
| |
| static void restoreState(List<Unit> newUnits, Map<String, Boolean> capturedState, boolean isMarkedAsDefault) { |
| for (Unit unit : newUnits) { |
| Boolean isChecked = capturedState.get(unit.updateUnit.getCodeName()); |
| if (isChecked != null) { |
| try { |
| if (isChecked.booleanValue() && !unit.isMarked() && unit.canBeMarked()) { |
| unit.setMarked(true); |
| } else if (!isChecked.booleanValue() && unit.isMarked() && unit.canBeMarked()) { |
| unit.setMarked(false); |
| } |
| } catch (IllegalArgumentException ex) { |
| Unit.log.log(Level.FINE, "Cannot change the unit state", ex); |
| } |
| } else if (isMarkedAsDefault && !unit.isMarked() && unit.canBeMarked()) { |
| unit.setMarked(true); |
| } |
| } |
| } |
| |
| public static boolean isMarkedAsDefault(Type type) { |
| return (type.equals(Type.LOCAL) || type.equals(Type.UPDATE)) ? true : false; |
| } |
| |
| protected final boolean isMarkedAsDefault() { |
| return isMarkedAsDefault(getType()); |
| } |
| |
| public abstract Object getValueAt (int row, int col); |
| @Override |
| public abstract Class getColumnClass (int c); |
| public abstract Type getType (); |
| public abstract boolean isSortAllowed (Object columnIdentifier); |
| public abstract int getDownloadSize (); |
| public abstract boolean needsRestart (); |
| protected abstract Comparator<Unit> getComparator (final Object columnIdentifier, final boolean sortAscending); |
| public abstract void setUnits (List<UpdateUnit> units); |
| public String getTabTooltipText() { |
| return null; |
| } |
| public abstract String getTabTitle(); |
| public final String getDecoratedTabTitle() { |
| int count = getItemCount (); |
| int rawCount = getRawItemCount (); |
| String countInfo = (count == rawCount) ? String.valueOf (rawCount) : |
| NbBundle.getMessage (PluginManagerUI.class, "PluginManagerUI_Tabs_CountFormat", count, rawCount); |
| String newName = NbBundle.getMessage (PluginManagerUI.class, "PluginManagerUI_Tabs_NameFormat", getTabTitle(), countInfo); |
| return (rawCount == 0) ? getTabTitle() : newName; |
| } |
| |
| public boolean canBePrimaryTab() { |
| return true; |
| } |
| public abstract int getTabIndex(); |
| public boolean isTabEnabled() { |
| return true; |
| } |
| public String getToolTipText (int row, int col) { |
| String retval = null; |
| if (col == 0) { |
| retval = getTooltipForCheckBox(row); |
| } else if (col == 1) { |
| retval = (String)getValueAt (row, 1); |
| } |
| return retval; |
| } |
| public int getMinWidth (JTableHeader header, int col) { |
| return header.getHeaderRect (col).width; |
| } |
| public abstract int getPreferredWidth (JTableHeader header, int col); |
| |
| protected Comparator<Unit> getDefaultComparator() { |
| return new Comparator<Unit>() { |
| public int compare(Unit o1, Unit o2) { |
| return Unit.compareCategories(o1, o2); |
| } |
| }; |
| } |
| |
| public final void sort (Object columnIdentifier, boolean sortAscending) { |
| if (columnIdentifier == null) { |
| setUnitComparator (getDefaultComparator ()); |
| } else { |
| setUnitComparator (getComparator (columnIdentifier, sortAscending)); |
| } |
| fireTableDataChanged (); |
| } |
| |
| private String getTooltipForCheckBox(int row) { |
| String key0 = null; |
| switch (getType()) { |
| case INSTALLED: |
| key0 = "UnitTab_TooltipCheckBox_INSTALLED"; //NOI18N |
| break; |
| case UPDATE: |
| key0 = "UnitTab_TooltipCheckBox_UPDATE"; //NOI18N |
| break; |
| case AVAILABLE: |
| key0 = "UnitTab_TooltipCheckBox_AVAILABLE"; //NOI18N |
| break; |
| case LOCAL: |
| key0 = "UnitTab_TooltipCheckBox_LOCAL"; //NOI18N |
| break; |
| } |
| return (key0 != null) ? NbBundle.getMessage (UnitCategoryTableModel.class, key0, (String)getValueAt (row, 1)) : null; |
| } |
| |
| private final void setData(List<UnitCategory> data, Comparator<Unit> unitCmp) { |
| this.unitCmp = unitCmp != null ? unitCmp : getDefaultComparator(); |
| featuretData = null; |
| if (data != null) { |
| this.unitData = Collections.emptyList(); |
| this.unitData = new ArrayList<Unit>(); |
| for (UnitCategory unitCategory : data) { |
| this.unitData.addAll(unitCategory.getUnits()); |
| } |
| standAloneModules = new ArrayList<Unit> (); |
| for (Unit u : unitData) { |
| if (UpdateManager.TYPE.STANDALONE_MODULE.equals(u.updateUnit.getType())) { |
| standAloneModules.add(u); |
| } |
| } |
| computeExtensionState(); |
| } else { |
| assert unitData != null; |
| } |
| if (unitCmp != null) { |
| Collections.sort(unitData,unitCmp); |
| } |
| this.fireTableDataChanged(); |
| } |
| |
| |
| private void computeExtensionState() { |
| boolean exp = isExpandableType(getType()) && !Utilities.modulesOnly() && !getVisibleUnits(getFeatureList(), getFilter(), false).isEmpty() && !getVisibleUnits(standAloneModules, getFilter(), false).isEmpty(); |
| if (exp) { |
| isExpanded = NbPreferences.forModule(UnitCategoryTableModel.class).getBoolean(EXPAND_STATE, false); |
| } else { |
| isExpanded = null; |
| } |
| } |
| |
| public void setUnitComparator (Comparator<Unit> comparator) { |
| setData (null, comparator); |
| } |
| |
| public final void setData (List<UnitCategory> data) { |
| setData (data, unitCmp); |
| } |
| |
| public void setFilter (final String filter, final Runnable runAfterwards) { |
| SwingUtilities.invokeLater (new Runnable () { |
| public void run () { |
| synchronized(UnitCategoryTableModel.class) { |
| UnitCategoryTableModel.this.filter = filter.toLowerCase (); |
| } |
| computeExtensionState(); |
| fireFilterChange(); |
| if (runAfterwards != null) { |
| runAfterwards.run(); |
| } |
| } |
| }); |
| } |
| |
| public String getFilter () { |
| synchronized(UnitCategoryTableModel.class) { |
| return this.filter == null ? "" : this.filter; |
| } |
| } |
| |
| public void addUpdateUnitListener (UpdateUnitListener l) { |
| listeners.add (l); |
| } |
| |
| public void removeUpdateUnitListener (UpdateUnitListener l) { |
| listeners.remove (l); |
| } |
| |
| void fireUpdataUnitChange () { |
| assert listeners != null : "UpdateUnitListener found."; |
| for (UpdateUnitListener l : listeners) { |
| l.updateUnitsChanged (); |
| } |
| } |
| |
| void fireButtonsChange () { |
| assert listeners != null : "UpdateUnitListener found."; |
| for (UpdateUnitListener l : listeners) { |
| l.buttonsChanged (); |
| } |
| } |
| |
| void fireFilterChange () { |
| assert listeners != null : "UpdateUnitListener found."; |
| for (UpdateUnitListener l : listeners) { |
| l.filterChanged(); |
| } |
| } |
| |
| List<Unit> getVisibleUnits () { |
| return getVisibleUnits(getUnits(), getFilter(), true); |
| } |
| |
| private List<Unit> getVisibleUnits (List<Unit> units, String filter, boolean filterAlsoStandardModules) { |
| List<Unit> retval = new ArrayList<Unit>(); |
| for (Unit unit : units) { |
| if (filterAlsoStandardModules) { |
| if (unit.isVisible(filter) && (!isExpandable() || isExpanded() || UpdateManager.TYPE.FEATURE.equals(unit.updateUnit.getType()))) { |
| retval.add(unit); |
| } |
| } else { |
| if (unit.isVisible(filter)) { |
| retval.add(unit); |
| } |
| } |
| } |
| return retval; |
| } |
| |
| |
| public int getRowCount () { |
| int retval = getVisibleUnits ().size (); |
| return (isExpansionControlPresent()) ? (retval + 1) : retval; |
| } |
| |
| public int getRawItemCount () { |
| return unitData.size (); |
| } |
| |
| public int getItemCount () { |
| return getVisibleUnits ().size (); |
| } |
| |
| |
| public Collection<Unit> getMarkedUnits() { |
| List<Unit> markedUnits = new ArrayList<Unit> (); |
| List<Unit> units = getUnits(); |
| |
| for (Unit u : units) { |
| if (u.isMarked()) { |
| markedUnits.add(u); |
| } |
| } |
| return markedUnits; |
| } |
| |
| public Unit getUnitAtRow (int row) { |
| if (row < 0 ) { |
| return null; |
| } |
| List <Unit> list = getVisibleUnits(); |
| return list.size () <= row ? null : list.get (row); |
| } |
| |
| public boolean isExpansionControlAtRow (int row) { |
| return ((row + 1) == getRowCount()) && isExpansionControlPresent(); |
| } |
| |
| public String getExpansionControlText() { |
| assert isExpansionControlPresent(); |
| String bundleKey = isExpanded() ? "Less_Command_Text" : "More_Command_Text";//NOI18N |
| return NbBundle.getMessage(UnitCategoryTableModel.class, bundleKey, getVisibleUnits(getStandAloneModules(), getFilter(), false).size()); |
| } |
| |
| public boolean isExpandable () { |
| return isExpanded != null; |
| } |
| |
| public boolean isExpansionControlPresent() { |
| return isExpandable () && !getFeatureList().isEmpty() && !getVisibleUnits(getStandAloneModules(), getFilter(), false).isEmpty(); |
| } |
| |
| public void setExpanded (Boolean expanded) { |
| this.isExpanded = expanded; |
| featuretData = null; |
| if (expanded != null) { |
| NbPreferences.forModule(UnitCategoryTableModel.class).putBoolean(EXPAND_STATE, expanded); |
| } |
| } |
| |
| public boolean isExpanded () { |
| boolean retval = isExpandable(); |
| if (retval) { |
| retval = isExpanded != null && isExpanded; |
| } |
| return retval; |
| } |
| |
| public boolean isCollapsed () { |
| boolean retval = isExpandable(); |
| if (retval) { |
| retval = isExpanded != null && !isExpanded; |
| } |
| return retval; |
| } |
| |
| private List<Unit> getFeatureList() { |
| if (featuretData == null) { |
| featuretData = new ArrayList<Unit> (unitData); |
| featuretData.removeAll(getStandAloneModules()); |
| if (unitCmp != null) { |
| Collections.sort(featuretData,unitCmp); |
| } |
| } |
| return featuretData; |
| } |
| |
| List<Unit> getStandAloneModules() { |
| List<Unit> retval = standAloneModules; |
| if (retval == null) { |
| retval = Collections.emptyList(); |
| } |
| return retval; |
| } |
| |
| public static boolean isExpandableType (Type type) { |
| return type.equals(UnitCategoryTableModel.Type.AVAILABLE) || |
| type.equals(UnitCategoryTableModel.Type.UPDATE); |
| } |
| |
| @Override |
| public boolean isCellEditable (int row, int col) { |
| if (isExpansionControlAtRow(row)) { |
| return false; |
| } |
| RequestProcessor.Task t = PluginManagerUI.getRunningTask (); |
| return (t == null || t.isFinished ()) && col == 0 && Boolean.class.equals (getColumnClass (col)); |
| } |
| |
| } |