com.nextgis.maplibui.fragment.LayersListAdapter.java Source code

Java tutorial

Introduction

Here is the source code for com.nextgis.maplibui.fragment.LayersListAdapter.java

Source

/*
 * Project:  NextGIS Mobile
 * Purpose:  Mobile GIS for Android.
 * Author:   Dmitry Baryshnikov (aka Bishop), bishop.dev@gmail.com
 * Author:   NikitaFeodonit, nfeodonit@yandex.com
 * Author:   Stanislav Petriakov, becomeglory@gmail.com
 * *****************************************************************************
 * Copyright (c) 2012-2016 NextGIS, info@nextgis.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser 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 Lesser Public License for more details.
 *
 * You should have received a copy of the GNU Lesser Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.nextgis.maplibui.fragment;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.widget.PopupMenu;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.nextgis.maplib.api.ILayer;
import com.nextgis.maplib.api.MapEventListener;
import com.nextgis.maplib.datasource.GeoEnvelope;
import com.nextgis.maplib.datasource.GeoPoint;
import com.nextgis.maplib.datasource.ngw.Connection;
import com.nextgis.maplib.map.Layer;
import com.nextgis.maplib.map.LayerGroup;
import com.nextgis.maplib.map.LocalTMSLayer;
import com.nextgis.maplib.map.MapDrawable;
import com.nextgis.maplib.map.NGWLookupTable;
import com.nextgis.maplib.map.NGWRasterLayer;
import com.nextgis.maplib.map.NGWTrackLayer;
import com.nextgis.maplib.map.RemoteTMSLayer;
import com.nextgis.maplib.map.Table;
import com.nextgis.maplib.map.TrackLayer;
import com.nextgis.maplib.map.VectorLayer;
import com.nextgis.maplibui.R;
import com.nextgis.maplibui.activity.NGActivity;
import com.nextgis.maplibui.api.ILayerUI;
import com.nextgis.maplibui.api.IVectorLayerUI;
import com.nextgis.maplibui.dialog.NGWResourcesListAdapter;
import com.nextgis.maplibui.dialog.SelectNGWResourceDialog;
import com.nextgis.maplibui.mapui.MapView;
import com.nextgis.maplibui.mapui.NGWRasterLayerUI;
import com.nextgis.maplibui.mapui.NGWWebMapLayerUI;
import com.nextgis.maplibui.mapui.RemoteTMSLayerUI;
import com.nextgis.maplibui.mapui.TrackLayerUI;
import com.nextgis.maplibui.mapui.VectorLayerUI;
import com.nextgis.maplibui.util.LayerUtil;
import com.nextgis.maplibui.util.NGWTrackLayerCreateTask;

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

import static com.nextgis.maplib.util.Constants.LAYERTYPE_NGW_TRACKS;
import static com.nextgis.maplib.util.Constants.NOT_FOUND;

/**
 * An adapter to show layers as list
 */
public class LayersListAdapter extends BaseAdapter implements MapEventListener {

    protected final MapView mMapView;
    protected final MapDrawable mMap;
    protected final Context mContext;
    protected final NGActivity mActivity;
    protected DrawerLayout mDrawer;
    protected onEdit mEditListener;
    protected View.OnClickListener mOnPencilClickListener;
    protected boolean mTracksSyncEnabled;

    public interface onEdit {
        void onLayerEdit(ILayer layer);
    }

    public LayersListAdapter(NGActivity activity, MapView map) {
        mMapView = map;
        mMap = map.getMap();
        mContext = mActivity = activity;

        if (null != mMap) {
            mMap.addListener(this);
        }
    }

    public void setOnLayerEditListener(onEdit listener) {
        mEditListener = listener;
    }

    public void setOnPencilClickListener(View.OnClickListener listener) {
        mOnPencilClickListener = listener;
    }

    @Override
    protected void finalize() throws Throwable {
        if (null != mMap) {
            mMap.removeListener(this);
        }
        super.finalize();
    }

    public void onResume() {
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        if (null != mMap) {
            return mMap.getLayerCount();
        }
        return 0;
    }

