package org.wordpress.android.ui.posts;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockListActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.justsystems.hpb.pad.R;
import org.xmlrpc.android.XMLRPCClient;
import org.xmlrpc.android.XMLRPCException;
import org.wordpress.android.WordPress;
import org.wordpress.android.models.Blog;
import org.wordpress.android.models.CategoryNode;
import org.wordpress.android.util.StringUtils;
public class SelectCategoriesActivity extends SherlockListActivity {
private XMLRPCClient client;
String finalResult = "";
ProgressDialog pd;
public String categoryErrorMsg = "";
private final Handler mHandler = new Handler();
private Blog blog;
private ListView mListView;
private int mListViewScrollStateOffset, mListViewScrollStateIndex;
private HashSet<String> mSelectedCategories;
private CategoryNode mCategories;
private ArrayList<CategoryNode> mCategoryLevels;
private Map<String, Integer> mCategoryNames = new HashMap<String, Integer>();
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.select_categories);
setTitle(getResources().getString(R.string.select_categories));
ActionBar actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
mListView = getListView();
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
mListView.setItemsCanFocus(false);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
if (getCheckedItemCount(mListView) > 1) {
boolean uncategorizedNeedToBeSelected = false;
for (int i = 0; i < mCategoryLevels.size(); i++) {
if (mCategoryLevels.get(i).getName()
.equalsIgnoreCase("uncategorized")) {
mListView.setItemChecked(i,
uncategorizedNeedToBeSelected);
}
}
}
}
});
mSelectedCategories = new HashSet<String>();
Bundle extras = getIntent().getExtras();
if (extras != null) {
int blogId = extras.getInt("id");
try {
blog = new Blog(blogId);
} catch (Exception e) {
Toast.makeText(this,
getResources().getText(R.string.blog_not_found),
Toast.LENGTH_SHORT).show();
finish();
}
if (extras.containsKey("categories"))
mSelectedCategories = (HashSet<String>) extras
.getSerializable("categories");
}
populateOrFetchCategories();
}
private void populateCategoryList() {
mCategoryLevels = CategoryNode
.getSortedListOfCategoriesFromRoot(mCategories);
for (int i = 0; i < mCategoryLevels.size(); i++) {
mCategoryNames.put(
StringUtils.unescapeHTML(mCategoryLevels.get(i).getName()),
i);
}
CategoryArrayAdapter categoryAdapter = new CategoryArrayAdapter(this,
R.layout.categories_row, mCategoryLevels);
this.setListAdapter(categoryAdapter);
if (mSelectedCategories != null) {
ListView lv = getListView();
for (String selectedCategory : mSelectedCategories) {
if (mCategoryNames.keySet().contains(selectedCategory)) {
lv.setItemChecked(mCategoryNames.get(selectedCategory),
true);
}
}
}
restoreScrollOffset();
}
private void populateOrFetchCategories() {
mCategories = CategoryNode.createCategoryTreeFromDB(blog.getId());
if (mCategories.getChildren().size() > 0) {
populateCategoryList();
} else {
refreshCategories();
}
}
final Runnable mUpdateResults = new Runnable() {
public void run() {
if (finalResult.equals("addCategory_success")) {
if (pd.isShowing()) {
pd.dismiss();
}
populateOrFetchCategories();
Toast.makeText(SelectCategoriesActivity.this,
getResources().getText(R.string.adding_cat_success),
Toast.LENGTH_SHORT).show();
}
if (finalResult.equals("addCategory_failed")) {
if (pd.isShowing()) {
pd.dismiss();
}
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(
SelectCategoriesActivity.this);
dialogBuilder.setTitle(getResources().getText(
R.string.adding_cat_failed));
dialogBuilder.setMessage(getResources().getText(
R.string.adding_cat_failed_check));
dialogBuilder.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
// Just close the window.
}
});
dialogBuilder.setCancelable(true);
if (!isFinishing())
dialogBuilder.create().show();
} else if (finalResult.equals("gotCategories")) {
if (pd.isShowing()) {
pd.dismiss();
}
populateOrFetchCategories();
Toast.makeText(SelectCategoriesActivity.this,
getResources().getText(R.string.categories_refreshed),
Toast.LENGTH_SHORT).show();
} else if (finalResult.equals("FAIL")) {
if (pd.isShowing()) {
pd.dismiss();
}
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(
SelectCategoriesActivity.this);
dialogBuilder.setTitle(getResources().getText(
R.string.category_refresh_error));
dialogBuilder.setMessage(categoryErrorMsg);
dialogBuilder.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
// Just close the window.
}
});
dialogBuilder.setCancelable(true);
if (!isFinishing())
dialogBuilder.create().show();
}
}
};
/**
* Gets the categories via a xmlrpc call
*
* @return result message
*/
public String fetchCategories() {
String returnMessage;
Object result[] = null;
Object[] params = { blog.getBlogId(), blog.getUsername(),
blog.getPassword(), };
client = new XMLRPCClient(blog.getUrl(), blog.getHttpuser(),
blog.getHttppassword());
boolean success = false;
try {
result = (Object[]) client.call("wp.getCategories", params);
success = true;
} catch (XMLRPCException e) {
e.printStackTrace();
}
if (success) {
// wipe out the categories table
WordPress.wpDB.clearCategories(blog.getId());
for (Object aResult : result) {
Map<?, ?> curHash = (Map<?, ?>) aResult;
String categoryName = curHash.get("categoryName").toString();
String categoryID = curHash.get("categoryId").toString();
String categoryParentID = curHash.get("parentId").toString();
int convertedCategoryID = Integer.parseInt(categoryID);
int convertedCategoryParentID = Integer
.parseInt(categoryParentID);
WordPress.wpDB.insertCategory(blog.getId(),
convertedCategoryID, convertedCategoryParentID,
categoryName);
}
returnMessage = "gotCategories";
} else {
returnMessage = "FAIL";
}
return returnMessage;
}
/**
* function addCategory
*
* @param String
* category_name
* @return
* @description Adds a new category
*/
public String addCategory(String category_name, String category_slug,
String category_desc, int parent_id) {
// Return string
String returnString = "";
// Save selected categories
updateSelectedCategoryList();
saveScrollOffset();
// Store the parameters for wp.addCategory
Map<String, Object> struct = new HashMap<String, Object>();
struct.put("name", category_name);
struct.put("slug", category_slug);
struct.put("description", category_desc);
struct.put("parent_id", parent_id);
client = new XMLRPCClient(blog.getUrl(), blog.getHttpuser(),
blog.getHttppassword());
Object[] params = { blog.getBlogId(), blog.getUsername(),
blog.getPassword(), struct };
Object result = null;
try {
result = client.call("wp.newCategory", params);
} catch (XMLRPCException e) {
e.printStackTrace();
}
if (result == null) {
returnString = "addCategory_failed";
} else {
// Category successfully created. "result" is the ID of the new category
// Initialize the category database
// Convert "result" (= category_id) from type Object to int
int category_id = Integer.parseInt(result.toString());
// Insert the new category into database
WordPress.wpDB.insertCategory(blog.getId(), category_id, parent_id,
category_name);
returnString = "addCategory_success";
// auto select new category
mSelectedCategories.add(category_name);
}
return returnString;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null) {
final Bundle extras = data.getExtras();
switch (requestCode) {
case 0: // Add category
// Does the user want to continue, or did he press "dismiss"?
if (extras.getString("continue").equals("TRUE")) {
// Get name, slug and desc from Intent
final String category_name = extras
.getString("category_name");
final String category_slug = extras
.getString("category_slug");
final String category_desc = extras
.getString("category_desc");
final int parent_id = extras.getInt("parent_id");
// Check if the category name already exists
if (!mCategoryNames.keySet().contains(category_name)) {
pd = ProgressDialog.show(
SelectCategoriesActivity.this,
getResources().getText(
R.string.cat_adding_category),
getResources().getText(
R.string.cat_attempt_add_category),
true, true);
Thread th = new Thread() {
public void run() {
finalResult = addCategory(category_name,
category_slug, category_desc, parent_id);
mHandler.post(mUpdateResults);
}
};
th.start();
}
break;
}
}// end null check
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.categories, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
int itemId = item.getItemId();
if (itemId == R.id.menu_refresh) {
refreshCategories();
return true;
} else if (itemId == R.id.menu_new_category) {
Bundle bundle = new Bundle();
bundle.putInt("id", blog.getId());
Intent i = new Intent(SelectCategoriesActivity.this,
AddCategoryActivity.class);
i.putExtras(bundle);
startActivityForResult(i, 0);
return true;
} else if (itemId == android.R.id.home) {
saveAndFinish();
return true;
}
return super.onOptionsItemSelected(item);
}
private void refreshCategories() {
saveScrollOffset();
updateSelectedCategoryList();
pd = ProgressDialog.show(SelectCategoriesActivity.this, getResources()
.getText(R.string.refreshing_categories), getResources()
.getText(R.string.attempting_categories_refresh), true, true);
Thread th = new Thread() {
public void run() {
finalResult = fetchCategories();
mHandler.post(mUpdateResults);
}
};
th.start();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
// ignore orientation change
super.onConfigurationChanged(newConfig);
}
@Override
public void onBackPressed() {
saveAndFinish();
super.onBackPressed();
}
private void saveScrollOffset() {
mListViewScrollStateIndex = mListView.getFirstVisiblePosition();
View view = mListView.getChildAt(0);
mListViewScrollStateOffset = 0;
if (view != null) {
mListViewScrollStateOffset = view.getTop();
}
}
private void restoreScrollOffset() {
mListView.setSelectionFromTop(mListViewScrollStateIndex,
mListViewScrollStateOffset);
}
private void updateSelectedCategoryList() {
SparseBooleanArray selectedItems = mListView.getCheckedItemPositions();
for (int i = 0; i < selectedItems.size(); i++) {
String currentName = StringUtils.unescapeHTML(mCategoryLevels.get(
selectedItems.keyAt(i)).getName());
if (selectedItems.get(selectedItems.keyAt(i))) {
mSelectedCategories.add(currentName);
} else {
mSelectedCategories.remove(currentName);
}
}
}
private void saveAndFinish() {
Bundle bundle = new Bundle();
updateSelectedCategoryList();
bundle.putSerializable("selectedCategories", new ArrayList<String>(
mSelectedCategories));
Intent mIntent = new Intent();
mIntent.putExtras(bundle);
setResult(RESULT_OK, mIntent);
finish();
}
private int getCheckedItemCount(ListView listView) {
if (Build.VERSION.SDK_INT >= 11)
return listView.getCheckedItemCount();
else {
int count = 0;
for (int i = listView.getCount() - 1; i >= 0; i--)
if (listView.isItemChecked(i))
count++;
return count;
}
}
}