<commit_before>package com.namelessdev.mpdroid.fragments;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.*;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.*;
import android.widget.PopupMenu.OnMenuItemClickListener;
import android.widget.SearchView.OnQueryTextListener;
import com.mobeta.android.dslv.DragSortController;
import com.mobeta.android.dslv.DragSortListView;
import com.namelessdev.mpdroid.MPDApplication;
import com.namelessdev.mpdroid.MainMenuActivity;
import com.namelessdev.mpdroid.R;
import com.namelessdev.mpdroid.helpers.AlbumCoverDownloadListener;
import com.namelessdev.mpdroid.helpers.CoverAsyncHelper;
import com.namelessdev.mpdroid.library.PlaylistEditActivity;
import com.namelessdev.mpdroid.models.AbstractPlaylistMusic;
import com.namelessdev.mpdroid.models.PlaylistSong;
import com.namelessdev.mpdroid.models.PlaylistStream;
import com.namelessdev.mpdroid.tools.Tools;
import com.namelessdev.mpdroid.views.holders.PlayQueueViewHolder;
import org.a0z.mpd.*;
import org.a0z.mpd.event.StatusChangeListener;
import org.a0z.mpd.exception.MPDServerException;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import static android.util.Log.e;

public class PlaylistFragment extends ListFragment implements StatusChangeListener, OnMenuItemClickListener {
    private ArrayList<AbstractPlaylistMusic> songlist;
    private MPDApplication app;
    private DragSortListView list;
    private ActionMode actionMode;
    private SearchView searchView;
    private String filter = null;
    private PopupMenu popupMenu;
    private Integer popupSongID;
    private DragSortController controller;
    private FragmentActivity activity;
    private static final boolean DEBUG = false;
    private int lastPlayingID = -1;

    public PlaylistFragment() {
        super();
        setHasOptionsMenu(true);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        this.activity = getActivity();
        app = (MPDApplication) activity.getApplication();
        refreshListColorCacheHint();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.playlist_activity, container, false);
        searchView = (SearchView) view.findViewById(R.id.search);
        searchView.setOnQueryTextListener(new OnQueryTextListener() {

            @Override
            public boolean onQueryTextSubmit(String query) {
                // Hide the keyboard and give focus to the list
                InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(searchView.getWindowToken(), 0);
                list.requestFocus();
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                filter = newText;
                if ("".equals(newText))
                    filter = null;
                if (filter != null)
                    filter = filter.toLowerCase();
                list.setDragEnabled(filter == null);
                update(false);
                return false;
            }
        });
        list = (DragSortListView) view.findViewById(android.R.id.list);
        list.requestFocus();
        list.setDropListener(onDrop);
        controller = new DragSortController(list);
        controller.setDragHandleId(R.id.cover);
        controller.setRemoveEnabled(false);
        controller.setSortEnabled(true);
        controller.setDragInitMode(1);

        list.setFloatViewManager(controller);
        list.setOnTouchListener(controller);
        list.setDragEnabled(true);

