summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
authorArtur Dryomov <artur.dryomov@gmail.com>2013-07-29 04:09:29 +0300
committerArtur Dryomov <artur.dryomov@gmail.com>2013-07-29 04:13:11 +0300
commitf1b77bf3715b7a28cf4a9afd5f47b3e20d50ca36 (patch)
tree9b31ef06824f682f6446991e9677899c72855325 /android
parent766b6f5b14b517e178c9b86611d0edb7582e1ede (diff)
Add timer support.
Show the timer as a dialog, plus update all following information as it should be. Change-Id: Idae00b009ce098cfd482ec79629fc8f674502c9a
Diffstat (limited to 'android')
-rwxr-xr-xandroid/sdremote/res/drawable-hdpi/ic_action_timer.pngbin0 -> 1794 bytes
-rwxr-xr-xandroid/sdremote/res/drawable-mdpi/ic_action_timer.pngbin0 -> 1408 bytes
-rwxr-xr-xandroid/sdremote/res/drawable-xhdpi/ic_action_timer.pngbin0 -> 2284 bytes
-rw-r--r--android/sdremote/res/menu/menu_action_bar_slide_show.xml27
-rw-r--r--android/sdremote/res/menu/menu_action_bar_slide_show_grid.xml10
-rw-r--r--android/sdremote/res/menu/menu_action_bar_slide_show_pager.xml10
-rw-r--r--android/sdremote/res/values/strings.xml10
-rw-r--r--android/sdremote/res/values/themes.xml2
-rw-r--r--android/sdremote/src/org/libreoffice/impressremote/activity/ComputersActivity.java2
-rw-r--r--android/sdremote/src/org/libreoffice/impressremote/activity/SlideShowActivity.java155
-rw-r--r--android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java10
-rw-r--r--android/sdremote/src/org/libreoffice/impressremote/communication/SlideShow.java4
-rw-r--r--android/sdremote/src/org/libreoffice/impressremote/communication/Timer.java128
-rw-r--r--android/sdremote/src/org/libreoffice/impressremote/fragment/TimerEditingDialog.java136
-rw-r--r--android/sdremote/src/org/libreoffice/impressremote/fragment/TimerSettingDialog.java72
-rw-r--r--android/sdremote/src/org/libreoffice/impressremote/util/FragmentOperator.java24
-rw-r--r--android/sdremote/src/org/libreoffice/impressremote/util/Intents.java29
17 files changed, 481 insertions, 138 deletions
diff --git a/android/sdremote/res/drawable-hdpi/ic_action_timer.png b/android/sdremote/res/drawable-hdpi/ic_action_timer.png
new file mode 100755
index 000000000000..314ec9319a07
--- /dev/null
+++ b/android/sdremote/res/drawable-hdpi/ic_action_timer.png
Binary files differ
diff --git a/android/sdremote/res/drawable-mdpi/ic_action_timer.png b/android/sdremote/res/drawable-mdpi/ic_action_timer.png
new file mode 100755
index 000000000000..a09df2b99c58
--- /dev/null
+++ b/android/sdremote/res/drawable-mdpi/ic_action_timer.png
Binary files differ
diff --git a/android/sdremote/res/drawable-xhdpi/ic_action_timer.png b/android/sdremote/res/drawable-xhdpi/ic_action_timer.png
new file mode 100755
index 000000000000..c8771db97158
--- /dev/null
+++ b/android/sdremote/res/drawable-xhdpi/ic_action_timer.png
Binary files differ
diff --git a/android/sdremote/res/menu/menu_action_bar_slide_show.xml b/android/sdremote/res/menu/menu_action_bar_slide_show.xml
new file mode 100644
index 000000000000..eaa2b3d0ea3c
--- /dev/null
+++ b/android/sdremote/res/menu/menu_action_bar_slide_show.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item
+ android:id="@+id/menu_slides_pager"
+ android:title="@string/menu_slides_pager"
+ android:icon="@drawable/ic_action_pager"
+ android:showAsAction="always"/>
+
+ <item
+ android:id="@+id/menu_slides_grid"
+ android:title="@string/menu_slides_grid"
+ android:icon="@drawable/ic_action_grid"
+ android:showAsAction="always"/>
+
+ <item
+ android:id="@+id/menu_timer"
+ android:title="@string/menu_timer"
+ android:icon="@drawable/ic_action_timer"
+ android:showAsAction="ifRoom"/>
+
+ <item
+ android:id="@+id/menu_stop_slide_show"
+ android:title="@string/menu_stop_slide_show"
+ android:showAsAction="never"/>
+
+</menu> \ No newline at end of file
diff --git a/android/sdremote/res/menu/menu_action_bar_slide_show_grid.xml b/android/sdremote/res/menu/menu_action_bar_slide_show_grid.xml
deleted file mode 100644
index d65c782669e2..000000000000
--- a/android/sdremote/res/menu/menu_action_bar_slide_show_grid.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item
- android:id="@+id/menu_slides_pager"
- android:title="@string/menu_slides_pager"
- android:icon="@drawable/ic_action_pager"
- android:showAsAction="always"/>
-
-</menu> \ No newline at end of file
diff --git a/android/sdremote/res/menu/menu_action_bar_slide_show_pager.xml b/android/sdremote/res/menu/menu_action_bar_slide_show_pager.xml
deleted file mode 100644
index 023dcd5e3301..000000000000
--- a/android/sdremote/res/menu/menu_action_bar_slide_show_pager.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item
- android:id="@+id/menu_slides_grid"
- android:title="@string/menu_slides_grid"
- android:icon="@drawable/ic_action_grid"
- android:showAsAction="always"/>
-
-</menu> \ No newline at end of file
diff --git a/android/sdremote/res/values/strings.xml b/android/sdremote/res/values/strings.xml
index 16c1de821d6f..f315add6ce86 100644
--- a/android/sdremote/res/values/strings.xml
+++ b/android/sdremote/res/values/strings.xml
@@ -10,6 +10,7 @@
<string name="title_connection">Connection</string>
<string name="title_creation">Creation</string>
<string name="title_slide_show">Slide Show</string>
+ <string name="title_timer">Timer</string>
<string name="menu_licenses">Open source licenses</string>
<string name="menu_reconnect">Reconnect</string>
@@ -17,9 +18,13 @@
<string name="menu_remove_computer">Remove</string>
<string name="menu_slides_grid">Slides grid</string>
<string name="menu_slides_pager">Slides pager</string>
+ <string name="menu_timer">Timer</string>
+ <string name="menu_stop_slide_show">Stop slide show</string>
<string name="button_cancel">Cancel</string>
<string name="button_save">Save</string>
+ <string name="button_start">Start</string>
+ <string name="button_reset">Reset</string>
<string name="message_impress_pin_validation">Go to “Slide Show → Impress Remote” in LibreOffice Impress and enter the code.</string>
<string name="message_connection_failed_title">Connection failed</string>
@@ -28,6 +33,7 @@
<string name="message_impress_pairing_check">If you have Bluetooth pairing issues check instructions related to your desktop OS.</string>
<string name="message_ip_address_validation">You should type a valid IP address.</string>
<string name="message_name_notice">Name is optional — IP address would be used instead if you wish.</string>
+ <string name="message_time_is_up">Time is up</string>
<string name="hint_ip_address">IP address</string>
<string name="hint_name">Name</string>
@@ -35,5 +41,9 @@
<string name="header_notes">Notes</string>
<string name="mask_slide_show_progress">Slide %1$d from %2$d</string>
+ <plurals name="mask_timer_progress">
+ <item quantity="one">One minute left</item>
+ <item quantity="other">%d minutes left</item>
+ </plurals>
</resources>
diff --git a/android/sdremote/res/values/themes.xml b/android/sdremote/res/values/themes.xml
index da70aa8e5776..20a4b2226722 100644
--- a/android/sdremote/res/values/themes.xml
+++ b/android/sdremote/res/values/themes.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <style name="Theme.ImpressRemote" parent="Theme.Sherlock.Light.DarkActionBar">
+ <style name="Theme.ImpressRemote" parent="Theme.Sherlock.Light.DarkActionBar.ForceOverflow">
<item name="android:actionBarStyle">@style/Theme.ImpressRemote.ActionBar</item>
<item name="actionBarStyle">@style/Theme.ImpressRemote.ActionBar</item>
diff --git a/android/sdremote/src/org/libreoffice/impressremote/activity/ComputersActivity.java b/android/sdremote/src/org/libreoffice/impressremote/activity/ComputersActivity.java
index 3fa617339b6d..2dd3b0b994b3 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/activity/ComputersActivity.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/activity/ComputersActivity.java
@@ -110,7 +110,7 @@ public class ComputersActivity extends SherlockFragmentActivity implements Actio
private void setUpComputersList() {
Fragment aComputersFragment = ComputersFragment.newInstance(ComputersFragment.Type.WIFI);
- FragmentOperator.setUpFragment(this, aComputersFragment);
+ FragmentOperator.addFragment(this, aComputersFragment);
}
@Override
diff --git a/android/sdremote/src/org/libreoffice/impressremote/activity/SlideShowActivity.java b/android/sdremote/src/org/libreoffice/impressremote/activity/SlideShowActivity.java
index 4b91a6af8f65..06967d1be6fd 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/activity/SlideShowActivity.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/activity/SlideShowActivity.java
@@ -16,8 +16,8 @@ import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
+import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.LocalBroadcastManager;
import com.actionbarsherlock.app.SherlockFragmentActivity;
@@ -26,8 +26,12 @@ import com.actionbarsherlock.view.MenuItem;
import org.libreoffice.impressremote.R;
import org.libreoffice.impressremote.communication.CommunicationService;
import org.libreoffice.impressremote.communication.SlideShow;
+import org.libreoffice.impressremote.communication.Timer;
import org.libreoffice.impressremote.fragment.SlidesGridFragment;
import org.libreoffice.impressremote.fragment.SlidesPagerFragment;
+import org.libreoffice.impressremote.fragment.TimerEditingDialog;
+import org.libreoffice.impressremote.fragment.TimerSettingDialog;
+import org.libreoffice.impressremote.util.FragmentOperator;
import org.libreoffice.impressremote.util.Intents;
public class SlideShowActivity extends SherlockFragmentActivity implements ServiceConnection {
@@ -57,7 +61,7 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
}
private void setUpFragment() {
- setUpFragment(buildFragment());
+ FragmentOperator.replaceFragmentAnimated(this, buildFragment());
}
private Fragment buildFragment() {
@@ -73,15 +77,6 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
}
}
- private void setUpFragment(Fragment aFragment) {
- FragmentTransaction aTransaction = getSupportFragmentManager().beginTransaction();
- aTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
-
- aTransaction.replace(android.R.id.content, aFragment);
-
- aTransaction.commit();
- }
-
private void bindService() {
Intent aIntent = Intents.buildCommunicationServiceIntent(this);
bindService(aIntent, this, Context.BIND_AUTO_CREATE);
@@ -124,6 +119,30 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
public void onReceive(Context aContext, Intent aIntent) {
if (Intents.Actions.SLIDE_CHANGED.equals(aIntent.getAction())) {
mSlideShowActivity.setUpSlideShowInformation();
+ return;
+ }
+
+ if (Intents.Actions.TIMER_UPDATED.equals(aIntent.getAction())) {
+ mSlideShowActivity.setUpSlideShowInformation();
+ return;
+ }
+
+ if (Intents.Actions.TIMER_STARTED.equals(aIntent.getAction())) {
+ int aMinutesLength = aIntent.getIntExtra(Intents.Extras.MINUTES, 0);
+ mSlideShowActivity.startTimer(aMinutesLength);
+ return;
+ }
+
+ if (Intents.Actions.TIMER_RESUMED.equals(aIntent.getAction())) {
+ mSlideShowActivity.resumeTimer();
+ return;
+ }
+
+ if (Intents.Actions.TIMER_CHANGED.equals(aIntent.getAction())) {
+ int aMinutesLength = aIntent.getIntExtra(Intents.Extras.MINUTES, 0);
+ mSlideShowActivity.changeTimer(aMinutesLength);
+ mSlideShowActivity.resumeTimer();
+ mSlideShowActivity.setUpSlideShowInformation();
}
}
}
@@ -131,6 +150,10 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
private IntentFilter buildIntentsReceiverFilter() {
IntentFilter aIntentFilter = new IntentFilter();
aIntentFilter.addAction(Intents.Actions.SLIDE_CHANGED);
+ aIntentFilter.addAction(Intents.Actions.TIMER_UPDATED);
+ aIntentFilter.addAction(Intents.Actions.TIMER_STARTED);
+ aIntentFilter.addAction(Intents.Actions.TIMER_RESUMED);
+ aIntentFilter.addAction(Intents.Actions.TIMER_CHANGED);
return aIntentFilter;
}
@@ -148,6 +171,10 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
getSupportActionBar().setSubtitle(buildSlideShowTimerProgress());
}
+ private boolean isServiceBound() {
+ return mCommunicationService != null;
+ }
+
private String buildSlideShowProgress() {
SlideShow aSlideShow = mCommunicationService.getSlideShow();
@@ -158,7 +185,38 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
}
private String buildSlideShowTimerProgress() {
- return null;
+ Timer aTimer = mCommunicationService.getSlideShow().getTimer();
+
+ if (!aTimer.isSet()) {
+ return null;
+ }
+
+ if (aTimer.isTimeUp()) {
+ return getString(R.string.message_time_is_up);
+ }
+
+ int aMinutesLeft = aTimer.getMinutesLeft();
+
+ return getResources().getQuantityString(R.plurals.mask_timer_progress, aMinutesLeft, aMinutesLeft);
+ }
+
+ private void startTimer(int aMinutesLength) {
+ Timer aTimer = mCommunicationService.getSlideShow().getTimer();
+
+ aTimer.setMinutesLength(aMinutesLength);
+ aTimer.start();
+
+ setUpSlideShowInformation();
+ }
+
+ private void resumeTimer() {
+ mCommunicationService.getSlideShow().getTimer().resume();
+ }
+
+ private void changeTimer(int aMinutesLength) {
+ Timer aTimer = mCommunicationService.getSlideShow().getTimer();
+
+ aTimer.setMinutesLength(aMinutesLength);
}
@Override
@@ -170,27 +228,42 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
@Override
public boolean onCreateOptionsMenu(Menu aMenu) {
- getSupportMenuInflater().inflate(getActionBarMenuResourceId(), aMenu);
+ getSupportMenuInflater().inflate(R.menu.menu_action_bar_slide_show, aMenu);
return true;
}
- private int getActionBarMenuResourceId() {
+ @Override
+ public boolean onPrepareOptionsMenu(Menu aMenu) {
+ MenuItem aSlidesPagerMenuItem = aMenu.findItem(R.id.menu_slides_pager);
+ MenuItem aSlidesGridMenuItem = aMenu.findItem(R.id.menu_slides_grid);
+
switch (mMode) {
case PAGER:
- return R.menu.menu_action_bar_slide_show_pager;
+ aSlidesPagerMenuItem.setVisible(false);
+ aSlidesGridMenuItem.setVisible(true);
+ break;
case GRID:
- return R.menu.menu_action_bar_slide_show_grid;
+ aSlidesPagerMenuItem.setVisible(true);
+ aSlidesGridMenuItem.setVisible(false);
+ break;
default:
- return R.menu.menu_action_bar_slide_show_pager;
+ break;
}
+
+ return super.onPrepareOptionsMenu(aMenu);
}
@Override
public boolean onOptionsItemSelected(MenuItem aMenuItem) {
switch (aMenuItem.getItemId()) {
+ case android.R.id.home:
+ navigateUp();
+
+ return true;
+
case R.id.menu_slides_grid:
mMode = Mode.GRID;
@@ -207,8 +280,13 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
return true;
- case android.R.id.home:
- navigateUp();
+ case R.id.menu_timer:
+ callTimer();
+
+ return true;
+
+ case R.id.menu_stop_slide_show:
+ stopSlideShow();
return true;
@@ -217,11 +295,38 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
}
}
+ private void navigateUp() {
+ finish();
+ }
+
private void refreshActionBarMenu() {
supportInvalidateOptionsMenu();
}
- private void navigateUp() {
+ private void callTimer() {
+ Timer aTimer = mCommunicationService.getSlideShow().getTimer();
+
+ if (aTimer.isSet()) {
+ int aTimerLength = aTimer.getMinutesLeft();
+
+ DialogFragment aFragment = TimerEditingDialog.newInstance(aTimerLength);
+ aFragment.show(getSupportFragmentManager(), TimerEditingDialog.TAG);
+
+ pauseTimer();
+ }
+ else {
+ DialogFragment aFragment = TimerSettingDialog.newInstance();
+ aFragment.show(getSupportFragmentManager(), TimerSettingDialog.TAG);
+ }
+ }
+
+ private void pauseTimer() {
+ mCommunicationService.getSlideShow().getTimer().pause();
+ }
+
+ private void stopSlideShow() {
+ mCommunicationService.getTransmitter().stopPresentation();
+
finish();
}
@@ -245,11 +350,17 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
protected void onDestroy() {
super.onDestroy();
+ stopTimer();
+
disconnectComputer();
unbindService();
}
+ private void stopTimer() {
+ mCommunicationService.getSlideShow().getTimer().stop();
+ }
+
private void disconnectComputer() {
if (!isServiceBound()) {
return;
@@ -258,10 +369,6 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
mCommunicationService.disconnect();
}
- private boolean isServiceBound() {
- return mCommunicationService != null;
- }
-
private void unbindService() {
if (!isServiceBound()) {
return;
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java b/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java
index 2977921f25a9..6041190f5857 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java
@@ -19,7 +19,7 @@ import android.support.v4.content.LocalBroadcastManager;
import org.libreoffice.impressremote.util.Intents;
-public class CommunicationService extends Service implements Runnable, MessagesListener {
+public class CommunicationService extends Service implements Runnable, MessagesListener, Timer.TimerListener {
public static enum State {
DISCONNECTED, SEARCHING, CONNECTING, CONNECTED
}
@@ -58,7 +58,7 @@ public class CommunicationService extends Service implements Runnable, MessagesL
mServersManager = new ServersManager(this);
- mSlideShow = new SlideShow();
+ mSlideShow = new SlideShow(new Timer(this));
mThread = new Thread(this);
mThread.start();
@@ -279,6 +279,12 @@ public class CommunicationService extends Service implements Runnable, MessagesL
}
@Override
+ public void onTimerUpdated() {
+ Intent aIntent = Intents.buildTimerUpdatedIntent();
+ LocalBroadcastManager.getInstance(this).sendBroadcast(aIntent);
+ }
+
+ @Override
public void onDestroy() {
stopSearch();
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/SlideShow.java b/android/sdremote/src/org/libreoffice/impressremote/communication/SlideShow.java
index 0b9b1d6dc61a..f6aa6dd1b40e 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/communication/SlideShow.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/SlideShow.java
@@ -20,14 +20,14 @@ public class SlideShow {
private final Timer mTimer;
- public SlideShow() {
+ public SlideShow(Timer aTimer) {
this.mSlidesCount = 0;
this.mCurrentSlideIndex = 0;
this.mSlidePreviewsBytes = new SparseArray<byte[]>();
this.mSlideNotes = new SparseArray<String>();
- this.mTimer = new Timer();
+ this.mTimer = aTimer;
}
public void setSlidesCount(int aSlidesCount) {
diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/Timer.java b/android/sdremote/src/org/libreoffice/impressremote/communication/Timer.java
index 84a793253328..9efc42e66fa9 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/communication/Timer.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/communication/Timer.java
@@ -8,116 +8,82 @@
*/
package org.libreoffice.impressremote.communication;
-public class Timer {
- /**
- * This stores the starting time of the timer if running.
- * <p/>
- * If paused this stores how long the timer was previously running.
- */
- private long mTime;
- private long mCountdownTime;
-
- private boolean mIsRunning;
- private boolean mIsCountdown;
-
- public Timer() {
- mTime = 0;
- mCountdownTime = 0;
-
- mIsRunning = false;
- mIsCountdown = false;
- }
+import java.util.concurrent.TimeUnit;
- /**
- * Set whether this timer should be a normal or a countdown timer.
- *
- * @param aIsCountdown Whether this should be a countdown timer.
- */
- public void setCountdown(boolean aIsCountdown) {
- mIsCountdown = aIsCountdown;
+import android.os.Handler;
- if (mIsRunning) {
- reset();
- }
+public class Timer implements Runnable {
+ public interface TimerListener {
+ public void onTimerUpdated();
}
- public boolean isCountdown() {
- return mIsCountdown;
- }
+ private static final long UPDATE_PERIOD_IN_MINUTES = 1;
+
+ private final Handler mTimerHandler;
+ private final TimerListener mTimerListener;
+
+ private int mTotalMinutes;
+ private int mPassedMinutes;
- /**
- * Set the countdown time. Can be set, and isn't lost, whatever mode
- * the timer is running in.
- *
- * @param aCountdownTime The countdown time.
- */
- public void setCountdownTime(long aCountdownTime) {
- mCountdownTime = aCountdownTime;
+ public Timer(TimerListener aTimerListener) {
+ mTimerHandler = new Handler();
+ mTimerListener = aTimerListener;
+
+ mTotalMinutes = 0;
+ mPassedMinutes = 0;
}
- public long getCountdownTime() {
- return mCountdownTime;
+ public void setMinutesLength(int aLengthInMinutes) {
+ mTotalMinutes = aLengthInMinutes;
}
- public boolean isRunning() {
- return mIsRunning;
+ public int getMinutesLength() {
+ return mTotalMinutes;
}
- /**
- * Reset the timer, and stop it it was running.
- */
- public void reset() {
- mIsRunning = false;
- mTime = 0;
+ public boolean isSet() {
+ return mTotalMinutes != 0;
}
public void start() {
- if (mIsRunning) {
+ if (!isSet()) {
return;
}
- mTime = System.currentTimeMillis() - mTime;
- mIsRunning = true;
+ mTimerHandler.postDelayed(this, TimeUnit.MINUTES.toMillis(UPDATE_PERIOD_IN_MINUTES));
}
- public void stop() {
- if (!mIsRunning)
- return;
+ @Override
+ public void run() {
+ updatePassedMinutes();
- mTime = System.currentTimeMillis() - mTime;
- mIsRunning = false;
- }
+ mTimerListener.onTimerUpdated();
- /**
- * Get either how long this timer has been running, or how long the
- * timer still has left to run.
- *
- * @return running time in millis.
- */
- public long getTimeMillis() {
- if (mIsCountdown) {
- return calculateCountdownRunningTime();
- }
+ start();
+ }
- return calculateRunningTime();
+ private void updatePassedMinutes() {
+ mPassedMinutes++;
}
- private long calculateCountdownRunningTime() {
- long aRunningTime = mCountdownTime - calculateRunningTime();
+ public void pause() {
+ stop();
+ }
- if (aRunningTime < 0) {
- reset();
- }
+ public void resume() {
+ start();
+ }
- return aRunningTime;
+ public void stop() {
+ mTimerHandler.removeCallbacks(this);
}
- private long calculateRunningTime() {
- if (mIsRunning) {
- return System.currentTimeMillis() - mTime;
- }
+ public boolean isTimeUp() {
+ return getMinutesLeft() <= 0;
+ }
- return mTime;
+ public int getMinutesLeft() {
+ return mTotalMinutes - mPassedMinutes;
}
}
diff --git a/android/sdremote/src/org/libreoffice/impressremote/fragment/TimerEditingDialog.java b/android/sdremote/src/org/libreoffice/impressremote/fragment/TimerEditingDialog.java
new file mode 100644
index 000000000000..accfd8bdeaaf
--- /dev/null
+++ b/android/sdremote/src/org/libreoffice/impressremote/fragment/TimerEditingDialog.java
@@ -0,0 +1,136 @@
+package org.libreoffice.impressremote.fragment;
+
+import java.util.concurrent.TimeUnit;
+
+import android.app.Dialog;
+import android.app.TimePickerDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.content.LocalBroadcastManager;
+import android.view.View;
+import android.widget.TimePicker;
+
+import com.actionbarsherlock.app.SherlockDialogFragment;
+import org.libreoffice.impressremote.R;
+import org.libreoffice.impressremote.util.Intents;
+
+public class TimerEditingDialog extends SherlockDialogFragment implements TimePickerDialog.OnTimeSetListener, DialogInterface.OnClickListener, DialogInterface.OnShowListener, View.OnClickListener {
+ public static final String TAG = "TIMER_EDITING";
+
+ private static final boolean IS_24_HOUR_VIEW = true;
+
+ private int mMinutes;
+
+ public static TimerEditingDialog newInstance(int aMinutes) {
+ TimerEditingDialog aDialog = new TimerEditingDialog();
+
+ aDialog.setArguments(buildArguments(aMinutes));
+
+ return aDialog;
+ }
+
+ private static Bundle buildArguments(int aMinutes) {
+ Bundle aArguments = new Bundle();
+
+ aArguments.putInt("MINUTES", aMinutes);
+
+ return aArguments;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mMinutes = getArguments().getInt("MINUTES");
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle aSavedInstanceState) {
+ TimePickerDialog aDialog = new TimePickerDialog(getActivity(), this,
+ getHours(mMinutes), getMinutes(mMinutes), IS_24_HOUR_VIEW);
+
+ aDialog.setTitle(R.string.title_timer);
+
+ aDialog.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.button_save), this);
+ aDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.button_cancel), this);
+ aDialog.setButton(DialogInterface.BUTTON_NEUTRAL, getString(R.string.button_reset), this);
+
+ aDialog.setOnShowListener(this);
+
+ return aDialog;
+ }
+
+ private int getMinutes(int aMinutes) {
+ return (int) (aMinutes - getHours(aMinutes) * TimeUnit.HOURS.toMinutes(1));
+ }
+
+ private int getHours(int aMinutes) {
+ return (int) (aMinutes / TimeUnit.HOURS.toMinutes(1));
+ }
+
+ @Override
+ public void onTimeSet(TimePicker aTimePicker, int aHour, int aMinute) {
+ mMinutes = getMinutes(aHour, aMinute);
+ }
+
+ private int getMinutes(int aHours, int aMinutes) {
+ return (int) (TimeUnit.HOURS.toMinutes(aHours) + aMinutes);
+ }
+
+ @Override
+ public void onClick(DialogInterface aDialogInterface, int aButtonId) {
+ getTimePickerDialog().onClick(aDialogInterface, aButtonId);
+
+ switch (aButtonId) {
+ case DialogInterface.BUTTON_NEGATIVE:
+ resumeTimer();
+ break;
+
+ case DialogInterface.BUTTON_POSITIVE:
+ changeTimer();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ private TimePickerDialog getTimePickerDialog() {
+ return (TimePickerDialog) getDialog();
+ }
+
+ private void resumeTimer() {
+ Intent aIntent = Intents.buildTimerResumedIntent();
+ LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(aIntent);
+ }
+
+ private void changeTimer() {
+ Intent aIntent = Intents.buildTimerChangedIntent(mMinutes);
+ LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(aIntent);
+ }
+
+ @Override
+ public void onShow(DialogInterface dialogInterface) {
+ setUpNeutralButton();
+ }
+
+ private void setUpNeutralButton() {
+ TimePickerDialog aDialog = (TimePickerDialog) getDialog();
+
+ aDialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener(this);
+ }
+
+ @Override
+ public void onClick(View aView) {
+ // Requires the additional listener to not close the dialog.
+
+ resetTime();
+ }
+
+ private void resetTime() {
+ TimePickerDialog aDialog = (TimePickerDialog) getDialog();
+
+ aDialog.updateTime(0, 0);
+ }
+}
diff --git a/android/sdremote/src/org/libreoffice/impressremote/fragment/TimerSettingDialog.java b/android/sdremote/src/org/libreoffice/impressremote/fragment/TimerSettingDialog.java
new file mode 100644
index 000000000000..99374f817bfe
--- /dev/null
+++ b/android/sdremote/src/org/libreoffice/impressremote/fragment/TimerSettingDialog.java
@@ -0,0 +1,72 @@
+package org.libreoffice.impressremote.fragment;
+
+import java.util.concurrent.TimeUnit;
+
+import android.app.Dialog;
+import android.app.TimePickerDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.content.LocalBroadcastManager;
+import android.widget.TimePicker;
+
+import com.actionbarsherlock.app.SherlockDialogFragment;
+import org.libreoffice.impressremote.R;
+import org.libreoffice.impressremote.util.Intents;
+
+public class TimerSettingDialog extends SherlockDialogFragment implements TimePickerDialog.OnTimeSetListener, DialogInterface.OnClickListener {
+ public static final String TAG = "TIMER_SETTING";
+
+ private static final int INITIAL_HOUR = 0;
+ private static final int INITIAL_MINUTE = 15;
+
+ private static final boolean IS_24_HOUR_VIEW = true;
+
+ private int mMinutes;
+
+ public static TimerSettingDialog newInstance() {
+ return new TimerSettingDialog();
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle aSavedInstanceState) {
+ TimePickerDialog aDialog = new TimePickerDialog(getActivity(), this,
+ INITIAL_HOUR, INITIAL_MINUTE, IS_24_HOUR_VIEW);
+
+ aDialog.setTitle(R.string.title_timer);
+
+ aDialog.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.button_start), this);
+ aDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.button_cancel), this);
+
+ return aDialog;
+ }
+
+ @Override
+ public void onTimeSet(TimePicker aTimePicker, int aHour, int aMinute) {
+ mMinutes = getMinutes(aHour, aMinute);
+ }
+
+ private int getMinutes(int aHours, int aMinutes) {
+ return (int) (TimeUnit.HOURS.toMinutes(aHours) + aMinutes);
+ }
+
+ @Override
+ public void onClick(DialogInterface aDialogInterface, int aButtonId) {
+ getTimePickerDialog().onClick(aDialogInterface, aButtonId);
+
+ if (aButtonId != DialogInterface.BUTTON_POSITIVE) {
+ return;
+ }
+
+ startTimer();
+ }
+
+ private TimePickerDialog getTimePickerDialog() {
+ return (TimePickerDialog) getDialog();
+ }
+
+ private void startTimer() {
+ Intent aIntent = Intents.buildTimerStartedIntent(mMinutes);
+ LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(aIntent);
+ }
+}
diff --git a/android/sdremote/src/org/libreoffice/impressremote/util/FragmentOperator.java b/android/sdremote/src/org/libreoffice/impressremote/util/FragmentOperator.java
index 3c6506307938..af7e47c5b700 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/util/FragmentOperator.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/util/FragmentOperator.java
@@ -17,25 +17,35 @@ public final class FragmentOperator {
private FragmentOperator() {
}
- public static void setUpFragment(FragmentActivity aActivity, Fragment aFragment) {
- if (isFragmentSetUp(aActivity)) {
+ public static void addFragment(FragmentActivity aActivity, Fragment aFragment) {
+ if (isFragmentAdded(aActivity)) {
return;
}
- installFragment(aActivity, aFragment);
+ FragmentTransaction aFragmentTransaction = beginFragmentTransaction(aActivity);
+
+ aFragmentTransaction.add(android.R.id.content, aFragment);
+
+ aFragmentTransaction.commit();
}
- private static boolean isFragmentSetUp(FragmentActivity aActivity) {
+ private static boolean isFragmentAdded(FragmentActivity aActivity) {
FragmentManager aFragmentManager = aActivity.getSupportFragmentManager();
return aFragmentManager.findFragmentById(android.R.id.content) != null;
}
- private static void installFragment(FragmentActivity aActivity, Fragment aFragment) {
+ private static FragmentTransaction beginFragmentTransaction(FragmentActivity aActivity) {
FragmentManager aFragmentManager = aActivity.getSupportFragmentManager();
- FragmentTransaction aFragmentTransaction = aFragmentManager.beginTransaction();
- aFragmentTransaction.add(android.R.id.content, aFragment);
+ return aFragmentManager.beginTransaction();
+ }
+
+ public static void replaceFragmentAnimated(FragmentActivity aActivity, Fragment aFragment) {
+ FragmentTransaction aFragmentTransaction = beginFragmentTransaction(aActivity);
+ aFragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
+
+ aFragmentTransaction.replace(android.R.id.content, aFragment);
aFragmentTransaction.commit();
}
diff --git a/android/sdremote/src/org/libreoffice/impressremote/util/Intents.java b/android/sdremote/src/org/libreoffice/impressremote/util/Intents.java
index ad7cfc1324c9..eb85418ea14d 100644
--- a/android/sdremote/src/org/libreoffice/impressremote/util/Intents.java
+++ b/android/sdremote/src/org/libreoffice/impressremote/util/Intents.java
@@ -39,6 +39,11 @@ public final class Intents {
public static final String SLIDE_CHANGED = "SLIDE_CHANGED";
public static final String SLIDE_PREVIEW = "SLIDE_PREVIEW";
public static final String SLIDE_NOTES = "SLIDE_NOTES";
+
+ public static final String TIMER_UPDATED = "TIMER_UPDATED";
+ public static final String TIMER_STARTED = "TIMER_STARTED";
+ public static final String TIMER_RESUMED = "TIMER_RESUMED";
+ public static final String TIMER_CHANGED = "TIMER_CHANGED";
}
public static final class Extras {
@@ -52,6 +57,8 @@ public final class Intents {
public static final String SERVER_NAME = "SERVER_NAME";
public static final String SLIDE_INDEX = "SLIDE_INDEX";
+
+ public static final String MINUTES = "MINUTES";
}
public static final class RequestCodes {
@@ -139,6 +146,28 @@ public final class Intents {
public static Intent buildCommunicationServiceIntent(Context aContext) {
return new Intent(aContext, CommunicationService.class);
}
+
+ public static Intent buildTimerUpdatedIntent() {
+ return new Intent(Actions.TIMER_UPDATED);
+ }
+
+ public static Intent buildTimerStartedIntent(int aMinutesLength) {
+ Intent aIntent = new Intent(Actions.TIMER_STARTED);
+ aIntent.putExtra(Extras.MINUTES, aMinutesLength);
+
+ return aIntent;
+ }
+
+ public static Intent buildTimerResumedIntent() {
+ return new Intent(Actions.TIMER_RESUMED);
+ }
+
+ public static Intent buildTimerChangedIntent(int aMinutesLength) {
+ Intent aIntent = new Intent(Actions.TIMER_CHANGED);
+ aIntent.putExtra(Extras.MINUTES, aMinutesLength);
+
+ return aIntent;
+ }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */