org.alfresco.mobile.android.application.fragments.sync.SyncCursorAdapter.java Source code

Java tutorial

Introduction

Here is the source code for org.alfresco.mobile.android.application.fragments.sync.SyncCursorAdapter.java

Source

/*
 *  Copyright (C) 2005-2015 Alfresco Software Limited.
 *
 *  This file is part of Alfresco Mobile for Android.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.alfresco.mobile.android.application.fragments.sync;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.alfresco.mobile.android.application.R;
import org.alfresco.mobile.android.application.activity.MainActivity;
import org.alfresco.mobile.android.application.fragments.DisplayUtils;
import org.alfresco.mobile.android.application.fragments.node.details.NodeDetailsFragment;
import org.alfresco.mobile.android.async.OperationRequest.OperationBuilder;
import org.alfresco.mobile.android.async.Operator;
import org.alfresco.mobile.android.async.node.sync.SyncNodeRequest;
import org.alfresco.mobile.android.platform.mimetype.MimeType;
import org.alfresco.mobile.android.platform.mimetype.MimeTypeManager;
import org.alfresco.mobile.android.platform.utils.AccessibilityUtils;
import org.alfresco.mobile.android.platform.utils.SessionUtils;
import org.alfresco.mobile.android.sync.SyncContentManager;
import org.alfresco.mobile.android.sync.SyncContentSchema;
import org.alfresco.mobile.android.sync.operations.SyncContentStatus;
import org.alfresco.mobile.android.ui.fragments.BaseCursorLoader;
import org.alfresco.mobile.android.ui.holder.TwoLinesProgressViewHolder;
import org.alfresco.mobile.android.ui.rendition.RenditionManager;
import org.alfresco.mobile.android.ui.utils.Formatter;
import org.alfresco.mobile.android.ui.utils.UIUtils;

import android.annotation.TargetApi;
import android.content.Context;
import android.database.Cursor;
import android.os.Build;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnDismissListener;
import android.widget.PopupMenu.OnMenuItemClickListener;

/**
 * @since 1.2
 * @author Jean Marie Pascal
 */
