diff options
Diffstat (limited to 'vdrmanager/src')
38 files changed, 3760 insertions, 1031 deletions
diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/app/Intents.java b/vdrmanager/src/de/bjusystems/vdrmanager/app/Intents.java new file mode 100644 index 0000000..9b113e8 --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/app/Intents.java @@ -0,0 +1,7 @@ +package de.bjusystems.vdrmanager.app; + +public interface Intents { + + public static final String CURRENT_CHANNEL = "CURRENT_CHANNEL"; + +} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/app/VdrManagerApp.java b/vdrmanager/src/de/bjusystems/vdrmanager/app/VdrManagerApp.java index e60d396..fd84f25 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/app/VdrManagerApp.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/app/VdrManagerApp.java @@ -22,7 +22,16 @@ public class VdrManagerApp extends Application { private Epg currentEvent; private Timer currentTimer; private Channel currentChannel; - private List<Channel> channels; + + private ArrayList<Epg> currentEpgList = new ArrayList<Epg>(); + public ArrayList<Epg> getCurrentEpgList() { + return currentEpgList; + } + + public void setCurrentEpgList(ArrayList<Epg> currentEpgList) { + this.currentEpgList = currentEpgList; + } + private EpgSearchParams currentSearch; private Class<? extends Activity> nextActivity; private final List<Activity> activitiesToFinish = new ArrayList<Activity>(); @@ -32,13 +41,13 @@ public class VdrManagerApp extends Application { public void onCreate() { super.onCreate(); } - + public void clear() { this.currentEvent = null; this.currentTimer = null; this.currentChannel = null; this.currentSearch = null; - + this.currentEpgList = null; this.epgListState = EpgListState.EPG_TIME; } @@ -75,13 +84,6 @@ public class VdrManagerApp extends Application { this.epgListState = EpgListState.EPG_CHANNEL; } - public List<Channel> getChannels() { - return channels; - } - - public void setChannels(final List<Channel> channels) { - this.channels = channels; - } public EpgSearchParams getCurrentSearch() { return currentSearch; diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/BaseEvent.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/BaseEvent.java new file mode 100644 index 0000000..d681ea6 --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/BaseEvent.java @@ -0,0 +1,95 @@ +package de.bjusystems.vdrmanager.data; + +import java.util.Date; + +import android.text.TextUtils; + +public abstract class BaseEvent implements Event { + + protected Event event; + protected String channelNumber; + protected String channelName; + protected String title; + protected String shortText; + protected String description; + protected Date start; + protected Date stop; + + public Event getEvent() { + return event; + } + + public void setEvent(Event event) { + this.event = event; + } + + public void setChannelNumber(String channelNumber) { + this.channelNumber = channelNumber; + } + + public void setChannelName(String channelName) { + this.channelName = channelName; + } + + public void setTitle(String title) { + this.title = title; + } + + public void setShortText(String shortText) { + this.shortText = shortText; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setStart(Date start) { + this.start = start; + } + + public void setStop(Date stop) { + this.stop = stop; + } + + public BaseEvent(Event event) { + this.event = event; + } + + public String getChannelNumber() { + return channelNumber; + } + + public String getChannelName() { + return channelName; + } + + public String getTitle() { + return title; + } + + public String getShortText() { + if (TextUtils.isEmpty(shortText) == false) { + return shortText; + } + if (TextUtils.isEmpty(description) == false) { + if (description.length() < 20) { + return description; + } + return TextUtils.substring(description, 0, 20) + "…"; + } + return shortText; + } + + public String getDescription() { + return description; + } + + public Date getStart() { + return start; + } + + public Date getStop() { + return stop; + } + +} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/Channel.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/Channel.java index 29215e4..eeda768 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/data/Channel.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/Channel.java @@ -1,6 +1,9 @@ package de.bjusystems.vdrmanager.data; -public class Channel { +import android.os.Parcel; +import android.os.Parcelable; + +public class Channel implements Parcelable { private final int number; private final String name; @@ -24,6 +27,12 @@ public class Channel { this.provider = "Unknown"; } + public Channel(Parcel in) { + this.number = in.readInt(); + this.name = in.readString(); + this.provider = in.readString(); + } + public boolean isGroupSeparator() { return number == 0; } @@ -46,8 +55,28 @@ public class Channel { text.append(number); text.append(" - "); text.append(name); - text.append(" : "); - text.append(provider); + // text.append(" : "); + // text.append(provider); return text.toString(); } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(number); + dest.writeString(name); + dest.writeString(provider); + } + + public static final Parcelable.Creator<Channel> CREATOR = new Parcelable.Creator<Channel>() { + public Channel createFromParcel(Parcel in) { + return new Channel(in); + } + + public Channel[] newArray(int size) { + return new Channel[size]; + } + }; } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/Epg.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/Epg.java index e228565..d9d07b0 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/data/Epg.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/Epg.java @@ -6,18 +6,13 @@ import java.util.Date; * Class for EPG events * @author bju */ -public class Epg implements Event { +public class Epg extends BaseEvent { - private final String channelNumber; - private final String channelName; - private final String title; - private final String description; - private final Date start; - private final Date stop; private Timer timer; public Epg(final String line) { - + super(null); + final String[] words = line.split(":"); channelNumber = words[0].substring(1); @@ -26,26 +21,9 @@ public class Epg implements Event { stop = new Date(Long.parseLong(words[3])*1000); title = words[4]; description = words.length > 5 ? words[5] : ""; + shortText = words.length > 6 ? words[6] : ""; } - - public String getChannelNumber() { - return channelNumber; - } - public String getChannelName() { - return channelName; - } - public String getTitle() { - return title; - } - public String getDescription() { - return description; - } - public Date getStart() { - return start; - } - public Date getStop() { - return stop; - } + public Timer getTimer() { return timer; diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/Event.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/Event.java index 6fa192d..8bf9270 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/data/Event.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/Event.java @@ -8,13 +8,16 @@ public interface Event { None, Active, Inactive, - Recording + Recording, + Recorded + ; } String getChannelNumber(); String getChannelName(); String getTitle(); String getDescription(); + String getShortText(); Date getStart(); Date getStop(); TimerState getTimerState(); diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/EventFormatter.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/EventFormatter.java index 430bca4..f4dc41e 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/data/EventFormatter.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/EventFormatter.java @@ -5,22 +5,51 @@ import de.bjusystems.vdrmanager.utils.date.DateFormatter; public class EventFormatter { private String time; + private final String stop; private final String date; private final String longDate; private final String title; + private final String shortText; private final String description; public EventFormatter(final Event event) { + this(event,false); + } + /** + * @param event + * @param onlyStartTime Event Time is rendered as 'start - stop' if false + */ + public EventFormatter(final Event event, boolean onlyStartTime) { DateFormatter formatter = new DateFormatter(event.getStart()); this.date = formatter.getDateString(); this.longDate = formatter.getDailyHeader(); this.time = formatter.getTimeString(); formatter = new DateFormatter(event.getStop()); - this.time += " - " + formatter.getTimeString(); - this.title = event.getTitle().replace("|##", ":").replace("||#", "\n"); - this.description = event.getDescription().replace("|##", ":").replace("||#", "\n"); + this.stop = formatter.getTimeString(); + if(onlyStartTime == false){ + this.time += " - " + stop; + } + this.title = mapSpecialChars(event.getTitle()); + this.shortText = mapSpecialChars(event.getShortText()); + this.description = mapSpecialChars(event.getDescription()); + } + + private static String mapSpecialChars(String src){ + if(src == null){ + return ""; + } + return src.replace("|##", ":").replace("||#", "\n"); } + public String getShortText() { + return shortText; + } + + + public String getStop(){ + return stop; + } + public String getTime() { return time; } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/EventListItem.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/EventListItem.java index b9370a1..18829f5 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/data/EventListItem.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/EventListItem.java @@ -2,33 +2,48 @@ package de.bjusystems.vdrmanager.data; import java.util.Date; +import de.bjusystems.vdrmanager.gui.Utils; -public class EventListItem implements Event { +public class EventListItem extends BaseEvent { + + private final Recording rec; private final Timer timer; private final Epg epg; private final String header; - private final Event event; + + + + public EventListItem(final Recording rec) { + super(rec); + this.header = null; + this.rec = rec; + this.epg = null; + this.timer = null; + } public EventListItem(final Timer timer) { + super(timer); this.header = null; this.timer = timer; this.epg = null; - this.event = timer; + this.rec = null; } public EventListItem(final Epg epg) { + super(epg); this.header = null; this.timer = null; this.epg = epg; - this.event = epg; + this.rec = null; } public EventListItem(final String header) { + super(null); this.header = header; this.timer = null; this.epg = null; - this.event = null; + this.rec = null; } public boolean isHeader() { @@ -82,6 +97,10 @@ public class EventListItem implements Event { public Event getEvent() { return event; } + + public boolean isLive(){ + return Utils.isLive(event); + } @Override public String toString() { @@ -97,4 +116,8 @@ public class EventListItem implements Event { text.append("Zeit: ").append(formatter.getDate()).append(" ").append(formatter.getTime()); return text.toString(); } + + public String getShortText() { + return event != null ? event.getShortText() : null; + } }
\ No newline at end of file diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/Preferences.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/Preferences.java index 9bb7c13..9b61417 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/data/Preferences.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/Preferences.java @@ -2,10 +2,12 @@ package de.bjusystems.vdrmanager.data; import android.content.Context; import android.content.SharedPreferences; +import android.test.IsolatedContext; import de.bjusystems.vdrmanager.R; /** * Class for all preferences + * * @author bju */ public class Preferences { @@ -29,6 +31,19 @@ public class Preferences { private String wakeupUser; /** Password for wakeup */ private String wakeupPassword; + /** + * vdr mac for wol + * + * @since 0.2 + */ + private String vdrMac; + /** + * which wakeup method to use + * + * @since 0.2 + * + */ + private String wakeupMethod; /** Check for running VDR is enabled */ private boolean aliveCheckEnabled; /** Intervall for alive test */ @@ -43,24 +58,69 @@ public class Preferences { private int timerDefaultLifetime; /** user defined epg search times */ private String epgSearchTimes; - + /** + * Which port to use for streaming + * + * @since 0.2 + */ private int streamPort = 3000; - - public int getStreamPort() { - return streamPort; - } - - public String getStreamFormat() { - return streamFormat; - } + /** + * Which format to use for streaming + * + * @since 0.2 + */ private String streamFormat = "TS"; + /** + * format times AM/PM or 24H + * + * @since 0.2 + */ + private boolean use24hFormat; + + /** + * Do not send broadcasts, send directly to the host (router problem) + * @since 0.2 + */ + private String wolCustomBroadcast = ""; + + /** + * Whether to show channel numbers in the overviews + * @since 0.2 + */ + private boolean showChannelNumbers = false; + + /** Properties singleton */ private static Preferences thePrefs; + + /** + * Whether to send Packets to the custom broadcast address. + * It is used, if the address ist not empty + * + * @return + * @since 0.2 + */ + public String getWolCustomBroadcast() { + return wolCustomBroadcast; + } + + + /** + * Getter for use24hFormat + * + * @since 0.2 + * @return + */ + public boolean isUse24hFormat() { + return use24hFormat; + } + /** * Checks for connect using SSL + * * @return true, if use SSL connections */ public boolean isSSL() { @@ -69,6 +129,7 @@ public class Preferences { /** * Retrieves the channel filtering mode + * * @return true, if channels will be filtered */ public boolean isFilterChannels() { @@ -77,6 +138,7 @@ public class Preferences { /** * Last channel to receive + * * @return channel number */ public String getChannels() { @@ -85,6 +147,7 @@ public class Preferences { /** * Gets the SVDRP host or IP address + * * @return SVDRP host */ public String getSvdrpHost() { @@ -93,6 +156,7 @@ public class Preferences { /** * Gets the SVDRP port + * * @return SVDRP port */ public int getSvdrpPort() { @@ -101,6 +165,7 @@ public class Preferences { /** * Gets the SVDRP password + * * @return SVDRO password */ public String getPassword() { @@ -109,6 +174,7 @@ public class Preferences { /** * Checks for enables remote wakeup + * * @return true, if remote wakeup is enabled */ public boolean isWakeupEnabled() { @@ -117,6 +183,7 @@ public class Preferences { /** * Gets the URL for the wakeup request + * * @return wakeup url */ public String getWakeupUrl() { @@ -125,6 +192,7 @@ public class Preferences { /** * Gets the user for the wakeup url + * * @return user name */ public String getWakeupUser() { @@ -133,6 +201,7 @@ public class Preferences { /** * Gets the password for the wakeup url + * * @return password */ public String getWakeupPassword() { @@ -141,6 +210,7 @@ public class Preferences { /** * Checks for enabled alive check + * * @return true, if enabled */ public boolean isAliveCheckEnabled() { @@ -149,6 +219,7 @@ public class Preferences { /** * Gets the time between alive checks + * * @return time in seconds */ public int getAliveCheckInterval() { @@ -157,6 +228,7 @@ public class Preferences { /** * Gets the buffer before the event start + * * @return pre event buffer */ public int getTimerPreMargin() { @@ -165,6 +237,7 @@ public class Preferences { /** * Gets the buffer after the event stop + * * @return post event buffer */ public int getTimerPostMargin() { @@ -173,6 +246,7 @@ public class Preferences { /** * Gets the default priority + * * @return default priority */ public int getTimerDefaultPriority() { @@ -181,6 +255,7 @@ public class Preferences { /** * Gets the default lifetime + * * @return default lifetime */ public int getTimerDefaultLifetime() { @@ -189,21 +264,66 @@ public class Preferences { /** * Gets the time values for the epg search + * * @return */ public String getEpgSearchTimes() { - return epgSearchTimes; + return epgSearchTimes; + } + + /** + * gets the MAC Address of the vdr host + * + * @return + * @since 0.2 + */ + public String getVdrMac() { + return vdrMac; + } + + /** + * Gets the selection which wakeup method to use + * + * @return + * @since 0.2 + */ + public String getWakeupMethod() { + return wakeupMethod; + } + + /** + * Getter for streaming port + * + * @return + * @since 02. + */ + public int getStreamPort() { + return streamPort; + } + + /** + * Getter for selected streaming format + * + * @return + * @since 0.2 + */ + public String getStreamFormat() { + return streamFormat; } /** * Sets the time values for the epg search - * @param epgSearchTimes new time values + * + * @param epgSearchTimes + * new time values */ - public void setEpgSearchTimes(final Context context, final String epgSearchTimes) { + public void setEpgSearchTimes(final Context context, + final String epgSearchTimes) { final SharedPreferences prefs = getSharedPreferences(context); final SharedPreferences.Editor editor = prefs.edit(); - editor.putString(context.getString(R.string.epg_search_times_key), epgSearchTimes); + editor.putString(context.getString(R.string.epg_search_times_key), + epgSearchTimes); editor.commit(); // reload @@ -212,104 +332,177 @@ public class Preferences { /** * Gets the name for the file which preferences will be saved into - * @param context Context + * + * @param context + * Context * @return filename */ public static String getPreferenceFile(final Context context) { return context.getString(R.string.app_name); } + + + + + /** + * Show Channel Numbers in the overviews + * @since 0.2 + * @return + */ + public boolean isShowChannelNumbers() { + return showChannelNumbers; + } + /** * Gets the previous loaded preferences + * * @return preferences */ public static Preferences getPreferences() { return thePrefs; } + + /** + * + * Gets the previous loaded preferences, same as getPreferences(); + * + * @return + */ + public static Preferences get(){ + return thePrefs; + } /** * Loads all preferences - * @param context Context + * + * @param context + * Context * @return Preferences */ public static void loadPreferences(final Context context) { - final SharedPreferences sharedPrefs = getSharedPreferences(context); - final Preferences prefs = new Preferences(); - prefs.svdrpHost = getString(context, sharedPrefs, R.string.vdr_host_key, "127.0.0.1"); - prefs.svdrpPort = getInt(context, sharedPrefs, R.string.vdr_port_key, 6419); - prefs.password = getString(context, sharedPrefs, R.string.vdr_password_key, ""); - prefs.ssl = getBoolean(context, sharedPrefs, R.string.vdr_ssl_key, false); - prefs.streamPort = getInt(context, sharedPrefs, R.string.vdr_stream_port, 3000); - prefs.streamFormat= getString(context, sharedPrefs, R.string.vdr_stream_format, "TS"); + prefs.svdrpHost = getString(context, R.string.vdr_host_key, "0.0.0.0"); + prefs.svdrpPort = getInt(context, R.string.vdr_port_key, 6419); + prefs.password = getString(context, R.string.vdr_password_key, ""); + prefs.ssl = getBoolean(context, R.string.vdr_ssl_key, false); + prefs.streamPort = getInt(context, R.string.vdr_stream_port, 3000); + prefs.streamFormat = getString(context, R.string.vdr_stream_format, + "TS"); + + prefs.aliveCheckEnabled = getBoolean(context, + R.string.alive_check_enabled_key, false); + prefs.aliveCheckInterval = getInt(context, + R.string.alive_check_interval_key, 60); + + prefs.channels = getString(context, R.string.channel_filter_last_key, + "").replace(" ", ""); + prefs.filterChannels = getBoolean(context, + R.string.channel_filter_filter_key, false); + + prefs.wakeupEnabled = getBoolean(context, R.string.wakeup_enabled_key, + false); + prefs.wakeupUrl = getString(context, R.string.wakeup_url_key, ""); + prefs.wakeupUser = getString(context, R.string.wakeup_user_key, ""); + prefs.wakeupPassword = getString(context, R.string.wakeup_password_key, + ""); + + prefs.timerPreMargin = getInt(context, + R.string.timer_pre_start_buffer_key, 5); + prefs.timerPostMargin = getInt(context, + R.string.timer_post_end_buffer_key, 30); + prefs.timerDefaultPriority = getInt(context, + R.string.timer_default_priority_key, 99); + prefs.timerDefaultLifetime = getInt(context, + R.string.timer_default_lifetime_key, 99); + + prefs.epgSearchTimes = getString(context, + R.string.epg_search_times_key, ""); + + prefs.vdrMac = getString(context, R.string.wakeup_wol_mac_key, ""); + prefs.wakeupMethod = getString(context, R.string.wakeup_method_key, + "url"); + + prefs.use24hFormat = getBoolean(context, + R.string.gui_enable_24h_format_key, true); - prefs.aliveCheckEnabled = getBoolean(context, sharedPrefs, R.string.alive_check_enabled_key, false); - prefs.aliveCheckInterval = getInt(context, sharedPrefs, R.string.alive_check_interval_key, 60); - - prefs.channels = getString(context, sharedPrefs, R.string.channel_filter_last_key, "").replace(" ", ""); - prefs.filterChannels = getBoolean(context, sharedPrefs, R.string.channel_filter_filter_key, false); - - prefs.wakeupEnabled = getBoolean(context, sharedPrefs, R.string.wakeup_enabled_key, false); - prefs.wakeupUrl = getString(context, sharedPrefs, R.string.wakeup_url_key, ""); - prefs.wakeupUser = getString(context, sharedPrefs, R.string.wakeup_user_key, ""); - prefs.wakeupPassword = getString(context, sharedPrefs, R.string.wakeup_password_key, ""); - - prefs.timerPreMargin = getInt(context, sharedPrefs, R.string.timer_pre_start_buffer_key, 5); - prefs.timerPostMargin = getInt(context, sharedPrefs, R.string.timer_post_end_buffer_key, 30); - prefs.timerDefaultPriority = getInt(context, sharedPrefs, R.string.timer_default_priority_key, 99); - prefs.timerDefaultLifetime = getInt(context, sharedPrefs, R.string.timer_default_lifetime_key, 99); - - prefs.epgSearchTimes = getString(context, sharedPrefs, R.string.epg_search_times_key, ""); + prefs.wolCustomBroadcast = getString(context, R.string.wakeup_wol_custom_broadcast_key, ""); + prefs.showChannelNumbers = getBoolean(context, R.string.gui_channels_show_channel_numbers_key, false); + thePrefs = prefs; } /** * Gets the persistent preferences - * @param context Context + * + * @param context + * Context * @return preferences */ - private static SharedPreferences getSharedPreferences(final Context context) { - - return context.getSharedPreferences(getPreferenceFile(context), Context.MODE_PRIVATE); + public static SharedPreferences getSharedPreferences(final Context context) { + return context.getSharedPreferences(getPreferenceFile(context), + Context.MODE_PRIVATE); } /** * Helper for retrieving integer values from preferences - * @param context Context - * @param sharedPrefs Object for the preference file - * @param resId ressource id of the preferences name - * @param defValue default value + * + * @param context + * Context + * @param resId + * ressource id of the preferences name + * @param defValue + * default value * @return value or the default value if not defined */ - private static int getInt(final Context context, final SharedPreferences sharedPrefs, final int resId, final int defValue) { - final String value = getString(context, sharedPrefs, resId, String.valueOf(defValue)); + private static int getInt(final Context context, final int resId, + final int defValue) { + final String value = getString(context, resId, String.valueOf(defValue)); return Integer.parseInt(value); } /** * Helper for retrieving boolean values from preferences - * @param context Context - * @param sharedPrefs Object for the preference file - * @param resId ressource id of the preferences name - * @param defValue default value + * + * @param context + * Context + * @param resId + * ressource id of the preferences name + * @param defValue + * default value * @return value or the default value if not defined */ - private static boolean getBoolean(final Context context, final SharedPreferences sharedPrefs, final int resId, final boolean defValue) { + private static boolean getBoolean(final Context context, final int resId, + final boolean defValue) { + final SharedPreferences sharedPrefs = getSharedPreferences(context); return sharedPrefs.getBoolean(context.getString(resId), defValue); } + /** * Helper for retrieving string values from preferences - * @param context Context - * @param sharedPrefs Object for the preference file - * @param resId ressource id of the preferences name - * @param defValue default value + * + * @param context + * Context + * @param resId + * ressource id of the preferences name + * @param defValue + * default value * @return value or the default value if not defined */ - private static String getString(final Context context, final SharedPreferences sharedPrefs, final int resId, final String defValue) { + private static String getString(final Context context, final int resId, + final String defValue) { + final SharedPreferences sharedPrefs = getSharedPreferences(context); return sharedPrefs.getString(context.getString(resId), defValue); } + + public String getTimeFormat() { + if (isUse24hFormat()) { + return "HH:mm"; + } + return "h:mm a"; + } } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/Recording.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/Recording.java new file mode 100644 index 0000000..c3e418f --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/Recording.java @@ -0,0 +1,34 @@ +package de.bjusystems.vdrmanager.data; + +import java.util.Date; + + +public class Recording extends BaseEvent{ + + public Recording(String line) { + super(null); + final String[] words = line.split(":"); + start = new Date(Long.parseLong(words[0])*1000); + stop = new Date(Long.parseLong(words[0] + 1000 * 60 * 60 * 2)*1000); + channelName = words[2]; + title = words[3]; + shortText = words[4]; + description = words[5]; + fileName = words[6]; + } + + private String fileName; + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public TimerState getTimerState() { + return TimerState.Recorded; + } + +} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/Timer.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/Timer.java index 8ce34d5..20a0975 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/data/Timer.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/Timer.java @@ -8,7 +8,7 @@ import java.util.GregorianCalendar; * Class for timer data * @author bju */ -public class Timer implements Event { +public class Timer extends BaseEvent { private static final int ENABLED = 1; private static final int INSTANT = 2; @@ -17,12 +17,6 @@ public class Timer implements Event { private final int number; private int flags; - private String title; - private String description; - private Date start; - private Date stop; - private final String channelNumber; - private final String channelName; private final int priority; private final int lifetime; @@ -33,6 +27,7 @@ public class Timer implements Event { * @param channels list of channels */ public Timer(final String timerData) { + super(null); final String[] values = timerData.split(":"); @@ -58,6 +53,7 @@ public class Timer implements Event { } public Timer(final Epg event) { + super(event); final Preferences prefs = Preferences.getPreferences(); @@ -99,42 +95,10 @@ public class Timer implements Event { return line.toString(); } - public String getDescription() { - return description; - } - - public void setDescription(final String description) { - this.description = description; - } - public int getNumber() { return number; } - - public Date getStart() { - return start; - } - - public Date getStop() { - return stop; - } - - public String getTitle() { - return title; - } - - public void setTitle(final String title) { - this.title = title; - } - - public String getChannelNumber() { - return channelNumber; - } - - public String getChannelName() { - return channelName; - } - + public int getPriority() { return priority; } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseActivity.java new file mode 100644 index 0000000..629f2a6 --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseActivity.java @@ -0,0 +1,105 @@ +package de.bjusystems.vdrmanager.gui; + +import de.bjusystems.vdrmanager.R; +import de.bjusystems.vdrmanager.app.VdrManagerApp; +import de.bjusystems.vdrmanager.data.Channel; +import android.app.Activity; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; + +public abstract class BaseActivity extends Activity implements OnClickListener{ + + + public static final int MENU_GROUP_REFRESH = 99; + + public static final int MENU_REFRESH = 99; + + abstract protected int getMainLayout(); + + protected void switchNoConnection(){ + View view = findViewById(R.id.main_content); + if(view != null){ + view.setVisibility(View.GONE); + } + findViewById(R.id.no_connection_layout).setVisibility(View.VISIBLE); + Button b = (Button) findViewById(R.id.retry_button); + b.setOnClickListener(this); + } + + public void onClick(View v) { + if(v.getId() == R.id.retry_button){ + findViewById(R.id.no_connection_layout).setVisibility(View.GONE); + View view = findViewById(R.id.main_content); + if(view != null){ + view.setVisibility(View.VISIBLE); + } + retry(); + } + } + + protected void updateWindowTitle(int topic, int subtopic) { + String title; + title = getString(topic); + if (subtopic != -1) { + title += " > " + getString(subtopic); + } + setTitle(title); + } + + protected void updateWindowTitle(String topic, String subtopic) { + String title = topic; + if (subtopic != null) { + title += " > " + subtopic; + } + setTitle(title); + } + + + @Override + public boolean onCreateOptionsMenu(final Menu menu) { + MenuItem item; + item = menu.add(MENU_GROUP_REFRESH, MENU_REFRESH, 0, R.string.refresh); + item.setIcon(android.R.drawable.ic_menu_rotate); + item.setAlphabeticShortcut('r'); + return true; + } + + abstract protected void refresh(); + + abstract protected void retry(); + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case MENU_REFRESH: + refresh(); + return true; + + default: + return false; + } + } + + + protected void setAsCurrent(Channel channel) { + getApp().setCurrentChannel(channel); + } + + + protected VdrManagerApp getApp(){ + final VdrManagerApp app = (VdrManagerApp) getApplication(); + return app; + } + + //protected Channel getCurrentChannel(){ + //final Channel channel = ((VdrManagerApp) getApplication()) + //.getCurrentChannel(); + //return channel; +// } + + + +} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseEpgListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseEpgListActivity.java new file mode 100644 index 0000000..e304009 --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseEpgListActivity.java @@ -0,0 +1,273 @@ +package de.bjusystems.vdrmanager.gui; + +import java.util.Date; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListView; +import de.bjusystems.vdrmanager.R; +import de.bjusystems.vdrmanager.app.Intents; +import de.bjusystems.vdrmanager.data.Channel; +import de.bjusystems.vdrmanager.data.Epg; +import de.bjusystems.vdrmanager.data.EventFormatter; +import de.bjusystems.vdrmanager.data.EventListItem; +import de.bjusystems.vdrmanager.tasks.DeleteTimerTask; +import de.bjusystems.vdrmanager.tasks.ToggleTimerTask; +import de.bjusystems.vdrmanager.utils.svdrp.EpgClient; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpEvent; + +public abstract class BaseEpgListActivity extends BaseActivity { + + + private static final int REQUEST_CODE_TIMED_EDIT = 41; + + protected EpgClient epgClient; + + protected EventAdapter adapter; + + protected SvdrpProgressDialog progress; + + protected static final Date FUTURE = new Date(Long.MAX_VALUE); + + //private static final Date BEGIN = new Date(0); + + + protected Channel currentChannel = null; + + protected ListView listView; + + + + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + initChannel(); + } + + private void initChannel(){ + currentChannel = getIntent().getParcelableExtra(Intents.CURRENT_CHANNEL); + } + + protected void deleteTimer(final EventListItem item) { + + final DeleteTimerTask task = new DeleteTimerTask(this, item.getEpg() + .getTimer()) { + @Override + public void finished() { + refresh(); + } + }; + task.start(); + } + + + + @Override + public boolean onCreateOptionsMenu(final Menu menu) { + super.onCreateOptionsMenu(menu); + + final MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.epg_list_menu, menu); + return true; + } + + protected void prepareTimer(EventListItem event){ + + } + + @Override + public boolean onContextItemSelected(final MenuItem item) { + + final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item + .getMenuInfo(); + final EventListItem event = adapter.getItem(info.position); + + switch (item.getItemId()) { + case R.id.epg_item_menu_timer_add: + case R.id.epg_item_menu_timer_modify: { + prepareTimer(event); + final Intent intent = new Intent(); + intent.setClass(this, TimerDetailsActivity.class); + startActivityForResult(intent, REQUEST_CODE_TIMED_EDIT); + break; + } + case R.id.epg_item_menu_timer_delete: { + deleteTimer(event); + break; + } + case R.id.epg_item_menu_timer_toggle: { + toggleTimer(event); + break; + } + case R.id.epg_item_menu_live_tv: { + Utils.stream(this, event.getEvent()); + break; + + } + } + + return true; + } + + public boolean onOptionsItemSelected(final MenuItem item) { + + Intent intent; + + switch (item.getItemId()) { + case R.id.epg_menu_search: + intent = new Intent(); + intent.setClass(this, EpgSearchActivity.class); + startActivity(intent); + break; + case R.id.epg_menu_times: + intent = new Intent(); + intent.setClass(this, EpgSearchTimesListActivity.class); + startActivity(intent); + break; + } + return super.onOptionsItemSelected(item); + } + + + @Override + public void onCreateContextMenu(final ContextMenu menu, final View v, + final ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + + if (v.getId() == R.id.whatson_list) { + final MenuInflater inflater = getMenuInflater(); + final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; + + // set menu title + final EventListItem item = adapter.getItem(info.position); + final EventFormatter formatter = new EventFormatter(item); + menu.setHeaderTitle(formatter.getTitle()); + + inflater.inflate(R.menu.epg_list_item_menu, menu); + + // remove unneeded menu items + if (item.getEpg().getTimer() != null) { + menu.findItem(R.id.epg_item_menu_timer_add).setVisible(false); + menu.findItem(R.id.epg_item_menu_timer_modify).setVisible(true); + menu.findItem(R.id.epg_item_menu_timer_delete).setVisible(true); + final MenuItem enableMenuItem = menu + .findItem(R.id.epg_item_menu_timer_toggle); + enableMenuItem.setVisible(true); + enableMenuItem + .setTitle(item.getEpg().getTimer().isEnabled() ? R.string.epg_item_menu_timer_disable + : R.string.epg_item_menu_timer_enable); + } + + if (item.isLive()) { + menu.findItem(R.id.epg_item_menu_live_tv).setVisible(true); + } + + } + + } + + + protected void toggleTimer(final EventListItem item) { + final ToggleTimerTask task = new ToggleTimerTask(this, item.getEpg() + .getTimer()) { + @Override + public void finished() { + refresh(); + } + }; + task.start(); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == REQUEST_CODE_TIMED_EDIT) { + if (resultCode == Activity.RESULT_OK) { + refresh(); + } + } + } + + public void onItemClick(final AdapterView<?> parent, final View view, + final int position, final long id) { + + // find and remember item + final EventListItem item = adapter.getItem(position); + + if (item.isHeader()) { + return; + } + + // prepare timer if we want to program + prepareTimer(item); + + // show details + final Intent intent = new Intent(); + intent.setClass(this, EpgDetailsActivity.class); + startActivity(intent); + } + + + @Override + protected void onPause() { + super.onPause(); + if (epgClient != null) { + epgClient.abort(); + } + if (progress != null) { + progress.dismiss(); + progress = null; + } + } + + + public void svdrpEvent(final SvdrpEvent event, final Epg result) { + + if (progress != null) { + progress.svdrpEvent(event); + } + + switch (event) { + case CONNECTING: + break; + case CONNECT_ERROR: + case FINISHED_ABNORMALY: + case LOGIN_ERROR: + switchNoConnection(); + break; + case FINISHED_SUCCESS: + finishedSuccess(); + break; + case RESULT_RECEIVED: + break; + } + } + + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + int index = savedInstanceState.getInt("INDEX"); + int top = savedInstanceState.getInt("TOP"); + listView.setSelectionFromTop(index, top); + } + @Override + protected void onSaveInstanceState(Bundle outState) { + int index = listView.getFirstVisiblePosition(); + View v = listView.getChildAt(0); + int top = (v == null) ? 0 : v.getTop(); + outState.putInt("INDEX", index); + outState.putInt("TOP", top); + super.onSaveInstanceState(outState); + } + + protected abstract void finishedSuccess(); + +} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelAdapter.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelAdapter.java index c609813..8140cc0 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelAdapter.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelAdapter.java @@ -1,39 +1,207 @@ package de.bjusystems.vdrmanager.gui; import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; import android.content.Context; import android.graphics.Color; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ArrayAdapter; +import android.widget.BaseExpandableListAdapter; +import android.widget.Filter; +import android.widget.Filterable; import android.widget.ImageView; import android.widget.TextView; import de.bjusystems.vdrmanager.R; import de.bjusystems.vdrmanager.data.Channel; +import de.bjusystems.vdrmanager.data.Preferences; -class ChannelAdapter extends ArrayAdapter<Channel> { +class ChannelAdapter extends BaseExpandableListAdapter implements Filterable// , + // SectionIndexer +{ - private final LayoutInflater inflater; - private final List<Channel> items; + @Override + public boolean areAllItemsEnabled() { + return true; + } + + private Context context; + + Map<String, ArrayList<Channel>> channels = new HashMap<String, ArrayList<Channel>>(); - public ChannelAdapter(final Context context) { - super(context, R.layout.channel_item); + ArrayList<String> groups = new ArrayList<String>(); + + private boolean showChannelNumber; + + public ChannelAdapter(Context context) { + this.context = context; inflater = LayoutInflater.from(context); - items = new ArrayList<Channel>(); + this.showChannelNumber = Preferences.get().isShowChannelNumbers(); } - @Override - public View getView(final int position, final View convertView, final ViewGroup parent) { + private LayoutInflater inflater; + + private int groupBy = -1; + + public void fill(ArrayList<String> groups, + Map<String, ArrayList<Channel>> data, int groupBy) { + this.groupBy = groupBy; + this.groups.clear(); + this.groups.addAll(groups); + channels.clear(); + channels.putAll(data); + // sections = new Object[groups.size()]; + // for(int i = 0; i < groups.size(); ++i){ + // String g = groups.get(i); + // /if(g.length() > 0){ + // sections[i] = g.subSequence(0, 1); + // } else { + // sections[i] = ""; + // } + // } + notifyDataSetChanged(); + + } + + // public ChannelAdapter(final Context context) { + // super(context, R.layout.channel_item); + // inflater = LayoutInflater.from(context); + // // items = new ArrayList<Channel>(); + // } + + // @Override + // public View getView(final int position, final View convertView, + // final ViewGroup parent) { + // + // ChannelHolder itemHolder = new ChannelHolder(); + // + // // recycle view? + // View view = convertView; + // if (view == null) { + // view = inflater.inflate(R.layout.channel_item, null); + // itemHolder = new ChannelHolder(); + // + // itemHolder.name = (TextView) view.findViewById(R.id.channel_name); + // itemHolder.type = (ImageView) view.findViewById(R.id.channel_type); + // + // view.setTag(itemHolder); + // } else { + // itemHolder = (ChannelHolder) view.getTag(); + // } + // + // // get item + // final Channel item = getItem(position); + // + // // fill item + // if (item.isGroupSeparator()) { + // view.setPadding(view.getPaddingLeft(), 0, view.getPaddingRight(), 0); + // view.setBackgroundColor(Color.DKGRAY); + // itemHolder.type.setVisibility(View.GONE); + // itemHolder.name.setVisibility(View.VISIBLE); + // itemHolder.name.setText(item.getName()); + // itemHolder.name.setPadding(0, 0, 0, 0); + // } else { + // view.setBackgroundColor(Color.BLACK); + // itemHolder.type.setVisibility(View.VISIBLE); + // itemHolder.type.setVisibility(View.VISIBLE); + // itemHolder.name.setText(item.toString()); + // } + // + // return view; + // } + + // + // public void addItem(final Channel channel) { + // items.add(channel); + // } + // + // public void clearItems() { + // items.clear(); + // } + + // public int getPositionForSection(int section) { + // // Log.v("getPositionForSection", ""+section); + // String letter = sections[section]; + // + // return alphaIndexer.get(letter); + // } + // + // public int getSectionForPosition(int position) { + // + // // you will notice it will be never called (right?) + // Log.v("getSectionForPosition", "called"); + // return 0; + // } + // + // public Object[] getSections() { + // + // if (sections == null) { + // alphaIndexer = new HashMap<String, Integer>(); + // int size = getCount(); + // for (int i = 0; i < size; ++i) { + // Channel element = getItem(i); + // alphaIndexer.put(element.getName().substring(0, 1), i); + // // We store the first letter of the word, and its index. + // // The Hashmap will replace the value for identical keys are + // // putted in + // } + // + // // now we have an hashmap containing for each first-letter + // // sections(key), the index(value) in where this sections begins + // + // // we have now to build the sections(letters to be displayed) + // // array .it must contains the keys, and must (I do so...) be + // // ordered alphabetically + // + // Set<String> keys = alphaIndexer.keySet(); // set of letters ...sets + // // cannot be sorted... + // + // Iterator<String> it = keys.iterator(); + // ArrayList<String> keyList = new ArrayList<String>(); // list can be + // // sorted + // + // while (it.hasNext()) { + // String key = it.next(); + // keyList.add(key); + // } + // + // Collections.sort(keyList); + // + // sections = new String[keyList.size()]; // simple conversion to an + // // array of object + // keyList.toArray(sections); + // } + // + // return sections; // to string will be called each object, to display + // // the letter + // } + + public Object getChild(int groupPosition, int childPosition) { + String gn = groups.get(groupPosition); + ArrayList<Channel> channels = this.channels.get(gn); + return channels.get(childPosition); + } + + public long getChildId(int groupPosition, int childPosition) { + return childPosition; + } + + // Return a child view. You can load your custom layout here. + + public View getChildView(int groupPosition, int childPosition, + boolean isLastChild, View convertView, ViewGroup parent) { + + Channel item = (Channel) getChild(groupPosition, childPosition); ChannelHolder itemHolder = new ChannelHolder(); // recycle view? View view = convertView; if (view == null) { - view = inflater.inflate(R.layout.channel_item, null); + view = inflater.inflate(R.layout.child_layout, null); itemHolder = new ChannelHolder(); itemHolder.name = (TextView) view.findViewById(R.id.channel_name); @@ -44,32 +212,143 @@ class ChannelAdapter extends ArrayAdapter<Channel> { itemHolder = (ChannelHolder) view.getTag(); } - // get item - final Channel item = getItem(position); - - // fill item - if (item.isGroupSeparator()) { - view.setPadding(view.getPaddingLeft(), 0, view.getPaddingRight(), 0); - view.setBackgroundColor(Color.DKGRAY); - itemHolder.type.setVisibility(View.GONE); - itemHolder.name.setVisibility(View.VISIBLE); - itemHolder.name.setText(item.getName()); - itemHolder.name.setPadding(0, 0, 0, 0); - } else { - view.setBackgroundColor(Color.BLACK); - itemHolder.type.setVisibility(View.VISIBLE); - itemHolder.type.setVisibility(View.VISIBLE); - itemHolder.name.setText(item.toString()); + // + // // fill item + // if (item.isGroupSeparator()) { + // view.setPadding(view.getPaddingLeft(), 0, view.getPaddingRight(), 0); + // view.setBackgroundColor(Color.DKGRAY); + // itemHolder.type.setVisibility(View.GONE); + // itemHolder.name.setVisibility(View.VISIBLE); + // itemHolder.name.setText(item.getName()); + // itemHolder.name.setPadding(0, 0, 0, 0); + // } else { + view.setBackgroundColor(Color.BLACK); + + String name = item.getName(); + if (showChannelNumber) { + name = item.getNumber() + " - " + name; } + itemHolder.name.setText(name); + // } + + return view; + + // if (convertView == null) { + // LayoutInflater infalInflater = (LayoutInflater) context + // .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + // convertView = infalInflater.inflate(R.layout.child_layout, null); + // } + // TextView tv = (TextView) convertView.findViewById(R.id.tvChild); + // tv.setText(" " + vehicle.getName()); + // + // // Depending upon the child type, set the imageTextView01 + // tv.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); + // // if (vehicle instanceof Car) { + // // tv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.car, 0, 0, + // 0); + // // } else if (vehicle instanceof Bus) { + // // tv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.bus, 0, 0, + // 0); + // // } else if (vehicle instanceof Bike) { + // // tv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.bike, 0, 0, + // 0); + // // } + // return convertView; + } + + public int getChildrenCount(int groupPosition) { + String gn = groups.get(groupPosition); + ArrayList<Channel> channels = this.channels.get(gn); + return channels.size(); + } + + public Object getGroup(int groupPosition) { + return groups.get(groupPosition); + } + + public int getGroupCount() { + return groups.size(); + } + + public long getGroupId(int groupPosition) { + return groupPosition; + } + + // Return a group view. You can load your custom layout here. + + public View getGroupView(int groupPosition, boolean isExpanded, + View convertView, ViewGroup parent) { + + String group = (String) getGroup(groupPosition); + ChannelHolder itemHolder = new ChannelHolder(); + + // recycle view? + View view = convertView; + if (view == null) { + view = inflater.inflate(R.layout.group_layout, null); + itemHolder = new ChannelHolder(); + + itemHolder.name = (TextView) view.findViewById(R.id.channel_name); + // itemHolder.type = (ImageView) + // view.findViewById(R.id.channel_type); + view.setTag(itemHolder); + } else { + itemHolder = (ChannelHolder) view.getTag(); + } + itemHolder.name.setText(group); return view; + + } + + @Override + public void notifyDataSetChanged() { + super.notifyDataSetChanged(); } - public void addItem(final Channel channel) { - items.add(channel); + public boolean hasStableIds() { + return true; } - public void clearItems() { - items.clear(); + public boolean isChildSelectable(int arg0, int arg1) { + return true; } + + public Filter getFilter() { + return new Filter() { + + private ArrayList<Channel> ALL = channels.get(0); + + @Override + protected FilterResults performFiltering(CharSequence arg0) { + ArrayList<Channel> c = new ArrayList<Channel>(ALL); + Iterator<Channel> ci = c.iterator(); + while (ci.hasNext()) { + if (ci.next().getName().startsWith(arg0.toString()) == false) { + ci.remove(); + } + } + FilterResults fr = new FilterResults(); + return fr; + } + + @Override + protected void publishResults(CharSequence arg0, FilterResults arg1) { + notifyDataSetChanged(); + } + }; + } + + // public int getPositionForSection(int arg0) { + // return arg0; + // } + // + // public int getSectionForPosition(int arg0) { + // return arg0; + // } + // + // public Object[] getSections() { + // return sections; + // } + }
\ No newline at end of file diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelEventAdapter.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelEventAdapter.java new file mode 100644 index 0000000..7e3d575 --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelEventAdapter.java @@ -0,0 +1,21 @@ +package de.bjusystems.vdrmanager.gui; + +import android.content.Context; +import de.bjusystems.vdrmanager.R; +import de.bjusystems.vdrmanager.data.Event; +import de.bjusystems.vdrmanager.data.EventFormatter; + +class ChannelEventAdapter extends EventAdapter +{ + + + public ChannelEventAdapter(final Context context) { + super(context, R.layout.epg_event_item); + hideChannelName = true; + } + + @Override + protected EventFormatter getEventFormatter(Event event) { + return new EventFormatter(event,true); + } +}
\ No newline at end of file diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelListActivity.java index 3d61b56..a89034b 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelListActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelListActivity.java @@ -1,21 +1,29 @@ package de.bjusystems.vdrmanager.gui; import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; import android.app.Activity; +import android.content.Context; import android.content.Intent; -import android.net.Uri; import android.os.Bundle; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; +import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ListView; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.ExpandableListView; +import android.widget.ExpandableListView.ExpandableListContextMenuInfo; +import android.widget.ExpandableListView.OnChildClickListener; +import android.widget.ExpandableListView.OnGroupClickListener; import de.bjusystems.vdrmanager.R; +import de.bjusystems.vdrmanager.app.Intents; import de.bjusystems.vdrmanager.app.VdrManagerApp; import de.bjusystems.vdrmanager.data.Channel; import de.bjusystems.vdrmanager.data.Preferences; @@ -31,54 +39,122 @@ import de.bjusystems.vdrmanager.utils.svdrp.SvdrpException; * * @author bju */ -public class ChannelListActivity extends Activity implements - OnItemClickListener, SvdrpAsyncListener<Channel> { +public class ChannelListActivity extends BaseActivity implements + OnChildClickListener, OnGroupClickListener, SvdrpAsyncListener<Channel> { ChannelClient channelClient; ChannelAdapter adapter; Preferences prefs; - List<Channel> channels; SvdrpProgressDialog progress; - + private EditText searchBox; + + public static final int MENU_GROUP_GROUP = 1; + public static final int MENU_GROUP_PROVIDER = 2; + public static final int MENU_GROUP_NAME = 3; + // public static final int MENU_GROUP_SHOW_CHANNEL_NUMBERS = 2; + + public static final int MENU_GROUP = 1; + public static final int MENU_PROVIDER = 2; + public static final int MENU_NAME = 3; + + private TextWatcher filterTextWatcher; + + private int groupBy = MENU_GROUP; + + private final ArrayList<String> ALL_CHANNELS_GROUP = new ArrayList<String>( + 1); + + ExpandableListView listView; + + // @Override + // public boolean onKeyLongPress(int keyCode, KeyEvent event) { + // // TODO Auto-generated method stub + // return super.onKeyLongPress(keyCode, event); + // } + // + // @Override + // public boolean onKeyDown(int keyCode, KeyEvent event) { + // // TODO Auto-generated method stub + // return super.onKeyDown(keyCode, event); + // } + + // @Override + // public boolean onKeyUp(int keyCode, KeyEvent event) { + // // TODO Auto-generated method stub + // return super.onKeyUp(keyCode, event); + // } + // @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); + // requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); + // Attach view - setContentView(R.layout.channel_list); + setContentView(getMainLayout()); + setTitle(R.string.action_menu_channels); + adapter = new ChannelAdapter(this); + + searchBox = (EditText) findViewById(R.id.search_box); + + filterTextWatcher = new TextWatcher() { + + public void afterTextChanged(Editable s) { + } + + public void beforeTextChanged(CharSequence s, int start, int count, + int after) { + } + + public void onTextChanged(CharSequence s, int start, int before, + int count) { + adapter.getFilter().filter(s); + } + }; + searchBox.addTextChangedListener(filterTextWatcher); // Create adapter for ListView - adapter = new ChannelAdapter(this); - final ListView listView = (ListView) findViewById(R.id.channel_list); + + listView = (ExpandableListView) findViewById(R.id.channel_list); + // listView.setOnItemClickListener(this); + listView.setOnChildClickListener(this); + // listView.setOnGroupClickListener(this); + // + // public boolean onChildClick(ExpandableListView arg0, View arg1, + // int arg2, int arg3, long arg4) { + // Toast.makeText(getBaseContext(), "Child clicked", + // Toast.LENGTH_LONG).show(); + // return false; + // } + // }); + // + // listView.setOnGroupClickListener(new OnGroupClickListener() { + // + // public boolean onGroupClick(ExpandableListView arg0, View arg1, + // int arg2, long arg3) { + // Toast.makeText(getBaseContext(), "Group clicked", + // Toast.LENGTH_LONG).show(); + // return false; + // } + // }); + listView.setTextFilterEnabled(true); + listView.setFastScrollEnabled(true); listView.setAdapter(adapter); // register context menu registerForContextMenu(listView); + startChannelQuery(); // create channel list - channels = new ArrayList<Channel>(); - listView.setOnItemClickListener(this); + // listView.setOnItemClickListener(this); } - public void onItemClick(final AdapterView<?> parent, final View view, - final int position, final long id) { - - // find and remember item - final Channel channel = adapter.getItem(position); - final VdrManagerApp app = (VdrManagerApp) getApplication(); - app.setCurrentChannel(channel); - app.setChannels(channels); - - // show details - final Intent intent = new Intent(); - intent.setClass(this, EpgListActivity.class); - startActivity(intent); - } + // @Override protected void onResume() { super.onResume(); - startChannelQuery(); + } @Override @@ -94,9 +170,13 @@ public class ChannelListActivity extends Activity implements } private void startChannelQuery() { + startChannelQuery(true); + } + + private void startChannelQuery(boolean useCache) { // get channel task - channelClient = new ChannelClient(); + channelClient = new ChannelClient(useCache); // create background task final SvdrpAsyncTask<Channel, SvdrpClient<Channel>> task = new SvdrpAsyncTask<Channel, SvdrpClient<Channel>>( @@ -112,6 +192,46 @@ public class ChannelListActivity extends Activity implements task.run(); } + private void fillAdapter() { + switch (groupBy) { + case MENU_GROUP: + adapter.fill( + new ArrayList<String>(channelClient.getChannelGroups()), + channelClient.getGroupChannels(), groupBy); + listView.collapseGroup(0); + updateWindowTitle( + getString(R.string.action_menu_channels), + getString(R.string.groupby_window_title_templte, + getString(R.string.groupby_group))); + break; + case MENU_GROUP_PROVIDER: + adapter.fill(new ArrayList<String>(channelClient + .getProviderChannels().keySet()), channelClient + .getProviderChannels(), groupBy); + listView.collapseGroup(0); + updateWindowTitle( + getString(R.string.action_menu_channels), + getString(R.string.groupby_window_title_templte, + getString(R.string.groupby_provider))); + break; + case MENU_GROUP_NAME: + if (ALL_CHANNELS_GROUP.isEmpty()) { + ALL_CHANNELS_GROUP + .add(getString(R.string.groupby_name_all_channels_group)); + } + HashMap<String, ArrayList<Channel>> channels = new HashMap<String, ArrayList<Channel>>( + 1); + channels.put(getString(R.string.groupby_name_all_channels_group), + channelClient.getChannels()); + adapter.fill(ALL_CHANNELS_GROUP, channels, groupBy); + listView.expandGroup(0); + + updateWindowTitle(R.string.action_menu_channels, + R.string.groupby_name_all_channels_group); + break; + } + } + public void svdrpEvent(final SvdrpEvent event, final Channel result) { if (progress != null) { @@ -120,18 +240,20 @@ public class ChannelListActivity extends Activity implements switch (event) { case CONNECTING: - adapter.clear(); - channels.clear(); + break; + case CONNECT_ERROR: + switchNoConnection(); break; case LOGIN_ERROR: - this.finish(); + switchNoConnection(); + break; + case FINISHED_SUCCESS: + case CACHE_HIT: + fillAdapter(); + break; + case FINISHED_ABNORMALY: + switchNoConnection(); break; - case FINISHED: - channels.addAll(channelClient.getResults()); - for (final Channel channel : channels) { - adapter.add(channel); - } - progress = null; } } @@ -141,58 +263,219 @@ public class ChannelListActivity extends Activity implements } } + public boolean onPrepareOptionsMenu(Menu menu) { + switch (groupBy) { + case MENU_GROUP: + menu.setGroupVisible(MENU_GROUP_GROUP, false); + menu.setGroupVisible(MENU_GROUP_PROVIDER, true); + menu.setGroupVisible(MENU_GROUP_NAME, true); + break; + + case MENU_PROVIDER: + menu.setGroupVisible(MENU_GROUP_PROVIDER, false); + menu.setGroupVisible(MENU_GROUP_GROUP, true); + menu.setGroupVisible(MENU_GROUP_NAME, true); + break; + + case MENU_NAME: + menu.setGroupVisible(MENU_GROUP_NAME, false); + menu.setGroupVisible(MENU_GROUP_GROUP, true); + menu.setGroupVisible(MENU_GROUP_PROVIDER, true); + break; + default: + return super.onPrepareOptionsMenu(menu); + } + return true; + + } + + @Override + public final boolean onCreateOptionsMenu(final Menu menu) { + super.onCreateOptionsMenu(menu); + + MenuItem item; + item = menu + .add(MENU_GROUP_GROUP, MENU_GROUP, 0, R.string.groupby_group); + item.setIcon(android.R.drawable.ic_menu_sort_alphabetically); + item.setAlphabeticShortcut('g'); + + item = menu.add(MENU_GROUP_PROVIDER, MENU_PROVIDER, 0, + R.string.groupby_provider); + item.setIcon(android.R.drawable.ic_menu_sort_alphabetically); + item.setAlphabeticShortcut('p'); + + item = menu.add(MENU_GROUP_NAME, MENU_NAME, 0, R.string.groupby_name); + item.setIcon(android.R.drawable.ic_menu_sort_alphabetically); + item.setAlphabeticShortcut('n'); + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + switch (item.getItemId()) { + case MENU_GROUP: + case MENU_PROVIDER: + case MENU_NAME: + groupBy = item.getItemId(); + fillAdapter(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + @Override public void onCreateContextMenu(final ContextMenu menu, final View v, final ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - - if (v.getId() == R.id.channel_list) { + ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo; + int type = ExpandableListView + .getPackedPositionType(info.packedPosition); + int group = ExpandableListView + .getPackedPositionGroup(info.packedPosition); + int child = ExpandableListView + .getPackedPositionChild(info.packedPosition); + // Only create a context menu for child items + if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { + // Array created earlier when we built the expandable list + Channel item = (Channel) adapter.getChild(group, child); + // if (v.getId() == R.id.channel_list) { final MenuInflater inflater = getMenuInflater(); - final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; - - // set menu title - final Channel item = adapter.getItem(info.position); menu.setHeaderTitle(item.getName()); - inflater.inflate(R.menu.channel_list_item_menu, menu); + } else if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { + Channel grp = (Channel) adapter.getGroup(group); + final MenuInflater infl = getMenuInflater(); + menu.setHeaderTitle(grp.getName()); + infl.inflate(R.menu.channel_list_group_menu, menu); } } @Override - public boolean onContextItemSelected(final MenuItem item) { + public boolean onContextItemSelected(MenuItem item) { - final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item + ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item .getMenuInfo(); - final Channel channel = adapter.getItem(info.position); - switch (item.getItemId()) { - case R.id.channel_item_menu_epg: - onItemClick(null, null, info.position, 0); - break; - case R.id.channel_item_menu_stream: - // show live stream - showStream(channel); - break; + // String title = ((TextView) info.targetView).getText().toString(); + + int type = ExpandableListView + .getPackedPositionType(info.packedPosition); + + Channel channel = null; + if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { + int groupPos = ExpandableListView + .getPackedPositionGroup(info.packedPosition); + int childPos = ExpandableListView + .getPackedPositionChild(info.packedPosition); + channel = (Channel) adapter.getChild(groupPos, childPos); + switch (item.getItemId()) { + case R.id.channel_item_menu_epg: + startChannelEPG(channel); + break; + case R.id.channel_item_menu_stream: + // show live stream + Utils.stream(this, channel); + break; + } + + return true; + } else if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { + int groupPos = ExpandableListView + .getPackedPositionGroup(info.packedPosition); + + return true; + } + + return false; + + } + + // @Override + // public boolean onContextItemSelected(final MenuItem item) { + // + // final AdapterView.AdapterContextMenuInfo info = + // (AdapterView.AdapterContextMenuInfo) item + // .getMenuInfo(); + // // final Channel channel = adapter.getItem(info.position); + // // if(channel.isGroupSeparator()){ + // // + // // } + // + // switch (item.getItemId()) { + // case R.id.channel_item_menu_epg: + // //onItemClick(null, null, info.position, 0); + // break; + // case R.id.channel_item_menu_stream: + // // show live stream + // // Utils.stream(this, channel); + // break; + // } + // + // return true; + // } + + @Override + public boolean onSearchRequested() { + if (groupBy != MENU_NAME) { + return true; } + searchBox.setVisibility(View.VISIBLE); + searchBox.requestFocus(); + InputMethodManager inputMgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + inputMgr.toggleSoftInput(0, 0); + return true; + } + + @Override + public void onBackPressed() { + if (searchBox.getVisibility() == View.VISIBLE) { + searchBox.setVisibility(View.GONE); + } else { + super.onBackPressed(); + } + } + public boolean onGroupClick(ExpandableListView arg0, View arg1, int arg2, + long arg3) { return true; } - private String getStreamUrl(Channel c) { - //"http://192.168.1.119:3000/TS/" - StringBuilder sb = new StringBuilder(); - Preferences p = Preferences.getPreferences(); - sb.append("http://").append(p.getSvdrpHost()).append(":") - .append(p.getStreamPort()).append("/") - .append(p.getStreamFormat()).append("/") - .append(c.getNumber()); - return sb.toString(); - } - private void showStream(final Channel channel) { - - String url = getStreamUrl(channel); - final Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setDataAndType(Uri.parse(url.toString()),"video/*"); - startActivityForResult(intent, 1); - } -} + private void startChannelEPG(Channel channel) { + // find and remember item + // final Channel channel = adapter.getItem(position); + //final VdrManagerApp app = (VdrManagerApp) getApplication(); + //app.setCurrentChannel(channel); + + // show details + final Intent intent = new Intent(); + intent.putExtra(Intents.CURRENT_CHANNEL, channel); + intent.setClass(this, EventEpgListActivity.class); + startActivity(intent); + } + + public boolean onChildClick(ExpandableListView parent, View v, + int groupPosition, int childPosition, long id) { + Channel channel = (Channel) adapter.getChild(groupPosition, + childPosition); + startChannelEPG(channel); + return false; + } + + @Override + protected void refresh() { + startChannelQuery(false); + } + + @Override + protected void retry() { + startChannelQuery(false); + } + + @Override + protected int getMainLayout() { + return R.layout.channel_list; + } + +}
\ No newline at end of file diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgDetailsActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgDetailsActivity.java index 7932e86..6e61099 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgDetailsActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgDetailsActivity.java @@ -1,70 +1,223 @@ package de.bjusystems.vdrmanager.gui; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + import android.app.Activity; import android.content.Intent; +import android.os.AsyncTask; import android.os.Bundle; -import android.util.TypedValue; +import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; -import android.widget.Button; +import android.widget.ImageButton; +import android.widget.ProgressBar; import android.widget.TextView; +import android.widget.Toast; import de.bjusystems.vdrmanager.R; import de.bjusystems.vdrmanager.app.VdrManagerApp; +import de.bjusystems.vdrmanager.data.Channel; import de.bjusystems.vdrmanager.data.Epg; import de.bjusystems.vdrmanager.data.EventFormatter; import de.bjusystems.vdrmanager.data.Preferences; +import de.bjusystems.vdrmanager.gui.SimpleGestureFilter.SimpleGestureListener; +import de.bjusystems.vdrmanager.utils.svdrp.EpgClient; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpException; /** - * This class is used for showing what's - * current running on all channels + * This class is used for showing what's current running on all channels + * * @author bju */ -public class EpgDetailsActivity extends Activity - implements OnClickListener { +public class EpgDetailsActivity extends Activity implements OnClickListener, + SimpleGestureListener { Preferences prefs; + private SimpleGestureFilter detector; + + ImageButton event_left; + + ImageButton event_right; + @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Attach view setContentView(R.layout.epg_detail); + detector = new SimpleGestureFilter(this, this); - - // current event + //event_left = (ImageButton) findViewById(R.id.epg_event_left); + //event_right = (ImageButton) findViewById(R.id.epg_event_right); + + + // current event final VdrManagerApp app = (VdrManagerApp) getApplication(); - final Epg event = app.getCurrentEvent(); - final EventFormatter formatter = new EventFormatter(event); - - final TextView title = (TextView)findViewById(R.id.epg_detail_title); - title.setText(formatter.getTitle()); - title.setTextSize(TypedValue.COMPLEX_UNIT_PX, title.getTextSize()*(float)1.3); - - ((TextView) findViewById(R.id.epg_detail_time)).setText(formatter.getTime()); - ((TextView)findViewById(R.id.epg_detail_channel)).setText(event.getChannelName()); - ((TextView)findViewById(R.id.epg_detail_date)).setText(formatter.getLongDate()); - final TextView textView = (TextView)findViewById(R.id.epg_detail_description); - textView.setText(formatter.getDescription()); - - // copy color for separator lines - final int color = textView.getTextColors().getDefaultColor(); - ((TextView)findViewById(R.id.epg_detail_separator_1)).setBackgroundColor(color); - ((TextView)findViewById(R.id.epg_detail_separator_2)).setBackgroundColor(color); - - // register button handler - final Button timeButton = (Button) findViewById(R.id.epg_event_create_timer); - timeButton.setOnClickListener(this); - - // set button text - if (event.getTimer() == null) { - timeButton.setText(R.string.epg_event_create_timer_text); - } else { - timeButton.setText(R.string.epg_event_modify_timer_text); - } - - // clear list of activities to finish - app.clearActivitiesToFinish(); + epgs = app.getCurrentEpgList(); + Epg epg = app.getCurrentEvent(); + + + counter = 0; + for(Epg e : epgs){ + if(epg == e){ + break; + } + counter++; + } + + + + new AsyncTask<Void,Void,Void>(){ + + protected void onPreExecute() { +// event_left.setEnabled(false); + // event_right.setEnabled(false); + }; + + protected Void doInBackground(Void... params) { + initEPGs(); + return null; + }; + + protected void onPostExecute(Void result) { + // event_left.setEnabled(true); + // event_right.setEnabled(true); + }; + + }.execute((Void)null); + + publishEPG(epg); + // final EventFormatter formatter = new EventFormatter(event); + // + // final TextView title = (TextView) + // findViewById(R.id.epg_detail_title); + // title.setText(formatter.getTitle()); + // title.setTextSize(TypedValue.COMPLEX_UNIT_PX, title.getTextSize() + // * (float) 1.3); + // + // ((TextView) findViewById(R.id.epg_detail_time)).setText(formatter + // .getTime()); + // ((TextView) findViewById(R.id.epg_detail_channel)).setText(event + // .getChannelName()); + // ((TextView) findViewById(R.id.epg_detail_date)).setText(formatter + // .getLongDate()); + // final TextView textView = (TextView) + // findViewById(R.id.epg_detail_description); + // textView.setText(formatter.getDescription()); + // + // // copy color for separator lines + // final int color = textView.getTextColors().getDefaultColor(); + // // ((TextView) findViewById(R.id.epg_detail_separator_1)) + // // .setBackgroundColor(color); + // + // ((ProgressBar) findViewById(R.id.epg_detail_progress)) + // .setProgress(Utils.getProgress(event)); + // + // ((TextView) findViewById(R.id.epg_detail_separator_2)) + // .setBackgroundColor(color); + // + // // register button handler + // final ImageButton timeButton = (ImageButton) + // findViewById(R.id.epg_event_create_timer); + // timeButton.setOnClickListener(this); + // + // final ImageButton livetvButton = (ImageButton) + // findViewById(R.id.epg_event_livetv); + // livetvButton.setOnClickListener(this); + // + // + // // set button text + // if (event.getTimer() == null) { + // // timeButton.setText(R.string.epg_event_create_timer_text); + // } else { + // // timeButton.setText(R.string.epg_event_modify_timer_text); + // } + + // clear list of activities to finish + app.clearActivitiesToFinish(); + } + + public void publishEPG(Epg event) { + + String cn = event.getChannelName(); + + setTitle(getString(R.string.epg_of_a_channel,cn)); + + final EventFormatter formatter = new EventFormatter(event); + + final TextView title = (TextView) findViewById(R.id.epg_detail_title); + title.setText(formatter.getTitle()); + // title.setTextSize(TypedValue.COMPLEX_UNIT_PX, title.getTextSize() + // * (float) 1.3); + + ((TextView) findViewById(R.id.epg_detail_time)).setText(formatter + .getDate() + " " + formatter.getTime()); + + TextView dura = (TextView) findViewById(R.id.epg_detail_duration); + + ((TextView) findViewById(R.id.epg_detail_channel)).setText(event + .getChannelName()); + //((TextView) findViewById(R.id.epg_detail_date)).setText(formatter + // .getLongDate()); + + final TextView shortText = (TextView) findViewById(R.id.epg_detail_shorttext); + shortText.setText(formatter.getShortText()); + + + final TextView textView = (TextView) findViewById(R.id.epg_detail_description); + textView.setText(formatter.getDescription()); + + // copy color for separator lines + final int color = textView.getTextColors().getDefaultColor(); + // ((TextView) findViewById(R.id.epg_detail_separator_1)) + // .setBackgroundColor(color); + + int p = Utils.getProgress(event); + + ((ProgressBar) findViewById(R.id.epg_detail_progress)) + .setProgress(p); + int dm = Utils.getDuration(event); + if(Utils.isLive(event)){ + int rest = dm - (dm * p / 100); + dura.setText(getString(R.string.epg_duration_template_live, rest, dm)); + } else { + dura.setText(getString(R.string.epg_duration_template, dm)); + } + + ((TextView) findViewById(R.id.epg_detail_separator_2)) + .setBackgroundColor(color); + + // register button handler + setThisAsOnClickListener(R.id.epg_event_create_timer); + View b = findViewById(R.id.epg_event_livetv); + if (Utils.isLive(event) == false) { + b.setVisibility(View.GONE); + } else { + b.setVisibility(View.VISIBLE); + setThisAsOnClickListener(b); + } +// setThisAsOnClickListener(R.id.epg_event_left); +// setThisAsOnClickListener(R.id.epg_event_right); + + // set button text + if (event.getTimer() == null) { + // timeButton.setText(R.string.epg_event_create_timer_text); + } else { + // timeButton.setText(R.string.epg_event_modify_timer_text); + } + + } + + private void setThisAsOnClickListener(View v) { + if (v != null) { + v.setOnClickListener(this); + } + } + + private void setThisAsOnClickListener(int view) { + setThisAsOnClickListener(findViewById(view)); } @Override @@ -79,13 +232,110 @@ public class EpgDetailsActivity extends Activity public void onClick(final View v) { - // after timer creation/modification return to the epg list final VdrManagerApp app = (VdrManagerApp) getApplication(); - app.addActivityToFinish(this); + switch (v.getId()) { + case R.id.epg_event_livetv: + Epg event = app.getCurrentEvent(); + Utils.stream(this, event.getChannelNumber()); + break; + case R.id.epg_event_create_timer: + Toast.makeText(this, "Soon we get here the timer menu", Toast.LENGTH_SHORT).show(); + break; + +// case R.id.epg_event_left: +// prevEPG(); +// break; +// case R.id.epg_event_right: +// nextEPG(); +// break; + } + } + + public void onSwipe(int direction) { + switch (direction) { + case SimpleGestureFilter.SWIPE_RIGHT: + prevEPG(); + break; + case SimpleGestureFilter.SWIPE_LEFT: + nextEPG(); + break; + } + } + + private void prevEPG() { + Epg epg; + if (counter == 0) { + epg = epgs.get(0); + } else { + epg = epgs.get(--counter); + } + + publishEPG(epg); + + } + + ArrayList<Epg> epgs = null; + int counter = 0; + + public void initEPGs() { + + // epgs = ((VdrManagerApp)getApplication()).getCurrentEpgList(); + + if (epgs != null) { + return; + } + epgs = new ArrayList<Epg>(); + + final VdrManagerApp app = (VdrManagerApp) getApplication(); + final Epg event = app.getCurrentEvent(); + EpgClient c = new EpgClient(new Channel() { + @Override + public String getName() { + return event.getChannelName(); + } + + @Override + public int getNumber() { + return Integer.valueOf(event.getChannelNumber()); + } + }); - // show timer details - final Intent intent = new Intent(); - intent.setClass(this, TimerDetailsActivity.class); - startActivity(intent); + try { + c.run(); + } catch (SvdrpException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + List<Epg> e = c.getResults(); + if (e == null || e.isEmpty()) { + return; + } + + epgs.addAll(e); + Epg fe = epgs.get(0); + if (event.getStart().equals(fe.getStart()) == false) { + epgs.set(0, event); + ; + } + } + + private void nextEPG() { + if(counter < epgs.size() - 1){ + counter ++ ; + } + Epg epg = epgs.get(counter); + publishEPG(epg); } + + public void onDoubleTap() { + + } + + @Override + public boolean dispatchTouchEvent(MotionEvent me) { + this.detector.onTouchEvent(me); + return super.dispatchTouchEvent(me); + } + } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgListActivity.java deleted file mode 100644 index 34ec06a..0000000 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgListActivity.java +++ /dev/null @@ -1,408 +0,0 @@ -package de.bjusystems.vdrmanager.gui; - -import java.util.List; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.AdapterView.OnItemSelectedListener; -import android.widget.ArrayAdapter; -import android.widget.LinearLayout; -import android.widget.ListView; -import android.widget.Spinner; -import android.widget.TextView; -import de.bjusystems.vdrmanager.R; -import de.bjusystems.vdrmanager.app.VdrManagerApp; -import de.bjusystems.vdrmanager.data.Channel; -import de.bjusystems.vdrmanager.data.Epg; -import de.bjusystems.vdrmanager.data.EpgSearchParams; -import de.bjusystems.vdrmanager.data.EpgSearchTimeValue; -import de.bjusystems.vdrmanager.data.EpgSearchTimeValues; -import de.bjusystems.vdrmanager.data.EventFormatter; -import de.bjusystems.vdrmanager.data.EventListItem; -import de.bjusystems.vdrmanager.data.Preferences; -import de.bjusystems.vdrmanager.tasks.DeleteTimerTask; -import de.bjusystems.vdrmanager.tasks.ToggleTimerTask; -import de.bjusystems.vdrmanager.utils.svdrp.EpgClient; -import de.bjusystems.vdrmanager.utils.svdrp.SvdrpAsyncListener; -import de.bjusystems.vdrmanager.utils.svdrp.SvdrpAsyncTask; -import de.bjusystems.vdrmanager.utils.svdrp.SvdrpClient; -import de.bjusystems.vdrmanager.utils.svdrp.SvdrpEvent; -import de.bjusystems.vdrmanager.utils.svdrp.SvdrpException; - -/** - * This class is used for showing what's - * current running on all channels - * @author bju - */ -public class EpgListActivity extends Activity - implements OnItemClickListener, OnItemSelectedListener, SvdrpAsyncListener<Epg> { - - EpgClient epgClient; - EventAdapter adapter; - Preferences prefs; - Spinner timeSpinner; - Spinner channelSpinner; - ArrayAdapter<EpgSearchTimeValue> timeSpinnerAdapter; - ListView listView; - SvdrpProgressDialog progress; - - @Override - protected void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // application object - final VdrManagerApp app = (VdrManagerApp)getApplication(); - // get state - final Channel channel = ((VdrManagerApp) getApplication()).getCurrentChannel(); - final List<Channel> channels = ((VdrManagerApp) getApplication()).getChannels(); - - // Attach view - setContentView(R.layout.epg_list); - - // create adapter for time spinner - timeSpinnerAdapter = new ArrayAdapter<EpgSearchTimeValue>(this, android.R.layout.simple_spinner_item); - timeSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - timeSpinner = (Spinner) findViewById(R.id.epg_list_time_spinner); - timeSpinner.setAdapter(timeSpinnerAdapter); - - // create adapter for channel spinner - final ArrayAdapter<Channel> channelSpinnerAdapter = new ArrayAdapter<Channel>(this, android.R.layout.simple_spinner_item); - channelSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - channelSpinner = (Spinner) findViewById(R.id.epg_list_channel_spinner); - channelSpinner.setAdapter(channelSpinnerAdapter); - - // get search label - final TextView searchLabel = (TextView) findViewById(R.id.epg_list_search_label); - - // fill spinners - if (channels != null) { - // add dummy timer - timeSpinnerAdapter.add(new EpgSearchTimeValue()); - // add channel values - for(final Channel c : channels) { - channelSpinnerAdapter.add(c); - } - } else { - // add dummy channel - channelSpinnerAdapter.add(new Channel()); - // add time values - fillTimeSpinnerValues(); - } - - // show needed items - final LinearLayout timeLayout = (LinearLayout) findViewById(R.id.whatson_time); - - // update gui - switch (app.getEpgListState()) { - case EPG_TIME: - adapter = new EventAdapter(this, false); - timeLayout.setVisibility(View.VISIBLE); - channelSpinner.setVisibility(View.GONE); - searchLabel.setVisibility(View.GONE); - timeSpinner.setOnItemSelectedListener(this); - timeSpinner.setSelection(0); - break; - case EPG_CHANNEL: - adapter = new EventAdapter(this, true); - timeLayout.setVisibility(View.GONE); - channelSpinner.setVisibility(View.VISIBLE); - searchLabel.setVisibility(View.GONE); - channelSpinner.setOnItemSelectedListener(this); - channelSpinner.setSelection(channel.getNumber() - 1); - break; - case EPG_SEARCH: - adapter = new EventAdapter(this, true); - timeLayout.setVisibility(View.GONE); - channelSpinner.setVisibility(View.GONE); - searchLabel.setVisibility(View.VISIBLE); - startSearchEpgQuery(app.getCurrentSearch()); - break; - } - - // Create adapter for EPG list - listView = (ListView) findViewById(R.id.whatson_list); - listView.setAdapter(adapter); - registerForContextMenu(listView); - - // register EPG item click - listView.setOnItemClickListener(this); - - } - - @Override - protected void onResume() { - super.onResume(); - fillTimeSpinnerValues(); - - reloadIfNeeded(); - } - - private void reloadIfNeeded() { - - final VdrManagerApp app = (VdrManagerApp) getApplication(); - if (app.isReload()) { - app.setReload(false); - startEpgQuery(epgClient); - } - } - - @Override - protected void onPause() { - super.onPause(); - if (epgClient != null) { - epgClient.abort(); - } - if (progress != null) { - progress.dismiss(); - progress = null; - } - } - - public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) { - - // find and remember item - final EventListItem item = adapter.getItem(position); - - // prepare timer if we want to program - prepareTimer(item); - - // show details - final Intent intent = new Intent(); - intent.setClass(this, EpgDetailsActivity.class); - startActivity(intent); - } - - public void onItemSelected(final AdapterView<?> parent, final View view, final int position, final long id) { - - if (parent == timeSpinner) { - // get spinner value - final EpgSearchTimeValue selection = (EpgSearchTimeValue) timeSpinner.getSelectedItem(); - // update search - startTimeEpgQuery(selection.getValue()); - } else { - // get spinner value - final Channel channel = (Channel) channelSpinner.getSelectedItem(); - // update search - startChannelEpgQuery(channel); - } - } - - @Override - public boolean onCreateOptionsMenu(final Menu menu) { - super.onCreateOptionsMenu(menu); - - final MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.epg_list_menu, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(final MenuItem item) { - - Intent intent; - - switch (item.getItemId()) - { - case R.id.epg_menu_search: - intent = new Intent(); - intent.setClass(this, EpgSearchActivity.class); - startActivity(intent); - break; - case R.id.epg_menu_times: - intent = new Intent(); - intent.setClass(this, EpgSearchTimesListActivity.class); - startActivity(intent); - break; - } - return true; - } - - @Override - public void onCreateContextMenu(final ContextMenu menu, final View v, final ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - - if (v.getId() == R.id.whatson_list) { - final MenuInflater inflater = getMenuInflater(); - final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo; - - // set menu title - final EventListItem item = adapter.getItem(info.position); - final EventFormatter formatter = new EventFormatter(item); - menu.setHeaderTitle(formatter.getTitle()); - - inflater.inflate(R.menu.epg_list_item_menu, menu); - - // remove unneeded menu items - if (item.getEpg().getTimer() != null) { - menu.findItem(R.id.epg_item_menu_timer_add).setVisible(false); - final MenuItem enableMenuItem = menu.findItem(R.id.epg_item_menu_timer_toggle); - enableMenuItem.setTitle(item.getEpg().getTimer().isEnabled() ? R.string.epg_item_menu_timer_disable : R.string.epg_item_menu_timer_enable); - } else { - menu.findItem(R.id.epg_item_menu_timer_modify).setVisible(false); - menu.findItem(R.id.epg_item_menu_timer_delete).setVisible(false); - } - } - } - - - - @Override - public boolean onContextItemSelected(final MenuItem item) { - - final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); - final EventListItem event = adapter.getItem(info.position); - - switch (item.getItemId()) { - case R.id.epg_item_menu_timer_add: - case R.id.epg_item_menu_timer_modify: - { - prepareTimer(event); - - final Intent intent = new Intent(); - intent.setClass(this, TimerDetailsActivity.class); - startActivity(intent); - break; - } - case R.id.epg_item_menu_timer_delete: - { - deleteTimer(event); - break; - } - case R.id.epg_item_menu_timer_toggle: - { - toggleTimer(event); - } - } - - return true; - } - - public void onNothingSelected(final AdapterView<?> arg0) { - //startTimeEpgQuery(((EpgTimeSpinnerValue)timeSpinner.getAdapter().getItem(0)).getValue()); - } - - private void startSearchEpgQuery(final EpgSearchParams search) { - - epgClient = new EpgClient(search); - startEpgQuery(epgClient); - } - - private void startTimeEpgQuery(final String time) { - - epgClient = new EpgClient(time); - startEpgQuery(epgClient); - } - - private void startChannelEpgQuery(final Channel channel) { - - epgClient = new EpgClient(channel); - startEpgQuery(epgClient); - } - - private void startEpgQuery(final EpgClient epgClient) { - - // remove old listeners - epgClient.clearSvdrpListener(); - - // create background task - final SvdrpAsyncTask<Epg, SvdrpClient<Epg>> task = new SvdrpAsyncTask<Epg, SvdrpClient<Epg>>(epgClient); - - // create progress - progress = new SvdrpProgressDialog(this, epgClient); - - // attach listener - task.addListener(this); - - // start task - task.run(); - } - - public void svdrpEvent(final SvdrpEvent event, final Epg result) { - - if (progress != null) { - progress.svdrpEvent(event); - } - - switch (event) { - case CONNECTING: - adapter.clearItems(); - break; - case LOGIN_ERROR: - this.finish(); - break; - case FINISHED: - epgClient.clearSvdrpListener(); - for(final Epg epg : epgClient.getResults()) { - adapter.addItem(new EventListItem(epg)); - } - adapter.sortItems(); - listView.setSelectionAfterHeaderView(); - progress = null; - break; - } - } - - public void svdrpException(final SvdrpException exception) { - if (progress != null) { - progress.svdrpException(exception); - } - } - - private void prepareTimer(final EventListItem item) { - - final VdrManagerApp app = (VdrManagerApp) getApplication(); - - // remember event for details view and timer things - app.setCurrentEvent(item.getEpg()); - - // if we create or modify the attached timer we will return to a new epg list - app.clearActivitiesToFinish(); - app.addActivityToFinish(this); - app.setNextActivity(EpgListActivity.class); - } - - private void deleteTimer(final EventListItem item) { - - final DeleteTimerTask task = new DeleteTimerTask(this, item.getEpg().getTimer()) { - @Override - public void finished() { - // refresh epg list after return - final VdrManagerApp app = (VdrManagerApp) getApplication(); - app.setReload(true); - reloadIfNeeded(); - } - }; - task.start(); - } - - private void toggleTimer(final EventListItem item) { - - final ToggleTimerTask task = new ToggleTimerTask(this, item.getEpg().getTimer()) { - @Override - public void finished() { - // refresh epg list after return - final VdrManagerApp app = (VdrManagerApp) getApplication(); - app.setReload(true); - reloadIfNeeded(); - } - }; - task.start(); - } - - private void fillTimeSpinnerValues() { - final EpgSearchTimeValues values = new EpgSearchTimeValues(this); - timeSpinnerAdapter.clear(); - for(final EpgSearchTimeValue value : values.getValues()) { - timeSpinnerAdapter.add(value); - } - } -} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgSearchActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgSearchActivity.java index 90e8c00..e6fbfdd 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgSearchActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgSearchActivity.java @@ -13,12 +13,11 @@ import de.bjusystems.vdrmanager.data.EpgSearchParams; import de.bjusystems.vdrmanager.data.Preferences; /** - * This class is used for showing what's - * current running on all channels + * This class is used for showing what's current running on all channels + * * @author bju */ -public class EpgSearchActivity extends Activity - implements OnClickListener { +public class EpgSearchActivity extends Activity implements OnClickListener { Preferences prefs; TextView text; @@ -33,9 +32,9 @@ public class EpgSearchActivity extends Activity // save fields text = (TextView) findViewById(R.id.epg_search_text); - // register button - final Button button = (Button) findViewById(R.id.epg_search_button); - button.setOnClickListener(this); + // register button + final Button button = (Button) findViewById(R.id.epg_search_button); + button.setOnClickListener(this); } @Override @@ -53,11 +52,11 @@ public class EpgSearchActivity extends Activity // Save search parameters final EpgSearchParams search = new EpgSearchParams(); search.setTitle(text.getText().toString()); - ((VdrManagerApp)getApplication()).setCurrentSearch(search); + ((VdrManagerApp) getApplication()).setCurrentSearch(search); // show timer details final Intent intent = new Intent(); - intent.setClass(this, EpgListActivity.class); + //intent.setClass(this, EpgListActivity.class); startActivity(intent); } } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventAdapter.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventAdapter.java index 0a97576..10d633b 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventAdapter.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventAdapter.java @@ -1,54 +1,64 @@ package de.bjusystems.vdrmanager.gui; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Comparator; -import java.util.GregorianCalendar; import java.util.List; import android.content.Context; import android.graphics.Color; +import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; +import android.widget.ProgressBar; import android.widget.TextView; import de.bjusystems.vdrmanager.R; +import de.bjusystems.vdrmanager.data.Event; import de.bjusystems.vdrmanager.data.EventFormatter; import de.bjusystems.vdrmanager.data.EventListItem; -import de.bjusystems.vdrmanager.utils.date.DateFormatter; -class EventAdapter extends ArrayAdapter<EventListItem> { +abstract class EventAdapter extends ArrayAdapter<EventListItem> { - private final LayoutInflater inflater; - private final List<EventListItem> items; - private final boolean sortByTime; + protected final int layout; + protected final LayoutInflater inflater; + //protected final List<EventListItem> items; + + protected boolean hideChannelName = false; - public EventAdapter(final Context context, final boolean sortByTime) { - super(context, R.layout.event_item); + public EventAdapter(final Context context, int layout) { + super(context, layout); + this.layout = layout; inflater = LayoutInflater.from(context); - items = new ArrayList<EventListItem>(); - this.sortByTime = sortByTime; } @Override - public View getView(final int position, final View convertView, final ViewGroup parent) { + public View getView(final int position, final View convertView, + final ViewGroup parent) { EventListItemHolder itemHolder = new EventListItemHolder(); // recycle view? View view = convertView; if (view == null) { - view = inflater.inflate(R.layout.event_item, null); - itemHolder = new EventListItemHolder(); + view = inflater.inflate(layout, null); - itemHolder.state = (ImageView) view.findViewById(R.id.timer_item_state); - itemHolder.time = (TextView) view.findViewById(R.id.timer_item_time); - itemHolder.channel = (TextView) view.findViewById(R.id.timer_item_channel); - itemHolder.title = (TextView) view.findViewById(R.id.timer_item_title); + itemHolder = new EventListItemHolder(); + itemHolder.state = (ImageView) view + .findViewById(R.id.timer_item_state); + itemHolder.time = (TextView) view + .findViewById(R.id.timer_item_time); + itemHolder.channel = (TextView) view + .findViewById(R.id.timer_item_channel); + itemHolder.title = (TextView) view + .findViewById(R.id.timer_item_title); + itemHolder.progress = (ProgressBar) view + .findViewById(R.id.timer_progress); + itemHolder.shortText = (TextView) view + .findViewById(R.id.timer_item_shorttext); + itemHolder.duration = (TextView) view + .findViewById(R.id.timer_item_duration); view.setTag(itemHolder); } else { itemHolder = (EventListItemHolder) view.getTag(); @@ -62,14 +72,24 @@ class EventAdapter extends ArrayAdapter<EventListItem> { view.setPadding(view.getPaddingLeft(), 0, view.getPaddingRight(), 0); view.setBackgroundColor(Color.DKGRAY); itemHolder.state.setVisibility(View.GONE); - itemHolder.channel.setVisibility(View.GONE); + itemHolder.channel.setText(item.getHeader()); itemHolder.title.setVisibility(View.GONE); - itemHolder.time.setText(item.getHeader()); + itemHolder.time.setVisibility(View.GONE); + itemHolder.progress.setVisibility(View.GONE); + itemHolder.shortText.setVisibility(View.GONE); + itemHolder.duration.setVisibility(View.GONE); + } else { + view.setBackgroundColor(Color.BLACK); - itemHolder.channel.setVisibility(View.VISIBLE); + // itemHolder.channel.setVisibility(View.VISIBLE); + itemHolder.time.setVisibility(View.VISIBLE); itemHolder.title.setVisibility(View.VISIBLE); itemHolder.state.setVisibility(View.VISIBLE); + // itemHolder.channel.setVisibility(View.VISIBLE); + itemHolder.shortText.setVisibility(View.VISIBLE); + itemHolder.duration.setVisibility(View.VISIBLE); + // itemHolder.state.setVisibility(View.); switch (item.getTimerState()) { case Active: itemHolder.state.setImageResource(R.drawable.timer_active); @@ -84,88 +104,42 @@ class EventAdapter extends ArrayAdapter<EventListItem> { itemHolder.state.setImageResource(R.drawable.timer_none); break; } - final EventFormatter formatter = new EventFormatter(item.getEvent()); + final EventFormatter formatter = getEventFormatter(item.getEvent()); itemHolder.time.setText(formatter.getTime()); - itemHolder.channel.setText(item.getChannelName()); - itemHolder.title.setText(formatter.getTitle()); - } - - return view; - } - - public void addItem(final EventListItem item) { - items.add(item); - } - - public void sortItems() { - if (sortByTime) { - sortItemsByTime(); - } else { - sortItemsByChannel(); - } - } - - private void sortItemsByTime() { - - // sort by start time - final EventListItem[] unsortedItems = items.toArray(new EventListItem[0]); - final Comparator<EventListItem> comparator = new Comparator<EventListItem>() { - - public int compare(final EventListItem item1, final EventListItem item2) { - return item1.getStart().compareTo(item2.getStart()); + if(hideChannelName){ + itemHolder.channel.setVisibility(View.GONE); + } else { + itemHolder.channel.setText(item.getChannelName()); } - }; - Arrays.sort(unsortedItems, comparator); - - // insert daily headers - final List<EventListItem> sortedItems = new ArrayList<EventListItem>(); - final GregorianCalendar itemCal = new GregorianCalendar(); - final GregorianCalendar lastHeaderCal = new GregorianCalendar(); - lastHeaderCal.set(Calendar.YEAR, 1970); - - for(final EventListItem item : unsortedItems) { - itemCal.setTime(item.getStart()); - - if (itemCal.get(Calendar.DAY_OF_YEAR) != lastHeaderCal.get(Calendar.DAY_OF_YEAR) || - itemCal.get(Calendar.YEAR) != lastHeaderCal.get(Calendar.YEAR)) { - lastHeaderCal.setTimeInMillis(itemCal.getTimeInMillis()); - final DateFormatter dateFormatter = new DateFormatter(lastHeaderCal); - sortedItems.add(new EventListItem(dateFormatter.getDailyHeader())); + itemHolder.title.setText(formatter.getTitle()); + itemHolder.shortText.setText(TextUtils.isEmpty(formatter + .getShortText()) ? " " : formatter.getShortText().trim()); + int p = Utils.getProgress(item); + if (p == -1) { + itemHolder.progress.setVisibility(View.GONE); + // itemHolder.time.setTypeface(null, Typeface.NORMAL); + // itemHolder.title.setTypeface(null, Typeface.NORMAL); + // itemHolder.shortText.setTypeface(null, Typeface.NORMAL); + int dura = Utils.getDuration(item); + itemHolder.duration.setText(getContext().getString( + R.string.epg_duration_template, dura)); + } else { + itemHolder.progress.setVisibility(View.VISIBLE); + itemHolder.progress.setProgress(p); + // itemHolder.time.setTypeface(null, Typeface.BOLD); + // itemHolder.title.setTypeface(null, Typeface.BOLD); + // itemHolder.shortText.setTypeface(null, Typeface.BOLD); + int dura = Utils.getDuration(item); + int rest = dura - (dura * p / 100); + itemHolder.duration.setText(getContext().getString( + R.string.epg_duration_template_live, rest, dura)); } - - sortedItems.add(item); - } - - // fill adapter - clear(); - for(final EventListItem item : sortedItems) { - add(item); } + return view; } - private void sortItemsByChannel() { - - final EventListItem[] sortedItems = items.toArray(new EventListItem[0]); - final Comparator<EventListItem> comparator = new Comparator<EventListItem>() { - - public int compare(final EventListItem item1, final EventListItem item2) { - return Integer.valueOf(item1.getChannelNumber()).compareTo(Integer.valueOf(item2.getChannelNumber())); - } - }; - Arrays.sort(sortedItems, comparator); - - // fill adapter - clear(); - if (sortedItems.length > 0) { - add(new EventListItem(new DateFormatter(sortedItems[0].getStart()).getDailyHeader())); - } - for(final EventListItem item : sortedItems) { - add(item); - } - + protected EventFormatter getEventFormatter(Event event) { + return new EventFormatter(event); } - public void clearItems() { - items.clear(); - } }
\ No newline at end of file diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventEpgListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventEpgListActivity.java new file mode 100644 index 0000000..0cdb287 --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventEpgListActivity.java @@ -0,0 +1,239 @@ +package de.bjusystems.vdrmanager.gui; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.Spinner; +import de.bjusystems.vdrmanager.R; +import de.bjusystems.vdrmanager.app.VdrManagerApp; +import de.bjusystems.vdrmanager.data.Channel; +import de.bjusystems.vdrmanager.data.Epg; +import de.bjusystems.vdrmanager.data.EventListItem; +import de.bjusystems.vdrmanager.utils.date.DateFormatter; +import de.bjusystems.vdrmanager.utils.svdrp.ChannelClient; +import de.bjusystems.vdrmanager.utils.svdrp.EpgClient; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpAsyncListener; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpAsyncTask; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpClient; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpException; + +/** + * This class is used for showing what's current running on all channels + * + * @author bju + */ +public class EventEpgListActivity extends BaseEpgListActivity implements + OnItemClickListener, OnItemSelectedListener, SvdrpAsyncListener<Epg> { + + private final static ArrayList<Epg> CACHE = new ArrayList<Epg>(); + + protected static Date nextForceCache = null; + + private static Channel cachedChannel = null; + + Spinner channelSpinner; + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // get state + final List<Channel> channels = ChannelClient.getChannels(); + + // Attach view + setContentView(getMainLayout()); + + ListView lv = (ListView) findViewById(R.id.whatson_list); + lv.setFastScrollEnabled(true); + + // create adapter for channel spinner + final ArrayAdapter<Channel> channelSpinnerAdapter = new ArrayAdapter<Channel>( + this, android.R.layout.simple_spinner_item); + channelSpinnerAdapter + .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + channelSpinner = (Spinner) findViewById(R.id.epg_list_channel_spinner); + channelSpinner.setAdapter(channelSpinnerAdapter); + + // add channel values + // boolean useChannelNumber = Preferences.get().isShowChannelNumbers(); + for (final Channel c : channels) { + channelSpinnerAdapter.add(c); + } + // show needed items + + adapter = new ChannelEventAdapter(this); + + channelSpinner.setOnItemSelectedListener(this); + channelSpinner.setSelection(currentChannel.getNumber() - 1); + // startChannelEpgQuery(channel); + // findViewById(R.id.timer_item_channel).setVisibility(View.GONE); + // break; + + // Create adapter for EPG list + listView = (ListView) findViewById(R.id.whatson_list); + listView.setAdapter(adapter); + registerForContextMenu(listView); + + // register EPG item click + listView.setOnItemClickListener(this); + + } + + @Override + protected void onResume() { + super.onResume(); + // startEpgQuery(); + } + + public void onItemSelected(final AdapterView<?> parent, final View view, + final int position, final long id) { + + // get spinner value + final Channel channel = (Channel) channelSpinner.getSelectedItem(); + currentChannel = channel; + // setAsCurrent(channel); + // update search + startEpgQuery(); + + } + + public void onNothingSelected(final AdapterView<?> arg0) { + // startTimeEpgQuery(((EpgTimeSpinnerValue)timeSpinner.getAdapter().getItem(0)).getValue()); + } + + private void clearCache() { + cachedChannel = null; + } + + private boolean useCache(Channel channel) { + if (cachedChannel == null) { + return false; + } + if (channel.getNumber() != cachedChannel.getNumber()) { + return false; + } + if (nextForceCache == null) { + return false; + } + Date now = new Date(); + if (nextForceCache.before(now)) { + return false; + } + return true; + } + + // + + private void startEpgQuery(boolean force) { + startEpgQuery(currentChannel, force); + } + + private void startEpgQuery() { + startEpgQuery(false); + } + + private void startEpgQuery(Channel channel, boolean force) { + + if (useCache(channel) && !force) { + Calendar cal = Calendar.getInstance(); + int day = -1; + for (Epg e : CACHE) { + cal.setTime(e.getStart()); + int eday = cal.get(Calendar.DAY_OF_YEAR); + if (eday != day) { + day = eday; + adapter.add(new EventListItem(new DateFormatter(cal) + .getDailyHeader())); + } + adapter.add(new EventListItem(e)); + } + return; + } + + clearCache(); + + epgClient = new EpgClient(channel); + + // remove old listeners + // epgClient.clearSvdrpListener(); + + // create background task + final SvdrpAsyncTask<Epg, SvdrpClient<Epg>> task = new SvdrpAsyncTask<Epg, SvdrpClient<Epg>>( + epgClient); + + // create progress + progress = new SvdrpProgressDialog(this, epgClient); + // attach listener + task.addListener(this); + + // start task + task.run(); + } + + @Override + protected void finishedSuccess() { + adapter.clear(); + CACHE.clear(); + Date now = new Date(); + nextForceCache = FUTURE; + Calendar cal = Calendar.getInstance(); + int day = -1; + for (Epg e : epgClient.getResults()) { + CACHE.add(e); + cal.setTime(e.getStart()); + int eday = cal.get(Calendar.DAY_OF_YEAR); + if (eday != day) { + day = eday; + adapter.add(new EventListItem(new DateFormatter(cal) + .getDailyHeader())); + } + adapter.add(new EventListItem(e)); + if (e.getStop().before(nextForceCache) && e.getStop().after(now)) { + nextForceCache = e.getStop(); + } + } + cachedChannel = currentChannel; + listView.setSelectionAfterHeaderView(); + if (progress != null) { + progress.dismiss(); + progress = null; + } + } + + public void svdrpException(final SvdrpException exception) { + if (progress != null) { + progress.svdrpException(exception); + } + } + + protected void prepareTimer(final EventListItem item) { + final VdrManagerApp app = (VdrManagerApp) getApplication(); + app.setCurrentEvent(item.getEpg()); + app.setCurrentEpgList(CACHE); + } + + @Override + protected int getMainLayout() { + return R.layout.event_epg_list; + } + + @Override + protected void refresh() { + startEpgQuery(currentChannel, true); + } + + @Override + protected void retry() { + startEpgQuery(currentChannel, true); + } + +} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventListItemHolder.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventListItemHolder.java index bac6ebb..f7086b0 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventListItemHolder.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventListItemHolder.java @@ -1,6 +1,8 @@ package de.bjusystems.vdrmanager.gui; + import android.widget.ImageView; +import android.widget.ProgressBar; import android.widget.TextView; class EventListItemHolder { @@ -9,4 +11,7 @@ class EventListItemHolder { public TextView date; public TextView time; public TextView channel; + public TextView shortText; + public ProgressBar progress; + public TextView duration; }
\ No newline at end of file diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/PreferencesActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/PreferencesActivity.java index cb6e4d1..47cd395 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/PreferencesActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/PreferencesActivity.java @@ -1,20 +1,117 @@ package de.bjusystems.vdrmanager.gui; +import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.os.Bundle; +import android.preference.EditTextPreference; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceActivity; +import android.preference.PreferenceManager; import de.bjusystems.vdrmanager.R; import de.bjusystems.vdrmanager.app.VdrManagerApp; import de.bjusystems.vdrmanager.data.Preferences; -public class PreferencesActivity extends PreferenceActivity { +public class PreferencesActivity extends PreferenceActivity implements + OnSharedPreferenceChangeListener, OnPreferenceChangeListener, + OnPreferenceClickListener { +// +// Preference somePreference = findPreference(SOME_PREFERENCE_KEY); +// PreferenceScreen preferenceScreen = getPreferenceScreen(); +// preferenceScreen.removePreference(somePreference); +// +// you can later call: +// +// preferenceScreen.addPreference(somePreference); + private static final String TAG = "PreferencesActivity"; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); - this.getPreferenceManager().setSharedPreferencesName(Preferences.getPreferenceFile(this)); + this.getPreferenceManager().setSharedPreferencesName( + Preferences.getPreferenceFile(this)); this.addPreferencesFromResource(R.xml.preferences); + + updateChildPreferences(); + + findPreference(getString(R.string.wakeup_wol_mac_key)) + .setOnPreferenceClickListener(this); + + } + + // /** Return a properly configured SharedPreferences instance */ + public static SharedPreferences getSharedPreferences(Context context) { + return PreferenceManager.getDefaultSharedPreferences(context); + } + + @Override + protected void onPause() { + super.onPause(); + // Unregister the listener whenever a key changes + Preferences.getSharedPreferences(this) + .unregisterOnSharedPreferenceChangeListener(this); + } + + @Override + protected void onResume() { + super.onResume(); + // Set up a listener whenever a key changes + Preferences.getSharedPreferences(this) + .registerOnSharedPreferenceChangeListener(this); + + } + + private void enableWolPreferences() { + findPreference(getString(R.string.wakeup_wol_mac_key)).setEnabled(true); + findPreference(getString(R.string.wakeup_wol_custom_broadcast_key)) + .setEnabled(true); + } + + private void disableWolPreferences() { + findPreference(getString(R.string.wakeup_wol_mac_key)) + .setEnabled(false); + findPreference(getString(R.string.wakeup_wol_custom_broadcast_key)) + .setEnabled(false); + + } + + private void disableWakeupUrlPreferences() { + findPreference(getString(R.string.wakeup_url_key)).setEnabled(false); + findPreference(getString(R.string.wakeup_password_key)).setEnabled( + false); + findPreference(getString(R.string.wakeup_user_key)).setEnabled(false); + } + + private void enableWakeupUrlPrefenreces() { + findPreference(getString(R.string.wakeup_url_key)).setEnabled(true); + findPreference(getString(R.string.wakeup_password_key)) + .setEnabled(true); + findPreference(getString(R.string.wakeup_user_key)).setEnabled(true); + } + + private void updateChildPreferences() { + SharedPreferences sp = Preferences.getSharedPreferences(this); + String wakup = sp.getString(getString(R.string.wakeup_method_key), + "wol"); + + if (wakup.equals("url")) { + disableWolPreferences(); + enableWakeupUrlPrefenreces(); + } else {// remote url + disableWakeupUrlPreferences(); + enableWolPreferences(); + } + + for (String key : sp.getAll().keySet()) { + Preference p = findPreference(key); + updateSummary(p); + } + } @Override @@ -31,4 +128,203 @@ public class PreferencesActivity extends PreferenceActivity { intent.setClass(this, VdrManagerActivity.class); startActivity(intent); } + + public void onSharedPreferenceChanged(SharedPreferences arg0, String key) { + updateChildPreferences(); + Preference p = findPreference(key); + updateSummary(p); + Preferences.loadPreferences(this); + } + + public boolean onPreferenceChange(Preference arg0, Object arg1) { + return false; + } + + public boolean onPreferenceClick(Preference arg0) { + // if (arg0.getKey().equals(getString(R.string.wakeup_wol_mac_key))) { + // // if(arg0.) + // String host = Preferences.getPreferences().getSvdrpHost(); + // + // if(host == null || host.length() == 0){ + // return true; + // } + // + // try { + // Socket echoSocket = new Socket(host, 7); + // InetAddress ia = echoSocket.getInetAddress(); + // + // } catch (Exception ex){ + // Log.w(TAG,ex); + // } + // + // String mac = WakeOnLan.getMacFromArpCache(host); + // System.err.println("mac"); + // } + + return true; + } + + private void updateSummary(Preference ep) { + if (ep instanceof EditTextPreference) { + updateSummary((EditTextPreference) ep); + } else if (ep instanceof ListPreference) { + updateSummary((ListPreference) ep); + } + } + + /** + * If text set add it to the summary + * + * @param ep + */ + private void updateSummary(EditTextPreference ep) { + String text = ep.getText(); + if (text == null) { + return; + } + + CharSequence sm = ep.getSummary(); + String sum; + if (sm != null) { + sum = ep.getSummary().toString(); + sum = substringBeforeLast(sum, + getString(R.string.prefs_current_value)).trim(); + } else { + sum = ""; + } + if (isBlank(sum)) { + sum = getString(R.string.prefs_current_value_template, text); + } else { + sum = sum + " " + + getString(R.string.prefs_current_value_template, text); + } + ep.setSummary(sum); + } + + private void updateSummary(ListPreference ep) { + CharSequence text = ep.getEntry(); + + if (text == null) { + return; + } + + CharSequence sm = ep.getSummary(); + String sum; + if (sm != null) { + sum = ep.getSummary().toString(); + sum = substringBeforeLast(sum, + getString(R.string.prefs_current_value)).trim(); + } else { + sum = ""; + } + if (isBlank(sum)) { + sum = getString(R.string.prefs_current_value_template, text); + } else { + sum = sum + " " + + getString(R.string.prefs_current_value_template, text); + } + ep.setSummary(sum); + } + + /** + * <p> + * Gets the substring before the last occurrence of a separator. The + * separator is not returned. + * </p> + * + * <p> + * A <code>null</code> string input will return <code>null</code>. An empty + * ("") string input will return the empty string. An empty or + * <code>null</code> separator will return the input string. + * </p> + * + * <pre> + * StringUtils.substringBeforeLast(null, *) = null + * StringUtils.substringBeforeLast("", *) = "" + * StringUtils.substringBeforeLast("abcba", "b") = "abc" + * StringUtils.substringBeforeLast("abc", "c") = "ab" + * StringUtils.substringBeforeLast("a", "a") = "" + * StringUtils.substringBeforeLast("a", "z") = "a" + * StringUtils.substringBeforeLast("a", null) = "a" + * StringUtils.substringBeforeLast("a", "") = "a" + * </pre> + * + * @param str + * the String to get a substring from, may be null + * @param separator + * the String to search for, may be null + * @return the substring before the last occurrence of the separator, + * <code>null</code> if null String input + * @since 2.0 + */ + public static String substringBeforeLast(String str, String separator) { + if (isEmpty(str) || isEmpty(separator)) { + return str; + } + int pos = str.lastIndexOf(separator); + if (pos == -1) { + return str; + } + return str.substring(0, pos); + } + + // Empty checks + // ----------------------------------------------------------------------- + /** + * <p> + * Checks if a String is empty ("") or null. + * </p> + * + * <pre> + * StringUtils.isEmpty(null) = true + * StringUtils.isEmpty("") = true + * StringUtils.isEmpty(" ") = false + * StringUtils.isEmpty("bob") = false + * StringUtils.isEmpty(" bob ") = false + * </pre> + * + * <p> + * NOTE: This method changed in Lang version 2.0. It no longer trims the + * String. That functionality is available in isBlank(). + * </p> + * + * @param str + * the String to check, may be null + * @return <code>true</code> if the String is empty or null + */ + public static boolean isEmpty(String str) { + return str == null || str.length() == 0; + } + + /** + * <p> + * Checks if a String is whitespace, empty ("") or null. + * </p> + * + * <pre> + * StringUtils.isBlank(null) = true + * StringUtils.isBlank("") = true + * StringUtils.isBlank(" ") = true + * StringUtils.isBlank("bob") = false + * StringUtils.isBlank(" bob ") = false + * </pre> + * + * @param str + * the String to check, may be null + * @return <code>true</code> if the String is null, empty or whitespace + * @since 2.0 + */ + public static boolean isBlank(String str) { + int strLen; + if (str == null || (strLen = str.length()) == 0) { + return true; + } + for (int i = 0; i < strLen; i++) { + if ((Character.isWhitespace(str.charAt(i)) == false)) { + return false; + } + } + return true; + } + } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/RecordingListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/RecordingListActivity.java new file mode 100644 index 0000000..e88bb88 --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/RecordingListActivity.java @@ -0,0 +1,241 @@ +package de.bjusystems.vdrmanager.gui; + +import android.content.Intent; +import android.os.Bundle; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ListView; +import android.widget.Toast; +import de.bjusystems.vdrmanager.R; +import de.bjusystems.vdrmanager.app.VdrManagerApp; +import de.bjusystems.vdrmanager.data.EventFormatter; +import de.bjusystems.vdrmanager.data.EventListItem; +import de.bjusystems.vdrmanager.data.Recording; +import de.bjusystems.vdrmanager.data.Timer; +import de.bjusystems.vdrmanager.tasks.DeleteTimerTask; +import de.bjusystems.vdrmanager.tasks.ToggleTimerTask; +import de.bjusystems.vdrmanager.utils.svdrp.RecordingClient; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpAsyncListener; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpAsyncTask; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpClient; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpEvent; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpException; +import de.bjusystems.vdrmanager.utils.svdrp.TimerClient; + +/** + * This class is used for showing what's current running on all channels + * + * @author bju + */ +public class RecordingListActivity extends BaseActivity implements + OnItemClickListener, SvdrpAsyncListener<Recording> { + + RecordingClient recordingClient; + EventAdapter adapter; + SvdrpProgressDialog progress; + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // set title + setTitle(R.string.action_menu_timers); + + // Attach view + setContentView(getMainLayout()); + + // create an adapter + adapter = new TimeEventAdapter(this); + + // attach adapter to ListView + final ListView listView = (ListView) findViewById(R.id.recording_list); + listView.setAdapter(adapter); + + // set click listener + listView.setOnItemClickListener(this); + + // context menu wanted + registerForContextMenu(listView); + + // start query + startRecordingQuery(); + } + + @Override + protected void onResume() { + super.onResume(); + } + + protected void updateWindowTitle(int topic, int subtopic) { + String title; + title = getString(topic); + if (subtopic != -1) { + title += " > " + getString(subtopic); + } + setTitle(title); + } + + @Override + protected void onPause() { + super.onPause(); + if (recordingClient != null) { + recordingClient.abort(); + } + if (progress != null) { + progress.dismiss(); + progress = null; + } + } + + @Override + public void onCreateContextMenu(final ContextMenu menu, final View v, + final ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + + if (v.getId() == R.id.recording_list) { + final MenuInflater inflater = getMenuInflater(); + final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; + + // set menu title + final EventListItem item = adapter.getItem(info.position); + final EventFormatter formatter = new EventFormatter(item); + menu.setHeaderTitle(formatter.getTitle()); + + inflater.inflate(R.menu.recording_list_item_menu, menu); + } + } + + @Override + public boolean onContextItemSelected(final MenuItem item) { + + final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item + .getMenuInfo(); + final EventListItem event = adapter.getItem(info.position); + + switch (item.getItemId()) { + case R.id.recording_item_menu_delete: { + + break; + } + case R.id.recording_item_menu_stream: { + break; + } + } + return true; + } + + public void onItemClick(final AdapterView<?> parent, final View view, + final int position, final long id) { + + // save selected item + final Timer timer = adapter.getItem(position).getTimer(); + if (timer == null) { + // header click + return; + } + + final VdrManagerApp app = (VdrManagerApp) getApplication(); + app.setCurrentTimer(timer); + + // after timer editing return to the timer list + app.setNextActivity(RecordingListActivity.class); + app.clearActivitiesToFinish(); + + // show timer details + final Intent intent = new Intent(); + intent.setClass(this, TimerDetailsActivity.class); + startActivity(intent); + } + + private void startRecordingQuery() { + + // get timer client + recordingClient = new RecordingClient(); + + // create backgound task + final SvdrpAsyncTask<Recording, SvdrpClient<Recording>> task = new SvdrpAsyncTask<Recording, SvdrpClient<Recording>>( + recordingClient); + + // create progress dialog + progress = new SvdrpProgressDialog(this, recordingClient); + + // attach listener + task.addListener(this); + + // start task + task.run(); + } + + public void svdrpEvent(final SvdrpEvent event, final Recording result) { + + if (progress != null) { + progress.svdrpEvent(event); + } + + switch (event) { + case CONNECTING: + break; + case FINISHED_ABNORMALY: + case CONNECT_ERROR: + switchNoConnection();// TODO pass arg, what is the problem + case LOGIN_ERROR: + progress.dismiss(); + switchNoConnection(); + break; + case FINISHED_SUCCESS: + adapter.clear(); + for (final Recording rec : recordingClient.getResults()) { + adapter.add(new EventListItem(rec)); + } + // adapter.sortItems(); + if (progress != null) { + progress.dismiss(); + progress = null; + } + if (recordingClient.getResults().isEmpty()) { + Toast.makeText(RecordingListActivity.this, + R.string.epg_no_items, Toast.LENGTH_SHORT).show(); + } + break; + } + } + + public void svdrpException(final SvdrpException exception) { + if (progress != null) { + progress.svdrpException(exception); + } + } + + private void deleteTimer(final EventListItem item) { + + final DeleteTimerTask task = new DeleteTimerTask(this, item.getTimer()) { + @Override + public void finished() { + // refresh epg list after return + final VdrManagerApp app = (VdrManagerApp) getApplication(); + app.setReload(true); + } + }; + task.start(); + } + + protected void retry() { + startRecordingQuery(); + } + + protected void refresh() { + startRecordingQuery(); + } + + @Override + protected int getMainLayout() { + return R.layout.recording_list; + } + + +} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/SimpleGestureFilter.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/SimpleGestureFilter.java new file mode 100644 index 0000000..85b6b5d --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/SimpleGestureFilter.java @@ -0,0 +1,169 @@ +package de.bjusystems.vdrmanager.gui; + +import android.app.Activity; +import android.view.GestureDetector; +import android.view.GestureDetector.SimpleOnGestureListener; +import android.view.MotionEvent; + +public class SimpleGestureFilter extends SimpleOnGestureListener{ + + public final static int SWIPE_UP = 1; + public final static int SWIPE_DOWN = 2; + public final static int SWIPE_LEFT = 3; + public final static int SWIPE_RIGHT = 4; + + public final static int MODE_TRANSPARENT = 0; + public final static int MODE_SOLID = 1; + public final static int MODE_DYNAMIC = 2; + + private final static int ACTION_FAKE = -13; //just an unlikely number + private int swipe_Min_Distance = 100; + private int swipe_Max_Distance = 350; + private int swipe_Min_Velocity = 100; + + private int mode = MODE_DYNAMIC; + private boolean running = true; + private boolean tapIndicator = false; + + private Activity context; + private GestureDetector detector; + private SimpleGestureListener listener; + + + public SimpleGestureFilter(Activity context, SimpleGestureListener sgl) { + + this.context = context; + this.detector = new GestureDetector(context, this); + this.listener = sgl; + } + + public void onTouchEvent(MotionEvent event){ + + if(!this.running) + return; + + boolean result = this.detector.onTouchEvent(event); + + if(this.mode == MODE_SOLID) + event.setAction(MotionEvent.ACTION_CANCEL); + else if (this.mode == MODE_DYNAMIC) { + + if(event.getAction() == ACTION_FAKE) + event.setAction(MotionEvent.ACTION_UP); + else if (result) + event.setAction(MotionEvent.ACTION_CANCEL); + else if(this.tapIndicator){ + event.setAction(MotionEvent.ACTION_DOWN); + this.tapIndicator = false; + } + + } + //else just do nothing, it's Transparent + } + + public void setMode(int m){ + this.mode = m; + } + + public int getMode(){ + return this.mode; + } + + public void setEnabled(boolean status){ + this.running = status; + } + + public void setSwipeMaxDistance(int distance){ + this.swipe_Max_Distance = distance; + } + + public void setSwipeMinDistance(int distance){ + this.swipe_Min_Distance = distance; + } + + public void setSwipeMinVelocity(int distance){ + this.swipe_Min_Velocity = distance; + } + + public int getSwipeMaxDistance(){ + return this.swipe_Max_Distance; + } + + public int getSwipeMinDistance(){ + return this.swipe_Min_Distance; + } + + public int getSwipeMinVelocity(){ + return this.swipe_Min_Velocity; + } + + + @Override + public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, + float velocityY) { + + final float xDistance = Math.abs(e1.getX() - e2.getX()); + final float yDistance = Math.abs(e1.getY() - e2.getY()); + + if(xDistance > this.swipe_Max_Distance || yDistance > this.swipe_Max_Distance) + return false; + + velocityX = Math.abs(velocityX); + velocityY = Math.abs(velocityY); + boolean result = false; + + if(velocityX > this.swipe_Min_Velocity && xDistance > this.swipe_Min_Distance){ + if(e1.getX() > e2.getX()) // right to left + this.listener.onSwipe(SWIPE_LEFT); + else + this.listener.onSwipe(SWIPE_RIGHT); + + result = true; + } + else if(velocityY > this.swipe_Min_Velocity && yDistance > this.swipe_Min_Distance){ + if(e1.getY() > e2.getY()) // bottom to up + this.listener.onSwipe(SWIPE_UP); + else + this.listener.onSwipe(SWIPE_DOWN); + + result = true; + } + + return result; + } + + @Override + public boolean onSingleTapUp(MotionEvent e) { + this.tapIndicator = true; + return false; + } + + @Override + public boolean onDoubleTap(MotionEvent arg0) { + this.listener.onDoubleTap();; + return true; + } + + @Override + public boolean onDoubleTapEvent(MotionEvent arg0) { + return true; + } + + @Override + public boolean onSingleTapConfirmed(MotionEvent arg0) { + + if(this.mode == MODE_DYNAMIC){ // we owe an ACTION_UP, so we fake an + arg0.setAction(ACTION_FAKE); //action which will be converted to an ACTION_UP later. + this.context.dispatchTouchEvent(arg0); + } + + return false; + } + + + static interface SimpleGestureListener{ + void onSwipe(int direction); + void onDoubleTap(); + } + + }
\ No newline at end of file diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/SvdrpProgressDialog.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/SvdrpProgressDialog.java index e630ff9..8997214 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/SvdrpProgressDialog.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/SvdrpProgressDialog.java @@ -2,6 +2,7 @@ package de.bjusystems.vdrmanager.gui; import android.app.Activity; import android.app.ProgressDialog; +import android.util.Log; import android.widget.Toast; import de.bjusystems.vdrmanager.R; import de.bjusystems.vdrmanager.utils.svdrp.SvdrpClient; @@ -10,25 +11,34 @@ import de.bjusystems.vdrmanager.utils.svdrp.SvdrpException; public class SvdrpProgressDialog extends ProgressDialog { + private static final String TAG = SvdrpProgressDialog.class.getName(); ProgressDialog progress; Activity activity; SvdrpClient<? extends Object> client; - public SvdrpProgressDialog(final Activity activity, final SvdrpClient<? extends Object> client) { + public SvdrpProgressDialog(final Activity activity, + final SvdrpClient<? extends Object> client) { super(activity); this.activity = activity; this.client = client; + progress = new ProgressDialog(activity); } public void svdrpEvent(final SvdrpEvent event) { + svdrpEvent(event, null); + } + public void svdrpEvent(final SvdrpEvent event, Throwable error) { switch (event) { case CONNECTING: - progress = new ProgressDialog(activity); progress.setProgressStyle(ProgressDialog.STYLE_SPINNER); setMessage(R.string.progress_connect); progress.show(); break; + case CONNECT_ERROR: + progress.dismiss(); + showToast(R.string.progress_connect_error); + break; case LOGGED_IN: setMessage(R.string.progress_login); break; @@ -46,27 +56,47 @@ public class SvdrpProgressDialog extends ProgressDialog { break; case DISCONNECTED: break; - case FINISHED: + case FINISHED_ABNORMALY: + progress.dismiss(); + if (error == null) { + showToast(R.string.progress_connect_finished_abnormal); + } else { + showToast(R.string.progress_connect_finished_abnormal_arg, + error.getMessage()); + } + case FINISHED_SUCCESS: + progress.dismiss(); + break; + case CACHE_HIT: progress.dismiss(); + setMessage(R.string.progress_cache_hit); break; } } public void svdrpException(final SvdrpException exception) { - showToast(R.string.vdr_error_text); + Log.w(TAG, String.valueOf(activity), exception); + showToast(R.string.vdr_error_text, exception.getMessage()); } - private void setMessage(final int resId) { - progress.setMessage(activity.getText(resId)); + private void setMessage(final int resId, Object... args) { + if (args.length == 0) { + progress.setMessage(activity.getText(resId)); + } else { + progress.setMessage(activity.getString(resId, args)); + } } - private void showToast(final int resId) { + private void showToast(final int resId, Object... args) { progress.dismiss(); - - final CharSequence text = activity.getText(resId); - final int duration = Toast.LENGTH_LONG; + final CharSequence text = args.length == 0 ? activity.getString(resId) + : activity.getString(resId, args); + final int duration = Toast.LENGTH_SHORT; final Toast toast = Toast.makeText(activity, text, duration); toast.show(); } + + public void dismiss(){ + progress.dismiss(); + } } - diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimeEpgListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimeEpgListActivity.java new file mode 100644 index 0000000..278b8d3 --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimeEpgListActivity.java @@ -0,0 +1,258 @@ +package de.bjusystems.vdrmanager.gui; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.Spinner; +import de.bjusystems.vdrmanager.R; +import de.bjusystems.vdrmanager.app.VdrManagerApp; +import de.bjusystems.vdrmanager.data.Epg; +import de.bjusystems.vdrmanager.data.EpgSearchTimeValue; +import de.bjusystems.vdrmanager.data.EpgSearchTimeValues; +import de.bjusystems.vdrmanager.data.EventListItem; +import de.bjusystems.vdrmanager.utils.date.DateFormatter; +import de.bjusystems.vdrmanager.utils.svdrp.EpgClient; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpAsyncListener; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpAsyncTask; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpClient; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpException; + +/** + * This class is used for showing what's current running on all channels + * + * @author bju + */ +public class TimeEpgListActivity extends BaseEpgListActivity implements + OnItemClickListener, OnItemSelectedListener, SvdrpAsyncListener<Epg> { + + Spinner timeSpinner; + + ArrayAdapter<EpgSearchTimeValue> timeSpinnerAdapter; + + protected static Date nextForceCache = null; + + private final static ArrayList<Epg> CACHE = new ArrayList<Epg>(); + + private static String cachedTime = null; + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Attach view + setContentView(getMainLayout()); + + ListView lv = (ListView) findViewById(R.id.whatson_list); + lv.setFastScrollEnabled(true); + + // create adapter for time spinner + timeSpinnerAdapter = new ArrayAdapter<EpgSearchTimeValue>(this, + android.R.layout.simple_spinner_item); + timeSpinnerAdapter + .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + timeSpinner = (Spinner) findViewById(R.id.epg_list_time_spinner); + timeSpinner.setAdapter(timeSpinnerAdapter); + + fillTimeSpinnerValues(); + + // update gui + adapter = new TimeEventAdapter(this); + // searchLabel.setVisibility(View.GONE); + timeSpinner.setOnItemSelectedListener(this); + timeSpinner.setSelection(0); + + // Create adapter for EPG list + listView = (ListView) findViewById(R.id.whatson_list); + listView.setAdapter(adapter); + registerForContextMenu(listView); + + // register EPG item click + listView.setOnItemClickListener(this); + + } + + private void fillTimeSpinnerValues() { + final EpgSearchTimeValues values = new EpgSearchTimeValues(this); + timeSpinnerAdapter.clear(); + for (final EpgSearchTimeValue value : values.getValues()) { + timeSpinnerAdapter.add(value); + } + } + + private int currentPostion = 0; + + @Override + protected void onPause() { + super.onPause(); + + } + + + + @Override + protected void onResume() { + super.onResume(); + } + + public void onItemSelected(final AdapterView<?> parent, final View view, + final int position, final long id) { + + // get spinner value + final EpgSearchTimeValue selection = (EpgSearchTimeValue) timeSpinner + .getSelectedItem(); + // update search + startEpgQuery(selection.getValue(), false); + + } + + public void onNothingSelected(final AdapterView<?> arg0) { + // startTimeEpgQuery(((EpgTimeSpinnerValue)timeSpinner.getAdapter().getItem(0)).getValue()); + } + + private void clearCache() { + cachedTime = null; + } + + private boolean useCache(String time) { + + if (cachedTime == null) { + return false; + } + + if (cachedTime.equals(time) == false) { + return false; + } + + if (nextForceCache == null) { + return false; + } + Date now = new Date(); + if (nextForceCache.before(now)) { + return false; + } + return true; + } + + private void startEpgQuery(String time, boolean force) { + + if (useCache(time) && !force) { + // TODO unschön, refactor to have one code for filling adapter. + adapter.clear(); + if (CACHE.isEmpty() == false) { + adapter.add(new EventListItem(new DateFormatter(CACHE.get(0) + .getStart()).getDailyHeader())); + } + for (Epg e : CACHE) { + adapter.add(new EventListItem(e)); + } + // adapter.sortItems(); + listView.setSelectionAfterHeaderView(); + return; + } + + clearCache(); + + epgClient = new EpgClient(time); + + // remove old listeners + // epgClient.clearSvdrpListener(); + + // create background task + final SvdrpAsyncTask<Epg, SvdrpClient<Epg>> task = new SvdrpAsyncTask<Epg, SvdrpClient<Epg>>( + epgClient); + + // create progress + progress = new SvdrpProgressDialog(this, epgClient); + // attach listener + task.addListener(this); + + // start task + task.run(); + } + + @Override + protected void finishedSuccess() { + // get spinner value + final EpgSearchTimeValue selection = (EpgSearchTimeValue) timeSpinner + .getSelectedItem(); + setTitle(getString(R.string.epg_of_a_channel, selection)); + adapter.clear(); + CACHE.clear(); + nextForceCache = FUTURE; + cachedTime = selection.getValue(); + Date now = new Date(); + List<Epg> results = epgClient.getResults(); + sortItemsByChannel(results); + if (results.isEmpty() == false) { + adapter.add(new EventListItem(new DateFormatter(results.get(0) + .getStart()).getDailyHeader())); + } + for (Epg e : results) { + CACHE.add(e); + adapter.add(new EventListItem(e)); + if (e.getStop().before(nextForceCache) && e.getStop().after(now)) { + nextForceCache = e.getStop(); + } + } + listView.setSelectionAfterHeaderView(); + if (progress != null) { + progress.dismiss(); + progress = null; + } + } + + public void svdrpException(final SvdrpException exception) { + if (progress != null) { + progress.svdrpException(exception); + } + } + + private void sortItemsByChannel(List<Epg> result) { + final Comparator<Epg> comparator = new Comparator<Epg>() { + + public int compare(final Epg item1, final Epg item2) { + return Integer.valueOf(item1.getChannelNumber()).compareTo( + Integer.valueOf(item2.getChannelNumber())); + } + }; + Collections.sort(result, comparator); + } + + protected void prepareTimer(final EventListItem item) { + final VdrManagerApp app = (VdrManagerApp) getApplication(); + + // remember event for details view and timer things + app.setCurrentEvent(item.getEpg()); + app.setCurrentEpgList(CACHE); + } + + @Override + protected int getMainLayout() { + return R.layout.time_epg_list; + } + + @Override + protected void refresh() { + // get spi + final EpgSearchTimeValue selection = (EpgSearchTimeValue) timeSpinner + .getSelectedItem(); + // update search + startEpgQuery(selection.getValue(), true); + } + + @Override + protected void retry() { + refresh(); + } + +} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimeEventAdapter.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimeEventAdapter.java new file mode 100644 index 0000000..dc7545e --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimeEventAdapter.java @@ -0,0 +1,22 @@ +package de.bjusystems.vdrmanager.gui; + +import android.content.Context; +import de.bjusystems.vdrmanager.R; +import de.bjusystems.vdrmanager.data.Event; +import de.bjusystems.vdrmanager.data.EventFormatter; + +public class TimeEventAdapter extends EventAdapter { + + public TimeEventAdapter(final Context context) { + super(context, R.layout.epg_event_item); + } + + public void sortItems() { + // sortItemsByChannel(); + } + + @Override + protected EventFormatter getEventFormatter(Event event) { + return new EventFormatter(event,true); + } +}
\ No newline at end of file diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerDetailsActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerDetailsActivity.java index 60db80c..10f1822 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerDetailsActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerDetailsActivity.java @@ -29,12 +29,12 @@ import de.bjusystems.vdrmanager.utils.svdrp.SvdrpEvent; import de.bjusystems.vdrmanager.utils.svdrp.SvdrpException; /** - * This class is used for showing what's - * current running on all channels + * This class is used for showing what's current running on all channels + * * @author bju */ -public class TimerDetailsActivity extends Activity - implements OnClickListener, OnDateSetListener, OnTimeSetListener, SvdrpAsyncListener<Timer> { +public class TimerDetailsActivity extends Activity implements OnClickListener, + OnDateSetListener, OnTimeSetListener, SvdrpAsyncListener<Timer> { Preferences prefs; TextView dateField; @@ -52,25 +52,25 @@ public class TimerDetailsActivity extends Activity // Attach view setContentView(R.layout.timer_detail); - // timer - timer = ((VdrManagerApp)getApplication()).getCurrentTimer(); - - // update display - updateDisplay(); - - // register buttons - final Button saveButton = (Button) findViewById(R.id.timer_details_save); - saveButton.setOnClickListener(this); - if (timer.getNumber() > 0) { - saveButton.setText(R.string.timer_details_save_title); - } else { - saveButton.setText(R.string.timer_details_create_title); - } - - // register text fields for editing - dateField.setOnClickListener(this); - startField.setOnClickListener(this); - endField.setOnClickListener(this); + // timer + timer = ((VdrManagerApp) getApplication()).getCurrentTimer(); + + // update display + updateDisplay(); + + // register buttons + final Button saveButton = (Button) findViewById(R.id.timer_details_save); + saveButton.setOnClickListener(this); + if (timer.getNumber() > 0) { + saveButton.setText(R.string.timer_details_save_title); + } else { + saveButton.setText(R.string.timer_details_create_title); + } + + // register text fields for editing + dateField.setOnClickListener(this); + startField.setOnClickListener(this); + endField.setOnClickListener(this); } @Override @@ -85,45 +85,46 @@ public class TimerDetailsActivity extends Activity public void onClick(final View view) { switch (view.getId()) { - case R.id.timer_detail_day: - { + case R.id.timer_detail_day: { final Calendar cal = new GregorianCalendar(); cal.setTime(timer.getStart()); - final DatePickerDialog dialog = new DatePickerDialog(this, this, cal.get(Calendar.YEAR), - cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)); + final DatePickerDialog dialog = new DatePickerDialog(this, this, + cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), + cal.get(Calendar.DAY_OF_MONTH)); dialog.show(); break; } - case R.id.timer_detail_start: - { + case R.id.timer_detail_start: { final Calendar cal = new GregorianCalendar(); cal.setTime(timer.getStart()); editStart = true; - final TimePickerDialog dialog = new TimePickerDialog(this, this, cal.get(Calendar.HOUR_OF_DAY), - cal.get(Calendar.MINUTE), true); + final TimePickerDialog dialog = new TimePickerDialog(this, this, + cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), + true); dialog.show(); break; } - case R.id.timer_detail_end: - { + case R.id.timer_detail_end: { final Calendar cal = new GregorianCalendar(); cal.setTime(timer.getStop()); editStart = false; - final TimePickerDialog dialog = new TimePickerDialog(this, this, cal.get(Calendar.HOUR_OF_DAY), - cal.get(Calendar.MINUTE), true); + final TimePickerDialog dialog = new TimePickerDialog(this, this, + cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), + true); dialog.show(); break; } - case R.id.timer_details_save: - { + case R.id.timer_details_save: { // collect values - timer.setTitle(((TextView)findViewById(R.id.timer_detail_title)).getText().toString()); + timer.setTitle(((TextView) findViewById(R.id.timer_detail_title)) + .getText().toString()); // create client for saving the timer setTimerClient = new SetTimerClient(timer, false); // create backgound task - final SvdrpAsyncTask<Timer, SvdrpClient<Timer>> task = new SvdrpAsyncTask<Timer, SvdrpClient<Timer>>(setTimerClient); + final SvdrpAsyncTask<Timer, SvdrpClient<Timer>> task = new SvdrpAsyncTask<Timer, SvdrpClient<Timer>>( + setTimerClient); // create progress progress = new SvdrpProgressDialog(this, setTimerClient); @@ -137,21 +138,27 @@ public class TimerDetailsActivity extends Activity } } - public void onTimeSet(final TimePicker view, final int hourOfDay, final int minute) { + public void onTimeSet(final TimePicker view, final int hourOfDay, + final int minute) { if (editStart) { - timer.setStart(calculateTime(timer.getStart(), hourOfDay, minute, null)); + timer.setStart(calculateTime(timer.getStart(), hourOfDay, minute, + null)); } else { - timer.setStop(calculateTime(timer.getStop(), hourOfDay, minute, timer.getStart())); + timer.setStop(calculateTime(timer.getStop(), hourOfDay, minute, + timer.getStart())); } updateDisplay(); } - public void onDateSet(final DatePicker view, final int year, final int monthOfYear, final int dayOfMonth) { - timer.setStart(calculateDate(timer.getStart(), year, monthOfYear, dayOfMonth)); + public void onDateSet(final DatePicker view, final int year, + final int monthOfYear, final int dayOfMonth) { + timer.setStart(calculateDate(timer.getStart(), year, monthOfYear, + dayOfMonth)); updateDisplay(); } - private Date calculateDate(final Date oldDate, final int year, final int monthOfYear, final int dayOfMonth) { + private Date calculateDate(final Date oldDate, final int year, + final int monthOfYear, final int dayOfMonth) { final Calendar cal = new GregorianCalendar(); cal.setTime(oldDate); @@ -162,7 +169,8 @@ public class TimerDetailsActivity extends Activity return cal.getTime(); } - private Date calculateTime(final Date oldTime, final int hourOfDay, final int minute, final Date startTime) { + private Date calculateTime(final Date oldTime, final int hourOfDay, + final int minute, final Date startTime) { // set hour and minute final Calendar cal = new GregorianCalendar(); @@ -183,24 +191,26 @@ public class TimerDetailsActivity extends Activity private void updateDisplay() { - ((TextView)findViewById(R.id.timer_detail_title)).setText(timer.getTitle()); - ((TextView)findViewById(R.id.timer_detail_channel)).setText(timer.getChannelName()); - dateField = (TextView)findViewById(R.id.timer_detail_day); - final DateFormatter dateFormatter = new DateFormatter(timer.getStart()); - dateField.setText(dateFormatter.getDateString()); - startField = (TextView)findViewById(R.id.timer_detail_start); - startField.setText(dateFormatter.getTimeString()); - endField = (TextView)findViewById(R.id.timer_detail_end); - endField.setText(new DateFormatter(timer.getStop()).getTimeString()); - - final Button button = (Button) findViewById(R.id.timer_details_save); - if (timer.getNumber() > 0) { - // existing timer - button.setText(R.string.timer_details_save_title); - } else { - // new timer - button.setText(R.string.timer_details_create_title); - } + ((TextView) findViewById(R.id.timer_detail_title)).setText(timer + .getTitle()); + ((TextView) findViewById(R.id.timer_detail_channel)).setText(timer + .getChannelName()); + dateField = (TextView) findViewById(R.id.timer_detail_day); + final DateFormatter dateFormatter = new DateFormatter(timer.getStart()); + dateField.setText(dateFormatter.getDateString()); + startField = (TextView) findViewById(R.id.timer_detail_start); + startField.setText(dateFormatter.getTimeString()); + endField = (TextView) findViewById(R.id.timer_detail_end); + endField.setText(new DateFormatter(timer.getStop()).getTimeString()); + + final Button button = (Button) findViewById(R.id.timer_details_save); + if (timer.getNumber() > 0) { + // existing timer + button.setText(R.string.timer_details_save_title); + } else { + // new timer + button.setText(R.string.timer_details_create_title); + } } public void svdrpEvent(final SvdrpEvent event, final Timer result) { @@ -208,20 +218,20 @@ public class TimerDetailsActivity extends Activity progress.svdrpEvent(event); switch (event) { - case FINISHED: - // remove this activity from stack + case FINISHED_ABNORMALY: + finish(); + if(progress != null) { + progress.dismiss(); + progress = null; + } + break; + case FINISHED_SUCCESS: + if(progress != null){ + progress.dismiss(); + progress = null; + } + setResult(Activity.RESULT_OK); finish(); - - // finish previous activities - final VdrManagerApp app = (VdrManagerApp) getApplication(); - app.finishActivities(); - - // refresh last view - app.setReload(true); - - // free progress dialog - progress = null; - break; } } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerListActivity.java index 52fa1e0..7cf96c0 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerListActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerListActivity.java @@ -1,6 +1,5 @@ package de.bjusystems.vdrmanager.gui; -import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.ContextMenu; @@ -11,6 +10,7 @@ import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; +import android.widget.Toast; import de.bjusystems.vdrmanager.R; import de.bjusystems.vdrmanager.app.VdrManagerApp; import de.bjusystems.vdrmanager.data.EventFormatter; @@ -26,13 +26,16 @@ import de.bjusystems.vdrmanager.utils.svdrp.SvdrpException; import de.bjusystems.vdrmanager.utils.svdrp.TimerClient; /** - * This class is used for showing what's - * current running on all channels + * This class is used for showing what's current running on all channels + * * @author bju */ -public class TimerListActivity extends Activity - implements OnItemClickListener, SvdrpAsyncListener<Timer> { +public class TimerListActivity extends BaseActivity implements + OnItemClickListener, SvdrpAsyncListener<Timer> { + + private static final int REQUEST_CODE_TIMED_EDIT = 41; + TimerClient timerClient; EventAdapter adapter; SvdrpProgressDialog progress; @@ -41,11 +44,14 @@ public class TimerListActivity extends Activity protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); + // set title + setTitle(R.string.action_menu_timers); + // Attach view - setContentView(R.layout.timer_list); + setContentView(getMainLayout()); // create an adapter - adapter = new EventAdapter(this, true); + adapter = new TimeEventAdapter(this); // attach adapter to ListView final ListView listView = (ListView) findViewById(R.id.timer_list); @@ -59,7 +65,7 @@ public class TimerListActivity extends Activity // start query startTimerQuery(); - } + } @Override protected void onResume() { @@ -76,6 +82,15 @@ public class TimerListActivity extends Activity } } + protected void updateWindowTitle(int topic, int subtopic) { + String title; + title = getString(topic); + if (subtopic != -1) { + title += " > " + getString(subtopic); + } + setTitle(title); + } + @Override protected void onPause() { super.onPause(); @@ -89,56 +104,57 @@ public class TimerListActivity extends Activity } @Override - public void onCreateContextMenu(final ContextMenu menu, final View v, final ContextMenuInfo menuInfo) { + public void onCreateContextMenu(final ContextMenu menu, final View v, + final ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); if (v.getId() == R.id.timer_list) { - final MenuInflater inflater = getMenuInflater(); - final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo; - - // set menu title - final EventListItem item = adapter.getItem(info.position); - final EventFormatter formatter = new EventFormatter(item); - menu.setHeaderTitle(formatter.getTitle()); - - inflater.inflate(R.menu.epg_list_item_menu, menu); - - // remove unneeded menu items - menu.findItem(R.id.epg_item_menu_timer_add).setVisible(false); - final MenuItem enableMenuItem = menu.findItem(R.id.epg_item_menu_timer_toggle); - enableMenuItem.setTitle(item.getTimer().isEnabled() ? R.string.epg_item_menu_timer_disable : R.string.epg_item_menu_timer_enable); - } - } - - - - @Override - public boolean onContextItemSelected(final MenuItem item) { - - final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); - final EventListItem event = adapter.getItem(info.position); - - switch (item.getItemId()) { - case R.id.epg_item_menu_timer_modify: - { - onItemClick(null, null, info.position, 0); - break; - } - case R.id.epg_item_menu_timer_delete: - { - deleteTimer(event); - break; - } - case R.id.epg_item_menu_timer_toggle: - { - toggleTimer(event); - } + final MenuInflater inflater = getMenuInflater(); + final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; + + // set menu title + final EventListItem item = adapter.getItem(info.position); + final EventFormatter formatter = new EventFormatter(item); + menu.setHeaderTitle(formatter.getTitle()); + + inflater.inflate(R.menu.epg_list_item_menu, menu); + + // remove unneeded menu items + menu.findItem(R.id.epg_item_menu_timer_add).setVisible(false); + final MenuItem enableMenuItem = menu + .findItem(R.id.epg_item_menu_timer_toggle); + enableMenuItem + .setTitle(item.getTimer().isEnabled() ? R.string.epg_item_menu_timer_disable + : R.string.epg_item_menu_timer_enable); } - - return true; } - - public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) { +// +// @Override +// public boolean onContextItemSelected(final MenuItem item) { +// +// final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item +// .getMenuInfo(); +// final EventListItem event = adapter.getItem(info.position); +// +// switch (item.getItemId()) { +// case R.id.epg_item_menu_timer_modify: { +// onItemClick(null, null, info.position, 0); +// break; +// } +// case R.id.epg_item_menu_timer_delete: { +// deleteTimer(event); +// break; +// } +// case R.id.epg_item_menu_timer_toggle: { +// toggleTimer(event); +// } +// } +// +// return true; +// } + + public void onItemClick(final AdapterView<?> parent, final View view, + final int position, final long id) { // save selected item final Timer timer = adapter.getItem(position).getTimer(); @@ -147,16 +163,13 @@ public class TimerListActivity extends Activity return; } - final VdrManagerApp app = (VdrManagerApp) getApplication(); - app.setCurrentTimer(timer); - // after timer editing return to the timer list - app.setNextActivity(TimerListActivity.class); - app.clearActivitiesToFinish(); + //timer.getChannelName() + //timer.getEvent(); - // show timer details + // show details final Intent intent = new Intent(); - intent.setClass(this, TimerDetailsActivity.class); + intent.setClass(this, EpgDetailsActivity.class); startActivity(intent); } @@ -166,7 +179,8 @@ public class TimerListActivity extends Activity timerClient = new TimerClient(); // create backgound task - final SvdrpAsyncTask<Timer, SvdrpClient<Timer>> task = new SvdrpAsyncTask<Timer, SvdrpClient<Timer>>(timerClient); + final SvdrpAsyncTask<Timer, SvdrpClient<Timer>> task = new SvdrpAsyncTask<Timer, SvdrpClient<Timer>>( + timerClient); // create progress dialog progress = new SvdrpProgressDialog(this, timerClient); @@ -186,17 +200,26 @@ public class TimerListActivity extends Activity switch (event) { case CONNECTING: - adapter.clearItems(); break; + case FINISHED_ABNORMALY: + case CONNECT_ERROR: + switchNoConnection();// TODO pass arg, what is the problem case LOGIN_ERROR: - this.finish(); + progress.dismiss(); + switchNoConnection(); break; - case FINISHED: - for(final Timer timer : timerClient.getResults()) { - adapter.addItem(new EventListItem(timer)); + case FINISHED_SUCCESS: + adapter.clear(); + for (final Timer timer : timerClient.getResults()) { + adapter.add(new EventListItem(timer)); } - adapter.sortItems(); + // adapter.sortItems(); + progress.dismiss(); progress = null; + if (timerClient.getResults().isEmpty()) { + Toast.makeText(TimerListActivity.this, R.string.epg_no_items, + Toast.LENGTH_SHORT).show(); + } break; } } @@ -221,6 +244,41 @@ public class TimerListActivity extends Activity task.start(); } + @Override + public boolean onContextItemSelected(final MenuItem item) { + + final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item + .getMenuInfo(); + final EventListItem event = adapter.getItem(info.position); + + switch (item.getItemId()) { + case R.id.epg_item_menu_timer_add: + case R.id.epg_item_menu_timer_modify: { + //prepareTimer(event); + final Intent intent = new Intent(); + intent.setClass(this, TimerDetailsActivity.class); + startActivityForResult(intent, REQUEST_CODE_TIMED_EDIT); + break; + } + case R.id.epg_item_menu_timer_delete: { + deleteTimer(event); + break; + } + case R.id.epg_item_menu_timer_toggle: { + toggleTimer(event); + break; + } + case R.id.epg_item_menu_live_tv: { + Utils.stream(this, event.getEvent()); + break; + + } + } + + return true; + } + + private void toggleTimer(final EventListItem item) { final ToggleTimerTask task = new ToggleTimerTask(this, item.getTimer()) { @@ -235,4 +293,17 @@ public class TimerListActivity extends Activity task.start(); } + protected void retry() { + startTimerQuery(); + } + + protected void refresh() { + startTimerQuery(); + } + + @Override + protected int getMainLayout() { + return R.layout.timer_list; + } + } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/Utils.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/Utils.java new file mode 100644 index 0000000..ee2ac5f --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/Utils.java @@ -0,0 +1,78 @@ +package de.bjusystems.vdrmanager.gui; + +import java.util.Date; + +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; + +import de.bjusystems.vdrmanager.data.Channel; +import de.bjusystems.vdrmanager.data.Event; +import de.bjusystems.vdrmanager.data.Preferences; + +public class Utils { + + public static int getProgress(Date start, Date stop) { + long now = System.currentTimeMillis(); + return getProgress(now, start.getTime(), stop.getTime()); + } + + public static int getProgress(Event e) { + return getProgress(e.getStart(), e.getStop()); + } + + /** + * @param now + * @param time + * @param time2 + * @return -1, is not not between start stop, + */ + private static int getProgress(long now, long start, long stop) { + if (now >= start && now <= stop) { + long dura = stop - start; + long prog = now - start; + return (int) (prog * 100 / dura); + } + return -1; + } + + public static boolean isLive(Event event){ + long now = new Date().getTime(); + return now >= event.getStart().getTime() && now < event.getStop().getTime(); + } + + private static String getStreamUrl(String chn) { + // "http://192.168.1.119:3000/TS/" + StringBuilder sb = new StringBuilder(); + Preferences p = Preferences.getPreferences(); + sb.append("http://").append(p.getSvdrpHost()).append(":") + .append(p.getStreamPort()).append("/") + .append(p.getStreamFormat()).append("/").append(chn); + return sb.toString(); + } + + + public static void stream(Activity activity, Event event) { + stream(activity, event.getChannelNumber()); + } + + public static void stream(Activity a, Channel c){ + stream(a, String.valueOf(c.getNumber())); + } + + + public static void stream(Activity activity, String chn) { + String url = getStreamUrl(chn); + final Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(Uri.parse(url.toString()), "video/*"); + activity.startActivityForResult(intent, 1); + + } + + public static int getDuration(Event event){ + long millis = event.getStop().getTime() - event.getStart().getTime(); + int minuts = (int)(millis / 1000 / 60); + return minuts; + } + +} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/VdrManagerActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/VdrManagerActivity.java index 7543ad7..a000525 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/VdrManagerActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/VdrManagerActivity.java @@ -46,6 +46,7 @@ public class VdrManagerActivity extends Activity { public int getIconId() { return iconId; } + public int getTextId() { return textId; } @@ -58,7 +59,8 @@ public class VdrManagerActivity extends Activity { return enabled; } - public MenuActivity(final int iconId, final int textId, final Class handler) { + public MenuActivity(final int iconId, final int textId, + final Class handler) { this.iconId = iconId; this.textId = textId; this.handler = handler; @@ -70,7 +72,8 @@ public class VdrManagerActivity extends Activity { } } - class MenuAdapter extends ArrayAdapter<MenuActivity> implements OnClickListener { + class MenuAdapter extends ArrayAdapter<MenuActivity> implements + OnClickListener { private final LayoutInflater inflater; @@ -81,7 +84,8 @@ public class VdrManagerActivity extends Activity { @SuppressWarnings("unchecked") @Override - public View getView(final int position, final View convertView, final ViewGroup parent) { + public View getView(final int position, final View convertView, + final ViewGroup parent) { View view = convertView; View itemView; @@ -130,7 +134,8 @@ public class VdrManagerActivity extends Activity { } else if (MenuActionHandler.class.isAssignableFrom(actionClass)) { final Class<? extends MenuActionHandler> handlerClass = actionClass; try { - final MenuActionHandler handler = handlerClass.newInstance(); + final MenuActionHandler handler = handlerClass + .newInstance(); handler.executeAction(getContext()); } catch (final InstantiationException e) { @@ -142,12 +147,18 @@ public class VdrManagerActivity extends Activity { } MenuActivity[] menuItems = new MenuActivity[] { - new MenuActivity(R.drawable.whatson, R.string.action_menu_epg, EpgListActivity.class), - new MenuActivity(0, R.string.action_menu_search, EpgSearchActivity.class), - new MenuActivity(R.drawable.timers, R.string.action_menu_timers, TimerListActivity.class), - new MenuActivity(R.drawable.channels, R.string.action_menu_channels, ChannelListActivity.class), - new MenuActivity(0, R.string.action_menu_wakeup, WakeupAction.class), - }; + new MenuActivity(R.drawable.whatson, R.string.action_menu_epg, + TimeEpgListActivity.class), + new MenuActivity(0, R.string.action_menu_search, + EpgSearchActivity.class), + new MenuActivity(R.drawable.timers, R.string.action_menu_timers, + TimerListActivity.class), + new MenuActivity(R.drawable.timers, R.string.action_menu_recordings, + RecordingListActivity.class), + + new MenuActivity(R.drawable.channels, + R.string.action_menu_channels, ChannelListActivity.class), + new MenuActivity(0, R.string.action_menu_wakeup, WakeupAction.class), }; Map<View, Class<? extends Activity>> menuActivityMap = new HashMap<View, Class<? extends Activity>>(); @Override @@ -157,6 +168,8 @@ public class VdrManagerActivity extends Activity { // attach view setContentView(R.layout.vdrmanager); + Preferences.loadPreferences(this); + // add and register buttons createButtons(); } @@ -170,19 +183,21 @@ public class VdrManagerActivity extends Activity { // get list final AbsListView listView = (AbsListView) findViewById(R.id.vdrmanager_menu); - final MenuAdapter adapter = new MenuAdapter(this, R.layout.vdrmanager_menu_item); + final MenuAdapter adapter = new MenuAdapter(this, + R.layout.vdrmanager_menu_item); listView.setAdapter(adapter); // add menu items - for(final MenuActivity menuItem : menuItems) { - if (menuItem.getTextId() != R.string.action_menu_wakeup || prefs.isWakeupEnabled()) { + for (final MenuActivity menuItem : menuItems) { + if (menuItem.getTextId() != R.string.action_menu_wakeup + || prefs.isWakeupEnabled()) { adapter.add(menuItem); } } // set grid layout dimensions if (listView instanceof GridView) { - final GridView grid = (GridView)listView; + final GridView grid = (GridView) listView; if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { grid.setNumColumns(2); } else { @@ -195,16 +210,15 @@ public class VdrManagerActivity extends Activity { public boolean onCreateOptionsMenu(final Menu menu) { super.onCreateOptionsMenu(menu); - final MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.main_menu, menu); - return true; + final MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.main_menu, menu); + return true; } @Override public boolean onOptionsItemSelected(final MenuItem item) { - switch (item.getItemId()) - { + switch (item.getItemId()) { case R.id.main_menu_preferences: // remember activity for finishing final VdrManagerApp app = (VdrManagerApp) getApplication(); diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/tasks/AsyncProgressTask.java b/vdrmanager/src/de/bjusystems/vdrmanager/tasks/AsyncProgressTask.java index edd1367..2b80499 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/tasks/AsyncProgressTask.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/tasks/AsyncProgressTask.java @@ -17,9 +17,9 @@ public abstract class AsyncProgressTask<Result> { public void svdrpEvent(final SvdrpEvent event, final Object result) { svdrpEvent(event); - switch (event) { - case FINISHED: + case FINISHED_ABNORMALY: + case FINISHED_SUCCESS: AsyncProgressTask.this.finished(); break; } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/date/DateFormatter.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/date/DateFormatter.java index 30fd047..95f99db 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/utils/date/DateFormatter.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/date/DateFormatter.java @@ -1,9 +1,13 @@ package de.bjusystems.vdrmanager.utils.date; import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; +import de.bjusystems.vdrmanager.data.Preferences; + + /** * Class for formatting date and time values * @author bju @@ -16,8 +20,10 @@ public class DateFormatter { private final String dailyHeader; public DateFormatter(final Date date) { - timeString = DateFormat.getTimeInstance(DateFormat.SHORT).format(date); - dateString = DateFormat.getDateInstance(DateFormat.SHORT).format(date); + SimpleDateFormat sdf = new SimpleDateFormat(Preferences.get().getTimeFormat()); + timeString = sdf.format(date); + sdf = new SimpleDateFormat("EEE dd.MM.yy"); + dateString = sdf.format(date); dailyHeader = DateFormat.getDateInstance(DateFormat.FULL).format(date); } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/ChannelClient.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/ChannelClient.java index c087358..5ec1a6a 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/ChannelClient.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/ChannelClient.java @@ -1,33 +1,96 @@ package de.bjusystems.vdrmanager.utils.svdrp; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.TreeMap; + import de.bjusystems.vdrmanager.R; import de.bjusystems.vdrmanager.data.Channel; import de.bjusystems.vdrmanager.data.Preferences; /** * Class for retrieving informations about the running program + * * @author bju - * + * */ -public class ChannelClient extends SvdrpClient<Channel> { +public class ChannelClient extends SvdrpClient<Channel> implements + SvdrpListener<Channel> { + + private static final ArrayList<String> channelGroups = new ArrayList<String>(); + + private static LinkedHashMap<String, ArrayList<Channel>> groupChannels = new LinkedHashMap<String, ArrayList<Channel>>(); + + private static TreeMap<String, ArrayList<Channel>> providerChannels = new TreeMap<String, ArrayList<Channel>>(); + + private static ArrayList<Channel> channels = new ArrayList<Channel>(); + + private static boolean inited = false; + + + public ChannelClient(boolean useCache){ + super(); + if(useCache == false){ + clearCache(); + } + addSvdrpListener(this); + } + + private void clearCache(){ + channelGroups.clear(); + groupChannels.clear(); + providerChannels.clear(); + channels.clear(); + inited = false; + } + + + public static ArrayList<String> getChannelGroups() { + return channelGroups; + } + + public static HashMap<String, ArrayList<Channel>> getGroupChannels() { + return groupChannels; + } + + public static TreeMap<String, ArrayList<Channel>> getProviderChannels() { + return providerChannels; + } + + public static ArrayList<Channel> getChannels() { + return channels; + } /** * Constructor - * @param host host - * @param port port - * @param ssl use ssl + * + * @param host + * host + * @param port + * port + * @param ssl + * use ssl */ public ChannelClient() { - super(); + this(true); + } /** * Starts the EPG request - * @param parameter parameter for lste + * + * @param parameter + * parameter for lste */ @Override public void run() throws SvdrpException { - runCommand("channels " + Preferences.getPreferences().getChannels()); + if (inited == true) { + informListener(SvdrpEvent.CACHE_HIT, null); + } else { + runCommand("channels " + Preferences.getPreferences().getChannels()); + } } @Override @@ -40,5 +103,37 @@ public class ChannelClient extends SvdrpClient<Channel> { return R.string.progress_channels_loading; } + private synchronized void initChannels(List<Channel> results) { + if(inited){ + return; + } + ArrayList<Channel> currentChannels = null; + for (Channel c : results) { + if (c.isGroupSeparator()) { + channelGroups.add(c.getName()); + currentChannels = new ArrayList<Channel>(); + groupChannels.put(c.getName(), currentChannels); + } else { + channels.add(c); + currentChannels.add(c); + String provider = c.getProvider(); + ArrayList<Channel> channels = providerChannels.get(provider); + if (channels == null) { + channels = new ArrayList<Channel>(); + providerChannels.put(provider, channels); + } + channels.add(c); + } + } + inited = true; + } + + public void svdrpEvent(SvdrpEvent event, Channel result) { + if(event != SvdrpEvent.FINISHED_SUCCESS){ + return; + } + initChannels(getResults()); + getResults().clear(); + } }
\ No newline at end of file diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/RecordingClient.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/RecordingClient.java new file mode 100644 index 0000000..40de70a --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/RecordingClient.java @@ -0,0 +1,29 @@ +package de.bjusystems.vdrmanager.utils.svdrp; + +import de.bjusystems.vdrmanager.R; +import de.bjusystems.vdrmanager.data.Recording; + +public class RecordingClient extends SvdrpClient<Recording> implements SvdrpListener<Recording> { + + public void svdrpEvent(SvdrpEvent event, Recording result) { +// if(event == SvdrpEvent.RESULT_RECEIVED){ +// results.add(result); +// } + } + + @Override + protected Recording parseAnswer(String line) { + return new Recording(line); + } + + @Override + public int getProgressTextId() { + return R.string.progress_recordings_loading; + } + + @Override + public void run() throws SvdrpException { + runCommand("recordings"); + } + +} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpClient.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpClient.java index ffb8b7b..374e2de 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpClient.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpClient.java @@ -8,16 +8,19 @@ import java.net.Socket; import java.util.ArrayList; import java.util.List; +import android.util.Log; import de.bjusystems.vdrmanager.data.Preferences; - /** * Class for SVDRP communication + * * @author bju - * + * */ public abstract class SvdrpClient<Result> { + private final String TAG = getClass().getName(); + /** Socket for connection to SVDRP */ private Socket socket; /** Output stream for sending commands */ @@ -35,7 +38,9 @@ public abstract class SvdrpClient<Result> { /** * Parse received answer line - * @param line line + * + * @param line + * line * @return received data object or null if not completed yet */ protected abstract Result parseAnswer(String line); @@ -46,10 +51,12 @@ public abstract class SvdrpClient<Result> { /** * Constructor - * @param prefs Preferences + * + * @param prefs + * Preferences */ protected SvdrpClient() { - results.clear(); + // results.clear(); } /** @@ -61,7 +68,9 @@ public abstract class SvdrpClient<Result> { /** * Adds the listener to the list of listeners - * @param listener listener + * + * @param listener + * listener */ public void addSvdrpListener(final SvdrpListener<Result> listener) { listeners.add(listener); @@ -69,7 +78,9 @@ public abstract class SvdrpClient<Result> { /** * Removes the listener from the list of listeners - * @param listener listener + * + * @param listener + * listener */ public void removeSvdrpListener(final SvdrpListener<Result> listener) { listeners.remove(listener); @@ -84,6 +95,7 @@ public abstract class SvdrpClient<Result> { /** * Gets the list of results + * * @return results */ public List<Result> getResults() { @@ -92,10 +104,15 @@ public abstract class SvdrpClient<Result> { /** * Connect to SVDRP - * @param host host - * @param port port - * @param ssl use SSL - * @throws IOException on errors + * + * @param host + * host + * @param port + * port + * @param ssl + * use SSL + * @throws IOException + * on errors */ protected boolean connect() throws IOException { @@ -107,6 +124,7 @@ public abstract class SvdrpClient<Result> { socket = new Socket(prefs.getSvdrpHost(), prefs.getSvdrpPort()); informListener(SvdrpEvent.CONNECTED, null); } catch (final IOException e) { + Log.w(TAG, e); informListener(SvdrpEvent.CONNECT_ERROR, null); return false; } @@ -131,7 +149,9 @@ public abstract class SvdrpClient<Result> { /** * Disconnect from SVDRP if connected - * @throws IOException on errors + * + * @throws IOException + * on errors */ protected void disconnect() throws IOException { informListener(SvdrpEvent.DISCONNECTING, null); @@ -144,8 +164,11 @@ public abstract class SvdrpClient<Result> { /** * Sends one line to SVDRP - * @param line line of text - * @throws IOException on errors + * + * @param line + * line of text + * @throws IOException + * on errors */ protected void writeLine(final String line) throws IOException { @@ -157,22 +180,24 @@ public abstract class SvdrpClient<Result> { /** * Reads one line from SVDRP + * * @return line read - * @throws IOException on errors + * @throws IOException + * on errors */ protected String readLine() throws IOException { // handle not gzipped input final ByteArrayOutputStream lineBytes = new ByteArrayOutputStream(); - for(;;) { + for (;;) { // read next char final int d = inputStream.read(); if (d < 0) { break; } - final char c = (char)d; + final char c = (char) d; // skip '\r' if (c == '\r') { @@ -219,7 +244,7 @@ public abstract class SvdrpClient<Result> { } // read answer lines - for(;!abort;) { + for (; !abort;) { // get next line line = readLine(); @@ -252,10 +277,11 @@ public abstract class SvdrpClient<Result> { // disconnect disconnect(); - } catch (final IOException e) { - throw new SvdrpException(e); - } finally { - informListener(SvdrpEvent.FINISHED, null); + informListener(SvdrpEvent.FINISHED_SUCCESS, null); + + } catch (final Exception e) { + // throw new SvdrpException(e); + informListener(SvdrpEvent.FINISHED_ABNORMALY, null); } } @@ -263,8 +289,13 @@ public abstract class SvdrpClient<Result> { this.resultInfoEnabled = resultInfoEnabled; } - private void informListener(final SvdrpEvent event, final Result result) { - for(final SvdrpListener<Result> listener : listeners) { + protected void informListenerError(final SvdrpEvent event, + final Throwable result) { + + } + + protected void informListener(final SvdrpEvent event, final Result result) { + for (final SvdrpListener<Result> listener : listeners) { listener.svdrpEvent(event, result); } } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpEvent.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpEvent.java index a807659..bb1ebb8 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpEvent.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpEvent.java @@ -12,6 +12,8 @@ public enum SvdrpEvent { RESULT_RECEIVED, DISCONNECTING, DISCONNECTED, - FINISHED, - ERROR + FINISHED_ABNORMALY, + FINISHED_SUCCESS, + ERROR, + CACHE_HIT, } |