package org.buildmlearn.toolkit.fragment; import android.app.Activity; import android.app.Fragment; import android.content.DialogInterface; import android.content.Intent; import android.graphics.drawable.ColorDrawable; import android.os.Build; import android.os.Bundle; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.Toast; import org.buildmlearn.toolkit.R; import org.buildmlearn.toolkit.ToolkitApplication; import org.buildmlearn.toolkit.activity.TemplateEditor; import org.buildmlearn.toolkit.adapter.DraftProjectAdapter; import org.buildmlearn.toolkit.constant.Constants; import org.buildmlearn.toolkit.model.SavedProject; import org.buildmlearn.toolkit.model.Template; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.xml.sax.SAXException; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; /** * Created by scopeinfinity on 10/3/16. */ /** * @brief Fragment used to save drafts. */ public class DraftsFragment extends Fragment implements AbsListView.OnItemClickListener { private static final String TAG = "Draft Project Fragment"; private AbsListView mListView; private boolean showTemplateSelectedMenu; private DraftProjectAdapter mAdapter; private ToolkitApplication mToolkit; private Activity activity; private ArrayList<SavedProject> draftProjects; private View selectedView = null; private int selectedPosition = -1; /** * {@inheritDoc} */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); mToolkit = (ToolkitApplication) getActivity().getApplicationContext(); activity = getActivity(); draftProjects = new ArrayList<>(); String path = mToolkit.getDraftDir(); Log.d("Files", "Path: " + path); reloadContent(); } /** * {@inheritDoc} */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_loadproject, container, false); } /** * {@inheritDoc} */ @Override public void onViewCreated(View view, Bundle savedInstanceState) { mAdapter = new DraftProjectAdapter(getActivity(), draftProjects); mListView = (AbsListView) view.findViewById(android.R.id.list); setAdapter(mAdapter); mListView.setOnItemClickListener(this); mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { if (mAdapter.isPositionSelected(position)) { mAdapter.removeSelectedPosition(position); view.setBackgroundResource(0); if (mAdapter.selectedPositionsSize() == 0) restoreColorScheme(); } else { view.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.color_divider)); mAdapter.putSelectedPosition(position); changeColorScheme(); } return true; } }); getView().setFocusableInTouchMode(true); getView().requestFocus(); getView().setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (mAdapter.selectedPositionsSize() > 0) { unselectAll(); return true; } } return false; } }); } /** * {@inheritDoc} */ @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if(mAdapter.selectedPositionsSize() > 0) { if(mAdapter.isPositionSelected(position)) { mAdapter.removeSelectedPosition(position); view.setBackgroundResource(0); if(mAdapter.selectedPositionsSize() == 0) restoreColorScheme(); } else{ view.setBackgroundColor(ContextCompat.getColor(mToolkit, R.color.color_divider)); mAdapter.putSelectedPosition(position); Log.d(TAG, "Position: " + position); changeColorScheme(); } return ; } SavedProject project = draftProjects.get(position); Template[] templates = Template.values(); for (int i = 0; i < templates.length; i++) { if (project.getType().equals(getString(templates[i].getType()))) { Intent intent = new Intent(getActivity(), TemplateEditor.class); intent.putExtra(Constants.TEMPLATE_ID, i); intent.putExtra(Constants.PROJECT_FILE_PATH, project.getFullPath()); startActivity(intent); return; } } Toast.makeText(getActivity(), "Invalid project file", Toast.LENGTH_SHORT).show(); } private void setAdapter(DraftProjectAdapter adapter) { mListView.setAdapter(adapter); setEmptyText(); } private void setEmptyText() { getView().findViewById(R.id.newProject).setVisibility(View.GONE); getView().findViewById(R.id.no_saved_project).setVisibility(View.GONE); getView().findViewById(R.id.no_saved_apks).setVisibility(View.GONE); if (mListView.getAdapter().getCount() == 0) { getView().findViewById(R.id.no_saved_drafts).setVisibility(View.VISIBLE); } else { getView().findViewById(R.id.no_saved_drafts).setVisibility(View.GONE); } } /** * {@inheritDoc} */ @Override public void onResume() { if (mAdapter != null) { reloadContent(); } setEmptyText(); super.onResume(); } private void reloadContent() { draftProjects.clear(); String path = mToolkit.getDraftDir(); Log.d("Files", "Path: " + path); File f = new File(path); File file[] = f.listFiles(); if (file == null) { return; } Log.d("Files", "Size: " + file.length); for (File aFile : file) { File fXmlFile = new File(aFile.getAbsolutePath()); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder; try { dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(fXmlFile); doc.getDocumentElement().normalize(); Log.d("Files", "Root element :" + doc.getDocumentElement().getAttribute("type")); draftProjects.add(new SavedProject(fXmlFile, fXmlFile.getName(), fXmlFile.lastModified(), doc.getDocumentElement().getAttribute("type"), fXmlFile.getAbsolutePath())); } catch (ParserConfigurationException | DOMException | IOException | SAXException e) { e.printStackTrace(); } } Collections.sort(draftProjects, new Comparator<SavedProject>() { public int compare(SavedProject f1, SavedProject f2) { //In Decreasing order of last modified return (Long.valueOf(f2.getFile().lastModified()).compareTo(f1.getFile().lastModified())); } }); if (mAdapter != null) mAdapter.notifyDataSetChanged(); } /** * @brief Restores the color scheme when switching from edit mode to normal mode. * <p/> * Edit mode is triggered, when the list item is long pressed. */ private void restoreColorScheme() { int primaryColor = ContextCompat.getColor(getActivity(), R.color.color_primary); int primaryColorDark = ContextCompat.getColor(getActivity(), R.color.color_primary_dark); ((AppCompatActivity) activity).getSupportActionBar().setBackgroundDrawable(new ColorDrawable(primaryColor)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { activity.getWindow().setStatusBarColor(primaryColorDark); activity.getWindow().setNavigationBarColor(primaryColor); } showTemplateSelectedMenu = false; activity.invalidateOptionsMenu(); } /** * @brief Changes the color scheme when switching from normal mode to edit mode. * <p/> * Edit mode is triggered, when the list item is long pressed. */ private void changeColorScheme() { int primaryColor = ContextCompat.getColor(getActivity(), R.color.color_primary_dark); int primaryColorDark = ContextCompat.getColor(getActivity(), R.color.color_selected_dark); ((AppCompatActivity) activity).getSupportActionBar().setBackgroundDrawable(new ColorDrawable(primaryColor)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { activity.getWindow().setStatusBarColor(primaryColorDark); activity.getWindow().setNavigationBarColor(primaryColor); } showTemplateSelectedMenu = true; activity.invalidateOptionsMenu(); } /** * {@inheritDoc} */ @Override public void onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); menu.clear(); if (showTemplateSelectedMenu) { activity.getMenuInflater().inflate(R.menu.menu_project_selected, menu); menu.findItem(R.id.action_share).setVisible(false); } else if (mAdapter.getCount() > 0) { activity.getMenuInflater().inflate(R.menu.menu_draft, menu); } } /** * {@inheritDoc} */ @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); switch (id) { case R.id.action_delete: final AlertDialog dialogDelete = new AlertDialog.Builder(activity) .setTitle(R.string.dialog_delete_title) .setMessage(R.string.dialog_delete_msg) .setPositiveButton(R.string.dialog_yes, null) .setNegativeButton(R.string.dialog_no, null) .create(); dialogDelete.show(); dialogDelete.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dialogDelete.dismiss(); deleteItems(); restoreSelectedView(); } }); break; case R.id.action_select_all: for(int i=0;i<mAdapter.getCount();i++) { if (!mAdapter.isPositionSelected(i)) { draftProjects.get(i).setSelected(true); mAdapter.putSelectedPosition(i); changeColorScheme(); } } mAdapter.notifyDataSetChanged(); break; case R.id.action_unselect_all: unselectAll(); break; case R.id.action_delete_all: final AlertDialog dialogDeleteAll = new AlertDialog.Builder(activity) .setTitle(R.string.dialog_delete_all_title) .setMessage(R.string.dialog_delete_all_msg) .setPositiveButton(R.string.dialog_yes, null) .setNegativeButton(R.string.dialog_no, null) .create(); dialogDeleteAll.show(); dialogDeleteAll.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dialogDeleteAll.dismiss(); deleteAllDrafts(); restoreSelectedView(); } }); break; default: //do nothing break; } return super.onOptionsItemSelected(item); } private void unselectAll() { for (int i = 0; i < mAdapter.getCount(); i++) if (mAdapter.isPositionSelected(i)) { draftProjects.get(i).setSelected(false); mAdapter.removeSelectedPosition(i); } mAdapter.notifyDataSetChanged(); restoreColorScheme(); } /** * @brief Removes selected project item */ private void deleteItems() { ArrayList<Integer> selectedPositions = mAdapter.getSelectedPositions(); boolean deleted = false; for(int selectedPosition : selectedPositions) { SavedProject project = draftProjects.get(selectedPosition); File file = new File(project.getFile().getPath()); deleted = file.delete(); if (deleted) { draftProjects.remove(selectedPosition); mAdapter.removeSelectedPosition(selectedPosition); mAdapter.notifyDataSetChanged(); setEmptyText(); } } if(deleted) if(selectedPositions.size()==1) Toast.makeText(activity,"Project Successfully Deleted", Toast.LENGTH_SHORT).show(); else Toast.makeText(activity,selectedPositions.size()+" Projects Successfully Deleted", Toast.LENGTH_SHORT).show(); else Toast.makeText(activity, "Project Deletion Failed!", Toast.LENGTH_SHORT).show(); } /** * @brief Removes All Drafts */ private void deleteAllDrafts() { File draftDir = new File(mToolkit.getDraftDir()); File[] allDrafts = draftDir.listFiles(); boolean allDeleted = true; for (File draft : allDrafts) { if (!draft.delete()) allDeleted = false; } if (allDeleted) Toast.makeText(activity, getResources().getString(R.string.draft_deleted), Toast.LENGTH_SHORT).show(); else Toast.makeText(activity, getResources().getString(R.string.draft_deleted_failed), Toast.LENGTH_SHORT).show(); reloadContent(); setEmptyText(); } /** * @brief Removes selected color from the selected ListView item when switching from edit mode to normal mode */ private void restoreSelectedView() { restoreColorScheme(); } }