/* * Copyright (C) 2009 Virgil Dobjanschi, Jeff Sharkey * * 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 no.java.schedule.activities.adapters; import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.os.Handler; import android.provider.BaseColumns; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.ImageView; import android.widget.TextView; import no.java.schedule.R; import no.java.schedule.activities.adapters.beans.Session; import no.java.schedule.activities.adapters.listitems.*; import no.java.schedule.provider.SessionsContract.Blocks; import no.java.schedule.provider.SessionsContract.BlocksColumns; import no.java.schedule.provider.SessionsContract.SessionsColumns; import no.java.schedule.provider.SessionsContract.TracksColumns; import no.java.schedule.util.StringUtils; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import static no.java.schedule.activities.adapters.listitems.ListItem.TYPE.BLOCK; /** * The sessions_menu adapter */ public class SessionsAdapter extends BaseAdapter { private static final boolean NO_BLOCK_HEADERS = false; public static final boolean DISPLAY_DAY = NO_BLOCK_HEADERS; private static final boolean CREATE_BLOCK_HEADERS = true; private static final SimpleDateFormat FORMAT = new SimpleDateFormat("EEE HH:mm"); public enum MODE{SCHEDULE,STARRED,SESSION_AGGREGATE_VIEW}; private enum BLOCK_HEADERS{YES,NO} private final MODE mode; private final Context context; private final List<ListItem> listItems; private final View.OnClickListener startListener; private final Uri uri; private final String selection; private final String[] selectionArgs; private final String sortOrder; private ContentObserver contentObserver; public SessionsAdapter(Context context, Uri uri, String selection, String[] selectionArgs, String sortOrder, MODE mode) { this.context = context; listItems = new ArrayList<ListItem>(); this.uri = uri; this.selection = selection; this.selectionArgs = selectionArgs; this.sortOrder = sortOrder; this.mode = mode; buildItems(); startListener = new StarredSessionListener(context); contentObserver = new ContentObserver(new Handler()) { @Override public void onChange(boolean selfChange) { buildItems(); notifyDataSetChanged(); } }; this.context.getContentResolver().registerContentObserver(this.uri, CREATE_BLOCK_HEADERS, contentObserver); } /** * Release the adapter */ public void close() { listItems.clear(); if (contentObserver != null) { context.getContentResolver().unregisterContentObserver(contentObserver); contentObserver = null; } } public ListItem getItemByPosition(int position) { return listItems.get(position); } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public int getCount() { return listItems.size(); } @Override public boolean areAllItemsEnabled() { return NO_BLOCK_HEADERS; } @Override public boolean isEnabled(int position) { switch (listItems.get(position).getType()) { case DAY: case BLOCK: return NO_BLOCK_HEADERS; default: return CREATE_BLOCK_HEADERS; } } @Override public int getViewTypeCount() { return 4; } @Override public int getItemViewType(int position) { ListItem listItem = listItems.get(position); return listItem.getType().ordinal(); } public View getView(int position, View view, ViewGroup parent) { ListItem listItem = listItems.get(position); if (view == null) { view = inflateView(view, listItem); } switch (listItem.getType()) { case DAY: setDayValues(view,listItem); break; case BLOCK: setBlockValues(view,listItem); break; case SESSION: setSessionValues(view,listItem); break; case SESSION_AGGREGATE_HEADER: setSessionAggregateHeaderValues(view,listItem); case EMPTY_BLOCK: default: break; } return view; } private void setSessionAggregateHeaderValues(View view, ListItem listItem) { SessionAggreateHeaderListItem headerListItem = (SessionAggreateHeaderListItem) listItem; ((TextView) view.findViewById(R.id.text_sep)).setText(headerListItem.getTitle()); ((ImageView) view.findViewById(R.id.image_sep)).setImageResource(R.drawable.ic_menu_agenda); } private void setSessionValues(View view, ListItem listItem) { Session session = ((SessionListItem) listItem).getSessionItem(); view.findViewById(R.id.session_color).setBackgroundColor(session.getColor()); ((TextView) view.findViewById(R.id.session_title)).setText(session.getTitle()); ((CheckBox) view.findViewById(R.id.session_star)).setTag(session); ((CheckBox) view.findViewById(R.id.session_star)).setOnClickListener(startListener); ((CheckBox) view.findViewById(R.id.session_star)).setChecked(session.isStarred()); ((TextView) view.findViewById(R.id.session_speakers)).setText(session.getSpeakers()); ((TextView) view.findViewById(R.id.session_track)).setText(session.getTrack()); ((TextView) view.findViewById(R.id.session_track)).setTextColor( session.getColor()); ((TextView) view.findViewById(R.id.session_room)).setText(session.getRoom()); } private void setBlockValues(View view, ListItem listItem) { BlockListItem tsi = (BlockListItem) listItem; ((TextView) view.findViewById(R.id.text_sep)).setText(tsi.getTime()); ((ImageView) view.findViewById(R.id.image_sep)).setImageResource(R.drawable.ic_dialog_time); } private void setDayValues(View view, ListItem listItem) { ((TextView) view.findViewById(R.id.text_sep)).setText(((DayListItem) listItem).getDay()); } private View inflateView(View view, ListItem listItem) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); switch (listItem.getType()) { case DAY: { view = inflater.inflate(R.layout.day_separator_row_view, null); break; } case BLOCK: { view = inflater.inflate(R.layout.time_slot_separator_row_view, null); break; } case SESSION: { view = inflater.inflate(R.layout.session_row, null); break; } case SESSION_AGGREGATE_HEADER: { view = inflater.inflate(R.layout.session_aggregate_header, null); break; } case EMPTY_BLOCK: { view = inflater.inflate(R.layout.empty_time_slot_row_view, null); break; } default: { break; } } return view; } private void buildItems() { listItems.clear(); switch (mode){ case STARRED: listItems.addAll(buildStarredItems()); return; case SESSION_AGGREGATE_VIEW: listItems.addAll(buildAllItems(BLOCK_HEADERS.NO)); listItems.add(0, createHeading(listItems,"Lightning talks starting %s in room %s")); return; case SCHEDULE: listItems.addAll(buildAllItems(BLOCK_HEADERS.NO)); listItems.add(0, createHeading(listItems,"Sessions starting %s in room %s")); return; default: listItems.addAll(buildAllItems(BLOCK_HEADERS.YES)); return; } } private SessionAggreateHeaderListItem createHeading(List<ListItem> items, final String format) { final Session sessionItem = ((SessionListItem) items.get(0)).getSessionItem(); final String timeAsString = StringUtils.getTimeAsString( context, FORMAT, sessionItem.getStartTime()); String heading = String.format(format, timeAsString, sessionItem.getRoom()); return new SessionAggreateHeaderListItem(heading); } private List<ListItem> buildAllItems(BLOCK_HEADERS createBlockHeaders) { List<ListItem> newListOfItems = new ArrayList<ListItem>(); Cursor cursor = context.getContentResolver().query(uri, null, selection, selectionArgs, sortOrder); if (cursor != null) { if (cursor.moveToFirst()) { long lastBlockStartTime = -1; do { if(createBlockHeaders == BLOCK_HEADERS.YES){ long startTime = cursor.getLong(cursor.getColumnIndexOrThrow(BlocksColumns.TIME_START)); createBlockHeaderIfNeeded(cursor,lastBlockStartTime,newListOfItems); lastBlockStartTime = startTime; } newListOfItems.add(createSessionListItem(cursor)); } while (cursor.moveToNext()); } cursor.close(); } return newListOfItems; } private void addDayHeaderIfNeccesary() { /*if( DISPLAY_DAY) { Date di = new Date( startTime*1000); if (di.getDay() != day) { day = di.getDay(); newListOfItems.add(new DayListItem(context, startTime)); } } */ } private void createBlockHeaderIfNeeded(Cursor cursor, long lastBlockStartTime, List<ListItem> newListOfItems) { if (lastBlockStartTime != cursor.getLong(cursor.getColumnIndexOrThrow(BlocksColumns.TIME_START))) { newListOfItems.add(new BlockListItem( context, BLOCK, cursor.getLong(cursor.getColumnIndexOrThrow(BlocksColumns.TIME_START)), cursor.getLong(cursor.getColumnIndexOrThrow(BlocksColumns.TIME_END))) ); } } private SessionListItem createSessionListItem(Cursor cursor) { return new SessionListItem( new Session( context, cursor.getInt(cursor.getColumnIndexOrThrow(BaseColumns._ID)), cursor.getLong(cursor.getColumnIndexOrThrow(BlocksColumns.TIME_START)), cursor.getLong(cursor.getColumnIndexOrThrow(BlocksColumns.TIME_END)), cursor.getString(cursor.getColumnIndexOrThrow(SessionsColumns.TITLE)), cursor.getString(cursor.getColumnIndexOrThrow(SessionsColumns.SPEAKER_NAMES)), cursor.getString(cursor.getColumnIndexOrThrow(SessionsColumns.ROOM)), cursor.getString(cursor.getColumnIndexOrThrow(TracksColumns.TRACK)), cursor.getInt(cursor.getColumnIndexOrThrow(TracksColumns.COLOR)), cursor.getInt(cursor.getColumnIndexOrThrow(SessionsColumns.STARRED)) == 1, cursor.getString(cursor.getColumnIndexOrThrow(SessionsColumns.TYPE)) ) ); } private List<ListItem> buildStarredItems() { //TODO refactor this to reuse code from buildAllItems - code is identical List<ListItem> newListOfItems = new ArrayList<ListItem>(); List<SessionListItem> list = new ArrayList<SessionListItem>(); populateWithSessions(list); Cursor blockCursor = context.getContentResolver().query(Blocks.CONTENT_URI, null, null, null, null); if (blockCursor != null) { if (blockCursor.moveToFirst()) { int day = 0; do { long startTime = blockCursor.getLong(blockCursor.getColumnIndexOrThrow(BlocksColumns.TIME_START)); long endTime = blockCursor.getLong(blockCursor.getColumnIndexOrThrow(BlocksColumns.TIME_END)); //addDayHeaderIfNeccesary(); newListOfItems.add(new BlockListItem(context, BLOCK, startTime, endTime)); boolean foundSession = NO_BLOCK_HEADERS; while (list.size() > 0 && !foundSession) { final Session sessionItem = list.get(0).getSessionItem(); if (sessionItem.getStartTime() == startTime && sessionItem.getEndTime() == endTime) { newListOfItems.add(list.remove(0)); foundSession = CREATE_BLOCK_HEADERS; } } if (!foundSession) { newListOfItems.add(new EmptyBlockListItem(context, startTime, endTime)); } } while (blockCursor.moveToNext()); } blockCursor.close(); } return newListOfItems; } private void populateWithSessions(List<SessionListItem> list) { Cursor cursor = context.getContentResolver().query(uri, null, selection, selectionArgs, sortOrder); if (cursor != null) { if (cursor.moveToFirst()) { do { list.add(createSessionListItem(cursor)); } while (cursor.moveToNext()); } cursor.close(); } } }