Drop custom hosts
This commit is contained in:
1 parent
a942a487a0
commit
c112322daf
22 files changed
+2
-871
No files matched your search
@@ -195,8 +195,6 @@ class EhApplication : Application(), DefaultLifecycleObserver, ImageLoaderFactor
|
||||
}
|
||||
}
|
||||
|
||||
val hosts by lazy { Hosts(application, "hosts.db") }
|
||||
|
||||
val favouriteStatusRouter by lazy { FavouriteStatusRouter() }
|
||||
|
||||
val readerPreferences by lazy { ReaderPreferences(AndroidPreferenceStore(application)) }
|
||||
|
||||
@@ -20,44 +20,13 @@ package com.hippo.ehviewer;
|
||||
* Created by Hippo on 2018/3/21.
|
||||
*/
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.hippo.ehviewer.database.MSQLiteBuilder;
|
||||
import com.hippo.ehviewer.util.SqlUtils;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Hosts {
|
||||
|
||||
private static final int VERSION_1 = 1;
|
||||
private static final String TABLE_HOSTS = "HOSTS";
|
||||
private static final String COLUMN_HOST = "HOST";
|
||||
private static final String COLUMN_IP = "IP";
|
||||
|
||||
private static final int DB_VERSION = VERSION_1;
|
||||
|
||||
private final SQLiteDatabase db;
|
||||
|
||||
public Hosts(Context context, String name) {
|
||||
SQLiteOpenHelper helper = new MSQLiteBuilder()
|
||||
.version(VERSION_1)
|
||||
.createTable(TABLE_HOSTS)
|
||||
.insertColumn(TABLE_HOSTS, COLUMN_HOST, String.class)
|
||||
.insertColumn(TABLE_HOSTS, COLUMN_IP, String.class)
|
||||
.build(context, name, DB_VERSION);
|
||||
db = helper.getWritableDatabase();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static InetAddress toInetAddress(String host, String ip) {
|
||||
if (!isValidHost(host)) {
|
||||
@@ -116,22 +85,6 @@ public class Hosts {
|
||||
return labelLength >= 1 && labelLength <= 63;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if ips are valid.
|
||||
*/
|
||||
public static boolean isValidIp(String ips) {
|
||||
if (ips == null) {
|
||||
return false;
|
||||
}
|
||||
String[] list = ips.split("\\+");
|
||||
for (String ip : list) {
|
||||
if (parseV4(ip) == null && parseV6(ip) == null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// org.xbill.DNS.Address.parseV4
|
||||
@Nullable
|
||||
private static byte[] parseV4(String s) {
|
||||
@@ -268,76 +221,4 @@ public class Hosts {
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a InetAddress with the host.
|
||||
*/
|
||||
@Nullable
|
||||
public List<InetAddress> get(String host) {
|
||||
if (!isValidHost(host)) {
|
||||
return null;
|
||||
}
|
||||
try (Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_HOSTS + " WHERE " + COLUMN_HOST + " = ?;", new String[]{host})) {
|
||||
if (cursor.moveToNext()) {
|
||||
String[] ips = SqlUtils.getString(cursor, COLUMN_IP, null).split("\\+");
|
||||
List<InetAddress> addresses = new ArrayList<>();
|
||||
for (String ip : ips) {
|
||||
addresses.add(toInetAddress(host, ip));
|
||||
}
|
||||
return addresses;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contains(String host) {
|
||||
try (Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_HOSTS + " WHERE " + COLUMN_HOST + " = ?;", new String[]{host})) {
|
||||
return cursor.moveToNext();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the host-ip pair into this hosts.
|
||||
*/
|
||||
public boolean put(String host, String ip) {
|
||||
if (!isValidHost(host) || !isValidIp(ip)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(COLUMN_HOST, host);
|
||||
values.put(COLUMN_IP, ip);
|
||||
|
||||
if (contains(host)) {
|
||||
db.update(TABLE_HOSTS, values, COLUMN_HOST + " = ?", new String[]{host});
|
||||
} else {
|
||||
db.insert(TABLE_HOSTS, null, values);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts delete the entry with the host.
|
||||
*/
|
||||
public void delete(String host) {
|
||||
db.delete(TABLE_HOSTS, COLUMN_HOST + " = ?", new String[]{host});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from this host.
|
||||
*/
|
||||
public List<Pair<String, String>> getAll() {
|
||||
List<Pair<String, String>> result = new ArrayList<>();
|
||||
|
||||
try (Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_HOSTS + ";", null)) {
|
||||
while (cursor.moveToNext()) {
|
||||
String host = SqlUtils.getString(cursor, COLUMN_HOST, null);
|
||||
String ip = SqlUtils.getString(cursor, COLUMN_IP, null);
|
||||
result.add(new Pair<>(host, ip));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.hippo.ehviewer.client
|
||||
|
||||
import com.hippo.ehviewer.EhApplication
|
||||
import com.hippo.ehviewer.Hosts
|
||||
import com.hippo.ehviewer.Settings
|
||||
import okhttp3.Dns
|
||||
@@ -23,7 +22,6 @@ import java.net.InetAddress
|
||||
import java.net.UnknownHostException
|
||||
|
||||
object EhDns : Dns {
|
||||
private val hosts = EhApplication.hosts
|
||||
private val builtInHosts: MutableMap<String, List<InetAddress>> = mutableMapOf()
|
||||
|
||||
init {
|
||||
@@ -127,11 +125,10 @@ object EhDns : Dns {
|
||||
|
||||
@Throws(UnknownHostException::class)
|
||||
override fun lookup(hostname: String): List<InetAddress> {
|
||||
return hosts[hostname] ?: builtInHosts[hostname].takeIf { Settings.builtInHosts }
|
||||
?: Dns.SYSTEM.lookup(hostname)
|
||||
return builtInHosts[hostname].takeIf { Settings.builtInHosts } ?: Dns.SYSTEM.lookup(hostname)
|
||||
}
|
||||
|
||||
fun isInHosts(hostname: String): Boolean {
|
||||
return hosts.contains(hostname) || (builtInHosts.contains(hostname) && Settings.builtInHosts)
|
||||
return builtInHosts.contains(hostname) && Settings.builtInHosts
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Hippo Seven
|
||||
*
|
||||
* Licensed 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 com.hippo.ehviewer.database
|
||||
|
||||
import android.content.Context
|
||||
import android.database.sqlite.SQLiteOpenHelper
|
||||
import android.util.SparseArray
|
||||
|
||||
class MSQLiteBuilder {
|
||||
companion object {
|
||||
const val COLUMN_ID = "_id"
|
||||
private val JAVA_TYPE_TO_SQLITE_TYPE: MutableMap<Class<*>?, String> = HashMap()
|
||||
private fun javaTypeToSQLiteType(clazz: Class<*>?): String {
|
||||
return JAVA_TYPE_TO_SQLITE_TYPE[clazz]
|
||||
?: throw IllegalStateException("Unknown type: $clazz")
|
||||
}
|
||||
|
||||
init {
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[Boolean::class.javaPrimitiveType] =
|
||||
"INTEGER NOT NULL DEFAULT 0"
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[Byte::class.javaPrimitiveType] =
|
||||
"INTEGER NOT NULL DEFAULT 0"
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[Short::class.javaPrimitiveType] =
|
||||
"INTEGER NOT NULL DEFAULT 0"
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[Int::class.javaPrimitiveType] = "INTEGER NOT NULL DEFAULT 0"
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[Long::class.javaPrimitiveType] =
|
||||
"INTEGER NOT NULL DEFAULT 0"
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[Float::class.javaPrimitiveType] =
|
||||
"REAL NOT NULL DEFAULT 0"
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[Double::class.javaPrimitiveType] = "REAL NOT NULL DEFAULT 0"
|
||||
JAVA_TYPE_TO_SQLITE_TYPE[String::class.java] = "TEXT"
|
||||
}
|
||||
}
|
||||
|
||||
private val statementsMap = SparseArray<List<String>?>()
|
||||
private var version = 0
|
||||
private var statements: MutableList<String>? = null
|
||||
|
||||
/**
|
||||
* Bump database version.
|
||||
*/
|
||||
fun version(version: Int): MSQLiteBuilder {
|
||||
check(version > this.version) {
|
||||
(
|
||||
"New version must be bigger than current version. " +
|
||||
"current version: " + this.version + ", new version: " + version + "."
|
||||
)
|
||||
}
|
||||
this.version = version
|
||||
statements = ArrayList()
|
||||
statementsMap.put(version, statements)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a table.
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun createTable(
|
||||
table: String,
|
||||
column: String = COLUMN_ID,
|
||||
clazz: Class<*>? = Int::class.javaPrimitiveType,
|
||||
): MSQLiteBuilder {
|
||||
return statement("CREATE TABLE " + table + " (" + column + " " + javaTypeToSQLiteType(clazz) + " PRIMARY KEY);")
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops a table.
|
||||
*/
|
||||
fun dropTable(table: String): MSQLiteBuilder {
|
||||
return statement("DROP TABLE $table;")
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a column to the table.
|
||||
*/
|
||||
fun insertColumn(table: String, column: String, clazz: Class<*>?): MSQLiteBuilder {
|
||||
return statement(
|
||||
"ALTER TABLE $table ADD COLUMN $column " + javaTypeToSQLiteType(
|
||||
clazz,
|
||||
) + ";",
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a statement.
|
||||
*/
|
||||
fun statement(statement: String): MSQLiteBuilder {
|
||||
check(!(version == 0 || statements == null)) { "Call version() first!" }
|
||||
statements!!.add(statement)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a SQLiteOpenHelper from it.
|
||||
*/
|
||||
fun build(context: Context?, name: String?, version: Int): SQLiteOpenHelper {
|
||||
return MSQLiteOpenHelper(context, name, version, this)
|
||||
}
|
||||
|
||||
fun getStatements(oldVersion: Int, newVersion: Int): List<String> {
|
||||
val result: MutableList<String> = ArrayList()
|
||||
for (i in oldVersion + 1..newVersion) {
|
||||
val list = statementsMap[i]
|
||||
if (list != null) {
|
||||
result.addAll(list)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Hippo Seven
|
||||
*
|
||||
* Licensed 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 com.hippo.ehviewer.database
|
||||
|
||||
import android.content.Context
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.database.sqlite.SQLiteOpenHelper
|
||||
import com.hippo.ehviewer.util.SqlUtils
|
||||
|
||||
internal class MSQLiteOpenHelper(
|
||||
context: Context?,
|
||||
name: String?,
|
||||
private val version: Int,
|
||||
private val builder: MSQLiteBuilder,
|
||||
) : SQLiteOpenHelper(context, name, null, version) {
|
||||
override fun onCreate(db: SQLiteDatabase) {
|
||||
onUpgrade(db, 0, version)
|
||||
}
|
||||
|
||||
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
for (command in builder.getStatements(oldVersion, newVersion)) {
|
||||
db.execSQL(command)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDowngrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
SqlUtils.dropAllTable(db)
|
||||
onCreate(db)
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,6 @@ open class BasePreferenceFragment :
|
||||
"filter" -> FilterFragment()
|
||||
"mytags" -> MyTagsFragment()
|
||||
"uconfig" -> UConfigFragment()
|
||||
"hosts" -> HostsFragment()
|
||||
"license" -> LicenseFragment()
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 Tarsin Norbin
|
||||
*
|
||||
* This file is part of EhViewer
|
||||
*
|
||||
* EhViewer is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* EhViewer is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with EhViewer.
|
||||
* If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.hippo.ehviewer.ui.fragment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.util.Pair
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.hippo.ehviewer.EhApplication
|
||||
import com.hippo.ehviewer.Hosts
|
||||
import com.hippo.ehviewer.R
|
||||
import com.hippo.ehviewer.ui.legacy.BaseDialogBuilder
|
||||
import com.hippo.ehviewer.ui.legacy.ViewTransition
|
||||
|
||||
class HostsFragment : BaseFragment(), View.OnClickListener {
|
||||
private var hosts: Hosts? = null
|
||||
private var data: List<Pair<String, String>>? = null
|
||||
private var mViewTransition: ViewTransition? = null
|
||||
private var adapter: HostsAdapter? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
EhApplication.hosts.apply {
|
||||
hosts = this
|
||||
data = all
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?,
|
||||
): View {
|
||||
val recyclerView = inflater.inflate(R.layout.rv_layout, container, false) as RecyclerView
|
||||
val tip = getTipView(R.string.hosts)
|
||||
mViewTransition =
|
||||
ViewTransition(recyclerView, tip)
|
||||
val fab = getFabViewAndShow()
|
||||
adapter = HostsAdapter()
|
||||
recyclerView.adapter = adapter
|
||||
recyclerView.layoutManager =
|
||||
LinearLayoutManager(requireActivity(), RecyclerView.VERTICAL, false)
|
||||
recyclerView.setHasFixedSize(true)
|
||||
fab.setOnClickListener(this)
|
||||
return recyclerView
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
updateView(false)
|
||||
}
|
||||
|
||||
fun onItemClick(position: Int): Boolean {
|
||||
val pair = data!![position]
|
||||
val args = Bundle()
|
||||
args.putString(KEY_HOST, pair.first)
|
||||
args.putString(KEY_IP, pair.second)
|
||||
val fragment: DialogFragment = EditHostDialogFragment()
|
||||
fragment.arguments = args
|
||||
fragment.show(childFragmentManager, DIALOG_TAG_EDIT_HOST)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
AddHostDialogFragment().show(childFragmentManager, DIALOG_TAG_ADD_HOST)
|
||||
}
|
||||
|
||||
private fun updateView(animation: Boolean) {
|
||||
if (null == mViewTransition) {
|
||||
return
|
||||
}
|
||||
data = hosts!!.all
|
||||
if ((data as MutableList<Pair<String, String>>?)?.isEmpty() == true) {
|
||||
mViewTransition!!.showView(1, animation)
|
||||
} else {
|
||||
mViewTransition!!.showView(0, animation)
|
||||
}
|
||||
adapter!!.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun getFragmentTitle(): Int {
|
||||
return R.string.hosts
|
||||
}
|
||||
|
||||
abstract class HostDialogFragment : DialogFragment() {
|
||||
private var hostsFragment: HostsFragment? = null
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
hostsFragment = parentFragment as HostsFragment?
|
||||
val view = layoutInflater.inflate(R.layout.dialog_hosts, null, false)
|
||||
val host = view.findViewById<TextView>(R.id.host)
|
||||
val ip = view.findViewById<TextView>(R.id.ip)
|
||||
val arguments = arguments
|
||||
if (savedInstanceState == null && arguments != null) {
|
||||
host.text = arguments.getString(KEY_HOST)
|
||||
ip.text = arguments.getString(KEY_IP)
|
||||
}
|
||||
val builder = BaseDialogBuilder(requireContext())
|
||||
builder.setView(view)
|
||||
onCreateDialogBuilder(builder)
|
||||
val dialog = builder.create()
|
||||
dialog.setOnShowListener { d: DialogInterface -> onCreateDialog(d as AlertDialog) }
|
||||
return dialog
|
||||
}
|
||||
|
||||
protected abstract fun onCreateDialogBuilder(builder: AlertDialog.Builder)
|
||||
protected abstract fun onCreateDialog(dialog: AlertDialog)
|
||||
protected fun put(dialog: AlertDialog) {
|
||||
val host = dialog.findViewById<TextView>(R.id.host)
|
||||
val ip = dialog.findViewById<TextView>(R.id.ip)
|
||||
if (host == null || ip == null) {
|
||||
return
|
||||
}
|
||||
val hostString = host.text.toString().trim { it <= ' ' }.lowercase()
|
||||
val ipString = ip.text.toString().trim { it <= ' ' }
|
||||
if (!Hosts.isValidHost(hostString)) {
|
||||
val hostInputLayout =
|
||||
dialog.findViewById<TextInputLayout>(R.id.host_input_layout) ?: return
|
||||
hostInputLayout.error = getString(R.string.invalid_host)
|
||||
return
|
||||
}
|
||||
if (!Hosts.isValidIp(ipString)) {
|
||||
val ipInputLayout =
|
||||
dialog.findViewById<TextInputLayout>(R.id.ip_input_layout) ?: return
|
||||
ipInputLayout.error = getString(R.string.invalid_ip)
|
||||
return
|
||||
}
|
||||
hostsFragment!!.hosts!!.put(hostString, ipString)
|
||||
hostsFragment!!.updateView(true)
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
protected fun delete(dialog: AlertDialog) {
|
||||
val host = dialog.findViewById<TextView>(R.id.host) ?: return
|
||||
val hostString = host.text.toString().trim { it <= ' ' }.lowercase()
|
||||
hostsFragment!!.hosts!!.delete(hostString)
|
||||
hostsFragment!!.updateView(true)
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
class AddHostDialogFragment : HostDialogFragment() {
|
||||
override fun onCreateDialogBuilder(builder: AlertDialog.Builder) {
|
||||
builder.setTitle(R.string.add_host)
|
||||
builder.setPositiveButton(R.string.add_host_add, null)
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
}
|
||||
|
||||
override fun onCreateDialog(dialog: AlertDialog) {
|
||||
dialog.getButton(DialogInterface.BUTTON_POSITIVE)
|
||||
.setOnClickListener { put(dialog) }
|
||||
}
|
||||
}
|
||||
|
||||
class EditHostDialogFragment : HostDialogFragment() {
|
||||
override fun onCreateDialogBuilder(builder: AlertDialog.Builder) {
|
||||
builder.setTitle(R.string.edit_host)
|
||||
builder.setPositiveButton(R.string.edit_host_confirm, null)
|
||||
builder.setNegativeButton(R.string.edit_host_delete, null)
|
||||
}
|
||||
|
||||
override fun onCreateDialog(dialog: AlertDialog) {
|
||||
val hostInputLayout =
|
||||
dialog.findViewById<TextInputLayout>(R.id.host_input_layout) ?: return
|
||||
hostInputLayout.isEnabled = false
|
||||
dialog.getButton(DialogInterface.BUTTON_POSITIVE)
|
||||
.setOnClickListener { put(dialog) }
|
||||
dialog.getButton(DialogInterface.BUTTON_NEGATIVE)
|
||||
.setOnClickListener { delete(dialog) }
|
||||
}
|
||||
}
|
||||
|
||||
private class HostsHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val host: TextView
|
||||
val ip: TextView
|
||||
|
||||
init {
|
||||
host = itemView.findViewById(R.id.host)
|
||||
ip = itemView.findViewById(R.id.ip)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class HostsAdapter : RecyclerView.Adapter<HostsHolder>() {
|
||||
private val inflater = layoutInflater
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HostsHolder {
|
||||
return HostsHolder(inflater.inflate(R.layout.item_hosts, parent, false))
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: HostsHolder, position: Int) {
|
||||
val pair = data!![position]
|
||||
holder.host.text = pair.first
|
||||
holder.ip.text = pair.second
|
||||
holder.itemView.setOnClickListener { onItemClick(position) }
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return data!!.size
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val DIALOG_TAG_ADD_HOST = AddHostDialogFragment::class.java.name
|
||||
private val DIALOG_TAG_EDIT_HOST = EditHostDialogFragment::class.java.name
|
||||
private const val KEY_HOST = "com.hippo.ehviewer.ui.fragment.HostsFragment.HOST"
|
||||
private const val KEY_IP = "com.hippo.ehviewer.ui.fragment.HostsFragment.IP"
|
||||
}
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 Hippo Seven
|
||||
*
|
||||
* Licensed 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 com.hippo.ehviewer.util;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.database.SQLException;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SqlUtils {
|
||||
|
||||
public static void exeSQLSafely(SQLiteDatabase db, String sql) {
|
||||
try {
|
||||
db.execSQL(sql);
|
||||
} catch (SQLException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
public static void dropTable(SQLiteDatabase db, String tableName) {
|
||||
exeSQLSafely(db, "DROP TABLE IF EXISTS " + tableName);
|
||||
}
|
||||
|
||||
public static void dropAllTable(SQLiteDatabase db) {
|
||||
List<String> tables = new ArrayList<>();
|
||||
Cursor cursor = db.rawQuery("SELECT * FROM sqlite_master WHERE type='table';", null);
|
||||
cursor.moveToFirst();
|
||||
while (!cursor.isAfterLast()) {
|
||||
String tableName = cursor.getString(1);
|
||||
if (!tableName.equals("android_metadata") &&
|
||||
!tableName.equals("sqlite_sequence"))
|
||||
tables.add(tableName);
|
||||
cursor.moveToNext();
|
||||
}
|
||||
cursor.close();
|
||||
|
||||
for (String tableName : tables) {
|
||||
dropTable(db, tableName);
|
||||
}
|
||||
}
|
||||
|
||||
public static String sqlEscapeString(String value) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int length = value.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
char c = value.charAt(i);
|
||||
if (c == '\'') {
|
||||
sb.append('\'');
|
||||
}
|
||||
sb.append(c);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static boolean getBoolean(Cursor cursor, String column, boolean defValue) {
|
||||
try {
|
||||
int index = cursor.getColumnIndex(column);
|
||||
if (index != -1) {
|
||||
return cursor.getInt(index) != 0;
|
||||
}
|
||||
} catch (Throwable e) { /* Ignore */ }
|
||||
return defValue;
|
||||
}
|
||||
|
||||
public static int getInt(Cursor cursor, String column, int defValue) {
|
||||
try {
|
||||
int index = cursor.getColumnIndex(column);
|
||||
if (index != -1) {
|
||||
return cursor.getInt(index);
|
||||
}
|
||||
} catch (Throwable e) { /* Ignore */ }
|
||||
return defValue;
|
||||
}
|
||||
|
||||
public static long getLong(Cursor cursor, String column, long defValue) {
|
||||
try {
|
||||
int index = cursor.getColumnIndex(column);
|
||||
if (index != -1) {
|
||||
return cursor.getLong(index);
|
||||
}
|
||||
} catch (Throwable e) { /* Ignore */ }
|
||||
return defValue;
|
||||
}
|
||||
|
||||
public static float getFloat(Cursor cursor, String column, float defValue) {
|
||||
try {
|
||||
int index = cursor.getColumnIndex(column);
|
||||
if (index != -1) {
|
||||
return cursor.getFloat(index);
|
||||
}
|
||||
} catch (Throwable e) { /* Ignore */ }
|
||||
return defValue;
|
||||
}
|
||||
|
||||
public static String getString(Cursor cursor, String column, String defValue) {
|
||||
try {
|
||||
int index = cursor.getColumnIndex(column);
|
||||
if (index != -1) {
|
||||
return cursor.getString(index);
|
||||
}
|
||||
} catch (Throwable e) { /* Ignore */ }
|
||||
return defValue;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user