public class SyncCursorAdapter extends BaseCursorLoader<TwoLinesProgressViewHolder>
        implements OnMenuItemClickListener {
    private static final String TAG = SyncCursorAdapter.class.getName();

    private WeakReference<Fragment> fragmentRef;

    private List<String> selectedItems;

    private int mode;

    private List<String> selectedOptionItems = new ArrayList<String>();

    private List<Long> selectedOptionItemId = new ArrayList<Long>();

    private boolean hasSynchroActive;

    public SyncCursorAdapter(Fragment fr, Cursor c, int layoutResourceId, List<String> selectedItems, int mode) {
        super(fr.getActivity(), c, layoutResourceId);
        this.fragmentRef = new WeakReference<Fragment>(fr);
        this.selectedItems = selectedItems;
        this.mode = mode;
        vhClassName = TwoLinesProgressViewHolder.class.getCanonicalName();
        hasSynchroActive = SyncContentManager.getInstance(fr.getActivity())
                .hasActivateSync(SessionUtils.getAccount(context));
    }

    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        // Specific part for dynaminc resize
        // int[] layouts = GridAdapterHelper.getGridLayoutId(context,
        // (GridFragment) fragmentRef.get());
        return createView(context, cursor, R.layout.row_two_lines_progress);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        // int[] layouts = GridAdapterHelper.getGridLayoutId(context,
        // (GridFragment) fragmentRef.get());
        if (view.findViewById(R.id.app_grid_progress) == null) {
            // ((ViewGroup) view).removeAllViews();
            view.invalidate();
            view.refreshDrawableState();
            return;
        }
        TwoLinesProgressViewHolder vh = (TwoLinesProgressViewHolder) view.getTag();
        updateControls(vh, cursor);
    }

    protected void updateIcon(TwoLinesProgressViewHolder vh, Cursor cursor) {
        if (SyncContentManager.isFolder(cursor)) {
            vh.icon.setImageResource(R.drawable.mime_256_folder);
        } else {
            MimeType mime = MimeTypeManager.getInstance(context)
                    .getMimetype(cursor.getString(SyncContentSchema.COLUMN_TITLE_ID));

            if (SessionUtils.getSession(context) != null) {
                RenditionManager.with(fragmentRef.get().getActivity())
                        .loadNode(cursor.getString(SyncContentSchema.COLUMN_NODE_ID_ID))
                        .placeHolder(mime != null ? mime.getLargeIconId(context)
                                : MimeTypeManager.getInstance(context)
                                        .getIcon(cursor.getString(SyncContentSchema.COLUMN_TITLE_ID), true))
                        .into(vh.icon);
            } else {
                vh.icon.setImageResource(mime != null ? mime.getLargeIconId(context)
                        : MimeTypeManager.getInstance(context)
                                .getIcon(cursor.getString(SyncContentSchema.COLUMN_TITLE_ID), true));
            }

            if (mime != null) {
                AccessibilityUtils.addContentDescription(vh.icon, mime.getDescription());
            } else {
                AccessibilityUtils.removeContentDescription(vh.icon);
            }
        }

    }

    protected void updateBottomText(TwoLinesProgressViewHolder vh, final Cursor cursor) {
        int status = cursor.getInt(SyncContentSchema.COLUMN_STATUS_ID);
        String nodeId = cursor.getString(SyncContentSchema.COLUMN_NODE_ID_ID);
        long favoriteId = cursor.getLong(SyncContentSchema.COLUMN_ID_ID);
        boolean syncRoot = cursor.getInt(SyncContentSchema.COLUMN_IS_SYNC_ROOT_ID) > 0;

        if (syncRoot) {
            vh.favoriteIcon.setVisibility(View.VISIBLE);
            vh.favoriteIcon.setImageResource(R.drawable.ic_sync_light);
        } else {
            vh.favoriteIcon.setVisibility(View.GONE);
        }

        vh.progress.setVisibility(View.GONE);
        switch (status) {
        case SyncContentStatus.STATUS_PENDING:
            displayStatut(vh, R.drawable.sync_status_pending);
            break;
        case SyncContentStatus.STATUS_RUNNING:
            displayStatut(vh, R.drawable.sync_status_loading);
            vh.progress.setVisibility(View.VISIBLE);
            vh.favoriteIcon.setVisibility(View.GONE);
            long totalSize = cursor.getLong(SyncContentSchema.COLUMN_TOTAL_SIZE_BYTES_ID);
            if (totalSize == -1) {
                vh.progress.setIndeterminate(true);
            } else {
                long progress = cursor.getLong(SyncContentSchema.COLUMN_BYTES_DOWNLOADED_SO_FAR_ID);
                float value = (((float) progress / ((float) totalSize)) * 100);
                int percentage = Math.round(value);
                vh.progress.setIndeterminate(false);
                vh.progress.setMax(100);
                vh.progress.setProgress(percentage);
            }
            break;
        case SyncContentStatus.STATUS_HIDDEN:
            vh.favoriteIcon.setVisibility(View.GONE);
            vh.iconRight.setVisibility(View.GONE);
            break;
        case SyncContentStatus.STATUS_PAUSED:
            displayStatut(vh, R.drawable.sync_status_pending);
            break;
        case SyncContentStatus.STATUS_MODIFIED:
            displayStatut(vh, R.drawable.sync_status_pending);
            break;
        case SyncContentStatus.STATUS_SUCCESSFUL:
            displayStatut(vh, R.drawable.sync_status_success);
            break;
        case SyncContentStatus.STATUS_FAILED:
            displayStatut(vh, R.drawable.sync_status_failed);
            break;
        case SyncContentStatus.STATUS_CANCEL:
            displayStatut(vh, R.drawable.sync_status_failed);
            break;
        case SyncContentStatus.STATUS_REQUEST_USER:
            displayStatut(vh, R.drawable.sync_status_failed);
            break;
        default:
            break;
        }

        if (selectedItems != null && selectedItems.contains(nodeId)) {
            UIUtils.setBackground(((View) vh.icon.getParent()),
                    context.getResources().getDrawable(R.drawable.list_longpressed_holo));
        } else {
            UIUtils.setBackground(((View) vh.icon.getParent()), null);
        }

        if (SyncContentStatus.STATUS_RUNNING != status) {
            vh.bottomText.setVisibility(View.VISIBLE);
            vh.bottomText.setText(createContentBottomText(context, cursor));
            AccessibilityUtils.addContentDescription(vh.bottomText,
                    createContentDescriptionBottomText(context, cursor));
        } else {
            vh.bottomText.setVisibility(View.GONE);
        }

        if (mode == SyncFragment.MODE_LISTING && fragmentRef.get().getActivity() instanceof MainActivity) {
            if (status != SyncContentStatus.STATUS_REQUEST_USER) {
                UIUtils.setBackground(vh.choose, null);
                return;
            }

            vh.choose.setImageResource(R.drawable.ic_more_options);
            vh.choose.setBackgroundResource(R.drawable.alfrescohololight_list_selector_holo_light);
            int d_16 = DisplayUtils.getPixels(context, R.dimen.d_16);
            vh.choose.setPadding(d_16, d_16, d_16, d_16);

            vh.choose.setVisibility(View.VISIBLE);
            vh.choose.setTag(R.id.node_action, nodeId);
            vh.choose.setTag(R.id.favorite_id, favoriteId);
            vh.choose.setTag(R.id.operation_status, status);
            vh.choose.setTag(R.id.is_synced, syncRoot);
            AccessibilityUtils.addContentDescription(vh.choose,
                    String.format(context.getString(R.string.more_options_favorite),
                            cursor.getString(SyncContentSchema.COLUMN_TITLE_ID)));
            vh.choose.setOnClickListener(new OnClickListener() {
                @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
                @Override
                public void onClick(View v) {
                    String item = (String) v.getTag(R.id.node_action);
                    Integer statut = (Integer) v.getTag(R.id.operation_status);
                    long favoriteId = (Long) v.getTag(R.id.favorite_id);
                    boolean rootSynced = (Boolean) v.getTag(R.id.is_synced);

                    selectedOptionItems.add(item);
                    selectedOptionItemId.add(favoriteId);

                    PopupMenu popup = new PopupMenu(context, v);
                    getMenu(popup.getMenu(), statut, rootSynced);
                    popup.setOnDismissListener(new OnDismissListener() {
                        @Override
                        public void onDismiss(PopupMenu menu) {
                            selectedOptionItems.clear();
                        }
                    });

                    popup.setOnMenuItemClickListener(SyncCursorAdapter.this);

                    popup.show();
                }
            });
        } else {
            UIUtils.setBackground(vh.choose, null);
        }
    }

    private String createContentBottomText(Context context, Cursor cursor) {
        String s = "";

        if (cursor.getLong(SyncContentSchema.COLUMN_SERVER_MODIFICATION_TIMESTAMP_ID) != -1) {
            s = Formatter.formatToRelativeDate(context,
                    new Date(cursor.getLong(SyncContentSchema.COLUMN_SERVER_MODIFICATION_TIMESTAMP_ID)));
            long size = cursor.getLong(SyncContentSchema.COLUMN_TOTAL_SIZE_BYTES_ID);
            if (size > 0) {
                s += " - " + Formatter.formatFileSize(context, size);
            }
        }

        return s;
    }

    private String createContentDescriptionBottomText(Context context, Cursor cursor) {
        StringBuilder s = new StringBuilder();

        s.append(context.getString(R.string.metadata_modified));
        s.append(Formatter.formatToRelativeDate(context,
                new Date(cursor.getLong(SyncContentSchema.COLUMN_SERVER_MODIFICATION_TIMESTAMP_ID))));
        long size = cursor.getLong(SyncContentSchema.COLUMN_TOTAL_SIZE_BYTES_ID);
        if (size > 0) {
            s.append(" - ");
            s.append(context.getString(R.string.metadata_size));
            s.append(Formatter.formatFileSize(context, size));
        }
        return s.toString();
    }

    protected void updateTopText(TwoLinesProgressViewHolder vh, Cursor cursor) {
        vh.topText.setText(cursor.getString(SyncContentSchema.COLUMN_TITLE_ID));
    }

    protected void displayStatut(TwoLinesProgressViewHolder vh, int imageResource) {
        if (hasSynchroActive) {
            vh.iconRight.setVisibility(View.VISIBLE);
            vh.iconRight.setImageResource(imageResource);
        } else {
            vh.iconRight.setVisibility(View.GONE);
        }
    }

    // ///////////////////////////////////////////////////////////////////////////
    // MENU
    // ///////////////////////////////////////////////////////////////////////////
    public void getMenu(Menu menu, Integer statut, boolean rootSynced) {
        MenuItem mi;

        switch (statut) {
        case SyncContentStatus.STATUS_HIDDEN:
            mi = menu.add(Menu.NONE, R.id.menu_action_favorite_group, Menu.FIRST, R.string.favorite);
            mi.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
            break;
        case SyncContentStatus.STATUS_FAILED:
        case SyncContentStatus.STATUS_REQUEST_USER:
            mi = menu.add(Menu.NONE, R.id.menu_sync_resolution, Menu.FIRST, R.string.sync_resolve_conflict);
            mi.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
            break;
        default:
            if (rootSynced) {
                mi = menu.add(Menu.NONE, R.id.menu_action_sync_group_unsync, Menu.FIRST, R.string.unsync);
                mi.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
            }
            break;
        }
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        boolean onMenuItemClick = true;
        List<OperationBuilder> requestsBuilder = new ArrayList<OperationBuilder>(selectedOptionItems.size());

        switch (item.getItemId()) {
        case R.id.menu_action_sync_group_sync:
            for (String nodeId : selectedOptionItems) {
                requestsBuilder.add(new SyncNodeRequest.Builder(nodeId, true, true));
            }
            Operator.with(context, SessionUtils.getAccount(context)).load(requestsBuilder);
            onMenuItemClick = true;
            break;
        case R.id.menu_action_sync_group_unsync:
            for (String nodeId : selectedOptionItems) {
                requestsBuilder.add(new SyncNodeRequest.Builder(nodeId, false, true));
            }
            Operator.with(context, SessionUtils.getAccount(context)).load(requestsBuilder);
            onMenuItemClick = true;
            break;
        case R.id.menu_sync_resolution:
            onMenuItemClick = true;
            ResolveConflictSyncDialogFragment.newInstance(selectedOptionItemId.get(0)).show(
                    fragmentRef.get().getActivity().getSupportFragmentManager(),
                    ResolveConflictSyncDialogFragment.TAG);
            selectedOptionItemId.clear();
            break;
        case R.id.menu_node_details:
            onMenuItemClick = true;
            NodeDetailsFragment.with((FragmentActivity) context).nodeId(selectedOptionItems.get(0)).display();
            selectedItems.clear();
            selectedItems.add(selectedOptionItems.get(0));
            notifyDataSetChanged();
            break;
        default:
            onMenuItemClick = false;
            break;
        }
        selectedOptionItems.clear();
        return onMenuItemClick;
    }

    public void refresh() {
        hasSynchroActive = SyncContentManager.getInstance(context)
                .hasActivateSync(SessionUtils.getAccount(context));
    }

    public List<String> getNodes() {
        ArrayList<String> nodes = new ArrayList<>(getCount());
        getCursor().moveToFirst();
        getCursor().moveToPrevious();
        while (getCursor().moveToNext()) {
            String nodeId = getCursor().getString(SyncContentSchema.COLUMN_NODE_ID_ID);
            nodes.add(nodeId);
        }
        return nodes;
    }
}