/* * Catroid: An on-device visual programming system for Android devices * Copyright (C) 2010-2016 The Catrobat Team * (<http://developer.catrobat.org/credits>) * * 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. * * An additional term exception under section 7 of the GNU Affero * General Public License, version 3, is available at * http://developer.catrobat.org/license_additional_term * * 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/>. */ package org.catrobat.catroid.ui.fragment; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.ActionMode; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; import org.catrobat.catroid.ProjectManager; import org.catrobat.catroid.R; import org.catrobat.catroid.common.Constants; import org.catrobat.catroid.content.Scene; import org.catrobat.catroid.io.StorageHandler; import org.catrobat.catroid.ui.BackPackActivity; import org.catrobat.catroid.ui.BottomBar; import org.catrobat.catroid.ui.ProjectActivity; import org.catrobat.catroid.ui.adapter.CheckBoxListAdapter; import org.catrobat.catroid.ui.adapter.SceneListAdapter; import org.catrobat.catroid.ui.controller.BackPackListManager; import org.catrobat.catroid.ui.controller.BackPackSceneController; import org.catrobat.catroid.ui.dialogs.RenameItemDialog; import org.catrobat.catroid.ui.dragndrop.DragAndDropListView; import org.catrobat.catroid.utils.SnackbarUtil; import org.catrobat.catroid.utils.Utils; import java.io.File; import java.io.IOException; import java.util.List; public class SceneListFragment extends ListActivityFragment implements CheckBoxListAdapter.ListItemClickHandler<Scene> { public static final String TAG = SceneListFragment.class.getSimpleName(); private static final String BUNDLE_ARGUMENTS_SCENE_TO_EDIT = "scene_to_edit"; private SceneListAdapter sceneAdapter; private DragAndDropListView listView; private Scene sceneToEdit; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View sceneListFragment = inflater.inflate(R.layout.fragment_scenes_list, container, false); listView = (DragAndDropListView) sceneListFragment.findViewById(android.R.id.list); sceneListFragment.findViewById(R.id.sceneList_headline).setVisibility(View.VISIBLE); SnackbarUtil.showHintSnackbar(getActivity(), R.string.hint_scenes); return sceneListFragment; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); registerForContextMenu(getListView()); singleItemTitle = getString(R.string.scene); multipleItemsTitle = getString(R.string.scenes); if (savedInstanceState != null) { sceneToEdit = (Scene) savedInstanceState.get(BUNDLE_ARGUMENTS_SCENE_TO_EDIT); } initializeList(); } private void initializeList() { List<Scene> sceneList = ProjectManager.getInstance().getCurrentProject().getSceneList(); sceneAdapter = new SceneListAdapter(getActivity(), R.layout.list_item, sceneList); setListAdapter(sceneAdapter); sceneAdapter.setListItemClickHandler(this); sceneAdapter.setListItemLongClickHandler(listView); sceneAdapter.setListItemCheckHandler(this); listView.setAdapterInterface(sceneAdapter); } @Override public void onSaveInstanceState(Bundle outState) { outState.putSerializable(BUNDLE_ARGUMENTS_SCENE_TO_EDIT, sceneToEdit); super.onSaveInstanceState(outState); } @Override public void onResume() { super.onResume(); getActivity().getActionBar().setTitle(ProjectManager.getInstance().getCurrentProject().getName()); getActivity().findViewById(R.id.fragment_container).setVisibility(View.VISIBLE); getActivity().findViewById(R.id.progress_bar_activity_project).setVisibility(View.GONE); if (!Utils.checkForExternalStorageAvailableAndDisplayErrorIfNot(getActivity())) { return; } if (BackPackListManager.getInstance().isBackpackEmpty()) { BackPackListManager.getInstance().loadBackpack(); } StorageHandler.getInstance().fillChecksumContainer(); ProjectManager.getInstance().setCurrentScene(ProjectManager.getInstance().getCurrentProject().getDefaultScene()); } @Override public void onPause() { super.onPause(); getActivity().getIntent().removeExtra(Constants.PROJECTNAME_TO_LOAD); ProjectManager projectManager = ProjectManager.getInstance(); if (projectManager.getCurrentProject() != null) { projectManager.saveProject(getActivity().getApplicationContext()); } } @Override public void handleOnItemClick(int position, View view, Scene scene) { if (isActionModeActive()) { return; } ProjectManager.getInstance().setCurrentScene(scene); Intent intent = new Intent(getActivity(), ProjectActivity.class); intent.putExtra(ProjectActivity.EXTRA_FRAGMENT_POSITION, ProjectActivity.FRAGMENT_SPRITES); startActivity(intent); } @Override protected void startActionMode(ActionMode.Callback actionModeCallback) { if (isActionModeActive()) { return; } if (sceneAdapter.getCount() == 1) { if (actionModeCallback.equals(copyModeCallBack)) { ((ProjectActivity) getActivity()).showEmptyActionModeDialog(getString(R.string.copy)); } else if (actionModeCallback.equals(deleteModeCallBack)) { ((ProjectActivity) getActivity()).showEmptyActionModeDialog(getString(R.string.delete)); } else if (actionModeCallback.equals(renameModeCallBack)) { ((ProjectActivity) getActivity()).showEmptyActionModeDialog(getString(R.string.rename)); } } else { actionMode = getActivity().startActionMode(actionModeCallback); BottomBar.hideBottomBar(getActivity()); isRenameActionMode = actionModeCallback.equals(renameModeCallBack); } } private void checkSceneCountAfterDeletion() { ProjectManager projectManager = ProjectManager.getInstance(); if (projectManager.getCurrentProject().getSceneList().size() == 0) { Scene emptyScene = new Scene(getActivity(), getString(R.string.default_scene_name, 1), projectManager .getCurrentProject()); projectManager.getCurrentProject().addScene(emptyScene); projectManager.setCurrentScene(emptyScene); Intent intent = new Intent(getActivity(), ProjectActivity.class); intent.putExtra(ProjectActivity.EXTRA_FRAGMENT_POSITION, ProjectActivity.FRAGMENT_SPRITES); getActivity().finish(); startActivity(intent); } else if (projectManager.getCurrentProject().getSceneList().size() == 1) { Intent intent = new Intent(getActivity(), ProjectActivity.class); intent.putExtra(ProjectActivity.EXTRA_FRAGMENT_POSITION, ProjectActivity.FRAGMENT_SPRITES); getActivity().finish(); startActivity(intent); } } public void switchToBackPack() { Intent intent = new Intent(getActivity(), BackPackActivity.class); intent.putExtra(BackPackActivity.EXTRA_FRAGMENT_POSITION, BackPackActivity.FRAGMENT_BACKPACK_SCENES); startActivity(intent); } public void showDeleteDialog() { int titleId; if (sceneAdapter.getCheckedItems().size() == 1) { titleId = R.string.dialog_confirm_delete_scene_title; } else { titleId = R.string.dialog_confirm_delete_multiple_scenes_title; } showDeleteDialog(titleId); } protected void deleteCheckedItems() { boolean success = true; for (Scene scene : sceneAdapter.getCheckedItems()) { sceneToEdit = scene; success &= deleteScene(); } if (success) { ProjectManager.getInstance().saveProject(getActivity()); checkSceneCountAfterDeletion(); } else { showError(R.string.error_scene_not_deleted); } } private boolean deleteScene() { ProjectManager projectManager = ProjectManager.getInstance(); try { projectManager.deleteScene(sceneToEdit.getProject().getName(), sceneToEdit.getName()); } catch (IOException e) { Log.e(TAG, "Error while deleting Scene: ", e); return false; } if (projectManager.getCurrentScene() != null && projectManager.getCurrentScene().equals(sceneToEdit)) { projectManager.setCurrentScene(projectManager.getCurrentProject().getDefaultScene()); } projectManager.getCurrentProject().getSceneList().remove(sceneToEdit); projectManager.getCurrentProject().getSceneOrder().remove(sceneToEdit.getName()); return true; } protected void copyCheckedItems() { boolean success = true; for (Scene scene : sceneAdapter.getCheckedItems()) { sceneToEdit = scene; success &= copyScene(); } if (success) { ProjectManager.getInstance().saveProject(getActivity()); } else { showError(R.string.error_scene_not_copied); } clearCheckedItems(); } private boolean copyScene() { ProjectManager projectManager = ProjectManager.getInstance(); String sceneName = getNewValidSceneName(sceneToEdit.getName().concat(getString(R.string.copy_sprite_name_suffix)), 0); String projectName = projectManager.getCurrentProject().getName(); File sourceScene = new File(Utils.buildScenePath(projectName, sceneToEdit.getName())); File targetScene = new File(Utils.buildScenePath(projectName, sceneName)); try { StorageHandler.copyDirectory(targetScene, sourceScene); } catch (IOException e) { Log.e(TAG, "Error while copying Scene: ", e); return false; } Scene copiedScene = sceneToEdit.clone(); if (copiedScene == null) { return false; } copiedScene.setSceneName(sceneName); copiedScene.setProject(projectManager.getCurrentProject()); projectManager.addScene(copiedScene); return true; } @Override public void showRenameDialog() { sceneToEdit = sceneAdapter.getCheckedItems().get(0); RenameItemDialog dialog = new RenameItemDialog(R.string.rename_scene_dialog, R.string.scene_name, sceneToEdit .getName(), this); dialog.show(getFragmentManager(), RenameItemDialog.DIALOG_FRAGMENT_TAG); } @Override public boolean itemNameExists(String newName) { ProjectManager projectManager = ProjectManager.getInstance(); return projectManager.sceneExists(newName); } public void renameItem(String newName) { List<String> sceneOrder = ProjectManager.getInstance().getCurrentProject().getSceneOrder(); int pos = sceneOrder.indexOf(sceneToEdit.getName()); ProjectManager.getInstance().getCurrentProject().getSceneOrder().set(pos, newName); sceneToEdit.rename(newName, getActivity(), true); clearCheckedItems(); sceneAdapter.notifyDataSetChanged(); } protected void packCheckedItems() { List<Scene> sceneListToBackpack = sceneAdapter.getCheckedItems(); boolean sceneAlreadyInBackpack = BackPackSceneController.getInstance().checkScenesReplaceInBackpack(sceneListToBackpack); if (!sceneAlreadyInBackpack) { showProgressCircle(); packScenes(sceneListToBackpack); } else { SceneListFragment fragment = ((ProjectActivity) getActivity()).getSceneListFragment(); BackPackSceneController.getInstance().showBackPackReplaceDialog(sceneListToBackpack, fragment); } } public void packScenes(List<Scene> sceneList) { boolean success = BackPackSceneController.getInstance().backpackScenes(sceneList); clearCheckedItems(); if (success) { switchToBackPack(); return; } showError(R.string.error_scene_backpack); } public void showProgressCircle() { ProgressBar progressCircle = (ProgressBar) getActivity().findViewById(R.id.progress_bar_activity_project); progressCircle.setVisibility(View.VISIBLE); progressCircle.bringToFront(); getActivity().findViewById(R.id.fragment_container).setVisibility(View.GONE); BottomBar.showBottomBar(getActivity()); } private static String getNewValidSceneName(String name, int nextNumber) { String newName; if (nextNumber == 0) { newName = name; } else { newName = name + nextNumber; } for (Scene scene : ProjectManager.getInstance().getCurrentProject().getSceneList()) { if (scene.getName().equals(newName)) { return getNewValidSceneName(name, ++nextNumber); } } return newName; } }