/********************************************************************************************** * * Asprise Scanning and Imaging API * Copyright (C) 1998-2016. Asprise Inc. <asprise.com> * * This file is licensed under the GNU Affero General Public License version 3 as published by * the Free Software Foundation. * * 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. * * You should have received a copy of the GNU Affero General Public License. If not, please * visit <http://www.gnu.org/licenses/agpl-3.0.html>. * **********************************************************************************************/ package com.asprise.imaging.core.scan.twain; import javax.swing.ComboBoxModel; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import java.util.ArrayList; import java.util.List; /** * Common used caption options */ public class CapOptions { public static int PAPER_SOURCE_FLATBED = 1; public static int PAPER_SOURCE_FEEDER_FRONT_SIDE = 2; public static int PAPER_SOURCE_FEEDER_BOTH_SIDES = 6; public static List<CapOptionItem> EMPTY_LIST = new ArrayList<CapOptionItem>(); public static class CapOptionItem { Object value; String label; boolean isDefault; public CapOptionItem(Object value, String label, boolean isDefault) { this.value = value; this.label = label; this.isDefault = isDefault; } public Object getValue() { return value; } public int getValueAsInt() { return ((Number)value).intValue(); } public String getLabel() { return label; } public boolean isDefault() { return isDefault; } public void setIsDefault(boolean isDefault) { this.isDefault = isDefault; } @Override public String toString() { return label == null ? String.valueOf(value) : label; } /** * Short-hand method to create list. * @param args in format value, label [, default]. */ public static List<CapOptionItem> createCapOptionItemList(Object ... args) { List<CapOptionItem> items = new ArrayList<CapOptionItem>(); for(int i = 0; i < args.length; ) { Object value = args[i++]; if(!(value instanceof Integer) && !(value instanceof String)) { throw new IllegalArgumentException("Invalid value type: " + value.getClass()); } if(i >= args.length) { throw new IllegalArgumentException("No label for value: " + value); } String label = (String) args[i++]; boolean isDefault = false; if(i < args.length && (args[i] instanceof Boolean)) { isDefault = (Boolean)args[i]; i++; } items.add(new CapOptionItem(value, label, isDefault)); } return items; } } public static List<CapOptionItem> getPaperSource() { return CapOptionItem.createCapOptionItemList( PAPER_SOURCE_FLATBED, "Flatbed", PAPER_SOURCE_FEEDER_FRONT_SIDE, "Feeder (Front Sides Only)", PAPER_SOURCE_FEEDER_BOTH_SIDES, "Feeder (Both Sides)" ); } public static Source.Capability createSyntheticCapForPaperSource(boolean hasFlatbed, boolean hasFeeder) { List list = new ArrayList(); if(hasFlatbed) { list.add(PAPER_SOURCE_FLATBED); } if(hasFeeder) { list.add(PAPER_SOURCE_FEEDER_FRONT_SIDE); list.add(PAPER_SOURCE_FEEDER_BOTH_SIDES); } Source.Capability cap = new Source.Capability("SYN-PAPER-SOURCE", list); return cap; } public static List<CapOptionItem> getPixelTypes() { return CapOptionItem.createCapOptionItemList( TwainConstants.TWPT_BW, "Black and White", TwainConstants.TWPT_GRAY, "Grayscale", TwainConstants.TWPT_RGB, "Color", true ); } public static List<CapOptionItem> getResolutions() { int[] values = new int[] {50, 100, 150, 200, 300, 400, 500, 600, 900, 1200, 2400, 3000}; List list = new ArrayList(); for(int value : values) { list.add(value); list.add(String.valueOf(value) + " DPI"); list.add(value == 300 ? true : false); } return CapOptionItem.createCapOptionItemList(list.toArray()); } public static List<CapOptionItem> getPaperSizes() { return CapOptionItem.createCapOptionItemList( TwainConstants.TWSS_NONE, "Default", true, TwainConstants.TWSS_A4, "A4 (210 x 297mm)", TwainConstants.TWSS_USLETTER, "US Letter (8.5 x 11 in.)", TwainConstants.TWSS_USLEGAL, "US Legal (8.5 x 14 in.)", TwainConstants.TWSS_USEXECUTIVE, "US Executive (7 x 10 in.)", TwainConstants.TWSS_USLEDGER, "US Ledger (11 x 17 in.)", TwainConstants.TWSS_A0, "A0 (841 × 1189mm)", TwainConstants.TWSS_A1, "A1 (594 × 841mm)", TwainConstants.TWSS_A2, "A2 (420 × 594mm)", TwainConstants.TWSS_A3, "A3 (297 × 420mm)", TwainConstants.TWSS_A5, "A5 (148 x 210mm)", TwainConstants.TWSS_A6, "A6 (104 x 148mm)", TwainConstants.TWSS_A6, "A6 (104 x 148mm)", TwainConstants.TWSS_A7, "A7 (74 x 105mm)", TwainConstants.TWSS_A8, "A8 (52 x 74mm)", TwainConstants.TWSS_ISOB0, "B0 (1000 × 1414mm)", TwainConstants.TWSS_ISOB1, "B1 (707 × 1000mm)", TwainConstants.TWSS_ISOB2, "B2 (500 × 707mm)", TwainConstants.TWSS_ISOB3, "B3 (353 × 500mm)", TwainConstants.TWSS_ISOB4, "B4 (250 × 353mm)", TwainConstants.TWSS_ISOB5, "B5 (176 × 250mm)", TwainConstants.TWSS_ISOB6, "B6 (125 × 176mm)", TwainConstants.TWSS_ISOB7, "B7 (88 × 125mm)", TwainConstants.TWSS_ISOB8, "B8 (62 × 88mm)", TwainConstants.TWSS_JISB0, "JISB0 (1030 × 1456mm)", TwainConstants.TWSS_JISB0, "JISB1 (728 × 1030mm)", TwainConstants.TWSS_JISB0, "JISB2 (515 × 728mm)", TwainConstants.TWSS_JISB0, "JISB3 (364 × 515mm)", TwainConstants.TWSS_JISB0, "JISB4 (257 × 364mm)", TwainConstants.TWSS_JISB0, "JISB5 (182 × 257mm)", TwainConstants.TWSS_JISB0, "JISB6 (128 × 182mm)", TwainConstants.TWSS_JISB0, "JISB7 (91 × 128mm)", TwainConstants.TWSS_JISB0, "JISB8 (64 × 91mm)", TwainConstants.TWSS_C0, "C0 (917 × 1297mm)", TwainConstants.TWSS_C1, "C1 (648 × 917mm)", TwainConstants.TWSS_C2, "C2 (458 × 648mm)", TwainConstants.TWSS_C3, "C3 (324 × 458mm)", TwainConstants.TWSS_C4, "C4 (229 × 324mm)", TwainConstants.TWSS_C5, "C5 (162 × 229mm)", TwainConstants.TWSS_C6, "C6 (114 × 162mm)", TwainConstants.TWSS_C7, "C7 (81 × 114mm)", TwainConstants.TWSS_C8, "C8 (57 × 81mm)" ); } public static class CapOptionsComboBoxModel implements ComboBoxModel { List<ListDataListener> listeners = new ArrayList<ListDataListener>(); List<CapOptionItem> list; int selecteIndex = -1; CapOptionItem selectedItem; // stored for future use Source.Capability capability; Object defaultSelectedValue; public CapOptionsComboBoxModel() { } /** * Will set the selectedItem to cap value, or list default (if cap value doesn't exist) or fall back to the first item. * @param fullList full list of items * @param capability */ public CapOptionsComboBoxModel(List<CapOptionItem> fullList, Source.Capability capability, boolean filterInvalidItems, Object selectedValue) { setList(fullList, capability, filterInvalidItems, selectedValue); } /** * Will set the selectedItem to cap value, or list default (if cap value doesn't exist) or fall back to the first item. * @param fullList full list of items * @param capability */ public void setList(List<CapOptionItem> fullList, Source.Capability capability, boolean filterInvalidItems, Object defaultSelectedValue) { this.selecteIndex = -1; this.selectedItem = null; this.capability = capability; this.defaultSelectedValue = defaultSelectedValue; List<CapOptionItem> filtered = new ArrayList<CapOptionItem>(); for(CapOptionItem item : fullList) { if(!filterInvalidItems || capability == null || capability.validate(item.getValue()) != 0) { filtered.add(item); } } this.list = filtered; int capValue = capability == null ? -999 : TwainUtil.toNumber(capability.getCurrentValue(), -999).intValue(); int indexCapValue = -1; int indexDefaultSelected = -1; int indexListDefault = -1; for(int i = 0; i < list.size(); i++) { CapOptionItem item = list.get(i); if(capValue != -1) { int itemValue = TwainUtil.toNumber(item.getValue(), -2).intValue(); if (itemValue == capValue) { indexCapValue = i; } } if(defaultSelectedValue != null) { int selectedValueInt = TwainUtil.toNumber(defaultSelectedValue, -3).intValue(); if(selectedValueInt == TwainUtil.toNumber(item.getValue(), -4).intValue()) { indexDefaultSelected = i; } } if(item.isDefault()) { indexListDefault = i; } } if(indexDefaultSelected >= 0) { selecteIndex = indexDefaultSelected; } else if(indexCapValue >= 0) { selecteIndex = indexCapValue; } else { if(indexListDefault >= 0) { selecteIndex = indexListDefault; } else { // fall back to use the first one. selecteIndex = list.size() > 0 ? 0 : -1; } } selectedItem = selecteIndex >= 0 ? list.get(selecteIndex) : null; for(ListDataListener listener : listeners) { listener.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, 0, 0)); } } public void setSelectedIndex(int index) { if(list == null) { throw new RuntimeException("List is null"); } if(index < 0 || index >= list.size()) { throw new IndexOutOfBoundsException(); } setSelectedItem(list.get(index)); } public int getSelecteIndex() { return selecteIndex; } @Override public void setSelectedItem(Object anItem) { this.selectedItem = (CapOptionItem) anItem; this.selecteIndex = list.indexOf(selectedItem); } @Override public Object getSelectedItem() { return selectedItem; } @Override public int getSize() { return list == null ? 0 : list.size(); } @Override public Object getElementAt(int index) { return list == null ? null : list.get(index); } @Override public void addListDataListener(ListDataListener l) { if(! listeners.contains(l)) { listeners.add(l); } } @Override public void removeListDataListener(ListDataListener l) { listeners.remove(l); } } }