13bf66744d61d18c66d46f2608de0467ad3df0268Mopria/* 23bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Copyright (C) 2016 The Android Open Source Project 33bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Copyright (C) 2016 Mopria Alliance, Inc. 43bf66744d61d18c66d46f2608de0467ad3df0268Mopria * 53bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Licensed under the Apache License, Version 2.0 (the "License"); 63bf66744d61d18c66d46f2608de0467ad3df0268Mopria * you may not use this file except in compliance with the License. 73bf66744d61d18c66d46f2608de0467ad3df0268Mopria * You may obtain a copy of the License at 83bf66744d61d18c66d46f2608de0467ad3df0268Mopria * 93bf66744d61d18c66d46f2608de0467ad3df0268Mopria * http://www.apache.org/licenses/LICENSE-2.0 103bf66744d61d18c66d46f2608de0467ad3df0268Mopria * 113bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Unless required by applicable law or agreed to in writing, software 123bf66744d61d18c66d46f2608de0467ad3df0268Mopria * distributed under the License is distributed on an "AS IS" BASIS, 133bf66744d61d18c66d46f2608de0467ad3df0268Mopria * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 143bf66744d61d18c66d46f2608de0467ad3df0268Mopria * See the License for the specific language governing permissions and 153bf66744d61d18c66d46f2608de0467ad3df0268Mopria * limitations under the License. 163bf66744d61d18c66d46f2608de0467ad3df0268Mopria */ 173bf66744d61d18c66d46f2608de0467ad3df0268Mopria 183bf66744d61d18c66d46f2608de0467ad3df0268Mopriapackage com.android.bips.ui; 193bf66744d61d18c66d46f2608de0467ad3df0268Mopria 203bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.annotation.SuppressLint; 213bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.app.AlertDialog; 223bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.content.Context; 233bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.os.Bundle; 243bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.text.Editable; 253bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.text.TextWatcher; 263bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.util.Log; 273bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.view.KeyEvent; 283bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.view.View; 293bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.view.Window; 303bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.view.WindowManager; 313bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.view.inputmethod.EditorInfo; 323bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.view.inputmethod.InputMethodManager; 333bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.widget.Button; 343bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.widget.ProgressBar; 353bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.widget.TextView; 363bf66744d61d18c66d46f2608de0467ad3df0268Mopria 373bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport com.android.bips.R; 383bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport com.android.bips.discovery.DiscoveredPrinter; 393bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport com.android.bips.discovery.ManualDiscovery; 403bf66744d61d18c66d46f2608de0467ad3df0268Mopria 413bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport java.util.regex.Matcher; 423bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport java.util.regex.Pattern; 433bf66744d61d18c66d46f2608de0467ad3df0268Mopria 443bf66744d61d18c66d46f2608de0467ad3df0268Mopria/** 453bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Allows the user to enter printer address manually 463bf66744d61d18c66d46f2608de0467ad3df0268Mopria */ 473bf66744d61d18c66d46f2608de0467ad3df0268Mopriaclass AddManualPrinterDialog extends AlertDialog implements TextWatcher, 483bf66744d61d18c66d46f2608de0467ad3df0268Mopria TextView.OnEditorActionListener, View.OnKeyListener { 493bf66744d61d18c66d46f2608de0467ad3df0268Mopria private static final String TAG = AddManualPrinterDialog.class.getSimpleName(); 503bf66744d61d18c66d46f2608de0467ad3df0268Mopria private static final boolean DEBUG = false; 513bf66744d61d18c66d46f2608de0467ad3df0268Mopria 523bf66744d61d18c66d46f2608de0467ad3df0268Mopria /** 533bf66744d61d18c66d46f2608de0467ad3df0268Mopria * A regex that matches IP addresses and domain names like "192.168.1.101" and 543bf66744d61d18c66d46f2608de0467ad3df0268Mopria * "printer1.company.com" 553bf66744d61d18c66d46f2608de0467ad3df0268Mopria */ 563bf66744d61d18c66d46f2608de0467ad3df0268Mopria private static final String NAME_IP_REGEX = 573bf66744d61d18c66d46f2608de0467ad3df0268Mopria "[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*)*"; 583bf66744d61d18c66d46f2608de0467ad3df0268Mopria private static final String HOSTNAME_REGEXP = "^" + NAME_IP_REGEX + "$"; 593bf66744d61d18c66d46f2608de0467ad3df0268Mopria private static final Pattern HOSTNAME_PATTERN = Pattern.compile(HOSTNAME_REGEXP); 603bf66744d61d18c66d46f2608de0467ad3df0268Mopria 613bf66744d61d18c66d46f2608de0467ad3df0268Mopria private final ManualDiscovery mDiscovery; 623bf66744d61d18c66d46f2608de0467ad3df0268Mopria private TextView mHostnameView; 633bf66744d61d18c66d46f2608de0467ad3df0268Mopria private Button mAddButton; 643bf66744d61d18c66d46f2608de0467ad3df0268Mopria private ProgressBar mProgressBar; 653bf66744d61d18c66d46f2608de0467ad3df0268Mopria 663bf66744d61d18c66d46f2608de0467ad3df0268Mopria AddManualPrinterDialog(Context context, ManualDiscovery discovery) { 673bf66744d61d18c66d46f2608de0467ad3df0268Mopria super(context); 683bf66744d61d18c66d46f2608de0467ad3df0268Mopria mDiscovery = discovery; 693bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 703bf66744d61d18c66d46f2608de0467ad3df0268Mopria 713bf66744d61d18c66d46f2608de0467ad3df0268Mopria @SuppressLint("InflateParams") 723bf66744d61d18c66d46f2608de0467ad3df0268Mopria @Override 733bf66744d61d18c66d46f2608de0467ad3df0268Mopria protected void onCreate(Bundle savedInstanceState) { 743bf66744d61d18c66d46f2608de0467ad3df0268Mopria if (DEBUG) Log.d(TAG, "onCreate"); 753bf66744d61d18c66d46f2608de0467ad3df0268Mopria View view = getLayoutInflater().inflate(R.layout.manual_printer_add, null); 763bf66744d61d18c66d46f2608de0467ad3df0268Mopria setView(view); 773bf66744d61d18c66d46f2608de0467ad3df0268Mopria setTitle(R.string.add_manual_printer); 783bf66744d61d18c66d46f2608de0467ad3df0268Mopria setButton(AlertDialog.BUTTON_NEGATIVE, getContext().getString(android.R.string.cancel), 793bf66744d61d18c66d46f2608de0467ad3df0268Mopria (OnClickListener) null); 803bf66744d61d18c66d46f2608de0467ad3df0268Mopria setButton(AlertDialog.BUTTON_POSITIVE, getContext().getString(R.string.add), 813bf66744d61d18c66d46f2608de0467ad3df0268Mopria (OnClickListener) null); 823bf66744d61d18c66d46f2608de0467ad3df0268Mopria 833bf66744d61d18c66d46f2608de0467ad3df0268Mopria super.onCreate(savedInstanceState); 843bf66744d61d18c66d46f2608de0467ad3df0268Mopria mAddButton = getButton(AlertDialog.BUTTON_POSITIVE); 853bf66744d61d18c66d46f2608de0467ad3df0268Mopria mHostnameView = (TextView) findViewById(R.id.hostname); 863bf66744d61d18c66d46f2608de0467ad3df0268Mopria mProgressBar = (ProgressBar) findViewById(R.id.progress); 873bf66744d61d18c66d46f2608de0467ad3df0268Mopria 883bf66744d61d18c66d46f2608de0467ad3df0268Mopria mAddButton.setOnClickListener(view1 -> addPrinter()); 893bf66744d61d18c66d46f2608de0467ad3df0268Mopria 903bf66744d61d18c66d46f2608de0467ad3df0268Mopria // Update add button as contents change 913bf66744d61d18c66d46f2608de0467ad3df0268Mopria mHostnameView.addTextChangedListener(this); 923bf66744d61d18c66d46f2608de0467ad3df0268Mopria mHostnameView.setOnEditorActionListener(this); 933bf66744d61d18c66d46f2608de0467ad3df0268Mopria mHostnameView.setOnKeyListener(this); 943bf66744d61d18c66d46f2608de0467ad3df0268Mopria 953bf66744d61d18c66d46f2608de0467ad3df0268Mopria // Force open keyboard if appropriate 963bf66744d61d18c66d46f2608de0467ad3df0268Mopria openKeyboard(mHostnameView); 973bf66744d61d18c66d46f2608de0467ad3df0268Mopria 983bf66744d61d18c66d46f2608de0467ad3df0268Mopria updateButtonState(); 993bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1003bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1013bf66744d61d18c66d46f2608de0467ad3df0268Mopria private void openKeyboard(TextView view) { 1023bf66744d61d18c66d46f2608de0467ad3df0268Mopria Window window = getWindow(); 1033bf66744d61d18c66d46f2608de0467ad3df0268Mopria if (window != null) { 1043bf66744d61d18c66d46f2608de0467ad3df0268Mopria window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); 1053bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1063bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1073bf66744d61d18c66d46f2608de0467ad3df0268Mopria view.requestFocus(); 1083bf66744d61d18c66d46f2608de0467ad3df0268Mopria InputMethodManager imm = (InputMethodManager) getContext() 1093bf66744d61d18c66d46f2608de0467ad3df0268Mopria .getSystemService(Context.INPUT_METHOD_SERVICE); 1103bf66744d61d18c66d46f2608de0467ad3df0268Mopria imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); 1113bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1123bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1133bf66744d61d18c66d46f2608de0467ad3df0268Mopria private void updateButtonState() { 1143bf66744d61d18c66d46f2608de0467ad3df0268Mopria String hostname = mHostnameView.getText().toString(); 1153bf66744d61d18c66d46f2608de0467ad3df0268Mopria Matcher hostMatch = HOSTNAME_PATTERN.matcher(hostname); 1163bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1173bf66744d61d18c66d46f2608de0467ad3df0268Mopria mAddButton.setEnabled(hostMatch.matches()); 1183bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1193bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1203bf66744d61d18c66d46f2608de0467ad3df0268Mopria /** Attempt to add the printer based on current data */ 1213bf66744d61d18c66d46f2608de0467ad3df0268Mopria private void addPrinter() { 1223bf66744d61d18c66d46f2608de0467ad3df0268Mopria // Disable other actions while we are checking 1233bf66744d61d18c66d46f2608de0467ad3df0268Mopria mAddButton.setEnabled(false); 1243bf66744d61d18c66d46f2608de0467ad3df0268Mopria mHostnameView.setEnabled(false); 1253bf66744d61d18c66d46f2608de0467ad3df0268Mopria mProgressBar.setVisibility(View.VISIBLE); 1263bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1273bf66744d61d18c66d46f2608de0467ad3df0268Mopria // Begin an attempt to add the printer 1283bf66744d61d18c66d46f2608de0467ad3df0268Mopria mDiscovery.addManualPrinter(mHostnameView.getText().toString(), 1293bf66744d61d18c66d46f2608de0467ad3df0268Mopria new ManualDiscovery.PrinterAddCallback() { 1303bf66744d61d18c66d46f2608de0467ad3df0268Mopria @Override 1313bf66744d61d18c66d46f2608de0467ad3df0268Mopria public void onFound(DiscoveredPrinter printer, boolean supported) { 1323bf66744d61d18c66d46f2608de0467ad3df0268Mopria if (supported) { 1333bf66744d61d18c66d46f2608de0467ad3df0268Mopria // Success case 1343bf66744d61d18c66d46f2608de0467ad3df0268Mopria dismiss(); 1353bf66744d61d18c66d46f2608de0467ad3df0268Mopria } else { 1363bf66744d61d18c66d46f2608de0467ad3df0268Mopria error(getContext().getString(R.string.printer_not_supported)); 1373bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1383bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1393bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1403bf66744d61d18c66d46f2608de0467ad3df0268Mopria @Override 1413bf66744d61d18c66d46f2608de0467ad3df0268Mopria public void onNotFound() { 1423bf66744d61d18c66d46f2608de0467ad3df0268Mopria error(getContext().getString(R.string.no_printer_found)); 1433bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1443bf66744d61d18c66d46f2608de0467ad3df0268Mopria }); 1453bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1463bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1473bf66744d61d18c66d46f2608de0467ad3df0268Mopria /** Inform user of error and allow them to correct it */ 1483bf66744d61d18c66d46f2608de0467ad3df0268Mopria private void error(String message) { 1493bf66744d61d18c66d46f2608de0467ad3df0268Mopria mProgressBar.setVisibility(View.GONE); 1503bf66744d61d18c66d46f2608de0467ad3df0268Mopria mHostnameView.setError(message); 1513bf66744d61d18c66d46f2608de0467ad3df0268Mopria mHostnameView.setEnabled(true); 1523bf66744d61d18c66d46f2608de0467ad3df0268Mopria openKeyboard(mHostnameView); 1533bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1543bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1553bf66744d61d18c66d46f2608de0467ad3df0268Mopria @Override 1563bf66744d61d18c66d46f2608de0467ad3df0268Mopria public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) { 1573bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1583bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1593bf66744d61d18c66d46f2608de0467ad3df0268Mopria @Override 1603bf66744d61d18c66d46f2608de0467ad3df0268Mopria public void onTextChanged(CharSequence charSequence, int start, int before, int count) { 1613bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1623bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1633bf66744d61d18c66d46f2608de0467ad3df0268Mopria @Override 1643bf66744d61d18c66d46f2608de0467ad3df0268Mopria public void afterTextChanged(Editable editable) { 1653bf66744d61d18c66d46f2608de0467ad3df0268Mopria updateButtonState(); 1663bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1673bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1683bf66744d61d18c66d46f2608de0467ad3df0268Mopria @Override 1693bf66744d61d18c66d46f2608de0467ad3df0268Mopria public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) { 1703bf66744d61d18c66d46f2608de0467ad3df0268Mopria if (id == EditorInfo.IME_ACTION_DONE && mAddButton.isEnabled()) { 1713bf66744d61d18c66d46f2608de0467ad3df0268Mopria addPrinter(); 1723bf66744d61d18c66d46f2608de0467ad3df0268Mopria return true; 1733bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1743bf66744d61d18c66d46f2608de0467ad3df0268Mopria return false; 1753bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1763bf66744d61d18c66d46f2608de0467ad3df0268Mopria 1773bf66744d61d18c66d46f2608de0467ad3df0268Mopria @Override 1783bf66744d61d18c66d46f2608de0467ad3df0268Mopria public boolean onKey(View view, int keyCode, KeyEvent keyEvent) { 1793bf66744d61d18c66d46f2608de0467ad3df0268Mopria if (keyCode == KeyEvent.KEYCODE_ENTER && mAddButton.isEnabled()) { 1803bf66744d61d18c66d46f2608de0467ad3df0268Mopria addPrinter(); 1813bf66744d61d18c66d46f2608de0467ad3df0268Mopria return true; 1823bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1833bf66744d61d18c66d46f2608de0467ad3df0268Mopria return false; 1843bf66744d61d18c66d46f2608de0467ad3df0268Mopria } 1853bf66744d61d18c66d46f2608de0467ad3df0268Mopria}