package nliveroid.nlr.main;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import nliveroid.nlr.main.parser.XMLparser;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TableRow;
import android.widget.TextView;
public class HandleNameList extends Activity implements HandleNamable {
private Activity ACT;
private ListView listview;
private ArrayAdapter<String[]> adapter;
private LayoutInflater inflater;
private ArrayList<String> ids;
private ArrayList<String> names;
private ArrayList<Integer> bgColors;
private ArrayList<Integer> foColors;
private HashMap<String,Boolean> cbCheck;
private String handleNameFile = "handlenames.xml";
private boolean isSelectMode;
private int tempPosition;
private boolean addFlug;//addする時のみキャンセル時処理を変える
private CheckBox allSelectCb;
private boolean isContextDisp;
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
ACT = this;
inflater = LayoutInflater.from(this);
View parent = inflater.inflate(R.layout.handle_list, null);
NLiveRoid app = (NLiveRoid)getApplicationContext();
TextView head0 = (TextView) parent.findViewById(R.id.handle_head_name);
head0.setWidth( app.getViewWidth() / 2);
TextView head1 = (TextView) parent.findViewById(R.id.handle_head_id);
head1.setWidth(app.getViewWidth() / 2);
listview = (ListView) parent.findViewById(R.id.handle_list);
adapter = new HandleListAdapter(this, R.layout.handle_list_row);
listview.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
if(isContextDisp){
isContextDisp = false;
return;
}
tempPosition = position;
new AlertDialog.Builder(ACT)
.setItems(new String[]{"編集","削除"}, new OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
switch(which){
case 0:
int defaultBgColor = bgColors.get(tempPosition);
int defaultFoColor = foColors.get(tempPosition);
new HandleNamePicker(ACT,
new ColorPickerView.OnColorChangedListener() {
@Override
public void colorChanged(int color) {
// 色が選択されるとcolorに値が入る OKボタンで確定するので未使用
int R = Color.red(color);
int G = Color.green(color);
int B = Color.blue(color);
}
}, defaultBgColor, defaultFoColor,ids.get(tempPosition),names.get(tempPosition),false).show();
break;
case 1:
AlertDialog.Builder ad = new AlertDialog.Builder(ACT);
ad.setTitle("ユーザ情報の削除");
ad.setMessage("このコテハンを削除します\nよろしいですか?");
ad.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
cbCheck.remove(ids.get(tempPosition));
adapter.remove(adapter.getItem(tempPosition));
ids.remove(tempPosition);
names.remove(tempPosition);
bgColors.remove(tempPosition);
foColors.remove(tempPosition);
new WriteHandleName().execute();
}
});
ad.setNegativeButton("CANCEL",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
}
});
ad.create();
ad.show();
break;
}
}
}).create().show();
}
});
listview.setFastScrollEnabled(true);
listview.setAdapter(adapter);
registerForContextMenu(listview);
ids = new ArrayList<String>();
names = new ArrayList<String>();
bgColors = new ArrayList<Integer>();
foColors = new ArrayList<Integer>();
cbCheck = new HashMap<String,Boolean>();
// ファイル読み込み
ErrorCode error = ((NLiveRoid)getApplicationContext()).getError();
readHandleNameData(error);
if(error != null &&error.getErrorCode() != 0){
error.showErrorToast();
finish();
return;
}
String id = "";
try{
for (int i = 0; i < ids.size(); i++) {
id = ids.get(i).length() > 8 ? ids.get(i).substring(0, 6) + ".."
: ids.get(i);
adapter.add(new String[] { names.get(i), id });
}
}catch(NullPointerException e){
MyToast.customToastShow(this.getApplicationContext(), "コテハンファイルの記述がおかしいです");
finish();
}
Button addButton = (Button) parent.findViewById(R.id.addbutton);
addButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
tempPosition = ids.size();
addFlug = true;
ids.add("");
names.add("");
bgColors.add(-1);
foColors.add(0);
cbCheck.put(ids.get(ids.size()-1),false);
adapter.add(new String[] { "", "" });
final EditText et = new EditText(ACT);
et.setSingleLine(true);
AlertDialog.Builder ad = new AlertDialog.Builder(ACT);
ad.setTitle("ユーザ情報の追加");
ad.setMessage("ユーザIDを入力して下さい");
ad.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
// 入力チェック
String tex = et.getText().toString().trim();
Matcher mc = Pattern.compile("[^0-9a-zA-Z]")
.matcher(tex);
if (!mc.find() && !tex.equals("")) {
ids.set(tempPosition, tex);
new HandleNamePicker(
ACT,
new ColorPickerView.OnColorChangedListener() {
@Override
public void colorChanged(
int color) {
// 色が選択されるとcolorに値が入る
// OKボタンで確定するので未使用
int R = Color.red(color);
int G = Color.green(color);
int B = Color.blue(color);
android.util.Log
.d("ColorPickerDialog",
"(R,G,B)=("
+ R
+ ","
+ G
+ ","
+ B
+ ")");
}
}, Color.WHITE,Color.BLACK, tex,tex,false).show();
} else {
Builder error = new AlertDialog.Builder(ACT);
error.setMessage("ユーザIDが不正です");
error.setPositiveButton("OK", null);
error.show();
cancelColorPicker();
}
}
});
ad.setView(et);
ad.setNegativeButton("CANCEL",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
cancelColorPicker();
}
});
ad.create();
ad.show();
}
});
final DialogInterface.OnClickListener preventVeryfiError1 = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int whichButton) {
// 削除処理
Log.d("NLR","REMOVED" );
for(int i = 0; i < ids.size(); i++){
if(cbCheck.get(ids.get(i))){
// Log.d("NLR","REMOVED" + adapter.getItem(i)[0]);
adapter.remove(adapter.getItem(i));
cbCheck.remove(ids.get(i));
ids.remove(i);
names.remove(i);
bgColors.remove(i);
foColors.remove(i);
i--;
}
}
new WriteHandleName().execute();
//削除モードをキャンセルする
clearDeleteMode();
}// End of reallyOK click
};
final DialogInterface.OnClickListener preventVeryfiError2 = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int whichButton) {}};
Button deleteButton = (Button) parent
.findViewById(R.id.deletebutton);
deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(isSelectMode){//選択中だったら、チェックされた項目を削除するダイアログをだす
//選択されたのが1つ以上なければ削除モードを解除
if(!cbCheck.containsValue(true)){
clearDeleteMode();
return;
}
AlertDialog.Builder bachDelete = new AlertDialog.Builder(ACT);
bachDelete.setMessage("選択したコテハンを削除します\nよろしいですか?");
bachDelete.setPositiveButton("OK",preventVeryfiError1
);
bachDelete.setNegativeButton("CANCEL",preventVeryfiError2);
bachDelete.create();
bachDelete.show();
}else{//チェックモードじゃなかった
toDeleteMode();
}
}// End of DeleteButton Click
});// End of DeleteButton listener
//一括削除チェック
allSelectCb = (CheckBox)parent.findViewById(R.id.handle_all_select);
allSelectCb.setOnCheckedChangeListener(new OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton compoundbutton,
boolean flag) {
if(flag){
for(int i = 0; i < ids.size(); i++){
cbCheck.put(ids.get(i),true);
}
//リストの見える部分のチェックを入れる
for(int i = 0; i< listview.getCount(); i++){
if(listview.getChildAt(i)==null)break;
CheckBox cb = (CheckBox) listview.getChildAt(i).findViewById(R.id.handle_delete_cb);
if(cb != null){
cb.setChecked(true);
}
}
}else{
for(int i = 0; i < ids.size(); i++){
cbCheck.put(ids.get(i),false);
}
//リストの見える部分のチェックをはずす
for(int i = 0; i< listview.getCount(); i++){
if(listview.getChildAt(i)==null)break;
CheckBox cb = (CheckBox) listview.getChildAt(i).findViewById(R.id.handle_delete_cb);
if(cb != null){
cb.setChecked(false);
}
}
}
}
});
parent.setBackgroundColor(Color.WHITE);
setContentView(parent);
}
private void toDeleteMode(){
//画面に見えている選択削除のチェックボックスを表示する
isSelectMode = true;
for(int i = 0; i< listview.getCount(); i++){
if(listview.getChildAt(i)==null)break;
CheckBox cb = (CheckBox) listview.getChildAt(i).findViewById(R.id.handle_delete_cb);
if(cb != null){
cb.setVisibility(View.VISIBLE);
cb.setChecked(false);
}
}
for(int i = 0; i < ids.size(); i++){
cbCheck.put(ids.get(i), false);
}
allSelectCb.setChecked(false);
allSelectCb.setVisibility(View.VISIBLE);
}
private void clearDeleteMode(){
Log.d("NLR","CLEAR DELETE MODE");
isSelectMode = false;//画面上に見えているチェックボックスのチェックをはずす
for(int i = 0 ; i < listview.getCount(); i++){
if(listview.getChildAt(i)==null)break;
CheckBox cb = (CheckBox)listview.getChildAt(i).findViewById(R.id.handle_delete_cb);
if(cb != null){
cb.setVisibility(View.GONE);
}else{
break;
}
}
allSelectCb.setVisibility(View.GONE);
}
class HandleListAdapter extends ArrayAdapter<String[]> {
NLiveRoid app = null;
public HandleListAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
app = (NLiveRoid)getApplicationContext();
}
@Override
public View getView(int position, View paramView,
ViewGroup paramViewGroup) {
final ViewHolder holder;
View view = paramView;
if (view == null) {
view = inflater.inflate(R.layout.handle_list_row, null);
holder = new ViewHolder();
holder.row = (TableRow)view.findViewById(R.id.handle_row);
holder.id = (TextView) view.findViewById(R.id.handle_id);
holder.name = (TextView) view.findViewById(R.id.handle_name);
holder.cb = (CheckBox)view.findViewById(R.id.handle_delete_cb);
holder.cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton compoundbutton,
boolean flag) {
cbCheck.put(holder.id.getText().toString(), flag);
//全てがチェックされたら全選択を全解除に変える
//リスナが自動的に呼ばれるのでcbCheckのデータはここでは変えない
if(flag){//新たな値がtrueの時、全てがtrueになったら解除に変える
if(!cbCheck.containsValue(false)){
allSelectCb.setChecked(true);
allSelectCb.setText("全解除");
}
}else{//新たな値がfalseの時、全てがfalseになったら選択に変える
if(!cbCheck.containsValue(true)){
allSelectCb.setChecked(false);
allSelectCb.setText("全選択");
}
}
}
});
view.setTag(holder);
}else {
holder = (ViewHolder) view.getTag();
}
holder.name.setWidth(app.getViewWidth() / 2);
holder.name.setText(names.get(position));
holder.id.setText(ids.get(position));
holder.id.setWidth(app.getViewWidth() / 2);
if (bgColors.size() > position) {//何故か色はこれでできる
holder.row.setBackgroundColor(bgColors.get(position));
holder.id.setBackgroundColor(bgColors.get(position));
holder.name.setBackgroundColor(bgColors.get(position));
holder.cb.setBackgroundColor(bgColors.get(position));
}
if (foColors.size() > position) {//何故か色はこれでできる
holder.id.setTextColor(foColors.get(position));
holder.name.setTextColor(foColors.get(position));
}
if(isSelectMode){
holder.cb.setVisibility(View.VISIBLE);
}else{
holder.cb.setVisibility(View.GONE);
}
if(cbCheck.size() > position){
holder.cb.setChecked(cbCheck.get(holder.id.getText()) ==null? true:cbCheck.get(holder.id.getText()));
}
return view;
}
}
private static class ViewHolder {
TableRow row;
TextView id;
TextView name;
CheckBox cb;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString("WORKAROUND_FOR_BUG_19917_KEY", "WORKAROUND_FOR_BUG_19917_VALUE");
// super.onSaveInstanceState(outState);
}
@Override
public boolean dispatchKeyEvent(KeyEvent keyevent){
if(keyevent.getKeyCode() == KeyEvent.KEYCODE_BACK&&isSelectMode){
//選択モードだったらキャンセルしてチェックも消す
clearDeleteMode();
for(int i = 0;i < ids.size();i++){
cbCheck.put(ids.get(i), false);
}
return false;
}
return super.dispatchKeyEvent(keyevent);
}
/**
* コンテキストメニュー生成時処理
*/
public void onCreateContextMenu(ContextMenu menu, View view,
ContextMenuInfo info) {
super.onCreateContextMenu(menu, view, info);
isContextDisp = true;
final AdapterContextMenuInfo adapterInfo = (AdapterContextMenuInfo) info;
tempPosition = adapterInfo.position;
addFlug = false;
// 引数はメニューのテキスト
int defaultBgColor = bgColors.get(tempPosition);
int defaultFoColor = foColors.get(tempPosition);
new HandleNamePicker(ACT,
new ColorPickerView.OnColorChangedListener() {
@Override
public void colorChanged(int color) {
// 色が選択されるとcolorに値が入る OKボタンで確定するので未使用
int R = Color.red(color);
int G = Color.green(color);
int B = Color.blue(color);
}
}, defaultBgColor, defaultFoColor,ids.get(tempPosition),names.get(tempPosition),false).show();
}
/**
* コテハン設定ダイアログの反映
*
* @param color
* @param name
*/
@Override
public void setHandleName(int bgColor,int foColor, String name) {
// idはすでにaddされている
bgColors.set(tempPosition, bgColor);
foColors.set(tempPosition, foColor);
names.set(tempPosition, name);
new WriteHandleName().execute();
listview.setAdapter(adapter);
listview.setSelection(tempPosition);
}
public void cancelColorPicker() {
if(addFlug){
cbCheck.remove(cbCheck.get(ids.get(tempPosition)));
ids.remove(tempPosition);
names.remove(tempPosition);
bgColors.remove(tempPosition);
foColors.remove(tempPosition);
adapter.remove(adapter.getItem(tempPosition));
}
}
/**
* ストレージのパスを取得します *
*
*/
private String getStorageFilePath(){
boolean isStorageAvalable = false;
boolean isStorageWriteable = false;
String state = Environment.getExternalStorageState();
if(state == null){
MyToast.customToastShow(this, "SDカードが利用できませんでした\nコテハンは機能できません");
return null;
}else if (Environment.MEDIA_MOUNTED.equals(state)) {
//読み書きOK
isStorageAvalable = isStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
//読み込みだけOK
isStorageAvalable = true;
isStorageWriteable = false;
} else {
//ストレージが有効でない
isStorageAvalable = isStorageWriteable = false;
}
boolean notAvalable = !isStorageAvalable;
boolean notWritable = !isStorageWriteable;
if(notAvalable||notWritable){
MyToast.customToastShow(this, "SDカードが利用できませんでした\nコテハンは機能できません");
return null;
}
//sdcard直下に、パッケージ名のフォルダを作りファイルを生成
String filePath = Environment.getExternalStorageDirectory().toString() + "/NLiveRoid";
File directory = new File(filePath);
// Log.d("log","filepath " + filePath + " \n isCANWRITE " + directory.canWrite());
if(directory.mkdirs()){//すでにあった場合も失敗する
Log.d("NLiveRoid","mkdir");
}
File file = new File(filePath,handleNameFile);
if(!file.exists()){
try {
file.createNewFile();
writeHandleName();//次からの読み込みがエラーしないように空のファイルを作っておく
} catch (IOException e) {
e.printStackTrace();
}
}
return file.getPath();
}
/**
* コテハンファイルの読み込み
*
* @author Owner
*
*/
private synchronized void readHandleNameData(ErrorCode error) {
try {
String filepath = getStorageFilePath();
if(filepath == null)return;
FileInputStream fis = new FileInputStream(filepath);
byte[] readBytes = new byte[fis.available()];
fis.read(readBytes);
XMLparser.setHandleNameMaps(ids, names, bgColors,foColors, readBytes,error);
//ここでチェックボックスのステータスもそのサイズで初期化
for(int i= 0; i < ids.size(); i++){
cbCheck.put(ids.get(i),false);
}
fis.close();
} catch (FileNotFoundException e) {
error.setErrorCode(-44);
e.printStackTrace();
} catch (IOException e) {
error.setErrorCode(-44);
e.printStackTrace();
}
}
/**
* コテハンの書き込み
*
* @author Owner
*
*/
class WriteHandleName extends AsyncTask<Void,Void,Void>{
@Override
protected Void doInBackground(Void... arg0) {
writeHandleName();
return null;
}
}
private synchronized void writeHandleName() {
try {
String filepath = getStorageFilePath();
if(filepath == null)return;
String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<HandleNames xmlns=\"http://nliveroid-tutorial.appspot.com/handlenames/\">\n";
for (int i = 0; i < ids.size(); i++) {
xml += "<user bgcolor=\"" + bgColors.get(i) + "\" name=\""
+ names.get(i) + "\" focolor=\""+foColors.get(i)+"\">" + ids.get(i) + "</user>\n";
}
xml += "</HandleNames>";
FileOutputStream fos = new FileOutputStream(filepath);
fos.write(xml.getBytes());
fos.close();
} catch (FileNotFoundException e) {
ErrorCode error = ((NLiveRoid)getApplicationContext()).getError();
e.printStackTrace();
} catch (IOException e) {
ErrorCode error = ((NLiveRoid)getApplicationContext()).getError();
e.printStackTrace();
}
}
@Override
public void createCommentedList(String userid) {
// TODO 自動生成されたメソッド・スタブ
}
@Override
public boolean isAt() {
// TODO 自動生成されたメソッド・スタブ
return false;
}
@Override
public boolean isAtOverwrite() {
// TODO 自動生成されたメソッド・スタブ
return false;
}
@Override
public void setAtEnable(boolean isAt) {
// TODO 自動生成されたメソッド・スタブ
}
@Override
public void setAtOverwrite(boolean isAtoverwrite) {
// TODO 自動生成されたメソッド・スタブ
}
@Override
public void setAutoGetUserName(boolean isChecked) {
// TODO 自動生成されたメソッド・スタブ
}
@Override
public boolean isSetNameReady() {
// TODO 自動生成されたメソッド・スタブ
return false;
}
}