        refreshListColorCacheHint();
        list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
        list.setMultiChoiceModeListener(new MultiChoiceModeListener() {

            @Override
            public boolean onPrepareActionMode(ActionMode mode, android.view.Menu menu) {
                actionMode = mode;
                controller.setSortEnabled(false);
                return false;
            }

            @Override
            public void onDestroyActionMode(ActionMode mode) {
                actionMode = null;
                controller.setSortEnabled(true);
            }

            @Override
            public boolean onCreateActionMode(ActionMode mode, android.view.Menu menu) {
                final android.view.MenuInflater inflater = mode.getMenuInflater();
                inflater.inflate(R.menu.mpd_queuemenu, menu);
                return true;
            }

            @SuppressWarnings("unchecked")
            @Override
            public boolean onActionItemClicked(ActionMode mode, android.view.MenuItem item) {

                final SparseBooleanArray checkedItems = list.getCheckedItemPositions();
                final int count = list.getCount();
                final ListAdapter adapter = list.getAdapter();
                int j = 0;
                final int positions[];

                switch (item.getItemId()) {

                    case R.id.menu_delete:
                        positions = new int[list.getCheckedItemCount()];
                        for (int i = 0; i < count && j < positions.length; i++) {
                            if (checkedItems.get(i)) {
                                positions[j] = ((AbstractPlaylistMusic) adapter.getItem(i)).getSongId();
                                j++;
                            }
                        }

                        app.oMPDAsyncHelper.execAsync(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    app.oMPDAsyncHelper.oMPD.getPlaylist().removeById(positions);
                                } catch (MPDServerException e) {
                                    e.printStackTrace();
                                }
                            }
                        });

                        mode.finish();
                        return true;
                    case R.id.menu_crop:
                        positions = new int[list.getCount() - list.getCheckedItemCount()];
                        for (int i = 0; i < count && j < positions.length; i++) {
                            if (!checkedItems.get(i)) {
                                positions[j] = ((AbstractPlaylistMusic) adapter.getItem(i)).getSongId();
                                j++;
                            }
                        }

                        app.oMPDAsyncHelper.execAsync(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    app.oMPDAsyncHelper.oMPD.getPlaylist().removeById(positions);
                                } catch (MPDServerException e) {
                                    e.printStackTrace();
                                }
                            }
                        });

                        mode.finish();
                        return true;
                    default:
                        return false;
                }
            }

            @Override
            public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
                final int selectCount = list.getCheckedItemCount();
                if (selectCount == 0)
                    mode.finish();
                if (selectCount == 1) {
                    mode.setTitle(R.string.actionSongSelected);
                } else {
                    mode.setTitle(getString(R.string.actionSongsSelected, selectCount));
                }
            }
        });

        return view;
    }

    private void refreshListColorCacheHint() {
        if (app == null || list == null)
            return;
        if (app.isLightThemeSelected()) {
            list.setCacheColorHint(getResources().getColor(android.R.color.background_light));
        } else {
            list.setCacheColorHint(getResources().getColor(R.color.nowplaying_background));
        }
    }

    public void update() {
        update(true);
    }

    protected synchronized void update(boolean forcePlayingIDRefresh) {
        try {
            MPDPlaylist playlist = app.oMPDAsyncHelper.oMPD.getPlaylist();
            final ArrayList<AbstractPlaylistMusic> newSonglist = new ArrayList<AbstractPlaylistMusic>();
            List<Music> musics = playlist.getMusicList();
            if (lastPlayingID == -1 || forcePlayingIDRefresh)
                lastPlayingID = app.oMPDAsyncHelper.oMPD.getStatus().getSongId();
            // The position in the songlist of the currently played song
            int listPlayingID = -1;
            // Copy list to avoid concurrent exception
            for (Music m : new ArrayList<Music>(musics)) {
                if (m == null) {
                    continue;
                }

                AbstractPlaylistMusic item = m.isStream() ? new PlaylistStream(m) : new PlaylistSong(m);

                if (filter != null) {
                    if (!(item.getAlbumArtist() != null ? item.getAlbumArtist() : "").toLowerCase(Locale.getDefault()).contains(filter) &&
                            !(item.getAlbum() != null ? item.getAlbum() : "").toLowerCase(Locale.getDefault()).contains(filter) &&
                            !(item.getTitle() != null ? item.getTitle() : "").toLowerCase(Locale.getDefault()).contains(filter)) {
                        continue;
                    }
                }

                if (item.getSongId() == lastPlayingID) {
                    item.setCurrentSongIconRefID(android.R.drawable.ic_media_play);
                    // Lie a little. Scroll to the previous song than the one playing. That way it shows that there are other songs before
                    // it
                    listPlayingID = newSonglist.size() - 1;
                } else {
                    item.setCurrentSongIconRefID(0);
                }
                newSonglist.add(item);

                final int finalListPlayingID = listPlayingID;

                activity.runOnUiThread(new Runnable() {
                    public void run() {
                        ArrayAdapter songs = new QueueAdapter(activity, newSonglist, R.layout.playlist_queue_item);
                        setListAdapter(songs);
                        songlist = newSonglist;
                        if (actionMode != null)
                            actionMode.finish();

                        // Only scroll if there is a valid song to scroll to. 0 is a valid song but does not require scroll anyway.
                        // Also, only scroll if it's the first update. You don't want your playlist to scroll itself while you are looking at
                        // other
                        // stuff.
                        if (finalListPlayingID > 0 && getView() != null)
                            setSelection(finalListPlayingID);
                    }
                });
            }<commit_msg>Avoid crash : adapter has changed but ListView did not receive a notification<commit_after>package com.namelessdev.mpdroid.fragments;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.*;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.*;
import android.widget.PopupMenu.OnMenuItemClickListener;
import android.widget.SearchView.OnQueryTextListener;
import com.mobeta.android.dslv.DragSortController;
import com.mobeta.android.dslv.DragSortListView;
import com.namelessdev.mpdroid.MPDApplication;
import com.namelessdev.mpdroid.MainMenuActivity;
import com.namelessdev.mpdroid.R;
import com.namelessdev.mpdroid.helpers.AlbumCoverDownloadListener;
import com.namelessdev.mpdroid.helpers.CoverAsyncHelper;
import com.namelessdev.mpdroid.library.PlaylistEditActivity;
import com.namelessdev.mpdroid.models.AbstractPlaylistMusic;
import com.namelessdev.mpdroid.models.PlaylistSong;
import com.namelessdev.mpdroid.models.PlaylistStream;
import com.namelessdev.mpdroid.tools.Tools;
import com.namelessdev.mpdroid.views.holders.PlayQueueViewHolder;
import org.a0z.mpd.*;
import org.a0z.mpd.event.StatusChangeListener;
import org.a0z.mpd.exception.MPDServerException;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import static android.util.Log.e;

public class PlaylistFragment extends ListFragment implements StatusChangeListener, OnMenuItemClickListener {
    private ArrayList<AbstractPlaylistMusic> songlist;
    private MPDApplication app;
    private DragSortListView list;
    private ActionMode actionMode;
    private SearchView searchView;
    private String filter = null;
    private PopupMenu popupMenu;
    private Integer popupSongID;
    private DragSortController controller;
    private FragmentActivity activity;
    private static final boolean DEBUG = false;
    private int lastPlayingID = -1;

    public PlaylistFragment() {
        super();
        setHasOptionsMenu(true);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        this.activity = getActivity();
        app = (MPDApplication) activity.getApplication();
        refreshListColorCacheHint();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.playlist_activity, container, false);
        searchView = (SearchView) view.findViewById(R.id.search);
        searchView.setOnQueryTextListener(new OnQueryTextListener() {

            @Override
            public boolean onQueryTextSubmit(String query) {
                // Hide the keyboard and give focus to the list
                InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(searchView.getWindowToken(), 0);
                list.requestFocus();
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                filter = newText;
                if ("".equals(newText))
                    filter = null;
                if (filter != null)
                    filter = filter.toLowerCase();
                list.setDragEnabled(filter == null);
                update(false);
                return false;
            }
        });
        list = (DragSortListView) view.findViewById(android.R.id.list);
        list.requestFocus();
        list.setDropListener(onDrop);
        controller = new DragSortController(list);
        controller.setDragHandleId(R.id.cover);
        controller.setRemoveEnabled(false);
        controller.setSortEnabled(true);
        controller.setDragInitMode(1);

        list.setFloatViewManager(controller);
        list.setOnTouchListener(controller);
        list.setDragEnabled(true);

        refreshListColorCacheHint();
        list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
        list.setMultiChoiceModeListener(new MultiChoiceModeListener() {

            @Override
            public boolean onPrepareActionMode(ActionMode mode, android.view.Menu menu) {
                actionMode = mode;
                controller.setSortEnabled(false);
                return false;
            }

            @Override
            public void onDestroyActionMode(ActionMode mode) {
                actionMode = null;
                controller.setSortEnabled(true);
            }

            @Override
            public boolean onCreateActionMode(ActionMode mode, android.view.Menu menu) {
                final android.view.MenuInflater inflater = mode.getMenuInflater();
                inflater.inflate(R.menu.mpd_queuemenu, menu);
                return true;
            }

            @SuppressWarnings("unchecked")
            @Override
            public boolean onActionItemClicked(ActionMode mode, android.view.MenuItem item) {

                final SparseBooleanArray checkedItems = list.getCheckedItemPositions();
                final int count = list.getCount();
                final ListAdapter adapter = list.getAdapter();
                int j = 0;
                final int positions[];

                switch (item.getItemId()) {

                    case R.id.menu_delete:
                        positions = new int[list.getCheckedItemCount()];
                        for (int i = 0; i < count && j < positions.length; i++) {
                            if (checkedItems.get(i)) {
                                positions[j] = ((AbstractPlaylistMusic) adapter.getItem(i)).getSongId();
                                j++;
                            }
                        }

                        app.oMPDAsyncHelper.execAsync(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    app.oMPDAsyncHelper.oMPD.getPlaylist().removeById(positions);
                                } catch (MPDServerException e) {
                                    e.printStackTrace();
                                }
                            }
                        });

                        mode.finish();
                        return true;
                    case R.id.menu_crop:
                        positions = new int[list.getCount() - list.getCheckedItemCount()];
                        for (int i = 0; i < count && j < positions.length; i++) {
                            if (!checkedItems.get(i)) {
                                positions[j] = ((AbstractPlaylistMusic) adapter.getItem(i)).getSongId();
                                j++;
                            }
                        }

                        app.oMPDAsyncHelper.execAsync(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    app.oMPDAsyncHelper.oMPD.getPlaylist().removeById(positions);
                                } catch (MPDServerException e) {
                                    e.printStackTrace();
                                }
                            }
                        });

                        mode.finish();
                        return true;
                    default:
                        return false;
                }
            }

            @Override
            public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
                final int selectCount = list.getCheckedItemCount();
                if (selectCount == 0)
                    mode.finish();
                if (selectCount == 1) {
                    mode.setTitle(R.string.actionSongSelected);
                } else {
                    mode.setTitle(getString(R.string.actionSongsSelected, selectCount));
                }
            }
        });

        return view;
    }

    private void refreshListColorCacheHint() {
        if (app == null || list == null)
            return;
        if (app.isLightThemeSelected()) {
            list.setCacheColorHint(getResources().getColor(android.R.color.background_light));
        } else {
            list.setCacheColorHint(getResources().getColor(R.color.nowplaying_background));
        }
    }

    public void update() {
        update(true);
    }

    protected synchronized void update(boolean forcePlayingIDRefresh) {
        try {
            MPDPlaylist playlist = app.oMPDAsyncHelper.oMPD.getPlaylist();
            final ArrayList<AbstractPlaylistMusic> newSonglist = new ArrayList<AbstractPlaylistMusic>();
            List<Music> musics = playlist.getMusicList();
            if (lastPlayingID == -1 || forcePlayingIDRefresh)
                lastPlayingID = app.oMPDAsyncHelper.oMPD.getStatus().getSongId();
            // The position in the songlist of the currently played song
            int listPlayingID = -1;
            // Copy list to avoid concurrent exception
            for (Music m : new ArrayList<Music>(musics)) {
                if (m == null) {
                    continue;
                }

                AbstractPlaylistMusic item = m.isStream() ? new PlaylistStream(m) : new PlaylistSong(m);

                if (filter != null) {
                    if (!(item.getAlbumArtist() != null ? item.getAlbumArtist() : "").toLowerCase(Locale.getDefault()).contains(filter) &&
                            !(item.getAlbum() != null ? item.getAlbum() : "").toLowerCase(Locale.getDefault()).contains(filter) &&
                            !(item.getTitle() != null ? item.getTitle() : "").toLowerCase(Locale.getDefault()).contains(filter)) {
                        continue;
                    }
                }

                if (item.getSongId() == lastPlayingID) {
                    item.setCurrentSongIconRefID(android.R.drawable.ic_media_play);
                    // Lie a little. Scroll to the previous song than the one playing. That way it shows that there are other songs before
                    // it
                    listPlayingID = newSonglist.size() - 1;
                } else {
                    item.setCurrentSongIconRefID(0);
                }
                newSonglist.add(item);

                final int finalListPlayingID = listPlayingID;

                activity.runOnUiThread(new Runnable() {
                    public void run() {
                        ArrayAdapter songs = new QueueAdapter(activity, newSonglist, R.layout.playlist_queue_item);
                        setListAdapter(songs);
                        songlist = newSonglist;
                        songs.notifyDataSetChanged();
                        if (actionMode != null)
                            actionMode.finish();

                        // Only scroll if there is a valid song to scroll to. 0 is a valid song but does not require scroll anyway.
                        // Also, only scroll if it's the first update. You don't want your playlist to scroll itself while you are looking at
                        // other
                        // stuff.
                        if (finalListPlayingID > 0 && getView() != null)
                            setSelection(finalListPlayingID);
                    }
                });
            }
{'fraction_non_alphanumeric': 0.08566226287262872, 'fraction_numerical': 0.001609078590785908, 'mean_word_length': 1.6987772825962748, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4740678', 'n_tokens_mistral': 5908, 'n_tokens_neox': 5523, 'n_words': 1192}