Merge remote-tracking branch 'goog/ics-ub-calendar-cream' into catchup
Conflicts: Android.mk res/values-de/strings.xml src/com/android/calendar/selectcalendars/SelectSyncedCalendarsMultiAccountActivity.java Change-Id: Ibee089fc6a12ea9dcde5555992fb873afd501224
9
.classpath
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src_ex_common"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
bin/
|
||||
gen/
|
||||
.project
|
||||
|
@ -4,7 +4,7 @@ include $(CLEAR_VARS)
|
||||
# Include res dir from chips
|
||||
chips_dir := ../../../frameworks/ex/chips/res
|
||||
res_dirs := $(chips_dir) res
|
||||
src_dirs := src extensions_src
|
||||
src_dirs := src
|
||||
|
||||
LOCAL_EMMA_COVERAGE_FILTER := +com.android.calendar.*
|
||||
|
||||
@ -24,6 +24,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
android-common-chips \
|
||||
android-support-v4 \
|
||||
calendar-common
|
||||
|
||||
LOCAL_SDK_VERSION := current
|
||||
|
||||
LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dirs))
|
||||
|
@ -38,7 +38,7 @@
|
||||
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH.mail" />
|
||||
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="16"></uses-sdk>
|
||||
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="17"></uses-sdk>
|
||||
|
||||
<application android:name="CalendarApplication"
|
||||
android:label="@string/app_label" android:icon="@mipmap/ic_launcher_calendar"
|
||||
|
1
libs/android-support-v4.jar
Symbolic link
@ -0,0 +1 @@
|
||||
../../../../out/target/common/obj/JAVA_LIBRARIES/android-support-v4_intermediates/javalib.jar
|
53
mkprojectfile
Executable file
@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
# Creates eclipse .project file
|
||||
|
||||
pushd ../../.. > /dev/null
|
||||
sed -e "s,SRC_ROOT_DIR,$PWD," <<- EOF > packages/apps/Calendar/.project
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>CalendarAndroid</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>src_ex_common</name>
|
||||
<type>2</type>
|
||||
<location>SRC_ROOT_DIR/frameworks/ex/common/java</location>
|
||||
</link>
|
||||
<link>
|
||||
<name>src_opt_calendar</name>
|
||||
<type>2</type>
|
||||
<location>SRC_ROOT_DIR/frameworks/opt/calendar/src</location>
|
||||
</link>
|
||||
</linkedResources>
|
||||
</projectDescription>
|
||||
EOF
|
||||
popd > /dev/null
|
||||
|
@ -10,6 +10,9 @@
|
||||
-keepclassmembers class com.android.calendar.AllInOneActivity {
|
||||
*** handleSelectSyncedCalendarsClicked(...);
|
||||
}
|
||||
-keepclassmembers class com.android.calendar.AsyncQueryService {
|
||||
*** setTestHandler(...);
|
||||
}
|
||||
-keepclassmembers class com.android.calendar.DayView {
|
||||
*** setAnimateDayHeight(...);
|
||||
*** setAnimateDayEventHeight(...);
|
||||
@ -25,5 +28,6 @@
|
||||
}
|
||||
|
||||
-keepclassmembers class * implements android.content.SharedPreferences$Editor {
|
||||
public *** apply();
|
||||
public *** apply();
|
||||
}
|
||||
|
||||
|
17
project.properties
Normal file
@ -0,0 +1,17 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system edit
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
#
|
||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=android-17
|
||||
android.library=false
|
||||
android.library.reference.1=../../../frameworks/ex/chips
|
||||
android.library.reference.2=../../../frameworks/opt/calendar
|
BIN
res/drawable-hdpi/ic_call.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
res/drawable-hdpi/ic_history_holo_light.png
Normal file
After Width: | Height: | Size: 749 B |
BIN
res/drawable-hdpi/ic_map.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
res/drawable-mdpi/ic_call.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
res/drawable-mdpi/ic_history_holo_light.png
Normal file
After Width: | Height: | Size: 507 B |
BIN
res/drawable-mdpi/ic_map.png
Normal file
After Width: | Height: | Size: 893 B |
BIN
res/drawable-xhdpi/ic_call.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
res/drawable-xhdpi/ic_history_holo_light.png
Normal file
After Width: | Height: | Size: 916 B |
BIN
res/drawable-xhdpi/ic_map.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
@ -72,7 +72,7 @@
|
||||
android:id="@+id/what_label"
|
||||
android:text="@string/what_label"
|
||||
style="@style/TextAppearance.EditEvent_Label" />
|
||||
<AutoCompleteTextView
|
||||
<EditText
|
||||
android:id="@+id/title"
|
||||
style="@style/TextAppearance.EditEvent_Value"
|
||||
android:layout_width="wrap_content"
|
||||
@ -88,7 +88,7 @@
|
||||
<TextView
|
||||
android:text="@string/where_label"
|
||||
style="@style/TextAppearance.EditEvent_Label" />
|
||||
<EditText
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/location"
|
||||
android:singleLine="false"
|
||||
style="@style/TextAppearance.EditEvent_Value"
|
||||
|
86
res/layout/create_event_dialog.xml
Normal file
@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2012 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingRight="12dp" >
|
||||
|
||||
<EditText
|
||||
android:id="@+id/event_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:hint="@string/hint_what"
|
||||
android:paddingBottom="4dp"
|
||||
android:paddingTop="4dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/event_day"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingBottom="4dp"
|
||||
android:paddingTop="4dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/create_event_date_color"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingTop="4dp" >
|
||||
|
||||
<View
|
||||
android:id="@+id/color"
|
||||
android:layout_width="16dip"
|
||||
android:layout_height="16dip"
|
||||
android:layout_marginRight="4dip"
|
||||
android:layout_marginTop="5dip" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/calendar_name"
|
||||
style="?android:attr/textAppearanceMedium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_toRightOf="@id/color"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true"
|
||||
android:textColor="#333333" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/account_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@id/calendar_name"
|
||||
android:layout_below="@id/calendar_name"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="@color/calendar_owner_text_color" />
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
@ -68,7 +68,7 @@
|
||||
</LinearLayout>
|
||||
|
||||
<!-- WHAT -->
|
||||
<AutoCompleteTextView
|
||||
<EditText
|
||||
android:id="@+id/title"
|
||||
style="@style/TextAppearance.EditEvent_Value"
|
||||
android:singleLine="true"
|
||||
@ -78,7 +78,6 @@
|
||||
android:minHeight="48dip"
|
||||
android:hint="@string/hint_what"
|
||||
android:capitalize="sentences"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="textAutoCorrect|textCapSentences"
|
||||
android:focusable="true" />
|
||||
|
||||
@ -89,7 +88,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="6dip"
|
||||
android:focusable="true">
|
||||
<EditText
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/location"
|
||||
android:singleLine="false"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -255,7 +255,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="29dip"
|
||||
android:gravity="center_vertical"
|
||||
style="?android:attr/textAppearanceMedium"
|
||||
android:textColor="@color/event_info_body_color"
|
||||
@ -266,7 +265,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="29dip"
|
||||
android:gravity="center_vertical"
|
||||
style="?android:attr/textAppearanceMedium"
|
||||
android:textColor="@color/event_info_body_color"
|
||||
@ -277,7 +275,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="29dip"
|
||||
android:gravity="center_vertical"
|
||||
style="?android:attr/textAppearanceMedium"
|
||||
android:textColor="@color/event_info_body_color"
|
||||
|
56
res/layout/location_dropdown_item.xml
Normal file
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2012 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="48dip"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:background="?android:attr/activatedBackgroundIndicator">
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="48dip"
|
||||
android:layout_height="48dip"
|
||||
android:layout_marginLeft="0dip"
|
||||
android:src="@drawable/ic_contact_picture"
|
||||
android:cropToPadding="true"
|
||||
android:scaleType="centerCrop" />
|
||||
<LinearLayout
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:layout_weight="1">
|
||||
<TextView android:id="@+id/location_name"
|
||||
android:textColor="@drawable/list_item_font_primary"
|
||||
android:textSize="18sp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="8dip"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end" />
|
||||
<TextView android:id="@+id/location_address"
|
||||
android:textColor="@drawable/list_item_font_secondary"
|
||||
android:textSize="14sp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="8dip"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:layout_marginTop="-4dip" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
@ -55,6 +55,24 @@
|
||||
android:ellipsize="end" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/map_button"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="center_vertical|right"
|
||||
android:src="@drawable/ic_map"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:padding="8dip"
|
||||
android:contentDescription="@string/map_label" />
|
||||
<ImageButton
|
||||
android:id="@+id/call_button"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="center_vertical|right"
|
||||
android:src="@drawable/ic_call"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:padding="8dip"
|
||||
android:contentDescription="@string/call_label" />
|
||||
<ImageButton
|
||||
android:id="@+id/email_button"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Leë gebeurtenis nie geskep nie."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Uitnodigings sal gestuur word."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Opdaterings sal gestuur word."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Stoor"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Kalender-kennisgewings"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Bekyk gebeurtenis"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Uitnodiging"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"E-posorganiseerder"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"E-pos met"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Gebeurtenis nie opgespoor nie."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Kaart"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Bel"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Kitsantwoorde"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Redigeer verstek antwoorde wanneer jy aan gaste e-pos stuur"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Redigeer kitsantwoorde"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Begin solank sonder my."</item>
|
||||
<item msgid="8036557974294987511">"Jammer, ek kan nie meer kom nie. Ons sal moet herskeduleer."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Gepasmaakte boodskap..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Skryf jou eie"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organiseerder:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Herinneringe"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"VANDAG, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"ባዶ ክስተት አልተፈጠረም::"</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"ግብዣዎች ይላካሉ።"</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"ዝማኔዎች ይላካሉ።"</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"አስቀምጥ"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"የቀን መቁጠሪያማሳወቂያዎች"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"ዝግጅቶች አሳይ"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"የስብሰባ ግብዣ"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"የኢሜይል አደራጅ"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"በነዚህ ኢሜይል ላክ"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"ክስተት አልተገኘም።"</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"ካርታ"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"ደውል"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"ፈጣን ምላሾች"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"ለእንግዶች ኢሜይል ሲላክ ነባሪ ምላሾችን አርትዕ"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"ፈጣን ምላሾችን አርትዕ"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"እኔን አትጠብቁኝ፣ ጀምሩ።"</item>
|
||||
<item msgid="8036557974294987511">"ይቅርታ ልደርስ አልችልም። ለሌላ ጊዜ ቀጠሮ ማስያዝ ይኖርብናል።"</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"ብጁ መልዕክት…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"የእራስዎን ይጻፉ…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"አዘጋጅ፡"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"ማስታወሻዎች"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"ዛሬ፣ <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"لم يتم إنشاء الحدث لأنه فارغ."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"سيتم إرسال الدعوات."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"سيتم إرسال التحديثات."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"حفظ"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"إعلامات التقاويم"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"عرض الحدث"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"دعوة اجتماع"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"منظم البريد الإلكتروني"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"إرسال رسالة إلكترونية إلى"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"لم يتم العثور على الحدث."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"خريطة"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"اتصال"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"الردود السريعة"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"تعديل الردود الافتراضية في المراسلة الإلكترونية للمدعوين"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"تعديل الردود السريعة"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"ابدأوا بدوني."</item>
|
||||
<item msgid="8036557974294987511">"عذرًا، لا يمكنني الحضور. علينا إعادة الجدولة."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"رسالة مخصصة…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"اكتب ردك…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"المنظِّم:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"تذكيرات"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"اليوم، <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Пустое мерапрыемства не створана."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Запрашэнні будуць адпраўлены."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Абнаўленні будуць адпраўлены."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Захаваць"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Паведамленні календара"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Прагледзець падзею"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Запрашэнне на сустрэчу"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Напiсаць арганiзатару"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Электронная пошта з"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Мерапрыемства не знойдзена."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Карта"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Выклік"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Хуткія адказы"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Змяніць адказы па змаўчанні пры адпраўцы электронных лістоў гасцям"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Рэд. хутк. адказы"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Працягваць і пачаць без мяне."</item>
|
||||
<item msgid="8036557974294987511">"На жаль, я не паспяваю. Нам прыйдзецца перанесці мерапрыемства."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Карыстальніцкае паведамленне..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Напiшыце вы"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Арганізатар:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Напаміны"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"СЁННЯ, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Празно събитие: Не е създадено"</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Ще бъдат изпратени покани."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Ще бъдат изпратени актуализации."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Запазване"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Известия от Календар"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Преглед на събитие"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Покана за среща"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Имейл до организатора"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Изпращане на имейл посредством"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Събитието не бе намерено."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Карта"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Обаждане"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Бързи отговори"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Редакт. на отговорите по подразб. при изпращ. на имейли до гостите"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Бързи отг.: Редакт."</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Можете да започнете без мен."</item>
|
||||
<item msgid="8036557974294987511">"За съжаление няма да успея. Ще трябва да пренасрочим събитието."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Персонализирано съобщение…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Напишете свой собствен…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Организатор:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Напомняния"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"ДНЕС, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Esdeven. buit, no s\'ha creat."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"S\'enviaran les invitacions."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"S\'enviaran les actualitzacions."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Desa"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Notificacions de calendari"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Visualitza l\'esdeveniment"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Invitació a una reunió"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Envia un correu a l\'organitzador"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Correu electrònic amb"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"No s\'ha trobat l\'esdeveniment."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Mapa"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Truca"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Respostes ràpides"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Edita les respostes en escriure als convidats"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Edita resp. ràpid."</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Comenceu sense mi."</item>
|
||||
<item msgid="8036557974294987511">"Em sap greu, no hi puc assistir. Ho haurem de tornar a planificar."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Personalitza el missatge..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Escriu la teva…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organitz.:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Recordatoris"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"AVUI, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Prázdná událost se nevytvořila"</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Pozvánky budou odeslány."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Aktualizace budou odeslány."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Uložit"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Upozornění kalendáře"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Zobrazit událost"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Pozvánka na schůzku"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Poslat e-mail organizátorovi"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Psát si s uživateli"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Událost nebyla nalezena."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Mapa"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Volat"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Rychlé odpovědi"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Výchozí odpovědi"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Rychlé odpovědi"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Začněte beze mne."</item>
|
||||
<item msgid="8036557974294987511">"Lituji, nestíhám. Naplánujeme to na jindy."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Vlastní zpráva…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Napsat vlastní odpověď..."</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organizátor:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Připomenutí"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"Dnes, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Tom begivenhed ikke oprettet."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Invitationer vil blive sendt."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Opdateringer vil blive sendt."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Gem"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Meddelelser fra Kalender"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Vis begivenhed"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Mødeinvitation"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Send e-mail til arrangøren"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Send e-mail til"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Begivenheden blev ikke fundet."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Kort"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Ring op"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Hurtige svar"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Rediger standardsvar for, når der sendes e-mail til gæster"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Ret hurtige svar"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Gå bare i gang uden mig."</item>
|
||||
<item msgid="8036557974294987511">"Jeg kan desværre ikke nå det. Vi bliver nødt til at lave en ny aftale."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Tilpasset besked..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Skriv dit eget…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organisator:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Påmindelser"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"I DAG, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Leerer Termin nicht erstellt"</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Einladungen werden gesendet."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Updates werden gesendet."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Speichern"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Benachrichtigungen"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Termin anzeigen"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Einladung zu einer Besprechung"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"E-Mail an Organisator senden"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"E-Mail über"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Ereignis nicht gefunden"</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Karte"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Anrufen"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Kurzantworten"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Standardantworten beim Senden von E-Mails an Gäste bearbeiten"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Kurzantworten bearbeiten"</string>
|
||||
@ -115,10 +118,10 @@
|
||||
<string-array name="quick_response_defaults">
|
||||
<item msgid="1524421198348168403">"Bin einige Minuten verspätet"</item>
|
||||
<item msgid="6215158751728689832">"Bin in etwa 10 Minuten da"</item>
|
||||
<item msgid="4485794001743679338">"Fangt ohne mich an"</item>
|
||||
<item msgid="8036557974294987511">"Schaffe es leider nicht. Können wir neuen Termin ausmachen?"</item>
|
||||
<item msgid="4485794001743679338">"Soll ohne mich anfangen"</item>
|
||||
<item msgid="8036557974294987511">"Ich schaffe es leider nicht. Wir müssen einen neuen Termin ausmachen."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Benutzerdefinierte Nachricht..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Eigene Antwort schreiben…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organisator:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Erinnerungen"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"Heute, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Δεν δημιουργήθηκε κενό συμβάν."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Θα σταλούν προσκλήσεις."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Θα σταλούν ενημερώσεις."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Aποθήκευση"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Ειδοποιήσεις ημερολογίου"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Προβολή συμβάντος"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Πρόσκληση συνάντησης"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Αποστολή μηνύματος ηλεκτρονικού ταχυδρομείου στον οργανωτή"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Αποστολή μηνύματος ηλεκτρονικού ταχυδρομείου με"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Το συμβάν δεν βρέθηκε."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Χάρτης"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Κλήση"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Γρήγορες απαντήσ."</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Επεξ.προεπ.απ.κατά την αποστ.μην.ηλ.ταχ.στους καλεσμ."</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Επεξ.γρήγ.απαντ,"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Προχωρήστε και συνεχίστε χωρίς εμένα."</item>
|
||||
<item msgid="8036557974294987511">"Λυπάμαι, δεν θα καταφέρω να παρευρεθώ. Θα πρέπει να επαναπρογραμματίσουμε τη συνάντηση."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Προσαρμοσμένο μήνυμα…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Συντάξτε τη δική σας…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Διοργανωτής:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Υπενθυμίσεις"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"ΣΗΜΕΡΑ, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Empty event not created."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Invitations will be sent."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Updates will be sent."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Save"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Calendar notifications"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"View event"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Meeting invitation"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Email organiser"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Email with"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Event not found."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Map"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Call"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Quick responses"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Edit default responses when emailing guests"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Edit quick responses"</string>
|
||||
@ -118,7 +121,8 @@
|
||||
<item msgid="4485794001743679338">"Go ahead and start without me."</item>
|
||||
<item msgid="8036557974294987511">"Sorry, I can\'t make it. We\'ll have to reschedule."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Customised message..."</string>
|
||||
<!-- no translation found for quick_response_custom_msg (8792374208224108798) -->
|
||||
<skip />
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organiser:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Reminders"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"TODAY, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"No se creó el evento vacío."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Se enviarán las invitaciones."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Se enviarán las actualizaciones."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Guardar"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Notificaciones de calendario"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Ver evento"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Invitación a la reunión"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Enviar correo al organizador"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Enviar correo a"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"No se encontró el evento."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Obtener mapa"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Llamar"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Respuestas rápidas"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Edita res. predet."</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Editar res. rápida"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Comienza sin mí."</item>
|
||||
<item msgid="8036557974294987511">"No puedo hacerlo. Tendremos que volver a programarlo"</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Mensaje personalizado…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Escribe tu propia respuesta…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organizador:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Recordatorios"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"HOY, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Evento vacío no creado"</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Se enviarán las invitaciones."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Se enviarán las actualizaciones."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Guardar"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Notificaciones de Calendar"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Ver evento"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Invitación a un evento"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Escribir al organizador"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Correo electrónico con"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"No se ha encontrado el evento."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Mapa"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Llamar"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Respuestas rápidas"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Editar respuestas predeterminadas al enviar correos electrónicos a los invitados"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Editar respuestas rápidas"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Empezad sin mi"</item>
|
||||
<item msgid="8036557974294987511">"No puedo, mejor en otro momento"</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Mensaje personalizado…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Escribe tu propia respuesta…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organizador:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Recordatorios"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"HOY, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Tühja sündmust ei loodud."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Kutsed saadetakse."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Värskendused saadetakse."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Salvesta"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Kalendriteadistused"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Sündmuse vaatamine"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Koosolekukutse"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Saatke korraldajale meil"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Meili saatmine:"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Sündmust ei leitud."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Kaart"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Helista"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Kiirvastused"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Vastuste muutmine"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Kiirvast. muutmine"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Alusta ilma minuta."</item>
|
||||
<item msgid="8036557974294987511">"Kahjuks ma ei jõua. Peame ajakava üle vaatama."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Kohandatud sõnum ..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Kirjutage ise …"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Korraldaja:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Meeldetuletused"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"TÄNA, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"رویداد خالی ایجاد نمیشود."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"دعوت نامهها ارسال خواهند شد."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"بهروزرسانیها ارسال خواهند شد."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"ذخیره"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"اعلانهای تقویم"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"مشاهده رویداد"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"دعوت نامه جلسه"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"سازماندهنده ایمیل"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"ایمیل با"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"رویداد یافت نشد."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"نقشه"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"تماس"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"پاسخهای سریع"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"ویرایش پاسخهای پیشفرض هنگام ارسال ایمیل به مهمانها"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"ویرایش پاسخهای سریع"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"دست به کار شوید و بدون من شروع کنید."</item>
|
||||
<item msgid="8036557974294987511">"با عرض پوزش، نمیتوانم این را ایجاد کنم. باید دوباره برنامهریزی کنیم."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"پیام سفارشی..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"نوشتن ..."</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"سازمان دهنده:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"یادآورها"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"امروز، <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Tyhjää tapahtumaa ei voi luoda"</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Kutsut lähetetään."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Päivitykset lähetetään."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Tallenna"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Kalenteri-ilmoitukset"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Näytä tapahtuma"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Kokouskutsu"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Sähköposti järjestäjälle"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Sähköposti ja"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Tapahtumaa ei löydy."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Kartta"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Soita"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Pikavastaukset"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Muokkaa pikavast."</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Muokkaa pikavast."</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Voitte aloittaa ilman minua."</item>
|
||||
<item msgid="8036557974294987511">"En pääse paikalle. Sovitaanko uusi aika?"</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Oma viesti..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Kirjoita oma…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Järjestäjä:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Muistutukset"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"TÄNÄÄN, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Événement vide non créé."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Les invitations vont être envoyées."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Les mises à jour vont être envoyées."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Enregistrer"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Notifications de l\'agenda"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Afficher l\'événement"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Invitation à une réunion"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Envoyer un e-mail à l\'organisateur"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Envoyer un e-mail via"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Événement introuvable."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Plan"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Appeler"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Réponses rapides"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Modifier réponses par défaut lors d\'envoi d\'e-mails aux invités"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Modif. rép. rapides"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Commencez sans moi."</item>
|
||||
<item msgid="8036557974294987511">"Désolé, je ne peux pas venir. Nous allons devoir reporter."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Message personnalisé…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Réponse personnalisée"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organisateur :"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Rappels"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"AUJOURD\'HUI, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"रिक्त ईवेंट नहीं बनाया गया."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"आमंत्रण भेज दिए जाएंगे."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"अपडेट भेज दिए जाएंगे."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"सहेजें"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"कैलेंडर सूचनाएं"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"ईवेंट देखें"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"मीटिंग आमंत्रण"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"ईमेल व्यवस्थापक"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"इन्हें ईमेल करें"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"इवेंट नहीं मिला."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"नक्शा"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"कॉल करें"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"त्वरित प्रतिसाद"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"जब अतिथि को ईमेल करें तो डिफ़ॉल्ट प्रतिसाद संपादित करें"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"त्वरित प्रतिसाद संपादित करें"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"आगे बढ़ें और मेरे बिना प्रारंभ करें."</item>
|
||||
<item msgid="8036557974294987511">"क्षमा करें, मुझसे यह कार्य नहीं हो पा रहा है. हमें पुन: शेड्यूल करना होगा."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"कस्टम संदेश…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"अपना स्वयं का लिखें…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"आयोजक:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"अनुस्मारक"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"आज, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Nije stvoren prazan događaj."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Pozivnice će biti poslane."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Ažuriranje će biti poslano."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Spremi"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Obavijesti kalendara"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Prikaži događaj"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Pozivnica za sastanak"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Organizator e-poruka"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Obavijesti e-poštom"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Događaj nije pronađen."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Karta"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Poziv"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Brzi odgovori"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Uređivanje zad. odgovora pri slanju gostima"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Uredi brze odgovore"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Samo naprijed, počnite bez mene."</item>
|
||||
<item msgid="8036557974294987511">"Žao mi je, ne mogu stići. Moramo promijeniti dogovor."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Prilagođena poruka…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Napišite vlastiti…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organizator:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Podsjetnici"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"DANAS, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Üres esemény nem hozható létre"</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"A rendszer meghívókat küld."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"A rendszer frissítéseket küld."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Mentés"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Naptár értesítései"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Esemény megtekintése"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Meghívás találkozóra"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"E-mail a szervezőnek"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"E-mail a következővel:"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Az esemény nem található."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Térkép"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Hívás"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Gyors válaszok"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Válaszok szerkesztése vendég e-mailek küldésekor"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Gyors válaszok szerkesztése"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Kezdjék el nélkülem."</item>
|
||||
<item msgid="8036557974294987511">"Sajnálom, nem érek oda. Kénytelenek leszünk átütemezni."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Egyéni üzenet..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Saját válasz írása..."</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Szervező:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Emlékeztetők"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"MA, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Acara kosong tidak dibuat."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Undangan akan dikirim."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Pembaruan akan dikirim."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Simpan"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Pemberitahuan kalender"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Lihat acara"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Undangan rapat"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Pengelola email"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Email dengan"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Acara tidak ditemukan."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Peta"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Panggil"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Tanggapan cepat"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Edit tanggapan default saat meng-email tamu"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Edit tanggapan cpt"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Silakan mulai tanpa saya."</item>
|
||||
<item msgid="8036557974294987511">"Maaf, saya tidak bisa. Kita harus menjadwalkan ulang."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Pesan khusus..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Tulis respons Anda sendiri…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Pnylenggara:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Pengingat"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"HARI INI, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Evento vuoto non creato."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Gli inviti verranno inviati."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Gli aggiornamenti verranno inviati."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Salva"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Notifiche di Google Calendar"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Visualizza evento"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Invito a riunione"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Invia email all\'organizzatore"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Invia email con"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Evento non trovato."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Mappa"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Chiama"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Risposte rapide"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Modifica risposte predefinite in caso di email agli invitati"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Modifica risposte rapide"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Continua e inizia senza di me."</item>
|
||||
<item msgid="8036557974294987511">"Spiacenti, impossibile portare a termine l\'operazione. È necessario stabilire una nuova pianificazione."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Personalizza messaggio…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Scrivi la tua risposta personale…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Agenda:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Promemoria"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"OGGI, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"האירוע הריק לא נוצר."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"הזמנות יישלחו."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"עדכונים יישלחו."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"שמור"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"התראות של יומן"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"הצג אירוע"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"הזמנה לפגישה"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"שלח דוא\"ל למארגן"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"שלח הודעת דוא\"ל באמצעות"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"האירוע לא נמצא."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"מפה"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"שיחה"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"תגובות מהירות"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"ערוך תגובות ברירת מחדל בעת שליחת דוא\"ל לאורחים"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"ערוך תגובות מהירות"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"תתחילו בלעדי."</item>
|
||||
<item msgid="8036557974294987511">"סליחה, לא אצליח להגיע. נצטרך לקבוע מועד חדש."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"הודעה מותאמת אישית..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"כתוב אחת משלך…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"מארגן:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"תזכורות"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"היום, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"予定は空のため保存できません。"</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"招待を送信します。"</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"アップデートを送信します。"</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"保存"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"カレンダーの通知"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"予定を表示"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"会議への招待状"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"主催者にメールを送信"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"メールに次を含める:"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"イベントが見つかりません。"</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"地図"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"発信"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"クイック返信"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"ゲストへメールを送るときのデフォルトの返事を編集"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"クイック返信の編集"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"先に始めていてください。"</item>
|
||||
<item msgid="8036557974294987511">"申し訳ありませんが、行けません。日程を変更する必要があります。"</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"カスタムメッセージ…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"カスタム返信を作成…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"主催:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"通知"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"今日: <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"빈 일정은 만들 수 없습니다."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"초대장이 전송됩니다."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"업데이트가 전송됩니다."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"저장"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"캘린더 알림"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"일정 보기"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"회의 초대"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"이메일 관리도구"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"이메일:"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"일정을 찾을 수 없습니다."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"지도"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"통화"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"빠른 응답"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"손님 메일 응답수정"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"빠른 응답 수정"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"저 없이 시작하세요."</item>
|
||||
<item msgid="8036557974294987511">"죄송합니다. 일정을 변경해야 합니다."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"맞춤 메시지..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"나만의 응답을 작성…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"주최자:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"알림"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"오늘, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Tuščias įvykis nesukurtas."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Bus išsiųsti pakvietimai."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Bus išsiųsti naujiniai."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Išsaugoti"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Kalendoriaus įspėjimai"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Žiūrėti įvykį"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Kvietimas į susitikimą"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"El. pašto tvarkymo priemonė"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Siųsti el. paštu su"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Įvykis nerastas."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Žemėlapis"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Skambinti"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Greiti atsakai"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Red. num. ats. sveč. siunč. el. laišk."</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Red. greit. ats."</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Pirmyn, pradėkite be manęs."</item>
|
||||
<item msgid="8036557974294987511">"Deja, nespėsiu. Turėsime suplanuoti iš naujo."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Tinkintas pranešimas…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Sukurkite patys…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Tvarkytuvė:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Priminimai"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"ŠIANDIEN, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Tukšs pasākums; nav izveidots."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Ielūgumi tiks nosūtīti."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Atjauninājumi tiks nosūtīti."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Saglabāt"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Kalendāra paziņojumi"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Skatīt pasākumu"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Ielūgums uz sapulci"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"E-pasta organizators"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"E-pasta ziņojuma adresāts(-i)"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Pasākums nav atrasts."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Karte"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Zvanīt"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Ātrās atbildes"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Mainīt atbildes"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Ātro atbilžu red."</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Sāciet bez manis."</item>
|
||||
<item msgid="8036557974294987511">"Diemžēl nevarēšu ierasties, pasākumu vajadzēs pārcelt."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Pielāgots ziņojums..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Rakstīt savu…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Rīkotājs:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Atgādinājumi"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"ŠODIEN, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Acara kosong tidak dibuat."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Jemputan akan dihantar."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Kemas kini akan dihantar."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Simpan"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Pemberitahuan kalendar"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Lihat acara"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Jemputan pertemuan"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Hantarkan e-mel kepada penganjur"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"E-mel dengan"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Acara tidak dijumpai."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Peta"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Panggil"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Respons pantas"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Edit jawapan lalai semasa menghantar e-mel kepada tetamu"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Edit respons pantas"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Teruskan dan mulakan tanpa saya."</item>
|
||||
<item msgid="8036557974294987511">"Maaf, saya tidak dapat datang. Kita perlu menjadualkannya semula."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Mesej peribadi..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Tulis sendiri…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Penganjur:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Peringatan"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"HARI INI, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Tom aktivitet ble opprettet."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Invitasjoner sendes."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Oppdateringer sendes."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Lagre"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Kalendervarslinger"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Vis aktivitet"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Møteinvitasjon"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Send e-post til arrangøren"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"E-post med"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Finner ikke aktiviteten."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Kart"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Ring"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Hurtigsvar"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Rediger standardsvar for e-poster til gjester"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Rediger hurtigsvar"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Sett i gang uten meg."</item>
|
||||
<item msgid="8036557974294987511">"Beklager, jeg rekker det ikke. Vi må avtale nytt tidspunkt."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Egendefinert melding"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Skriv din egen"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Arrangør:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Påminnelser"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"I DAG, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Lege afspraak niet gemaakt."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Uitnodigingen worden verzonden."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Updates worden verzonden."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Opslaan"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Agenda-herinneringen"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Afspraak weergeven"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Uitnodiging voor vergadering"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Organisator e-mailen"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"E-mail met"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Evenement niet gevonden."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Kaart"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Bellen"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Snelle reacties"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Standaardreacties bewerken voor het e-mailen van gasten"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Snelle reacties bewerken"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Begin maar vast zonder mij."</item>
|
||||
<item msgid="8036557974294987511">"Ik red het helaas niet. Laten we een nieuwe afspraak maken."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Aangepast bericht…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Eigen reactie opstellen…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organisator:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Herinneringen"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"VANDAAG, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Nie utworzono: puste wydarzenie."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Zaproszenia zostaną wysłane."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Aktualizacje zostaną wysłane."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Zapisz"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Powiadomienia kalendarza"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Wyświetl wydarzenie"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Zaproszenie na spotkanie"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Wyślij e-maila do organizatora"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"E-mail przez"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Nie znaleziono wydarzenia."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Mapa"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Zadzwoń"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Szybkie odpowiedzi"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Edytuj domyślne odpowiedzi e-mail do gości"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Edytuj szybkie odpowiedzi"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Zacznijcie beze mnie."</item>
|
||||
<item msgid="8036557974294987511">"Niestety, nie dam rady. Musimy to przełożyć."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Wiadomość niestandardowa…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Napisz własną…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organizator:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Przypomnienia"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"DZIŚ, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Evento vazio não criado."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Serão enviados convites."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Serão enviadas atualizações."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Guardar"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Notificações do calendário"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Visualizar evento"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Convite para reunião"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Organizador de email"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Enviar email a"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Evento não encontrado."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Mapa"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Ligar"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Respostas rápidas"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Editar respostas predefinidas ao enviar email a convidados"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Editar respostas rápidas"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Podem começar sem mim."</item>
|
||||
<item msgid="8036557974294987511">"Lamento, mas não me é possível comparecer. Teremos de reagendar."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Mensagem personalizada..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Escreva a sua própria..."</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organizador:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Lembretes"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"HOJE, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Evento vazio não criado."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Os convites serão enviados."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"As atualizações serão enviadas."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Salvar"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Notificações da agenda"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Visualizar evento"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Convite para reunião"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Enviar e-mail para o organizador"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Enviar e-mail para"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Evento não encontrado."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Mapa"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Chamar"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Respostas rápidas"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Resp padrão p conv"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Editar resp. ráp."</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Vá em frente e comece sem mim."</item>
|
||||
<item msgid="8036557974294987511">"Sinto muito, não posso comparecer. Precisaremos remarcar."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Mensagem personalizada..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Escreva sua resposta..."</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organizador:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Lembretes"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"HOJE, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Evenimentul gol nu s-a creat."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Invitaţiile vor fi trimise."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Actualizările vor fi trimise."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Salvați"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Notificările calendarului"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Vizualizaţi evenimentul"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Invitaţie de întâlnire"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Trimiteţi e-mail organizatorului"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"E-mail cu"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Evenimentul nu a fost găsit."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Vedeți harta"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Apelați"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Răspunsuri rapide"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Editaţi răspuns prestab. e-mailuri invitaţi"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Editaţi răsp. rapide"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Începeţi fără mine."</item>
|
||||
<item msgid="8036557974294987511">"Îmi pare rău, nu pot să ajung. Va trebui să ne vedem altădată."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Mesaj personalizat..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Scrieți propriul răspuns…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organizator:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Mementouri"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"AZI, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Нельзя создать мероприятие без данных."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Приглашения будут отправлены."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Обновления будут отправлены."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Сохранить"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Уведомления календаря"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Просмотр мероприятия"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Приглашение на встречу"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Написать организатору"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Отправить из"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Мероприятие не найдено"</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Карта"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Позвонить"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Быстрые ответы"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Изменить ответы"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Изменить ответы"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Начинайте без меня."</item>
|
||||
<item msgid="8036557974294987511">"К сожалению, я не успеваю. Придется перенести мероприятие."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Свое сообщение…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Ваш ответ…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Организатор:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Напоминания"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"СЕГОДНЯ, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Prázdna udal. nebola vytvor."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Pozvánky budú odoslané."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Aktualizácie budú odoslané."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Uložiť"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Upozornenia v kalendári"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Zobraziť udalosť"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Pozvánka na stretnutie"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"E-mail pre organizátora"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Poslať e-mail"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Udalosť sa nenašla."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Mapa"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Zavolať"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Rýchle odpovede"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Upraviť predv. odp."</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Upraviť rýchle odp."</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Začnite bezo mňa."</item>
|
||||
<item msgid="8036557974294987511">"Je mi ľúto, ale nestíham. Naplánujeme to na inokedy."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Vlastná správa..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Napíšte vlastnú..."</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organizátor:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Pripomienky"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"DNES, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Prazen dogodek ni bil ustvarjen."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Vabila bodo poslana."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Posodobitve bodo poslane."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Shrani"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Obvestila koledarja"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Ogled dogodka"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Povabilo na srečanje"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Pošlji e-poštno sporočilo organizatorju"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Pošlji e-pošto z"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Dogodka ni bilo mogoče najti."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Zemljevid"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Klic"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Jedrnati odgovori"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Urejanje privzetih odgovorov za e-poštno pošiljanje"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Urejanje jedrnatih odgovorov"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Odpravite se in začnite brez mene."</item>
|
||||
<item msgid="8036557974294987511">"Oprostite, ne utegnem. Dogovor velja za drugič."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Sporočilo po meri ..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Napišite lastno besedilo …"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organizator:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Opomniki"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"DANES, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Празан догађај није направљен."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Позивнице ће бити послате."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Ажурирања ће бити послата."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Сачувај"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Обавештења календара"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Приказ догађаја"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Позивница за састанак"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Пошаљи поруку е-поште организатору"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Пошаљи поруку е-поште за"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Догађај није пронађен."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Мапа"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Позови"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Брзи одговори"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Измени подраз. одгов. у е-порукама за госте"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Измена брзих одгов."</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Почните без мене."</item>
|
||||
<item msgid="8036557974294987511">"Жао ми је, не могу да стигнем. Мораћемо да одложимо."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Прилагођена порука…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Напишите сами…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Организатор:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Подсетници"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"ДАНАС, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Den tomma händelsen sparades inte."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Inbjudningar kommer att skickas."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Uppdateringar kommer att skickas."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Spara"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Kalenderaviseringar"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Visa händelse"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Inbjudan till möte"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Skicka e-post till arrangören"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Skicka e-post till"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Händelsen hittades inte."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Karta"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Ring"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Snabbsvar"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Redigera standardsvar när du skickar e-post till gäster"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Redigera snabbsvar"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Börja gärna, vänta inte på mig."</item>
|
||||
<item msgid="8036557974294987511">"Jag kan tyvärr inte komma. Vi får välja en ny tid."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Anpassat meddelande ..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Skriv eget svar ..."</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Organisatör:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Påminnelser"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"IDAG, DEN <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Tukio tupu halikuundwa."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Mialiko itatumwa."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Visasisho vitatumwa."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Hifadhi"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Arifa za kalenda"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Tazama tukio"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Mwaliko wa mktutano"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Mratibishaji barua pepe"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Tuma barua pepe na"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Tukio halikupatikana."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Ramani"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Piga simu"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Majibu ya haraka"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Hariri majibu ya chaguo-msingi wakati wa kutumia wateja barua pepe"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Hariri majibu ya haraka"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Endelea na uanze bila mimi."</item>
|
||||
<item msgid="8036557974294987511">"Samahani, Siwezi. Itabidi tupange upya."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Ujumbe maalum…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Andika yako binafsi…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Mwandalizi:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Makumbusho"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"LEO, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"ไม่ได้สร้างกิจกรรมเปล่า"</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"จะมีการส่งข้อความเชิญ"</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"จะมีการส่งการอัปเดต"</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"บันทึก"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"การแจ้งเตือนของปฏิทิน"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"ดูกิจกรรม"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"คำเชิญเข้าประชุม"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"ส่งอีเมลถึงผู้จัด"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"ส่งอีเมลด้วย"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"ไม่พบกิจกรรม"</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"แผนที่"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"โทร"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"คำตอบด่วน"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"แก้ไขคำตอบเริ่มต้น"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"แก้ไขคำตอบด่วน"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"เริ่มไปเลย ไม่ต้องรอ"</item>
|
||||
<item msgid="8036557974294987511">"ขอโทษ ฉันไปไม่ได้ เราต้องกำหนดเวลากันใหม่"</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"ข้อความที่กำหนดเอง…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"เขียนคำตอบของคุณเอง…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"ผู้จัด:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"การแจ้งเตือน"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"วันนี้ <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Hindi nalikha ang walang lamang kaganapan."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Magpapadala ng mga imbitasyon."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Magpapadala ng mga update."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"I-save"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Mga notifcation sa kalendaryo"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Tingnan ang kaganapan"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Imbitasyon sa meeting"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Tagaayos ng email"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Mag-email gamit ang"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Hindi nahanap ang kaganapan."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Mapa"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Tumawag"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Mabilisang tugon"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Edit default tugon pag email sa mga bisita"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Edit mabilis tugon"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Magsimula na kayo nang wala ako."</item>
|
||||
<item msgid="8036557974294987511">"Paumanhin, hindi ako makakapunta. Kakailanganin nating mag-reschedule."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Custom na mensahe..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Isulat ang iyong sariling…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Taga-ayos:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Mga Paalala"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"NGAYON, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Boş etkinlik oluşturulamadı."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Davetiyeler gönderilecek."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Güncellemeler gönderilecek."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Kaydet"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Takvim bildirimleri"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Etkinliği görüntüle"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Toplantı davetiyesi"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"E-posta düzenleyici"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"E-posta gönder"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Etkinlik bulunamadı."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Harita"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Çağrı"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Hızlı yanıtlar"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Konuklara gönderilecek e-posta varsayılan yanıtlarını düzenle"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Hızlı yanıtları düzenle"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Bensiz başlayın."</item>
|
||||
<item msgid="8036557974294987511">"Maalesef katılamıyorum. Başka bir zaman ayarlamamız gerek."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Özel mesaj"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Kendi yanıtınızı oluşturun…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Düzenleyici:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Hatırlatıcılar"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"BUGÜN, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Порожню подію не створено."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Запрошення буде надіслано."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Оновлення буде надіслано."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Зберегти"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Сповіщення календаря"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Перегл. подію"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Запрошення на зустріч"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Написати організатору"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Надіслати електронний лист"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Подію не знайдено."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Карта"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Виклик"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Швидкі відповіді"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Редагувати відповіді за умовчанням"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Редагувати швидкі відповіді"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Починайте без мене."</item>
|
||||
<item msgid="8036557974294987511">"Вибачте, я не зможу. Доведеться перенести зустріч."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Спеціальне повідомлення…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Напишіть власну відповідь…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Організатор:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Нагадування"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"СЬОГОДНІ, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Chưa tạo sự kiện trống."</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Thư mời sẽ được gửi."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Các cập nhật sẽ được gửi."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Lưu"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Thông báo lịch"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Xem sự kiện"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Thư mời họp"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Gửi email đến người tổ chức"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"Gửi email với"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Không tìm thấy sự kiện."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Bản đồ"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Cuộc gọi"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"Trả lời nhanh"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"Sửa trả lời mặc định khi email cho khách"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"Sửa trả lời nhanh"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"Hãy tiến hành và bắt đầu mà không có tôi."</item>
|
||||
<item msgid="8036557974294987511">"Rất tiếc, tôi không thu xếp được. Chúng ta phải lên lịch lại."</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"Thông báo tùy chỉnh..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Viết trả lời của riêng bạn…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Người t.chức"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Lời nhắc"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"HÔM NAY, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"无法创建空白活动。"</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"即将发送邀请。"</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"即将发送更新。"</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"保存"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"日历通知"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"查看活动"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"会议邀请"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"给组织者发送电子邮件"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"发送邮件时使用"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"找不到活动。"</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"地图"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"电话"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"快速回复"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"修改向参加者发邮件时所用的默认回复"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"修改快速回复"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"先开始,不用等我。"</item>
|
||||
<item msgid="8036557974294987511">"抱歉,我赶不上了,我们另约时间吧。"</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"自己写邮件..."</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"自行撰写回复…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"组织者:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"提醒"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"今天,<xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"無法建立空白活動。"</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"即將傳送邀請。"</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"即將傳送更新。"</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"儲存"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"日曆通知"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"檢視活動"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"會議邀請"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"傳送電子郵件給主辦者"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"寄送電子郵件時使用"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"找不到活動。"</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"地圖"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"電洽"</string>
|
||||
<string name="quick_response_settings" msgid="6776151690686068278">"快速回應"</string>
|
||||
<string name="quick_response_settings_summary" msgid="7878304729027355604">"編輯傳送給邀請對象的預設電子郵件回應"</string>
|
||||
<string name="quick_response_settings_title" msgid="8966517107774567031">"編輯快速回應"</string>
|
||||
@ -118,7 +121,7 @@
|
||||
<item msgid="4485794001743679338">"別等我,請直接開始。"</item>
|
||||
<item msgid="8036557974294987511">"抱歉不克前往。我們再約時間。"</item>
|
||||
</string-array>
|
||||
<string name="quick_response_custom_msg" msgid="7265035125070482285">"自訂訊息…"</string>
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"自行撰寫回應…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"主辦人:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"提醒"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"今天,<xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -80,6 +80,7 @@
|
||||
<string name="empty_event" msgid="9018699257414338634">"Isenzakalo esingenalutho asenziwanga"</string>
|
||||
<string name="creating_event_with_guest" msgid="5758688413124191931">"Izimemo zizothunyelwa."</string>
|
||||
<string name="saving_event_with_guest" msgid="9184584438475689577">"Ukubuyekeza kuzothunyelwa."</string>
|
||||
<string name="create_event_dialog_save" msgid="1080859798521717414">"Londoloza"</string>
|
||||
<string name="alert_title" msgid="7869592820853066853">"Izaziso zekhalenda"</string>
|
||||
<string name="event_info_title" msgid="56024222340421620">"Buka isenzakalo"</string>
|
||||
<string name="event_info_title_invite" msgid="9160326363769403865">"Isimemo somhlangano"</string>
|
||||
@ -106,6 +107,8 @@
|
||||
<string name="email_organizer_label" msgid="7178059542798074813">"Isihleli se-imeyili"</string>
|
||||
<string name="email_picker_label" msgid="4808253965057791781">"I-imeyili no"</string>
|
||||
<string name="event_not_found" msgid="8356864185947582727">"Umcimbi awutholakalanga."</string>
|
||||
<string name="map_label" msgid="8795383535586556038">"Imephu"</string>
|
||||
<string name="call_label" msgid="2960328220008869083">"Fonela"</string>
|
||||
<!-- no translation found for quick_response_settings (6776151690686068278) -->
|
||||
<skip />
|
||||
<!-- no translation found for quick_response_settings_summary (7878304729027355604) -->
|
||||
@ -122,8 +125,7 @@
|
||||
<!-- no translation found for quick_response_defaults:1 (6215158751728689832) -->
|
||||
<!-- no translation found for quick_response_defaults:2 (4485794001743679338) -->
|
||||
<!-- no translation found for quick_response_defaults:3 (8036557974294987511) -->
|
||||
<!-- no translation found for quick_response_custom_msg (7265035125070482285) -->
|
||||
<skip />
|
||||
<string name="quick_response_custom_msg" msgid="8792374208224108798">"Bhala okwakho…"</string>
|
||||
<string name="event_info_organizer" msgid="9138683335394832629">"Umhleli:"</string>
|
||||
<string name="event_info_reminders_label" msgid="8913097552956388972">"Izikhumbuzi"</string>
|
||||
<string name="agenda_today" msgid="5965841338467422191">"NAMHLANJE, <xliff:g id="DATE">%1$s</xliff:g>"</string>
|
||||
|
@ -70,16 +70,11 @@
|
||||
<color name="month_sunday">#80333333</color>
|
||||
<color name="month_grid_lines">#ffCCCCCC</color>
|
||||
<color name="month_other_month_day_number">#ff939497</color>
|
||||
|
||||
|
||||
|
||||
<color name="month_other_bgcolor">#FFEEEEEE</color>
|
||||
<color name="month_selected_week_bgcolor">#FFDDDDDD</color>
|
||||
<color name="month_today_bgcolor">#FFFFFFFF</color>
|
||||
<color name="month_bgcolor">#FFE5E5E5</color>
|
||||
|
||||
|
||||
|
||||
<color name="month_dna_conflict_time_color">#FF333333</color>
|
||||
|
||||
<color name="event_center">#ff6bd697</color>
|
||||
@ -141,6 +136,11 @@
|
||||
<color name="event_info_label_color">#FF999999</color>
|
||||
<color name="event_info_label_background_color">#FFDDDDDD</color>
|
||||
|
||||
<!-- Create event colors -->
|
||||
<color name="create_event_date_color">#FF000000</color>
|
||||
<color name="create_event_more_details_color">#FF888888</color>
|
||||
<color name="create_event_divider_color">#FFDDDDDD</color>
|
||||
|
||||
<color name="text_shadow_color">#4D000000</color>
|
||||
|
||||
<color name="alert_event_title">#FFFFFFFF</color>
|
||||
|
@ -215,6 +215,11 @@
|
||||
a new event -->
|
||||
|
||||
|
||||
<!-- Create event dialog -->
|
||||
<skip/>
|
||||
<!-- Create event dialog save button [CHAR LIMIT=10] -->
|
||||
<string name="create_event_dialog_save">Save</string>
|
||||
|
||||
<!-- The alert toast is not actually being displayed for some reason. -->
|
||||
<skip/>
|
||||
<!-- the title of the alert/notification activity -->
|
||||
@ -294,6 +299,11 @@
|
||||
<!-- Toast message displayed when the event id was not found LIMIT=30] -->
|
||||
<string name="event_not_found">"Event not found."</string>
|
||||
|
||||
<!-- Notification label for getting a map of the location. -->
|
||||
<string name="map_label">Map</string>
|
||||
<!-- Notification label for calling a phone number in the location. -->
|
||||
<string name="call_label">Call</string>
|
||||
|
||||
<!-- Title of the quick response item in Settings [CHAR LIMIT=18]-->
|
||||
<string name="quick_response_settings">Quick responses</string>
|
||||
<!-- Summary of the quick response item in Settings [CHAR LIMIT=80]-->
|
||||
@ -315,7 +325,7 @@
|
||||
<item>Sorry, I can\'t make it. We\'ll have to reschedule.</item>
|
||||
</string-array>
|
||||
<!-- Option to create a custom response instead of using defaults [CHAR LIMIT=none] -->
|
||||
<string name="quick_response_custom_msg">Custom message\u2026</string>
|
||||
<string name="quick_response_custom_msg">Write your own\u2026</string>
|
||||
|
||||
<!-- Event Info strings-->
|
||||
<!-- Time Zone Label [CHAR LIMIT=12]-->
|
||||
|
@ -19,6 +19,6 @@
|
||||
<header android:fragment="com.android.calendar.GeneralPreferences"
|
||||
android:title="@string/menu_general_preferences" />
|
||||
|
||||
<header android:fragment="com.android.calendar.extensions.AboutPreferences"
|
||||
<header android:fragment="com.android.calendar.AboutPreferences"
|
||||
android:title="@string/menu_about_preferences" />
|
||||
</preference-headers>
|
||||
|
@ -24,6 +24,5 @@
|
||||
<CheckBoxPreference
|
||||
android:key="preferences_tardis_1"
|
||||
android:title="@string/do_not_check" />
|
||||
android:defaultValue="false" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.calendar.extensions;
|
||||
package com.android.calendar;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.pm.PackageInfo;
|
@ -31,7 +31,6 @@ import android.animation.Animator.AnimatorListener;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.app.ActionBar;
|
||||
import android.app.ActionBar.Tab;
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.app.FragmentTransaction;
|
||||
@ -75,7 +74,6 @@ import com.android.calendar.CalendarController.EventInfo;
|
||||
import com.android.calendar.CalendarController.EventType;
|
||||
import com.android.calendar.CalendarController.ViewType;
|
||||
import com.android.calendar.agenda.AgendaFragment;
|
||||
import com.android.calendar.extensions.AllInOneMenuExtensions;
|
||||
import com.android.calendar.month.MonthByWeekFragment;
|
||||
import com.android.calendar.selectcalendars.SelectVisibleCalendarsFragment;
|
||||
|
||||
@ -84,7 +82,7 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class AllInOneActivity extends Activity implements EventHandler,
|
||||
public class AllInOneActivity extends AbstractCalendarActivity implements EventHandler,
|
||||
OnSharedPreferenceChangeListener, SearchView.OnQueryTextListener, ActionBar.TabListener,
|
||||
ActionBar.OnNavigationListener, OnSuggestionListener {
|
||||
private static final String TAG = "AllInOneActivity";
|
||||
@ -95,7 +93,6 @@ public class AllInOneActivity extends Activity implements EventHandler,
|
||||
private static final String BUNDLE_KEY_RESTORE_VIEW = "key_restore_view";
|
||||
private static final String BUNDLE_KEY_CHECK_ACCOUNTS = "key_check_for_accounts";
|
||||
private static final int HANDLER_KEY = 0;
|
||||
private static float mScale = 0;
|
||||
|
||||
// Indices of buttons for the drop down menu (tabs replacement)
|
||||
// Must match the strings in the array buttons_list in arrays.xml and the
|
||||
@ -167,7 +164,8 @@ public class AllInOneActivity extends Activity implements EventHandler,
|
||||
private LayoutParams mControlsParams;
|
||||
private LinearLayout.LayoutParams mVerticalControlsParams;
|
||||
|
||||
private AllInOneMenuExtensions mExtensions = new AllInOneMenuExtensions();
|
||||
private AllInOneMenuExtensionsInterface mExtensions = ExtensionsFactory
|
||||
.getAllInOneMenuExtensions();
|
||||
|
||||
private final AnimatorListener mSlideAnimationDoneListener = new AnimatorListener() {
|
||||
|
||||
@ -470,31 +468,6 @@ public class AllInOneActivity extends Activity implements EventHandler,
|
||||
}
|
||||
}
|
||||
|
||||
private void createTabs() {
|
||||
mActionBar = getActionBar();
|
||||
if (mActionBar == null) {
|
||||
Log.w(TAG, "ActionBar is null.");
|
||||
} else {
|
||||
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
|
||||
mDayTab = mActionBar.newTab();
|
||||
mDayTab.setText(getString(R.string.day_view));
|
||||
mDayTab.setTabListener(this);
|
||||
mActionBar.addTab(mDayTab);
|
||||
mWeekTab = mActionBar.newTab();
|
||||
mWeekTab.setText(getString(R.string.week_view));
|
||||
mWeekTab.setTabListener(this);
|
||||
mActionBar.addTab(mWeekTab);
|
||||
mMonthTab = mActionBar.newTab();
|
||||
mMonthTab.setText(getString(R.string.month_view));
|
||||
mMonthTab.setTabListener(this);
|
||||
mActionBar.addTab(mMonthTab);
|
||||
mAgendaTab = mActionBar.newTab();
|
||||
mAgendaTab.setText(getString(R.string.agenda_view));
|
||||
mAgendaTab.setTabListener(this);
|
||||
mActionBar.addTab(mAgendaTab);
|
||||
}
|
||||
}
|
||||
|
||||
private void createButtonsSpinner(int viewType, boolean tabletConfig) {
|
||||
// If tablet configuration , show spinner with no dates
|
||||
mActionBarMenuSpinnerAdapter = new CalendarViewAdapter (this, viewType, !tabletConfig);
|
||||
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.calendar;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
/*
|
||||
* Interface for additional options in the AllInOne menu.
|
||||
*/
|
||||
public interface AllInOneMenuExtensionsInterface {
|
||||
/**
|
||||
* Returns additional options.
|
||||
*/
|
||||
Integer getExtensionMenuResource(Menu menu);
|
||||
|
||||
/**
|
||||
* Handle selection of the additional options.
|
||||
*/
|
||||
boolean handleItemSelected(MenuItem item, Context context);
|
||||
}
|
@ -33,5 +33,8 @@ public class CalendarApplication extends Application {
|
||||
// moved to that implementation.
|
||||
Utils.setSharedPreference(this, GeneralPreferences.KEY_VERSION,
|
||||
Utils.getVersionCode(this));
|
||||
|
||||
// Initialize the registry mapping some custom behavior.
|
||||
ExtensionsFactory.init(getAssets());
|
||||
}
|
||||
}
|
||||
|
@ -16,14 +16,11 @@
|
||||
|
||||
package com.android.calendar;
|
||||
|
||||
import static android.provider.CalendarContract.EXTRA_EVENT_ALL_DAY;
|
||||
import static android.provider.CalendarContract.EXTRA_EVENT_BEGIN_TIME;
|
||||
import static android.provider.CalendarContract.EXTRA_EVENT_END_TIME;
|
||||
import static android.provider.CalendarContract.EXTRA_EVENT_ALL_DAY;
|
||||
import static android.provider.CalendarContract.Attendees.ATTENDEE_STATUS;
|
||||
|
||||
import com.android.calendar.event.EditEventActivity;
|
||||
import com.android.calendar.selectcalendars.SelectVisibleCalendarsActivity;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.app.Activity;
|
||||
@ -34,18 +31,18 @@ import android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.provider.CalendarContract.Attendees;
|
||||
import android.provider.CalendarContract.Calendars;
|
||||
import android.provider.CalendarContract.Events;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.Time;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.calendar.event.EditEventActivity;
|
||||
import com.android.calendar.selectcalendars.SelectVisibleCalendarsActivity;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
@ -55,10 +52,6 @@ import java.util.WeakHashMap;
|
||||
public class CalendarController {
|
||||
private static final boolean DEBUG = false;
|
||||
private static final String TAG = "CalendarController";
|
||||
private static final String REFRESH_SELECTION = Calendars.SYNC_EVENTS + "=?";
|
||||
private static final String[] REFRESH_ARGS = new String[] { "1" };
|
||||
private static final String REFRESH_ORDER = Calendars.ACCOUNT_NAME + ","
|
||||
+ Calendars.ACCOUNT_TYPE;
|
||||
|
||||
public static final String EVENT_EDIT_ON_LAUNCH = "editMode";
|
||||
|
||||
@ -162,12 +155,19 @@ public class CalendarController {
|
||||
public int viewType; // one of the ViewType
|
||||
public long id; // event id
|
||||
public Time selectedTime; // the selected time in focus
|
||||
public Time startTime; // start of a range of time.
|
||||
public Time endTime; // end of a range of time.
|
||||
|
||||
// Event start and end times. All-day events are represented in:
|
||||
// - local time for GO_TO commands
|
||||
// - UTC time for VIEW_EVENT and other event-related commands
|
||||
public Time startTime;
|
||||
public Time endTime;
|
||||
|
||||
public int x; // x coordinate in the activity space
|
||||
public int y; // y coordinate in the activity space
|
||||
public String query; // query for a user search
|
||||
public ComponentName componentName; // used in combination with query
|
||||
public String eventTitle;
|
||||
public long calendarId;
|
||||
|
||||
/**
|
||||
* For EventType.VIEW_EVENT:
|
||||
@ -336,11 +336,35 @@ public class CalendarController {
|
||||
*/
|
||||
public void sendEventRelatedEventWithExtra(Object sender, long eventType, long eventId,
|
||||
long startMillis, long endMillis, int x, int y, long extraLong, long selectedMillis) {
|
||||
sendEventRelatedEventWithExtraWithTitleWithCalendarId(sender, eventType, eventId,
|
||||
startMillis, endMillis, x, y, extraLong, selectedMillis, null, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for sending New/View/Edit/Delete events
|
||||
*
|
||||
* @param sender object of the caller
|
||||
* @param eventType one of {@link EventType}
|
||||
* @param eventId event id
|
||||
* @param startMillis start time
|
||||
* @param endMillis end time
|
||||
* @param x x coordinate in the activity space
|
||||
* @param y y coordinate in the activity space
|
||||
* @param extraLong default response value for the "simple event view" and all day indication.
|
||||
* Use Attendees.ATTENDEE_STATUS_NONE for no response.
|
||||
* @param selectedMillis The time to specify as selected
|
||||
* @param title The title of the event
|
||||
* @param calendarId The id of the calendar which the event belongs to
|
||||
*/
|
||||
public void sendEventRelatedEventWithExtraWithTitleWithCalendarId(Object sender, long eventType,
|
||||
long eventId, long startMillis, long endMillis, int x, int y, long extraLong,
|
||||
long selectedMillis, String title, long calendarId) {
|
||||
EventInfo info = new EventInfo();
|
||||
info.eventType = eventType;
|
||||
if (eventType == EventType.EDIT_EVENT || eventType == EventType.VIEW_EVENT_DETAILS) {
|
||||
info.viewType = ViewType.CURRENT;
|
||||
}
|
||||
|
||||
info.id = eventId;
|
||||
info.startTime = new Time(Utils.getTimeZone(mContext, mUpdateTimezone));
|
||||
info.startTime.set(startMillis);
|
||||
@ -355,9 +379,10 @@ public class CalendarController {
|
||||
info.x = x;
|
||||
info.y = y;
|
||||
info.extraLong = extraLong;
|
||||
info.eventTitle = title;
|
||||
info.calendarId = calendarId;
|
||||
this.sendEvent(sender, info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for sending non-calendar-event events
|
||||
*
|
||||
@ -432,11 +457,11 @@ public class CalendarController {
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Log.e(TAG, "vvvvvvvvvvvvvvv");
|
||||
Log.e(TAG, "Start " + (event.startTime == null ? "null" : event.startTime.toString()));
|
||||
Log.e(TAG, "End " + (event.endTime == null ? "null" : event.endTime.toString()));
|
||||
Log.e(TAG, "Select " + (event.selectedTime == null ? "null" : event.selectedTime.toString()));
|
||||
Log.e(TAG, "mTime " + (mTime == null ? "null" : mTime.toString()));
|
||||
Log.d(TAG, "vvvvvvvvvvvvvvv");
|
||||
Log.d(TAG, "Start " + (event.startTime == null ? "null" : event.startTime.toString()));
|
||||
Log.d(TAG, "End " + (event.endTime == null ? "null" : event.endTime.toString()));
|
||||
Log.d(TAG, "Select " + (event.selectedTime == null ? "null" : event.selectedTime.toString()));
|
||||
Log.d(TAG, "mTime " + (mTime == null ? "null" : mTime.toString()));
|
||||
}
|
||||
|
||||
long startMillis = 0;
|
||||
@ -469,11 +494,11 @@ public class CalendarController {
|
||||
event.startTime = mTime;
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.e(TAG, "Start " + (event.startTime == null ? "null" : event.startTime.toString()));
|
||||
Log.e(TAG, "End " + (event.endTime == null ? "null" : event.endTime.toString()));
|
||||
Log.e(TAG, "Select " + (event.selectedTime == null ? "null" : event.selectedTime.toString()));
|
||||
Log.e(TAG, "mTime " + (mTime == null ? "null" : mTime.toString()));
|
||||
Log.e(TAG, "^^^^^^^^^^^^^^^");
|
||||
Log.d(TAG, "Start " + (event.startTime == null ? "null" : event.startTime.toString()));
|
||||
Log.d(TAG, "End " + (event.endTime == null ? "null" : event.endTime.toString()));
|
||||
Log.d(TAG, "Select " + (event.selectedTime == null ? "null" : event.selectedTime.toString()));
|
||||
Log.d(TAG, "mTime " + (mTime == null ? "null" : mTime.toString()));
|
||||
Log.d(TAG, "^^^^^^^^^^^^^^^");
|
||||
}
|
||||
|
||||
// Store the eventId if we're entering edit event
|
||||
@ -567,7 +592,8 @@ public class CalendarController {
|
||||
long endTime = (event.endTime == null) ? -1 : event.endTime.toMillis(false);
|
||||
if (event.eventType == EventType.CREATE_EVENT) {
|
||||
launchCreateEvent(event.startTime.toMillis(false), endTime,
|
||||
event.extraLong == EXTRA_CREATE_ALL_DAY);
|
||||
event.extraLong == EXTRA_CREATE_ALL_DAY, event.eventTitle,
|
||||
event.calendarId);
|
||||
return;
|
||||
} else if (event.eventType == EventType.VIEW_EVENT) {
|
||||
launchViewEvent(event.id, event.startTime.toMillis(false), endTime,
|
||||
@ -701,14 +727,24 @@ public class CalendarController {
|
||||
mContext.startActivity(intent);
|
||||
}
|
||||
|
||||
private void launchCreateEvent(long startMillis, long endMillis, boolean allDayEvent) {
|
||||
private void launchCreateEvent(long startMillis, long endMillis, boolean allDayEvent,
|
||||
String title, long calendarId) {
|
||||
Intent intent = generateCreateEventIntent(startMillis, endMillis, allDayEvent, title,
|
||||
calendarId);
|
||||
mEventId = -1;
|
||||
mContext.startActivity(intent);
|
||||
}
|
||||
|
||||
public Intent generateCreateEventIntent(long startMillis, long endMillis,
|
||||
boolean allDayEvent, String title, long calendarId) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setClass(mContext, EditEventActivity.class);
|
||||
intent.putExtra(EXTRA_EVENT_BEGIN_TIME, startMillis);
|
||||
intent.putExtra(EXTRA_EVENT_END_TIME, endMillis);
|
||||
intent.putExtra(EXTRA_EVENT_ALL_DAY, allDayEvent);
|
||||
mEventId = -1;
|
||||
mContext.startActivity(intent);
|
||||
intent.putExtra(Events.CALENDAR_ID, calendarId);
|
||||
intent.putExtra(Events.TITLE, title);
|
||||
return intent;
|
||||
}
|
||||
|
||||
public void launchViewEvent(long eventId, long startMillis, long endMillis, int response) {
|
||||
|
@ -170,6 +170,7 @@ public class CalendarEventModel implements Serializable {
|
||||
* Comparison function for a sort ordered primarily descending by minutes,
|
||||
* secondarily ascending by method type.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(ReminderEntry re) {
|
||||
if (re.mMinutes != mMinutes) {
|
||||
return re.mMinutes - mMinutes;
|
||||
@ -359,16 +360,16 @@ public class CalendarEventModel implements Serializable {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isEmpty() {
|
||||
if (mTitle != null && mTitle.length() > 0) {
|
||||
public boolean isEmpty() {
|
||||
if (mTitle != null && mTitle.trim().length() > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mLocation != null && mLocation.length() > 0) {
|
||||
if (mLocation != null && mLocation.trim().length() > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mDescription != null && mDescription.length() > 0) {
|
||||
if (mDescription != null && mDescription.trim().length() > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -56,16 +56,12 @@ import android.provider.ContactsContract.CommonDataKinds;
|
||||
import android.provider.ContactsContract.Intents;
|
||||
import android.provider.ContactsContract.QuickContact;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.Time;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.method.MovementMethod;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.URLSpan;
|
||||
import android.text.util.Linkify;
|
||||
import android.text.util.Rfc822Token;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
@ -102,13 +98,14 @@ import com.android.calendar.event.AttendeesView;
|
||||
import com.android.calendar.event.EditEventActivity;
|
||||
import com.android.calendar.event.EditEventHelper;
|
||||
import com.android.calendar.event.EventViewUtils;
|
||||
import com.android.calendarcommon2.DateException;
|
||||
import com.android.calendarcommon2.Duration;
|
||||
import com.android.calendarcommon2.EventRecurrence;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class EventInfoFragment extends DialogFragment implements OnCheckedChangeListener,
|
||||
CalendarController.EventHandler, OnClickListener, DeleteEventHelper.DeleteNotifyListener {
|
||||
@ -174,12 +171,15 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
|
||||
Events.CUSTOM_APP_PACKAGE, // 17
|
||||
Events.CUSTOM_APP_URI, // 18
|
||||
Events.ORIGINAL_SYNC_ID, // 19 do not remove; used in DeleteEventHelper
|
||||
Events.DTEND, // 20
|
||||
Events.DURATION, // 21
|
||||
};
|
||||
private static final int EVENT_INDEX_ID = 0;
|
||||
private static final int EVENT_INDEX_TITLE = 1;
|
||||
private static final int EVENT_INDEX_RRULE = 2;
|
||||
private static final int EVENT_INDEX_ALL_DAY = 3;
|
||||
private static final int EVENT_INDEX_CALENDAR_ID = 4;
|
||||
private static final int EVENT_INDEX_DTSTART = 5;
|
||||
private static final int EVENT_INDEX_SYNC_ID = 6;
|
||||
private static final int EVENT_INDEX_EVENT_TIMEZONE = 7;
|
||||
private static final int EVENT_INDEX_DESCRIPTION = 8;
|
||||
@ -193,6 +193,8 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
|
||||
private static final int EVENT_INDEX_ALLOWED_REMINDERS = 16;
|
||||
private static final int EVENT_INDEX_CUSTOM_APP_PACKAGE = 17;
|
||||
private static final int EVENT_INDEX_CUSTOM_APP_URI = 18;
|
||||
private static final int EVENT_INDEX_DTEND = 20;
|
||||
private static final int EVENT_INDEX_DURATION = 21;
|
||||
|
||||
private static final String[] ATTENDEES_PROJECTION = new String[] {
|
||||
Attendees._ID, // 0
|
||||
@ -254,10 +256,6 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
|
||||
static final String CALENDARS_DUPLICATE_NAME_WHERE = Calendars.CALENDAR_DISPLAY_NAME + "=?";
|
||||
static final String CALENDARS_VISIBLE_WHERE = Calendars.VISIBLE + "=?";
|
||||
|
||||
private static final String NANP_ALLOWED_SYMBOLS = "()+-*#.";
|
||||
private static final int NANP_MIN_DIGITS = 7;
|
||||
private static final int NANP_MAX_DIGITS = 11;
|
||||
|
||||
|
||||
private View mView;
|
||||
|
||||
@ -320,8 +318,6 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
|
||||
private boolean mNoCrossFade = false; // Used to prevent repeated cross-fade
|
||||
|
||||
|
||||
private static final Pattern mWildcardPattern = Pattern.compile("^.*$");
|
||||
|
||||
ArrayList<Attendee> mAcceptedAttendees = new ArrayList<Attendee>();
|
||||
ArrayList<Attendee> mDeclinedAttendees = new ArrayList<Attendee>();
|
||||
ArrayList<Attendee> mTentativeAttendees = new ArrayList<Attendee>();
|
||||
@ -477,7 +473,6 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
|
||||
}
|
||||
break;
|
||||
case TOKEN_QUERY_DUPLICATE_CALENDARS:
|
||||
Resources res = activity.getResources();
|
||||
SpannableStringBuilder sb = new SpannableStringBuilder();
|
||||
|
||||
// Calendar display name
|
||||
@ -1161,6 +1156,33 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
|
||||
eventName = getActivity().getString(R.string.no_title_label);
|
||||
}
|
||||
|
||||
// 3rd parties might not have specified the start/end time when firing the
|
||||
// Events.CONTENT_URI intent. Update these with values read from the db.
|
||||
if (mStartMillis == 0 && mEndMillis == 0) {
|
||||
mStartMillis = mEventCursor.getLong(EVENT_INDEX_DTSTART);
|
||||
mEndMillis = mEventCursor.getLong(EVENT_INDEX_DTEND);
|
||||
if (mEndMillis == 0) {
|
||||
String duration = mEventCursor.getString(EVENT_INDEX_DURATION);
|
||||
if (!TextUtils.isEmpty(duration)) {
|
||||
try {
|
||||
Duration d = new Duration();
|
||||
d.parse(duration);
|
||||
long endMillis = mStartMillis + d.getMillis();
|
||||
if (endMillis >= mStartMillis) {
|
||||
mEndMillis = endMillis;
|
||||
} else {
|
||||
Log.d(TAG, "Invalid duration string: " + duration);
|
||||
}
|
||||
} catch (DateException e) {
|
||||
Log.d(TAG, "Error parsing duration string " + duration, e);
|
||||
}
|
||||
}
|
||||
if (mEndMillis == 0) {
|
||||
mEndMillis = mStartMillis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mAllDay = mEventCursor.getInt(EVENT_INDEX_ALL_DAY) != 0;
|
||||
String location = mEventCursor.getString(EVENT_INDEX_EVENT_LOCATION);
|
||||
String description = mEventCursor.getString(EVENT_INDEX_DESCRIPTION);
|
||||
@ -1233,7 +1255,17 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
|
||||
textView.setAutoLinkMask(0);
|
||||
textView.setText(location.trim());
|
||||
try {
|
||||
linkifyTextView(textView);
|
||||
textView.setText(Utils.extendedLinkify(textView.getText().toString(), true));
|
||||
|
||||
// Linkify.addLinks() sets the TextView movement method if it finds any links.
|
||||
// We must do the same here, in case linkify by itself did not find any.
|
||||
// (This is cloned from Linkify.addLinkMovementMethod().)
|
||||
MovementMethod mm = textView.getMovementMethod();
|
||||
if ((mm == null) || !(mm instanceof LinkMovementMethod)) {
|
||||
if (textView.getLinksClickable()) {
|
||||
textView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// unexpected
|
||||
Log.e(TAG, "Linkification failed", ex);
|
||||
@ -1337,326 +1369,6 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds North American Numbering Plan (NANP) phone numbers in the input text.
|
||||
*
|
||||
* @param text The text to scan.
|
||||
* @return A list of [start, end) pairs indicating the positions of phone numbers in the input.
|
||||
*/
|
||||
// @VisibleForTesting
|
||||
static int[] findNanpPhoneNumbers(CharSequence text) {
|
||||
ArrayList<Integer> list = new ArrayList<Integer>();
|
||||
|
||||
int startPos = 0;
|
||||
int endPos = text.length() - NANP_MIN_DIGITS + 1;
|
||||
if (endPos < 0) {
|
||||
return new int[] {};
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't just strip the whitespace out and crunch it down, because the whitespace
|
||||
* is significant. March through, trying to figure out where numbers start and end.
|
||||
*/
|
||||
while (startPos < endPos) {
|
||||
// skip whitespace
|
||||
while (Character.isWhitespace(text.charAt(startPos)) && startPos < endPos) {
|
||||
startPos++;
|
||||
}
|
||||
if (startPos == endPos) {
|
||||
break;
|
||||
}
|
||||
|
||||
// check for a match at this position
|
||||
int matchEnd = findNanpMatchEnd(text, startPos);
|
||||
if (matchEnd > startPos) {
|
||||
list.add(startPos);
|
||||
list.add(matchEnd);
|
||||
startPos = matchEnd; // skip past match
|
||||
} else {
|
||||
// skip to next whitespace char
|
||||
while (!Character.isWhitespace(text.charAt(startPos)) && startPos < endPos) {
|
||||
startPos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int[] result = new int[list.size()];
|
||||
for (int i = list.size() - 1; i >= 0; i--) {
|
||||
result[i] = list.get(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if there is a valid phone number in the input, starting at the specified
|
||||
* offset. If so, the index of the last character + 1 is returned. The input is assumed
|
||||
* to begin with a non-whitespace character.
|
||||
*
|
||||
* @return Exclusive end position, or -1 if not a match.
|
||||
*/
|
||||
private static int findNanpMatchEnd(CharSequence text, int startPos) {
|
||||
/*
|
||||
* A few interesting cases:
|
||||
* 94043 # too short, ignore
|
||||
* 123456789012 # too long, ignore
|
||||
* +1 (650) 555-1212 # 11 digits, spaces
|
||||
* (650) 555 5555 # Second space, only when first is present.
|
||||
* (650) 555-1212, (650) 555-1213 # two numbers, return first
|
||||
* 1-650-555-1212 # 11 digits with leading '1'
|
||||
* *#650.555.1212#*! # 10 digits, include #*, ignore trailing '!'
|
||||
* 555.1212 # 7 digits
|
||||
*
|
||||
* For the most part we want to break on whitespace, but it's common to leave a space
|
||||
* between the initial '1' and/or after the area code.
|
||||
*/
|
||||
|
||||
// Check for "tel:" URI prefix.
|
||||
if (text.length() > startPos+4
|
||||
&& text.subSequence(startPos, startPos+4).toString().equalsIgnoreCase("tel:")) {
|
||||
startPos += 4;
|
||||
}
|
||||
|
||||
int endPos = text.length();
|
||||
int curPos = startPos;
|
||||
int foundDigits = 0;
|
||||
char firstDigit = 'x';
|
||||
boolean foundWhiteSpaceAfterAreaCode = false;
|
||||
|
||||
while (curPos <= endPos) {
|
||||
char ch;
|
||||
if (curPos < endPos) {
|
||||
ch = text.charAt(curPos);
|
||||
} else {
|
||||
ch = 27; // fake invalid symbol at end to trigger loop break
|
||||
}
|
||||
|
||||
if (Character.isDigit(ch)) {
|
||||
if (foundDigits == 0) {
|
||||
firstDigit = ch;
|
||||
}
|
||||
foundDigits++;
|
||||
if (foundDigits > NANP_MAX_DIGITS) {
|
||||
// too many digits, stop early
|
||||
return -1;
|
||||
}
|
||||
} else if (Character.isWhitespace(ch)) {
|
||||
if ( (firstDigit == '1' && foundDigits == 4) ||
|
||||
(foundDigits == 3)) {
|
||||
foundWhiteSpaceAfterAreaCode = true;
|
||||
} else if (firstDigit == '1' && foundDigits == 1) {
|
||||
} else if (foundWhiteSpaceAfterAreaCode
|
||||
&& ( (firstDigit == '1' && (foundDigits == 7)) || (foundDigits == 6))) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (NANP_ALLOWED_SYMBOLS.indexOf(ch) == -1) {
|
||||
break;
|
||||
}
|
||||
// else it's an allowed symbol
|
||||
|
||||
curPos++;
|
||||
}
|
||||
|
||||
if ((firstDigit != '1' && (foundDigits == 7 || foundDigits == 10)) ||
|
||||
(firstDigit == '1' && foundDigits == 11)) {
|
||||
// match
|
||||
return curPos;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static int indexFirstNonWhitespaceChar(CharSequence str) {
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
if (!Character.isWhitespace(str.charAt(i))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static int indexLastNonWhitespaceChar(CharSequence str) {
|
||||
for (int i = str.length() - 1; i >= 0; i--) {
|
||||
if (!Character.isWhitespace(str.charAt(i))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces stretches of text that look like addresses and phone numbers with clickable
|
||||
* links.
|
||||
* <p>
|
||||
* This is really just an enhanced version of Linkify.addLinks().
|
||||
*/
|
||||
private static void linkifyTextView(TextView textView) {
|
||||
/*
|
||||
* If the text includes a street address like "1600 Amphitheater Parkway, 94043",
|
||||
* the current Linkify code will identify "94043" as a phone number and invite
|
||||
* you to dial it (and not provide a map link for the address). For outside US,
|
||||
* use Linkify result iff it spans the entire text. Otherwise send the user to maps.
|
||||
*/
|
||||
String defaultPhoneRegion = System.getProperty("user.region", "US");
|
||||
if (!defaultPhoneRegion.equals("US")) {
|
||||
CharSequence origText = textView.getText();
|
||||
Linkify.addLinks(textView, Linkify.ALL);
|
||||
|
||||
// If Linkify links the entire text, use that result.
|
||||
if (textView.getText() instanceof Spannable) {
|
||||
Spannable spanText = (Spannable) textView.getText();
|
||||
URLSpan[] spans = spanText.getSpans(0, spanText.length(), URLSpan.class);
|
||||
if (spans.length == 1) {
|
||||
int linkStart = spanText.getSpanStart(spans[0]);
|
||||
int linkEnd = spanText.getSpanEnd(spans[0]);
|
||||
if (linkStart <= indexFirstNonWhitespaceChar(origText) &&
|
||||
linkEnd >= indexLastNonWhitespaceChar(origText) + 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise default to geo.
|
||||
textView.setText(origText);
|
||||
Linkify.addLinks(textView, mWildcardPattern, "geo:0,0?q=");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* For within US, we want to have better recognition of phone numbers without losing
|
||||
* any of the existing annotations. Ideally this would be addressed by improving Linkify.
|
||||
* For now we manage it as a second pass over the text.
|
||||
*
|
||||
* URIs and e-mail addresses are pretty easy to pick out of text. Phone numbers
|
||||
* are a bit tricky because they have radically different formats in different
|
||||
* countries, in terms of both the digits and the way in which they are commonly
|
||||
* written or presented (e.g. the punctuation and spaces in "(650) 555-1212").
|
||||
* The expected format of a street address is defined in WebView.findAddress(). It's
|
||||
* pretty narrowly defined, so it won't often match.
|
||||
*
|
||||
* The RFC 3966 specification defines the format of a "tel:" URI.
|
||||
*
|
||||
* Start by letting Linkify find anything that isn't a phone number. We have to let it
|
||||
* run first because every invocation removes all previous URLSpan annotations.
|
||||
*
|
||||
* Ideally we'd use the external/libphonenumber routines, but those aren't available
|
||||
* to unbundled applications.
|
||||
*/
|
||||
boolean linkifyFoundLinks = Linkify.addLinks(textView,
|
||||
Linkify.ALL & ~(Linkify.PHONE_NUMBERS));
|
||||
|
||||
/*
|
||||
* Search for phone numbers.
|
||||
*
|
||||
* Some URIs contain strings of digits that look like phone numbers. If both the URI
|
||||
* scanner and the phone number scanner find them, we want the URI link to win. Since
|
||||
* the URI scanner runs first, we just need to avoid creating overlapping spans.
|
||||
*/
|
||||
CharSequence text = textView.getText();
|
||||
int[] phoneSequences = findNanpPhoneNumbers(text);
|
||||
|
||||
/*
|
||||
* If the contents of the TextView are already Spannable (which will be the case if
|
||||
* Linkify found stuff, but might not be otherwise), we can just add annotations
|
||||
* to what's there. If it's not, and we find phone numbers, we need to convert it to
|
||||
* a Spannable form. (This mimics the behavior of Linkable.addLinks().)
|
||||
*/
|
||||
Spannable spanText;
|
||||
if (text instanceof SpannableString) {
|
||||
spanText = (SpannableString) text;
|
||||
} else {
|
||||
spanText = SpannableString.valueOf(text);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a list of any spans created by Linkify, for the overlapping span check.
|
||||
*/
|
||||
URLSpan[] existingSpans = spanText.getSpans(0, spanText.length(), URLSpan.class);
|
||||
|
||||
/*
|
||||
* Insert spans for the numbers we found. We generate "tel:" URIs.
|
||||
*/
|
||||
int phoneCount = 0;
|
||||
for (int match = 0; match < phoneSequences.length / 2; match++) {
|
||||
int start = phoneSequences[match*2];
|
||||
int end = phoneSequences[match*2 + 1];
|
||||
|
||||
if (spanWillOverlap(spanText, existingSpans, start, end)) {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
CharSequence seq = text.subSequence(start, end);
|
||||
Log.v(TAG, "Not linkifying " + seq + " as phone number due to overlap");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* The Linkify code takes the matching span and strips out everything that isn't a
|
||||
* digit or '+' sign. We do the same here. Extension numbers will get appended
|
||||
* without a separator, but the dialer wasn't doing anything useful with ";ext="
|
||||
* anyway.
|
||||
*/
|
||||
|
||||
//String dialStr = phoneUtil.format(match.number(),
|
||||
// PhoneNumberUtil.PhoneNumberFormat.RFC3966);
|
||||
StringBuilder dialBuilder = new StringBuilder();
|
||||
for (int i = start; i < end; i++) {
|
||||
char ch = spanText.charAt(i);
|
||||
if (ch == '+' || Character.isDigit(ch)) {
|
||||
dialBuilder.append(ch);
|
||||
}
|
||||
}
|
||||
URLSpan span = new URLSpan("tel:" + dialBuilder.toString());
|
||||
|
||||
spanText.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
phoneCount++;
|
||||
}
|
||||
|
||||
if (phoneCount != 0) {
|
||||
// If we had to "upgrade" to Spannable, store the object into the TextView.
|
||||
if (spanText != text) {
|
||||
textView.setText(spanText);
|
||||
}
|
||||
|
||||
// Linkify.addLinks() sets the TextView movement method if it finds any links. We
|
||||
// want to do the same here. (This is cloned from Linkify.addLinkMovementMethod().)
|
||||
MovementMethod mm = textView.getMovementMethod();
|
||||
|
||||
if ((mm == null) || !(mm instanceof LinkMovementMethod)) {
|
||||
if (textView.getLinksClickable()) {
|
||||
textView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!linkifyFoundLinks && phoneCount == 0) {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.v(TAG, "No linkification matches, using geo default");
|
||||
}
|
||||
Linkify.addLinks(textView, mWildcardPattern, "geo:0,0?q=");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a new span at [start,end) will overlap with any existing span.
|
||||
*/
|
||||
private static boolean spanWillOverlap(Spannable spanText, URLSpan[] spanList, int start,
|
||||
int end) {
|
||||
if (start == end) {
|
||||
// empty span, ignore
|
||||
return false;
|
||||
}
|
||||
for (URLSpan span : spanList) {
|
||||
int existingStart = spanText.getSpanStart(span);
|
||||
int existingEnd = spanText.getSpanEnd(span);
|
||||
if ((start >= existingStart && start < existingEnd) ||
|
||||
end > existingStart && end <= existingEnd) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void sendAccessibilityEvent() {
|
||||
AccessibilityManager am =
|
||||
(AccessibilityManager) getActivity().getSystemService(Service.ACCESSIBILITY_SERVICE);
|
||||
@ -1715,8 +1427,6 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
|
||||
mOwnerCanRespond = mCalendarsCursor.getInt(CALENDARS_INDEX_OWNER_CAN_RESPOND) != 0;
|
||||
mSyncAccountName = mCalendarsCursor.getString(CALENDARS_INDEX_ACCOUNT_NAME);
|
||||
|
||||
String displayName = mCalendarsCursor.getString(CALENDARS_INDEX_DISPLAY_NAME);
|
||||
|
||||
// start visible calendars query
|
||||
mHandler.startQuery(TOKEN_QUERY_VISIBLE_CALENDARS, null, Calendars.CONTENT_URI,
|
||||
CALENDARS_PROJECTION, CALENDARS_VISIBLE_WHERE, new String[] {"1"}, null);
|
||||
@ -2204,6 +1914,7 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleteStarted() {
|
||||
mEventDeletionStarted = true;
|
||||
}
|
||||
|
94
src/com/android/calendar/ExtensionsFactory.java
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.calendar;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetManager;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
/*
|
||||
* Skeleton for additional options in the AllInOne menu.
|
||||
*/
|
||||
public class ExtensionsFactory {
|
||||
private static String TAG = "ExtensionsFactory";
|
||||
|
||||
// Config filename for mappings of various class names to their custom implementations.
|
||||
private static String EXTENSIONS_PROPERTIES = "calendar_extensions.properties";
|
||||
|
||||
private static String ALL_IN_ONE_MENU_KEY = "AllInOneMenuExtensions";
|
||||
|
||||
private static Properties sProperties = new Properties();
|
||||
private static AllInOneMenuExtensionsInterface sAllInOneMenuExtensions = null;
|
||||
|
||||
public static void init(AssetManager assetManager) {
|
||||
try {
|
||||
InputStream fileStream = assetManager.open(EXTENSIONS_PROPERTIES);
|
||||
sProperties.load(fileStream);
|
||||
fileStream.close();
|
||||
} catch (IOException e) {
|
||||
// No custom extensions. Ignore.
|
||||
Log.d(TAG, "No custom extensions.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> T createInstance(String className) {
|
||||
try {
|
||||
Class<?> c = Class.forName(className);
|
||||
return (T) c.newInstance();
|
||||
} catch (ClassNotFoundException e) {
|
||||
Log.e(TAG, className + ": unable to create instance.", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e(TAG, className + ": unable to create instance.", e);
|
||||
} catch (InstantiationException e) {
|
||||
Log.e(TAG, className + ": unable to create instance.", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static AllInOneMenuExtensionsInterface getAllInOneMenuExtensions() {
|
||||
if (sAllInOneMenuExtensions == null) {
|
||||
String className = sProperties.getProperty(ALL_IN_ONE_MENU_KEY);
|
||||
if (className != null) {
|
||||
sAllInOneMenuExtensions = createInstance(className);
|
||||
} else {
|
||||
Log.d(TAG, ALL_IN_ONE_MENU_KEY + " not found in properties file.");
|
||||
}
|
||||
|
||||
if (sAllInOneMenuExtensions == null) {
|
||||
sAllInOneMenuExtensions = new AllInOneMenuExtensionsInterface() {
|
||||
@Override
|
||||
public Integer getExtensionMenuResource(Menu menu) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleItemSelected(MenuItem item, Context context) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return sAllInOneMenuExtensions;
|
||||
}
|
||||
}
|
@ -227,7 +227,7 @@ public class GeneralPreferences extends PreferenceFragment implements
|
||||
if (mAlert.isChecked()) {
|
||||
intent.setAction(AlertReceiver.ACTION_DISMISS_OLD_REMINDERS);
|
||||
} else {
|
||||
intent.setAction(CalendarContract.ACTION_EVENT_REMINDER);
|
||||
intent.setAction(AlertReceiver.EVENT_REMINDER_APP_ACTION);
|
||||
}
|
||||
a.sendBroadcast(intent);
|
||||
}
|
||||
|
@ -384,11 +384,11 @@ public class TimezoneAdapter extends ArrayAdapter<TimezoneRow> {
|
||||
*/
|
||||
public CharSequence[][] getAllTimezones() {
|
||||
CharSequence[][] timeZones = new CharSequence[2][sTimezones.size()];
|
||||
List<String> ids = new ArrayList<String>(sTimezones.keySet());
|
||||
List<TimezoneRow> timezones = new ArrayList<TimezoneRow>(sTimezones.values());
|
||||
Collections.sort(timezones);
|
||||
int i = 0;
|
||||
for (TimezoneRow row : timezones) {
|
||||
timeZones[0][i] = ids.get(i);
|
||||
timeZones[0][i] = row.mId;
|
||||
timeZones[1][i++] = row.toString();
|
||||
}
|
||||
return timeZones;
|
||||
@ -400,12 +400,31 @@ public class TimezoneAdapter extends ArrayAdapter<TimezoneRow> {
|
||||
String[] labels = resources.getStringArray(R.array.timezone_labels);
|
||||
|
||||
int length = ids.length;
|
||||
sTimezones = new LinkedHashMap<String, TimezoneRow>(length);
|
||||
|
||||
if (ids.length != labels.length) {
|
||||
Log.wtf(TAG, "ids length (" + ids.length + ") and labels length(" + labels.length +
|
||||
Log.e(TAG, "ids length (" + ids.length + ") and labels length(" + labels.length +
|
||||
") should be equal but aren't.");
|
||||
if (Log.isLoggable(TAG, Log.INFO)) {
|
||||
StringBuilder tzLog = new StringBuilder();
|
||||
for (int id_i = 0; id_i < Math.max(ids.length, labels.length); id_i++) {
|
||||
String id, label;
|
||||
id = label = "{NONE FOUND}";
|
||||
if (id_i < ids.length) {
|
||||
id = ids[id_i];
|
||||
}
|
||||
if (id_i < labels.length) {
|
||||
label = labels[id_i];
|
||||
}
|
||||
tzLog.append(id_i).append(": ").append("id=").append(id).append("\t\t\t\t")
|
||||
.append("label=").append(label).append("\n");
|
||||
}
|
||||
Log.i(TAG, tzLog.toString());
|
||||
}
|
||||
if (ids.length > labels.length) {
|
||||
length = labels.length;
|
||||
}
|
||||
}
|
||||
|
||||
sTimezones = new LinkedHashMap<String, TimezoneRow>(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
sTimezones.put(ids[i], new TimezoneRow(ids[i], labels[i]));
|
||||
}
|
||||
|
@ -39,10 +39,15 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.provider.CalendarContract.Calendars;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateFormat;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.format.Time;
|
||||
import android.text.style.URLSpan;
|
||||
import android.text.util.Linkify;
|
||||
import android.util.Log;
|
||||
import android.widget.SearchView;
|
||||
|
||||
@ -62,6 +67,8 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Utils {
|
||||
private static final boolean DEBUG = false;
|
||||
@ -130,6 +137,65 @@ public class Utils {
|
||||
private static long mTardis = 0;
|
||||
private static String sVersion = null;
|
||||
|
||||
private static final Pattern mWildcardPattern = Pattern.compile("^.*$");
|
||||
|
||||
/**
|
||||
* A coordinate must be of the following form for Google Maps to correctly use it:
|
||||
* Latitude, Longitude
|
||||
*
|
||||
* This may be in decimal form:
|
||||
* Latitude: {-90 to 90}
|
||||
* Longitude: {-180 to 180}
|
||||
*
|
||||
* Or, in degrees, minutes, and seconds:
|
||||
* Latitude: {-90 to 90}° {0 to 59}' {0 to 59}"
|
||||
* Latitude: {-180 to 180}° {0 to 59}' {0 to 59}"
|
||||
* + or - degrees may also be represented with N or n, S or s for latitude, and with
|
||||
* E or e, W or w for longitude, where the direction may either precede or follow the value.
|
||||
*
|
||||
* Some examples of coordinates that will be accepted by the regex:
|
||||
* 37.422081°, -122.084576°
|
||||
* 37.422081,-122.084576
|
||||
* +37°25'19.49", -122°5'4.47"
|
||||
* 37°25'19.49"N, 122°5'4.47"W
|
||||
* N 37° 25' 19.49", W 122° 5' 4.47"
|
||||
**/
|
||||
private static final String COORD_DEGREES_LATITUDE =
|
||||
"([-+NnSs]" + "(\\s)*)?"
|
||||
+ "[1-9]?[0-9](\u00B0)" + "(\\s)*"
|
||||
+ "([1-5]?[0-9]\')?" + "(\\s)*"
|
||||
+ "([1-5]?[0-9]" + "(\\.[0-9]+)?\")?"
|
||||
+ "((\\s)*" + "[NnSs])?";
|
||||
private static final String COORD_DEGREES_LONGITUDE =
|
||||
"([-+EeWw]" + "(\\s)*)?"
|
||||
+ "(1)?[0-9]?[0-9](\u00B0)" + "(\\s)*"
|
||||
+ "([1-5]?[0-9]\')?" + "(\\s)*"
|
||||
+ "([1-5]?[0-9]" + "(\\.[0-9]+)?\")?"
|
||||
+ "((\\s)*" + "[EeWw])?";
|
||||
private static final String COORD_DEGREES_PATTERN =
|
||||
COORD_DEGREES_LATITUDE
|
||||
+ "(\\s)*" + "," + "(\\s)*"
|
||||
+ COORD_DEGREES_LONGITUDE;
|
||||
private static final String COORD_DECIMAL_LATITUDE =
|
||||
"[+-]?"
|
||||
+ "[1-9]?[0-9]" + "(\\.[0-9]+)"
|
||||
+ "(\u00B0)?";
|
||||
private static final String COORD_DECIMAL_LONGITUDE =
|
||||
"[+-]?"
|
||||
+ "(1)?[0-9]?[0-9]" + "(\\.[0-9]+)"
|
||||
+ "(\u00B0)?";
|
||||
private static final String COORD_DECIMAL_PATTERN =
|
||||
COORD_DECIMAL_LATITUDE
|
||||
+ "(\\s)*" + "," + "(\\s)*"
|
||||
+ COORD_DECIMAL_LONGITUDE;
|
||||
private static final Pattern COORD_PATTERN =
|
||||
Pattern.compile(COORD_DEGREES_PATTERN + "|" + COORD_DECIMAL_PATTERN);
|
||||
|
||||
private static final String NANP_ALLOWED_SYMBOLS = "()+-*#.";
|
||||
private static final int NANP_MIN_DIGITS = 7;
|
||||
private static final int NANP_MAX_DIGITS = 11;
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the SDK is the Jellybean release or later.
|
||||
*/
|
||||
@ -303,7 +369,7 @@ public class Utils {
|
||||
return mTardis;
|
||||
}
|
||||
|
||||
static void setSharedPreference(Context context, String key, boolean value) {
|
||||
public static void setSharedPreference(Context context, String key, boolean value) {
|
||||
SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context);
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
editor.putBoolean(key, value);
|
||||
@ -1572,4 +1638,331 @@ public class Utils {
|
||||
extras.putBoolean("metafeedonly", true);
|
||||
ContentResolver.requestSync(account, Calendars.CONTENT_URI.getAuthority(), extras);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces stretches of text that look like addresses and phone numbers with clickable
|
||||
* links. If lastDitchGeo is true, then if no links are found in the textview, the entire
|
||||
* string will be converted to a single geo link. Any spans that may have previously been
|
||||
* in the text will be cleared out.
|
||||
* <p>
|
||||
* This is really just an enhanced version of Linkify.addLinks().
|
||||
*
|
||||
* @param text - The string to search for links.
|
||||
* @param lastDitchGeo - If no links are found, turn the entire string into one geo link.
|
||||
* @return Spannable object containing the list of URL spans found.
|
||||
*/
|
||||
public static Spannable extendedLinkify(String text, boolean lastDitchGeo) {
|
||||
// We use a copy of the string argument so it's available for later if necessary.
|
||||
Spannable spanText = SpannableString.valueOf(text);
|
||||
|
||||
/*
|
||||
* If the text includes a street address like "1600 Amphitheater Parkway, 94043",
|
||||
* the current Linkify code will identify "94043" as a phone number and invite
|
||||
* you to dial it (and not provide a map link for the address). For outside US,
|
||||
* use Linkify result iff it spans the entire text. Otherwise send the user to maps.
|
||||
*/
|
||||
String defaultPhoneRegion = System.getProperty("user.region", "US");
|
||||
if (!defaultPhoneRegion.equals("US")) {
|
||||
Linkify.addLinks(spanText, Linkify.ALL);
|
||||
|
||||
// If Linkify links the entire text, use that result.
|
||||
URLSpan[] spans = spanText.getSpans(0, spanText.length(), URLSpan.class);
|
||||
if (spans.length == 1) {
|
||||
int linkStart = spanText.getSpanStart(spans[0]);
|
||||
int linkEnd = spanText.getSpanEnd(spans[0]);
|
||||
if (linkStart <= indexFirstNonWhitespaceChar(spanText) &&
|
||||
linkEnd >= indexLastNonWhitespaceChar(spanText) + 1) {
|
||||
return spanText;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, to be cautious and to try to prevent false positives, reset the spannable.
|
||||
spanText = SpannableString.valueOf(text);
|
||||
// If lastDitchGeo is true, default the entire string to geo.
|
||||
if (lastDitchGeo && !text.isEmpty()) {
|
||||
Linkify.addLinks(spanText, mWildcardPattern, "geo:0,0?q=");
|
||||
}
|
||||
return spanText;
|
||||
}
|
||||
|
||||
/*
|
||||
* For within US, we want to have better recognition of phone numbers without losing
|
||||
* any of the existing annotations. Ideally this would be addressed by improving Linkify.
|
||||
* For now we manage it as a second pass over the text.
|
||||
*
|
||||
* URIs and e-mail addresses are pretty easy to pick out of text. Phone numbers
|
||||
* are a bit tricky because they have radically different formats in different
|
||||
* countries, in terms of both the digits and the way in which they are commonly
|
||||
* written or presented (e.g. the punctuation and spaces in "(650) 555-1212").
|
||||
* The expected format of a street address is defined in WebView.findAddress(). It's
|
||||
* pretty narrowly defined, so it won't often match.
|
||||
*
|
||||
* The RFC 3966 specification defines the format of a "tel:" URI.
|
||||
*
|
||||
* Start by letting Linkify find anything that isn't a phone number. We have to let it
|
||||
* run first because every invocation removes all previous URLSpan annotations.
|
||||
*
|
||||
* Ideally we'd use the external/libphonenumber routines, but those aren't available
|
||||
* to unbundled applications.
|
||||
*/
|
||||
boolean linkifyFoundLinks = Linkify.addLinks(spanText,
|
||||
Linkify.ALL & ~(Linkify.PHONE_NUMBERS));
|
||||
|
||||
/*
|
||||
* Get a list of any spans created by Linkify, for the coordinate overlapping span check.
|
||||
*/
|
||||
URLSpan[] existingSpans = spanText.getSpans(0, spanText.length(), URLSpan.class);
|
||||
|
||||
/*
|
||||
* Check for coordinates.
|
||||
* This must be done before phone numbers because longitude may look like a phone number.
|
||||
*/
|
||||
Matcher coordMatcher = COORD_PATTERN.matcher(spanText);
|
||||
int coordCount = 0;
|
||||
while (coordMatcher.find()) {
|
||||
int start = coordMatcher.start();
|
||||
int end = coordMatcher.end();
|
||||
if (spanWillOverlap(spanText, existingSpans, start, end)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
URLSpan span = new URLSpan("geo:0,0?q=" + coordMatcher.group());
|
||||
spanText.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
coordCount++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the list of existing spans, for the phone number overlapping span check.
|
||||
*/
|
||||
existingSpans = spanText.getSpans(0, spanText.length(), URLSpan.class);
|
||||
|
||||
/*
|
||||
* Search for phone numbers.
|
||||
*
|
||||
* Some URIs contain strings of digits that look like phone numbers. If both the URI
|
||||
* scanner and the phone number scanner find them, we want the URI link to win. Since
|
||||
* the URI scanner runs first, we just need to avoid creating overlapping spans.
|
||||
*/
|
||||
int[] phoneSequences = findNanpPhoneNumbers(text);
|
||||
|
||||
/*
|
||||
* Insert spans for the numbers we found. We generate "tel:" URIs.
|
||||
*/
|
||||
int phoneCount = 0;
|
||||
for (int match = 0; match < phoneSequences.length / 2; match++) {
|
||||
int start = phoneSequences[match*2];
|
||||
int end = phoneSequences[match*2 + 1];
|
||||
|
||||
if (spanWillOverlap(spanText, existingSpans, start, end)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* The Linkify code takes the matching span and strips out everything that isn't a
|
||||
* digit or '+' sign. We do the same here. Extension numbers will get appended
|
||||
* without a separator, but the dialer wasn't doing anything useful with ";ext="
|
||||
* anyway.
|
||||
*/
|
||||
|
||||
//String dialStr = phoneUtil.format(match.number(),
|
||||
// PhoneNumberUtil.PhoneNumberFormat.RFC3966);
|
||||
StringBuilder dialBuilder = new StringBuilder();
|
||||
for (int i = start; i < end; i++) {
|
||||
char ch = spanText.charAt(i);
|
||||
if (ch == '+' || Character.isDigit(ch)) {
|
||||
dialBuilder.append(ch);
|
||||
}
|
||||
}
|
||||
URLSpan span = new URLSpan("tel:" + dialBuilder.toString());
|
||||
|
||||
spanText.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
phoneCount++;
|
||||
}
|
||||
|
||||
/*
|
||||
* If lastDitchGeo, and no other links have been found, set the entire string as a geo link.
|
||||
*/
|
||||
if (lastDitchGeo && !text.isEmpty() &&
|
||||
!linkifyFoundLinks && phoneCount == 0 && coordCount == 0) {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
Log.v(TAG, "No linkification matches, using geo default");
|
||||
}
|
||||
Linkify.addLinks(spanText, mWildcardPattern, "geo:0,0?q=");
|
||||
}
|
||||
|
||||
return spanText;
|
||||
}
|
||||
|
||||
private static int indexFirstNonWhitespaceChar(CharSequence str) {
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
if (!Character.isWhitespace(str.charAt(i))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static int indexLastNonWhitespaceChar(CharSequence str) {
|
||||
for (int i = str.length() - 1; i >= 0; i--) {
|
||||
if (!Character.isWhitespace(str.charAt(i))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds North American Numbering Plan (NANP) phone numbers in the input text.
|
||||
*
|
||||
* @param text The text to scan.
|
||||
* @return A list of [start, end) pairs indicating the positions of phone numbers in the input.
|
||||
*/
|
||||
// @VisibleForTesting
|
||||
static int[] findNanpPhoneNumbers(CharSequence text) {
|
||||
ArrayList<Integer> list = new ArrayList<Integer>();
|
||||
|
||||
int startPos = 0;
|
||||
int endPos = text.length() - NANP_MIN_DIGITS + 1;
|
||||
if (endPos < 0) {
|
||||
return new int[] {};
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't just strip the whitespace out and crunch it down, because the whitespace
|
||||
* is significant. March through, trying to figure out where numbers start and end.
|
||||
*/
|
||||
while (startPos < endPos) {
|
||||
// skip whitespace
|
||||
while (Character.isWhitespace(text.charAt(startPos)) && startPos < endPos) {
|
||||
startPos++;
|
||||
}
|
||||
if (startPos == endPos) {
|
||||
break;
|
||||
}
|
||||
|
||||
// check for a match at this position
|
||||
int matchEnd = findNanpMatchEnd(text, startPos);
|
||||
if (matchEnd > startPos) {
|
||||
list.add(startPos);
|
||||
list.add(matchEnd);
|
||||
startPos = matchEnd; // skip past match
|
||||
} else {
|
||||
// skip to next whitespace char
|
||||
while (!Character.isWhitespace(text.charAt(startPos)) && startPos < endPos) {
|
||||
startPos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int[] result = new int[list.size()];
|
||||
for (int i = list.size() - 1; i >= 0; i--) {
|
||||
result[i] = list.get(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if there is a valid phone number in the input, starting at the specified
|
||||
* offset. If so, the index of the last character + 1 is returned. The input is assumed
|
||||
* to begin with a non-whitespace character.
|
||||
*
|
||||
* @return Exclusive end position, or -1 if not a match.
|
||||
*/
|
||||
private static int findNanpMatchEnd(CharSequence text, int startPos) {
|
||||
/*
|
||||
* A few interesting cases:
|
||||
* 94043 # too short, ignore
|
||||
* 123456789012 # too long, ignore
|
||||
* +1 (650) 555-1212 # 11 digits, spaces
|
||||
* (650) 555 5555 # Second space, only when first is present.
|
||||
* (650) 555-1212, (650) 555-1213 # two numbers, return first
|
||||
* 1-650-555-1212 # 11 digits with leading '1'
|
||||
* *#650.555.1212#*! # 10 digits, include #*, ignore trailing '!'
|
||||
* 555.1212 # 7 digits
|
||||
*
|
||||
* For the most part we want to break on whitespace, but it's common to leave a space
|
||||
* between the initial '1' and/or after the area code.
|
||||
*/
|
||||
|
||||
// Check for "tel:" URI prefix.
|
||||
if (text.length() > startPos+4
|
||||
&& text.subSequence(startPos, startPos+4).toString().equalsIgnoreCase("tel:")) {
|
||||
startPos += 4;
|
||||
}
|
||||
|
||||
int endPos = text.length();
|
||||
int curPos = startPos;
|
||||
int foundDigits = 0;
|
||||
char firstDigit = 'x';
|
||||
boolean foundWhiteSpaceAfterAreaCode = false;
|
||||
|
||||
while (curPos <= endPos) {
|
||||
char ch;
|
||||
if (curPos < endPos) {
|
||||
ch = text.charAt(curPos);
|
||||
} else {
|
||||
ch = 27; // fake invalid symbol at end to trigger loop break
|
||||
}
|
||||
|
||||
if (Character.isDigit(ch)) {
|
||||
if (foundDigits == 0) {
|
||||
firstDigit = ch;
|
||||
}
|
||||
foundDigits++;
|
||||
if (foundDigits > NANP_MAX_DIGITS) {
|
||||
// too many digits, stop early
|
||||
return -1;
|
||||
}
|
||||
} else if (Character.isWhitespace(ch)) {
|
||||
if ( (firstDigit == '1' && foundDigits == 4) ||
|
||||
(foundDigits == 3)) {
|
||||
foundWhiteSpaceAfterAreaCode = true;
|
||||
} else if (firstDigit == '1' && foundDigits == 1) {
|
||||
} else if (foundWhiteSpaceAfterAreaCode
|
||||
&& ( (firstDigit == '1' && (foundDigits == 7)) || (foundDigits == 6))) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (NANP_ALLOWED_SYMBOLS.indexOf(ch) == -1) {
|
||||
break;
|
||||
}
|
||||
// else it's an allowed symbol
|
||||
|
||||
curPos++;
|
||||
}
|
||||
|
||||
if ((firstDigit != '1' && (foundDigits == 7 || foundDigits == 10)) ||
|
||||
(firstDigit == '1' && foundDigits == 11)) {
|
||||
// match
|
||||
return curPos;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a new span at [start,end) will overlap with any existing span.
|
||||
*/
|
||||
private static boolean spanWillOverlap(Spannable spanText, URLSpan[] spanList, int start,
|
||||
int end) {
|
||||
if (start == end) {
|
||||
// empty span, ignore
|
||||
return false;
|
||||
}
|
||||
for (URLSpan span : spanList) {
|
||||
int existingStart = spanText.getSpanStart(span);
|
||||
int existingEnd = spanText.getSpanEnd(span);
|
||||
if ((start >= existingStart && start < existingEnd) ||
|
||||
end > existingStart && end <= existingEnd) {
|
||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||
CharSequence seq = spanText.subSequence(start, end);
|
||||
Log.v(TAG, "Not linkifying " + seq + " as phone number due to overlap");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,23 +16,22 @@
|
||||
|
||||
package com.android.calendar.agenda;
|
||||
|
||||
import com.android.calendar.R;
|
||||
import com.android.calendar.Utils;
|
||||
import com.android.calendar.agenda.AgendaWindowAdapter.DayAdapterInfo;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Typeface;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.format.Time;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.calendar.R;
|
||||
import com.android.calendar.Utils;
|
||||
import com.android.calendar.agenda.AgendaWindowAdapter.DayAdapterInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Formatter;
|
||||
import java.util.Iterator;
|
||||
@ -125,6 +124,7 @@ public class AgendaByDayAdapter extends BaseAdapter {
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
if (mRowInfo != null) {
|
||||
return mRowInfo.size();
|
||||
@ -132,6 +132,7 @@ public class AgendaByDayAdapter extends BaseAdapter {
|
||||
return mAgendaAdapter.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
if (mRowInfo != null) {
|
||||
RowInfo row = mRowInfo.get(position);
|
||||
@ -144,6 +145,7 @@ public class AgendaByDayAdapter extends BaseAdapter {
|
||||
return mAgendaAdapter.getItem(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
if (mRowInfo != null) {
|
||||
RowInfo row = mRowInfo.get(position);
|
||||
@ -171,6 +173,7 @@ public class AgendaByDayAdapter extends BaseAdapter {
|
||||
return (getItemViewType(position) == TYPE_DAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
if ((mRowInfo == null) || (position > mRowInfo.size())) {
|
||||
// If we have no row info, mAgendaAdapter returns the view.
|
||||
|
@ -44,6 +44,8 @@ import com.android.calendar.R;
|
||||
import com.android.calendar.StickyHeaderListView;
|
||||
import com.android.calendar.Utils;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class AgendaFragment extends Fragment implements CalendarController.EventHandler,
|
||||
OnScrollListener {
|
||||
|
||||
@ -256,9 +258,9 @@ public class AgendaFragment extends Fragment implements CalendarController.Event
|
||||
outState.putLong(BUNDLE_KEY_RESTORE_TIME, timeToSave);
|
||||
mController.setTime(timeToSave);
|
||||
} else {
|
||||
AgendaWindowAdapter.EventInfo e = mAgendaListView.getFirstVisibleEvent();
|
||||
if (e != null) {
|
||||
long firstVisibleTime = mAgendaListView.getFirstVisibleTime(e);
|
||||
AgendaWindowAdapter.AgendaItem item = mAgendaListView.getFirstVisibleAgendaItem();
|
||||
if (item != null) {
|
||||
long firstVisibleTime = mAgendaListView.getFirstVisibleTime(item);
|
||||
if (firstVisibleTime > 0) {
|
||||
mTime.set(firstVisibleTime);
|
||||
mController.setTime(firstVisibleTime);
|
||||
@ -267,7 +269,7 @@ public class AgendaFragment extends Fragment implements CalendarController.Event
|
||||
// Tell AllInOne the event id of the first visible event in the list. The id will be
|
||||
// used in the GOTO when AllInOne is restored so that Agenda Fragment can select a
|
||||
// specific event and not just the time.
|
||||
mLastShownEventId = e.id;
|
||||
mLastShownEventId = item.id;
|
||||
}
|
||||
}
|
||||
if (DEBUG) {
|
||||
@ -329,6 +331,7 @@ public class AgendaFragment extends Fragment implements CalendarController.Event
|
||||
mShowEventDetailsWithAgenda) ? true : false);
|
||||
AgendaAdapter.ViewHolder vh = mAgendaListView.getSelectedViewHolder();
|
||||
// Make sure that on the first time the event info is shown to recreate it
|
||||
Log.d(TAG, "selected viewholder is null: " + (vh == null));
|
||||
showEventInfo(event, vh != null ? vh.allDay : false, mForceReplace);
|
||||
mForceReplace = false;
|
||||
}
|
||||
@ -408,6 +411,14 @@ public class AgendaFragment extends Fragment implements CalendarController.Event
|
||||
event.endTime.timezone = Time.TIMEZONE_UTC;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "***");
|
||||
Log.d(TAG, "showEventInfo: start: " + new Date(event.startTime.toMillis(true)));
|
||||
Log.d(TAG, "showEventInfo: end: " + new Date(event.endTime.toMillis(true)));
|
||||
Log.d(TAG, "showEventInfo: all day: " + allDay);
|
||||
Log.d(TAG, "***");
|
||||
}
|
||||
|
||||
long startMillis = event.startTime.toMillis(true);
|
||||
long endMillis = event.endTime.toMillis(true);
|
||||
EventInfoFragment fOld =
|
||||
@ -415,7 +426,7 @@ public class AgendaFragment extends Fragment implements CalendarController.Event
|
||||
if (fOld == null || replaceFragment || fOld.getStartMillis() != startMillis ||
|
||||
fOld.getEndMillis() != endMillis || fOld.getEventId() != event.id) {
|
||||
mEventFragment = new EventInfoFragment(mActivity, event.id,
|
||||
event.startTime.toMillis(true), event.endTime.toMillis(true),
|
||||
startMillis, endMillis,
|
||||
Attendees.ATTENDEE_STATUS_NONE, false,
|
||||
EventInfoFragment.DIALOG_WINDOW_STYLE);
|
||||
ft.replace(R.id.agenda_event_info, mEventFragment);
|
||||
|
@ -23,7 +23,7 @@ import com.android.calendar.R;
|
||||
import com.android.calendar.Utils;
|
||||
import com.android.calendar.agenda.AgendaAdapter.ViewHolder;
|
||||
import com.android.calendar.agenda.AgendaWindowAdapter.DayAdapterInfo;
|
||||
import com.android.calendar.agenda.AgendaWindowAdapter.EventInfo;
|
||||
import com.android.calendar.agenda.AgendaWindowAdapter.AgendaItem;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
@ -172,17 +172,17 @@ public class AgendaListView extends ListView implements OnItemClickListener {
|
||||
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
|
||||
if (id != -1) {
|
||||
// Switch to the EventInfo view
|
||||
EventInfo event = mWindowAdapter.getEventByPosition(position);
|
||||
AgendaItem item = mWindowAdapter.getAgendaItemByPosition(position);
|
||||
long oldInstanceId = mWindowAdapter.getSelectedInstanceId();
|
||||
mWindowAdapter.setSelectedView(v);
|
||||
|
||||
// If events are shown to the side of the agenda list , do nothing
|
||||
// when the same event is selected , otherwise show the selected event.
|
||||
|
||||
if (event != null && (oldInstanceId != mWindowAdapter.getSelectedInstanceId() ||
|
||||
if (item != null && (oldInstanceId != mWindowAdapter.getSelectedInstanceId() ||
|
||||
!mShowEventDetailsWithAgenda)) {
|
||||
long startTime = event.begin;
|
||||
long endTime = event.end;
|
||||
long startTime = item.begin;
|
||||
long endTime = item.end;
|
||||
// Holder in view holds the start of the specific part of a multi-day event ,
|
||||
// use it for the goto
|
||||
long holderStartTime;
|
||||
@ -192,15 +192,15 @@ public class AgendaListView extends ListView implements OnItemClickListener {
|
||||
} else {
|
||||
holderStartTime = startTime;
|
||||
}
|
||||
if (event.allDay) {
|
||||
if (item.allDay) {
|
||||
startTime = Utils.convertAlldayLocalToUTC(mTime, startTime, mTimeZone);
|
||||
endTime = Utils.convertAlldayLocalToUTC(mTime, endTime, mTimeZone);
|
||||
}
|
||||
mTime.set(startTime);
|
||||
CalendarController controller = CalendarController.getInstance(mContext);
|
||||
controller.sendEventRelatedEventWithExtra(this, EventType.VIEW_EVENT, event.id,
|
||||
controller.sendEventRelatedEventWithExtra(this, EventType.VIEW_EVENT, item.id,
|
||||
startTime, endTime, 0, 0, CalendarController.EventInfo.buildViewExtraLong(
|
||||
Attendees.ATTENDEE_STATUS_NONE, event.allDay), holderStartTime);
|
||||
Attendees.ATTENDEE_STATUS_NONE, item.allDay), holderStartTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -230,9 +230,9 @@ public class AgendaListView extends ListView implements OnItemClickListener {
|
||||
|
||||
public void deleteSelectedEvent() {
|
||||
int position = getSelectedItemPosition();
|
||||
EventInfo event = mWindowAdapter.getEventByPosition(position);
|
||||
if (event != null) {
|
||||
mDeleteEventHelper.delete(event.begin, event.end, event.id, -1);
|
||||
AgendaItem agendaItem = mWindowAdapter.getAgendaItemByPosition(position);
|
||||
if (agendaItem != null) {
|
||||
mDeleteEventHelper.delete(agendaItem.begin, agendaItem.end, agendaItem.id, -1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,9 +252,9 @@ public class AgendaListView extends ListView implements OnItemClickListener {
|
||||
public long getSelectedTime() {
|
||||
int position = getSelectedItemPosition();
|
||||
if (position >= 0) {
|
||||
EventInfo event = mWindowAdapter.getEventByPosition(position);
|
||||
if (event != null) {
|
||||
return event.begin;
|
||||
AgendaItem item = mWindowAdapter.getAgendaItemByPosition(position);
|
||||
if (item != null) {
|
||||
return item.begin;
|
||||
}
|
||||
}
|
||||
return getFirstVisibleTime(null);
|
||||
@ -264,19 +264,19 @@ public class AgendaListView extends ListView implements OnItemClickListener {
|
||||
return mWindowAdapter.getSelectedViewHolder();
|
||||
}
|
||||
|
||||
public long getFirstVisibleTime(EventInfo e) {
|
||||
EventInfo event = e;
|
||||
if (e == null) {
|
||||
event = getFirstVisibleEvent();
|
||||
public long getFirstVisibleTime(AgendaItem item) {
|
||||
AgendaItem agendaItem = item;
|
||||
if (item == null) {
|
||||
agendaItem = getFirstVisibleAgendaItem();
|
||||
}
|
||||
if (event != null) {
|
||||
if (agendaItem != null) {
|
||||
Time t = new Time(mTimeZone);
|
||||
t.set(event.begin);
|
||||
t.set(agendaItem.begin);
|
||||
// Save and restore the time since setJulianDay sets the time to 00:00:00
|
||||
int hour = t.hour;
|
||||
int minute = t.minute;
|
||||
int second = t.second;
|
||||
t.setJulianDay(event.startDay);
|
||||
t.setJulianDay(agendaItem.startDay);
|
||||
t.hour = hour;
|
||||
t.minute = minute;
|
||||
t.second = second;
|
||||
@ -289,7 +289,7 @@ public class AgendaListView extends ListView implements OnItemClickListener {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public EventInfo getFirstVisibleEvent() {
|
||||
public AgendaItem getFirstVisibleAgendaItem() {
|
||||
int position = getFirstVisiblePosition();
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "getFirstVisiblePosition = " + position);
|
||||
@ -309,7 +309,7 @@ public class AgendaListView extends ListView implements OnItemClickListener {
|
||||
}
|
||||
}
|
||||
|
||||
return mWindowAdapter.getEventByPosition(position,
|
||||
return mWindowAdapter.getAgendaItemByPosition(position,
|
||||
false /* startDay = date separator date instead of actual event startday */);
|
||||
|
||||
}
|
||||
@ -323,7 +323,7 @@ public class AgendaListView extends ListView implements OnItemClickListener {
|
||||
}
|
||||
|
||||
// Finds is a specific event (defined by start time and id) is visible
|
||||
public boolean isEventVisible(Time startTime, long id) {
|
||||
public boolean isAgendaItemVisible(Time startTime, long id) {
|
||||
|
||||
if (id == -1 || startTime == null) {
|
||||
return false;
|
||||
@ -343,11 +343,11 @@ public class AgendaListView extends ListView implements OnItemClickListener {
|
||||
if (i + start >= eventsInAdapter) {
|
||||
break;
|
||||
}
|
||||
EventInfo event = mWindowAdapter.getEventByPosition(i + start);
|
||||
if (event == null) {
|
||||
AgendaItem agendaItem = mWindowAdapter.getAgendaItemByPosition(i + start);
|
||||
if (agendaItem == null) {
|
||||
continue;
|
||||
}
|
||||
if (event.id == id && event.begin == milliTime) {
|
||||
if (agendaItem.id == id && agendaItem.begin == milliTime) {
|
||||
View listItem = getChildAt(i);
|
||||
if (listItem.getTop() <= getHeight() &&
|
||||
listItem.getTop() >= mWindowAdapter.getStickyHeaderHeight()) {
|
||||
|
@ -48,6 +48,7 @@ import com.android.calendar.R;
|
||||
import com.android.calendar.StickyHeaderListView;
|
||||
import com.android.calendar.Utils;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Formatter;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
@ -290,7 +291,14 @@ public class AgendaWindowAdapter extends BaseAdapter
|
||||
}
|
||||
}
|
||||
|
||||
static class EventInfo {
|
||||
/**
|
||||
* Class representing a list item within the Agenda view. Could be either an instance of an
|
||||
* event, or a header marking the specific day.
|
||||
*
|
||||
* The begin and end times of an AgendaItem should always be in local time, even if the event
|
||||
* is all day. buildAgendaItemFromCursor() converts each event to local time.
|
||||
*/
|
||||
static class AgendaItem {
|
||||
long begin;
|
||||
long end;
|
||||
long id;
|
||||
@ -566,8 +574,8 @@ public class AgendaWindowAdapter extends BaseAdapter
|
||||
return null;
|
||||
}
|
||||
|
||||
public EventInfo getEventByPosition(final int positionInListView) {
|
||||
return getEventByPosition(positionInListView, true);
|
||||
public AgendaItem getAgendaItemByPosition(final int positionInListView) {
|
||||
return getAgendaItemByPosition(positionInListView, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -578,7 +586,7 @@ public class AgendaWindowAdapter extends BaseAdapter
|
||||
* The two will differ for multi-day events after the first day.
|
||||
* @return
|
||||
*/
|
||||
public EventInfo getEventByPosition(final int positionInListView,
|
||||
public AgendaItem getAgendaItemByPosition(final int positionInListView,
|
||||
boolean returnEventStartDay) {
|
||||
if (DEBUGLOG) Log.e(TAG, "getEventByPosition " + positionInListView);
|
||||
if (positionInListView < 0) {
|
||||
@ -603,54 +611,75 @@ public class AgendaWindowAdapter extends BaseAdapter
|
||||
}
|
||||
|
||||
if (cursorPosition < info.cursor.getCount()) {
|
||||
EventInfo ei = buildEventInfoFromCursor(info.cursor, cursorPosition, isDayHeader);
|
||||
AgendaItem item = buildAgendaItemFromCursor(info.cursor, cursorPosition, isDayHeader);
|
||||
if (!returnEventStartDay && !isDayHeader) {
|
||||
ei.startDay = info.dayAdapter.findJulianDayFromPosition(positionInAdapter -
|
||||
item.startDay = info.dayAdapter.findJulianDayFromPosition(positionInAdapter -
|
||||
info.offset);
|
||||
}
|
||||
return ei;
|
||||
return item;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private EventInfo buildEventInfoFromCursor(final Cursor cursor, int cursorPosition,
|
||||
private AgendaItem buildAgendaItemFromCursor(final Cursor cursor, int cursorPosition,
|
||||
boolean isDayHeader) {
|
||||
if (cursorPosition == -1) {
|
||||
cursor.moveToFirst();
|
||||
} else {
|
||||
cursor.moveToPosition(cursorPosition);
|
||||
}
|
||||
EventInfo event = new EventInfo();
|
||||
event.begin = cursor.getLong(AgendaWindowAdapter.INDEX_BEGIN);
|
||||
event.end = cursor.getLong(AgendaWindowAdapter.INDEX_END);
|
||||
event.startDay = cursor.getInt(AgendaWindowAdapter.INDEX_START_DAY);
|
||||
|
||||
event.allDay = cursor.getInt(AgendaWindowAdapter.INDEX_ALL_DAY) != 0;
|
||||
if (event.allDay) { // UTC
|
||||
AgendaItem agendaItem = new AgendaItem();
|
||||
agendaItem.begin = cursor.getLong(AgendaWindowAdapter.INDEX_BEGIN);
|
||||
agendaItem.end = cursor.getLong(AgendaWindowAdapter.INDEX_END);
|
||||
agendaItem.startDay = cursor.getInt(AgendaWindowAdapter.INDEX_START_DAY);
|
||||
agendaItem.allDay = cursor.getInt(AgendaWindowAdapter.INDEX_ALL_DAY) != 0;
|
||||
if (agendaItem.allDay) { // UTC to Local time conversion
|
||||
Time time = new Time(mTimeZone);
|
||||
time.setJulianDay(Time.getJulianDay(event.begin, 0));
|
||||
event.begin = time.toMillis(false /* use isDst */);
|
||||
time.setJulianDay(Time.getJulianDay(agendaItem.begin, 0));
|
||||
agendaItem.begin = time.toMillis(false /* use isDst */);
|
||||
} else if (isDayHeader) { // Trim to midnight.
|
||||
Time time = new Time(mTimeZone);
|
||||
time.set(event.begin);
|
||||
time.set(agendaItem.begin);
|
||||
time.hour = 0;
|
||||
time.minute = 0;
|
||||
time.second = 0;
|
||||
event.begin = time.toMillis(false /* use isDst */);
|
||||
agendaItem.begin = time.toMillis(false /* use isDst */);
|
||||
}
|
||||
|
||||
// If this is not a day header, then it's an event.
|
||||
if (!isDayHeader) {
|
||||
if (event.allDay) {
|
||||
agendaItem.id = cursor.getLong(AgendaWindowAdapter.INDEX_EVENT_ID);
|
||||
if (agendaItem.allDay) {
|
||||
Time time = new Time(mTimeZone);
|
||||
time.setJulianDay(Time.getJulianDay(event.end, 0));
|
||||
event.end = time.toMillis(false /* use isDst */);
|
||||
} else {
|
||||
event.end = cursor.getLong(AgendaWindowAdapter.INDEX_END);
|
||||
time.setJulianDay(Time.getJulianDay(agendaItem.end, 0));
|
||||
agendaItem.end = time.toMillis(false /* use isDst */);
|
||||
}
|
||||
|
||||
event.id = cursor.getLong(AgendaWindowAdapter.INDEX_EVENT_ID);
|
||||
}
|
||||
return event;
|
||||
return agendaItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that any all day events are converted to UTC before a VIEW_EVENT command is sent.
|
||||
*/
|
||||
private void sendViewEvent(AgendaItem item, long selectedTime) {
|
||||
long startTime;
|
||||
long endTime;
|
||||
if (item.allDay) {
|
||||
startTime = Utils.convertAlldayLocalToUTC(null, item.begin, mTimeZone);
|
||||
endTime = Utils.convertAlldayLocalToUTC(null, item.end, mTimeZone);
|
||||
} else {
|
||||
startTime = item.begin;
|
||||
endTime = item.end;
|
||||
}
|
||||
if (DEBUGLOG) {
|
||||
Log.d(TAG, "Sent (AgendaWindowAdapter): VIEW EVENT: " + new Date(startTime));
|
||||
}
|
||||
CalendarController.getInstance(mContext)
|
||||
.sendEventRelatedEventWithExtra(this, EventType.VIEW_EVENT,
|
||||
item.id, startTime, endTime, 0,
|
||||
0, CalendarController.EventInfo.buildViewExtraLong(
|
||||
Attendees.ATTENDEE_STATUS_NONE,
|
||||
item.allDay), selectedTime);
|
||||
}
|
||||
|
||||
public void refresh(Time goToTime, long id, String searchQuery, boolean forced,
|
||||
@ -670,7 +699,7 @@ public class AgendaWindowAdapter extends BaseAdapter
|
||||
|
||||
if (!forced && isInRange(startDay, startDay)) {
|
||||
// No need to re-query
|
||||
if (!mAgendaListView.isEventVisible(goToTime, id)) {
|
||||
if (!mAgendaListView.isAgendaItemVisible(goToTime, id)) {
|
||||
int gotoPosition = findEventPositionNearestTime(goToTime, id);
|
||||
if (gotoPosition > 0) {
|
||||
mAgendaListView.setSelectionFromTop(gotoPosition +
|
||||
@ -686,15 +715,12 @@ public class AgendaWindowAdapter extends BaseAdapter
|
||||
Cursor tempCursor = getCursorByPosition(gotoPosition);
|
||||
if (tempCursor != null) {
|
||||
int tempCursorPosition = getCursorPositionByPosition(gotoPosition);
|
||||
EventInfo event =
|
||||
buildEventInfoFromCursor(tempCursor, tempCursorPosition,
|
||||
AgendaItem item =
|
||||
buildAgendaItemFromCursor(tempCursor, tempCursorPosition,
|
||||
false);
|
||||
CalendarController.getInstance(mContext)
|
||||
.sendEventRelatedEventWithExtra(this, EventType.VIEW_EVENT,
|
||||
event.id, event.begin, event.end, 0,
|
||||
0, CalendarController.EventInfo.buildViewExtraLong(
|
||||
Attendees.ATTENDEE_STATUS_NONE,
|
||||
event.allDay), goToTime.toMillis(false));
|
||||
mSelectedVH = new AgendaAdapter.ViewHolder();
|
||||
mSelectedVH.allDay = item.allDay;
|
||||
sendViewEvent(item, goToTime.toMillis(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -831,7 +857,7 @@ public class AgendaWindowAdapter extends BaseAdapter
|
||||
private boolean queueQuery(int start, int end, Time goToTime,
|
||||
String searchQuery, int queryType, long id) {
|
||||
QuerySpec queryData = new QuerySpec(queryType);
|
||||
queryData.goToTime = goToTime;
|
||||
queryData.goToTime = new Time(goToTime); // Creates a new time reference per QuerySpec.
|
||||
queryData.start = start;
|
||||
queryData.end = end;
|
||||
queryData.searchQuery = searchQuery;
|
||||
@ -936,6 +962,9 @@ public class AgendaWindowAdapter extends BaseAdapter
|
||||
|
||||
@Override
|
||||
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
|
||||
if (DEBUGLOG) {
|
||||
Log.d(TAG, "(+)onQueryComplete");
|
||||
}
|
||||
QuerySpec data = (QuerySpec)cookie;
|
||||
|
||||
if (cursor == null) {
|
||||
@ -983,6 +1012,9 @@ public class AgendaWindowAdapter extends BaseAdapter
|
||||
mStickyHeaderSize);
|
||||
Time actualTime = new Time(mTimeZone);
|
||||
actualTime.set(goToTime);
|
||||
if (DEBUGLOG) {
|
||||
Log.d(TAG, "onQueryComplete: Updating title...");
|
||||
}
|
||||
CalendarController.getInstance(mContext).sendEvent(this,
|
||||
EventType.UPDATE_TITLE, actualTime, actualTime, -1,
|
||||
ViewType.CURRENT);
|
||||
@ -1044,14 +1076,13 @@ public class AgendaWindowAdapter extends BaseAdapter
|
||||
tempCursorPosition = getCursorPositionByPosition(newPosition);
|
||||
}
|
||||
if (tempCursor != null) {
|
||||
EventInfo event = buildEventInfoFromCursor(tempCursor, tempCursorPosition,
|
||||
AgendaItem item = buildAgendaItemFromCursor(tempCursor, tempCursorPosition,
|
||||
false);
|
||||
long selectedTime = findStartTimeFromPosition(newPosition);
|
||||
CalendarController.getInstance(mContext).sendEventRelatedEventWithExtra(
|
||||
this, EventType.VIEW_EVENT, event.id, event.begin,
|
||||
event.end, 0, 0, CalendarController.EventInfo.buildViewExtraLong(
|
||||
Attendees.ATTENDEE_STATUS_NONE, event.allDay),
|
||||
selectedTime);
|
||||
if (DEBUGLOG) {
|
||||
Log.d(TAG, "onQueryComplete: Sending View Event...");
|
||||
}
|
||||
sendViewEvent(item, selectedTime);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
322
src/com/android/calendar/alerts/AlarmScheduler.java
Normal file
@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.calendar.alerts;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.provider.CalendarContract;
|
||||
import android.provider.CalendarContract.Events;
|
||||
import android.provider.CalendarContract.Instances;
|
||||
import android.provider.CalendarContract.Reminders;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.format.Time;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.calendar.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Schedules the next EVENT_REMINDER_APP broadcast with AlarmManager, by querying the events
|
||||
* and reminders tables for the next upcoming alert.
|
||||
*/
|
||||
public class AlarmScheduler {
|
||||
private static final String TAG = "AlarmScheduler";
|
||||
|
||||
private static final String INSTANCES_WHERE = Events.VISIBLE + "=? AND "
|
||||
+ Instances.BEGIN + ">=? AND " + Instances.BEGIN + "<=? AND "
|
||||
+ Events.ALL_DAY + "=?";
|
||||
static final String[] INSTANCES_PROJECTION = new String[] {
|
||||
Instances.EVENT_ID,
|
||||
Instances.BEGIN,
|
||||
Instances.ALL_DAY,
|
||||
};
|
||||
private static final int INSTANCES_INDEX_EVENTID = 0;
|
||||
private static final int INSTANCES_INDEX_BEGIN = 1;
|
||||
private static final int INSTANCES_INDEX_ALL_DAY = 2;
|
||||
|
||||
private static final String REMINDERS_WHERE = Reminders.METHOD + "=1 AND "
|
||||
+ Reminders.EVENT_ID + " IN ";
|
||||
static final String[] REMINDERS_PROJECTION = new String[] {
|
||||
Reminders.EVENT_ID,
|
||||
Reminders.MINUTES,
|
||||
Reminders.METHOD,
|
||||
};
|
||||
private static final int REMINDERS_INDEX_EVENT_ID = 0;
|
||||
private static final int REMINDERS_INDEX_MINUTES = 1;
|
||||
private static final int REMINDERS_INDEX_METHOD = 2;
|
||||
|
||||
// Add a slight delay for the EVENT_REMINDER_APP broadcast for a couple reasons:
|
||||
// (1) so that the concurrent reminder broadcast from the provider doesn't result
|
||||
// in a double ring, and (2) some OEMs modified the provider to not add an alert to
|
||||
// the CalendarAlerts table until the alert time, so for the unbundled app's
|
||||
// notifications to work on these devices, a delay ensures that AlertService won't
|
||||
// read from the CalendarAlerts table until the alert is present.
|
||||
static final int ALARM_DELAY_MS = 1000;
|
||||
|
||||
// The reminders query looks like "SELECT ... AND eventId IN 101,102,202,...". This
|
||||
// sets the max # of events in the query before batching into multiple queries, to
|
||||
// limit the SQL query length.
|
||||
private static final int REMINDER_QUERY_BATCH_SIZE = 50;
|
||||
|
||||
// We really need to query for reminder times that fall in some interval, but
|
||||
// the Reminders table only stores the reminder interval (10min, 15min, etc), and
|
||||
// we cannot do the join with the Events table to calculate the actual alert time
|
||||
// from outside of the provider. So the best we can do for now consider events
|
||||
// whose start times begin within some interval (ie. 1 week out). This means
|
||||
// reminders which are configured for more than 1 week out won't fire on time. We
|
||||
// can minimize this to being only 1 day late by putting a 1 day max on the alarm time.
|
||||
private static final long EVENT_LOOKAHEAD_WINDOW_MS = DateUtils.WEEK_IN_MILLIS;
|
||||
private static final long MAX_ALARM_ELAPSED_MS = DateUtils.DAY_IN_MILLIS;
|
||||
|
||||
/**
|
||||
* Schedules the nearest upcoming alarm, to refresh notifications.
|
||||
*
|
||||
* This is historically done in the provider but we dupe this here so the unbundled
|
||||
* app will work on devices that have modified this portion of the provider. This
|
||||
* has the limitation of querying events within some interval from now (ie. looks at
|
||||
* reminders for all events occurring in the next week). This means for example,
|
||||
* a 2 week notification will not fire on time.
|
||||
*/
|
||||
public static void scheduleNextAlarm(Context context) {
|
||||
scheduleNextAlarm(context, AlertUtils.createAlarmManager(context),
|
||||
REMINDER_QUERY_BATCH_SIZE, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
// VisibleForTesting
|
||||
static void scheduleNextAlarm(Context context, AlarmManagerInterface alarmManager,
|
||||
int batchSize, long currentMillis) {
|
||||
Cursor instancesCursor = null;
|
||||
try {
|
||||
instancesCursor = queryUpcomingEvents(context, context.getContentResolver(),
|
||||
currentMillis);
|
||||
if (instancesCursor != null) {
|
||||
queryNextReminderAndSchedule(instancesCursor, context,
|
||||
context.getContentResolver(), alarmManager, batchSize, currentMillis);
|
||||
}
|
||||
} finally {
|
||||
if (instancesCursor != null) {
|
||||
instancesCursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries events starting within a fixed interval from now.
|
||||
*/
|
||||
private static Cursor queryUpcomingEvents(Context context, ContentResolver contentResolver,
|
||||
long currentMillis) {
|
||||
Time time = new Time();
|
||||
time.normalize(false);
|
||||
long localOffset = time.gmtoff * 1000;
|
||||
final long localStartMin = currentMillis;
|
||||
final long localStartMax = localStartMin + EVENT_LOOKAHEAD_WINDOW_MS;
|
||||
final long utcStartMin = localStartMin - localOffset;
|
||||
final long utcStartMax = utcStartMin + EVENT_LOOKAHEAD_WINDOW_MS;
|
||||
|
||||
// Expand Instances table range by a day on either end to account for
|
||||
// all-day events.
|
||||
Uri.Builder uriBuilder = Instances.CONTENT_URI.buildUpon();
|
||||
ContentUris.appendId(uriBuilder, localStartMin - DateUtils.DAY_IN_MILLIS);
|
||||
ContentUris.appendId(uriBuilder, localStartMax + DateUtils.DAY_IN_MILLIS);
|
||||
|
||||
// Build query for all events starting within the fixed interval.
|
||||
StringBuilder queryBuilder = new StringBuilder();
|
||||
queryBuilder.append("(");
|
||||
queryBuilder.append(INSTANCES_WHERE);
|
||||
queryBuilder.append(") OR (");
|
||||
queryBuilder.append(INSTANCES_WHERE);
|
||||
queryBuilder.append(")");
|
||||
String[] queryArgs = new String[] {
|
||||
// allday selection
|
||||
"1", /* visible = ? */
|
||||
String.valueOf(utcStartMin), /* begin >= ? */
|
||||
String.valueOf(utcStartMax), /* begin <= ? */
|
||||
"1", /* allDay = ? */
|
||||
|
||||
// non-allday selection
|
||||
"1", /* visible = ? */
|
||||
String.valueOf(localStartMin), /* begin >= ? */
|
||||
String.valueOf(localStartMax), /* begin <= ? */
|
||||
"0" /* allDay = ? */
|
||||
};
|
||||
|
||||
Cursor cursor = contentResolver.query(uriBuilder.build(), INSTANCES_PROJECTION,
|
||||
queryBuilder.toString(), queryArgs, null);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries for all the reminders of the events in the instancesCursor, and schedules
|
||||
* the alarm for the next upcoming reminder.
|
||||
*/
|
||||
private static void queryNextReminderAndSchedule(Cursor instancesCursor, Context context,
|
||||
ContentResolver contentResolver, AlarmManagerInterface alarmManager,
|
||||
int batchSize, long currentMillis) {
|
||||
if (AlertService.DEBUG) {
|
||||
int eventCount = instancesCursor.getCount();
|
||||
if (eventCount == 0) {
|
||||
Log.d(TAG, "No events found starting within 1 week.");
|
||||
} else {
|
||||
Log.d(TAG, "Query result count for events starting within 1 week: " + eventCount);
|
||||
}
|
||||
}
|
||||
|
||||
// Put query results of all events starting within some interval into map of event ID to
|
||||
// local start time.
|
||||
Map<Integer, List<Long>> eventMap = new HashMap<Integer, List<Long>>();
|
||||
Time timeObj = new Time();
|
||||
long nextAlarmTime = Long.MAX_VALUE;
|
||||
int nextAlarmEventId = 0;
|
||||
instancesCursor.moveToPosition(-1);
|
||||
while (!instancesCursor.isAfterLast()) {
|
||||
int index = 0;
|
||||
eventMap.clear();
|
||||
StringBuilder eventIdsForQuery = new StringBuilder();
|
||||
eventIdsForQuery.append('(');
|
||||
while (index++ < batchSize && instancesCursor.moveToNext()) {
|
||||
int eventId = instancesCursor.getInt(INSTANCES_INDEX_EVENTID);
|
||||
long begin = instancesCursor.getLong(INSTANCES_INDEX_BEGIN);
|
||||
boolean allday = instancesCursor.getInt(INSTANCES_INDEX_ALL_DAY) != 0;
|
||||
long localStartTime;
|
||||
if (allday) {
|
||||
// Adjust allday to local time.
|
||||
localStartTime = Utils.convertAlldayUtcToLocal(timeObj, begin,
|
||||
Time.getCurrentTimezone());
|
||||
} else {
|
||||
localStartTime = begin;
|
||||
}
|
||||
List<Long> startTimes = eventMap.get(eventId);
|
||||
if (startTimes == null) {
|
||||
startTimes = new ArrayList<Long>();
|
||||
eventMap.put(eventId, startTimes);
|
||||
eventIdsForQuery.append(eventId);
|
||||
eventIdsForQuery.append(",");
|
||||
}
|
||||
startTimes.add(localStartTime);
|
||||
|
||||
// Log for debugging.
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
timeObj.set(localStartTime);
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("Events cursor result -- eventId:").append(eventId);
|
||||
msg.append(", allDay:").append(allday);
|
||||
msg.append(", start:").append(localStartTime);
|
||||
msg.append(" (").append(timeObj.format("%a, %b %d, %Y %I:%M%P")).append(")");
|
||||
Log.d(TAG, msg.toString());
|
||||
}
|
||||
}
|
||||
if (eventIdsForQuery.charAt(eventIdsForQuery.length() - 1) == ',') {
|
||||
eventIdsForQuery.deleteCharAt(eventIdsForQuery.length() - 1);
|
||||
}
|
||||
eventIdsForQuery.append(')');
|
||||
|
||||
// Query the reminders table for the events found.
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = contentResolver.query(Reminders.CONTENT_URI, REMINDERS_PROJECTION,
|
||||
REMINDERS_WHERE + eventIdsForQuery, null, null);
|
||||
|
||||
// Process the reminders query results to find the next reminder time.
|
||||
cursor.moveToPosition(-1);
|
||||
while (cursor.moveToNext()) {
|
||||
int eventId = cursor.getInt(REMINDERS_INDEX_EVENT_ID);
|
||||
int reminderMinutes = cursor.getInt(REMINDERS_INDEX_MINUTES);
|
||||
List<Long> startTimes = eventMap.get(eventId);
|
||||
if (startTimes != null) {
|
||||
for (Long startTime : startTimes) {
|
||||
long alarmTime = startTime -
|
||||
reminderMinutes * DateUtils.MINUTE_IN_MILLIS;
|
||||
if (alarmTime > currentMillis && alarmTime < nextAlarmTime) {
|
||||
nextAlarmTime = alarmTime;
|
||||
nextAlarmEventId = eventId;
|
||||
}
|
||||
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
timeObj.set(alarmTime);
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("Reminders cursor result -- eventId:").append(eventId);
|
||||
msg.append(", startTime:").append(startTime);
|
||||
msg.append(", minutes:").append(reminderMinutes);
|
||||
msg.append(", alarmTime:").append(alarmTime);
|
||||
msg.append(" (").append(timeObj.format("%a, %b %d, %Y %I:%M%P"))
|
||||
.append(")");
|
||||
Log.d(TAG, msg.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Schedule the alarm for the next reminder time.
|
||||
if (nextAlarmTime < Long.MAX_VALUE) {
|
||||
scheduleAlarm(context, nextAlarmEventId, nextAlarmTime, currentMillis, alarmManager);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules an alarm for the EVENT_REMINDER_APP broadcast, for the specified
|
||||
* alarm time with a slight delay (to account for the possible duplicate broadcast
|
||||
* from the provider).
|
||||
*/
|
||||
private static void scheduleAlarm(Context context, long eventId, long alarmTime,
|
||||
long currentMillis, AlarmManagerInterface alarmManager) {
|
||||
// Max out the alarm time to 1 day out, so an alert for an event far in the future
|
||||
// (not present in our event query results for a limited range) can only be at
|
||||
// most 1 day late.
|
||||
long maxAlarmTime = currentMillis + MAX_ALARM_ELAPSED_MS;
|
||||
if (alarmTime > maxAlarmTime) {
|
||||
alarmTime = maxAlarmTime;
|
||||
}
|
||||
|
||||
// Add a slight delay (see comments on the member var).
|
||||
alarmTime += ALARM_DELAY_MS;
|
||||
|
||||
if (AlertService.DEBUG) {
|
||||
Time time = new Time();
|
||||
time.set(alarmTime);
|
||||
String schedTime = time.format("%a, %b %d, %Y %I:%M%P");
|
||||
Log.d(TAG, "Scheduling alarm for EVENT_REMINDER_APP broadcast for event " + eventId
|
||||
+ " at " + alarmTime + " (" + schedTime + ")");
|
||||
}
|
||||
|
||||
// Schedule an EVENT_REMINDER_APP broadcast with AlarmManager. The extra is
|
||||
// only used by AlertService for logging. It is ignored by Intent.filterEquals,
|
||||
// so this scheduling will still overwrite the alarm that was previously pending.
|
||||
// Note that the 'setClass' is required, because otherwise it seems the broadcast
|
||||
// can be eaten by other apps and we somehow may never receive it.
|
||||
Intent intent = new Intent(AlertReceiver.EVENT_REMINDER_APP_ACTION);
|
||||
intent.setClass(context, AlertReceiver.class);
|
||||
intent.putExtra(CalendarContract.CalendarAlerts.ALARM_TIME, alarmTime);
|
||||
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
|
||||
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, pi);
|
||||
}
|
||||
}
|
@ -43,7 +43,7 @@ public class AlertAdapter extends ResourceCursorAdapter {
|
||||
|
||||
public AlertAdapter(AlertActivity activity, int resource) {
|
||||
super(activity, resource, null);
|
||||
this.alertActivity = activity;
|
||||
alertActivity = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,10 +32,13 @@ import android.os.PowerManager;
|
||||
import android.provider.CalendarContract.Attendees;
|
||||
import android.provider.CalendarContract.Calendars;
|
||||
import android.provider.CalendarContract.Events;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.text.style.TextAppearanceSpan;
|
||||
import android.text.style.URLSpan;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
@ -66,9 +69,16 @@ public class AlertReceiver extends BroadcastReceiver {
|
||||
private static final String TAG = "AlertReceiver";
|
||||
|
||||
private static final String DELETE_ALL_ACTION = "com.android.calendar.DELETEALL";
|
||||
private static final String MAP_ACTION = "com.android.calendar.MAP";
|
||||
private static final String CALL_ACTION = "com.android.calendar.CALL";
|
||||
private static final String MAIL_ACTION = "com.android.calendar.MAIL";
|
||||
private static final String EXTRA_EVENT_ID = "eventid";
|
||||
|
||||
// The broadcast for notification refreshes scheduled by the app. This is to
|
||||
// distinguish the EVENT_REMINDER broadcast sent by the provider.
|
||||
public static final String EVENT_REMINDER_APP_ACTION =
|
||||
"com.android.calendar.EVENT_REMINDER_APP";
|
||||
|
||||
static final Object mStartingServiceSync = new Object();
|
||||
static PowerManager.WakeLock mStartingService;
|
||||
private static final Pattern mBlankLinePattern = Pattern.compile("^\\s*$[\n\r]",
|
||||
@ -77,6 +87,10 @@ public class AlertReceiver extends BroadcastReceiver {
|
||||
public static final String ACTION_DISMISS_OLD_REMINDERS = "removeOldReminders";
|
||||
private static final int NOTIFICATION_DIGEST_MAX_LENGTH = 3;
|
||||
|
||||
private static final String GEO_PREFIX = "geo:";
|
||||
private static final String TEL_PREFIX = "tel:";
|
||||
private static final int MAX_NOTIF_ACTIONS = 3;
|
||||
|
||||
private static Handler sAsyncHandler;
|
||||
static {
|
||||
HandlerThread thr = new HandlerThread("AlertReceiver async");
|
||||
@ -97,10 +111,46 @@ public class AlertReceiver extends BroadcastReceiver {
|
||||
// TODO Grab a wake lock here?
|
||||
Intent serviceIntent = new Intent(context, DismissAlarmsService.class);
|
||||
context.startService(serviceIntent);
|
||||
} else if (MAP_ACTION.equals(intent.getAction())) {
|
||||
// Try starting the map action.
|
||||
// If no map location is found (something changed since the notification was originally
|
||||
// fired), update the notifications to express this change.
|
||||
final long eventId = intent.getLongExtra(EXTRA_EVENT_ID, -1);
|
||||
if (eventId != -1) {
|
||||
URLSpan[] urlSpans = getURLSpans(context, eventId);
|
||||
Intent geoIntent = createMapActivityIntent(context, urlSpans);
|
||||
if (geoIntent != null) {
|
||||
// Location was successfully found, so dismiss the shade and start maps.
|
||||
context.startActivity(geoIntent);
|
||||
closeNotificationShade(context);
|
||||
} else {
|
||||
// No location was found, so update all notifications.
|
||||
// Our alert service does not currently allow us to specify only one
|
||||
// specific notification to refresh.
|
||||
AlertService.updateAlertNotification(context);
|
||||
}
|
||||
}
|
||||
} else if (CALL_ACTION.equals(intent.getAction())) {
|
||||
// Try starting the call action.
|
||||
// If no call location is found (something changed since the notification was originally
|
||||
// fired), update the notifications to express this change.
|
||||
final long eventId = intent.getLongExtra(EXTRA_EVENT_ID, -1);
|
||||
if (eventId != -1) {
|
||||
URLSpan[] urlSpans = getURLSpans(context, eventId);
|
||||
Intent callIntent = createCallActivityIntent(context, urlSpans);
|
||||
if (callIntent != null) {
|
||||
// Call location was successfully found, so dismiss the shade and start dialer.
|
||||
context.startActivity(callIntent);
|
||||
closeNotificationShade(context);
|
||||
} else {
|
||||
// No call location was found, so update all notifications.
|
||||
// Our alert service does not currently allow us to specify only one
|
||||
// specific notification to refresh.
|
||||
AlertService.updateAlertNotification(context);
|
||||
}
|
||||
}
|
||||
} else if (MAIL_ACTION.equals(intent.getAction())) {
|
||||
// Close the notification shade.
|
||||
Intent closeNotificationShadeIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
|
||||
context.sendBroadcast(closeNotificationShadeIntent);
|
||||
closeNotificationShade(context);
|
||||
|
||||
// Now start the email intent.
|
||||
final long eventId = intent.getLongExtra(EXTRA_EVENT_ID, -1);
|
||||
@ -254,15 +304,24 @@ public class AlertReceiver extends BroadcastReceiver {
|
||||
notificationBuilder.setFullScreenIntent(createAlertActivityIntent(context), true);
|
||||
}
|
||||
|
||||
PendingIntent snoozeIntent = null;
|
||||
PendingIntent emailIntent = null;
|
||||
PendingIntent mapIntent = null, callIntent = null, snoozeIntent = null, emailIntent = null;
|
||||
if (addActionButtons) {
|
||||
// Create snooze intent. TODO: change snooze to 10 minutes.
|
||||
snoozeIntent = createSnoozeIntent(context, eventId, startMillis, endMillis,
|
||||
notificationId);
|
||||
// Send map, call, and email intent back to ourself first for a couple reasons:
|
||||
// 1) Workaround issue where clicking action button in notification does
|
||||
// not automatically close the notification shade.
|
||||
// 2) Event information will always be up to date.
|
||||
|
||||
// Create map and/or call intents.
|
||||
URLSpan[] urlSpans = getURLSpans(context, eventId);
|
||||
mapIntent = createMapBroadcastIntent(context, urlSpans, eventId);
|
||||
callIntent = createCallBroadcastIntent(context, urlSpans, eventId);
|
||||
|
||||
// Create email intent for emailing attendees.
|
||||
emailIntent = createBroadcastMailIntent(context, eventId, title);
|
||||
|
||||
// Create snooze intent. TODO: change snooze to 10 minutes.
|
||||
snoozeIntent = createSnoozeIntent(context, eventId, startMillis, endMillis,
|
||||
notificationId);
|
||||
}
|
||||
|
||||
if (Utils.isJellybeanOrLater()) {
|
||||
@ -273,14 +332,34 @@ public class AlertReceiver extends BroadcastReceiver {
|
||||
// A higher priority will encourage notification manager to expand it.
|
||||
notificationBuilder.setPriority(priority);
|
||||
|
||||
// Add action buttons.
|
||||
if (snoozeIntent != null) {
|
||||
notificationBuilder.addAction(R.drawable.ic_alarm_holo_dark,
|
||||
resources.getString(R.string.snooze_label), snoozeIntent);
|
||||
// Add action buttons. Show at most three, using the following priority ordering:
|
||||
// 1. Map
|
||||
// 2. Call
|
||||
// 3. Email
|
||||
// 4. Snooze
|
||||
// Actions will only be shown if they are applicable; i.e. with no location, map will
|
||||
// not be shown, and with no recipients, snooze will not be shown.
|
||||
// TODO: Get icons, get strings. Maybe show preview of actual location/number?
|
||||
int numActions = 0;
|
||||
if (mapIntent != null && numActions < MAX_NOTIF_ACTIONS) {
|
||||
notificationBuilder.addAction(R.drawable.ic_map,
|
||||
resources.getString(R.string.map_label), mapIntent);
|
||||
numActions++;
|
||||
}
|
||||
if (emailIntent != null) {
|
||||
if (callIntent != null && numActions < MAX_NOTIF_ACTIONS) {
|
||||
notificationBuilder.addAction(R.drawable.ic_call,
|
||||
resources.getString(R.string.call_label), callIntent);
|
||||
numActions++;
|
||||
}
|
||||
if (emailIntent != null && numActions < MAX_NOTIF_ACTIONS) {
|
||||
notificationBuilder.addAction(R.drawable.ic_menu_email_holo_dark,
|
||||
resources.getString(R.string.email_guests_label), emailIntent);
|
||||
numActions++;
|
||||
}
|
||||
if (snoozeIntent != null && numActions < MAX_NOTIF_ACTIONS) {
|
||||
notificationBuilder.addAction(R.drawable.ic_alarm_holo_dark,
|
||||
resources.getString(R.string.snooze_label), snoozeIntent);
|
||||
numActions++;
|
||||
}
|
||||
return notificationBuilder.getNotification();
|
||||
|
||||
@ -295,20 +374,41 @@ public class AlertReceiver extends BroadcastReceiver {
|
||||
contentView.setImageViewResource(R.id.image, R.drawable.stat_notify_calendar);
|
||||
contentView.setTextViewText(R.id.title, title);
|
||||
contentView.setTextViewText(R.id.text, summaryText);
|
||||
if (snoozeIntent == null) {
|
||||
contentView.setViewVisibility(R.id.email_button, View.GONE);
|
||||
|
||||
int numActions = 0;
|
||||
if (mapIntent == null || numActions >= MAX_NOTIF_ACTIONS) {
|
||||
contentView.setViewVisibility(R.id.map_button, View.GONE);
|
||||
} else {
|
||||
contentView.setViewVisibility(R.id.snooze_button, View.VISIBLE);
|
||||
contentView.setOnClickPendingIntent(R.id.snooze_button, snoozeIntent);
|
||||
contentView.setViewVisibility(R.id.map_button, View.VISIBLE);
|
||||
contentView.setOnClickPendingIntent(R.id.map_button, mapIntent);
|
||||
contentView.setViewVisibility(R.id.end_padding, View.GONE);
|
||||
numActions++;
|
||||
}
|
||||
if (emailIntent == null) {
|
||||
if (callIntent == null || numActions >= MAX_NOTIF_ACTIONS) {
|
||||
contentView.setViewVisibility(R.id.call_button, View.GONE);
|
||||
} else {
|
||||
contentView.setViewVisibility(R.id.call_button, View.VISIBLE);
|
||||
contentView.setOnClickPendingIntent(R.id.call_button, callIntent);
|
||||
contentView.setViewVisibility(R.id.end_padding, View.GONE);
|
||||
numActions++;
|
||||
}
|
||||
if (emailIntent == null || numActions >= MAX_NOTIF_ACTIONS) {
|
||||
contentView.setViewVisibility(R.id.email_button, View.GONE);
|
||||
} else {
|
||||
contentView.setViewVisibility(R.id.email_button, View.VISIBLE);
|
||||
contentView.setOnClickPendingIntent(R.id.email_button, emailIntent);
|
||||
contentView.setViewVisibility(R.id.end_padding, View.GONE);
|
||||
numActions++;
|
||||
}
|
||||
if (snoozeIntent == null || numActions >= MAX_NOTIF_ACTIONS) {
|
||||
contentView.setViewVisibility(R.id.snooze_button, View.GONE);
|
||||
} else {
|
||||
contentView.setViewVisibility(R.id.snooze_button, View.VISIBLE);
|
||||
contentView.setOnClickPendingIntent(R.id.snooze_button, snoozeIntent);
|
||||
contentView.setViewVisibility(R.id.end_padding, View.GONE);
|
||||
numActions++;
|
||||
}
|
||||
|
||||
n.contentView = contentView;
|
||||
|
||||
return n;
|
||||
@ -466,6 +566,8 @@ public class AlertReceiver extends BroadcastReceiver {
|
||||
contentView.setTextViewText(R.id.title, nEventsStr);
|
||||
contentView.setTextViewText(R.id.text, digestTitle);
|
||||
contentView.setViewVisibility(R.id.time, View.VISIBLE);
|
||||
contentView.setViewVisibility(R.id.map_button, View.GONE);
|
||||
contentView.setViewVisibility(R.id.call_button, View.GONE);
|
||||
contentView.setViewVisibility(R.id.email_button, View.GONE);
|
||||
contentView.setViewVisibility(R.id.snooze_button, View.GONE);
|
||||
contentView.setViewVisibility(R.id.end_padding, View.VISIBLE);
|
||||
@ -486,6 +588,11 @@ public class AlertReceiver extends BroadcastReceiver {
|
||||
return nw;
|
||||
}
|
||||
|
||||
private void closeNotificationShade(Context context) {
|
||||
Intent closeNotificationShadeIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
|
||||
context.sendBroadcast(closeNotificationShadeIntent);
|
||||
}
|
||||
|
||||
private static final String[] ATTENDEES_PROJECTION = new String[] {
|
||||
Attendees.ATTENDEE_EMAIL, // 0
|
||||
Attendees.ATTENDEE_STATUS, // 1
|
||||
@ -519,6 +626,12 @@ public class AlertReceiver extends BroadcastReceiver {
|
||||
ATTENDEES_SORT_ORDER);
|
||||
}
|
||||
|
||||
private static Cursor getLocationCursor(Context context, long eventId) {
|
||||
return context.getContentResolver().query(
|
||||
ContentUris.withAppendedId(Events.CONTENT_URI, eventId),
|
||||
new String[] { Events.EVENT_LOCATION }, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a broadcast pending intent that fires to AlertReceiver when the email button
|
||||
* is clicked.
|
||||
@ -545,10 +658,6 @@ public class AlertReceiver extends BroadcastReceiver {
|
||||
do {
|
||||
String email = attendeesCursor.getString(ATTENDEES_INDEX_EMAIL);
|
||||
if (Utils.isEmailableFrom(email, syncAccount)) {
|
||||
// Send intent back to ourself first for a couple reasons:
|
||||
// 1) Workaround issue where clicking action button in notification does
|
||||
// not automatically close the notification shade.
|
||||
// 2) Attendees list in email will always be up to date.
|
||||
Intent broadcastIntent = new Intent(MAIL_ACTION);
|
||||
broadcastIntent.setClass(context, AlertReceiver.class);
|
||||
broadcastIntent.putExtra(EXTRA_EVENT_ID, eventId);
|
||||
@ -647,4 +756,130 @@ public class AlertReceiver extends BroadcastReceiver {
|
||||
emailList.add(email);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Using the linkify magic, get a list of URLs from the event's location. If no such links
|
||||
* are found, we should end up with a single geo link of the entire string.
|
||||
*/
|
||||
private static URLSpan[] getURLSpans(Context context, long eventId) {
|
||||
Cursor locationCursor = getLocationCursor(context, eventId);
|
||||
if (locationCursor != null && locationCursor.moveToFirst()) {
|
||||
String location = locationCursor.getString(0); // Only one item in this cursor.
|
||||
if (location == null || location.isEmpty()) {
|
||||
// Return an empty list if we know there was nothing in the location field.
|
||||
return new URLSpan[0];
|
||||
}
|
||||
|
||||
Spannable text = Utils.extendedLinkify(location, true);
|
||||
|
||||
// The linkify method should have found at least one link, at the very least.
|
||||
// If no smart links were found, it should have set the whole string as a geo link.
|
||||
URLSpan[] urlSpans = text.getSpans(0, text.length(), URLSpan.class);
|
||||
return urlSpans;
|
||||
}
|
||||
|
||||
// If no links were found or location was empty, return an empty list.
|
||||
return new URLSpan[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a pending intent to send ourself a broadcast to start maps, using the first map
|
||||
* link available.
|
||||
* If no links are found, return null.
|
||||
*/
|
||||
private static PendingIntent createMapBroadcastIntent(Context context, URLSpan[] urlSpans,
|
||||
long eventId) {
|
||||
for (int span_i = 0; span_i < urlSpans.length; span_i++) {
|
||||
URLSpan urlSpan = urlSpans[span_i];
|
||||
String urlString = urlSpan.getURL();
|
||||
if (urlString.startsWith(GEO_PREFIX)) {
|
||||
Intent broadcastIntent = new Intent(MAP_ACTION);
|
||||
broadcastIntent.setClass(context, AlertReceiver.class);
|
||||
broadcastIntent.putExtra(EXTRA_EVENT_ID, eventId);
|
||||
return PendingIntent.getBroadcast(context,
|
||||
Long.valueOf(eventId).hashCode(), broadcastIntent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
}
|
||||
}
|
||||
|
||||
// No geo link was found, so return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an intent to take the user to maps, using the first map link available.
|
||||
* If no links are found, return null.
|
||||
*/
|
||||
private static Intent createMapActivityIntent(Context context, URLSpan[] urlSpans) {
|
||||
for (int span_i = 0; span_i < urlSpans.length; span_i++) {
|
||||
URLSpan urlSpan = urlSpans[span_i];
|
||||
String urlString = urlSpan.getURL();
|
||||
if (urlString.startsWith(GEO_PREFIX)) {
|
||||
Intent geoIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(urlString));
|
||||
geoIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
return geoIntent;
|
||||
}
|
||||
}
|
||||
|
||||
// No geo link was found, so return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a pending intent to send ourself a broadcast to take the user to dialer, or any other
|
||||
* app capable of making phone calls. Use the first phone number available. If no phone number
|
||||
* is found, or if the device is not capable of making phone calls (i.e. a tablet), return null.
|
||||
*/
|
||||
private static PendingIntent createCallBroadcastIntent(Context context, URLSpan[] urlSpans,
|
||||
long eventId) {
|
||||
// Return null if the device is unable to make phone calls.
|
||||
TelephonyManager tm =
|
||||
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int span_i = 0; span_i < urlSpans.length; span_i++) {
|
||||
URLSpan urlSpan = urlSpans[span_i];
|
||||
String urlString = urlSpan.getURL();
|
||||
if (urlString.startsWith(TEL_PREFIX)) {
|
||||
Intent broadcastIntent = new Intent(CALL_ACTION);
|
||||
broadcastIntent.setClass(context, AlertReceiver.class);
|
||||
broadcastIntent.putExtra(EXTRA_EVENT_ID, eventId);
|
||||
return PendingIntent.getBroadcast(context,
|
||||
Long.valueOf(eventId).hashCode(), broadcastIntent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
}
|
||||
}
|
||||
|
||||
// No tel link was found, so return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an intent to take the user to dialer, or any other app capable of making phone calls.
|
||||
* Use the first phone number available. If no phone number is found, or if the device is
|
||||
* not capable of making phone calls (i.e. a tablet), return null.
|
||||
*/
|
||||
private static Intent createCallActivityIntent(Context context, URLSpan[] urlSpans) {
|
||||
// Return null if the device is unable to make phone calls.
|
||||
TelephonyManager tm =
|
||||
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int span_i = 0; span_i < urlSpans.length; span_i++) {
|
||||
URLSpan urlSpan = urlSpans[span_i];
|
||||
String urlString = urlSpan.getURL();
|
||||
if (urlString.startsWith(TEL_PREFIX)) {
|
||||
Intent callIntent = new Intent(Intent.ACTION_DIAL, Uri.parse(urlString));
|
||||
callIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
return callIntent;
|
||||
}
|
||||
}
|
||||
|
||||
// No tel link was found, so return null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -109,6 +109,15 @@ public class AlertService extends Service {
|
||||
// Hard limit to the number of notifications displayed.
|
||||
public static final int MAX_NOTIFICATIONS = 20;
|
||||
|
||||
// Shared prefs key for storing whether the EVENT_REMINDER event from the provider
|
||||
// was ever received. Some OEMs modified this provider broadcast, so we had to
|
||||
// do the alarm scheduling here in the app, for the unbundled app's reminders to work.
|
||||
// If the EVENT_REMINDER event was ever received, we know we can skip our secondary
|
||||
// alarm scheduling.
|
||||
private static final String PROVIDER_REMINDER_PREF_KEY =
|
||||
"preference_received_provider_reminder_broadcast";
|
||||
private static Boolean sReceivedProviderReminderBroadcast = null;
|
||||
|
||||
// Added wrapper for testing
|
||||
public static class NotificationWrapper {
|
||||
Notification mNotification;
|
||||
@ -170,9 +179,41 @@ public class AlertService extends Service {
|
||||
+ " Action = " + action);
|
||||
}
|
||||
|
||||
if (action.equals(Intent.ACTION_PROVIDER_CHANGED) ||
|
||||
// Some OEMs had changed the provider's EVENT_REMINDER broadcast to their own event,
|
||||
// which broke our unbundled app's reminders. So we added backup alarm scheduling to the
|
||||
// app, but we know we can turn it off if we ever receive the EVENT_REMINDER broadcast.
|
||||
boolean providerReminder = action.equals(
|
||||
android.provider.CalendarContract.ACTION_EVENT_REMINDER);
|
||||
if (providerReminder) {
|
||||
if (sReceivedProviderReminderBroadcast == null) {
|
||||
sReceivedProviderReminderBroadcast = Utils.getSharedPreference(this,
|
||||
PROVIDER_REMINDER_PREF_KEY, false);
|
||||
}
|
||||
|
||||
if (!sReceivedProviderReminderBroadcast) {
|
||||
sReceivedProviderReminderBroadcast = true;
|
||||
Log.d(TAG, "Setting key " + PROVIDER_REMINDER_PREF_KEY + " to: true");
|
||||
Utils.setSharedPreference(this, PROVIDER_REMINDER_PREF_KEY, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (providerReminder ||
|
||||
action.equals(Intent.ACTION_PROVIDER_CHANGED) ||
|
||||
action.equals(android.provider.CalendarContract.ACTION_EVENT_REMINDER) ||
|
||||
action.equals(AlertReceiver.EVENT_REMINDER_APP_ACTION) ||
|
||||
action.equals(Intent.ACTION_LOCALE_CHANGED)) {
|
||||
|
||||
// b/7652098: Add a delay after the provider-changed event before refreshing
|
||||
// notifications to help issue with the unbundled app installed on HTC having
|
||||
// stale notifications.
|
||||
if (action.equals(Intent.ACTION_PROVIDER_CHANGED)) {
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (Exception e) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
|
||||
updateAlertNotification(this);
|
||||
} else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
|
||||
// The provider usually initiates this setting up of alarms on startup,
|
||||
@ -193,6 +234,13 @@ public class AlertService extends Service {
|
||||
} else {
|
||||
Log.w(TAG, "Invalid action: " + action);
|
||||
}
|
||||
|
||||
// Schedule the alarm for the next upcoming reminder, if not done by the provider.
|
||||
if (sReceivedProviderReminderBroadcast == null || !sReceivedProviderReminderBroadcast) {
|
||||
Log.d(TAG, "Scheduling next alarm with AlarmScheduler. "
|
||||
+ "sEventReminderReceived: " + sReceivedProviderReminderBroadcast);
|
||||
AlarmScheduler.scheduleNextAlarm(this);
|
||||
}
|
||||
}
|
||||
|
||||
static void dismissOldAlerts(Context context) {
|
||||
@ -331,7 +379,8 @@ public class AlertService extends Service {
|
||||
// Add options for a quiet update.
|
||||
addNotificationOptions(notification, true, expiredDigestTitle,
|
||||
notificationPrefs.getDefaultVibrate(),
|
||||
notificationPrefs.getRingtoneAndSilence());
|
||||
notificationPrefs.getRingtoneAndSilence(),
|
||||
false); /* Do not show the LED for the expired events. */
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Quietly posting digest alarm notification, numEvents:" + numLowPriority
|
||||
@ -725,7 +774,8 @@ public class AlertService extends Service {
|
||||
ringtone = prefs.getRingtoneAndSilence();
|
||||
}
|
||||
addNotificationOptions(notification, quietUpdate, tickerText,
|
||||
prefs.getDefaultVibrate(), ringtone);
|
||||
prefs.getDefaultVibrate(), ringtone,
|
||||
true); /* Show the LED for these non-expired events */
|
||||
|
||||
// Post the notification.
|
||||
notificationMgr.notify(notificationId, notification);
|
||||
@ -770,10 +820,13 @@ public class AlertService extends Service {
|
||||
}
|
||||
|
||||
private static void addNotificationOptions(NotificationWrapper nw, boolean quietUpdate,
|
||||
String tickerText, boolean defaultVibrate, String reminderRingtone) {
|
||||
String tickerText, boolean defaultVibrate, String reminderRingtone,
|
||||
boolean showLights) {
|
||||
Notification notification = nw.mNotification;
|
||||
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
|
||||
notification.defaults |= Notification.DEFAULT_LIGHTS;
|
||||
if (showLights) {
|
||||
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
|
||||
notification.defaults |= Notification.DEFAULT_LIGHTS;
|
||||
}
|
||||
|
||||
// Quietly update notification bar. Nothing new. Maybe something just got deleted.
|
||||
if (!quietUpdate) {
|
||||
|
@ -98,7 +98,7 @@ public class AlertUtils {
|
||||
* listeners when a reminder should be fired. The provider will keep
|
||||
* scheduled reminders up to date but apps may use this to implement snooze
|
||||
* functionality without modifying the reminders table. Scheduled alarms
|
||||
* will generate an intent using {@link #ACTION_EVENT_REMINDER}.
|
||||
* will generate an intent using AlertReceiver.EVENT_REMINDER_APP_ACTION.
|
||||
*
|
||||
* @param context A context for referencing system resources
|
||||
* @param manager The AlarmManager to use or null
|
||||
@ -121,7 +121,7 @@ public class AlertUtils {
|
||||
private static void scheduleAlarmHelper(Context context, AlarmManagerInterface manager,
|
||||
long alarmTime, boolean quietUpdate) {
|
||||
int alarmType = AlarmManager.RTC_WAKEUP;
|
||||
Intent intent = new Intent(CalendarContract.ACTION_EVENT_REMINDER);
|
||||
Intent intent = new Intent(AlertReceiver.EVENT_REMINDER_APP_ACTION);
|
||||
intent.setClass(context, AlertReceiver.class);
|
||||
if (quietUpdate) {
|
||||
alarmType = AlarmManager.RTC;
|
||||
@ -154,7 +154,7 @@ public class AlertUtils {
|
||||
time.setToNow();
|
||||
int today = Time.getJulianDay(time.toMillis(false), time.gmtoff);
|
||||
time.set(startMillis);
|
||||
int eventDay = Time.getJulianDay(time.toMillis(false), time.gmtoff);
|
||||
int eventDay = Time.getJulianDay(time.toMillis(false), allDay ? 0 : time.gmtoff);
|
||||
|
||||
int flags = DateUtils.FORMAT_ABBREV_ALL;
|
||||
if (!allDay) {
|
||||
|
315
src/com/android/calendar/event/CreateEventDialogFragment.java
Normal file
@ -0,0 +1,315 @@
|
||||
/* Copyright (C) 2012 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.calendar.event;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.provider.CalendarContract;
|
||||
import android.provider.CalendarContract.Calendars;
|
||||
import android.provider.Settings;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.format.Time;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.calendar.AsyncQueryService;
|
||||
import com.android.calendar.CalendarController;
|
||||
import com.android.calendar.CalendarController.EventType;
|
||||
import com.android.calendar.CalendarEventModel;
|
||||
import com.android.calendar.GeneralPreferences;
|
||||
import com.android.calendar.R;
|
||||
import com.android.calendar.Utils;
|
||||
|
||||
|
||||
/**
|
||||
* Allows the user to quickly create a new all-day event from the calendar's month view.
|
||||
*/
|
||||
public class CreateEventDialogFragment extends DialogFragment implements TextWatcher {
|
||||
|
||||
private static final int TOKEN_CALENDARS = 1 << 3;
|
||||
|
||||
private static final String KEY_DATE_STRING = "date_string";
|
||||
private static final String KEY_DATE_IN_MILLIS = "date_in_millis";
|
||||
private static final String EVENT_DATE_FORMAT = "%a, %b %d, %Y";
|
||||
|
||||
private AlertDialog mAlertDialog;
|
||||
|
||||
private CalendarQueryService mService;
|
||||
|
||||
private EditText mEventTitle;
|
||||
private View mColor;
|
||||
|
||||
private TextView mCalendarName;
|
||||
private TextView mAccountName;
|
||||
private TextView mDate;
|
||||
private Button mButtonAddEvent;
|
||||
|
||||
private CalendarController mController;
|
||||
private EditEventHelper mEditEventHelper;
|
||||
|
||||
private String mDateString;
|
||||
private long mDateInMillis;
|
||||
|
||||
private CalendarEventModel mModel;
|
||||
private long mCalendarId = -1;
|
||||
private String mCalendarOwner;
|
||||
|
||||
private class CalendarQueryService extends AsyncQueryService {
|
||||
|
||||
/**
|
||||
* @param context
|
||||
*/
|
||||
public CalendarQueryService(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueryComplete(int token, Object cookie, Cursor cursor) {
|
||||
setDefaultCalendarView(cursor);
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CreateEventDialogFragment() {
|
||||
// Empty constructor required for DialogFragment.
|
||||
}
|
||||
|
||||
public CreateEventDialogFragment(Time day) {
|
||||
setDay(day);
|
||||
}
|
||||
|
||||
public void setDay(Time day) {
|
||||
mDateString = day.format(EVENT_DATE_FORMAT);
|
||||
mDateInMillis = day.toMillis(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (savedInstanceState != null) {
|
||||
mDateString = savedInstanceState.getString(KEY_DATE_STRING);
|
||||
mDateInMillis = savedInstanceState.getLong(KEY_DATE_IN_MILLIS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final Activity activity = getActivity();
|
||||
final LayoutInflater layoutInflater = (LayoutInflater) activity
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
View view = layoutInflater.inflate(R.layout.create_event_dialog, null);
|
||||
|
||||
mColor = view.findViewById(R.id.color);
|
||||
mCalendarName = (TextView) view.findViewById(R.id.calendar_name);
|
||||
mAccountName = (TextView) view.findViewById(R.id.account_name);
|
||||
|
||||
mEventTitle = (EditText) view.findViewById(R.id.event_title);
|
||||
mEventTitle.addTextChangedListener(this);
|
||||
|
||||
mDate = (TextView) view.findViewById(R.id.event_day);
|
||||
if (mDateString != null) {
|
||||
mDate.setText(mDateString);
|
||||
}
|
||||
|
||||
mAlertDialog = new AlertDialog.Builder(activity)
|
||||
.setTitle(R.string.new_event_dialog_label)
|
||||
.setView(view)
|
||||
.setPositiveButton(R.string.create_event_dialog_save,
|
||||
new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
createAllDayEvent();
|
||||
dismiss();
|
||||
}
|
||||
})
|
||||
.setNeutralButton(R.string.edit_label,
|
||||
new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
mController.sendEventRelatedEventWithExtraWithTitleWithCalendarId(this,
|
||||
EventType.CREATE_EVENT, -1, mDateInMillis,
|
||||
mDateInMillis + DateUtils.DAY_IN_MILLIS, 0, 0,
|
||||
CalendarController.EXTRA_CREATE_ALL_DAY, -1,
|
||||
mEventTitle.getText().toString(),
|
||||
mCalendarId);
|
||||
dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.create();
|
||||
|
||||
return mAlertDialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (mButtonAddEvent == null) {
|
||||
mButtonAddEvent = mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
mButtonAddEvent.setEnabled(mEventTitle.getText().toString().length() > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(KEY_DATE_STRING, mDateString);
|
||||
outState.putLong(KEY_DATE_IN_MILLIS, mDateInMillis);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle args) {
|
||||
super.onActivityCreated(args);
|
||||
final Context context = getActivity();
|
||||
mController = CalendarController.getInstance(getActivity());
|
||||
mEditEventHelper = new EditEventHelper(context);
|
||||
mModel = new CalendarEventModel(context);
|
||||
mService = new CalendarQueryService(context);
|
||||
mService.startQuery(TOKEN_CALENDARS, null, Calendars.CONTENT_URI,
|
||||
EditEventHelper.CALENDARS_PROJECTION,
|
||||
EditEventHelper.CALENDARS_WHERE_WRITEABLE_VISIBLE, null,
|
||||
null);
|
||||
}
|
||||
|
||||
private void createAllDayEvent() {
|
||||
mModel.mStart = mDateInMillis;
|
||||
mModel.mEnd = mDateInMillis + DateUtils.DAY_IN_MILLIS;
|
||||
mModel.mTitle = mEventTitle.getText().toString();
|
||||
mModel.mAllDay = true;
|
||||
mModel.mCalendarId = mCalendarId;
|
||||
mModel.mOwnerAccount = mCalendarOwner;
|
||||
|
||||
if (mEditEventHelper.saveEvent(mModel, null, 0)) {
|
||||
Toast.makeText(getActivity(), R.string.creating_event, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
if (mButtonAddEvent != null) {
|
||||
mButtonAddEvent.setEnabled(s.length() > 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Find the calendar position in the cursor that matches calendar in
|
||||
// preference
|
||||
private void setDefaultCalendarView(Cursor cursor) {
|
||||
if (cursor == null || cursor.getCount() == 0) {
|
||||
// Create an error message for the user that, when clicked,
|
||||
// will exit this activity without saving the event.
|
||||
dismiss();
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle(R.string.no_syncable_calendars).setIconAttribute(
|
||||
android.R.attr.alertDialogIcon).setMessage(R.string.no_calendars_found)
|
||||
.setPositiveButton(R.string.add_account, new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
Intent nextIntent = new Intent(Settings.ACTION_ADD_ACCOUNT);
|
||||
final String[] array = {"com.android.calendar"};
|
||||
nextIntent.putExtra(Settings.EXTRA_AUTHORITIES, array);
|
||||
nextIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
activity.startActivity(nextIntent);
|
||||
}
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.no, null);
|
||||
builder.show();
|
||||
return;
|
||||
}
|
||||
|
||||
String defaultCalendar = Utils.getSharedPreference(
|
||||
getActivity(), GeneralPreferences.KEY_DEFAULT_CALENDAR, (String) null);
|
||||
|
||||
int calendarOwnerIndex = cursor.getColumnIndexOrThrow(Calendars.OWNER_ACCOUNT);
|
||||
int accountNameIndex = cursor.getColumnIndexOrThrow(Calendars.ACCOUNT_NAME);
|
||||
int accountTypeIndex = cursor.getColumnIndexOrThrow(Calendars.ACCOUNT_TYPE);
|
||||
|
||||
cursor.moveToPosition(-1);
|
||||
while (cursor.moveToNext()) {
|
||||
String calendarOwner = cursor.getString(calendarOwnerIndex);
|
||||
if (defaultCalendar == null) {
|
||||
// There is no stored default upon the first time running. Use a primary
|
||||
// calendar in this case.
|
||||
if (calendarOwner != null &&
|
||||
calendarOwner.equals(cursor.getString(accountNameIndex)) &&
|
||||
!CalendarContract.ACCOUNT_TYPE_LOCAL.equals(
|
||||
cursor.getString(accountTypeIndex))) {
|
||||
setCalendarFields(cursor);
|
||||
return;
|
||||
}
|
||||
} else if (defaultCalendar.equals(calendarOwner)) {
|
||||
// Found the default calendar.
|
||||
setCalendarFields(cursor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
cursor.moveToFirst();
|
||||
setCalendarFields(cursor);
|
||||
}
|
||||
|
||||
private void setCalendarFields(Cursor cursor) {
|
||||
int calendarIdIndex = cursor.getColumnIndexOrThrow(Calendars._ID);
|
||||
int colorIndex = cursor.getColumnIndexOrThrow(Calendars.CALENDAR_COLOR);
|
||||
int calendarNameIndex = cursor.getColumnIndexOrThrow(Calendars.CALENDAR_DISPLAY_NAME);
|
||||
int accountNameIndex = cursor.getColumnIndexOrThrow(Calendars.ACCOUNT_NAME);
|
||||
int calendarOwnerIndex = cursor.getColumnIndexOrThrow(Calendars.OWNER_ACCOUNT);
|
||||
|
||||
mCalendarId = cursor.getLong(calendarIdIndex);
|
||||
mCalendarOwner = cursor.getString(calendarOwnerIndex);
|
||||
mColor.setBackgroundColor(Utils.getDisplayColorFromColor(cursor
|
||||
.getInt(colorIndex)));
|
||||
String accountName = cursor.getString(accountNameIndex);
|
||||
String calendarName = cursor.getString(calendarNameIndex);
|
||||
mCalendarName.setText(calendarName);
|
||||
if (calendarName.equals(accountName)) {
|
||||
mAccountName.setVisibility(View.GONE);
|
||||
} else {
|
||||
mAccountName.setVisibility(View.VISIBLE);
|
||||
mAccountName.setText(accountName);
|
||||
}
|
||||
}
|
||||
}
|
@ -16,15 +16,16 @@
|
||||
|
||||
package com.android.calendar.event;
|
||||
|
||||
import static android.provider.CalendarContract.EXTRA_EVENT_ALL_DAY;
|
||||
import static android.provider.CalendarContract.EXTRA_EVENT_BEGIN_TIME;
|
||||
import static android.provider.CalendarContract.EXTRA_EVENT_END_TIME;
|
||||
import static android.provider.CalendarContract.EXTRA_EVENT_ALL_DAY;
|
||||
|
||||
import android.app.ActionBar;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.CalendarContract.Events;
|
||||
import android.text.format.Time;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
@ -127,6 +128,8 @@ public class EditEventActivity extends AbstractCalendarActivity {
|
||||
info.startTime.set(begin);
|
||||
}
|
||||
info.id = eventId;
|
||||
info.eventTitle = intent.getStringExtra(Events.TITLE);
|
||||
info.calendarId = intent.getLongExtra(Events.CALENDAR_ID, -1);
|
||||
|
||||
if (allDay) {
|
||||
info.extraLong = CalendarController.EXTRA_CREATE_ALL_DAY;
|
||||
|
@ -107,6 +107,7 @@ public class EditEventFragment extends Fragment implements EventHandler {
|
||||
private Uri mUri;
|
||||
private long mBegin;
|
||||
private long mEnd;
|
||||
private long mCalendarId = -1;
|
||||
|
||||
private Activity mContext;
|
||||
private final Done mOnDone = new Done();
|
||||
@ -288,14 +289,15 @@ public class EditEventFragment extends Fragment implements EventHandler {
|
||||
break;
|
||||
case TOKEN_CALENDARS:
|
||||
try {
|
||||
if (mModel.mCalendarId == -1) {
|
||||
// Populate Calendar spinner only if no calendar is set e.g. new event
|
||||
if (mModel.mId == -1) {
|
||||
// Populate Calendar spinner only if no event id is set.
|
||||
MatrixCursor matrixCursor = Utils.matrixCursorFromCursor(cursor);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onQueryComplete: setting cursor with "
|
||||
+ matrixCursor.getCount() + " calendars");
|
||||
}
|
||||
mView.setCalendarsCursor(matrixCursor, isAdded() && isResumed());
|
||||
mView.setCalendarsCursor(matrixCursor, isAdded() && isResumed(),
|
||||
mCalendarId);
|
||||
} else {
|
||||
// Populate model for an existing event
|
||||
EditEventHelper.setModelFromCalendarCursor(mModel, cursor);
|
||||
@ -364,6 +366,9 @@ public class EditEventFragment extends Fragment implements EventHandler {
|
||||
if (mEvent.endTime != null) {
|
||||
mEnd = mEvent.endTime.toMillis(true);
|
||||
}
|
||||
if (mEvent.calendarId != -1) {
|
||||
mCalendarId = mEvent.calendarId;
|
||||
}
|
||||
} else if (mEventBundle != null) {
|
||||
if (mEventBundle.id != -1) {
|
||||
mModel.mId = mEventBundle.id;
|
||||
@ -397,8 +402,11 @@ public class EditEventFragment extends Fragment implements EventHandler {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "startQuery: Editing a new event.");
|
||||
}
|
||||
mModel.mOriginalStart = mBegin;
|
||||
mModel.mOriginalEnd = mEnd;
|
||||
mModel.mStart = mBegin;
|
||||
mModel.mEnd = mEnd;
|
||||
mModel.mCalendarId = mCalendarId;
|
||||
mModel.mSelfAttendeeStatus = Attendees.ATTENDEE_STATUS_ACCEPTED;
|
||||
|
||||
// Start a query in the background to read the list of calendars
|
||||
@ -601,6 +609,7 @@ public class EditEventFragment extends Fragment implements EventHandler {
|
||||
}
|
||||
mModifyDialog = new AlertDialog.Builder(mContext).setTitle(R.string.edit_event_label)
|
||||
.setItems(items, new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (which == 0) {
|
||||
// Update this if we start allowing exceptions
|
||||
@ -637,10 +646,12 @@ public class EditEventFragment extends Fragment implements EventHandler {
|
||||
class Done implements EditEventHelper.EditDoneRunnable {
|
||||
private int mCode = -1;
|
||||
|
||||
@Override
|
||||
public void setDoneCode(int code) {
|
||||
mCode = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// We only want this to get called once, either because the user
|
||||
// pressed back/home or one of the buttons on screen
|
||||
@ -745,32 +756,15 @@ public class EditEventFragment extends Fragment implements EventHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isEmpty();
|
||||
}
|
||||
|
||||
private boolean isEmpty() {
|
||||
if (mModel.mTitle != null) {
|
||||
String title = mModel.mTitle.trim();
|
||||
if (title.length() > 0) {
|
||||
return false;
|
||||
}
|
||||
if (mModel.mOriginalStart != mModel.mStart || mModel.mOriginalEnd != mModel.mEnd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mModel.mLocation != null) {
|
||||
String location = mModel.mLocation.trim();
|
||||
if (location.length() > 0) {
|
||||
return false;
|
||||
}
|
||||
if (!mModel.mAttendeesList.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mModel.mDescription != null) {
|
||||
String description = mModel.mDescription.trim();
|
||||
if (description.length() > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return mModel.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
|