diff options
Diffstat (limited to 'vdrmanager/src/de')
31 files changed, 977 insertions, 503 deletions
diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/app/VdrManagerApp.java b/vdrmanager/src/de/bjusystems/vdrmanager/app/VdrManagerApp.java index 9ce2d6b..e9018eb 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/app/VdrManagerApp.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/app/VdrManagerApp.java @@ -6,13 +6,13 @@ import java.util.Locale; import android.app.Activity; import android.app.Application; +import de.bjusystems.vdrmanager.data.Cache; import de.bjusystems.vdrmanager.data.Channel; import de.bjusystems.vdrmanager.data.EpgSearchParams; import de.bjusystems.vdrmanager.data.Event; import de.bjusystems.vdrmanager.data.Preferences; import de.bjusystems.vdrmanager.data.Timer; import de.bjusystems.vdrmanager.data.Vdr; -import de.bjusystems.vdrmanager.gui.Cache; public class VdrManagerApp extends Application { @@ -131,7 +131,7 @@ public class VdrManagerApp extends Application { public void finishActivities() { for (final Activity activity : activitiesToFinish) { if (activity instanceof Cache) { - ((Cache) activity).reset(); + ((Cache) activity).clearCache(); } activity.finish(); } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/AudioTrack.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/AudioTrack.java new file mode 100644 index 0000000..323507f --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/AudioTrack.java @@ -0,0 +1,61 @@ +package de.bjusystems.vdrmanager.data; + +import java.util.ArrayList; +import java.util.List; + +public class AudioTrack { + + private String cached = null; + + public int index; + + public String type; + + public String display; + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(type).append(", ").append(display).append("+").append(index); + return sb.toString(); + }; + + private static final ArrayList<AudioTrack> EMPTY = new ArrayList<AudioTrack>( + 0); + + /** + * a,1,deu|d,2,deu + * + * @param raw + * @return + */ + public static List<AudioTrack> getAudio(String rawAudio) { + + if(rawAudio == null){ + return EMPTY; + } + + String[] splitted = rawAudio.split("\\|"); + + if (splitted == null || splitted.length == 0) { + return EMPTY; + } + + ArrayList<AudioTrack> audio; + audio = new ArrayList<AudioTrack>(splitted.length); + for (String a : splitted) { + String[] ar = a.split(","); + if (ar == null || ar.length != 3) { + continue; + } + AudioTrack track = new AudioTrack(); + track.type = ar[0]; + track.index = Integer.valueOf(ar[1]); + track.display = ar[2]; + audio.add(track); + } + return audio; + + } + +} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/Cache.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/Cache.java new file mode 100644 index 0000000..cd47d1e --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/Cache.java @@ -0,0 +1,6 @@ +package de.bjusystems.vdrmanager.data; + +public interface Cache { + + void clearCache(); +} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/Channel.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/Channel.java index f885be8..d8ca9ec 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/data/Channel.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/Channel.java @@ -1,6 +1,5 @@ package de.bjusystems.vdrmanager.data; -import java.util.ArrayList; import java.util.List; import android.os.Parcel; @@ -45,32 +44,14 @@ public class Channel implements Parcelable { return group; } - private List<Audio> audio; + private List<AudioTrack> audio; - public List<Audio> getAudio() { + public List<AudioTrack> getAudio() { if (audio != null) { return audio; } - - String[] splitted = rawAudio.split("\\|"); - if (splitted == null || splitted.length == 0) { - audio = new ArrayList<Channel.Audio>(0); - } else { - audio = new ArrayList<Channel.Audio>(splitted.length); - for (String a : splitted) { - String[] ar = a.split(","); - if (ar == null || ar.length != 3) { - continue; - } - Audio track = new Audio(); - track.type = ar[0]; - track.index = Integer.valueOf(ar[1]); - track.display = ar[2]; - audio.add(track); - } - } + audio = AudioTrack.getAudio(rawAudio); return audio; - } public void setGroup(String group) { @@ -183,23 +164,12 @@ public class Channel implements Parcelable { if (o == this) { return true; } - - return number == ((Channel) o).getNumber(); + return ((Channel)o).getId().equals(id); }; @Override public int hashCode() { - return number; - } - - class Audio { - - public int index; - - public String type; - - public String display; - + return id.hashCode(); } } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/Epg.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/Epg.java index 8d077bb..1fb8ed7 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/data/Epg.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/Epg.java @@ -37,6 +37,7 @@ public class Epg extends Event implements Timerable { description = words.length > 5 ? mapSpecialChars(words[5]) : ""; shortText = words.length > 6 ? mapSpecialChars(words[6]) : ""; channelId = words.length > 7 ? mapSpecialChars(words[7]) : ""; + rawAudio = words.length > 8 ? mapSpecialChars(words[8]) : ""; } public Timer getTimer() { diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/Event.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/Event.java index af45ba5..dcfb010 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/data/Event.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/Event.java @@ -1,6 +1,7 @@ package de.bjusystems.vdrmanager.data; import java.util.Date; +import java.util.List; import android.text.TextUtils; @@ -21,6 +22,17 @@ public abstract class Event { protected String description; protected Date start; protected Date stop; + protected String rawAudio; + + private List<AudioTrack> audio; + + public List<AudioTrack> getAudio() { + if (audio != null) { + return audio; + } + audio = AudioTrack.getAudio(rawAudio); + return audio; + } public long getDuration(){ @@ -62,12 +74,14 @@ public abstract class Event { public Event(Event event) { channelNumber = event.getChannelNumber(); + channelId = event.getChannelId(); channelName = event.getChannelName(); title = event.getTitle(); shortText = event.getShortText(); description = event.getDescription(); start = event.getStart(); stop = event.getStop(); + rawAudio = event.rawAudio; } public Long getChannelNumber() { @@ -118,5 +132,4 @@ public abstract class Event { } return String.valueOf(channelNumber); } - } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/HasAudio.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/HasAudio.java new file mode 100644 index 0000000..10d9fd9 --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/HasAudio.java @@ -0,0 +1,5 @@ +package de.bjusystems.vdrmanager.data; + +public class HasAudio { + +} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/Recording.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/Recording.java index 94a60f7..ea414a1 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/data/Recording.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/Recording.java @@ -94,4 +94,9 @@ public class Recording extends Event{ public String toCommandLine(){ return String.valueOf(index); } + + @Override + public String toString() { + return title; + } } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/Vdr.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/Vdr.java index 8f89b54..6147379 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/data/Vdr.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/Vdr.java @@ -26,11 +26,11 @@ public class Vdr { /** SVDRP host name or ip */ @DatabaseField - private String host; + private String host = "0.0.0.0"; /** SVDRP port */ @DatabaseField - private int port; + private int port = 6420; /** Password */ @DatabaseField @@ -46,7 +46,7 @@ public class Vdr { /** Enable remote wakeup */ @DatabaseField - private boolean wakeupEnabled; + private boolean wakeupEnabled = false; /** URL of the wakeup script */ @DatabaseField @@ -75,7 +75,7 @@ public class Vdr { * */ @DatabaseField - private String wakeupMethod; + private String wakeupMethod = "wol"; /** Check for running VDR is enabled */ @DatabaseField @@ -87,19 +87,19 @@ public class Vdr { /** Buffer before event */ @DatabaseField - private int timerPreMargin; + private int timerPreMargin = 5; /** Buffer after event */ @DatabaseField - private int timerPostMargin; + private int timerPostMargin = 30; /** Default priority */ @DatabaseField - private int timerDefaultPriority; + private int timerDefaultPriority = 50; /** Default lifetime */ @DatabaseField - private int timerDefaultLifetime; + private int timerDefaultLifetime = 99; /** user defined epg search times */ @DatabaseField @@ -127,25 +127,25 @@ public class Vdr { * @since 0.2 */ @DatabaseField - private String wolCustomBroadcast = ""; + private String wolCustomBroadcast = "255.255.255.255"; /** * Use remux ? */ @DatabaseField - private boolean enableRemux; + private boolean enableRemux = false; /** * Remux command */ @DatabaseField - private String remuxCommand; + private String remuxCommand = "EXT"; /** * Remux command Parameter */ @DatabaseField - private String remuxParameter; + private String remuxParameter = "QUALITY=DSL1000"; @DatabaseField private String encoding = "utf-8"; @@ -154,19 +154,19 @@ public class Vdr { * Connection timeout */ @DatabaseField - private int connectionTimeout; + private int connectionTimeout = 10; /** * Read Timeout */ @DatabaseField - private int readTimeout; + private int readTimeout = 10; /** * Timeout for a whole command run */ @DatabaseField - private int timeout; + private int timeout = 60; @DatabaseField private String streamingUsername; @@ -175,10 +175,10 @@ public class Vdr { private String streamingPassword; @DatabaseField - private int livePort; + private int livePort = 8008; @DatabaseField - private String recStreamMethod; + private String recStreamMethod = "vdr-live"; @DatabaseField private boolean enableRecStreaming = false; diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseActivity.java index d4f6f32..569f59e 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseActivity.java @@ -1,6 +1,6 @@ package de.bjusystems.vdrmanager.gui; -import com.actionbarsherlock.app.ActionBar.OnNavigationListener; +import java.util.List; import android.app.AlertDialog; import android.app.ProgressDialog; @@ -12,10 +12,14 @@ import android.view.View.OnClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; -import android.widget.SpinnerAdapter; +import android.widget.TextView; import android.widget.ViewFlipper; + +import com.actionbarsherlock.app.ActionBar.OnNavigationListener; + import de.bjusystems.vdrmanager.R; import de.bjusystems.vdrmanager.app.VdrManagerApp; +import de.bjusystems.vdrmanager.data.Cache; import de.bjusystems.vdrmanager.data.Channel; import de.bjusystems.vdrmanager.data.Preferences; import de.bjusystems.vdrmanager.utils.svdrp.SvdrpAsyncTask; @@ -23,13 +27,12 @@ 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.SvdrpExceptionListener; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpFinishedListener; import de.bjusystems.vdrmanager.utils.svdrp.SvdrpListener; -import de.bjusystems.vdrmanager.utils.svdrp.SvdrpResultListener; public abstract class BaseActivity<Result, T extends ListView> extends - ICSBaseActivity implements OnClickListener, - SvdrpResultListener<Result>, SvdrpListener, SvdrpExceptionListener, - Cache { + ICSBaseActivity implements OnClickListener, SvdrpListener, + SvdrpExceptionListener, SvdrpFinishedListener<Result>, Cache { public static final String TAG = BaseActivity.class.getName(); @@ -39,18 +42,13 @@ public abstract class BaseActivity<Result, T extends ListView> extends protected T listView; - @Override - public boolean onSearchRequested() { - // TODO Auto-generated method stub - return super.onSearchRequested(); - } - protected ViewFlipper flipper; private Button retry; private ProgressDialog progress; + // protected SvdrpProgressDialog progress; abstract protected String getWindowTitle(); @@ -73,10 +71,6 @@ public abstract class BaseActivity<Result, T extends ListView> extends protected boolean forceRefresh = false; - public void reset() { - - } - protected void switchNoConnection() { if (flipper == null) { say(R.string.no_connection); @@ -141,13 +135,13 @@ public abstract class BaseActivity<Result, T extends ListView> extends public static final int LIST_NAVIGATION_RECORDINGS = 3; public static final int LIST_NAVIGATION_TIMERS = 4; - protected boolean hasListNavigation(){ + protected boolean hasListNavigation() { return true; } - protected void initListNavigation(){ + protected void initListNavigation() { - if(hasListNavigation() == false){ + if (hasListNavigation() == false) { return; } @@ -213,6 +207,8 @@ public abstract class BaseActivity<Result, T extends ListView> extends super.onCreate(savedInstanceState); Preferences.setLocale(this); progress = new ProgressDialog(this); + + getApp().addActivityToFinish(this); initActionBar(); @@ -247,6 +243,10 @@ public abstract class BaseActivity<Result, T extends ListView> extends finish(); } + protected int getBaseMenu() { + return R.menu.refresh_filter_menu; + } + @Override public boolean onCreateOptionsMenu( final com.actionbarsherlock.view.Menu menu) { @@ -257,7 +257,7 @@ public abstract class BaseActivity<Result, T extends ListView> extends // item.setIcon(R.drawable.ic_menu_refresh); // item.setAlphabeticShortcut('r'); com.actionbarsherlock.view.MenuInflater inf = getSupportMenuInflater(); - inf.inflate(R.menu.refresh_menu, menu); + inf.inflate(getBaseMenu(), menu); // SearchView searchView = (SearchView) // menu.findItem(R.id.menu_search).getActionView(); @@ -270,7 +270,7 @@ public abstract class BaseActivity<Result, T extends ListView> extends abstract protected void retry(); - abstract protected SvdrpClient<Result> getClient(); + // abstract protected SvdrpClient<Result> getClient(); @Override public boolean onOptionsItemSelected( @@ -280,6 +280,10 @@ public abstract class BaseActivity<Result, T extends ListView> extends backupViewSelection(); refresh(); return true; + case R.id.list_filter: { + onSearchRequested(); + return true; + } case android.R.id.home: Intent intent = new Intent(this, VdrManagerActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); @@ -372,9 +376,9 @@ public abstract class BaseActivity<Result, T extends ListView> extends return false; } - public void svdrpEvent(Result result) { - resultReceived(result); - } + // public void svdrpEvent(Result result) { + // resultReceived(result); + // } @Override public void svdrpEvent(SvdrpEvent event, Throwable t) { @@ -383,8 +387,8 @@ public abstract class BaseActivity<Result, T extends ListView> extends protected void addListener(SvdrpAsyncTask<Result, SvdrpClient<Result>> task) { task.addSvdrpExceptionListener(this); - task.addSvdrpResultListener(this); task.addSvdrpListener(this); + task.addSvdrpFinishedListener(this); } @Override @@ -398,13 +402,15 @@ public abstract class BaseActivity<Result, T extends ListView> extends case CONNECTING: progress.setProgressStyle(ProgressDialog.STYLE_SPINNER); setMessage(R.string.progress_connect); - progress.show(); + if (!isFinishing()) { + progress.show(); + } break; case LOGGED_IN: setMessage(R.string.progress_login); break; case COMMAND_SENT: - setMessage(getClient().getProgressTextId()); + setMessage(getProgressTextId()); break; case DISCONNECTING: setMessage(R.string.progress_disconnect); @@ -435,13 +441,6 @@ public abstract class BaseActivity<Result, T extends ListView> extends return; case FINISHED_SUCCESS: progress.dismiss(); - if (finishedSuccess()) { - finishedSuccess = true; - restoreViewSelection(); - } else { - say(R.string.epg_no_items); - } - break; } // case RESULT_RECEIVED: @@ -450,6 +449,10 @@ public abstract class BaseActivity<Result, T extends ListView> extends // } } + protected int getProgressTextId() { + return R.string.progress_loading; + } + private void setMessage(int progressConnect) { progress.setMessage(getString(progressConnect)); } @@ -463,18 +466,17 @@ public abstract class BaseActivity<Result, T extends ListView> extends /** * @return false, if no results found */ - protected abstract boolean finishedSuccess(); + protected abstract boolean finishedSuccess(List<Result> results); - /** - * @param result - */ - protected abstract void resultReceived(Result result); + // /** + // * @param result + // */ + // protected abstract void resultReceived(Result result); protected void connected() { if (flipper != null) { flipper.setDisplayedChild(0); } - // results.clear(); } public void svdrpException(final SvdrpException exception) { @@ -491,4 +493,14 @@ public abstract class BaseActivity<Result, T extends ListView> extends super.onDestroy(); } + @Override + public void finished(List<Result> results) { + if (finishedSuccess(results)) { + finishedSuccess = true; + restoreViewSelection(); + } else { + say(R.string.epg_no_items); + } + } + } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseEventListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseEventListActivity.java index a744e28..be1e17d 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseEventListActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseEventListActivity.java @@ -1,6 +1,5 @@ package de.bjusystems.vdrmanager.gui; -import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; @@ -30,7 +29,6 @@ import de.bjusystems.vdrmanager.data.P; import de.bjusystems.vdrmanager.data.Preferences; import de.bjusystems.vdrmanager.gui.SimpleGestureFilter.SimpleGestureListener; import de.bjusystems.vdrmanager.tasks.VoidAsyncTask; -import de.bjusystems.vdrmanager.utils.svdrp.EpgClient; import de.bjusystems.vdrmanager.utils.svdrp.SvdrpException; /** @@ -53,19 +51,19 @@ public abstract class BaseEventListActivity<T extends Event> extends private SimpleGestureFilter detector; - protected EpgClient epgClient; - protected EventAdapter adapter; protected String highlight = null; + protected Date lastUpdate = null; + protected static final Date FUTURE = new Date(Long.MAX_VALUE); // private static final Date BEGIN = new Date(0); protected Channel currentChannel = null; - protected List<T> results = new ArrayList<T>(); + //protected List<T> results = new ArrayList<T>(); AlertDialog sortByDialog = null; @@ -115,7 +113,6 @@ public abstract class BaseEventListActivity<T extends Event> extends public boolean onCreateOptionsMenu( final com.actionbarsherlock.view.Menu menu) { super.onCreateOptionsMenu(menu); - final com.actionbarsherlock.view.MenuInflater inflater = getSupportMenuInflater(); inflater.inflate(R.menu.epg_list_menu, menu); return true; @@ -150,6 +147,8 @@ public abstract class BaseEventListActivity<T extends Event> extends Utils.stream(this, event); break; } + + case MENU_SHARE: { Utils.shareEvent(this, event); break; @@ -275,8 +274,11 @@ public abstract class BaseEventListActivity<T extends Event> extends MenuItem mi = menu.findItem(R.id.epg_item_menu_live_tv); if (item.isLive() && item.getStreamId() != null) { + mi.setVisible(true); + } else { + mi.setVisible(false); } menu.add(MENU_GROUP_SHARE, MENU_SHARE, 0, R.string.share); @@ -330,9 +332,9 @@ public abstract class BaseEventListActivity<T extends Event> extends // } } - protected void resultReceived(T result) { - results.add(result); - } +// protected void resultReceived(T result) { +// results.add(result); +// } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { @@ -408,25 +410,39 @@ public abstract class BaseEventListActivity<T extends Event> extends alert(getString(R.string.vdr_error_text, exception.getMessage())); } - abstract protected boolean finishedSuccessImpl(); + abstract protected boolean finishedSuccessImpl(List<T> results); protected String getViewID(){ return this.getClass().getSimpleName(); } - protected final synchronized boolean finishedSuccess() { + protected void pushResultCountToTitle(){ setTitle(getString(R.string.epg_window_title_count, getWindowTitle(), - results.size())); + getCACHE().size())); + } + + + synchronized protected final boolean finishedSuccess(List<T> results) { + //ProgressDialog dialog = new ProgressDialog(this); + //dialog.setMessage("Loading"); + //dialog.show(); try { - return finishedSuccessImpl(); + lastUpdate = new Date(); + boolean r = finishedSuccessImpl(results); + if(r == false){ + adapter.clear(); + adapter.notifyDataSetChanged(); + } + return r; } finally { - results.clear(); +// dialog.dismiss(); + //results.clear(); } } @Override protected boolean displayingResults() { - return results.isEmpty() == false; + return getCACHE().isEmpty() == false; } class TitleComparator implements Comparator<Event> { @@ -443,14 +459,17 @@ public abstract class BaseEventListActivity<T extends Event> extends } }; - class TimeAndChannelComparator implements Comparator<T> { + class TimeAndChannelComparator implements Comparator<Event> { boolean r = false; + TimeAndChannelComparator() { + this(false); + } TimeAndChannelComparator(boolean r) { this.r = r; } - public int compare(final T item1, final T item2) { + public int compare(final Event item1, final Event item2) { int c = item1.getStart().compareTo(item2.getStart()); if (c != 0) { @@ -472,6 +491,7 @@ public abstract class BaseEventListActivity<T extends Event> extends } } + class TimeComparator implements Comparator<Event> { boolean r = false; @@ -509,4 +529,18 @@ public abstract class BaseEventListActivity<T extends Event> extends } } + + + public void clearCache() { + getCACHE().clear(); + } + + protected abstract List<T> getCACHE(); + +// @Override +// protected void connected() { +// super.connected(); +// results.clear(); +// } + } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseTimerEditActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseTimerEditActivity.java index 313bf1a..42d995d 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseTimerEditActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseTimerEditActivity.java @@ -11,7 +11,6 @@ import android.widget.AdapterView; import de.bjusystems.vdrmanager.R; import de.bjusystems.vdrmanager.app.Intents; import de.bjusystems.vdrmanager.data.Event; -import de.bjusystems.vdrmanager.data.EventFormatter; import de.bjusystems.vdrmanager.data.EventListItem; import de.bjusystems.vdrmanager.data.Timer; import de.bjusystems.vdrmanager.data.Timerable; @@ -20,11 +19,11 @@ import de.bjusystems.vdrmanager.tasks.ToggleTimerTask; import de.bjusystems.vdrmanager.utils.svdrp.SvdrpEvent; /** - * + * * This class is a base class for all the listings, which can deal with timers - * + * * @author lado - * + * * @param <T> * Class extending Event */ @@ -32,8 +31,8 @@ public abstract class BaseTimerEditActivity<T extends Event> extends BaseEventListActivity<T> implements OnClickListener // SvdrpAsyncListener<Timer>, { - //private static final ScheduledExecutorService worker = Executors - //.newSingleThreadScheduledExecutor(); + // private static final ScheduledExecutorService worker = Executors + // .newSingleThreadScheduledExecutor(); // /@Override // public boolean onPrepareOptionsMenu(Menu menu) { @@ -41,7 +40,7 @@ public abstract class BaseTimerEditActivity<T extends Event> extends // } /* * (non-Javadoc) - * + * * @see android.app.Activity#onContextItemSelected(android.view.MenuItem) */ // @Override @@ -90,7 +89,7 @@ public abstract class BaseTimerEditActivity<T extends Event> extends /* * (non-Javadoc) - * + * * @see android.app.Activity#onCreateContextMenu(android.view.ContextMenu, * android.view.View, android.view.ContextMenu.ContextMenuInfo) */ @@ -103,12 +102,12 @@ public abstract class BaseTimerEditActivity<T extends Event> extends // set menu title final EventListItem item = adapter.getItem(info.position); - - if(item.isHeader()){ + + if (item.isHeader()) { return; } - - //final EventFormatter formatter = new EventFormatter(item); + + // final EventFormatter formatter = new EventFormatter(item); menu.setHeaderTitle(item.getTitle()); inflater.inflate(R.menu.epg_list_item_menu, menu); @@ -140,7 +139,7 @@ public abstract class BaseTimerEditActivity<T extends Event> extends /** * Extract a Timer from a given {@link EventListItem} - * + * * @param item * @return Timer if any on the event */ @@ -152,11 +151,11 @@ public abstract class BaseTimerEditActivity<T extends Event> extends return ((Timerable) e).getTimer(); } - protected void toggleTimer(Timer timer) { + protected void toggleTimer(final Timer timer) { final ToggleTimerTask task = new ToggleTimerTask(this, timer) { @Override public void finished(SvdrpEvent event) { - timerModified(); + timerModified(timer); restoreViewSelection(); } }; @@ -165,7 +164,7 @@ public abstract class BaseTimerEditActivity<T extends Event> extends /** * Delete a given timer - * + * * @param timer */ protected void deleteTimer(final Timer timer) { @@ -173,35 +172,40 @@ public abstract class BaseTimerEditActivity<T extends Event> extends final DeleteTimerTask task = new DeleteTimerTask(this, timer) { @Override public void finished(SvdrpEvent event) { - timerModified(); + timerModified(timer); restoreViewSelection(); } }; task.start(); } + protected void timerModified() { + timerModified(null); + } + /** * Is called, if a timer has been changed and so update of the list is * required */ - protected void timerModified() { + protected void timerModified(final Timer timer) { backupViewSelection(); - //say(R.string.update_will_start_in); - //Runnable task = new Runnable() { - //public void run() { - refresh(); - //} - //}; - //worker.schedule(task, 1000, TimeUnit.MILLISECONDS); + // say(R.string.update_will_start_in); + // Runnable task = new Runnable() { + // public void run() { + refresh(); + // } + // }; + // worker.schedule(task, 1000, TimeUnit.MILLISECONDS); } @Override protected void onResume() { super.onResume(); } + /* * (non-Javadoc) - * + * * @see android.app.Activity#onActivityResult(int, int, * android.content.Intent) */ diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/Cache.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/Cache.java deleted file mode 100644 index 35d33d9..0000000 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/Cache.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.bjusystems.vdrmanager.gui; - -public interface Cache { - - - void reset(); - -} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelListActivity.java index 60134fb..d3b9e57 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelListActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelListActivity.java @@ -47,8 +47,6 @@ public class ChannelListActivity extends private static final String TAG = ChannelListActivity.class.getName(); - ChannelClient channelClient; - ChannelAdapter adapter; Preferences prefs; @@ -99,8 +97,11 @@ public class ChannelListActivity extends // register context menu registerForContextMenu(listView); startChannelQuery(); + } + + // @Override @@ -119,12 +120,7 @@ public class ChannelListActivity extends return; } - if (channelClient == null) { - // get channel task - channelClient = new ChannelClient(); - } else { - channelClient.removeSvdrpListener(this); - } + ChannelClient channelClient = new ChannelClient(); if (useCache == false) { ChannelClient.clearCache(); @@ -134,9 +130,12 @@ public class ChannelListActivity extends final SvdrpAsyncTask<Channel, SvdrpClient<Channel>> task = new SvdrpAsyncTask<Channel, SvdrpClient<Channel>>( channelClient); - task.addSvdrpExceptionListener(this); - task.addSvdrpResultListener(this); - task.addSvdrpListener(this); + addListener(task); + //task.addSvdrpExceptionListener(this); + //task.addSvdrpResultListener(this); + //task.addSvdrpListener(this); + //task.addSvdrpFinishedListener(this); + // start task task.run(); } @@ -195,11 +194,6 @@ public class ChannelListActivity extends } - @Override - public void reset() { - channelClient.clearCache(); - } - private void fillAdapter() { switch (groupBy) { case MENU_GROUP: @@ -368,7 +362,7 @@ public class ChannelListActivity extends recentAdapter.clear(); for (Channel c : DBAccess.get(ChannelListActivity.this) .getRecentChannelDAO() - .getRecentChannels(channelClient.getIdChannels(), rcs)) { + .getRecentChannels(ChannelClient.getIdChannels(), rcs)) { recentAdapter.add(c); } @@ -390,6 +384,7 @@ public class ChannelListActivity extends } } + @Override public void onCreateContextMenu(final ContextMenu menu, final View v, final ContextMenuInfo menuInfo) { @@ -405,9 +400,12 @@ public class ChannelListActivity extends // 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(); menu.setHeaderTitle(item.getName()); inflater.inflate(R.menu.channel_list_item_menu, menu); + + } else if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { /* * http://projects.vdr-developer.org/issues/722 String grp = @@ -437,19 +435,20 @@ public class ChannelListActivity extends .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_epg: + //startChannelEPG(channel); + //break; case R.id.channel_item_menu_stream: // show live stream Utils.stream(this, channel); break; - case R.id.channel_item_menu_hide: + + //case R.id.channel_item_menu_hide: // TODO http://projects.vdr-developer.org/issues/722 - break; - case R.id.channel_item_menu_hide_permanent: + //break; + //case R.id.channel_item_menu_hide_permanent: // TODO http://projects.vdr-developer.org/issues/722 - break; + //break; case R.id.channel_item_menu_switch: Utils.switchTo(this, channel); @@ -574,17 +573,13 @@ public class ChannelListActivity extends } @Override - protected synchronized boolean finishedSuccess() { + protected synchronized boolean finishedSuccess(List<Channel> results) { fillAdapter(); restoreViewSelection(); updateWindowTitle(); return ChannelClient.getChannels().isEmpty() == false; } - @Override - protected void resultReceived(Channel result) { - } - protected void cacheHit() { fillAdapter(); restoreViewSelection(); @@ -600,13 +595,19 @@ public class ChannelListActivity extends } @Override - protected SvdrpClient<Channel> getClient() { - return channelClient; + protected int getProgressTextId() { + return R.string.progress_channels_loading; } + @Override protected int getListNavigationIndex() { return LIST_NAVIGATION_CHANNELS; } + @Override + public void clearCache() { + ChannelClient.clearCache(); + } + }
\ 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 4c22597..1eadf34 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgDetailsActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgDetailsActivity.java @@ -35,6 +35,7 @@ import de.bjusystems.vdrmanager.data.EventFormatter; import de.bjusystems.vdrmanager.data.Preferences; import de.bjusystems.vdrmanager.data.Recording; import de.bjusystems.vdrmanager.data.Timer; +import de.bjusystems.vdrmanager.data.TimerMatch; import de.bjusystems.vdrmanager.data.Timerable; import de.bjusystems.vdrmanager.data.Timerable.TimerState; import de.bjusystems.vdrmanager.tasks.DeleteTimerTask; @@ -47,8 +48,8 @@ import de.bjusystems.vdrmanager.utils.svdrp.SvdrpEvent; * * @author bju */ -public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListener, - OnPageChangeListener { +public class EpgDetailsActivity extends ICSBaseActivity implements + OnClickListener, OnPageChangeListener { public static final String TAG = "EpgDetailsActivity"; @@ -174,9 +175,9 @@ public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListen final VdrManagerApp app = (VdrManagerApp) getApplication(); epgs = app.getCurrentEpgList(); - if(epgs.isEmpty()){ + if (epgs.isEmpty()) { epgs.add(cEvent); - return (Void)null; + return (Void) null; } for (Event e : epgs) { @@ -186,9 +187,9 @@ public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListen counter++; } - if (counter == epgs.size()) {//not found? + if (counter == epgs.size()) {// not found? epgs.add(0, cEvent); - counter = 0; + counter = 0; } return (Void) null; } @@ -232,6 +233,8 @@ public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListen Event event = epgs.get(position); + // view.setTag(event); + final EventFormatter formatter = new EventFormatter(event); final TextView title = (TextView) view @@ -255,15 +258,17 @@ public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListen setState(state, R.drawable.timer_none); } else { + TimerMatch match = timerable.getTimerMatch(); + switch (timerable.getTimerState()) { case Active: - setState(state, R.drawable.timer_active); + setState(state, Utils.getTimerStateDrawable(match, R.drawable.timer_active, R.drawable.timer_active_begin, R.drawable.timer_active_end) ); break; case Inactive: - setState(state, R.drawable.timer_inactive); + setState(state, Utils.getTimerStateDrawable(match, R.drawable.timer_inactive,R.drawable.timer_inactive_begin, R.drawable.timer_inactive_end)); break; case Recording: - setState(state, R.drawable.timer_recording); + setState(state, Utils.getTimerStateDrawable(match, R.drawable.timer_recording, R.drawable.timer_recording_begin, R.drawable.timer_recording_end)); break; default: setState(state, R.drawable.timer_none); @@ -277,6 +282,18 @@ public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListen .findViewById(R.id.epg_detail_description); textView.setText(Utils.highlight(formatter.getDescription(), highlight)); + + + if(cEvent.getAudio().isEmpty() == false){ + final TextView audioTracks = (TextView) view.findViewById(R.id.epg_detail_audio); + audioTracks.setText(Utils.formatAudio(this, cEvent.getAudio())); + } else { + view.findViewById(R.id.audio_image).setVisibility(View.GONE); + } + + + + // copy color for separator lines // final int color = textView.getTextColors().getDefaultColor(); // ((TextView) findViewById(R.id.epg_detail_separator_1)) @@ -315,47 +332,48 @@ public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListen b.setOnClickListener(new OnClickListener() { public void onClick(View v) { - startFilmDatabaseBrowseIntent(String.format(IMDB_BASE_URL, Preferences.get().getImdbUrl()) + IMDB_URL_QUERY, view, IMDB_URL_ENCODING); + startFilmDatabaseBrowseIntent( + String.format(IMDB_BASE_URL, Preferences.get() + .getImdbUrl()) + + IMDB_URL_QUERY, view, IMDB_URL_ENCODING); } }); } + b = view.findViewById(R.id.epg_event_omdb); - b = view.findViewById(R.id.epg_event_omdb); - - if (Preferences.get().isShowOmdbButton() == false) { - b.setVisibility(View.GONE); - } else { - b.setVisibility(View.VISIBLE); - b.setOnClickListener(new OnClickListener() { - - public void onClick(View v) { - startFilmDatabaseBrowseIntent(OMDB_URL, view, OMDB_URL_ENCODING); - } - }); - } - - b = view.findViewById(R.id.epg_event_tmdb); - - if (Preferences.get().isShowTmdbButton() == false) { - b.setVisibility(View.GONE); - } else { - b.setVisibility(View.VISIBLE); - b.setOnClickListener(new OnClickListener() { - - public void onClick(View v) { - startFilmDatabaseBrowseIntent(TMDB_URL, view, TMDB_URL_ENCODING); - } - }); - } - + if (Preferences.get().isShowOmdbButton() == false) { + b.setVisibility(View.GONE); + } else { + b.setVisibility(View.VISIBLE); + b.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + startFilmDatabaseBrowseIntent(OMDB_URL, view, + OMDB_URL_ENCODING); + } + }); + } + b = view.findViewById(R.id.epg_event_tmdb); + if (Preferences.get().isShowTmdbButton() == false) { + b.setVisibility(View.GONE); + } else { + b.setVisibility(View.VISIBLE); + b.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + startFilmDatabaseBrowseIntent(TMDB_URL, view, + TMDB_URL_ENCODING); + } + }); + } b = view.findViewById(R.id.epg_event_livetv); - if (Utils.isLive(event) == false && (event instanceof Recording == false || Preferences.get().isEnableRecStream() == false)) { + if (Utils.isLive(event) == false + && (event instanceof Recording == false || Preferences.get() + .isEnableRecStream() == false)) { b.setVisibility(View.GONE); } else { b.setVisibility(View.VISIBLE); @@ -373,16 +391,18 @@ public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListen } - private void startFilmDatabaseBrowseIntent(String url, View view, String encoding){ + private void startFilmDatabaseBrowseIntent(String url, View view, + String encoding) { final TextView title = (TextView) view .findViewById(R.id.epg_detail_title); - url = String.format(url, encode(String.valueOf(title.getText()), encoding)); + url = String.format(url, + encode(String.valueOf(title.getText()), encoding)); Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(url)); - i.addCategory(Intent.CATEGORY_BROWSABLE); - try{ + i.addCategory(Intent.CATEGORY_BROWSABLE); + try { startActivity(i); - }catch(ActivityNotFoundException anfe){ + } catch (ActivityNotFoundException anfe) { Log.w(TAG, anfe); say(anfe.getLocalizedMessage()); } @@ -394,6 +414,7 @@ public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListen } } + private void setThisAsOnClickListener(View root, int view) { setThisAsOnClickListener(root.findViewById(view)); } @@ -441,8 +462,8 @@ public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListen public void onClick(final View v) { switch (v.getId()) { case R.id.epg_event_livetv: - if(cEvent instanceof Recording){ - Utils.streamRecording(this, (Recording)cEvent); + if (cEvent instanceof Recording) { + Utils.streamRecording(this, (Recording) cEvent); } else { Utils.stream(this, String.valueOf(cEvent.getChannelNumber())); } @@ -531,10 +552,12 @@ public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListen public void finished(SvdrpEvent event) { if (event == SvdrpEvent.FINISHED_SUCCESS) { TimerState state = timer.getTimerState(); + TimerMatch match = timer.getTimerMatch(); int res = -1; if (state == TimerState.Active) { - res = R.drawable.timer_inactive; + res = Utils.getTimerStateDrawable(match, R.drawable.timer_inactive, R.drawable.timer_inactive_begin, R.drawable.timer_inactive_end); } else if (state == TimerState.Inactive) { + Utils.getTimerStateDrawable(match,R.drawable.timer_active, R.drawable.timer_active_begin, R.drawable.timer_active_end); res = R.drawable.timer_active; } if (res != -1) { @@ -548,10 +571,8 @@ public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListen task.start(); } - private List<Event> epgs = new ArrayList<Event>(); - protected void say(int res) { Toast.makeText(this, res, Toast.LENGTH_SHORT).show(); } @@ -560,11 +581,9 @@ public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListen Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); } - - - @Override - public final boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) { + public final boolean onCreateOptionsMenu( + com.actionbarsherlock.view.Menu menu) { super.onCreateOptionsMenu(menu); final com.actionbarsherlock.view.MenuInflater inflater = getSupportMenuInflater(); @@ -582,13 +601,14 @@ public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListen } @Override - public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item) { + public boolean onOptionsItemSelected( + com.actionbarsherlock.view.MenuItem item) { if (item.getItemId() == R.id.epg_details_menu_share) { shareEvent(cEvent); return true; } - if(item.getItemId() == R.id.epg_details_menu_add_to_cal){ + if (item.getItemId() == R.id.epg_details_menu_add_to_cal) { Utils.addCalendarEvent(this, cEvent); } @@ -600,14 +620,13 @@ public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListen return true; } - if(item.getItemId() == R.id.epg_details_menu_switch){ + if (item.getItemId() == R.id.epg_details_menu_switch) { Utils.switchTo(this, cEvent.getChannelId(), cEvent.getChannelName()); return true; } return super.onOptionsItemSelected(item); } - protected void deleteTimer(final Timer timer) { final DeleteTimerTask task = new DeleteTimerTask(this, timer) { @Override @@ -673,6 +692,4 @@ public class EpgDetailsActivity extends ICSBaseActivity implements OnClickListen epgs.size())); } - // private ShareActionProvider mShareActionProvider; - } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgSearchListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgSearchListActivity.java index 7a52e63..86df035 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgSearchListActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EpgSearchListActivity.java @@ -1,6 +1,9 @@ package de.bjusystems.vdrmanager.gui; +import java.util.ArrayList; import java.util.Calendar; +import java.util.Collections; +import java.util.List; import android.app.SearchManager; import android.content.Intent; @@ -10,13 +13,18 @@ import android.text.TextUtils; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; + +import com.actionbarsherlock.view.MenuItem; + import de.bjusystems.vdrmanager.R; import de.bjusystems.vdrmanager.app.VdrManagerApp; import de.bjusystems.vdrmanager.data.Epg; import de.bjusystems.vdrmanager.data.EpgSearchParams; import de.bjusystems.vdrmanager.data.Event; import de.bjusystems.vdrmanager.data.EventListItem; +import de.bjusystems.vdrmanager.data.P; import de.bjusystems.vdrmanager.data.Preferences; +import de.bjusystems.vdrmanager.data.Timer; import de.bjusystems.vdrmanager.data.db.EPGSearchSuggestionsProvider; import de.bjusystems.vdrmanager.utils.date.DateFormatter; import de.bjusystems.vdrmanager.utils.svdrp.EpgClient; @@ -31,6 +39,12 @@ import de.bjusystems.vdrmanager.utils.svdrp.SvdrpClient; public class EpgSearchListActivity extends BaseTimerEditActivity<Epg> implements OnItemClickListener { + protected static ArrayList<Epg> CACHE = new ArrayList<Epg>(); + + protected List<Epg> getCACHE() { + return CACHE; + } + private void initSearch(Intent intent) { if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); @@ -45,11 +59,6 @@ public class EpgSearchListActivity extends BaseTimerEditActivity<Epg> implements } @Override - protected SvdrpClient<Epg> getClient() { - return this.epgClient; - } - - @Override protected void onNewIntent(Intent intent) { initSearch(intent); startSearch(); @@ -59,6 +68,11 @@ public class EpgSearchListActivity extends BaseTimerEditActivity<Epg> implements startEpgQuery(); } + protected String getViewID(){ + return this.getClass().getSimpleName(); + } + + @Override protected void onCreate(final Bundle savedInstanceState) { Preferences.setLocale(this); @@ -66,6 +80,10 @@ public class EpgSearchListActivity extends BaseTimerEditActivity<Epg> implements super.onCreate(savedInstanceState); + sortBy = Preferences.get(this, getViewID() + "_" + + P.EPG_LAST_SORT, MENU_GROUP_DEFAULT); + + Intent intent = getIntent(); initSearch(intent); adapter = new TimeEventAdapter(this); @@ -96,7 +114,7 @@ public class EpgSearchListActivity extends BaseTimerEditActivity<Epg> implements EpgSearchParams sp = new EpgSearchParams(); sp.setTitle(highlight); setTitle(getWindowTitle()); - epgClient = new EpgClient(sp); + EpgClient epgClient = new EpgClient(sp); // remove old listeners // epgClient.clearSvdrpListener(); @@ -111,21 +129,43 @@ public class EpgSearchListActivity extends BaseTimerEditActivity<Epg> implements task.run(); } - /* - * (non-Javadoc) TODO this method also should be used in startEpgQuery on - * cache hit - * - * @see de.bjusystems.vdrmanager.gui.BaseEpgListActivity#finishedSuccess() - */ + protected void sort() { + /* */ + switch (sortBy) { + case MENU_GROUP_DEFAULT: { + //Collections.sort(CACHE, getTimeComparator(false)); + break; + } + case MENU_GROUP_ALPHABET: { + Collections.sort(CACHE, new TitleComparator()); + break; + } + //case MENU_GROUP_CHANNEL: { + //sortItemsByChannel(results); + //} + } + } + + @Override - protected boolean finishedSuccessImpl() { - adapter.clear(); + protected int getBaseMenu() { + return R.menu.refresh_menu; + } + + @Override + protected synchronized void fillAdapter() { + adapter.highlight = this.highlight; + adapter.clear(); + + if(CACHE.isEmpty()){ + return; + } + Calendar cal = Calendar.getInstance(); int day = -1; - sortItemsByTime(results); - for (Event e : results) { + for (Event e : CACHE) { cal.setTime(e.getStart()); int eday = cal.get(Calendar.DAY_OF_YEAR); if (eday != day) { @@ -135,6 +175,31 @@ public class EpgSearchListActivity extends BaseTimerEditActivity<Epg> implements } adapter.add(new EventListItem((Epg) e)); } + adapter.notifyDataSetChanged(); + } + + + @Override + protected int getAvailableSortByEntries() { + return R.array.epg_sort_by_time_alpha; + } + + + /* + * (non-Javadoc) TODO this method also should be used in startEpgQuery on + * cache hit + * + * @see de.bjusystems.vdrmanager.gui.BaseEpgListActivity#finishedSuccess() + */ + @Override + protected boolean finishedSuccessImpl(List<Epg> results) { + + clearCache(); + for(Epg e : results){ + CACHE.add(e); + } + pushResultCountToTitle(); + fillAdapter(); listView.setSelectionAfterHeaderView(); return adapter.getCount() > 0; } @@ -142,7 +207,7 @@ public class EpgSearchListActivity extends BaseTimerEditActivity<Epg> implements protected void prepareDetailsViewData(final EventListItem item) { final VdrManagerApp app = (VdrManagerApp) getApplication(); app.setCurrentEvent(item.getEvent()); - app.setCurrentEpgList(results); + app.setCurrentEpgList(CACHE); } @Override @@ -160,6 +225,27 @@ public class EpgSearchListActivity extends BaseTimerEditActivity<Epg> implements startEpgQuery(); } + public boolean onCreateOptionsMenu(final com.actionbarsherlock.view.Menu menu) { + // MenuItem item; + // item = menu.add(MENU_GROUP_NEW_TIMER, MENU_NEW_TIMER, 0, + // R.string.new_timer); + // item.setIcon(android.R.drawable.ic_menu_add);; + // /item.setAlphabeticShortcut('r'); + + final com.actionbarsherlock.view.MenuInflater inflater = getSupportMenuInflater(); + inflater.inflate(R.menu.epg_search_menu, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if(item.getItemId() == R.id.epg_search){ + startSearchManager(); + return true; + } + return super.onOptionsItemSelected(item); + } + @Override protected String getWindowTitle() { if (TextUtils.isEmpty(highlight)) { @@ -169,11 +255,11 @@ public class EpgSearchListActivity extends BaseTimerEditActivity<Epg> implements return getString(R.string.epg_by_search_param, highlight); } - @Override - public boolean onSearchRequested() { - startSearchManager(); - return true; - } + //@Override + //public boolean onSearchRequested() { + //startSearchManager(); + //return true; + //} @Override protected int getListNavigationIndex() { @@ -185,4 +271,10 @@ public class EpgSearchListActivity extends BaseTimerEditActivity<Epg> implements return false; } + @Override + protected void timerModified(Timer timer) { + clearCache(); + super.timerModified(timer); + } + } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventAdapter.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventAdapter.java index a1a7775..55f871d 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventAdapter.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventAdapter.java @@ -1,8 +1,6 @@ package de.bjusystems.vdrmanager.gui; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.List; import android.content.Context; @@ -25,7 +23,9 @@ import de.bjusystems.vdrmanager.data.TimerMatch; import de.bjusystems.vdrmanager.data.Timerable; abstract class EventAdapter extends ArrayAdapter<EventListItem> implements - Filterable { + Filterable +// , SectionIndexer + { private final int TYPE_ITEM = 0; private final int TYPE_HEADER = 1; @@ -61,11 +61,12 @@ abstract class EventAdapter extends ArrayAdapter<EventListItem> implements @Override public void add(EventListItem object) { items.add(object); + //if (object.isHeader()) { + //sections.add(object.getHeader()); + //} super.add(object); } - - @Override public int getItemViewType(int position) { @@ -145,50 +146,42 @@ abstract class EventAdapter extends ArrayAdapter<EventListItem> implements return itemHolder; } - private int getTimerStateDrawable(TimerMatch match, int full, int begin, - int end) { - if (match == TimerMatch.Full) { - return full; - } - - if (match == TimerMatch.Begin) { - return begin; - } - - return end; - } public void fillEventViewHolder(EventListItemHolder itemHolder, EventListItem item) { - - - - itemHolder.state.setVisibility(View.VISIBLE); - if(item.getEvent() instanceof Timerable == false){ + if (item.getEvent() instanceof Timerable == false) { itemHolder.state.setImageResource(R.drawable.timer_none); - } else if(item.getEvent() instanceof Recording){ - if(Utils.isLive(item.getEvent())){ + } else if (item.getEvent() instanceof Recording) { + if (Utils.isLive(item.getEvent())) { itemHolder.state.setImageResource(R.drawable.timer_recording); } } else { - TimerMatch match = ((Timerable)item.getEvent()).getTimerMatch(); - switch (((Timerable)item.getEvent()).getTimerState()) { - case Active: - itemHolder.state.setImageResource(getTimerStateDrawable(match, R.drawable.timer_active, R.drawable.timer_active_begin, R.drawable.timer_active_end)); - break; - case Inactive: - itemHolder.state.setImageResource(getTimerStateDrawable(match, R.drawable.timer_inactive, R.drawable.timer_inactive_begin, R.drawable.timer_inactive_end)); - break; - case Recording: - itemHolder.state.setImageResource(getTimerStateDrawable(match, R.drawable.timer_recording, R.drawable.timer_recording_begin, R.drawable.timer_recording_end)); - break; - case None: - itemHolder.state.setImageResource(R.drawable.timer_none); - break; - } + TimerMatch match = ((Timerable) item.getEvent()).getTimerMatch(); + switch (((Timerable) item.getEvent()).getTimerState()) { + case Active: + itemHolder.state.setImageResource(Utils.getTimerStateDrawable(match, + R.drawable.timer_active, R.drawable.timer_active_begin, + R.drawable.timer_active_end)); + break; + case Inactive: + itemHolder.state.setImageResource(Utils.getTimerStateDrawable(match, + R.drawable.timer_inactive, + R.drawable.timer_inactive_begin, + R.drawable.timer_inactive_end)); + break; + case Recording: + itemHolder.state.setImageResource(Utils.getTimerStateDrawable(match, + R.drawable.timer_recording, + R.drawable.timer_recording_begin, + R.drawable.timer_recording_end)); + break; + case None: + itemHolder.state.setImageResource(R.drawable.timer_none); + break; + } } final EventFormatter formatter = getEventFormatter(item); @@ -214,7 +207,7 @@ abstract class EventAdapter extends ArrayAdapter<EventListItem> implements } } - //TODO better render of duration + // TODO better render of duration int p = Utils.getProgress(item); if (p == -1) { itemHolder.progress.setVisibility(View.GONE); @@ -250,6 +243,10 @@ abstract class EventAdapter extends ArrayAdapter<EventListItem> implements super.add(item); } + private void clearSuper() { + super.clear(); + } + public boolean isHideDescription() { return hideDescription; } @@ -306,7 +303,7 @@ abstract class EventAdapter extends ArrayAdapter<EventListItem> implements @Override protected void publishResults(CharSequence arg0, FilterResults arg1) { - EventAdapter.this.clear(); + clearSuper(); for (EventListItem item : (ArrayList<EventListItem>) arg1.values) { addSuper(item); } @@ -314,4 +311,32 @@ abstract class EventAdapter extends ArrayAdapter<EventListItem> implements } }; } + + //@Override + //public int getPositionForSection(int section) { + //return 0; +// } + + //@Override + //public int getSectionForPosition(int position) { + // TODO Auto-generated method stub + //return 0; + //} + + //ArrayList<String> sections = new ArrayList<String>(); + + //@Override + //public Object[] getSections() { + //try { + // return sections.toArray(); + //} finally { + //sections.clear(); + //} + //} + + @Override + public void clear() { + super.clear(); + 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 index 6bf93da..8557f20 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventEpgListActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventEpgListActivity.java @@ -3,9 +3,12 @@ package de.bjusystems.vdrmanager.gui; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; -import java.util.Comparator; import java.util.Date; import java.util.List; +import java.util.WeakHashMap; + +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuItem; import android.content.Intent; import android.os.Bundle; @@ -16,15 +19,15 @@ import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Spinner; +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.EpgSearchTimeValue; import de.bjusystems.vdrmanager.data.Event; import de.bjusystems.vdrmanager.data.EventListItem; -import de.bjusystems.vdrmanager.gui.BaseEventListActivity.TitleComparator; +import de.bjusystems.vdrmanager.data.Timer; import de.bjusystems.vdrmanager.tasks.ChannelsTask; import de.bjusystems.vdrmanager.utils.date.DateFormatter; import de.bjusystems.vdrmanager.utils.svdrp.ChannelClient; @@ -41,14 +44,12 @@ import de.bjusystems.vdrmanager.utils.svdrp.SvdrpEvent; public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements OnItemClickListener, OnItemSelectedListener { - private final static ArrayList<Event> CACHE = new ArrayList<Event>(); - private static final String TAG = EventEpgListActivity.class .getSimpleName(); - protected static Date nextForceCache = null; + // protected static Date nextForceCache = null; - private static Channel cachedChannel = null; + // private static Channel cachedChannel = null; Spinner channelSpinner; @@ -56,12 +57,15 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements ArrayAdapter<Channel> channelSpinnerAdapter; - @Override - public void reset() { - CACHE.clear(); - ChannelClient.clearCache(); - super.reset(); - } + // protected static ArrayList<Epg> CACHE = new ArrayList<Epg>(); + + private static WeakHashMap<String, ArrayList<Epg>> CACHE = new WeakHashMap<String, ArrayList<Epg>>(); + + private static WeakHashMap<String, Date> NEXT_REFRESH = new WeakHashMap<String, Date>(); + + private TextView audio; + + private View channelInfo; @Override protected void onCreate(final Bundle savedInstanceState) { @@ -84,6 +88,12 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements // show needed items + channelInfo = findViewById(R.id.channel_info); + + channelInfo.setOnClickListener(this); + + audio = (TextView) channelInfo.findViewById(R.id.channel_audio); + adapter = new ChannelEventAdapter(this); // if (currentChannel != null) { @@ -152,9 +162,9 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements void sort() { if (sortBy == BaseEventListActivity.MENU_GROUP_ALPHABET) { - Collections.sort(CACHE, new TitleComparator()); + Collections.sort(getCache(), new TitleComparator()); } else if (sortBy == BaseEventListActivity.MENU_GROUP_DEFAULT) { - Collections.sort(CACHE, new TimeComparator(false)); + Collections.sort(getCache(), new TimeComparator(false)); } } @@ -176,6 +186,12 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements setCurrent(channel); // setAsCurrent(channel); // update search + if (channel.getAudio().isEmpty() == false) { + audio.setText(Utils.formatAudio(this, channel.getAudio())); + } else { + audio.setText(""); + } + startEpgQuery(false); } @@ -183,18 +199,26 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements // startTimeEpgQuery(((EpgTimeSpinnerValue)timeSpinner.getAdapter().getItem(0)).getValue()); } - private void clearCache() { - cachedChannel = null; - CACHE.clear(); + public void clearCache() { + getCache().clear(); + CACHE.remove(currentChannel); + NEXT_REFRESH.remove(currentChannel); } private boolean useCache() { - if (cachedChannel == null || currentChannel == null) { + + if(currentChannel == null){ return false; } - if (currentChannel.getNumber() != cachedChannel.getNumber()) { + + ArrayList<Epg> cachedChannel = CACHE.get(currentChannel) ; + + if (cachedChannel == null) { return false; } + + Date nextForceCache = NEXT_REFRESH.get(currentChannel); + if (nextForceCache == null) { return false; } @@ -207,12 +231,15 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements @Override public void onClick(View view) { + if (view == switcher) { final Intent intent = new Intent(); intent.setClass(this, TimeEpgListActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(intent); + } else if (view == channelInfo) { + Utils.stream(this, currentChannel); } else { super.onClick(view); } @@ -220,19 +247,7 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements private void startEpgQuery(final boolean force) { if (useCache() && !force) { - Calendar cal = Calendar.getInstance(); - int day = -1; - for (Event i : CACHE) { - Epg e = (Epg) i; - 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)); - } + fillAdapter(); return; } @@ -240,9 +255,9 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements return; } - clearCache(); + // clearCache(); - epgClient = new EpgClient(currentChannel); + EpgClient epgClient = new EpgClient(currentChannel); // remove old listeners // epgClient.clearSvdrpListener(); @@ -260,14 +275,32 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements } @Override - protected SvdrpClient<Epg> getClient() { - return this.epgClient; + protected void timerModified(Timer timer) { + if(timer != null){ + CACHE.remove(timer.getChannelId()); + } + super.timerModified(timer); + } + + private static final ArrayList<Epg> EMPTY = new ArrayList<Epg>(0); + + private ArrayList<Epg> getCache() { + ArrayList<Epg> arrayList = CACHE.get(currentChannel); + if (arrayList == null) { + return EMPTY; + } + return arrayList; } @Override protected void fillAdapter() { - if (CACHE.isEmpty()) { + adapter.clear(); + + + ArrayList<Epg> cache = getCache(); + + if (cache.isEmpty()) { return; } @@ -275,8 +308,7 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements Calendar cal = Calendar.getInstance(); int day = -1; - adapter.clear(); - for (Event e : CACHE) { + for (Event e : cache) { cal.setTime(e.getStart()); int eday = cal.get(Calendar.DAY_OF_YEAR); if (eday != day) { @@ -287,7 +319,6 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements adapter.add(new EventListItem((Epg) e)); } - adapter.notifyDataSetChanged(); } @@ -299,7 +330,7 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements * @see de.bjusystems.vdrmanager.gui.BaseEpgListActivity#finishedSuccess() */ @Override - synchronized protected boolean finishedSuccessImpl() { + protected boolean finishedSuccessImpl(List<Epg> results) { // adapter.clear(); // CACHE.clear(); @@ -311,12 +342,17 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements Date now = new Date(); - nextForceCache = FUTURE; + + NEXT_REFRESH.put(currentChannel.getId(), FUTURE); + + Date nextForceCache = FUTURE; + // Calendar cal = Calendar.getInstance(); // int day = -1; // sortItemsByTime(results); - for (Event e : results) { - CACHE.add(e); + ArrayList<Epg> cache = new ArrayList<Epg>(); + for (Epg e : results) { + cache.add(e); // cal.setTime(e.getStart()); // int eday = cal.get(Calendar.DAY_OF_YEAR); // if (eday != day) { @@ -329,7 +365,9 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements nextForceCache = e.getStop(); } } - cachedChannel = currentChannel; + + NEXT_REFRESH.put(currentChannel.getId(), nextForceCache); + CACHE.put(currentChannel.getId(), cache); fillAdapter(); listView.setSelectionAfterHeaderView(); @@ -360,7 +398,7 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements protected void prepareDetailsViewData(final EventListItem item) { final VdrManagerApp app = (VdrManagerApp) getApplication(); app.setCurrentEvent(item.getEvent()); - app.setCurrentEpgList(CACHE); + app.setCurrentEpgList(CACHE.get(currentChannel)); } @Override @@ -419,6 +457,28 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements return LIST_NAVIGATION_EPG_BY_CHANNEL; } + @Override + protected List<Epg> getCACHE() { + return getCACHE(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + final com.actionbarsherlock.view.MenuInflater inflater = getSupportMenuInflater(); + inflater.inflate(R.menu.epg_event_list_menu, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == R.id.epg_list_stream) { + Utils.stream(this, currentChannel); + return true; + } + return super.onOptionsItemSelected(item); + } + // @Override // protected void timerModified() { // cachedChannel = null; diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/RecordingAdapter.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/RecordingAdapter.java index 09c6921..3645596 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/RecordingAdapter.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/RecordingAdapter.java @@ -8,14 +8,16 @@ import de.bjusystems.vdrmanager.data.EventFormatter; class RecordingAdapter extends EventAdapter { - + public RecordingAdapter(final Context context) { super(context, R.layout.epg_event_item); hideChannelName = false; } - + @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/RecordingListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/RecordingListActivity.java index 56f91bd..84509f6 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/RecordingListActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/RecordingListActivity.java @@ -2,9 +2,9 @@ package de.bjusystems.vdrmanager.gui; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collections; +import java.util.List; -import android.app.AlertDialog; -import android.content.DialogInterface; import android.os.Bundle; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; @@ -35,17 +35,16 @@ import de.bjusystems.vdrmanager.utils.svdrp.SvdrpEvent; public class RecordingListActivity extends BaseEventListActivity<Recording> implements OnItemLongClickListener { - RecordingClient recordingClient; + //RecordingClient recordingClient; - public static final int MENU_DATE = 0; - public static final int MENU_NAME = 1; - public static final int MENU_CHANNEL = 2; + //public static final int MENU_GROUP_CHANNEL = 2; public static final int ASC = 0; public static final int DESC = 1; - private int groupBy = MENU_DATE; + protected static ArrayList<Recording> CACHE = new ArrayList<Recording>(); + private int ASC_DESC = ASC; @@ -72,53 +71,49 @@ public class RecordingListActivity extends BaseEventListActivity<Recording> startRecordingQuery(); } - private String[] getAvailableGroupByEntries() { - ArrayList<String> entries = new ArrayList<String>(2); - entries.add(getString(R.string.groupby_date)); - entries.add(getString(R.string.groupby_name)); - entries.add(getString(R.string.groupby_channel)); - return entries.toArray(Utils.EMPTY); - } - - AlertDialog groupByDialog = null; - - @Override - public boolean onOptionsItemSelected( - final com.actionbarsherlock.view.MenuItem item) { - - switch (item.getItemId()) { - case R.id.menu_groupby: - // case MENU_PROVIDER: - // case MENU_NAME: - if (groupByDialog == null) { - groupByDialog = new AlertDialog.Builder(this) - .setTitle(R.string.menu_groupby) - .setIcon(android.R.drawable.ic_menu_sort_alphabetically) - .setSingleChoiceItems(getAvailableGroupByEntries(), - groupBy, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, - int which) { - if (groupBy == which) { - ASC_DESC = ASC_DESC == ASC ? DESC - : ASC; - } else { - groupBy = which; - ASC_DESC = ASC; - } - // fillAdapter(); - groupByDialog.dismiss(); - say("Comming soon..."); - } - }).create(); - } - - groupByDialog.show(); - - return true; - default: - return super.onOptionsItemSelected(item); - } - } + protected int getAvailableSortByEntries() { + return R.array.recordings_group_by; + }; + + // AlertDialog groupByDialog = null; + + // @Override + // public boolean onOptionsItemSelected( + // final com.actionbarsherlock.view.MenuItem item) { + // + // switch (item.getItemId()) { + // case R.id.menu_groupby: + // // case MENU_PROVIDER: + // // case MENU_NAME: + // if (groupByDialog == null) { + // groupByDialog = new AlertDialog.Builder(this) + // .setTitle(R.string.menu_groupby) + // .setIcon(android.R.drawable.ic_menu_sort_alphabetically) + // .setSingleChoiceItems(getAvailableGroupByEntries(), + // groupBy, new DialogInterface.OnClickListener() { + // public void onClick(DialogInterface dialog, + // int which) { + // if (groupBy == which) { + // ASC_DESC = ASC_DESC == ASC ? DESC + // : ASC; + // } else { + // groupBy = which; + // ASC_DESC = ASC; + // } + // // fillAdapter(); + // groupByDialog.dismiss(); + // say("Comming soon..."); + // } + // }).create(); + // } + // + // groupByDialog.show(); + // + // return true; + // default: + // return super.onOptionsItemSelected(item); + // } + // } /* * (non-Javadoc) @@ -136,11 +131,6 @@ public class RecordingListActivity extends BaseEventListActivity<Recording> } @Override - protected SvdrpClient<Recording> getClient() { - return this.recordingClient; - } - - @Override protected void onPause() { super.onPause(); } @@ -148,7 +138,7 @@ public class RecordingListActivity extends BaseEventListActivity<Recording> @Override protected void prepareDetailsViewData(EventListItem event) { getApp().setCurrentEvent(event.getEvent()); - getApp().setCurrentEpgList(results); + getApp().setCurrentEpgList(CACHE); } @Override @@ -222,7 +212,7 @@ public class RecordingListActivity extends BaseEventListActivity<Recording> } // get timer client - recordingClient = new RecordingClient(); + RecordingClient recordingClient = new RecordingClient(); // create backgound task final SvdrpAsyncTask<Recording, SvdrpClient<Recording>> task = new SvdrpAsyncTask<Recording, SvdrpClient<Recording>>( @@ -254,13 +244,38 @@ public class RecordingListActivity extends BaseEventListActivity<Recording> return getString(R.string.action_menu_recordings); } + protected void sort() { + /* */ + switch (sortBy) { + case MENU_GROUP_DEFAULT: { + sortItemsByTime(CACHE, true); + break; + } + case MENU_GROUP_ALPHABET: { + Collections.sort(CACHE, new TitleComparator()); + break; + } + //case MENU_GROUP_CHANNEL: { + //sortItemsByChannel(results); + //} + } + } + @Override - protected boolean finishedSuccessImpl() { + protected void fillAdapter() { + adapter.clear(); + + if (CACHE.isEmpty()) { + return; + } + + sort(); + Calendar cal = Calendar.getInstance(); int day = -1; - sortItemsByTime(results, true); - for (final Event rec : results) { + + for (final Event rec : CACHE) { cal.setTime(rec.getStart()); int eday = cal.get(Calendar.DAY_OF_YEAR); if (eday != day) { @@ -269,9 +284,21 @@ public class RecordingListActivity extends BaseEventListActivity<Recording> .getDailyHeader())); } adapter.add(new EventListItem((Recording) rec)); + adapter.notifyDataSetChanged(); } - // adapter.sortItems(); + + } + + @Override + protected boolean finishedSuccessImpl(List<Recording> results) { + clearCache(); + for(Recording r :results){ + CACHE.add(r); + } + pushResultCountToTitle(); + fillAdapter(); return adapter.isEmpty() == false; + } public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, @@ -285,4 +312,9 @@ public class RecordingListActivity extends BaseEventListActivity<Recording> return LIST_NAVIGATION_RECORDINGS; } + @Override + protected List<Recording> getCACHE() { + return CACHE; + } + } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimeEpgListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimeEpgListActivity.java index 2893583..caa97f0 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimeEpgListActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimeEpgListActivity.java @@ -9,6 +9,7 @@ import java.util.TimeZone; import android.app.TimePickerDialog; import android.app.TimePickerDialog.OnTimeSetListener; +import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.view.View; @@ -27,6 +28,7 @@ import de.bjusystems.vdrmanager.data.EpgSearchTimeValues; import de.bjusystems.vdrmanager.data.Event; import de.bjusystems.vdrmanager.data.EventListItem; import de.bjusystems.vdrmanager.data.Preferences; +import de.bjusystems.vdrmanager.data.Timer; import de.bjusystems.vdrmanager.utils.date.DateFormatter; import de.bjusystems.vdrmanager.utils.svdrp.EpgClient; import de.bjusystems.vdrmanager.utils.svdrp.SvdrpAsyncTask; @@ -50,24 +52,15 @@ public class TimeEpgListActivity extends BaseTimerEditActivity<Epg> implements protected static Date nextForceCache = null; - private final static ArrayList<Event> CACHE = new ArrayList<Event>(); - private static String cachedTime = null; int selectedIndex = 0; + protected static ArrayList<Epg> CACHE = new ArrayList<Epg>(); @Override - public void reset() { - CACHE.clear(); - cachedTime = null; - super.reset(); - } - - - @Override - protected SvdrpClient<Epg> getClient() { - return this.epgClient; + public int getProgressTextId() { + return R.string.progress_whatson_loading; } @Override @@ -135,6 +128,7 @@ public class TimeEpgListActivity extends BaseTimerEditActivity<Epg> implements intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(intent); + finish(); } else if (view == clock) { Intent intent = new Intent(); intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT @@ -196,6 +190,15 @@ public class TimeEpgListActivity extends BaseTimerEditActivity<Epg> implements final TimePickerDialog dialog = new TimePickerDialog(this, this, cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), Preferences.get().isUse24hFormat()); +// dialog.setOnDismissListener(new OnDismissListener() { + + // @Override + // public void onDismiss(DialogInterface dialog) { + + + // } + //}); + dialog.show(); } else { // update search @@ -208,9 +211,9 @@ public class TimeEpgListActivity extends BaseTimerEditActivity<Epg> implements // startTimeEpgQuery(((EpgTimeSpinnerValue)timeSpinner.getAdapter().getItem(0)).getValue()); } - private void clearCache() { + public void clearCache() { + super.clearCache(); cachedTime = null; - CACHE.clear(); } private boolean useCache(String time) { @@ -244,7 +247,7 @@ public class TimeEpgListActivity extends BaseTimerEditActivity<Epg> implements return; } - epgClient = new EpgClient(time); + EpgClient epgClient = new EpgClient(time); // remove old listeners // epgClient.clearSvdrpListener(); @@ -260,45 +263,46 @@ public class TimeEpgListActivity extends BaseTimerEditActivity<Epg> implements task.run(); } - @Override - protected void fillAdapter() { - if(CACHE.isEmpty()){ + protected synchronized void fillAdapter() { + + adapter.clear(); + + if (CACHE.isEmpty()) { return; } sort(); - adapter.clear(); - adapter.add(new EventListItem(new DateFormatter(CACHE.get(0) - .getStart()).getDailyHeader())); + listView.setFastScrollEnabled(false); + adapter.add(new EventListItem( + new DateFormatter(CACHE.get(0).getStart()).getDailyHeader())); for (Event e : CACHE) { adapter.add(new EventListItem((Epg) e)); } adapter.notifyDataSetChanged(); + listView.setFastScrollEnabled(true); } void sort() { - if(sortBy == BaseEventListActivity.MENU_GROUP_ALPHABET) { + if (sortBy == BaseEventListActivity.MENU_GROUP_ALPHABET) { Collections.sort(CACHE, new TitleComparator()); } else if (sortBy == BaseEventListActivity.MENU_GROUP_DEFAULT) { Collections.sort(CACHE, new ChannelComparator()); } } - @Override protected int getAvailableSortByEntries() { return R.array.epg_sort_by_channels_alpha; } - - protected String getViewID(){ + protected String getViewID() { return TimeEpgListActivity.class.getSimpleName(); } @Override - protected boolean finishedSuccessImpl() { + protected boolean finishedSuccessImpl(List<Epg> results) { clearCache(); if (results.isEmpty()) { @@ -312,16 +316,17 @@ public class TimeEpgListActivity extends BaseTimerEditActivity<Epg> implements cachedTime = selection.getValue(); Date now = new Date(); - //adapter.add(new EventListItem(new DateFormatter(results.get(0) - // .getStart()).getDailyHeader())); + // adapter.add(new EventListItem(new DateFormatter(results.get(0) + // .getStart()).getDailyHeader())); - for (Event e : results) { + for (Epg e : results) { CACHE.add(e); if (e.getStop().before(nextForceCache) && e.getStop().after(now)) { nextForceCache = e.getStop(); } } fillAdapter(); + pushResultCountToTitle(); listView.setSelectionAfterHeaderView(); return results.isEmpty() == false; @@ -389,10 +394,20 @@ public class TimeEpgListActivity extends BaseTimerEditActivity<Epg> implements } } - @Override protected int getListNavigationIndex() { return LIST_NAVIGATION_EPG_BY_TIME; } + @Override + protected List<Epg> getCACHE() { + return CACHE; + } + + @Override + protected void timerModified(Timer timer) { + clearCache(); + super.timerModified(timer); + } + } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerListActivity.java index 3ba957a..45a75ca 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerListActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerListActivity.java @@ -1,7 +1,10 @@ package de.bjusystems.vdrmanager.gui; +import java.util.ArrayList; import java.util.Calendar; +import java.util.Collections; import java.util.Comparator; +import java.util.List; import android.os.Bundle; import android.widget.AdapterView.OnItemClickListener; @@ -26,15 +29,8 @@ public class TimerListActivity extends BaseTimerEditActivity<Timer> implements private static final int MENU_NEW_TIMER = 2; private static final int MENU_GROUP_NEW_TIMER = 2; - /** - * - */ - TimerClient timerClient; - @Override - protected SvdrpClient<Timer> getClient() { - return this.timerClient; - } + protected static ArrayList<Timer> CACHE = new ArrayList<Timer>(); /* * (non-Javadoc) @@ -80,7 +76,7 @@ public class TimerListActivity extends BaseTimerEditActivity<Timer> implements } // get timer client - timerClient = new TimerClient(); + TimerClient timerClient = new TimerClient(); // create backgound task final SvdrpAsyncTask<Timer, SvdrpClient<Timer>> task = new SvdrpAsyncTask<Timer, SvdrpClient<Timer>>( @@ -120,11 +116,12 @@ public class TimerListActivity extends BaseTimerEditActivity<Timer> implements final VdrManagerApp app = (VdrManagerApp) getApplication(); // remember event for details view and timer things app.setCurrentEvent(item.getEvent()); - app.setCurrentEpgList(results); + app.setCurrentEpgList(CACHE); } protected Comparator<Timer> getTimeComparator(boolean reverse) { - return new TimeAndChannelComparator(reverse) { + return new Comparator<Timer>() { + TimeAndChannelComparator c = new TimeAndChannelComparator(); @Override public int compare(Timer item1, Timer item2) { if (item1.isRecurring()) { @@ -133,18 +130,60 @@ public class TimerListActivity extends BaseTimerEditActivity<Timer> implements if (item2.isRecurring()) { return -1; } - return super.compare(item1, item2); + return c.compare(item1, item2); } }; } - protected boolean finishedSuccessImpl() { + + + @Override + protected boolean finishedSuccessImpl(List<Timer> results) { + clearCache(); + for(Timer r :results){ + CACHE.add(r); + } + pushResultCountToTitle(); + fillAdapter(); + return adapter.isEmpty() == false; + + } + + + protected void sort() { + /* */ + switch (sortBy) { + case MENU_GROUP_DEFAULT: { + Collections.sort(CACHE, getTimeComparator(false)); + break; + } + case MENU_GROUP_ALPHABET: { + Collections.sort(CACHE, new TitleComparator()); + break; + } + //case MENU_GROUP_CHANNEL: { + //sortItemsByChannel(results); + //} + } + } + + + @Override + protected void fillAdapter() { + adapter.clear(); - sortItemsByTime(results); + + if (CACHE.isEmpty()) { + return; + } + + sort(); + int day = -1; Calendar cal = Calendar.getInstance(); - for (Timer e : results) { + + for (Timer e : CACHE) { if (e.isRecurring()) { adapter.add(new EventListItem(e.getWeekdays())); } else { @@ -158,10 +197,32 @@ public class TimerListActivity extends BaseTimerEditActivity<Timer> implements } adapter.add(new EventListItem(e)); } - listView.setSelectionAfterHeaderView(); - return adapter.isEmpty() == false; + adapter.notifyDataSetChanged(); } +// protected boolean finishedSuccessImpl() { +// adapter.clear(); +// sortItemsByTime(results); +// int day = -1; +// Calendar cal = Calendar.getInstance(); +// for (Timer e : results) { +// if (e.isRecurring()) { +// adapter.add(new EventListItem(e.getWeekdays())); +// } else { +// 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)); +// } +// listView.setSelectionAfterHeaderView(); +// return adapter.isEmpty() == false; +// } + @Override protected boolean notifyDataSetChangedOnResume() { return true; @@ -187,33 +248,9 @@ public class TimerListActivity extends BaseTimerEditActivity<Timer> implements refresh(); } - /* - * (non-Javadoc) - * - * @see - * de.bjusystems.vdrmanager.gui.BaseActivity#onOptionsItemSelected(android - * .view.MenuItem) - */ - public boolean onOptionsItemSelected(final com.actionbarsherlock.view.MenuItem item) { - - switch (item.getItemId()) { - case R.id.timer_menu_add: - say("Comming soon..."); - return true; - } - - // switch (item.getItemId()) { - // case R.id.epg_menu_search: - // startSearchManager(); - // super.onSearchRequested(); - // break; - // case R.id.epg_menu_times: - // intent = new Intent(); - // /intent.setClass(this, EpgSearchTimesListActivity.class); - // startActivity(intent); - // break; - // } - return super.onOptionsItemSelected(item); + @Override + protected int getAvailableSortByEntries() { + return R.array.epg_sort_by_time_alpha; } public boolean onCreateOptionsMenu(final com.actionbarsherlock.view.Menu menu) { @@ -233,4 +270,9 @@ public class TimerListActivity extends BaseTimerEditActivity<Timer> implements return LIST_NAVIGATION_TIMERS; } + @Override + protected List<Timer> getCACHE() { + return CACHE; + } + } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/Utils.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/Utils.java index 20730da..dd66e8c 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/Utils.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/Utils.java @@ -29,11 +29,13 @@ import android.widget.Toast; import de.bjusystems.vdrmanager.R; import de.bjusystems.vdrmanager.StringUtils; import de.bjusystems.vdrmanager.app.C; +import de.bjusystems.vdrmanager.data.AudioTrack; import de.bjusystems.vdrmanager.data.Channel; import de.bjusystems.vdrmanager.data.Event; import de.bjusystems.vdrmanager.data.EventFormatter; import de.bjusystems.vdrmanager.data.Preferences; import de.bjusystems.vdrmanager.data.Recording; +import de.bjusystems.vdrmanager.data.TimerMatch; import de.bjusystems.vdrmanager.utils.svdrp.SvdrpAsyncTask; import de.bjusystems.vdrmanager.utils.svdrp.SvdrpEvent; import de.bjusystems.vdrmanager.utils.svdrp.SvdrpException; @@ -147,6 +149,7 @@ public class Utils { StringBuilder sb = new StringBuilder(); sb.append(getBaseUrl()).append("/").append(p.getStreamFormat()) .append("/").append(chn); + return sb.toString(); } @@ -160,12 +163,12 @@ public class Utils { return sb.toString(); } - public static void stream(Activity activity, Event event) { + public static void stream(final Activity activity, Event event) { stream(activity, event.getStreamId()); } - public static void stream(Activity a, Channel c) { - stream(a, String.valueOf(c.getId())); + public static void stream(final Activity activity, Channel channel) { + stream(activity, channel.getId()); } public static void stream(final Activity activity, final String idornr) { @@ -338,8 +341,7 @@ public class Utils { String urlstring = url.toString(); return urlstring; } else if (StringUtils.equals(m, "vdr-streamdev")) { - url.append("http://") - .append(Preferences.get().getSvdrpHost()) + url.append("http://").append(Preferences.get().getSvdrpHost()) // .append(":") .append(Integer.valueOf(Preferences.get().getStreamPort())) @@ -417,5 +419,33 @@ public class Utils { DateUtils.FORMAT_SHOW_TIME).toString(); } - + public static int getTimerStateDrawable(TimerMatch match, int full, + int begin, int end) { + if (match == TimerMatch.Full) { + return full; + } + + if (match == TimerMatch.Begin) { + return begin; + } + + return end; + } + + public static String formatAudio(Context context, List<AudioTrack> tracks){ + + StringBuilder sb = new StringBuilder(); + + String sep = ""; + for(AudioTrack a : tracks){ + sb.append(sep).append(a.display); + if(a.type.equals("d")){ + sb.append(" (").append(context.getString(R.string.audio_track_dolby)).append(")"); + } + sep = ", "; + } + return sb.toString(); + + } + } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/VdrPreferencesActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/VdrPreferencesActivity.java index 5d5ff0e..d3ec64c 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/VdrPreferencesActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/VdrPreferencesActivity.java @@ -240,6 +240,7 @@ public class VdrPreferencesActivity extends BasePreferencesActivity implements @Override protected void onResume() { super.onResume(); + pref.registerOnSharedPreferenceChangeListener(this); } @Override diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/ChannelClient.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/ChannelClient.java index a9af2dd..3b524c7 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/ChannelClient.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/ChannelClient.java @@ -141,9 +141,6 @@ public class ChannelClient extends SvdrpClient<Channel> implements private void received(Channel c) { - - - if (c.isGroupSeparator()) { currentGroup = c.getName(); channelGroups.add(currentGroup); diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/EpgClient.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/EpgClient.java index 0e7464e..88c1801 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/EpgClient.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/EpgClient.java @@ -12,7 +12,7 @@ import de.bjusystems.vdrmanager.data.Timer; * @author bju * */ -public class EpgClient extends SvdrpClient<Epg> { +public class EpgClient extends SvdrpClient<Epg> { /** Time to retrieve EPG for */ private String time; @@ -87,5 +87,6 @@ public class EpgClient extends SvdrpClient<Epg> { public int getProgressTextId() { return R.string.progress_whatson_loading; } + } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/RecordingClient.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/RecordingClient.java index ab832bc..025dcf9 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/RecordingClient.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/RecordingClient.java @@ -16,7 +16,7 @@ public class RecordingClient extends SvdrpClient<Recording> { } @Override - public void run() { + public synchronized void run() { runCommand("recordings"); } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpAsyncTask.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpAsyncTask.java index a979931..0a7e539 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpAsyncTask.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpAsyncTask.java @@ -7,7 +7,7 @@ import android.os.AsyncTask; public class SvdrpAsyncTask<Result, Client extends SvdrpClient<Result>> extends AsyncTask<Void, Object, Void> implements SvdrpListener, - SvdrpExceptionListener { + SvdrpExceptionListener, SvdrpResultListener<Result> { Client client; @@ -19,12 +19,23 @@ public class SvdrpAsyncTask<Result, Client extends SvdrpClient<Result>> extends List<SvdrpExceptionListener> exceptionListeners = new ArrayList<SvdrpExceptionListener>(); + List<SvdrpFinishedListener<Result>> finishedListeners = new ArrayList<SvdrpFinishedListener<Result>>(); + public SvdrpAsyncTask(final Client client) { this.client = client; this.client.addSvdrpListener(this); this.client.addSvdrpExceptionListener(this); + this.client.addSvdrpResultListener(this); + } + + protected List<Result> results = new ArrayList<Result>(); + + + public List<Result> getResults() { + return results; } + /** * Adds the listener to the list of listeners * @@ -47,6 +58,10 @@ public class SvdrpAsyncTask<Result, Client extends SvdrpClient<Result>> extends client.addSvdrpResultListener(listener); } + public void addSvdrpFinishedListener(final SvdrpFinishedListener<Result> liste) { + finishedListeners.add(liste); + } + /** * Adds the listener to the list of listeners * @@ -72,6 +87,14 @@ public class SvdrpAsyncTask<Result, Client extends SvdrpClient<Result>> extends protected void onProgressUpdate(final Object... values) { if (values.length == 1) { + + if (List.class.isAssignableFrom(values[0].getClass())) { + for (final SvdrpFinishedListener<Result> listener : finishedListeners) { + listener.finished((List<Result>) values[0]); + } + return; + } + for (final SvdrpListener listener : eventListeners) { listener.svdrpEvent((SvdrpEvent) values[0]); } @@ -111,11 +134,25 @@ public class SvdrpAsyncTask<Result, Client extends SvdrpClient<Result>> extends @Override public void svdrpEvent(SvdrpEvent event) { - publishProgress(event); + publishProgress(event);; + if(event == SvdrpEvent.FINISHED_SUCCESS){ + publishProgress(results); + } } +// @Override +// public void finished(ListResult> results) { +// publishProgress(results); +// } + @Override public void svdrpEvent(SvdrpEvent event, Throwable t) { publishProgress(event, t); } + + + @Override + public void svdrpEvent(Result result) { + results.add(result); + } } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpClient.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpClient.java index 90262e5..f6307f5 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpClient.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpClient.java @@ -45,8 +45,7 @@ public abstract class SvdrpClient<Result> { private final List<SvdrpExceptionListener> svdrpExceptionListeners = new ArrayList<SvdrpExceptionListener>(); - // private final List<SvdrpListener<>> listeners = new - // ArrayList<SvdrpListener<Result>>(); + private final List<SvdrpFinishedListener<Result>> svdrpFinishedListeners = new ArrayList<SvdrpFinishedListener<Result>>(); /** list of results */ // private final List<Result> results = new ArrayList<Result>(); @@ -129,6 +128,17 @@ public abstract class SvdrpClient<Result> { * @param listener * listener */ + public void addSvdrpFinishedListener( + final SvdrpFinishedListener<Result> listener) { + svdrpFinishedListeners.add(listener); + } + + /** + * Adds the listener to the list of listeners + * + * @param listener + * listener + */ public void addSvdrpExceptionListener(final SvdrpExceptionListener listener) { svdrpExceptionListeners.add(listener); } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpFinishedListener.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpFinishedListener.java new file mode 100644 index 0000000..7fba637 --- /dev/null +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpFinishedListener.java @@ -0,0 +1,9 @@ +package de.bjusystems.vdrmanager.utils.svdrp; + +import java.util.List; + +public interface SvdrpFinishedListener<Result> { + + public void finished(List<Result> results); + +} diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/TimerClient.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/TimerClient.java index bd98773..6417541 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/TimerClient.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/TimerClient.java @@ -33,7 +33,7 @@ public class TimerClient extends SvdrpClient<Timer> { * @param parameter parameter for lste */ @Override - public void run() { + public synchronized void run() { runCommand("timers"); } |