/* * Copyright © 2016 TIBCO Software,Inc.All rights reserved. * http://community.jaspersoft.com/project/jaspermobile-android * * Unless you have purchased a commercial license agreement from TIBCO Jaspersoft, * the following license terms apply: * * This program is part of TIBCO Jaspersoft Mobile for Android. * * TIBCO Jaspersoft Mobile is free software:you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation,either version 3of the License,or * (at your option)any later version. * * TIBCO Jaspersoft Mobile 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with TIBCO Jaspersoft Mobile for Android.If not,see * <http://www.gnu.org/licenses/lgpl>. */ package com.jaspersoft.android.jaspermobile.activities.inputcontrols; import android.app.Activity; import android.content.Intent; import android.support.design.widget.TabLayout; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.SearchView; import android.support.v7.widget.Toolbar; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.jaspersoft.android.jaspermobile.R; import com.jaspersoft.android.jaspermobile.activities.inputcontrols.adapters.FilterableAdapter; import com.jaspersoft.android.jaspermobile.activities.inputcontrols.adapters.MultiSelectAvailableAdapter; import com.jaspersoft.android.jaspermobile.activities.inputcontrols.adapters.MultiSelectSelectedAdapter; import com.jaspersoft.android.jaspermobile.internal.di.modules.activity.ActivityModule; import com.jaspersoft.android.jaspermobile.internal.di.modules.activity.ReportModule; import com.jaspersoft.android.jaspermobile.ui.view.activity.ToolbarActivity; import com.jaspersoft.android.jaspermobile.util.ReportParamsStorage; import com.jaspersoft.android.sdk.client.oxm.control.InputControl; import com.jaspersoft.android.sdk.client.oxm.control.InputControlOption; import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.EActivity; import org.androidannotations.annotations.Extra; import org.androidannotations.annotations.OptionsItem; import org.androidannotations.annotations.OptionsMenu; import org.androidannotations.annotations.OptionsMenuItem; import org.androidannotations.annotations.ViewById; import java.util.List; import javax.inject.Inject; /** * @author Andrew Tivodar * @since 2.2 */ @EActivity(R.layout.activity_multi_select) @OptionsMenu({R.menu.multi_select_menu, R.menu.search_menu}) public class MultiSelectActivity extends ToolbarActivity implements SearchView.OnQueryTextListener { public static final String SELECT_IC_ARG = "select_input_control_id"; private final static int TAB_COUNT = 2; private final static int TAB_AVAILABLE = 0; private final static int TAB_SELECTED = 1; @Inject protected ReportParamsStorage paramsStorage; @Extra protected String reportUri; @Extra protected String inputControlId; @OptionsMenuItem(R.id.search) public MenuItem searchMenuItem; @ViewById(R.id.tlMultiSelect) protected TabLayout headerTab; private RecyclerView availableList; private RecyclerView selectedList; private TextView emptyTextSelected; private TextView emptyTextAvailable; private List<InputControlOption> mInputControlOptions; private String mInputControlLabel; private MultiSelectAvailableAdapter mAvailableAdapter; private MultiSelectSelectedAdapter mSelectedAdapter; private boolean isValueChanged; @AfterViews protected void init() { getProfileComponent() .plusControlsPage( new ActivityModule(this), new ReportModule(reportUri) ) .inject(this); initInputControlOptions(); initAdapters(); initViews(); getSupportActionBar().setTitle(mInputControlLabel); getSupportActionBar().setDisplayHomeAsUpEnabled(true); } @Override public boolean onCreateOptionsMenu(Menu menu) { SearchView searchView = (SearchView) searchMenuItem.getActionView(); searchView.setOnQueryTextListener(this); searchView.setQueryHint(getString(R.string.ro_search)); return super.onCreateOptionsMenu(menu); } @Override public boolean onPrepareOptionsMenu(Menu menu) { boolean isActiveSearchableTab = headerTab.getSelectedTabPosition() == TAB_AVAILABLE; searchMenuItem.setVisible(isActiveSearchableTab); return super.onPrepareOptionsMenu(menu); } @Override public void onBackPressed() { Intent dataIntent = new Intent(); dataIntent.putExtra(SELECT_IC_ARG, inputControlId); int resultCode = isValueChanged ? Activity.RESULT_OK : Activity.RESULT_CANCELED; setResult(resultCode, dataIntent); super.onBackPressed(); } @OptionsItem(R.id.selectAll) final void selectAll() { for (InputControlOption inputControlOption : mInputControlOptions) { inputControlOption.setSelected(true); } onItemsSelectionChange(); } @OptionsItem(R.id.deselectAll) final void deselectAll() { for (InputControlOption inputControlOption : mInputControlOptions) { inputControlOption.setSelected(false); } onItemsSelectionChange(); } @OptionsItem(R.id.inverse) final void selectInverse() { for (InputControlOption inputControlOption : mInputControlOptions) { inputControlOption.setSelected(!inputControlOption.isSelected()); } onItemsSelectionChange(); } @Override public boolean onQueryTextSubmit(String query) { return false; } @Override public boolean onQueryTextChange(String newText) { mAvailableAdapter.filter(newText); return true; } @Override protected String getScreenName() { return getString(R.string.ja_ms_ic_s); } private void initAdapters() { mAvailableAdapter = new MultiSelectAvailableAdapter(mInputControlOptions); mSelectedAdapter = new MultiSelectSelectedAdapter(mInputControlOptions); mAvailableAdapter.setFilterListener(new FilterableAdapter.FilterListener() { @Override public void onFilterDone() { onFilteringList(); } }); mAvailableAdapter.setItemSelectListener(new MultiSelectAvailableAdapter.ItemSelectListener() { @Override public void onItemSelected(int position) { InputControlOption inputControlOption = mInputControlOptions.get(position); inputControlOption.setSelected(!mInputControlOptions.get(position).isSelected()); onItemSelectionChange(position); } }); mSelectedAdapter.setItemSelectListener(new MultiSelectSelectedAdapter.ItemSelectedListener() { @Override public void onItemUnselected(int position) { InputControlOption inputControlOption = mInputControlOptions.get(position); inputControlOption.setSelected(false); onItemSelectionChange(position); } }); } private void initViews() { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); final ViewPager viewPager = (ViewPager) findViewById(R.id.vpMultiSelect); MultiSelectViewPagerAdapter adapter = new MultiSelectViewPagerAdapter(); viewPager.setAdapter(adapter); headerTab.setupWithViewPager(viewPager); headerTab.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { viewPager.setCurrentItem(tab.getPosition()); invalidateOptionsMenu(); } @Override public void onTabUnselected(TabLayout.Tab tab) { } @Override public void onTabReselected(TabLayout.Tab tab) { } }); } private void initInputControlOptions() { List<InputControl> inputControls = paramsStorage.getInputControlHolder(reportUri).getInputControls(); for (InputControl inputControl : inputControls) { if (inputControl.getId().equals(inputControlId)) { mInputControlLabel = inputControl.getLabel(); mInputControlOptions = inputControl.getState().getOptions(); break; } } } private void onItemSelectionChange(int position) { mAvailableAdapter.updateItem(position); mSelectedAdapter.notifySelectionChanged(mInputControlOptions.get(position).isSelected(), position); updateSelectedTabTitle(); emptyTextSelected.setVisibility(mSelectedAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE); isValueChanged = true; } private void onItemsSelectionChange() { mAvailableAdapter.notifyItemRangeChanged(0, mAvailableAdapter.getItemCount()); mSelectedAdapter.notifySelectionsChanged(mInputControlOptions); updateSelectedTabTitle(); searchMenuItem.collapseActionView(); emptyTextSelected.setVisibility(mSelectedAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE); isValueChanged = true; } private void onFilteringList() { updateAvailableTabTitle(); emptyTextAvailable.setVisibility(mAvailableAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE); availableList.scrollToPosition(0); } private void updateSelectedTabTitle() { TabLayout.Tab selectedTab = headerTab.getTabAt(TAB_SELECTED); if (selectedTab != null) { selectedTab.setText(getString(R.string.ro_ms_selected, mSelectedAdapter.getItemCount())); } } private void updateAvailableTabTitle() { TabLayout.Tab selectedTab = headerTab.getTabAt(TAB_AVAILABLE); if (selectedTab != null) { selectedTab.setText(getString(R.string.ro_ms_available, mInputControlOptions.size())); } } private class MultiSelectViewPagerAdapter extends PagerAdapter { @Override public int getCount() { return TAB_COUNT; } @Override public boolean isViewFromObject(View view, Object o) { return view.equals(o); } @Override public Object instantiateItem(ViewGroup container, int position) { LayoutInflater layoutInflater = LayoutInflater.from(MultiSelectActivity.this); View selectView = layoutInflater.inflate(R.layout.view_select_ic_list, container, false); RecyclerView list = (RecyclerView) selectView.findViewById(R.id.inputControlsList); list.setLayoutManager(new LinearLayoutManager(MultiSelectActivity.this)); list.setHasFixedSize(true); if (position == TAB_AVAILABLE) { availableList = list; availableList.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); int visibleItemCount = recyclerView.getChildCount(); int totalItemCount = recyclerView.getLayoutManager().getItemCount(); int firstVisibleItem = ((LinearLayoutManager) layoutManager).findFirstCompletelyVisibleItemPosition(); if (totalItemCount > 0 && firstVisibleItem + visibleItemCount >= totalItemCount) { mAvailableAdapter.loadNextItems(); } } }); list.setAdapter(mAvailableAdapter); emptyTextAvailable = (TextView) selectView.findViewById(R.id.empty); emptyTextAvailable.setText(getString(R.string.r_search_nothing_to_display)); emptyTextAvailable.setVisibility(mAvailableAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE); } else { selectedList = list; list.setAdapter(mSelectedAdapter); emptyTextSelected = (TextView) selectView.findViewById(R.id.empty); emptyTextSelected.setText(getString(R.string.ro_no_items_selected)); emptyTextSelected.setVisibility(mSelectedAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE); } container.addView(selectView, 0); return selectView; } @Override public void destroyItem(ViewGroup collection, int position, Object view) { collection.removeView(((View) view)); } @Override public CharSequence getPageTitle(int position) { if (position == TAB_AVAILABLE) { return getString(R.string.ro_ms_available, mInputControlOptions.size()); } return getString(R.string.ro_ms_selected, mSelectedAdapter.getItemCount()); } } }