package org.bbssh.ui.screens; import java.io.IOException; import net.rim.device.api.i18n.ResourceBundleFamily; import net.rim.device.api.ui.Field; import net.rim.device.api.ui.FieldChangeListener; import net.rim.device.api.ui.Font; import net.rim.device.api.ui.Screen; import net.rim.device.api.ui.UiApplication; import net.rim.device.api.ui.component.BasicEditField; import net.rim.device.api.ui.component.CheckboxField; import net.rim.device.api.ui.component.LabelField; import net.rim.device.api.ui.component.ObjectChoiceField; import net.rim.device.api.ui.component.SeparatorField; import net.rim.device.api.ui.component.Status; import net.rim.device.api.ui.container.HorizontalFieldManager; import net.rim.device.api.ui.container.MainScreen; import net.rim.device.api.ui.container.VerticalFieldManager; import org.bbssh.BBSSHApp; import org.bbssh.i18n.BBSSHResource; import org.bbssh.model.ConnectionProperties; import org.bbssh.model.FontSettings; import org.bbssh.net.ConnectionHelper; import org.bbssh.platform.PlatformServicesProvider; import org.bbssh.terminal.TerminalStateData; import org.bbssh.ui.components.ClickableButtonField; import org.bbssh.ui.components.FontPicker; public class ConnectionPropertiesScreen extends MainScreen implements FieldChangeListener, BBSSHResource { // @todo ultimately make a collapsibleFieldManager to contain thesse -- // allowing us to add field groups and collapse them. protected VerticalFieldManager baseFields = new VerticalFieldManager(); protected VerticalFieldManager appearanceFields = new VerticalFieldManager(); protected VerticalFieldManager networkingFields = new VerticalFieldManager(); protected ConnectionProperties prop; protected ResourceBundleFamily res = ResourceBundleFamily.getBundle(BUNDLE_ID, BUNDLE_NAME); protected String[] COLOR_TABLE = res.getStringArray(BBSSHResource.SESSION_DTL_LIST_COLORS); protected boolean saved; protected LabelField basicHeader; protected LabelField networkingHeader; protected BasicEditField keepAliveDurationField; protected LabelField appearanceHeader; protected ClickableButtonField chooseFont; protected BasicEditField termTypeField; protected ObjectChoiceField fnkeyMode; protected ObjectChoiceField bgColorField; protected ObjectChoiceField fgColorField; protected BasicEditField termColField; protected BasicEditField termRowField; protected BasicEditField scrollbackLines; protected ObjectChoiceField connectionTypeField; protected HorizontalFieldManager fontHFM; protected CheckboxField useWifiIfAvailable; protected CheckboxField altPrefixMeta; protected FontSettings fs; /** Connection type */ /** Delimiter between host and port */ protected CheckboxField useHybridInputMode; protected BasicEditField besTimeout; public ConnectionPropertiesScreen(ConnectionProperties prop) { super(Screen.DEFAULT_CLOSE); this.prop = prop; fs = prop.getFontSettings(); createFields(); addFields(); setTitle(res.getString(SESSION_DTL_TITLE_0)); add(baseFields); add(new SeparatorField()); add(appearanceFields); add(new SeparatorField()); add(networkingFields); } /** * Creates the fields. */ protected void createFields() { Font boldFont = getFont().derive(Font.BOLD); besTimeout = new BasicEditField(res.getString(SESSION_DTL_LBL_BES_TIMEOUT), String.valueOf(prop.getBESTimeout()), 5, Field.EDITABLE | BasicEditField.NO_NEWLINE | BasicEditField.NON_SPELLCHECKABLE | BasicEditField.FILTER_NUMERIC); // Networking networkingHeader = new LabelField(res.getString(SESSION_DTL_LBL_NETWORKING)); networkingHeader.setFont(boldFont); connectionTypeField = new ObjectChoiceField(res.getString(SESSION_DTL_LBL_SESSION_TYPE), res.getStringArray(SESSION_DTL_LIST_CONNECT_CHOICES), prop.getConnectionType()); useWifiIfAvailable = new CheckboxField(res.getString(SESSION_DTL_LBL_USE_WIFI_IF_AVAILABLE), prop.getUseWifiIfAvailable()); keepAliveDurationField = new BasicEditField(res.getString(SESSION_DTL_LBL_KEEPALIVE_DURATION), Integer.toString(prop.getKeepAliveTime()), 5, BasicEditField.FILTER_INTEGER | BasicEditField.NON_SPELLCHECKABLE); appearanceHeader = new LabelField(res.getString(SESSION_DTL_LBL_APPEARANCE)); appearanceHeader.setFont(boldFont); FontSettings fs = prop.getFontSettings(); fontHFM = new HorizontalFieldManager(); chooseFont = new ClickableButtonField(); chooseFont.setChangeListener(this); fontHFM.add(new LabelField(res.getString(SESSION_DTL_LBL_FONT))); fontHFM.add(chooseFont); // Free string, 32 termTypeField = new BasicEditField(res.getString(SESSION_DTL_LBL_TERMINAL_TYPE), prop.getTermType(), 32, Field.EDITABLE | BasicEditField.NO_NEWLINE | BasicEditField.NON_SPELLCHECKABLE); fnkeyMode = new ObjectChoiceField(res.getString(SESSION_DTL_LBL_FN_KEY_WORKAROUND), res.getStringArray(SESSION_DTL_LIST_FN_KEY_MODES), prop.getFunctionKeyMode()); if (!PlatformServicesProvider.getInstance().isReducedLayout()) { useHybridInputMode = new CheckboxField(res.getString(SESSION_DTL_LBL_USE_HYBRID), prop.getDefaultInputMode() == TerminalStateData.TYPING_MODE_HYBRID); } bgColorField = new ObjectChoiceField(res.getString(SESSION_DTL_LBL_BG_COLOR), COLOR_TABLE, prop.getBackgroundColorIndex()); fgColorField = new ObjectChoiceField(res.getString(SESSION_DTL_LBL_FG_COLOR), COLOR_TABLE, prop.getForegroundColorIndex()); termColField = new BasicEditField(res.getString(SESSION_DTL_LBL_COLS), Integer.toString(prop.getTerminalCols()), 3, Field.EDITABLE | BasicEditField.FILTER_NUMERIC | BasicEditField.NO_NEWLINE | BasicEditField.NON_SPELLCHECKABLE); termRowField = new BasicEditField(res.getString(SESSION_DTL_LBL_ROWS), Integer.toString(prop.getTerminalRows()), 3, Field.EDITABLE | BasicEditField.FILTER_NUMERIC | BasicEditField.NO_NEWLINE | BasicEditField.NON_SPELLCHECKABLE); scrollbackLines = new BasicEditField(res.getString(SESSION_DTL_LBL_SCROLLBACK), Integer.toString(prop .getScrollbackLines()), 3, Field.EDITABLE | BasicEditField.FILTER_NUMERIC | BasicEditField.NO_NEWLINE | BasicEditField.NON_SPELLCHECKABLE); altPrefixMeta = new CheckboxField(res.getString(SESSION_DTL_ALT_PREFIX_META), prop.getAltPrefixesMeta()); // Finally, update some labels to reflect current state. updateFontButtonText(fs); // Refresh various network releated fields based on selected connection type fieldChanged(connectionTypeField, 1); connectionTypeField.setChangeListener(this); } private void updateFontButtonText(FontSettings fs) { String s = fs.toString(); if (s == null || s.length() == 0) { s = res.getString(GEN_LBL_CLICK_TO_CHOOSE); } chooseFont.setLabel(s); } /** * Adds fields to the screen * * @todo split into ssh vs telnet -for validation too. Provide a ConnectionPropertiesValidator? */ protected void addFields() { appearanceFields.add(appearanceHeader); appearanceFields.add(fontHFM); appearanceFields.add(termTypeField); appearanceFields.add(fnkeyMode); appearanceFields.add(altPrefixMeta); if (!PlatformServicesProvider.getInstance().isReducedLayout()) appearanceFields.add(useHybridInputMode); appearanceFields.add(scrollbackLines); appearanceFields.add(bgColorField); appearanceFields.add(fgColorField); appearanceFields.add(termColField); appearanceFields.add(termRowField); networkingFields.add(networkingHeader); networkingFields.add(connectionTypeField); networkingFields.add(useWifiIfAvailable); networkingFields.add(keepAliveDurationField); networkingFields.add(besTimeout); } public void fieldChanged(Field field, int context) { if (field == chooseFont) { FontPicker p = new FontPicker(prop.getFontSettings()); UiApplication.getUiApplication().pushModalScreen(p); FontSettings s = p.getUpdatedFontSettings(); if (s != null) { fs = s; updateFontButtonText(fs); } } else if (field == connectionTypeField) { // If wifi conection is selected, use wifi flag is meaningless as that's the only OK connection type. if (connectionTypeField.getSelectedIndex() == ConnectionHelper.CONNECTION_TYPE_WIFI) { useWifiIfAvailable.setEditable(false); useWifiIfAvailable.setChecked(false); } else { useWifiIfAvailable.setEditable(true); } if (connectionTypeField.getSelectedIndex() == ConnectionHelper.CONNECTION_TYPE_BES) { besTimeout.setEditable(true); } else { besTimeout.setEditable(false); } } } public void save() throws IOException { byte connType = (byte) connectionTypeField.getSelectedIndex(); prop.setConnectionType(connType); prop.setFontSettings(fs); prop.setTermType(termTypeField.getText()); int sel = bgColorField.getSelectedIndex(); prop.setBackgroundColorIndex(sel == -1 ? 0 : sel); sel = fgColorField.getSelectedIndex(); prop.setForegroundColorIndex(sel == -1 ? 7 : sel); prop.setTerminalCols(Short.parseShort(termColField.getText())); prop.setTerminalRows(Short.parseShort(termRowField.getText())); prop.setScrollbackLines(Short.parseShort(scrollbackLines.getText())); prop.setKeepAliveTime(Integer.parseInt(keepAliveDurationField.getText())); prop.setFunctionKeyMode((byte) fnkeyMode.getSelectedIndex()); if (!PlatformServicesProvider.getInstance().isReducedLayout()) { prop.setDefaultInputMode(useHybridInputMode.getChecked() ? TerminalStateData.TYPING_MODE_HYBRID : TerminalStateData.TYPING_MODE_DIRECT); } prop.setUseWifiIfAvailable(useWifiIfAvailable.getChecked()); prop.setBESTimeout(Integer.parseInt(besTimeout.getText())); prop.setAltPrefixesMeta(altPrefixMeta.getChecked()); super.save(); } protected void promptPermissions(int connType, int msg) { int requiredPermType = ConnectionHelper.getPermissionForConnType(connType); BBSSHApp.inst().requestPermission(requiredPermType, msg); } public boolean isDataValid() { if (besTimeout.isEditable() && Integer.parseInt(besTimeout.getText()) < 0) { Status.show(res.getString(MSG_BES_TIMEOUT_INVALID)); besTimeout.setFocus(); return false; } if (termColField.getTextLength() == 0) termColField.setText("0"); if (termRowField.getTextLength() == 0) termRowField.setText("0"); if (scrollbackLines.getTextLength() == 0) scrollbackLines.setText("0"); promptPermissions(connectionTypeField.getSelectedIndex(), MSG_NET_PERMISSIONS_MISSING_ADD_NOW); if (useWifiIfAvailable.isEditable() && useWifiIfAvailable.getChecked()) { promptPermissions(ConnectionHelper.CONNECTION_TYPE_WIFI, MSG_NET_PERMISSIONS_MISSING_WIFI); } return true; } protected boolean onSave() { saved = true; return super.onSave(); } /** * Returns true if the session details were validated and saved. * * @return save staet */ public boolean isSaved() { return saved; } public ConnectionProperties getEditedProperties() { return prop; } }