blob: 6af25e2f67d1edb59795c2837a685c8d786576a7 [file] [log] [blame]
/*
* 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));
}
}