/**
* Odoo, Open Source Management Solution
* Copyright (C) 2012-today Odoo SA (<http:www.odoo.com>)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version
*
* This program 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 Affero General Public License for more details
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http:www.gnu.org/licenses/>
*
* Created on 18/12/14 5:25 PM
*/
package com.odoo;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBarDrawerToggle;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import com.odoo.core.account.AppIntro;
import com.odoo.core.account.ManageAccounts;
import com.odoo.core.account.OdooLogin;
import com.odoo.core.account.OdooUserAskPassword;
import com.odoo.core.auth.OdooAccountManager;
import com.odoo.core.auth.OdooAuthenticator;
import com.odoo.core.orm.OModel;
import com.odoo.core.support.OUser;
import com.odoo.core.support.addons.fragment.IBaseFragment;
import com.odoo.core.support.drawer.ODrawerItem;
import com.odoo.core.support.sync.SyncUtils;
import com.odoo.core.utils.BitmapUtils;
import com.odoo.core.utils.OActionBarUtils;
import com.odoo.core.utils.OAlert;
import com.odoo.core.utils.OControls;
import com.odoo.core.utils.OFragmentUtils;
import com.odoo.core.utils.OPreferenceManager;
import com.odoo.core.utils.OResource;
import com.odoo.core.utils.drawer.DrawerUtils;
import com.odoo.core.utils.sys.IOnActivityResultListener;
import com.odoo.core.utils.sys.IOnBackPressListener;
import com.odoo.R;
import java.util.List;
public class OdooActivity extends ActionBarActivity {
public static final String TAG = OdooActivity.class.getSimpleName();
public static final Integer DRAWER_ITEM_LAUNCH_DELAY = 300;
public static final Integer DRAWER_ACCOUNT_BOX_ANIMATION_DURATION = 250;
public static final String KEY_ACCOUNT_REQUEST = "key_account_request";
public static final String KEY_NEW_USER_NAME = "key_new_account_username";
public static final String KEY_CURRENT_DRAWER_ITEM = "key_drawer_item_index";
public static final String KEY_APP_TITLE = "key_app_title";
public static final String KEY_HAS_ACTIONBAR_SPINNER = "key_has_actionbar_spinner";
public static final Integer REQUEST_ACCOUNT_CREATE = 1101;
public static final Integer REQUEST_ACCOUNTS_MANAGE = 1102;
public static final String KEY_FRESH_LOGIN = "key_fresh_login";
private DrawerLayout mDrawerLayout = null;
private ActionBarDrawerToggle mDrawerToggle = null;
private IOnBackPressListener backPressListener = null;
private IOnActivityResultListener mIOnActivityResultListener = null;
//Drawer Containers
private LinearLayout mDrawerAccountContainer = null;
private LinearLayout mDrawerItemContainer = null;
private Boolean mAccountBoxExpanded = false;
private Bundle mSavedInstanceState = null;
private Spinner spinner_nav = null;
private Integer mDrawerSelectedIndex = -1;
private Boolean mHasActionBarSpinner = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "OdooActivity->onCreate");
mSavedInstanceState = savedInstanceState;
OPreferenceManager preferenceManager = new OPreferenceManager(this);
if (!preferenceManager.getBoolean(KEY_FRESH_LOGIN, false)) {
preferenceManager.setBoolean(KEY_FRESH_LOGIN, true);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
startActivity(new Intent(OdooActivity.this, AppIntro.class));
}
}, 1000);
}
setContentView(R.layout.odoo_activity);
OActionBarUtils.setActionBar(this, true);
setupDrawer();
}
// Creating drawer
private void setupDrawer() {
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.app_name, R.string.app_name) {
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
setTitle(getResources().getString(R.string.app_name));
invalidateOptionsMenu();
}
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
invalidateOptionsMenu();
setTitle(R.string.app_name);
}
@Override
public void onDrawerStateChanged(int newState) {
super.onDrawerStateChanged(newState);
invalidateOptionsMenu();
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
invalidateOptionsMenu();
}
};
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, Gravity.START);
mDrawerToggle.syncState();
setupAccountBox();
setupDrawerBox();
}
private void setupDrawerBox() {
mDrawerItemContainer = (LinearLayout) findViewById(R.id.drawerItemList);
mDrawerItemContainer.removeAllViews();
List<ODrawerItem> items = DrawerUtils.getDrawerItems(this);
for (ODrawerItem item : items) {
View view = LayoutInflater.from(this).
inflate((item.isGroupTitle()) ? R.layout.base_drawer_group_layout :
R.layout.base_drawer_menu_item, mDrawerItemContainer, false);
view.setTag(item);
if (!item.isGroupTitle()) {
view.setOnClickListener(drawerItemClick);
}
mDrawerItemContainer.addView(DrawerUtils.fillDrawerItemValue(view, item));
}
}
private View.OnClickListener drawerItemClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
int index = mDrawerItemContainer.indexOfChild(v);
if (mDrawerSelectedIndex != index) {
ODrawerItem item = (ODrawerItem) v.getTag();
if (item.getInstance() instanceof Fragment) {
focusOnDrawerItem(index);
setTitle(item.getTitle());
}
loadDrawerItemInstance(item.getInstance(), item.getExtra());
} else {
closeDrawer();
}
}
};
public void closeDrawer() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mDrawerLayout.closeDrawer(Gravity.START);
}
}, DRAWER_ITEM_LAUNCH_DELAY);
}
/**
* Loads fragment or start intent
*
* @param instance, instance of fragment or intent
*/
private void loadDrawerItemInstance(Object instance, Bundle extra) {
if (instance != null) {
if (instance instanceof Intent) {
Log.i(TAG, "Loading intent: " + instance.getClass().getCanonicalName());
startActivity((Intent) instance);
}
if (instance instanceof Class<?>) {
Class<?> cls = (Class<?>) instance;
Intent intent = null;
if (cls.getSuperclass().isAssignableFrom(Activity.class)) {
intent = new Intent(this, cls);
}
if (cls.getSuperclass().isAssignableFrom(ActionBarActivity.class)) {
intent = new Intent(this, cls);
}
if (intent != null) {
if (extra != null)
intent.putExtras(extra);
loadDrawerItemInstance(intent, null);
return;
}
}
if (instance instanceof Fragment) {
Log.i(TAG, "Loading fragment: " + instance.getClass().getCanonicalName());
OFragmentUtils.get(this, mSavedInstanceState).startFragment((Fragment) instance, false, extra);
}
}
closeDrawer();
}
public void loadFragment(Fragment fragment, Boolean addToBackState, Bundle extra) {
OFragmentUtils.get(this, null).startFragment(fragment, addToBackState, extra);
}
private void setupAccountBox() {
mDrawerAccountContainer = (LinearLayout) findViewById(R.id.accountList);
View chosenAccountView = findViewById(R.id.drawerAccountView);
OUser currentUser = OUser.current(this);
if (currentUser == null) {
chosenAccountView.setVisibility(View.GONE);
mDrawerAccountContainer.setVisibility(View.GONE);
return;
} else {
chosenAccountView.setVisibility(View.VISIBLE);
mDrawerAccountContainer.setVisibility(View.INVISIBLE);
}
ImageView avatar = (ImageView) chosenAccountView.findViewById(R.id.profile_image);
TextView name = (TextView) chosenAccountView.findViewById(R.id.profile_name_text);
TextView url = (TextView) chosenAccountView.findViewById(R.id.profile_url_text);
name.setText(currentUser.getName());
url.setText((currentUser.isOAauthLogin()) ? currentUser.getInstanceUrl() : currentUser.getHost());
if (!currentUser.getAvatar().equals("false")) {
Bitmap bitmap = BitmapUtils.getBitmapImage(this, currentUser.getAvatar());
if (bitmap != null)
avatar.setImageBitmap(bitmap);
}
// Setting Accounts
List<OUser> accounts = OdooAccountManager.getAllAccounts(this);
if (accounts.size() > 0) {
chosenAccountView.setEnabled(true);
ImageView boxIndicator = (ImageView) findViewById(R.id.expand_account_box_indicator);
boxIndicator.setVisibility(View.VISIBLE);
chosenAccountView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mAccountBoxExpanded = !mAccountBoxExpanded;
accountBoxToggle();
}
});
populateAccountList(currentUser, accounts);
}
}
private void accountBoxToggle() {
ImageView boxIndicator = (ImageView) findViewById(R.id.expand_account_box_indicator);
boxIndicator.setImageResource(mAccountBoxExpanded ? R.drawable.ic_drawer_accounts_collapse
: R.drawable.ic_drawer_accounts_expand);
int hideTranslateY = -mDrawerAccountContainer.getHeight() / 4;
if (mAccountBoxExpanded && mDrawerAccountContainer.getTranslationY() == 0) {
// initial setup
mDrawerAccountContainer.setAlpha(0);
mDrawerAccountContainer.setTranslationY(hideTranslateY);
}
AnimatorSet set = new AnimatorSet();
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mDrawerItemContainer
.setVisibility(mAccountBoxExpanded ? View.INVISIBLE
: View.VISIBLE);
mDrawerAccountContainer
.setVisibility(mAccountBoxExpanded ? View.VISIBLE
: View.INVISIBLE);
}
@Override
public void onAnimationCancel(Animator animation) {
onAnimationEnd(animation);
}
});
if (mAccountBoxExpanded) {
mDrawerAccountContainer.setVisibility(View.VISIBLE);
AnimatorSet subSet = new AnimatorSet();
subSet.playTogether(
ObjectAnimator
.ofFloat(mDrawerAccountContainer, View.ALPHA, 1)
.setDuration(DRAWER_ACCOUNT_BOX_ANIMATION_DURATION),
ObjectAnimator.ofFloat(mDrawerAccountContainer,
View.TRANSLATION_Y, 0).setDuration(
DRAWER_ACCOUNT_BOX_ANIMATION_DURATION));
set.playSequentially(
ObjectAnimator.ofFloat(mDrawerItemContainer,
View.ALPHA, 0).setDuration(
DRAWER_ACCOUNT_BOX_ANIMATION_DURATION), subSet);
set.start();
} else {
mDrawerItemContainer.setVisibility(View.VISIBLE);
AnimatorSet subSet = new AnimatorSet();
subSet.playTogether(
ObjectAnimator
.ofFloat(mDrawerAccountContainer, View.ALPHA, 0)
.setDuration(DRAWER_ACCOUNT_BOX_ANIMATION_DURATION),
ObjectAnimator.ofFloat(mDrawerAccountContainer,
View.TRANSLATION_Y, hideTranslateY).setDuration(
DRAWER_ACCOUNT_BOX_ANIMATION_DURATION));
set.playSequentially(
subSet,
ObjectAnimator.ofFloat(mDrawerItemContainer,
View.ALPHA, 1).setDuration(
DRAWER_ACCOUNT_BOX_ANIMATION_DURATION));
set.start();
}
set.start();
}
private void populateAccountList(OUser me, List<OUser> accounts) {
mDrawerAccountContainer.removeAllViews();
for (final OUser user : accounts) {
if (!user.getAndroidName().equals(me.getAndroidName())) {
View view = LayoutInflater.from(this).inflate(R.layout.base_drawer_account_item, mDrawerAccountContainer, false);
ImageView avatar = (ImageView) view.findViewById(R.id.profile_image);
if (!user.getAvatar().equals("false")) {
Bitmap img = BitmapUtils.getBitmapImage(this, user.getAvatar());
if (img != null)
avatar.setImageBitmap(img);
}
OControls.setText(view, R.id.profile_name_text, user.getName());
OControls.setText(view, R.id.profile_url_text, (user.isOAauthLogin()) ? user.getInstanceUrl() : user.getHost());
// Setting login event for other account
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
OdooUserAskPassword.get(OdooActivity.this, user)
.setOnUserPasswordValidateListener(
new OdooUserAskPassword.OnUserPasswordValidateListener() {
@Override
public void onSuccess() {
// Logging in to other account
OdooAccountManager.login(OdooActivity.this,
user.getAndroidName());
OModel.sqLite = null;
mAccountBoxExpanded = false;
accountBoxToggle();
mDrawerLayout.closeDrawer(Gravity.START);
// Restarting activity
restartActivity();
}
@Override
public void onCancel() {
}
@Override
public void onFail() {
OAlert.showError(OdooActivity.this,
OResource.string(OdooActivity.this,
R.string.error_invalid_password));
}
}).show();
}
});
mDrawerAccountContainer.addView(view);
}
}
accountListDefaultItems();
}
private void restartActivity() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(OdooActivity.this, OdooActivity.class);
finish();
startActivity(intent);
}
}, DRAWER_ITEM_LAUNCH_DELAY);
}
private void accountListDefaultItems() {
// Adding add account
View view = generateView(OResource.string(this, R.string.label_drawer_account_add_account),
R.drawable.ic_action_add);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent loginActivity = new Intent(OdooActivity.this, OdooLogin.class);
loginActivity.putExtra(OdooAuthenticator.KEY_NEW_ACCOUNT_REQUEST, true);
loginActivity.putExtra(KEY_ACCOUNT_REQUEST, true);
startActivityForResult(loginActivity, REQUEST_ACCOUNT_CREATE);
}
});
mDrawerAccountContainer.addView(view);
// Adding add account
view = generateView(OResource.string(this, R.string.label_drawer_account_manage_accounts),
R.drawable.ic_action_settings);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(new Intent(OdooActivity.this, ManageAccounts.class),
REQUEST_ACCOUNTS_MANAGE);
}
});
mDrawerAccountContainer.addView(view);
}
private View generateView(String title, int res_id) {
View view = LayoutInflater.from(this).inflate(R.layout.base_drawer_account_item,
mDrawerAccountContainer, false);
OControls.setGone(view, R.id.profile_url_text);
ImageView icon = (ImageView) view.findViewById(R.id.profile_image);
icon.setImageResource(res_id);
icon.setColorFilter(OResource.color(this, R.color.body_text_2));
TextView name = (TextView) view.findViewById(R.id.profile_name_text);
name.setTypeface(name.getTypeface(), Typeface.BOLD);
name.setText(title);
return view;
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (mDrawerToggle != null) {
mDrawerToggle.onConfigurationChanged(newConfig);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onBackPressed() {
if (backPressListener != null) {
if (backPressListener.onBackPressed()) {
super.onBackPressed();
}
} else
super.onBackPressed();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (mIOnActivityResultListener != null) {
mIOnActivityResultListener.onOdooActivityResult(requestCode, resultCode, data);
}
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_ACCOUNT_CREATE) {
if (mDrawerLayout != null) {
mDrawerLayout.closeDrawer(Gravity.START);
accountBoxToggle();
}
OdooAccountManager.login(this, data.getStringExtra(KEY_NEW_USER_NAME));
OModel.sqLite = null;
restartActivity();
}
if (requestCode == REQUEST_ACCOUNTS_MANAGE) {
startActivity(new Intent(this, OdooLogin.class));
finish();
}
}
}
/**
* Set system back button press listener
*
* @param listener
*/
public void setOnBackPressListener(IOnBackPressListener listener) {
backPressListener = listener;
}
public void setOnActivityResultListener(IOnActivityResultListener listener) {
mIOnActivityResultListener = listener;
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mSavedInstanceState = savedInstanceState;
if (savedInstanceState == null) {
// Loading Default Fragment (if any)
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
IBaseFragment fragment = DrawerUtils.getDefaultDrawerFragment();
if (fragment != null) {
ODrawerItem item = DrawerUtils.getStartableObject(OdooActivity.this, fragment);
setTitle(item.getTitle());
loadDrawerItemInstance(item.getInstance(), item.getExtra());
int selected_item = DrawerUtils.findItemIndex(item, mDrawerItemContainer);
if (selected_item > -1) {
focusOnDrawerItem(selected_item);
}
}
}
}, DRAWER_ITEM_LAUNCH_DELAY);
} else {
mHasActionBarSpinner = savedInstanceState.getBoolean(KEY_HAS_ACTIONBAR_SPINNER);
mDrawerSelectedIndex = savedInstanceState.getInt(KEY_CURRENT_DRAWER_ITEM);
setTitle(savedInstanceState.getString(KEY_APP_TITLE));
focusOnDrawerItem(mDrawerSelectedIndex);
}
}
private void focusOnDrawerItem(int index) {
mDrawerSelectedIndex = index;
for (int i = 0; i < mDrawerItemContainer.getChildCount(); i++) {
DrawerUtils.focusOnView(this, mDrawerItemContainer.getChildAt(i), i == index);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt(KEY_CURRENT_DRAWER_ITEM, mDrawerSelectedIndex);
outState.putString(KEY_APP_TITLE, getTitle().toString());
outState.putBoolean(KEY_HAS_ACTIONBAR_SPINNER, mHasActionBarSpinner);
super.onSaveInstanceState(outState);
}
public SyncUtils sync() {
return SyncUtils.get(this);
}
/**
* Actionbar Spinner handler
*/
public void setHasActionBarSpinner(Boolean hasActionBarSpinner) {
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
Spinner spinner = (Spinner) findViewById(R.id.spinner_nav);
if (hasActionBarSpinner) {
if (spinner != null)
spinner.setVisibility(View.VISIBLE);
actionBar.setDisplayShowTitleEnabled(false);
} else {
if (spinner != null)
spinner.setVisibility(View.GONE);
actionBar.setDisplayShowTitleEnabled(true);
}
mHasActionBarSpinner = hasActionBarSpinner;
}
}
public Spinner getActionBarSpinner() {
Spinner spinner = null;
if (mHasActionBarSpinner) {
spinner = (Spinner) findViewById(R.id.spinner_nav);
spinner.setAdapter(null);
}
return spinner;
}
public void refreshDrawer() {
setupDrawerBox();
}
}