Calendar trigger

This commit is contained in:
jens 2024-01-07 15:15:56 +01:00
parent eaecf63724
commit 4521bc7d4e
5 changed files with 219 additions and 38 deletions

View File

@ -33,7 +33,7 @@ import java.util.List;
public class ActivityManageTriggerCalendar extends Activity public class ActivityManageTriggerCalendar extends Activity
{ {
CheckBox chkCalendarEventActive, chkCalendarAvailabilityBusy, chkCalendarAvailabilityFree, chkCalendarAvailabilityTentative, chkCalendarAvailabilityOutOfOffice, chkCalendarAvailabilityWorkingElsewhere, chkCalendarAllDayEvent, calendarEvaluateAllDayEvent; CheckBox chkCalendarEventActive, chkCalendarAvailabilityBusy, chkCalendarAvailabilityFree, chkCalendarAvailabilityTentative, chkCalendarAvailabilityOutOfOffice, chkCalendarAvailabilityWorkingElsewhere, chkCalendarAllDayEvent, chkCalendarEvaluateAllDayEvent, chkCalendarEvaluateReoccurring, chkCalendarReoccurring;
Spinner spinnerCalendarTitleDirection, spinnerCalendarLocationDirection, spinnerCalendarDescriptionDirection; Spinner spinnerCalendarTitleDirection, spinnerCalendarLocationDirection, spinnerCalendarDescriptionDirection;
EditText etCalendarTitle, etCalendarLocation, etCalendarDescription; EditText etCalendarTitle, etCalendarLocation, etCalendarDescription;
LinearLayout llCalendarSelection; LinearLayout llCalendarSelection;
@ -53,7 +53,7 @@ public class ActivityManageTriggerCalendar extends Activity
Miscellaneous.setDisplayLanguage(this); Miscellaneous.setDisplayLanguage(this);
setContentView(R.layout.activity_manage_trigger_calendar); setContentView(R.layout.activity_manage_trigger_calendar);
//TODO: Hint text about multiple rule execution //TODO: Hint text about multiple rule execution and reoccurring events always being included in the query
chkCalendarEventActive = (CheckBox) findViewById(R.id.chkCalendarEventActive); chkCalendarEventActive = (CheckBox) findViewById(R.id.chkCalendarEventActive);
spinnerCalendarTitleDirection = (Spinner)findViewById(R.id.spinnerCalendarTitleDirection); spinnerCalendarTitleDirection = (Spinner)findViewById(R.id.spinnerCalendarTitleDirection);
@ -65,7 +65,9 @@ public class ActivityManageTriggerCalendar extends Activity
chkCalendarAvailabilityTentative = (CheckBox)findViewById(R.id.chkCalendarAvailabilityTentative); chkCalendarAvailabilityTentative = (CheckBox)findViewById(R.id.chkCalendarAvailabilityTentative);
chkCalendarAvailabilityOutOfOffice = (CheckBox)findViewById(R.id.chkCalendarAvailabilityOutOfOffice); chkCalendarAvailabilityOutOfOffice = (CheckBox)findViewById(R.id.chkCalendarAvailabilityOutOfOffice);
chkCalendarAvailabilityWorkingElsewhere = (CheckBox)findViewById(R.id.chkCalendarAvailabilityWorkingElsewhere); chkCalendarAvailabilityWorkingElsewhere = (CheckBox)findViewById(R.id.chkCalendarAvailabilityWorkingElsewhere);
calendarEvaluateAllDayEvent = (CheckBox)findViewById(R.id.calendarEvaluateAllDayEvent); chkCalendarEvaluateAllDayEvent = (CheckBox)findViewById(R.id.chkCalendarEvaluateAllDayEvent);
chkCalendarEvaluateReoccurring = (CheckBox)findViewById(R.id.chkCalendarEvaluateReoccurring);
chkCalendarReoccurring = (CheckBox)findViewById(R.id.chkCalendarReoccurring);
tvMissingCalendarHint = (TextView) findViewById(R.id.tvMissingCalendarHint); tvMissingCalendarHint = (TextView) findViewById(R.id.tvMissingCalendarHint);
@ -91,9 +93,9 @@ public class ActivityManageTriggerCalendar extends Activity
spinnerCalendarDescriptionDirection.setAdapter(directionSpinnerAdapter); spinnerCalendarDescriptionDirection.setAdapter(directionSpinnerAdapter);
directionSpinnerAdapter.notifyDataSetChanged(); directionSpinnerAdapter.notifyDataSetChanged();
calendarEvaluateAllDayEvent.setChecked(false); chkCalendarEvaluateAllDayEvent.setChecked(false);
chkCalendarAllDayEvent.setEnabled(false); chkCalendarAllDayEvent.setEnabled(false);
calendarEvaluateAllDayEvent.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() chkCalendarEvaluateAllDayEvent.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{ {
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
@ -102,6 +104,17 @@ public class ActivityManageTriggerCalendar extends Activity
} }
}); });
chkCalendarEvaluateReoccurring.setChecked(false);
chkCalendarReoccurring.setEnabled(false);
chkCalendarEvaluateReoccurring.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
{
chkCalendarReoccurring.setEnabled(checked);
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{ {
if(ActivityPermissions.havePermission(Manifest.permission.READ_CALENDAR, ActivityManageTriggerCalendar.this) || ActivityPermissions.havePermission(Manifest.permission.WRITE_CALENDAR, ActivityManageTriggerCalendar.this)) if(ActivityPermissions.havePermission(Manifest.permission.READ_CALENDAR, ActivityManageTriggerCalendar.this) || ActivityPermissions.havePermission(Manifest.permission.WRITE_CALENDAR, ActivityManageTriggerCalendar.this))
@ -157,6 +170,18 @@ public class ActivityManageTriggerCalendar extends Activity
} }
}); });
chkCalendarReoccurring.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
{
if(checked)
chkCalendarReoccurring.setText(R.string.reoccurringTrue);
else
chkCalendarReoccurring.setText(R.string.reoccurringFalse);
}
});
bSaveTriggerCalendar.setOnClickListener(new View.OnClickListener() bSaveTriggerCalendar.setOnClickListener(new View.OnClickListener()
{ {
@Override @Override
@ -199,8 +224,10 @@ public class ActivityManageTriggerCalendar extends Activity
titleDir + Trigger.triggerParameter2Split + title + Trigger.triggerParameter2Split + titleDir + Trigger.triggerParameter2Split + title + Trigger.triggerParameter2Split +
descriptionDir + Trigger.triggerParameter2Split + description + Trigger.triggerParameter2Split + descriptionDir + Trigger.triggerParameter2Split + description + Trigger.triggerParameter2Split +
locationDir + Trigger.triggerParameter2Split + location + Trigger.triggerParameter2Split + locationDir + Trigger.triggerParameter2Split + location + Trigger.triggerParameter2Split +
String.valueOf(calendarEvaluateAllDayEvent.isChecked()) + Trigger.triggerParameter2Split + String.valueOf(chkCalendarEvaluateAllDayEvent.isChecked()) + Trigger.triggerParameter2Split +
String.valueOf(chkCalendarAllDayEvent.isChecked()) + Trigger.triggerParameter2Split + String.valueOf(chkCalendarAllDayEvent.isChecked()) + Trigger.triggerParameter2Split +
String.valueOf(chkCalendarEvaluateReoccurring.isChecked()) + Trigger.triggerParameter2Split +
String.valueOf(chkCalendarReoccurring.isChecked()) + Trigger.triggerParameter2Split +
Miscellaneous.explode(separator, availabilityList.toArray(new String[availabilityList.size()])) + Trigger.triggerParameter2Split + Miscellaneous.explode(separator, availabilityList.toArray(new String[availabilityList.size()])) + Trigger.triggerParameter2Split +
Miscellaneous.explode(separator, selectedCalendarsIdArray.toArray(new String[selectedCalendarsIdArray.size()])); Miscellaneous.explode(separator, selectedCalendarsIdArray.toArray(new String[selectedCalendarsIdArray.size()]));
@ -261,8 +288,10 @@ public class ActivityManageTriggerCalendar extends Activity
5 = location 5 = location
6 = evaluate all day event 6 = evaluate all day event
7 = all day event 7 = all day event
8 = availability list 8 = evaluate reoccurring
9 = calendars list 9 = reoccurring
10 = availability list
11 = calendars list
*/ */
for (int i = 0; i < directions.length; i++) for (int i = 0; i < directions.length; i++)
@ -281,12 +310,15 @@ public class ActivityManageTriggerCalendar extends Activity
etCalendarDescription.setText(input[3]); etCalendarDescription.setText(input[3]);
etCalendarLocation.setText(input[5]); etCalendarLocation.setText(input[5]);
calendarEvaluateAllDayEvent.setChecked(Boolean.parseBoolean(input[6])); chkCalendarEvaluateAllDayEvent.setChecked(Boolean.parseBoolean(input[6]));
chkCalendarAllDayEvent.setChecked(Boolean.parseBoolean(input[7])); chkCalendarAllDayEvent.setChecked(Boolean.parseBoolean(input[7]));
chkCalendarEvaluateReoccurring.setChecked(Boolean.parseBoolean(input[8]));
chkCalendarReoccurring.setChecked(Boolean.parseBoolean(input[9]));
String[] availabilities = null; String[] availabilities = null;
if (!StringUtils.isEmpty(input[8])) if (!StringUtils.isEmpty(input[10]))
availabilities = input[8].split(separator); availabilities = input[10].split(separator);
if (availabilities != null) if (availabilities != null)
{ {
@ -306,8 +338,8 @@ public class ActivityManageTriggerCalendar extends Activity
} }
String[] calendars = null; String[] calendars = null;
if (!StringUtils.isEmpty(input[9])) if (!StringUtils.isEmpty(input[11]))
calendars = input[9].split(separator); calendars = input[11].split(separator);
if (calendars != null) if (calendars != null)
{ {

View File

@ -622,7 +622,7 @@ public class Trigger
try try
{ {
String[] conditions = this.getTriggerParameter2().split(Trigger.triggerParameter2Split); String[] conditions = this.getTriggerParameter2().split(Trigger.triggerParameter2Split);
List<CalendarReceiver.CalendarEvent> calendarEvents = CalendarReceiver.readCalendarEvents(AutomationService.getInstance(), false); List<CalendarReceiver.CalendarEvent> calendarEvents = CalendarReceiver.readCalendarEvents(AutomationService.getInstance(), true,false);
/* /*
0 = titleDirection 0 = titleDirection
@ -675,19 +675,21 @@ public class Trigger
public boolean checkCalendarEvent(CalendarReceiver.CalendarEvent event, boolean ignoreActive) public boolean checkCalendarEvent(CalendarReceiver.CalendarEvent event, boolean ignoreActive)
{ {
String[] conditions = this.getTriggerParameter2().split(Trigger.triggerParameter2Split); String[] conditions = this.getTriggerParameter2().split(Trigger.triggerParameter2Split);
List<CalendarReceiver.CalendarEvent> calendarEvents = CalendarReceiver.readCalendarEvents(AutomationService.getInstance(), false); List<CalendarReceiver.CalendarEvent> calendarEvents = CalendarReceiver.readCalendarEvents(AutomationService.getInstance(), true,false);
/* /*
0 = titleDirection 0 = titleDir
1 = title; 1 = title
2 = descriptionDirection 2 = descriptionDir
3 = description 3 = description
4 = eventLocationDirection 4 = locationDir
5 = eventLocation 5 = location
6 = evaluate all day event 6 = evaluate all day event
7 = all day event 7 = all day event
8 = availabilityList 8 = evaluate reoccurring
9 = calendarList 9 = reoccurring
10 = availability list
11 = calendars list
*/ */
boolean isActive = getTriggerParameter(); boolean isActive = getTriggerParameter();
@ -733,9 +735,18 @@ public class Trigger
} }
} }
if (!StringUtils.isEmpty(conditions[8])) if (Boolean.parseBoolean(conditions[8]))
{ {
String[] availabilities = conditions[8].split(ActivityManageTriggerCalendar.separator); if (Boolean.parseBoolean(conditions[9]) != event.reoccurring)
{
Miscellaneous.logEvent("i", "CalendarCheck", "Reoccurring setting does not match.", 5);
return false;
}
}
if (!StringUtils.isEmpty(conditions[10]))
{
String[] availabilities = conditions[10].split(ActivityManageTriggerCalendar.separator);
if (availabilities.length > 0) if (availabilities.length > 0)
{ {
if (!Miscellaneous.arraySearch(availabilities, event.availability, false, true)) if (!Miscellaneous.arraySearch(availabilities, event.availability, false, true))
@ -746,9 +757,9 @@ public class Trigger
} }
} }
if (!StringUtils.isEmpty(conditions[9])) if (!StringUtils.isEmpty(conditions[11]))
{ {
String[] calendars = conditions[9].split(ActivityManageTriggerCalendar.separator); String[] calendars = conditions[11].split(ActivityManageTriggerCalendar.separator);
if (calendars.length > 0) if (calendars.length > 0)
{ {
if (!Miscellaneous.arraySearch(calendars, String.valueOf(event.calendarId), false, true)) if (!Miscellaneous.arraySearch(calendars, String.valueOf(event.calendarId), false, true))
@ -1998,11 +2009,19 @@ public class Trigger
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.allDayEventFalse) + ", "); returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.allDayEventFalse) + ", ");
} }
if (!StringUtils.isEmpty(conditions[8])) if(Boolean.parseBoolean(conditions[8]))
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.availabilities) + " " + conditions[8] + ", "); {
if (Boolean.parseBoolean(conditions[9]))
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.reoccurringTrue) + ", ");
else
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.reoccurringFalse) + ", ");
}
if (!StringUtils.isEmpty(conditions[9])) if (!StringUtils.isEmpty(conditions[10]))
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendars) + " " + conditions[9]); returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.availabilities) + " " + conditions[10] + ", ");
if (!StringUtils.isEmpty(conditions[11]))
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendars) + " " + conditions[11]);
if (returnString.toString().endsWith(", ")) if (returnString.toString().endsWith(", "))
returnString.delete(returnString.length() - 2, returnString.length()); returnString.delete(returnString.length() - 2, returnString.length());

