dev.drsoran.moloko.fragments.TaskFragment.java Source code

Java tutorial

Introduction

Here is the source code for dev.drsoran.moloko.fragments.TaskFragment.java

Source

/* 
 *   Copyright (c) 2013 Ronny Rhricht
 *
 *   This file is part of Moloko.
 *
 *   Moloko is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   Moloko 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with Moloko.  If not, see <http://www.gnu.org/licenses/>.
 *
 *   Contributors:
 * Ronny Rhricht - implementation
 */

package dev.drsoran.moloko.fragments;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.content.Loader;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;

import dev.drsoran.moloko.IOnSettingsChangedListener;
import dev.drsoran.moloko.R;
import dev.drsoran.moloko.annotations.InstanceState;
import dev.drsoran.moloko.format.MolokoDateFormatter;
import dev.drsoran.moloko.format.RtmStyleTaskDescTextViewFormatter;
import dev.drsoran.moloko.fragments.base.IAbsViewPagerSupport;
import dev.drsoran.moloko.fragments.base.MolokoLoaderFragment;
import dev.drsoran.moloko.fragments.listeners.ITaskFragmentListener;
import dev.drsoran.moloko.fragments.listeners.NullTaskFragmentListener;
import dev.drsoran.moloko.layouts.TitleWithTextLayout;
import dev.drsoran.moloko.loaders.TaskLoader;
import dev.drsoran.moloko.util.MenuItemPreparer;
import dev.drsoran.moloko.util.UIUtils;
import dev.drsoran.moloko.util.parsing.RecurrenceParsing;
import dev.drsoran.moloko.widgets.SimpleLineView;
import dev.drsoran.rtm.Participant;
import dev.drsoran.rtm.ParticipantList;
import dev.drsoran.rtm.Task;

public class TaskFragment extends MolokoLoaderFragment<Task> implements IAbsViewPagerSupport {
    public final int FULL_DATE_FLAGS = MolokoDateFormatter.FORMAT_WITH_YEAR;

    public static class Config {
        public final static String TASK_ID = "task_id";
    }

    private boolean enableAbsViewPagerWorkaround;

    private ITaskFragmentListener listener;

    @InstanceState(key = Config.TASK_ID)
    private String taskId;

    private ViewGroup content;

    private SimpleLineView priorityBar;

    private TextView addedDate;

    private TextView completedDate;

    private TextView source;

    private TextView postponed;

    private TextView description;

    private TextView listName;

    private ViewGroup tagsLayout;

    private View dateTimeSection;

    private View locationSection;

    private ViewGroup participantsSection;

    private TitleWithTextLayout urlSection;

    public final static TaskFragment newInstance(Bundle config) {
        final TaskFragment fragment = new TaskFragment();

        fragment.setArguments(config);

        return fragment;
    }

    public TaskFragment() {
        registerAnnotatedConfiguredInstance(this, TaskFragment.class);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        enableAbsViewPagerWorkaround = getResources().getBoolean(R.bool.env_enable_abs_viewpager_workaround);

        super.onCreate(savedInstanceState);
        setHasOptionsMenu(!enableAbsViewPagerWorkaround);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        if (activity instanceof ITaskFragmentListener)
            listener = (ITaskFragmentListener) activity;
        else
            listener = new NullTaskFragmentListener();
    }

    @Override
    public void onDetach() {
        listener = null;
        super.onDetach();
    }

    @Override
    public View createFragmentView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View fragmentView = inflater.inflate(R.layout.task_fragment, container, false);

        content = (ViewGroup) fragmentView.findViewById(android.R.id.content);
        priorityBar = (SimpleLineView) content.findViewById(R.id.task_overview_priority_bar);
        addedDate = (TextView) content.findViewById(R.id.task_overview_added_date);
        completedDate = (TextView) content.findViewById(R.id.task_overview_completed_date);
        source = (TextView) content.findViewById(R.id.task_overview_src);
        postponed = (TextView) content.findViewById(R.id.task_overview_postponed);
        description = (TextView) content.findViewById(R.id.task_overview_desc);
        listName = (TextView) content.findViewById(R.id.task_overview_list_name);
        tagsLayout = (ViewGroup) content.findViewById(R.id.task_overview_tags);
        dateTimeSection = content.findViewById(R.id.task_dateTime);
        locationSection = content.findViewById(R.id.task_location);
        participantsSection = (ViewGroup) content.findViewById(R.id.task_participants);
        urlSection = (TitleWithTextLayout) content.findViewById(R.id.task_url);