    @Override
    public Object getItem(int i) {
        int nIndex = getCount() - 1 - i;
        if (null != mMap) {
            return mMap.getLayer(nIndex);
        }
        return null;
    }

    @Override
    public long getItemId(int i) {
        if (i < 0 || i >= mMap.getLayerCount()) {
            return NOT_FOUND;
        }
        Table layer = (Table) getItem(i);
        if (null != layer) {
            return layer.getId();
        }
        return NOT_FOUND;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        final Table layer = (Table) getItem(i);
        return getStandardLayerView(layer, view);
    }

    private View getStandardLayerView(final ILayer layer, View view) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View v = view;
        if (v == null || v.getId() == R.id.empty_row)
            v = inflater.inflate(R.layout.row_layer, null);

        if (layer instanceof NGWLookupTable || layer instanceof NGWTrackLayer)
            return inflater.inflate(R.layout.row_empty, null);

        final ILayerUI layerui;
        if (layer == null) {
            return v;
        } else if (layer instanceof ILayerUI) {
            layerui = (ILayerUI) layer;
        } else {
            layerui = null;
        }

        ImageView ivIcon = (ImageView) v.findViewById(R.id.ivIcon);
        ivIcon.setImageDrawable(layerui != null ? layerui.getIcon(mContext) : null);

        TextView tvPaneName = (TextView) v.findViewById(R.id.tvLayerName);
        tvPaneName.setText(layer.getName());
        //final int id = layer.getId();

        final ImageButton btMore = (ImageButton) v.findViewById(R.id.btMore);
        ImageButton btShow = (ImageButton) v.findViewById(R.id.btShow);
        ImageView ivEdited = (ImageView) v.findViewById(R.id.ivEdited);

        boolean hide = layerui instanceof VectorLayer && ((VectorLayer) layerui).isLocked();
        btMore.setVisibility(hide ? View.GONE : View.VISIBLE);
        btShow.setVisibility(hide ? View.GONE : View.VISIBLE);
        ivEdited.setVisibility(hide ? View.VISIBLE : View.GONE);
        if (mOnPencilClickListener != null)
            ivEdited.setOnClickListener(mOnPencilClickListener);

        int[] attrs = new int[] { R.attr.ic_action_visibility_on, R.attr.ic_action_visibility_off };
        TypedArray ta = mContext.obtainStyledAttributes(attrs);
        Drawable visibilityOn = ta.getDrawable(0);
        Drawable visibilityOff = ta.getDrawable(1);

        if (layer instanceof Layer) {
            btShow.setImageDrawable(//setImageResource(
                    ((Layer) layer).isVisible() ? visibilityOn : visibilityOff);
            //btShow.refreshDrawableState();
            btShow.setOnClickListener(new View.OnClickListener() {
                public void onClick(View arg0) {
                    //Layer layer = mMap.getLayerById(id);
                    ((Layer) layer).setVisible(!((Layer) layer).isVisible());
                    layer.save();
                }
            });
        }
        ta.recycle();

        btMore.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                PopupMenu popup = new PopupMenu(mContext, btMore);
                popup.getMenuInflater().inflate(R.menu.layer_popup, popup.getMenu());

                if (layerui == null) {
                    popup.getMenu().findItem(R.id.menu_settings).setEnabled(false);
                    popup.getMenu().findItem(R.id.menu_share).setEnabled(false);
                }

                if (layer instanceof VectorLayerUI)
                    popup.getMenu().findItem(R.id.menu_send_to_ngw).setVisible(true);