View File

@ -9,6 +9,7 @@ import android.content.IntentFilter;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.provider.CalendarContract;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -39,6 +40,7 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
static List<AndroidCalendar> calendarsCache = null; static List<AndroidCalendar> calendarsCache = null;
static List<CalendarEvent> calendarEventsCache = null; static List<CalendarEvent> calendarEventsCache = null;
static List<CalendarEvent> calendarEventsReoccuringCache = null;
static Timer timer = null; static Timer timer = null;
static TimerTask timerTask = null; static TimerTask timerTask = null;
@ -166,7 +168,7 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
public String location; public String location;
public String availability; public String availability;
public Calendar start, end; public Calendar start, end;
public boolean allDay; public boolean allDay, reoccurring;
public boolean isCurrentlyActive() public boolean isCurrentlyActive()
{ {
@ -223,7 +225,8 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
cursor = context.getContentResolver().query( cursor = context.getContentResolver().query(
Uri.parse("content://com.android.calendar/calendars"), Uri.parse("content://com.android.calendar/calendars"),
new String[]{ "_id", "calendar_displayName", "ownerAccount", },
new String[]{ CalendarContract.Calendars._ID, CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CalendarContract.Calendars.OWNER_ACCOUNT, },
null, null, null); null, null, null);
cursor.moveToFirst(); cursor.moveToFirst();
@ -256,7 +259,7 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
return calendarsCache; return calendarsCache;
} }
public static List<CalendarEvent> readCalendarEvents(Context context, boolean includePastEvents) public static List<CalendarEvent> readCalendarEvents(Context context, boolean includeReoccurring, boolean includePastEvents)
{ {
if(calendarEventsCache == null) if(calendarEventsCache == null)
{ {
@ -266,7 +269,17 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
cursor = context.getContentResolver().query( cursor = context.getContentResolver().query(
Uri.parse("content://com.android.calendar/events"), Uri.parse("content://com.android.calendar/events"),
new String[] { "calendar_id", "_id", "title", "description", "allDay", "dtstart", "dtend", "eventLocation", "availability" }, new String[] {
CalendarContract.Events.CALENDAR_ID,
CalendarContract.Events._ID,
CalendarContract.Events.TITLE,
CalendarContract.Events.DESCRIPTION,
CalendarContract.Events.ALL_DAY,
CalendarContract.Events.DTSTART,
CalendarContract.Events.DTEND,
CalendarContract.Events.EVENT_LOCATION,
CalendarContract.Events.AVAILABILITY
},
null, null, null); null, null, null);
cursor.moveToFirst(); cursor.moveToFirst();
@ -299,6 +312,7 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
event.end = Miscellaneous.calendarFromLong(Long.parseLong(cursor.getString(6))); event.end = Miscellaneous.calendarFromLong(Long.parseLong(cursor.getString(6)));
event.location = cursor.getString(7); event.location = cursor.getString(7);
event.availability = cursor.getString(8); event.availability = cursor.getString(8);
event.reoccurring = false;
if(includePastEvents || event.end.getTimeInMillis() > now.getTimeInMillis()) if(includePastEvents || event.end.getTimeInMillis() > now.getTimeInMillis())
calendarEventsCache.add(event); calendarEventsCache.add(event);
@ -313,6 +327,87 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
} }
if(includeReoccurring && calendarEventsReoccuringCache == null)
{
calendarEventsReoccuringCache = new ArrayList<>();
Cursor cursor;
Calendar queryStart, queryEnd;
if(includePastEvents)
queryStart = Miscellaneous.calendarFromLong(0);
else
queryStart = Calendar.getInstance();
queryEnd = Calendar.getInstance();
queryEnd.add(Calendar.YEAR, 1);
cursor = context.getContentResolver().query(
Uri.parse("content://com.android.calendar/instances/when/" + queryStart.getTimeInMillis() + "/" + queryEnd.getTimeInMillis()),
new String[] {
CalendarContract.Instances.CALENDAR_ID,
CalendarContract.Instances._ID,
CalendarContract.Instances.TITLE,
CalendarContract.Instances.DESCRIPTION,
CalendarContract.Instances.ALL_DAY,
CalendarContract.Instances.BEGIN,
CalendarContract.Instances.END,
// CalendarContract.Instances.DTSTART,
// CalendarContract.Instances.DTEND,
CalendarContract.Instances.EVENT_LOCATION,
CalendarContract.Instances.AVAILABILITY
},
null, null, null);
cursor.moveToFirst();
// fetching calendars name
String CNames[] = new String[cursor.getCount()];
Calendar now = Calendar.getInstance();
for (int i = 0; i < CNames.length; i++)
{
try
{
CalendarEvent event = new CalendarEvent();
event.calendarId = Integer.parseInt(cursor.getString(0));
for(AndroidCalendar cal : readCalendars(context))
{
if(cal.calendarId == event.calendarId)
{
event.calendar = cal;
break;
}
}
event.eventId = cursor.getString(1);
event.title = cursor.getString(2);
event.description = cursor.getString(3);
event.allDay = cursor.getString(4).equals("1");
event.start = Miscellaneous.calendarFromLong(Long.parseLong(cursor.getString(5)));
event.end = Miscellaneous.calendarFromLong(Long.parseLong(cursor.getString(6)));
event.location = cursor.getString(7);
event.availability = cursor.getString(8);
event.reoccurring = true;
if(includePastEvents || event.end.getTimeInMillis() > now.getTimeInMillis())
{
// For the moment keeping separate records to some extent
calendarEventsReoccuringCache.add(event);
calendarEventsCache.add(event);
}
}
catch (Exception e)
{}
cursor.moveToNext();
}
if(cursor != null)
cursor.close();
}
return calendarEventsCache; return calendarEventsCache;
} }
@ -363,7 +458,7 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
if(nextWakeup == null) if(nextWakeup == null)
{ {
readCalendarEvents(Miscellaneous.getAnyContext(), false); readCalendarEvents(Miscellaneous.getAnyContext(), true,false);
calculateNextWakeup(); calculateNextWakeup();
} }
@ -395,7 +490,7 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
private static void calculateNextWakeup() private static void calculateNextWakeup()
{ {
Calendar now = Calendar.getInstance(); Calendar now = Calendar.getInstance();
List<CalendarEvent> events = readCalendarEvents(Miscellaneous.getAnyContext(), false); List<CalendarEvent> events = readCalendarEvents(Miscellaneous.getAnyContext(), true, false);
if (events.size() == 0) if (events.size() == 0)
{ {
@ -479,7 +574,7 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis
public static boolean mayRuleStillBeActivatedForPendingCalendarEvents(Rule rule) public static boolean mayRuleStillBeActivatedForPendingCalendarEvents(Rule rule)
{ {
for(CalendarEvent event : readCalendarEvents(Miscellaneous.getAnyContext(), false)) for(CalendarEvent event : readCalendarEvents(Miscellaneous.getAnyContext(), true,false))
{ {
for(Trigger t : rule.getTriggerSet()) for(Trigger t : rule.getTriggerSet())
{ {

View File

@ -176,7 +176,7 @@
android:background="#aa000000" /> android:background="#aa000000" />
<CheckBox <CheckBox
android:id="@+id/calendarEvaluateAllDayEvent" android:id="@+id/chkCalendarEvaluateAllDayEvent"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/evaluate" android:text="@string/evaluate"
@ -200,6 +200,38 @@
</TableRow> </TableRow>
<ImageView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_margin="10dp"
android:layout_marginVertical="@dimen/default_margin"
android:background="#aa000000" />
<CheckBox
android:id="@+id/chkCalendarEvaluateReoccurring"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/evaluate"
android:checked="false"/>
<TableRow
android:layout_marginBottom="@dimen/activity_vertical_margin">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/reoccurring" />
<CheckBox
android:id="@+id/chkCalendarReoccurring"
android:checked="false"
android:text="@string/reoccurringFalse"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<ImageView <ImageView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"

View File

@ -936,4 +936,7 @@
<string name="evaluate">Evaluate</string> <string name="evaluate">Evaluate</string>
<string name="errorLoadingValues">An error occur occured while loading values.</string> <string name="errorLoadingValues">An error occur occured while loading values.</string>
<string name="enterValidDataIntoParametersFields">Enter valid data into the parameter fields.</string> <string name="enterValidDataIntoParametersFields">Enter valid data into the parameter fields.</string>
<string name="reoccurringFalse">event is not reoccurring</string>
<string name="reoccurringTrue">event is reoccurring</string>
<string name="reoccurring">reoccurring</string>
</resources> </resources>