        return fragmentView;
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        if (!enableAbsViewPagerWorkaround) {
            onCreateOptionsMenuImpl(menu, inflater);
        }
    }

    @Override
    public boolean onCreateOptionsMenuViewPagerSupportWorkaround(Menu menu, MenuInflater inflater) {
        onCreateOptionsMenuImpl(menu, inflater);
        return true;
    }

    private void onCreateOptionsMenuImpl(Menu menu, MenuInflater inflater) {
        final Task task = getLoaderData();
        if (task != null && isWritableAccess()) {
            inflater.inflate(R.menu.task_fragment_rwd, menu);
        }
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        if (!enableAbsViewPagerWorkaround) {
            onPrepareOptionsMenuImpl(menu);
        }
    }

    @Override
    public boolean onPrepareOptionsMenuViewPagerSupportWorkaround(Menu menu) {
        onPrepareOptionsMenuImpl(menu);
        return true;
    }

    private void onPrepareOptionsMenuImpl(Menu menu) {
        final Task task = getLoaderData();
        if (task != null) {
            final boolean taskIsCompleted = task.getCompleted() != null;
            final MenuItemPreparer preparer = new MenuItemPreparer(menu);

            preparer.setVisible(R.id.menu_complete_selected_tasks, !taskIsCompleted);
            preparer.setVisible(R.id.menu_uncomplete_selected_tasks, taskIsCompleted);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (!enableAbsViewPagerWorkaround) {
            return onOptionsItemSelectedImpl(item);
        } else {
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public boolean onOptionsItemSelectedViewPagerSupportWorkaround(MenuItem item) {
        return onOptionsItemSelectedImpl(item);
    }

    private boolean onOptionsItemSelectedImpl(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_complete_selected_tasks:
            listener.onCompleteTask(getLoaderDataAssertNotNull());
            return true;

        case R.id.menu_uncomplete_selected_tasks:
            listener.onIncompleteTask(getLoaderDataAssertNotNull());
            return true;

        case R.id.menu_postpone_selected_tasks:
            listener.onPostponeTask(getLoaderDataAssertNotNull());
            return true;

        case R.id.menu_delete_selected:
            listener.onDeleteTask(getLoaderDataAssertNotNull());
            return true;

        case R.id.menu_edit_selected:
            listener.onEditTask(getLoaderDataAssertNotNull());

        default:
            return false;
        }
    }

    public String getTaskId() {
        return taskId;
    }

    @Override
    public void initContentAfterDataLoaded(ViewGroup container) {
        final Task task = getLoaderDataAssertNotNull();
        final SherlockFragmentActivity activity = getSherlockActivity();

        UIUtils.setPriorityColor(activity, priorityBar, task);

        addedDate.setText(MolokoDateFormatter.formatDateTime(activity, task.getAdded().getTime(), FULL_DATE_FLAGS));

        if (task.getCompleted() != null) {
            completedDate.setVisibility(View.VISIBLE);
            completedDate.setText(
                    MolokoDateFormatter.formatDateTime(activity, task.getCompleted().getTime(), FULL_DATE_FLAGS));
        } else {
            completedDate.setVisibility(View.GONE);
        }

        if (task.getPosponed() > 0) {
            postponed.setText(getString(R.string.task_postponed, task.getPosponed()));
            postponed.setVisibility(View.VISIBLE);
        } else
            postponed.setVisibility(View.GONE);

        if (!TextUtils.isEmpty(task.getSource())) {
            String sourceStr = task.getSource();
            if (sourceStr.equalsIgnoreCase("js"))
                sourceStr = "web";

            source.setText(getString(R.string.task_source, sourceStr));
        } else
            source.setText("?");

        RtmStyleTaskDescTextViewFormatter.setTaskDescription(description, task, null);

        listName.setText(task.getListName());

        UIUtils.inflateTags(activity, tagsLayout, task.getTags(), null);

        setDateTimeSection(dateTimeSection, task);

        setLocationSection(locationSection, task);

        setParticipantsSection(participantsSection, task);

        if (!TextUtils.isEmpty(task.getUrl())) {
            urlSection.setVisibility(View.VISIBLE);
            urlSection.setText(task.getUrl());
        } else {
            urlSection.setVisibility(View.GONE);
        }

        activity.invalidateOptionsMenu();
    }

    private void setDateTimeSection(View view, Task task) {
        final boolean hasDue = task.getDue() != null;
        final boolean hasEstimate = !TextUtils.isEmpty(task.getEstimate());
        final boolean isRecurrent = !TextUtils.isEmpty(task.getRecurrence());

        // Check if we need this section
        if (!hasEstimate && !hasDue && !isRecurrent) {
            view.setVisibility(View.GONE);
        } else {
            view.setVisibility(View.VISIBLE);

            final StringBuilder textBuffer = new StringBuilder();

            if (hasDue) {
                if (task.hasDueTime())
                    UIUtils.appendAtNewLine(textBuffer, MolokoDateFormatter.formatDateTime(getSherlockActivity(),
                            task.getDue().getTime(),
                            MolokoDateFormatter.FORMAT_WITH_YEAR | MolokoDateFormatter.FORMAT_SHOW_WEEKDAY));
                else
                    UIUtils.appendAtNewLine(textBuffer, MolokoDateFormatter.formatDate(getSherlockActivity(),
                            task.getDue().getTime(),
                            MolokoDateFormatter.FORMAT_WITH_YEAR | MolokoDateFormatter.FORMAT_SHOW_WEEKDAY));

            }

            if (isRecurrent) {
                final String sentence = RecurrenceParsing.parseRecurrencePattern(getSherlockActivity(),
                        task.getRecurrence(), task.isEveryRecurrence());

                // In this case we add the 'repeat' to the beginning of the pattern, otherwise
                // the 'repeat' will be the header of the section.
                if (hasDue || hasEstimate) {
                    UIUtils.appendAtNewLine(textBuffer, getString(R.string.task_datetime_recurr_inline,
                            (sentence != null ? sentence : getString(R.string.task_datetime_err_recurr))));
                } else {
                    UIUtils.appendAtNewLine(textBuffer,
                            (sentence != null ? sentence : getString(R.string.task_datetime_err_recurr)));
                }

            }

            if (hasEstimate) {
                UIUtils.appendAtNewLine(textBuffer, getString(R.string.task_datetime_estimate_inline,
                        MolokoDateFormatter.formatEstimated(getSherlockActivity(), task.getEstimateMillis())));
            }

            // Determine the section title
            int titleId;

            if (hasDue)
                titleId = R.string.task_datetime_title_due;
            else if (hasEstimate)
                titleId = R.string.task_datetime_title_estimate;
            else
                titleId = R.string.task_datetime_title_recurr;

            UIUtils.initializeTitleWithTextLayout(view, getString(titleId), textBuffer.toString());
        }
    }

    private void setLocationSection(View view, final Task task) {
        String locationName = null;

        boolean showSection = !TextUtils.isEmpty(task.getLocationId());

        if (showSection) {
            // Tasks which are received by sharing from someone else may also have
            // a location ID set. But this ID is from the other ones DB. We identify
            // these tasks not by looking for the ID in our DB. These tasks do not
            // have a name and a location of 0.0, 0.0.
            //
            // @see: Issue 12: http://code.google.com/p/moloko/issues/detail?id=12
            locationName = task.getLocationName();

            showSection = !TextUtils.isEmpty(locationName) || Float.compare(task.getLongitude(), 0.0f) != 0
                    || Float.compare(task.getLatitude(), 0.0f) != 0;
        }

        if (!showSection) {
            view.setVisibility(View.GONE);
        } else {
            view.setVisibility(View.VISIBLE);

            if (TextUtils.isEmpty(locationName)) {
                locationName = "Lon: " + task.getLongitude() + ", Lat: " + task.getLatitude();
            }

            boolean locationIsClickable = task.isLocationViewable();

            if (locationIsClickable) {
                final SpannableString clickableLocation = new SpannableString(locationName);
                UIUtils.initializeTitleWithTextLayoutAsLink(view, getString(R.string.task_location),
                        clickableLocation, new ClickableSpan() {
                            @Override
                            public void onClick(View widget) {
                                listener.onOpenLocation(task);
                            }
                        });
            } else {
                UIUtils.initializeTitleWithTextLayout(view, getString(R.string.task_location), locationName);
            }
        }
    }

    private void setParticipantsSection(ViewGroup view, Task task) {
        final ParticipantList participants = task.getParticipants();

        if (participants != null && participants.getCount() > 0) {
            view.setVisibility(View.VISIBLE);

            for (final Participant participant : participants.getParticipants()) {
                final TextView textView = new TextView(getSherlockActivity());
                UIUtils.makeLink(textView, participant.getFullname(), new ClickableSpan() {
                    @Override
                    public void onClick(View widget) {
                        listener.onOpenContact(participant.getFullname(), participant.getUsername());
                    }
                });

                view.addView(textView);
            }
        } else {
            view.setVisibility(View.GONE);
        }
    }

    @Override
    public Loader<Task> newLoaderInstance(int id, Bundle args) {
        return new TaskLoader(getSherlockActivity(), args.getString(Config.TASK_ID));
    }

    @Override
    public String getLoaderDataName() {
        return getString(R.string.app_task);
    }

    @Override
    public int getLoaderId() {
        return TaskLoader.ID;
    }

    @Override
    public int getSettingsMask() {
        return IOnSettingsChangedListener.DATE_TIME_RELATED;
    }

    public Task getTask() {
        return getLoaderData();
    }

    public Task getTaskAssertNotNull() {
        return getLoaderDataAssertNotNull();
    }
}