                if (layerui instanceof TrackLayer) {
                    popup.getMenu().findItem(R.id.menu_delete).setVisible(false);
                    popup.getMenu().findItem(R.id.menu_settings).setTitle(R.string.track_list);

                    List<ILayer> tracks = new ArrayList<>();
                    LayerGroup.getLayersByType(mMap, LAYERTYPE_NGW_TRACKS, tracks);
                    popup.getMenu().findItem(R.id.menu_share).setVisible(true);
                    mTracksSyncEnabled = tracks.size() > 0;
                    int title = mTracksSyncEnabled ? R.string.sync_disable : R.string.sync;
                    popup.getMenu().findItem(R.id.menu_share).setTitle(title);
                } else if (layerui instanceof VectorLayer) {
                    popup.getMenu().findItem(R.id.menu_edit).setVisible(true);
                    popup.getMenu().findItem(R.id.menu_share).setVisible(true);
                    popup.getMenu().findItem(R.id.menu_zoom_extent).setVisible(true);
                    popup.getMenu().findItem(R.id.menu_download_tiles).setVisible(true);
                    popup.getMenu().findItem(R.id.menu_download_tiles).setTitle(R.string.attributes);
                } else if (layerui instanceof LocalTMSLayer) {
                    popup.getMenu().findItem(R.id.menu_zoom_extent).setVisible(true);
                } else if (layerui instanceof NGWRasterLayer) {
                    popup.getMenu().findItem(R.id.menu_zoom_extent).setVisible(true);
                    popup.getMenu().findItem(R.id.menu_download_tiles).setVisible(true);
                } else if (layerui instanceof RemoteTMSLayer) {
                    popup.getMenu().findItem(R.id.menu_download_tiles).setVisible(true);
                }

                if (layerui instanceof NGWWebMapLayerUI) {
                    popup.getMenu().findItem(R.id.menu_zoom_extent).setVisible(false);
                    popup.getMenu().findItem(R.id.menu_edit).setVisible(true);
                    popup.getMenu().findItem(R.id.menu_edit).setTitle(R.string.sync_layers);
                }

                popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    public boolean onMenuItemClick(MenuItem item) {
                        int i = item.getItemId();
                        if (i == R.id.menu_settings) {
                            assert layerui != null;
                            layerui.changeProperties(mContext);
                        } else if (i == R.id.menu_share) {
                            assert layerui != null;

                            if (layerui instanceof TrackLayerUI) {
                                //                                                handleTrackSync();
                                Toast.makeText(mContext, R.string.commercial, Toast.LENGTH_SHORT).show();
                                return true;
                            } else if (layerui instanceof VectorLayer) {
                                VectorLayer vectorLayer = (VectorLayer) layerui;
                                LayerUtil.shareLayerAsGeoJSON(mActivity, vectorLayer);
                            }
                        } else if (i == R.id.menu_edit) {
                            if (layerui instanceof NGWWebMapLayerUI)
                                ((NGWWebMapLayerUI) layerui).showLayersDialog(mMapView, mActivity);
                            else if (mEditListener != null)
                                mEditListener.onLayerEdit(layer);
                        } else if (i == R.id.menu_delete) {
                            return deleteLayer(layer);
                        } else if (i == R.id.menu_zoom_extent) {
                            mMap.zoomToExtent(layer.getExtents());
                        } else if (i == R.id.menu_download_tiles) {
                            GeoEnvelope env = mMap.getCurrentBounds();

                            if (layer instanceof RemoteTMSLayerUI) {
                                RemoteTMSLayerUI remoteTMSLayer = (RemoteTMSLayerUI) layer;
                                remoteTMSLayer.downloadTiles(mContext, env);
                            } else if (layer instanceof NGWRasterLayerUI) {
                                NGWRasterLayerUI remoteTMSLayer = (NGWRasterLayerUI) layer;
                                remoteTMSLayer.downloadTiles(mContext, env);
                            } else if (layer instanceof NGWWebMapLayerUI) {
                                NGWWebMapLayerUI remoteTMSLayer = (NGWWebMapLayerUI) layer;
                                remoteTMSLayer.downloadTiles(mContext, env);
                            } else if (layer instanceof IVectorLayerUI) {
                                IVectorLayerUI vectorLayerUI = (IVectorLayerUI) layer;
                                vectorLayerUI.showAttributes();
                            }
                        } else if (i == R.id.menu_send_to_ngw) {
                            if (layer instanceof VectorLayerUI)
                                ((VectorLayerUI) layer).sendToNGW(mActivity);
                        }

                        if (mDrawer != null)
                            mDrawer.closeDrawers();

                        return true;
                    }
                });

                popup.show();
            }
        });

        return v;
    }

    private boolean deleteLayer(final ILayer layer) {
        final int position = mMap.removeLayer(layer);

        View focus = mActivity.getCurrentFocus();
        if (focus == null)
            return true;

        Snackbar snackbar = Snackbar
                .make(focus, mActivity.getString(R.string.delete_layer_done), Snackbar.LENGTH_LONG)
                .setAction(R.string.undo, new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mMap.insertLayer(position, layer);
                    }
                }).setCallback(new Snackbar.Callback() {
                    @Override
                    public void onDismissed(Snackbar snackbar, int event) {
                        super.onDismissed(snackbar, event);
                        if (event == DISMISS_EVENT_MANUAL)
                            return;
                        if (event != DISMISS_EVENT_ACTION) {
                            layer.delete();
                            mMap.save();
                        }
                    }

                    @Override
                    public void onShown(Snackbar snackbar) {
                        super.onShown(snackbar);
                    }
                });

        View view = snackbar.getView();
        TextView textView = (TextView) view.findViewById(R.id.snackbar_text);
        textView.setTextColor(ContextCompat.getColor(mActivity, R.color.color_white));
        snackbar.show();
        return true;
    }

    private void handleTrackSync() {
        if (mTracksSyncEnabled) {
            List<ILayer> tracks = new ArrayList<>();
            LayerGroup.getLayersByType(mMap, LAYERTYPE_NGW_TRACKS, tracks);
            if (tracks.size() > 0) {
                tracks.get(0).delete();
                mMap.save();
                Toast.makeText(mContext, R.string.sync_disabled, Toast.LENGTH_SHORT).show();
            }
        } else {
            final SelectNGWResourceDialog selectAccountDialog = new SelectNGWResourceDialog();
            selectAccountDialog.setConnectionListener(new NGWResourcesListAdapter.OnConnectionListener() {
                @Override
                public void onConnectionSelected(final Connection connection) {
                    new NGWTrackLayerCreateTask(mActivity, connection).execute();
                    selectAccountDialog.dismiss();
                }

                @Override
                public void onAddConnection() {
                    selectAccountDialog.onAddAccount(mContext);
                }
            }).setTitle(mContext.getString(R.string.accounts)).setTheme(mActivity.getThemeId())
                    .show(mActivity.getSupportFragmentManager(), "choose_ngw_account");
        }
    }

    @Override
    public void onLayerAdded(int id) {
        notifyDataChanged();
    }

    @Override
    public void onLayerDeleted(int id) {
        notifyDataChanged();
    }

    @Override
    public void onLayerChanged(int id) {
        notifyDataChanged();
    }

    @Override
    public void onExtentChanged(float zoom, GeoPoint center) {

    }

    @Override
    public void onLayersReordered() {
        notifyDataChanged();
    }

    @Override
    public void onLayerDrawFinished(int id, float percent) {

    }

    @Override
    public void onLayerDrawStarted() {

    }

    void notifyDataChanged() {
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                notifyDataSetChanged();
            }
        });
    }

    public void setDrawer(DrawerLayout drawer) {
        mDrawer = drawer;
    }

    public void swapElements(int originalPosition, int newPosition) {
        //Log.d(TAG,
        //      "Original position: " + originalPosition + " Destination position: " + newPosition);
        if (null == mMap) {
            return;
        }
        int newPositionFixed = getCount() - 1 - newPosition;
        mMap.moveLayer(newPositionFixed, (com.nextgis.maplib.api.ILayer) getItem(originalPosition));
        notifyDataSetChanged();
    }

    public void endDrag() {
        if (null == mMap) {
            return;
        }
        mMap.save();

        mMap.thaw();
        mMap.runDraw(null);
    }

    void beginDrag() {
        if (null == mMap) {
            return;
        }
        mMap.freeze();
    }
}