+++ /dev/null
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := user
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
-# TODO: Remove dependency of application on the test runner (android.test.runner)
-# library.
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_STATIC_JAVA_LIBRARIES := googlelogin-client
-
-LOCAL_PACKAGE_NAME := Calendar
-
-include $(BUILD_PACKAGE)
-
-# Use the following include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/Calendar/AndroidManifest.xml
-**
-** Copyright 2006, 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.
-*/
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.calendar"
- android:sharedUserId="android.uid.calendar"
- android:sharedUserLabel="@string/app_label">
-
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.VIBRATE"/>
- <uses-permission android:name="android.permission.READ_CALENDAR" />
- <uses-permission android:name="android.permission.WRITE_CALENDAR" />
- <uses-permission android:name="android.permission.WAKE_LOCK" />
- <uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH.mail" />
-
- <application android:name="CalendarApplication"
- android:label="@string/app_label" android:icon="@drawable/app_icon"
- android:taskAffinity="android.task.calendar">
- <!-- TODO: Remove dependency of application on the test runner
- (android.test) library. -->
- <uses-library android:name="android.test.runner" />
-
- <activity android:name="LaunchActivity"
- android:theme="@android:style/Theme.Light">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
-
- <activity android:name="MonthActivity" android:label="@string/month_view"
- android:theme="@android:style/Theme.Light.NoTitleBar" />
- <activity android:name="WeekActivity" android:label="@string/week_view"
- android:theme="@android:style/Theme.Light.NoTitleBar" />
- <activity android:name="DayActivity" android:label="@string/day_view"
- android:theme="@android:style/Theme.Light.NoTitleBar" />
- <activity android:name="AgendaActivity" android:label="@string/agenda_view"
- android:theme="@android:style/Theme.Light.NoTitleBar" />
-
- <activity android:name="EditEvent" android:label="@string/event_edit_title"
- android:theme="@android:style/Theme.Light"
- android:configChanges="orientation|keyboardHidden">
-
- <intent-filter>
- <action android:name="android.intent.action.EDIT" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:mimeType="vnd.android.cursor.item/event" />
- </intent-filter>
- </activity>
-
- <activity android:name="EventInfoActivity" android:label="@string/event_info_title"
- android:theme="@android:style/Theme.Light"
- android:configChanges="orientation|keyboardHidden">
-
- <intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:mimeType="vnd.android.cursor.item/event" />
- </intent-filter>
- </activity>
- <activity android:name="SelectCalendarsActivity" android:label="@string/calendars_title" />
- <activity android:name="CalendarPreferenceActivity" android:label="@string/preferences_title" />
- <activity android:name="AlertActivity" android:launchMode="singleInstance"
- android:theme="@style/Alert" android:excludeFromRecents="true" />
- <receiver android:name="AlertReceiver">
- <intent-filter>
- <action android:name="android.intent.action.EVENT_REMINDER" />
- <data android:mimeType="vnd.android.cursor.item/calendar-alert" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- <action android:name="android.intent.action.TIME_SET" />
- </intent-filter>
- </receiver>
-
- <service android:name="AlertService" />
-
- <activity android:name="CalendarTests" android:label="Calendar Tests">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.UNIT_TEST" />
- </intent-filter>
- </activity>
-
- <receiver android:name="CalendarGadgetProvider">
- <intent-filter>
- <action android:name="android.gadget.action.GADGET_UPDATE" />
- <action android:name="com.android.providers.calendar.EVENTS_CHANGED" />
- </intent-filter>
- <meta-data android:name="android.gadget.provider" android:resource="@xml/gadget_info" />
- </receiver>
- </application>
-</manifest>
-
+++ /dev/null
-
- Copyright (c) 2005-2008, 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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromYDelta="-100%p" android:toYDelta="0" android:duration="400"/>
-</set>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromYDelta="0" android:toYDelta="100%p" android:duration="400"/>
-</set>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="400"/>
-</set>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromXDelta="0" android:toXDelta="-100%p" android:duration="400"/>
-</set>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromXDelta="-100%p" android:toXDelta="0" android:duration="400"/>
-</set>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromXDelta="0" android:toXDelta="100%p" android:duration="400"/>
-</set>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromYDelta="100%p" android:toYDelta="0" android:duration="400"/>
-</set>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromYDelta="0" android:toYDelta="-100%p" android:duration="400"/>
-</set>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/box_appointment_pressed" />
- <item android:state_selected="true" android:drawable="@drawable/box_appointment_selected" />
- <item android:drawable="@drawable/box_appointment_normal" />
-</selector>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
-
- <corners android:radius="6dip"/>
- <solid android:color="#00ffffff"/>
-</shape>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/Calendar/assets/res/any/drawable/selection.xml
-**
-** Copyright 2008, 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.
-*/
--->
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
- <gradient android:startColor="#ffffffff" android:endColor="#ffffaa00"
- android:angle="270"/>
- <stroke android:width="1dp" android:color="#ffc1a43a"/>
- <corners android:radius="0dp"/>
- <padding android:left="0dp" android:top="0dp"
- android:right="0dp" android:bottom="0dp" />
-</shape>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/gadget"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="6px"
- android:background="@drawable/bg_calendar"
- >
-
- <TextView
- android:id="@+id/no_events"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:paddingTop="6px"
- android:gravity="center"
- android:textStyle="bold"
- android:textSize="16sp"
- android:text="@string/gadget_no_events"
- android:textColor="@color/gadget_no_events"
- />
-
- <FrameLayout
- android:id="@+id/landscape_hidden"
- android:layout_width="0dip"
- android:layout_height="0dip"
- android:visibility="gone"
- >
-
- <TextView
- android:id="@+id/secondary_card"
- android:layout_width="0dip"
- android:layout_height="0dip"
- />
-
- <TextView
- android:id="@+id/stub_when"
- android:layout_width="0dip"
- android:layout_height="0dip"
- />
-
- <TextView
- android:id="@+id/stub_title"
- android:layout_width="0dip"
- android:layout_height="0dip"
- />
-
- <TextView
- android:id="@+id/stub_where"
- android:layout_width="0dip"
- android:layout_height="0dip"
- />
-
- <TextView
- android:id="@+id/secondary_when"
- android:layout_width="0dip"
- android:layout_height="0dip"
- android:background="@drawable/strip_cal_secondary"
- />
-
- <TextView
- android:id="@+id/secondary_title"
- android:layout_width="0dip"
- android:layout_height="0dip"
- />
-
- <ImageView
- android:id="@+id/divider"
- android:layout_width="0dip"
- android:layout_height="0dip"
- android:background="@drawable/white_list_rule_cal"
- />
-
- <TextView
- android:id="@+id/title2"
- android:layout_width="0dip"
- android:layout_height="0dip"
- />
-
- </FrameLayout>
-
- <LinearLayout
- android:id="@+id/primary_card"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:paddingLeft="3px"
- android:paddingRight="3px"
- android:paddingTop="3px"
- android:paddingBottom="8px"
- android:background="@drawable/bg_calendar_primary"
- android:orientation="vertical"
- android:visibility="gone"
- >
-
- <TextView
- android:id="@+id/when"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingRight="64px"
- android:paddingLeft="8px"
- android:paddingTop="1px"
- android:paddingBottom="1px"
- android:gravity="center_vertical"
- android:background="@drawable/strip_cal"
- android:textStyle="bold"
- android:textSize="11sp"
- android:textColor="@color/gadget_when"
- android:singleLine="true"
- />
-
- <TextView
- android:id="@+id/title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingRight="64px"
- android:paddingLeft="8px"
- android:textStyle="bold"
- android:textSize="16sp"
- android:textColor="@color/gadget_title"
- android:singleLine="true"
- />
-
- <TextView
- android:id="@+id/where"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingRight="64px"
- android:paddingLeft="8px"
- android:textSize="11sp"
- android:textColor="@color/gadget_where"
- android:singleLine="true"
- />
-
- </LinearLayout>
-
- <ImageView
- android:id="@+id/icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:layout_alignParentRight="true"
- android:layout_marginRight="8px"
- android:src="@drawable/app_icon_blank"
- android:visibility="gone"
- />
-
-</RelativeLayout>
-
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <ViewSwitcher android:id="@+id/switcher"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" />
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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:orientation="horizontal"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent"
- android:background="@android:color/darker_gray"
- android:padding="4dip"
- >
- <TextView android:id="@+id/date"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:textStyle="bold"
- android:textColor="?android:attr/textColorPrimary"
- />
- <TextView android:id="@+id/day_of_week"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_marginLeft="5dip"
- android:textColor="?android:attr/textColorPrimary"
- />
-</LinearLayout>
-
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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.
--->
-
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@android:id/content"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent">
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent"
- >
-
- <View android:id="@+id/vertical_stripe"
- android:layout_width="10dip"
- android:layout_height="fill_parent"
- android:layout_marginRight="5dip" />
-
- <LinearLayout
- android:orientation="vertical"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent"
- android:layout_weight="1">
-
- <TextView android:id="@+id/title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:textStyle="bold"
- android:textColor="@android:color/black"
- style="?android:attr/textAppearanceMediumInverse"
- />
-
- <TextView android:id="@+id/when"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textStyle="bold"
- android:textColor="@android:color/black"
- style="?android:attr/textAppearanceSmallInverse"
- />
-
- <TextView android:id="@+id/where"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:textStyle="bold"
- android:textColor="@android:color/black"
- style="?android:attr/textAppearanceSmallInverse"
- />
- </LinearLayout>
- </LinearLayout>
-</FrameLayout>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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:orientation="horizontal"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent">
-
- <ImageView android:id="@+id/reminder_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:src="@drawable/ic_alarm_dark"
- android:focusable="false"
- android:clickable="false"
- />
-
- <TextView android:id="@+id/reminder"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- style="@style/TextAppearance.AgendaView_ValueLabel"
- />
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:padding="10dip">
-
- <ListView android:id="@+id/alert_container"
- android:layout_width="fill_parent"
- android:layout_height="0dip"
- android:layout_weight="1"
- android:listSelector="@android:color/transparent"
- android:divider="@null" />
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingTop="3dip">
-
- <Button android:id="@+id/snooze_all"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:text="@string/snooze_all_label" />
-
- <TextView android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_weight="1" />
-
- <Button android:id="@+id/dismiss_all"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:text="@string/dismiss_all_label" />
- </LinearLayout>
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/box_appointment">
-
- <ImageView android:id="@+id/vertical_stripe"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_marginTop="2dip"
- android:layout_marginBottom="2dip"
- android:layout_marginRight="5dip"
- android:background="@drawable/box_color_white" />
-
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
-
- <LinearLayout android:id="@+id/event_title_container"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
-
- <TextView android:id="@+id/event_title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:textStyle="bold"
- android:textColor="@android:color/black"
- style="?android:attr/textAppearanceMediumInverse" />
- </LinearLayout>
-
- <LinearLayout android:id="@+id/event_details"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="0dip"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:gravity="center_vertical">
-
- <TextView android:id="@+id/when"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:textStyle="bold"
- style="?android:attr/textAppearanceSmallInverse" />
-
- <ImageView android:id="@+id/repeat_icon"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_marginLeft="5dip"
- android:src="@drawable/ic_repeat_dark"
- android:focusable="false"
- android:clickable="false"
- />
-
- </LinearLayout>
- <LinearLayout android:id="@+id/reminders_container"
- android:orientation="vertical"
- android:layout_height="fill_parent"
- android:layout_width="wrap_content"
- />
- </LinearLayout>
-
- <TextView android:id="@+id/where"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:textStyle="bold"
- style="?android:attr/textAppearanceSmallInverse" />
- </LinearLayout>
- </LinearLayout>
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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:orientation="vertical"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@android:drawable/toast_frame">
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:padding="10dip">
-
- <ImageView android:id="@+id/repeat_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginRight="10dip"
- android:src="@android:drawable/ic_popup_reminder"
- />
-
- <TextView android:id="@+id/event_title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- style="@style/TextAppearance.Alert_Title" />
- </LinearLayout>
-
- <ImageView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:background="@android:drawable/divider_horizontal_dark" />
-
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:padding="10dip">
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
-
- <TextView android:id="@+id/when_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingRight="4dip"
- android:text="@string/alert_when_label"
- style="@style/TextAppearance.Alert_Label" />
-
- <TextView android:id="@+id/when"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- style="@style/TextAppearance.Alert_Value" />
- </LinearLayout>
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
-
- <TextView android:id="@+id/where_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingRight="4dip"
- android:text="@string/alert_where_label"
- style="@style/TextAppearance.Alert_Label" />
-
- <TextView android:id="@+id/where"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- style="@style/TextAppearance.Alert_Value" />
- </LinearLayout>
- </LinearLayout>
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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:id="@+id/bubble_layout"
- android:orientation="vertical"
- android:paddingTop="5dip"
- android:paddingBottom="5dip"
- android:paddingLeft="10dip"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
-
- <TextView android:id="@+id/event_title"
- android:textStyle="bold"
- android:textColor="@color/panel_text_foreground"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
-
- <ImageView android:id="@+id/reminder_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginRight="6dip"
- android:src="@drawable/ic_alarm_white"
- />
-
- <ImageView android:id="@+id/repeat_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginRight="6dip"
- android:src="@drawable/ic_repeat_white"
- />
-
- <TextView android:id="@+id/time"
- android:textColor="@color/panel_text_foreground"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-
- </LinearLayout>
-
- <TextView android:id="@+id/where"
- android:textColor="@color/panel_text_foreground"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:gravity="center_vertical">
-
- <View android:id="@+id/color"
- android:layout_width="10dip"
- android:layout_height="58dip"
- />
-
- <CheckBox android:id="@+id/checkbox"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="4dip"
- android:layout_marginRight="2dip"
- />
-
- <TextView android:id="@+id/calendar"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- style="?android:attr/textAppearanceLarge"
- />
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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:id="@+id/calendars"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <ListView android:id="@+id/items"
- android:layout_width="fill_parent"
- android:layout_height="0dip"
- android:layout_weight="1" />
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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:orientation="horizontal"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent">
-
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:src="@drawable/calendars_item"/>
-
- <CheckedTextView
- android:id="@+id/calendar_name"
- style="?android:attr/spinnerDropDownItemStyle"
- android:singleLine="true"
- android:layout_width="fill_parent"
- android:layout_height="?android:attr/listPreferredItemHeight" />
-
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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:orientation="horizontal"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent">
-
- <ImageView android:id="@+id/right_arrow"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:src="@drawable/calendars_item"/>
-
- <TextView android:id="@+id/calendar_name"
- style="?android:attr/spinnerItemStyle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
-
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2006 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:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
-
- <RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="?android:attr/windowTitleSize"
- style="?android:attr/windowTitleBackgroundStyle">
-
- <TextView android:id="@+id/title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- style="?android:attr/windowTitleStyle"
- android:background="@null"
- android:fadingEdge="horizontal"
- android:layout_alignParentLeft="true"
- android:layout_alignParentRight="true"
- android:layout_alignParentTop="true"
- />
-
- <ProgressBar android:id="@+id/progress_circular"
- style="?android:attr/progressBarStyleSmall"
- android:visibility="gone"
- android:max="10000"
- android:layout_centerVertical="true"
- android:layout_alignParentRight="true"
- android:layout_marginLeft="6dip"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- </RelativeLayout>
-
- <ViewSwitcher android:id="@+id/switcher"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" />
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2006 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.
--->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/scroll_view"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <LinearLayout android:id="@+id/event"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <!-- WHAT -->
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:padding="5dip">
-
- <TextView android:id="@+id/what_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/what_label"
- style="@style/TextAppearance.EditEvent_Label"/>
-
- <EditText android:id="@+id/title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:hint="@string/hint_what"
- android:capitalize="words"/>
- </LinearLayout>
-
- <!-- WHEN -->
- <View
- android:layout_width="fill_parent"
- android:layout_height="1dip"
- android:background="@android:drawable/divider_horizontal_dark"
- />
-
- <LinearLayout android:id="@+id/when_container"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:padding="5dip">
-
- <TextView android:id="@+id/from_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/edit_event_from_label"
- style="@style/TextAppearance.EditEvent_Label"/>
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
-
- <Button android:id="@+id/start_date"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
-
- <Button android:id="@+id/start_time"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
-
- </LinearLayout>
-
- <TextView android:id="@+id/to_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/edit_event_to_label"
- style="@style/TextAppearance.EditEvent_Label"/>
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
-
- <Button android:id="@+id/end_date"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
-
- <Button android:id="@+id/end_time"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- </LinearLayout>
-
- <CheckBox android:id="@+id/is_all_day"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/edit_event_all_day_label"/>
- </LinearLayout>
-
- <!-- WHERE -->
- <View
- android:layout_width="fill_parent"
- android:layout_height="1dip"
- android:background="@android:drawable/divider_horizontal_dark"
- />
-
- <LinearLayout android:id="@+id/where_container"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:padding="5dip">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/where_label"
- style="@style/TextAppearance.EditEvent_Label"/>
-
- <EditText android:id="@+id/location"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:hint="@string/hint_where"
- android:capitalize="sentences"/>
- </LinearLayout>
-
- <!-- DESCRIPTION -->
- <View
- android:layout_width="fill_parent"
- android:layout_height="1dip"
- android:background="@android:drawable/divider_horizontal_dark"
- />
-
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:padding="5dip">
-
- <TextView android:id="@+id/description_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/description_label"
- style="@style/TextAppearance.EditEvent_Label"/>
-
- <EditText android:id="@+id/description"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:hint="@string/hint_description"
- android:capitalize="sentences"/>
- </LinearLayout>
-
- <!-- CALENDARS -->
- <View android:id="@+id/calendar_separator"
- android:layout_width="fill_parent"
- android:layout_height="1dip"
- android:background="@android:drawable/divider_horizontal_dark"
- />
-
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="5dip"
- android:paddingRight="5dip"
- android:paddingTop="5dip"
- android:paddingBottom="1dip">
-
- <TextView android:id="@+id/calendar_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/edit_event_calendar_label"
- style="@style/TextAppearance.EditEvent_Label"/>
-
- <Spinner android:id="@+id/calendars"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- </LinearLayout>
-
- <!-- REMINDERS -->
- <View android:id="@+id/reminders_separator"
- android:layout_width="fill_parent"
- android:layout_height="1dip"
- android:background="@android:drawable/divider_horizontal_dark"
- />
-
- <LinearLayout android:id="@+id/reminders_container"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="5dip"
- android:paddingRight="5dip"
- android:paddingTop="5dip"
- android:paddingBottom="1dip">
-
- <TextView android:id="@+id/reminders_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/reminders_label"
- style="@style/TextAppearance.EditEvent_Label"/>
-
- <LinearLayout android:id="@+id/reminder_items_container"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
- </LinearLayout>
- </LinearLayout>
-
- <!-- REPEATS -->
- <View
- android:layout_width="fill_parent"
- android:layout_height="1dip"
- android:background="@android:drawable/divider_horizontal_dark"
- />
-
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="5dip"
- android:paddingRight="5dip"
- android:paddingTop="5dip"
- android:paddingBottom="1dip">
-
- <TextView android:id="@+id/repeats_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/repeats_label"
- style="@style/TextAppearance.EditEvent_Label"/>
-
- <Spinner android:id="@+id/repeats"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"/>
- </LinearLayout>
-
- <!-- MORE OPTIONS -->
- <LinearLayout android:id="@+id/extra_options_container"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:visibility="gone">
-
- <!-- PRESENCE -->
- <View
- android:layout_width="fill_parent"
- android:layout_height="1dip"
- android:background="@android:drawable/divider_horizontal_dark"
- />
-
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="5dip"
- android:paddingRight="5dip"
- android:paddingTop="5dip"
- android:paddingBottom="1dip">
-
- <TextView android:id="@+id/presence_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/presence_label"
- style="@style/TextAppearance.EditEvent_Label"/>
-
- <Spinner android:id="@+id/availability"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:entries="@array/availability" />
- </LinearLayout>
-
- <!-- PRIVACY -->
- <View
- android:layout_width="fill_parent"
- android:layout_height="1dip"
- android:background="@android:drawable/divider_horizontal_dark"
- />
-
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="5dip"
- android:paddingRight="5dip"
- android:paddingTop="5dip"
- android:paddingBottom="1dip">
-
- <TextView android:id="@+id/privacy_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/privacy_label"
- style="@style/TextAppearance.EditEvent_Label"/>
-
- <Spinner android:id="@+id/visibility"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:entries="@array/visibility" />
- </LinearLayout>
- </LinearLayout>
-
- <!-- BUTTONS -->
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingTop="5dip"
- android:paddingLeft="4dip"
- android:paddingRight="4dip"
- android:paddingBottom="1dip"
- android:background="@android:drawable/bottom_bar" >
-
- <Button android:id="@+id/save"
- android:layout_width="0dip"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:text="@string/save_label"
- />
-
- <Button android:id="@+id/discard"
- android:layout_width="0dip"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:text="@string/discard_label"
- />
-
- <Button android:id="@+id/delete"
- android:layout_width="0dip"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:text="@string/delete_label"
- />
- </LinearLayout>
- </LinearLayout>
-</ScrollView>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
-
- <Spinner android:id="@+id/reminder_value"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:layout_gravity="center_vertical"
- android:entries="@array/reminder_minutes_labels"/>
-
- <ImageButton android:id="@+id/reminder_remove"
- style="?android:attr/buttonStyleInset"
- android:src="@android:drawable/ic_delete"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginRight="2dip"
- android:gravity="center_vertical"
- />
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2006 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.
--->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_weight="1.0" >
-
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:padding="8dip"
- android:layout_alignParentTop="true" >
-
-
- <LinearLayout android:id="@+id/event"
- android:background="@drawable/bg_cal_card"
- android:orientation="vertical"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent"
- android:layout_weight="1">
-
-
- <View android:id="@+id/strip"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/strip_cal"
- />
-
- <!-- WHAT -->
- <TextView android:id="@+id/title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:autoLink="all"
- android:textStyle="bold"
- android:padding="8dip"
- style="?android:attr/textAppearanceMedium"
- />
-
- <View android:id="@+id/divider"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="8dip"
- android:layout_marginRight="8dip"
- android:background="@android:drawable/divider_horizontal_dark"
- />
-
- <!-- WHEN -->
- <TextView android:id="@+id/when"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingTop="5dip"
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
- android:textStyle="bold"
- style="?android:attr/textAppearanceSmall"
- />
-
- <!-- TIMEZONE -->
- <LinearLayout android:id="@+id/timezone_container"
- android:orientation="horizontal"
- android:paddingTop="5dip"
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
-
- <TextView android:id="@+id/timezone_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginRight="5dip"
- android:text="@string/view_event_timezone_label"
- style="?android:attr/textAppearanceSmall"
- />
-
- <TextView android:id="@+id/timezone"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:textStyle="bold"
- style="?android:attr/textAppearanceSmall"
- />
- </LinearLayout>
-
- <!-- REPEATS -->
- <LinearLayout android:id="@+id/repeat_container"
- android:orientation="horizontal"
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
-
- <ImageView android:id="@+id/repeat_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:src="@drawable/ic_repeat_dark"
- android:focusable="false"
- android:clickable="false"
- />
-
- <TextView android:id="@+id/repeat"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="3dip"
- style="?android:attr/textAppearanceSmall"
- />
- </LinearLayout>
-
- <!-- WHERE -->
- <TextView android:id="@+id/where"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
- android:autoLink="all"
- android:textStyle="bold"
- style="?android:attr/textAppearanceSmall"
- />
-
- <!-- DESCRIPTION -->
- <TextView android:id="@+id/description"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
- android:autoLink="all"
- style="?android:attr/textAppearanceSmall"
- />
-
- <!-- CALENDAR -->
- <LinearLayout android:id="@+id/calendar_container"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
- android:paddingBottom="5dip"
- >
-
- <TextView android:id="@+id/calendar_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginRight="5dip"
- android:text="@string/view_event_calendar_label"
- style="?android:attr/textAppearanceSmall"
- />
-
- <TextView android:id="@+id/calendar"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:textStyle="bold"
- style="?android:attr/textAppearanceSmall"
- />
- </LinearLayout>
- </LinearLayout>
-
- <!-- REMINDERS -->
- <LinearLayout android:id="@+id/reminders_container"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingTop="5dip"
- android:paddingBottom="1dip">
-
- <TextView android:id="@+id/reminders_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/reminders_label"
- style="?android:attr/textAppearanceMedium"/>
-
- <LinearLayout android:id="@+id/reminder_items_container"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
- </LinearLayout>
- </LinearLayout>
-
- <!-- RESPONSE -->
- <LinearLayout android:id="@+id/response_container"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingTop="5dip"
- android:paddingBottom="1dip">
-
- <TextView android:id="@+id/response_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/view_event_response_label"
- style="?android:attr/textAppearanceMedium"/>
-
- <Spinner android:id="@+id/response_value"
- android:prompt="@string/view_event_response_label"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:entries="@array/response_labels1"/>
- </LinearLayout>
- </LinearLayout>
-</ScrollView>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/gadget"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="6px"
- android:background="@drawable/bg_calendar"
- >
-
- <TextView
- android:id="@+id/no_events"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:paddingTop="6px"
- android:gravity="center"
- android:textStyle="bold"
- android:textSize="16sp"
- android:text="@string/gadget_no_events"
- android:textColor="@color/gadget_no_events"
- />
-
- <LinearLayout
- android:id="@+id/secondary_card"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="3px"
- android:layout_marginRight="3px"
- android:orientation="vertical"
- android:visibility="gone"
- >
-
- <TextView
- android:id="@+id/stub_when"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:textStyle="bold"
- android:textSize="11sp"
- android:paddingTop="8px"
- android:visibility="invisible"
- />
-
- <TextView
- android:id="@+id/stub_title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:textStyle="bold"
- android:textSize="16sp"
- android:visibility="invisible"
- />
-
- <TextView
- android:id="@+id/stub_where"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:textSize="11sp"
- android:visibility="invisible"
- />
-
- <TextView
- android:id="@+id/secondary_when"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="8px"
- android:paddingTop="1px"
- android:paddingBottom="1px"
- android:gravity="center_vertical"
- android:background="@drawable/strip_cal_secondary"
- android:textStyle="bold"
- android:textSize="11sp"
- android:textColor="@color/gadget_when"
- android:singleLine="true"
- />
-
- <TextView
- android:id="@+id/secondary_title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="8px"
- android:textSize="11sp"
- android:textColor="@color/gadget_title"
- android:singleLine="true"
- />
-
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/primary_card"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:paddingLeft="3px"
- android:paddingRight="3px"
- android:paddingTop="3px"
- android:paddingBottom="8px"
- android:background="@drawable/bg_calendar_primary"
- android:orientation="vertical"
- android:visibility="gone"
- >
-
- <TextView
- android:id="@+id/when"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingRight="64px"
- android:paddingLeft="8px"
- android:paddingTop="1px"
- android:paddingBottom="1px"
- android:gravity="center_vertical"
- android:background="@drawable/strip_cal"
- android:textStyle="bold"
- android:textSize="11sp"
- android:textColor="@color/gadget_when"
- android:singleLine="true"
- />
-
- <TextView
- android:id="@+id/title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingRight="64px"
- android:paddingLeft="8px"
- android:textStyle="bold"
- android:textSize="16sp"
- android:textColor="@color/gadget_title"
- android:singleLine="true"
- />
-
- <TextView
- android:id="@+id/where"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingRight="64px"
- android:paddingLeft="8px"
- android:textSize="11sp"
- android:textColor="@color/gadget_where"
- android:singleLine="true"
- />
-
- <ImageView
- android:id="@+id/divider"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="4px"
- android:layout_marginBottom="2px"
- android:layout_marginLeft="16px"
- android:layout_marginRight="16px"
- android:background="@drawable/white_list_rule_cal"
- />
-
- <TextView
- android:id="@+id/title2"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingRight="64px"
- android:paddingLeft="8px"
- android:textStyle="bold"
- android:textSize="11sp"
- android:textColor="@color/gadget_title"
- android:singleLine="true"
- />
-
- </LinearLayout>
-
- <ImageView
- android:id="@+id/icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:layout_alignParentRight="true"
- android:layout_marginRight="8px"
- android:src="@drawable/app_icon_blank"
- android:visibility="gone"
- />
-
-</RelativeLayout>
-
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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.
--->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@color/event_background" >
-
- <LinearLayout android:id="@+id/import_ics"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <TextView android:id="@+id/num_events_label"
- android:text="@string/num_events"
- android:gravity="right|top"
- android:paddingRight="10dip"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
- <TextView android:id="@+id/num_events"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-
- <LinearLayout android:id="@+id/calendar_row"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
-
- <ImageView android:id="@+id/calendar_icon"
- android:layout_marginTop="4dip"
- android:layout_marginRight="10dip"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/sym_calendar_event" />
-
- <Spinner android:id="@+id/calendars"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- </LinearLayout>
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_column="1">
-
- <Button android:id="@+id/import_button"
- android:layout_marginTop="8dip"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/import_label" />
-
- <Button android:id="@+id/cancel_button"
- android:layout_marginTop="8dip"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@android:string/cancel" />
- </LinearLayout>
- </LinearLayout>
-</ScrollView>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2006 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:id="@+id/month_container"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
-
- <RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="?android:attr/windowTitleSize"
- style="?android:attr/windowTitleBackgroundStyle">
-
- <TextView android:id="@+id/title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- style="?android:attr/windowTitleStyle"
- android:background="@null"
- android:fadingEdge="horizontal"
- android:layout_alignParentLeft="true"
- android:layout_alignParentRight="true"
- android:layout_alignParentTop="true"
- />
-
- <ProgressBar android:id="@+id/progress_circular"
- style="?android:attr/progressBarStyleSmall"
- android:visibility="gone"
- android:max="10000"
- android:layout_centerVertical="true"
- android:layout_alignParentRight="true"
- android:layout_marginLeft="6dip"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- </RelativeLayout>
-
- <LinearLayout android:id="@+id/day_names"
- android:orientation="horizontal"
- android:background="@color/daynames_background"
- android:layout_width="fill_parent"
- android:layout_height="23dip" >
-
- <TextView android:id="@+id/day0"
- style="@style/MonthView_DayLabel" />
- <TextView android:id="@+id/day1"
- style="@style/MonthView_DayLabel" />
- <TextView android:id="@+id/day2"
- style="@style/MonthView_DayLabel" />
- <TextView android:id="@+id/day3"
- style="@style/MonthView_DayLabel" />
- <TextView android:id="@+id/day4"
- style="@style/MonthView_DayLabel" />
- <TextView android:id="@+id/day5"
- style="@style/MonthView_DayLabel" />
- <TextView android:id="@+id/day6"
- style="@style/MonthView_DayLabel" />
- </LinearLayout>
-
- <View
- android:layout_width="fill_parent"
- android:layout_height="1dip"
- android:background="@android:drawable/divider_horizontal_dark" />
-
- <ViewSwitcher android:id="@+id/switcher"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" />
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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:id="@+id/bubble_layout"
- android:orientation="vertical"
- android:paddingTop="5dip"
- android:paddingLeft="10dip"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
-
- <TableLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:shrinkColumns="1">
-
- <TableRow android:id="@+id/item_layout0">
- <TextView android:id="@+id/time0"
- android:paddingRight="10dip"
- android:textColor="@color/panel_text_foreground"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-
- <TextView android:id="@+id/event_title0"
- android:singleLine="true"
- android:ellipsize="end"
- android:textStyle="bold"
- android:textColor="@color/panel_text_foreground"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- </TableRow>
-
- <TableRow android:id="@+id/item_layout1">
- <TextView android:id="@+id/time1"
- android:paddingRight="10dip"
- android:textColor="@color/panel_text_foreground"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-
- <TextView android:id="@+id/event_title1"
- android:singleLine="true"
- android:ellipsize="end"
- android:textStyle="bold"
- android:textColor="@color/panel_text_foreground"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- </TableRow>
-
- <TableRow android:id="@+id/item_layout2">
- <TextView android:id="@+id/time2"
- android:paddingRight="10dip"
- android:textColor="@color/panel_text_foreground"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-
- <TextView android:id="@+id/event_title2"
- android:singleLine="true"
- android:ellipsize="end"
- android:textStyle="bold"
- android:textColor="@color/panel_text_foreground"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- </TableRow>
-
- <TableRow android:id="@+id/item_layout3">
- <TextView android:id="@+id/time3"
- android:paddingRight="10dip"
- android:textColor="@color/panel_text_foreground"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-
- <TextView android:id="@+id/event_title3"
- android:singleLine="true"
- android:ellipsize="end"
- android:textStyle="bold"
- android:textColor="@color/panel_text_foreground"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- </TableRow>
- </TableLayout>
-
- <TextView android:id="@+id/plus_more"
- android:singleLine="true"
- android:textStyle="bold"
- android:textColor="@color/panel_text_foreground"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2006 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:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
-
- <RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="?android:attr/windowTitleSize"
- style="?android:attr/windowTitleBackgroundStyle">
-
- <TextView android:id="@+id/title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- style="?android:attr/windowTitleStyle"
- android:background="@null"
- android:fadingEdge="horizontal"
- android:layout_alignParentLeft="true"
- android:layout_alignParentRight="true"
- android:layout_alignParentTop="true"
- />
-
- <ProgressBar android:id="@+id/progress_circular"
- style="?android:attr/progressBarStyleSmall"
- android:visibility="gone"
- android:max="10000"
- android:layout_centerVertical="true"
- android:layout_alignParentRight="true"
- android:layout_marginLeft="6dip"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- </RelativeLayout>
-
- <ViewSwitcher android:id="@+id/switcher"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" />
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="reminder_minutes_labels">
- <item>"5 minut"</item>
- <item>"10 minut"</item>
- <item>"15 minut"</item>
- <item>"20 minut"</item>
- <item>"25 minut"</item>
- <item>"30 minut"</item>
- <item>"45 minut"</item>
- <item>"1 hodina"</item>
- <item>"2 hodiny"</item>
- <item>"3 hodiny"</item>
- <item>"12 hodin"</item>
- <item>"24 hodin"</item>
- <item>"2 dny"</item>
- <item>"1 týden"</item>
- </string-array>
- <string-array name="reminder_minutes_values">
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_default_reminder_labels">
- <item>"Žádné"</item>
- <item>"5 minut"</item>
- <item>"10 minut"</item>
- <item>"15 minut"</item>
- <item>"20 minut"</item>
- <item>"25 minut"</item>
- <item>"30 minut"</item>
- <item>"45 minut"</item>
- <item>"1 hodina"</item>
- <item>"2 hodiny"</item>
- <item>"3 hodiny"</item>
- <item>"12 hodin"</item>
- <item>"24 hodin"</item>
- <item>"2 dny"</item>
- <item>"1 týden"</item>
- </string-array>
- <string-array name="preferences_default_reminder_values">
- <item>"0"</item>
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_alert_type_labels">
- <item>"Upozornění"</item>
- <item>"Oznámení ve stavovém řádku"</item>
- <item>"Vypnuto"</item>
- </string-array>
- <string-array name="preferences_alert_type_values">
- <item>"0"</item>
- <item>"1"</item>
- <item>"2"</item>
- </string-array>
- <string-array name="availability">
- <item>"Nedostupný"</item>
- <item>"Dostupný"</item>
- </string-array>
- <string-array name="visibility">
- <item>"Výchozí hodnota"</item>
- <item>"Soukromá"</item>
- <item>"Veřejná"</item>
- </string-array>
- <string-array name="day_labels">
- <item>"neděle"</item>
- <item>"pondělí"</item>
- <item>"úterý"</item>
- <item>"středa"</item>
- <item>"čtvrtek"</item>
- <item>"pátek"</item>
- <item>"sobota"</item>
- </string-array>
- <string-array name="ordinal_labels">
- <item>"1."</item>
- <item>"2."</item>
- <item>"3."</item>
- <item>"4."</item>
- <item>"poslední"</item>
- </string-array>
- <string-array name="response_labels1">
- <item>"(Bez odpovědi)"</item>
- <item>"Ano"</item>
- <item>"Možná"</item>
- <item>"Ne"</item>
- </string-array>
- <string-array name="response_labels2">
- <item>"Ano"</item>
- <item>"Možná"</item>
- <item>"Ne"</item>
- </string-array>
- <string-array name="delete_repeating_labels">
- <item>"Pouze tato událost"</item>
- <item>"Tato a budoucí události"</item>
- <item>"Všechny události"</item>
- </string-array>
- <string-array name="delete_repeating_labels_no_selected">
- <item>"Tato a budoucí události"</item>
- <item>"Všechny události"</item>
- </string-array>
- <string-array name="change_response_labels">
- <item>"Pouze tato instance"</item>
- <item>"Všechny instance události"</item>
- </string-array>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label">"Kalendář"</string>
- <string name="calendar_plug"><font fgcolor="#ffffffff">"Vítá vás Kalendář Google!"</font>" "\n" Přístup společnosti Google ke správě vašeho časového plánu je založen na myšlence, že plánování událostí může být intuitivnější, efektivnější a přístupnější."</string>
- <string name="what_label">"Co"</string>
- <string name="when_label">"Kdy"</string>
- <string name="where_label">"Kde"</string>
- <string name="repeats_label">"Opakování"</string>
- <string name="no_title_label">"(Bez předmětu)"</string>
- <plurals name="Nminutes">
- <item quantity="one">"1 minuta"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> minut"</item>
- </plurals>
- <plurals name="Nmins">
- <item quantity="one">"1 min"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> min"</item>
- </plurals>
- <plurals name="Nhours">
- <item quantity="one">"1 hodina"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> hod."</item>
- </plurals>
- <plurals name="Ndays">
- <item quantity="one">"1 den"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> dnů"</item>
- </plurals>
- <string name="show_agenda_view">"Zobrazit agendu"</string>
- <string name="show_day_view">"Zobrazit den"</string>
- <string name="agenda_view">"Agenda"</string>
- <string name="day_view">"Den"</string>
- <string name="week_view">"Týden"</string>
- <string name="month_view">"Měsíc"</string>
- <string name="event_view">"Zobrazit událost"</string>
- <string name="event_create">"Nová událost"</string>
- <string name="event_edit">"Upravit událost"</string>
- <string name="event_delete">"Odstranit událost"</string>
- <string name="goto_today">"Dnes"</string>
- <string name="menu_select_calendars">"Moje kalendáře"</string>
- <string name="menu_preferences">"Nastavení"</string>
- <string name="plus_N_more">"(plus o <xliff:g id="MORE_COUNT">%d</xliff:g> více …)"</string>
- <string name="calendars_title">"Moje kalendáře"</string>
- <string name="add_calendars">"Přidat kalendáře"</string>
- <string name="remove_calendars">"Odebrat kalendáře"</string>
- <string name="event_edit_title">"Podrobnosti události"</string>
- <string name="hint_what">"Název události"</string>
- <string name="hint_where">"Místo události"</string>
- <string name="hint_description">"Popis události"</string>
- <string name="creating_event">"Vytváření události…"</string>
- <string name="saving_event">"Ukládání události…"</string>
- <string name="loading_calendars_title">"Načítání kalendářů"</string>
- <string name="loading_calendars_message">"Načítání kalendářů..."</string>
- <string name="alert_when_label">"Kdy:"</string>
- <string name="alert_where_label">"Kde:"</string>
- <string name="alert_missed_events_single">"(zbývá <xliff:g id="REMINDER_COUNT">%s</xliff:g> připomenutí)"</string>
- <string name="alert_missed_events_multiple">"(zbývá připomenutí: <xliff:g id="REMINDER_COUNT">%s</xliff:g>)"</string>
- <string name="event_info_title">"Zobrazit událost"</string>
- <string name="event_info_title_invite">"Pozvánka na schůzku"</string>
- <string name="add_new_reminder">"Přidat připomenutí"</string>
- <string name="edit_event_to_label">"Do"</string>
- <string name="edit_event_from_label">"Od"</string>
- <string name="edit_event_all_day_label">"Celý den"</string>
- <string name="edit_event_calendar_label">"Kalendář"</string>
- <string name="edit_event_show_extra_options">"Zobrazit další možnosti"</string>
- <string name="edit_event_hide_extra_options">"Skrýt další možnosti"</string>
- <string name="description_label">"Popis"</string>
- <string name="presence_label">"Účast"</string>
- <string name="privacy_label">"Přístupnost"</string>
- <string name="reminders_label">"Připomenutí"</string>
- <string name="no_syncable_calendars">"Žádné kalendáře"</string>
- <string name="no_calendars_found">"Nemáte žádné kalendáře."</string>
- <string name="view_event_calendar_label">"Kalendář"</string>
- <string name="view_event_timezone_label">"Místní časové pásmo"</string>
- <string name="view_event_response_label">"Zúčastníte se?"</string>
- <string name="agenda_today">"Dnes"</string>
- <string name="num_events">"Počet událostí"</string>
- <string name="edit_event_label">"Upravit událost"</string>
- <string name="delete_label">"Smazat"</string>
- <string name="delete_event_label">"Odstranit událost"</string>
- <string name="save_label">"Uložit"</string>
- <string name="discard_label">"Zrušit změny"</string>
- <string name="import_label">"Importovat"</string>
- <string name="snooze_all_label">"Odložit vše"</string>
- <string name="dismiss_all_label">"Zavřít vše"</string>
- <string name="does_not_repeat">"Jednorázová událost"</string>
- <string name="daily">"Denně"</string>
- <string name="every_weekday">"Každý pracovní den (po–pá)"</string>
- <string name="weekly">"Týdně (vždy <xliff:g id="DAYS_OF_WEEK">%s</xliff:g>)"</string>
- <string name="monthly_on_day_count">"Měsíčně (vždy <xliff:g id="ORDINAL_NUMBER">%1$s</xliff:g> <xliff:g id="DAY_OF_WEEK">%2$s</xliff:g>)"</string>
- <string name="monthly_on_day">"Měsíčně (<xliff:g id="DAY_OF_MONTH">%s</xliff:g>. den)"</string>
- <string name="yearly">"Ročně (<xliff:g id="DATES">%s</xliff:g>)"</string>
- <string name="custom">"Vlastní... (nelze personalizovat v telefonu)"</string>
- <string name="modify_event">"Změnit pouze tuto událost"</string>
- <string name="modify_all">"Změnit všechny události série"</string>
- <string name="modify_all_following">"Změnit tuto událost a všechny budoucí"</string>
- <string name="delete_this_event_title">"Tato událost bude odstraněna."</string>
- <string name="delete_title">"Smazat"</string>
- <string name="change_response_title">"Změnit odpověď"</string>
- <string name="preferences_title">"Nastavení"</string>
- <string name="preferences_general_title">"Nastavení zobrazení kalendáře"</string>
- <string name="preferences_alerts_title">"Nastavení připomenutí"</string>
- <string name="preferences_hide_declined_title">"Skrýt odmítnuté události"</string>
- <string name="preferences_alerts_type_title">"Nastavit upozornění a oznámení"</string>
- <string name="preferences_alerts_type_dialog">"Upozornění a oznámení"</string>
- <string name="preferences_alerts_vibrate_title">"Vibrace"</string>
- <string name="preferences_alerts_ringtone_title">"Vybrat zvonění"</string>
- <string name="preferences_default_reminder_title">"Nastavit výchozí připomenutí"</string>
- <string name="preferences_default_reminder_dialog">"Výchozí čas připomenutí"</string>
- <string name="preferences_default_reminder_default">"10"</string>
- <string name="gadget_calendar">"Kalendář:"</string>
- <string name="gadget_now_event">"Nyní: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_next_event">"Další: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_later_event">"Později: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <plurals name="gadget_more_events">
- <item quantity="one">"Jedna další událost"</item>
- <item quantity="other">"<xliff:g id="NUMBER">%d</xliff:g> dalších událostí"</item>
- </plurals>
- <string name="gadget_no_events">"Žádné nadcházející události"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="reminder_minutes_labels">
- <item>"5 Minuten"</item>
- <item>"10 Minuten"</item>
- <item>"15 Minuten"</item>
- <item>"20 Minuten"</item>
- <item>"25 Minuten"</item>
- <item>"30 Minuten"</item>
- <item>"45 Minuten"</item>
- <item>"1 Stunde"</item>
- <item>"2 Stunden"</item>
- <item>"3 Stunden"</item>
- <item>"12 Stunden"</item>
- <item>"24 Stunden"</item>
- <item>"2 Tage"</item>
- <item>"1 Woche"</item>
- </string-array>
- <string-array name="reminder_minutes_values">
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_default_reminder_labels">
- <item>"Keine"</item>
- <item>"5 Minuten"</item>
- <item>"10 Minuten"</item>
- <item>"15 Minuten"</item>
- <item>"20 Minuten"</item>
- <item>"25 Minuten"</item>
- <item>"30 Minuten"</item>
- <item>"45 Minuten"</item>
- <item>"1 Stunde"</item>
- <item>"2 Stunden"</item>
- <item>"3 Stunden"</item>
- <item>"12 Stunden"</item>
- <item>"24 Stunden"</item>
- <item>"2 Tage"</item>
- <item>"1 Woche"</item>
- </string-array>
- <string-array name="preferences_default_reminder_values">
- <item>"0"</item>
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_alert_type_labels">
- <item>"Benachrichtigung"</item>
- <item>"Statuszeilenbenachrichtigung"</item>
- <item>"Aus"</item>
- </string-array>
- <string-array name="preferences_alert_type_values">
- <item>"0"</item>
- <item>"1"</item>
- <item>"2"</item>
- </string-array>
- <string-array name="availability">
- <item>"Beschäftigt"</item>
- <item>"Verfügbar"</item>
- </string-array>
- <string-array name="visibility">
- <item>"Standard"</item>
- <item>"Privat"</item>
- <item>"Öffentlich"</item>
- </string-array>
- <string-array name="day_labels">
- <item>"Sonntag"</item>
- <item>"Montag"</item>
- <item>"Dienstag"</item>
- <item>"Mittwoch"</item>
- <item>"Donnerstag"</item>
- <item>"Freitag"</item>
- <item>"Samstag"</item>
- </string-array>
- <string-array name="ordinal_labels">
- <item>"ersten"</item>
- <item>"zweiten"</item>
- <item>"dritten"</item>
- <item>"vierten"</item>
- <item>"letzten"</item>
- </string-array>
- <string-array name="response_labels1">
- <item>"(keine Antwort)"</item>
- <item>"Ja"</item>
- <item>"Vielleicht"</item>
- <item>"Nein"</item>
- </string-array>
- <string-array name="response_labels2">
- <item>"Ja"</item>
- <item>"Vielleicht"</item>
- <item>"Nein"</item>
- </string-array>
- <string-array name="delete_repeating_labels">
- <item>"Nur dieser Termin"</item>
- <item>"Dieser und zukünftige Termine"</item>
- <item>"Alle Termine"</item>
- </string-array>
- <string-array name="delete_repeating_labels_no_selected">
- <item>"Dieser und zukünftige Termine"</item>
- <item>"Alle Termine"</item>
- </string-array>
- <string-array name="change_response_labels">
- <item>"Nur diese Instanz"</item>
- <item>"Alle Termine dieser Serie"</item>
- </string-array>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label">"Kalender"</string>
- <string name="calendar_plug"><font fgcolor="#ffffffff">"Willkommen bei Google Kalender!"</font>" "\n"Ein Ansatz à la Google beim Verwalten Ihrer Termine, der zeigen soll, dass Terminverwaltung intuitiver, effizienter und einfacher sein kann."</string>
- <string name="what_label">"Was"</string>
- <string name="when_label">"Wann"</string>
- <string name="where_label">"Wo"</string>
- <string name="repeats_label">"Wiederholung"</string>
- <string name="no_title_label">"(kein Thema)"</string>
- <plurals name="Nminutes">
- <item quantity="one">"1 Minute"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> Minuten"</item>
- </plurals>
- <plurals name="Nmins">
- <item quantity="one">"1 Min."</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> Min."</item>
- </plurals>
- <plurals name="Nhours">
- <item quantity="one">"1 Stunde"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> Stunden"</item>
- </plurals>
- <plurals name="Ndays">
- <item quantity="one">"1 Tag"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> Tag(e)"</item>
- </plurals>
- <string name="show_agenda_view">"Terminübersicht anzeigen"</string>
- <string name="show_day_view">"Tag anzeigen"</string>
- <string name="agenda_view">"Terminübersicht"</string>
- <string name="day_view">"Tag"</string>
- <string name="week_view">"Woche"</string>
- <string name="month_view">"Monat"</string>
- <string name="event_view">"Termin anzeigen"</string>
- <string name="event_create">"Neuer Termin"</string>
- <string name="event_edit">"Termin bearbeiten"</string>
- <string name="event_delete">"Termin löschen"</string>
- <string name="goto_today">"Heute"</string>
- <string name="menu_select_calendars">"Meine Kalender"</string>
- <string name="menu_preferences">"Einstellungen"</string>
- <string name="plus_N_more">"(und <xliff:g id="MORE_COUNT">%d</xliff:g> weitere…)"</string>
- <string name="calendars_title">"Meine Kalender"</string>
- <string name="add_calendars">"Kalender hinzufügen"</string>
- <string name="remove_calendars">"Kalender entfernen"</string>
- <string name="event_edit_title">"Termindetails"</string>
- <string name="hint_what">"Terminname"</string>
- <string name="hint_where">"Ort des Termins"</string>
- <string name="hint_description">"Terminbeschreibung"</string>
- <string name="creating_event">"Termin wird erstellt…"</string>
- <string name="saving_event">"Termin wird gespeichert…"</string>
- <string name="loading_calendars_title">"Kalender werden geladen."</string>
- <string name="loading_calendars_message">"Kalender werden geladen..."</string>
- <string name="alert_when_label">"Wann:"</string>
- <string name="alert_where_label">"Wo:"</string>
- <string name="alert_missed_events_single">"(<xliff:g id="REMINDER_COUNT">%s</xliff:g> weitere Erinnerung)"</string>
- <string name="alert_missed_events_multiple">"(<xliff:g id="REMINDER_COUNT">%s</xliff:g> weitere Erinnerungen)"</string>
- <string name="event_info_title">"Termin anzeigen"</string>
- <string name="event_info_title_invite">"Einladung zu einer Besprechung"</string>
- <string name="add_new_reminder">"Erinnerung hinzufügen"</string>
- <string name="edit_event_to_label">"Bis"</string>
- <string name="edit_event_from_label">"Von"</string>
- <string name="edit_event_all_day_label">"Ganztägig"</string>
- <string name="edit_event_calendar_label">"Kalender"</string>
- <string name="edit_event_show_extra_options">"Zusätzliche Optionen anzeigen"</string>
- <string name="edit_event_hide_extra_options">"Zusätzliche Optionen ausblenden"</string>
- <string name="description_label">"Beschreibung"</string>
- <string name="presence_label">"Status"</string>
- <string name="privacy_label">"Datenschutz"</string>
- <string name="reminders_label">"Erinnerungen"</string>
- <string name="no_syncable_calendars">"Keine Kalender"</string>
- <string name="no_calendars_found">"Sie haben keine Kalender."</string>
- <string name="view_event_calendar_label">"Kalender"</string>
- <string name="view_event_timezone_label">"Lokalzeit"</string>
- <string name="view_event_response_label">"Teilnahme?"</string>
- <string name="agenda_today">"Heute"</string>
- <string name="num_events">"Anzahl Termine"</string>
- <string name="edit_event_label">"Termin bearbeiten"</string>
- <string name="delete_label">"Löschen"</string>
- <string name="delete_event_label">"Termin löschen"</string>
- <string name="save_label">"Speichern"</string>
- <string name="discard_label">"Änderungen verwerfen"</string>
- <string name="import_label">"Import"</string>
- <string name="snooze_all_label">"Später erinnern"</string>
- <string name="dismiss_all_label">"Alle schließen"</string>
- <string name="does_not_repeat">"Einmaliger Termin"</string>
- <string name="daily">"Täglich"</string>
- <string name="every_weekday">"Jeden Werktag (Mo. - Fr.)"</string>
- <string name="weekly">"Wöchentlich (jeden <xliff:g id="DAYS_OF_WEEK">%s</xliff:g>)"</string>
- <string name="monthly_on_day_count">"Monatlich (jeden <xliff:g id="ORDINAL_NUMBER">%1$s</xliff:g> <xliff:g id="DAY_OF_WEEK">%2$s</xliff:g>)"</string>
- <string name="monthly_on_day">"Monatlich (am <xliff:g id="DAY_OF_MONTH">%s</xliff:g>.)"</string>
- <string name="yearly">"Jährlich (am <xliff:g id="DATES">%s</xliff:g>)"</string>
- <string name="custom">"Benutzerdefiniert… (Anpassung über Telefon nicht möglich)"</string>
- <string name="modify_event">"Nur diesen Termin ändern"</string>
- <string name="modify_all">"Alle Termine in dieser Serie ändern"</string>
- <string name="modify_all_following">"Diesen und alle zukünftigen Termine ändern"</string>
- <string name="delete_this_event_title">"Dieser Termin wird gelöscht."</string>
- <string name="delete_title">"Löschen"</string>
- <string name="change_response_title">"Antwort ändern"</string>
- <string name="preferences_title">"Einstellungen"</string>
- <string name="preferences_general_title">"Einstellung für Kalenderansicht"</string>
- <string name="preferences_alerts_title">"Erinnerungseinstellungen"</string>
- <string name="preferences_hide_declined_title">"Abgelehnte Termine ausblenden"</string>
- <string name="preferences_alerts_type_title">"Benachrichtigungen und Hinweise festlegen"</string>
- <string name="preferences_alerts_type_dialog">"Benachrichtigungen und Hinweise"</string>
- <string name="preferences_alerts_vibrate_title">"Vibration"</string>
- <string name="preferences_alerts_ringtone_title">"Klingelton auswählen"</string>
- <string name="preferences_default_reminder_title">"Standarderinnerung festlegen"</string>
- <string name="preferences_default_reminder_dialog">"Standard-Erinnerungszeit"</string>
- <string name="preferences_default_reminder_default">"10"</string>
- <string name="gadget_calendar">"Kalender:"</string>
- <string name="gadget_now_event">"Jetzt: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_next_event">"Weiter: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_later_event">"Später: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <plurals name="gadget_more_events">
- <item quantity="one">"1 weiterer Termin"</item>
- <item quantity="other">"<xliff:g id="NUMBER">%d</xliff:g> weitere Termine"</item>
- </plurals>
- <string name="gadget_no_events">"Keine anstehenden Kalendertermine"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="reminder_minutes_labels">
- <item>"5 minutos"</item>
- <item>"10 minutos"</item>
- <item>"15 minutos"</item>
- <item>"20 minutos"</item>
- <item>"25 minutos"</item>
- <item>"30 minutos"</item>
- <item>"45 minutos"</item>
- <item>"1 hora"</item>
- <item>"2 horas"</item>
- <item>"3 horas"</item>
- <item>"12 horas"</item>
- <item>"24 horas"</item>
- <item>"2 días"</item>
- <item>"1 semana"</item>
- </string-array>
- <string-array name="reminder_minutes_values">
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_default_reminder_labels">
- <item>"Ninguno"</item>
- <item>"5 minutos"</item>
- <item>"10 minutos"</item>
- <item>"15 minutos"</item>
- <item>"20 minutos"</item>
- <item>"25 minutos"</item>
- <item>"30 minutos"</item>
- <item>"45 minutos"</item>
- <item>"1 hora"</item>
- <item>"2 horas"</item>
- <item>"3 horas"</item>
- <item>"12 horas"</item>
- <item>"24 horas"</item>
- <item>"2 días"</item>
- <item>"1 semana"</item>
- </string-array>
- <string-array name="preferences_default_reminder_values">
- <item>"0"</item>
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_alert_type_labels">
- <item>"Alertar"</item>
- <item>"Notificación de la barra de estado"</item>
- <item>"Desconectado"</item>
- </string-array>
- <string-array name="preferences_alert_type_values">
- <item>"0"</item>
- <item>"1"</item>
- <item>"2"</item>
- </string-array>
- <string-array name="availability">
- <item>"Ocupado"</item>
- <item>"Disponible"</item>
- </string-array>
- <string-array name="visibility">
- <item>"Predeterminado"</item>
- <item>"Privado"</item>
- <item>"Público"</item>
- </string-array>
- <string-array name="day_labels">
- <item>"Domingo"</item>
- <item>"Lunes"</item>
- <item>"Martes"</item>
- <item>"Miércoles"</item>
- <item>"Jueves"</item>
- <item>"Viernes"</item>
- <item>"Sábado"</item>
- </string-array>
- <string-array name="ordinal_labels">
- <item>"primero"</item>
- <item>"segundo"</item>
- <item>"tercero"</item>
- <item>"cuarto"</item>
- <item>"último"</item>
- </string-array>
- <string-array name="response_labels1">
- <item>"(No responde)"</item>
- <item>"Sí"</item>
- <item>"Quizás"</item>
- <item>"No"</item>
- </string-array>
- <string-array name="response_labels2">
- <item>"Sí"</item>
- <item>"Quizás"</item>
- <item>"No"</item>
- </string-array>
- <string-array name="delete_repeating_labels">
- <item>"Sólo este evento"</item>
- <item>"Este evento y eventos futuros"</item>
- <item>"Todos los eventos"</item>
- </string-array>
- <string-array name="delete_repeating_labels_no_selected">
- <item>"Éste y otros eventos posteriores"</item>
- <item>"Todos los eventos"</item>
- </string-array>
- <string-array name="change_response_labels">
- <item>"Sólo esta ocasión"</item>
- <item>"Todos los eventos de la serie"</item>
- </string-array>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label">"Calendario"</string>
- <string name="calendar_plug"><font fgcolor="#ffffffff">"Bienvenido a Google Calendar"</font>\n" Una propuesta de Google para gestionar su agenda basándonos en la idea de que la programación de los eventos puede ser más intuitiva, eficaz y accesible."</string>
- <string name="what_label">"Asunto"</string>
- <string name="when_label">"Cuándo"</string>
- <string name="where_label">"Dónde"</string>
- <string name="repeats_label">"Repetición"</string>
- <string name="no_title_label">"(Sin asunto)"</string>
- <plurals name="Nminutes">
- <item quantity="one">"1 minuto"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> minutos"</item>
- </plurals>
- <plurals name="Nmins">
- <item quantity="one">"1 minuto"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> minutos"</item>
- </plurals>
- <plurals name="Nhours">
- <item quantity="one">"1 hora"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> horas"</item>
- </plurals>
- <plurals name="Ndays">
- <item quantity="one">"1 día"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> días"</item>
- </plurals>
- <string name="show_agenda_view">"Mostrar agenda"</string>
- <string name="show_day_view">"Mostrar día"</string>
- <string name="agenda_view">"Agenda"</string>
- <string name="day_view">"Día"</string>
- <string name="week_view">"Semana"</string>
- <string name="month_view">"Mes"</string>
- <string name="event_view">"Ver evento"</string>
- <string name="event_create">"Evento nuevo"</string>
- <string name="event_edit">"Editar evento"</string>
- <string name="event_delete">"Suprimir evento"</string>
- <string name="goto_today">"Hoy"</string>
- <string name="menu_select_calendars">"Mis calendarios"</string>
- <string name="menu_preferences">"Ajustes"</string>
- <string name="plus_N_more">"(además de <xliff:g id="MORE_COUNT">%d</xliff:g> más...)"</string>
- <string name="calendars_title">"Mis calendarios"</string>
- <string name="add_calendars">"Añadir calendarios"</string>
- <string name="remove_calendars">"Eliminar calendarios"</string>
- <string name="event_edit_title">"Información del evento"</string>
- <string name="hint_what">"Nombre del evento"</string>
- <string name="hint_where">"Ubicación del evento"</string>
- <string name="hint_description">"Descripción del evento"</string>
- <string name="creating_event">"Creando evento..."</string>
- <string name="saving_event">"Guardando evento..."</string>
- <string name="loading_calendars_title">"Cargando calendarios"</string>
- <string name="loading_calendars_message">"Cargando calendarios..."</string>
- <string name="alert_when_label">"Cuándo:"</string>
- <string name="alert_where_label">"Dónde:"</string>
- <string name="alert_missed_events_single">"(<xliff:g id="REMINDER_COUNT">%s</xliff:g> más recordatorios)"</string>
- <string name="alert_missed_events_multiple">"(<xliff:g id="REMINDER_COUNT">%s</xliff:g> más recordatorios)"</string>
- <string name="event_info_title">"Ver evento"</string>
- <string name="event_info_title_invite">"Invitación a un evento"</string>
- <string name="add_new_reminder">"Añadir recordatorio"</string>
- <string name="edit_event_to_label">"Hasta"</string>
- <string name="edit_event_from_label">"Desde"</string>
- <string name="edit_event_all_day_label">"Todo el día"</string>
- <string name="edit_event_calendar_label">"Calendario"</string>
- <string name="edit_event_show_extra_options">"Mostrar opciones extra"</string>
- <string name="edit_event_hide_extra_options">"Ocultar opciones extra"</string>
- <string name="description_label">"Descripción"</string>
- <string name="presence_label">"Presencia"</string>
- <string name="privacy_label">"Privacidad"</string>
- <string name="reminders_label">"Recordatorios"</string>
- <string name="no_syncable_calendars">"No hay calendarios."</string>
- <string name="no_calendars_found">"No tienes ningún calendario."</string>
- <string name="view_event_calendar_label">"Calendario"</string>
- <string name="view_event_timezone_label">"Zona horaria local"</string>
- <string name="view_event_response_label">"¿Asistiendo?"</string>
- <string name="agenda_today">"Hoy"</string>
- <string name="num_events">"Número de eventos"</string>
- <string name="edit_event_label">"Editar evento"</string>
- <string name="delete_label">"Eliminar"</string>
- <string name="delete_event_label">"Suprimir evento"</string>
- <string name="save_label">"Guardar"</string>
- <string name="discard_label">"Descartar cambios"</string>
- <string name="import_label">"Importar"</string>
- <string name="snooze_all_label">"Posponer todos"</string>
- <string name="dismiss_all_label">"Descartar todas"</string>
- <string name="does_not_repeat">"Evento único"</string>
- <string name="daily">"Cada día"</string>
- <string name="every_weekday">"Cada día laboral (lunes-viernes)"</string>
- <string name="weekly">"Cada semana (todos los <xliff:g id="DAYS_OF_WEEK">%s</xliff:g>)"</string>
- <string name="monthly_on_day_count">"Cada mes (todos los <xliff:g id="ORDINAL_NUMBER">%1$s</xliff:g><xliff:g id="DAY_OF_WEEK">%2$s</xliff:g>)"</string>
- <string name="monthly_on_day">"Cada mes (el día <xliff:g id="DAY_OF_MONTH">%s</xliff:g>)"</string>
- <string name="yearly">"Cada año (el <xliff:g id="DATES">%s</xliff:g>)"</string>
- <string name="custom">"Personalizado... (no se puede personalizar por teléfono)"</string>
- <string name="modify_event">"Cambiar sólo este evento"</string>
- <string name="modify_all">"Cambiar todos los eventos de la serie"</string>
- <string name="modify_all_following">"Cambiar éste y todos los eventos futuros"</string>
- <string name="delete_this_event_title">"Este evento se suprimirá."</string>
- <string name="delete_title">"Eliminar"</string>
- <string name="change_response_title">"Cambiar respuesta"</string>
- <string name="preferences_title">"Ajustes"</string>
- <string name="preferences_general_title">"Configuración de la vista de calendario"</string>
- <string name="preferences_alerts_title">"Configuración de los recordatorios"</string>
- <string name="preferences_hide_declined_title">"Ocultar eventos rechazados"</string>
- <string name="preferences_alerts_type_title">"Configurar notificaciones y alertas"</string>
- <string name="preferences_alerts_type_dialog">"Alertas y notificaciones"</string>
- <string name="preferences_alerts_vibrate_title">"Vibrar"</string>
- <string name="preferences_alerts_ringtone_title">"Seleccionar tono"</string>
- <string name="preferences_default_reminder_title">"Configurar recordatorio predeterminado"</string>
- <string name="preferences_default_reminder_dialog">"Duración predeterminada del recordatorio"</string>
- <string name="preferences_default_reminder_default">"10"</string>
- <string name="gadget_calendar">"Calendario:"</string>
- <string name="gadget_now_event">"Ahora: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_next_event">"Siguiente: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_later_event">"Posterior: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <plurals name="gadget_more_events">
- <item quantity="one">"Un evento más"</item>
- <item quantity="other">"<xliff:g id="NUMBER">%d</xliff:g> eventos más"</item>
- </plurals>
- <string name="gadget_no_events">"No hay próximos eventos en el calendario"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="reminder_minutes_labels">
- <item>"5 minutes"</item>
- <item>"10 minutes"</item>
- <item>"15 minutes"</item>
- <item>"20 minutes"</item>
- <item>"25 minutes"</item>
- <item>"30 minutes"</item>
- <item>"45 minutes"</item>
- <item>"1 heure"</item>
- <item>"2 heures"</item>
- <item>"3 heures"</item>
- <item>"12 heures"</item>
- <item>"24 heures"</item>
- <item>"2 jours"</item>
- <item>"1 semaine"</item>
- </string-array>
- <string-array name="reminder_minutes_values">
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_default_reminder_labels">
- <item>"Aucun"</item>
- <item>"5 minutes"</item>
- <item>"10 minutes"</item>
- <item>"15 minutes"</item>
- <item>"20 minutes"</item>
- <item>"25 minutes"</item>
- <item>"30 minutes"</item>
- <item>"45 minutes"</item>
- <item>"1 heure"</item>
- <item>"2 heures"</item>
- <item>"3 heures"</item>
- <item>"12 heures"</item>
- <item>"24 heures"</item>
- <item>"2 jours"</item>
- <item>"1 semaine"</item>
- </string-array>
- <string-array name="preferences_default_reminder_values">
- <item>"0"</item>
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_alert_type_labels">
- <item>"Alerte"</item>
- <item>"Notification de barre d\'état"</item>
- <item>"Désactivé"</item>
- </string-array>
- <string-array name="preferences_alert_type_values">
- <item>"0"</item>
- <item>"1"</item>
- <item>"2"</item>
- </string-array>
- <string-array name="availability">
- <item>"Occupé"</item>
- <item>"Disponible"</item>
- </string-array>
- <string-array name="visibility">
- <item>"Par défaut"</item>
- <item>"Privé"</item>
- <item>"Public"</item>
- </string-array>
- <string-array name="day_labels">
- <item>"dimanche"</item>
- <item>"lundi"</item>
- <item>"mardi"</item>
- <item>"mercredi"</item>
- <item>"jeudi"</item>
- <item>"vendredi"</item>
- <item>"samedi"</item>
- </string-array>
- <string-array name="ordinal_labels">
- <item>"premier"</item>
- <item>"seconde"</item>
- <item>"troisième"</item>
- <item>"quatrième"</item>
- <item>"dernier"</item>
- </string-array>
- <string-array name="response_labels1">
- <item>"(Aucune réponse)"</item>
- <item>"Oui"</item>
- <item>"Peut-être"</item>
- <item>"Non"</item>
- </string-array>
- <string-array name="response_labels2">
- <item>"Oui"</item>
- <item>"Peut-être"</item>
- <item>"Non"</item>
- </string-array>
- <string-array name="delete_repeating_labels">
- <item>"Uniquement cet événement"</item>
- <item>"Cet événement et les suivants"</item>
- <item>"Tous les événements"</item>
- </string-array>
- <string-array name="delete_repeating_labels_no_selected">
- <item>"Cet événement et les suivants"</item>
- <item>"Tous les événements"</item>
- </string-array>
- <string-array name="change_response_labels">
- <item>"Uniquement cette instance"</item>
- <item>"Tous les événements de la série"</item>
- </string-array>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label">"Google Agenda"</string>
- <string name="calendar_plug"><font fgcolor="#ffffffff">"Bienvenue dans Google Agenda !"</font>" "\n"La solution de Google pour gérer votre emploi du temps en planifiant vos événements de manière plus intuitive, efficace et directe."</string>
- <string name="what_label">"Objet"</string>
- <string name="when_label">"Date"</string>
- <string name="where_label">"Lieu"</string>
- <string name="repeats_label">"Fréquence"</string>
- <string name="no_title_label">"(Aucun objet)"</string>
- <plurals name="Nminutes">
- <item quantity="one">"1 minute"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> minutes"</item>
- </plurals>
- <plurals name="Nmins">
- <item quantity="one">"1 mn"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> mn"</item>
- </plurals>
- <plurals name="Nhours">
- <item quantity="one">"1 heure"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> heures"</item>
- </plurals>
- <plurals name="Ndays">
- <item quantity="one">"1 jour"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> jours"</item>
- </plurals>
- <string name="show_agenda_view">"Afficher le planning"</string>
- <string name="show_day_view">"Afficher le jour"</string>
- <string name="agenda_view">"Agenda"</string>
- <string name="day_view">"Jour"</string>
- <string name="week_view">"Semaine"</string>
- <string name="month_view">"Mois"</string>
- <string name="event_view">"Afficher l\'événement"</string>
- <string name="event_create">"Nouvel événement"</string>
- <string name="event_edit">"Modifier l\'événement"</string>
- <string name="event_delete">"Supprimer l\'événement"</string>
- <string name="goto_today">"Aujourd\'hui"</string>
- <string name="menu_select_calendars">"Mes agendas"</string>
- <string name="menu_preferences">"Paramètres"</string>
- <string name="plus_N_more">"(et <xliff:g id="MORE_COUNT">%d</xliff:g> autres…)"</string>
- <string name="calendars_title">"Mes agendas"</string>
- <string name="add_calendars">"Ajouter des agendas"</string>
- <string name="remove_calendars">"Supprimer les agendas"</string>
- <string name="event_edit_title">"Détails sur l\'événement"</string>
- <string name="hint_what">"Nom de l\'événement"</string>
- <string name="hint_where">"Lieu de l\'événement"</string>
- <string name="hint_description">"Description de l\'événement"</string>
- <string name="creating_event">"Création de l\'événement…"</string>
- <string name="saving_event">"Enregistrement de l\'événement…"</string>
- <string name="loading_calendars_title">"Chargement des agendas"</string>
- <string name="loading_calendars_message">"Chargement des agendas..."</string>
- <string name="alert_when_label">"Date :"</string>
- <string name="alert_where_label">"Lieu :"</string>
- <string name="alert_missed_events_single">"(<xliff:g id="REMINDER_COUNT">%s</xliff:g> rappel supplémentaire)"</string>
- <string name="alert_missed_events_multiple">"(<xliff:g id="REMINDER_COUNT">%s</xliff:g> rappels supplémentaires)"</string>
- <string name="event_info_title">"Afficher l\'événement"</string>
- <string name="event_info_title_invite">"Invitation à une réunion"</string>
- <string name="add_new_reminder">"Ajouter un rappel"</string>
- <string name="edit_event_to_label">"Au"</string>
- <string name="edit_event_from_label">"Du"</string>
- <string name="edit_event_all_day_label">"Journée entière"</string>
- <string name="edit_event_calendar_label">"Agenda"</string>
- <string name="edit_event_show_extra_options">"Afficher les options supplémentaires"</string>
- <string name="edit_event_hide_extra_options">"Masquer les options supplémentaires"</string>
- <string name="description_label">"Description"</string>
- <string name="presence_label">"Présence"</string>
- <string name="privacy_label">"Confidentialité"</string>
- <string name="reminders_label">"Rappels"</string>
- <string name="no_syncable_calendars">"Pas d\'agenda"</string>
- <string name="no_calendars_found">"Vous n\'avez pas d\'agenda."</string>
- <string name="view_event_calendar_label">"Agenda"</string>
- <string name="view_event_timezone_label">"Fuseau horaire local"</string>
- <string name="view_event_response_label">"Participation ?"</string>
- <string name="agenda_today">"Aujourd\'hui"</string>
- <string name="num_events">"Nbre d\'événements"</string>
- <string name="edit_event_label">"Modifier l\'événement"</string>
- <string name="delete_label">"Supprimer"</string>
- <string name="delete_event_label">"Supprimer l\'événement"</string>
- <string name="save_label">"Enregistrer"</string>
- <string name="discard_label">"Ignorer les modifications"</string>
- <string name="import_label">"Importer"</string>
- <string name="snooze_all_label">"Tout mettre en attente"</string>
- <string name="dismiss_all_label">"Tout supprimer"</string>
- <string name="does_not_repeat">"Événement ponctuel"</string>
- <string name="daily">"Quotidien"</string>
- <string name="every_weekday">"Chaque jour de semaine (lun–ven)"</string>
- <string name="weekly">"Hebdomadaire (chaque <xliff:g id="DAYS_OF_WEEK">%s</xliff:g>)"</string>
- <string name="monthly_on_day_count">"Mensuel (chaque <xliff:g id="ORDINAL_NUMBER">%1$s</xliff:g> <xliff:g id="DAY_OF_WEEK">%2$s</xliff:g>)"</string>
- <string name="monthly_on_day">"Mensuel (le <xliff:g id="DAY_OF_MONTH">%s</xliff:g>)"</string>
- <string name="yearly">"Annuel (le <xliff:g id="DATES">%s</xliff:g>)"</string>
- <string name="custom">"Personnalisé… (paramétrage impossible avec un téléphone)"</string>
- <string name="modify_event">"Modifier uniquement cet événement."</string>
- <string name="modify_all">"Modifier tous les événements de la série."</string>
- <string name="modify_all_following">"Modifier cet événement et tous les suivants."</string>
- <string name="delete_this_event_title">"Cet événement va être supprimé."</string>
- <string name="delete_title">"Supprimer"</string>
- <string name="change_response_title">"Modifier la réponse"</string>
- <string name="preferences_title">"Paramètres"</string>
- <string name="preferences_general_title">"Paramètre d\'affichage de l\'agenda"</string>
- <string name="preferences_alerts_title">"Paramètres de rappel"</string>
- <string name="preferences_hide_declined_title">"Masquer les événements refusés"</string>
- <string name="preferences_alerts_type_title">"Définir les alertes et les notifications"</string>
- <string name="preferences_alerts_type_dialog">"Alertes et notifications"</string>
- <string name="preferences_alerts_vibrate_title">"Vibreur"</string>
- <string name="preferences_alerts_ringtone_title">"Sélectionner la sonnerie"</string>
- <string name="preferences_default_reminder_title">"Définir le rappel par défaut"</string>
- <string name="preferences_default_reminder_dialog">"Intervalle de rappel par défaut"</string>
- <string name="preferences_default_reminder_default">"10"</string>
- <string name="gadget_calendar">"Agenda :"</string>
- <string name="gadget_now_event">"Maintenant : <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_next_event">"Suivant : <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_later_event">"Plus tard : <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <plurals name="gadget_more_events">
- <item quantity="one">"1 événement supplémentaire"</item>
- <item quantity="other">"<xliff:g id="NUMBER">%d</xliff:g> autres événements"</item>
- </plurals>
- <string name="gadget_no_events">"Aucun événement d\'agenda à venir"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="reminder_minutes_labels">
- <item>"5 minuti"</item>
- <item>"10 minuti"</item>
- <item>"15 minuti"</item>
- <item>"20 minuti"</item>
- <item>"25 minuti"</item>
- <item>"30 minuti"</item>
- <item>"45 minuti"</item>
- <item>"1 ora"</item>
- <item>"2 ore"</item>
- <item>"3 ore"</item>
- <item>"12 ore"</item>
- <item>"24 ore"</item>
- <item>"2 giorni"</item>
- <item>"1 settimana"</item>
- </string-array>
- <string-array name="reminder_minutes_values">
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_default_reminder_labels">
- <item>"Nessuno"</item>
- <item>"5 minuti"</item>
- <item>"10 minuti"</item>
- <item>"15 minuti"</item>
- <item>"20 minuti"</item>
- <item>"25 minuti"</item>
- <item>"30 minuti"</item>
- <item>"45 minuti"</item>
- <item>"1 ora"</item>
- <item>"2 ore"</item>
- <item>"3 ore"</item>
- <item>"12 ore"</item>
- <item>"24 ore"</item>
- <item>"2 giorni"</item>
- <item>"1 settimana"</item>
- </string-array>
- <string-array name="preferences_default_reminder_values">
- <item>"0"</item>
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_alert_type_labels">
- <item>"Avviso"</item>
- <item>"Notifica barra di stato"</item>
- <item>"Disattivato"</item>
- </string-array>
- <string-array name="preferences_alert_type_values">
- <item>"0"</item>
- <item>"1"</item>
- <item>"2"</item>
- </string-array>
- <string-array name="availability">
- <item>"Occupato"</item>
- <item>"Disponibile"</item>
- </string-array>
- <string-array name="visibility">
- <item>"Predefinito"</item>
- <item>"Privato"</item>
- <item>"Pubblico"</item>
- </string-array>
- <string-array name="day_labels">
- <item>"Domenica"</item>
- <item>"Lunedì"</item>
- <item>"Martedì"</item>
- <item>"Mercoledì"</item>
- <item>"Giovedì"</item>
- <item>"Venerdì"</item>
- <item>"Sabato"</item>
- </string-array>
- <string-array name="ordinal_labels">
- <item>"primo"</item>
- <item>"secondo"</item>
- <item>"terzo"</item>
- <item>"quarto"</item>
- <item>"ultimo"</item>
- </string-array>
- <string-array name="response_labels1">
- <item>"(Nessuna risposta)"</item>
- <item>"Sì"</item>
- <item>"Forse"</item>
- <item>"No"</item>
- </string-array>
- <string-array name="response_labels2">
- <item>"Sì"</item>
- <item>"Forse"</item>
- <item>"No"</item>
- </string-array>
- <string-array name="delete_repeating_labels">
- <item>"Solo questo evento"</item>
- <item>"Questo e gli eventi futuri"</item>
- <item>"Tutti gli eventi"</item>
- </string-array>
- <string-array name="delete_repeating_labels_no_selected">
- <item>"Questo e gli eventi futuri"</item>
- <item>"Tutti gli eventi"</item>
- </string-array>
- <string-array name="change_response_labels">
- <item>"Solo questa istanza"</item>
- <item>"Tutti gli eventi nella serie"</item>
- </string-array>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label">"Calendario"</string>
- <string name="calendar_plug"><font fgcolor="#ffffffff">"Benvenuto in Google Calendar!"</font>" "\n"Un approccio di Google alla gestione della tua pianificazione in base all\'idea che gli eventi di pianificazione possano essere più intuitivi, efficaci e accessibili."</string>
- <string name="what_label">"Titolo"</string>
- <string name="when_label">"Intervallo di tempo"</string>
- <string name="where_label">"Posizione"</string>
- <string name="repeats_label">"Ripetizione"</string>
- <string name="no_title_label">"(Nessun oggetto)"</string>
- <plurals name="Nminutes">
- <item quantity="one">"1 minuto"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> minuti"</item>
- </plurals>
- <plurals name="Nmins">
- <item quantity="one">"1 min"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> min"</item>
- </plurals>
- <plurals name="Nhours">
- <item quantity="one">"1 ora"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> ore"</item>
- </plurals>
- <plurals name="Ndays">
- <item quantity="one">"1 giorno"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> giorni"</item>
- </plurals>
- <string name="show_agenda_view">"Mostra agenda"</string>
- <string name="show_day_view">"Mostra giorno"</string>
- <string name="agenda_view">"Agenda"</string>
- <string name="day_view">"Giorno"</string>
- <string name="week_view">"Settimana"</string>
- <string name="month_view">"Mese"</string>
- <string name="event_view">"Visualizza evento"</string>
- <string name="event_create">"Nuovo evento"</string>
- <string name="event_edit">"Modifica evento"</string>
- <string name="event_delete">"Elimina evento"</string>
- <string name="goto_today">"Oggi"</string>
- <string name="menu_select_calendars">"I miei calendari"</string>
- <string name="menu_preferences">"Impostazioni"</string>
- <string name="plus_N_more">"(più altri <xliff:g id="MORE_COUNT">%d</xliff:g>…)"</string>
- <string name="calendars_title">"I miei calendari"</string>
- <string name="add_calendars">"Aggiungi calendari"</string>
- <string name="remove_calendars">"Rimuovi calendari"</string>
- <string name="event_edit_title">"Dettagli evento"</string>
- <string name="hint_what">"Nome evento"</string>
- <string name="hint_where">"Luogo evento"</string>
- <string name="hint_description">"Descrizione evento"</string>
- <string name="creating_event">"Creazione evento in corso…"</string>
- <string name="saving_event">"Salvataggio evento in corso…"</string>
- <string name="loading_calendars_title">"Caricamento calendari"</string>
- <string name="loading_calendars_message">"Caricamento calendari in corso..."</string>
- <string name="alert_when_label">"Intervallo di tempo:"</string>
- <string name="alert_where_label">"Posizione:"</string>
- <string name="alert_missed_events_single">"(Altri <xliff:g id="REMINDER_COUNT">%s</xliff:g> promemoria)"</string>
- <string name="alert_missed_events_multiple">"(Altri <xliff:g id="REMINDER_COUNT">%s</xliff:g> promemoria)"</string>
- <string name="event_info_title">"Visualizza evento"</string>
- <string name="event_info_title_invite">"Invito a riunione"</string>
- <string name="add_new_reminder">"Aggiungi promemoria"</string>
- <string name="edit_event_to_label">"A"</string>
- <string name="edit_event_from_label">"Da"</string>
- <string name="edit_event_all_day_label">"Tutto il giorno"</string>
- <string name="edit_event_calendar_label">"Calendario"</string>
- <string name="edit_event_show_extra_options">"Mostra opzioni aggiuntive"</string>
- <string name="edit_event_hide_extra_options">"Nascondi opzioni aggiuntive"</string>
- <string name="description_label">"Descrizione"</string>
- <string name="presence_label">"Presenza"</string>
- <string name="privacy_label">"Privacy"</string>
- <string name="reminders_label">"Promemoria"</string>
- <string name="no_syncable_calendars">"Nessun calendario"</string>
- <string name="no_calendars_found">"Non sono presenti calendari."</string>
- <string name="view_event_calendar_label">"Calendario"</string>
- <string name="view_event_timezone_label">"Fuso orario locale"</string>
- <string name="view_event_response_label">"Partecipanti?"</string>
- <string name="agenda_today">"Oggi"</string>
- <string name="num_events">"N. eventi"</string>
- <string name="edit_event_label">"Modifica evento"</string>
- <string name="delete_label">"Elimina"</string>
- <string name="delete_event_label">"Elimina evento"</string>
- <string name="save_label">"Salva"</string>
- <string name="discard_label">"Ignora modifiche"</string>
- <string name="import_label">"Importa"</string>
- <string name="snooze_all_label">"Posponi tutto"</string>
- <string name="dismiss_all_label">"Ignora tutto"</string>
- <string name="does_not_repeat">"Evento occasionale"</string>
- <string name="daily">"Ogni giorno"</string>
- <string name="every_weekday">"Ogni giorno della settimana (Lun-Ven)"</string>
- <string name="weekly">"Ogni settimana (ogni <xliff:g id="DAYS_OF_WEEK">%s</xliff:g>)"</string>
- <string name="monthly_on_day_count">"Ogni mese (ogni <xliff:g id="ORDINAL_NUMBER">%1$s</xliff:g><xliff:g id="DAY_OF_WEEK">%2$s</xliff:g>"</string>
- <string name="monthly_on_day">"Ogni mese (il <xliff:g id="DAY_OF_MONTH">%s</xliff:g>)"</string>
- <string name="yearly">"Ogni anno (il <xliff:g id="DATES">%s</xliff:g>"</string>
- <string name="custom">"Personalizzato… (impossibile personalizzare sul telefono)"</string>
- <string name="modify_event">"Modifica solo questo evento."</string>
- <string name="modify_all">"Modifica tutti gli eventi nelle serie."</string>
- <string name="modify_all_following">"Modifica questo e tutti gli eventi futuri."</string>
- <string name="delete_this_event_title">"L\'evento verrà eliminato."</string>
- <string name="delete_title">"Elimina"</string>
- <string name="change_response_title">"Cambia risposta"</string>
- <string name="preferences_title">"Impostazioni"</string>
- <string name="preferences_general_title">"Impostazione visualizzazione calendario"</string>
- <string name="preferences_alerts_title">"Impostazioni promemoria"</string>
- <string name="preferences_hide_declined_title">"Nascondi eventi rifiutati"</string>
- <string name="preferences_alerts_type_title">"Imposta avvisi e notifiche"</string>
- <string name="preferences_alerts_type_dialog">"Avvisi e notifiche"</string>
- <string name="preferences_alerts_vibrate_title">"Vibrazione"</string>
- <string name="preferences_alerts_ringtone_title">"Seleziona suoneria"</string>
- <string name="preferences_default_reminder_title">"Imposta promemoria predefinito"</string>
- <string name="preferences_default_reminder_dialog">"Orario promemoria predefinito"</string>
- <string name="preferences_default_reminder_default">"10"</string>
- <string name="gadget_calendar">"Calendario:"</string>
- <string name="gadget_now_event">"Adesso: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_next_event">"Successivo: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_later_event">"Successivo: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <plurals name="gadget_more_events">
- <item quantity="one">"1 altro evento"</item>
- <item quantity="other">"<xliff:g id="NUMBER">%d</xliff:g> altri eventi"</item>
- </plurals>
- <string name="gadget_no_events">"Nessun evento di calendario imminente"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="reminder_minutes_labels">
- <item>"5分"</item>
- <item>"10分"</item>
- <item>"15分"</item>
- <item>"20分"</item>
- <item>"25分"</item>
- <item>"30分"</item>
- <item>"45分"</item>
- <item>"1時間"</item>
- <item>"2時間"</item>
- <item>"3時間"</item>
- <item>"12時間"</item>
- <item>"24時間"</item>
- <item>"2日"</item>
- <item>"1週間"</item>
- </string-array>
- <string-array name="reminder_minutes_values">
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1,440"</item>
- <item>"2,880"</item>
- <item>"10,080"</item>
- </string-array>
- <string-array name="preferences_default_reminder_labels">
- <item>"なし"</item>
- <item>"5分"</item>
- <item>"10分"</item>
- <item>"15分"</item>
- <item>"20分"</item>
- <item>"25分"</item>
- <item>"30分"</item>
- <item>"45分"</item>
- <item>"1時間"</item>
- <item>"2時間"</item>
- <item>"3時間"</item>
- <item>"12時間"</item>
- <item>"24時間"</item>
- <item>"2日"</item>
- <item>"1週間"</item>
- </string-array>
- <string-array name="preferences_default_reminder_values">
- <item>"0"</item>
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1,440"</item>
- <item>"2,880"</item>
- <item>"10,080"</item>
- </string-array>
- <string-array name="preferences_alert_type_labels">
- <item>"アラート"</item>
- <item>"ステータスバーの通知"</item>
- <item>"オフ"</item>
- </string-array>
- <string-array name="preferences_alert_type_values">
- <item>"0"</item>
- <item>"1"</item>
- <item>"2"</item>
- </string-array>
- <string-array name="availability">
- <item>"予定あり"</item>
- <item>"予定なし"</item>
- </string-array>
- <string-array name="visibility">
- <item>"既定"</item>
- <item>"限定公開"</item>
- <item>"一般公開"</item>
- </string-array>
- <string-array name="day_labels">
- <item>"日曜日"</item>
- <item>"月曜日"</item>
- <item>"火曜日"</item>
- <item>"水曜日"</item>
- <item>"木曜日"</item>
- <item>"金曜日"</item>
- <item>"土曜日"</item>
- </string-array>
- <string-array name="ordinal_labels">
- <item>"第1"</item>
- <item>"第2"</item>
- <item>"第3"</item>
- <item>"第4"</item>
- <item>"最終"</item>
- </string-array>
- <string-array name="response_labels1">
- <item>"(返答なし)"</item>
- <item>"はい"</item>
- <item>"未定"</item>
- <item>"いいえ"</item>
- </string-array>
- <string-array name="response_labels2">
- <item>"はい"</item>
- <item>"未定"</item>
- <item>"いいえ"</item>
- </string-array>
- <string-array name="delete_repeating_labels">
- <item>"この予定のみ"</item>
- <item>"これ以降の予定"</item>
- <item>"すべての予定"</item>
- </string-array>
- <string-array name="delete_repeating_labels_no_selected">
- <item>"これ以降の予定"</item>
- <item>"すべての予定"</item>
- </string-array>
- <string-array name="change_response_labels">
- <item>"今回のみ"</item>
- <item>"一連の定期的な予定すべて"</item>
- </string-array>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label">"カレンダー"</string>
- <string name="calendar_plug"><font fgcolor="#ffffffff">"Googleカレンダーにようこそ"</font>" "\n"いつでもどこでも簡単にスケジュールを管理できます。"</string>
- <string name="what_label">"タイトル"</string>
- <string name="when_label">"日時"</string>
- <string name="where_label">"場所"</string>
- <string name="repeats_label">"繰り返し"</string>
- <string name="no_title_label">"(無題)"</string>
- <plurals name="Nminutes">
- <item quantity="one">"1分"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>分"</item>
- </plurals>
- <plurals name="Nmins">
- <item quantity="one">"1分"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>分"</item>
- </plurals>
- <plurals name="Nhours">
- <item quantity="one">"1時間"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>時間"</item>
- </plurals>
- <plurals name="Ndays">
- <item quantity="one">"1日"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>日"</item>
- </plurals>
- <string name="show_agenda_view">"予定リストを表示"</string>
- <string name="show_day_view">"日付を表示"</string>
- <string name="agenda_view">"予定リスト"</string>
- <string name="day_view">"日"</string>
- <string name="week_view">"週"</string>
- <string name="month_view">"月"</string>
- <string name="event_view">"予定を表示"</string>
- <string name="event_create">"新しい予定"</string>
- <string name="event_edit">"予定を編集"</string>
- <string name="event_delete">"予定を削除"</string>
- <string name="goto_today">"今日"</string>
- <string name="menu_select_calendars">"マイ カレンダー"</string>
- <string name="menu_preferences">"設定"</string>
- <string name="plus_N_more">"(あと <xliff:g id="MORE_COUNT">%d</xliff:g> 件...)"</string>
- <string name="calendars_title">"マイ カレンダー"</string>
- <string name="add_calendars">"カレンダーを追加"</string>
- <string name="remove_calendars">"カレンダーを削除"</string>
- <string name="event_edit_title">"予定の詳細"</string>
- <string name="hint_what">"予定の名前"</string>
- <string name="hint_where">"予定の場所"</string>
- <string name="hint_description">"予定の説明"</string>
- <string name="creating_event">"予定を作成中..."</string>
- <string name="saving_event">"予定を保存中..."</string>
- <string name="loading_calendars_title">"カレンダーを読み込み中"</string>
- <string name="loading_calendars_message">"カレンダーを読み込み中..."</string>
- <string name="alert_when_label">"日時:"</string>
- <string name="alert_where_label">"場所:"</string>
- <string name="alert_missed_events_single">"(<xliff:g id="REMINDER_COUNT">%s</xliff:g> 件の通知がありました)"</string>
- <string name="alert_missed_events_multiple">"(<xliff:g id="REMINDER_COUNT">%s</xliff:g> 件の通知がありました)"</string>
- <string name="event_info_title">"予定を表示"</string>
- <string name="event_info_title_invite">"会議への招待状"</string>
- <string name="add_new_reminder">"通知を追加"</string>
- <string name="edit_event_to_label">"終了"</string>
- <string name="edit_event_from_label">"開始"</string>
- <string name="edit_event_all_day_label">"終日"</string>
- <string name="edit_event_calendar_label">"カレンダー"</string>
- <string name="edit_event_show_extra_options">"追加のオプションを表示する"</string>
- <string name="edit_event_hide_extra_options">"追加のオプションを表示しない"</string>
- <string name="description_label">"説明"</string>
- <string name="presence_label">"ステータス"</string>
- <string name="privacy_label">"プライバシー"</string>
- <string name="reminders_label">"通知"</string>
- <string name="no_syncable_calendars">"カレンダーがありません"</string>
- <string name="no_calendars_found">"カレンダーがありません。"</string>
- <string name="view_event_calendar_label">"カレンダー"</string>
- <string name="view_event_timezone_label">"ローカルタイムゾーン"</string>
- <string name="view_event_response_label">"参加しますか?"</string>
- <string name="agenda_today">"今日"</string>
- <string name="num_events">"予定数"</string>
- <string name="edit_event_label">"予定を編集"</string>
- <string name="delete_label">"削除"</string>
- <string name="delete_event_label">"予定を削除"</string>
- <string name="save_label">"保存"</string>
- <string name="discard_label">"変更取消"</string>
- <string name="import_label">"インポート"</string>
- <string name="snooze_all_label">"すべてスヌーズ"</string>
- <string name="dismiss_all_label">"すべて表示しない"</string>
- <string name="does_not_repeat">"一度だけの予定"</string>
- <string name="daily">"毎日"</string>
- <string name="every_weekday">"平日(月~金)"</string>
- <string name="weekly">"毎週(<xliff:g id="DAYS_OF_WEEK">%s</xliff:g>)"</string>
- <string name="monthly_on_day_count">"毎月(<xliff:g id="ORDINAL_NUMBER">%1$s</xliff:g> <xliff:g id="DAY_OF_WEEK">%2$s</xliff:g>)"</string>
- <string name="monthly_on_day">"毎月(<xliff:g id="DAY_OF_MONTH">%s</xliff:g>日)"</string>
- <string name="yearly">"毎年(<xliff:g id="DATES">%s</xliff:g>)"</string>
- <string name="custom">"カスタム…(携帯端末ではカスタマイズ不可)"</string>
- <string name="modify_event">"この予定のみを変更します。"</string>
- <string name="modify_all">"一連の定期的な予定すべてを削除します。"</string>
- <string name="modify_all_following">"これ以降の予定すべてを削除します。"</string>
- <string name="delete_this_event_title">"この予定を削除します。"</string>
- <string name="delete_title">"削除"</string>
- <string name="change_response_title">"返答を変更"</string>
- <string name="preferences_title">"設定"</string>
- <string name="preferences_general_title">"カレンダーの表示の設定"</string>
- <string name="preferences_alerts_title">"通知の設定"</string>
- <string name="preferences_hide_declined_title">"辞退した予定を非表示"</string>
- <string name="preferences_alerts_type_title">"アラートと通知を設定"</string>
- <string name="preferences_alerts_type_dialog">"アラートと通知"</string>
- <string name="preferences_alerts_vibrate_title">"バイブレーション"</string>
- <string name="preferences_alerts_ringtone_title">"着信音を選択"</string>
- <string name="preferences_default_reminder_title">"通知設定"</string>
- <string name="preferences_default_reminder_dialog">"デフォルトの通知時間"</string>
- <string name="preferences_default_reminder_default">"10"</string>
- <string name="gadget_calendar">"カレンダー:"</string>
- <string name="gadget_now_event">"現在時刻: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_next_event">"次へ: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_later_event">"後で: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <plurals name="gadget_more_events">
- <item quantity="one">"他1件"</item>
- <item quantity="other">"他<xliff:g id="NUMBER">%d</xliff:g>件"</item>
- </plurals>
- <string name="gadget_no_events">"予定されているカレンダーの予定はありません"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="reminder_minutes_labels">
- <item>"5분"</item>
- <item>"10분"</item>
- <item>"15분"</item>
- <item>"20분"</item>
- <item>"25분"</item>
- <item>"30분"</item>
- <item>"45분"</item>
- <item>"1시간"</item>
- <item>"2시간"</item>
- <item>"3시간"</item>
- <item>"12시간"</item>
- <item>"24시간"</item>
- <item>"2일"</item>
- <item>"1주"</item>
- </string-array>
- <string-array name="reminder_minutes_values">
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_default_reminder_labels">
- <item>"없음"</item>
- <item>"5분"</item>
- <item>"10분"</item>
- <item>"15분"</item>
- <item>"20분"</item>
- <item>"25분"</item>
- <item>"30분"</item>
- <item>"45분"</item>
- <item>"1시간"</item>
- <item>"2시간"</item>
- <item>"3시간"</item>
- <item>"12시간"</item>
- <item>"24시간"</item>
- <item>"2일"</item>
- <item>"1주"</item>
- </string-array>
- <string-array name="preferences_default_reminder_values">
- <item>"0"</item>
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_alert_type_labels">
- <item>"알림"</item>
- <item>"상태 표시줄 알림"</item>
- <item>"해제"</item>
- </string-array>
- <string-array name="preferences_alert_type_values">
- <item>"0"</item>
- <item>"1"</item>
- <item>"2"</item>
- </string-array>
- <string-array name="availability">
- <item>"다른 용무 중"</item>
- <item>"대화가능"</item>
- </string-array>
- <string-array name="visibility">
- <item>"기본값"</item>
- <item>"비공개"</item>
- <item>"공개"</item>
- </string-array>
- <string-array name="day_labels">
- <item>"일요일"</item>
- <item>"월요일"</item>
- <item>"화요일"</item>
- <item>"수요일"</item>
- <item>"목요일"</item>
- <item>"금요일"</item>
- <item>"토요일"</item>
- </string-array>
- <string-array name="ordinal_labels">
- <item>"첫 번째"</item>
- <item>"두 번째"</item>
- <item>"3번째"</item>
- <item>"4번째"</item>
- <item>"마지막"</item>
- </string-array>
- <string-array name="response_labels1">
- <item>"(응답 없음)"</item>
- <item>"예"</item>
- <item>"미정"</item>
- <item>"아니요"</item>
- </string-array>
- <string-array name="response_labels2">
- <item>"예"</item>
- <item>"미정"</item>
- <item>"아니요"</item>
- </string-array>
- <string-array name="delete_repeating_labels">
- <item>"해당 이벤트만"</item>
- <item>"현재 일정 및 향후 일정"</item>
- <item>"모든 일정"</item>
- </string-array>
- <string-array name="delete_repeating_labels_no_selected">
- <item>"현재 및 향후 일정"</item>
- <item>"모든 일정"</item>
- </string-array>
- <string-array name="change_response_labels">
- <item>"이 일정에만"</item>
- <item>"모든 반복 일정"</item>
- </string-array>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label">"캘린더"</string>
- <string name="calendar_plug"><font fgcolor="#ffffffff">"Google 캘린더에 오신 것을 환영합니다."</font>" "\n"일정 예약을 보다 간편하고 효율적이며 쉽게 사용할 수 있도록 만들어진 Google의 일정 관리 서비스입니다."</string>
- <string name="what_label">"내용"</string>
- <string name="when_label">"일자"</string>
- <string name="where_label">"위치"</string>
- <string name="repeats_label">"반복"</string>
- <string name="no_title_label">"(제목 없음)"</string>
- <plurals name="Nminutes">
- <item quantity="one">"1분"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>분"</item>
- </plurals>
- <plurals name="Nmins">
- <item quantity="one">"1분"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>분"</item>
- </plurals>
- <plurals name="Nhours">
- <item quantity="one">"1시간"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>시간"</item>
- </plurals>
- <plurals name="Ndays">
- <item quantity="one">"1일"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>일"</item>
- </plurals>
- <string name="show_agenda_view">"일정 표시"</string>
- <string name="show_day_view">"하루 일정 표시"</string>
- <string name="agenda_view">"일정목록"</string>
- <string name="day_view">"일"</string>
- <string name="week_view">"주"</string>
- <string name="month_view">"월"</string>
- <string name="event_view">"일정 보기"</string>
- <string name="event_create">"새 일정"</string>
- <string name="event_edit">"일정 수정"</string>
- <string name="event_delete">"일정 삭제"</string>
- <string name="goto_today">"오늘"</string>
- <string name="menu_select_calendars">"내 캘린더"</string>
- <string name="menu_preferences">"설정"</string>
- <string name="plus_N_more">"(<xliff:g id="MORE_COUNT">%d</xliff:g>개 추가 표시)"</string>
- <string name="calendars_title">"내 캘린더"</string>
- <string name="add_calendars">"캘린더 추가"</string>
- <string name="remove_calendars">"캘린더 삭제"</string>
- <string name="event_edit_title">"일정 세부정보"</string>
- <string name="hint_what">"일정 이름"</string>
- <string name="hint_where">"일정 위치"</string>
- <string name="hint_description">"일정 설명"</string>
- <string name="creating_event">"일정을 만드는 중..."</string>
- <string name="saving_event">"일정 저장 중..."</string>
- <string name="loading_calendars_title">"캘린더 로드 중"</string>
- <string name="loading_calendars_message">"캘린더 로드 중..."</string>
- <string name="alert_when_label">"일자:"</string>
- <string name="alert_where_label">"위치:"</string>
- <string name="alert_missed_events_single">"(<xliff:g id="REMINDER_COUNT">%s</xliff:g>개 이상의 알림)"</string>
- <string name="alert_missed_events_multiple">"(<xliff:g id="REMINDER_COUNT">%s</xliff:g>개 이상의 알림)"</string>
- <string name="event_info_title">"일정 보기"</string>
- <string name="event_info_title_invite">"회의 초대장"</string>
- <string name="add_new_reminder">"알림 추가"</string>
- <string name="edit_event_to_label">"종료일:"</string>
- <string name="edit_event_from_label">"시작일:"</string>
- <string name="edit_event_all_day_label">"종일"</string>
- <string name="edit_event_calendar_label">"캘린더"</string>
- <string name="edit_event_show_extra_options">"추가 옵션 표시"</string>
- <string name="edit_event_hide_extra_options">"추가 옵션 숨기기"</string>
- <string name="description_label">"설명"</string>
- <string name="presence_label">"상태"</string>
- <string name="privacy_label">"비공개"</string>
- <string name="reminders_label">"알림"</string>
- <string name="no_syncable_calendars">"캘린더 없음"</string>
- <string name="no_calendars_found">"캘린더가 없습니다."</string>
- <string name="view_event_calendar_label">"캘린더"</string>
- <string name="view_event_timezone_label">"현지 시간대"</string>
- <string name="view_event_response_label">"참석 여부"</string>
- <string name="agenda_today">"오늘"</string>
- <string name="num_events">"일정 수"</string>
- <string name="edit_event_label">"일정 수정"</string>
- <string name="delete_label">"삭제"</string>
- <string name="delete_event_label">"일정 삭제"</string>
- <string name="save_label">"저장"</string>
- <string name="discard_label">"변경사항 취소"</string>
- <string name="import_label">"가져오기"</string>
- <string name="snooze_all_label">"모든 알림 일시중지"</string>
- <string name="dismiss_all_label">"모두 해제"</string>
- <string name="does_not_repeat">"일회성 일정"</string>
- <string name="daily">"매일"</string>
- <string name="every_weekday">"주중 매일(월-금)"</string>
- <string name="weekly">"매주(<xliff:g id="DAYS_OF_WEEK">%s</xliff:g>마다)"</string>
- <string name="monthly_on_day_count">"매월(<xliff:g id="ORDINAL_NUMBER">%1$s</xliff:g> <xliff:g id="DAY_OF_WEEK">%2$s</xliff:g>마다)"</string>
- <string name="monthly_on_day">"매월(<xliff:g id="DAY_OF_MONTH">%s</xliff:g>일)"</string>
- <string name="yearly">"매년(<xliff:g id="DATES">%s</xliff:g>일"</string>
- <string name="custom">"사용자설정...(휴대전화에서는 불가능)"</string>
- <string name="modify_event">"해당 일정만 변경합니다."</string>
- <string name="modify_all">"반복되는 모든 일정을 변경합니다."</string>
- <string name="modify_all_following">"현재 일정 및 모든 향후 일정을 변경합니다."</string>
- <string name="delete_this_event_title">"일정이 삭제됩니다."</string>
- <string name="delete_title">"삭제"</string>
- <string name="change_response_title">"응답 변경"</string>
- <string name="preferences_title">"설정"</string>
- <string name="preferences_general_title">"캘린더 보기 설정"</string>
- <string name="preferences_alerts_title">"알림 설정"</string>
- <string name="preferences_hide_declined_title">"거절한 일정 숨기기"</string>
- <string name="preferences_alerts_type_title">"알리미 및 알림 설정"</string>
- <string name="preferences_alerts_type_dialog">"알리미 및 알림"</string>
- <string name="preferences_alerts_vibrate_title">"진동"</string>
- <string name="preferences_alerts_ringtone_title">"벨소리 선택"</string>
- <string name="preferences_default_reminder_title">"기본 알림 설정"</string>
- <string name="preferences_default_reminder_dialog">"기본 알림 시간"</string>
- <string name="preferences_default_reminder_default">"10"</string>
- <string name="gadget_calendar">"캘린더:"</string>
- <string name="gadget_now_event">"현재 시각: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_next_event">"다음: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_later_event">"예정 시각: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <plurals name="gadget_more_events">
- <item quantity="one">"1개 일정 더보기"</item>
- <item quantity="other">"<xliff:g id="NUMBER">%d</xliff:g>개 일정 더보기"</item>
- </plurals>
- <string name="gadget_no_events">"예정된 캘린더 일정이 없습니다."</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<resources>
- <integer name="number_of_hours">8</integer>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="reminder_minutes_labels">
- <item>"5 minutter"</item>
- <item>"10 minutter"</item>
- <item>"15 minutter"</item>
- <item>"20 minutter"</item>
- <item>"25 minutter"</item>
- <item>"30 minutter"</item>
- <item>"45 minutter"</item>
- <item>"1 time"</item>
- <item>"2 timer"</item>
- <item>"3 timer"</item>
- <item>"12 timer"</item>
- <item>"24 timer"</item>
- <item>"2 dager"</item>
- <item>"1 uke"</item>
- </string-array>
- <string-array name="reminder_minutes_values">
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_default_reminder_labels">
- <item>"Ingen"</item>
- <item>"5 minutter"</item>
- <item>"10 minutter"</item>
- <item>"15 minutter"</item>
- <item>"20 minutter"</item>
- <item>"25 minutter"</item>
- <item>"30 minutter"</item>
- <item>"45 minutter"</item>
- <item>"1 time"</item>
- <item>"2 timer"</item>
- <item>"3 timer"</item>
- <item>"12 timer"</item>
- <item>"24 timer"</item>
- <item>"2 dager"</item>
- <item>"1 uke"</item>
- </string-array>
- <string-array name="preferences_default_reminder_values">
- <item>"0"</item>
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_alert_type_labels">
- <item>"Advarsel"</item>
- <item>"Varsling i statusfeltet"</item>
- <item>"Av"</item>
- </string-array>
- <string-array name="preferences_alert_type_values">
- <item>"0"</item>
- <item>"1"</item>
- <item>"2"</item>
- </string-array>
- <string-array name="availability">
- <item>"Opptatt"</item>
- <item>"Tilgjengelig"</item>
- </string-array>
- <string-array name="visibility">
- <item>"Standard"</item>
- <item>"Privat"</item>
- <item>"Offentlig"</item>
- </string-array>
- <string-array name="day_labels">
- <item>"søndag"</item>
- <item>"mandag"</item>
- <item>"tirsdag"</item>
- <item>"onsdag"</item>
- <item>"torsdag"</item>
- <item>"fredag"</item>
- <item>"lørdag"</item>
- </string-array>
- <string-array name="ordinal_labels">
- <item>"første"</item>
- <item>"andre"</item>
- <item>"tredje"</item>
- <item>"fjerde"</item>
- <item>"siste"</item>
- </string-array>
- <string-array name="response_labels1">
- <item>"(Ikke svart)"</item>
- <item>"Ja"</item>
- <item>"Kanskje"</item>
- <item>"Nei"</item>
- </string-array>
- <string-array name="response_labels2">
- <item>"Ja"</item>
- <item>"Kanskje"</item>
- <item>"Nei"</item>
- </string-array>
- <string-array name="delete_repeating_labels">
- <item>"Bare denne hendelsen"</item>
- <item>"Denne og framtidige hendelser"</item>
- <item>"Alle hendelser"</item>
- </string-array>
- <string-array name="delete_repeating_labels_no_selected">
- <item>"Denne og framtidige hendelser"</item>
- <item>"Alle hendelser"</item>
- </string-array>
- <!-- no translation found for change_response_labels:0 (2012815396992847028) -->
- <!-- no translation found for change_response_labels:1 (140670561403965380) -->
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label">"Kalender"</string>
- <string name="calendar_plug"><font fgcolor="#ffffffff">"Velkommen til Google-kalenderen!"</font>" "\n"En Google-løsning for å vedlikeholde timeplanen din, bygget på ideen om at å planlegge ting skal være intuitivt, effektivt og tilgjengelig."</string>
- <string name="what_label">"Hva"</string>
- <string name="when_label">"Når"</string>
- <string name="where_label">"Hvor"</string>
- <string name="repeats_label">"Gjentas"</string>
- <string name="no_title_label">"(Mangler emne)"</string>
- <plurals name="Nminutes">
- <item quantity="one">"Et minutt"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> minutter"</item>
- </plurals>
- <plurals name="Nmins">
- <item quantity="one">"1 min"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> min"</item>
- </plurals>
- <plurals name="Nhours">
- <item quantity="one">"En time"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> timer"</item>
- </plurals>
- <plurals name="Ndays">
- <item quantity="one">"En dag"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> dager"</item>
- </plurals>
- <string name="show_agenda_view">"Vis agenda"</string>
- <string name="show_day_view">"Vis dag"</string>
- <string name="agenda_view">"Agenda"</string>
- <string name="day_view">"Dag"</string>
- <string name="week_view">"Uke"</string>
- <string name="month_view">"Måned"</string>
- <string name="event_view">"Vis hendelse"</string>
- <string name="event_create">"Ny hendelse"</string>
- <string name="event_edit">"Rediger hendelse"</string>
- <string name="event_delete">"Slett hendelse"</string>
- <string name="goto_today">"I dag"</string>
- <string name="menu_select_calendars">"Mine kalendre"</string>
- <string name="menu_preferences">"Innstillinger"</string>
- <string name="plus_N_more">"(samt <xliff:g id="MORE_COUNT">%d</xliff:g> til …)"</string>
- <string name="calendars_title">"Mine kalendre"</string>
- <string name="add_calendars">"Legg til kalendre"</string>
- <string name="remove_calendars">"Fjern kalendre"</string>
- <string name="event_edit_title">"Hendelsesdetaljer"</string>
- <string name="hint_what">"Navn på hendelse"</string>
- <string name="hint_where">"Sted"</string>
- <string name="hint_description">"Beskrivelse av hendelsen"</string>
- <string name="creating_event">"Lager hendelse…"</string>
- <string name="saving_event">"Lagrer hendelse…"</string>
- <string name="loading_calendars_title">"Laster kalendre"</string>
- <string name="loading_calendars_message">"Laster kalendre…"</string>
- <string name="alert_when_label">"Hva:"</string>
- <string name="alert_where_label">"Hvor:"</string>
- <!-- no translation found for alert_missed_events_single (8042891195314876684) -->
- <skip />
- <string name="alert_missed_events_multiple">"(<xliff:g id="REMINDER_COUNT">%s</xliff:g> hendelser til)"</string>
- <string name="event_info_title">"Vis hendelse"</string>
- <string name="event_info_title_invite">"Møteinvitasjon"</string>
- <string name="add_new_reminder">"Legg til påminnelse"</string>
- <string name="edit_event_to_label">"Til"</string>
- <string name="edit_event_from_label">"Fra"</string>
- <string name="edit_event_all_day_label">"Hele dagen"</string>
- <string name="edit_event_calendar_label">"Kalender"</string>
- <string name="edit_event_show_extra_options">"Vis ekstra valg"</string>
- <string name="edit_event_hide_extra_options">"Skjul ekstra valg"</string>
- <string name="description_label">"Beskrivelse"</string>
- <string name="presence_label">"Vis meg som"</string>
- <string name="privacy_label">"Personvern"</string>
- <string name="reminders_label">"Påminnelser"</string>
- <string name="no_syncable_calendars">"Ingen kalendre"</string>
- <string name="no_calendars_found">"Du har ingen kalendre."</string>
- <string name="view_event_calendar_label">"Kalender"</string>
- <string name="view_event_timezone_label">"Lokal tidssone"</string>
- <string name="view_event_response_label">"Kommer du?"</string>
- <string name="agenda_today">"I dag"</string>
- <string name="num_events">"Ant. hendelser"</string>
- <string name="edit_event_label">"Rediger hendelse"</string>
- <string name="delete_label">"Slett"</string>
- <string name="delete_event_label">"Slett hendelse"</string>
- <string name="save_label">"Lagre"</string>
- <string name="discard_label">"Forkast hendelse"</string>
- <string name="import_label">"Importer"</string>
- <string name="snooze_all_label">"Slumre alle"</string>
- <string name="dismiss_all_label">"Skjul alle"</string>
- <string name="does_not_repeat">"Engangshendelse"</string>
- <string name="daily">"Daglig"</string>
- <string name="every_weekday">"Hverdager (man–fre)"</string>
- <string name="weekly">"Ukentlig (hver <xliff:g id="DAYS_OF_WEEK">%s</xliff:g>)"</string>
- <string name="monthly_on_day_count">"Hver måned (hver <xliff:g id="ORDINAL_NUMBER">%1$s</xliff:g> <xliff:g id="DAY_OF_WEEK">%2$s</xliff:g>)"</string>
- <string name="monthly_on_day">"Hver måned (den <xliff:g id="DAY_OF_MONTH">%s</xliff:g>.)"</string>
- <string name="yearly">"Hvert år (<xliff:g id="DATES">%s</xliff:g>)"</string>
- <string name="custom">"Egendefinert… (kan ikke settes på telefonen)"</string>
- <string name="modify_event">"Endre bare denne hendelsen."</string>
- <string name="modify_all">"Endre alle hendelser i denne serien."</string>
- <string name="modify_all_following">"Endre denne og alle framtidige hendelser."</string>
- <string name="delete_this_event_title">"Denne hendelsen vil bli slettet."</string>
- <string name="delete_title">"Slett"</string>
- <string name="change_response_title">"Endre svar"</string>
- <string name="preferences_title">"Innstillinger"</string>
- <string name="preferences_general_title">"Kalender visningsinnstilling"</string>
- <string name="preferences_alerts_title">"Innstillinger for påminnelser"</string>
- <string name="preferences_hide_declined_title">"Skjul avslåtte hendelser"</string>
- <string name="preferences_alerts_type_title">"Sett varsling og påminnelser"</string>
- <string name="preferences_alerts_type_dialog">"Varsling og påminnelser"</string>
- <string name="preferences_alerts_vibrate_title">"Vibrer"</string>
- <string name="preferences_alerts_ringtone_title">"Velg ringetone"</string>
- <string name="preferences_default_reminder_title">"Sett standard påminnelse"</string>
- <string name="preferences_default_reminder_dialog">"Standard påminnelsestid"</string>
- <string name="preferences_default_reminder_default">"10"</string>
- <string name="gadget_calendar">"Kalender:"</string>
- <string name="gadget_now_event">"Nå: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_next_event">"Neste: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_later_event">"Senere: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <plurals name="gadget_more_events">
- <item quantity="one">"En hendelse til"</item>
- <item quantity="other">"<xliff:g id="NUMBER">%d</xliff:g> hendelser til"</item>
- </plurals>
- <string name="gadget_no_events">"Ingen kommende kalenderhendelser"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="reminder_minutes_labels">
- <item>"5 minuten"</item>
- <item>"10 minuten"</item>
- <item>"15 minuten"</item>
- <item>"20 minuten"</item>
- <item>"25 minuten"</item>
- <item>"30 minuten"</item>
- <item>"45 minuten"</item>
- <item>"1 uur"</item>
- <item>"2 uur"</item>
- <item>"3 uur"</item>
- <item>"12 uur"</item>
- <item>"24 uur"</item>
- <item>"2 dagen"</item>
- <item>"1 week"</item>
- </string-array>
- <string-array name="reminder_minutes_values">
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_default_reminder_labels">
- <item>"Geen"</item>
- <item>"5 minuten"</item>
- <item>"10 minuten"</item>
- <item>"15 minuten"</item>
- <item>"20 minuten"</item>
- <item>"25 minuten"</item>
- <item>"30 minuten"</item>
- <item>"45 minuten"</item>
- <item>"1 uur"</item>
- <item>"2 uur"</item>
- <item>"3 uur"</item>
- <item>"12 uur"</item>
- <item>"24 uur"</item>
- <item>"2 dagen"</item>
- <item>"1 week"</item>
- </string-array>
- <string-array name="preferences_default_reminder_values">
- <item>"0"</item>
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_alert_type_labels">
- <item>"Melding"</item>
- <item>"Statusbalkmelding"</item>
- <item>"Uit"</item>
- </string-array>
- <string-array name="preferences_alert_type_values">
- <item>"0"</item>
- <item>"1"</item>
- <item>"2"</item>
- </string-array>
- <string-array name="availability">
- <item>"Bezet"</item>
- <item>"Beschikbaar"</item>
- </string-array>
- <string-array name="visibility">
- <item>"Standaard"</item>
- <item>"Privé"</item>
- <item>"Openbaar"</item>
- </string-array>
- <string-array name="day_labels">
- <item>"Zondag"</item>
- <item>"Maandag"</item>
- <item>"Dinsdag"</item>
- <item>"Woensdag"</item>
- <item>"Donderdag"</item>
- <item>"Vrijdag"</item>
- <item>"Zaterdag"</item>
- </string-array>
- <string-array name="ordinal_labels">
- <item>"eerste"</item>
- <item>"tweede"</item>
- <item>"derde"</item>
- <item>"vierde"</item>
- <item>"laatste"</item>
- </string-array>
- <string-array name="response_labels1">
- <item>"(Geen antwoord)"</item>
- <item>"Ja"</item>
- <item>"Misschien"</item>
- <item>"Nee"</item>
- </string-array>
- <string-array name="response_labels2">
- <item>"Ja"</item>
- <item>"Misschien"</item>
- <item>"Nee"</item>
- </string-array>
- <string-array name="delete_repeating_labels">
- <item>"Alleen deze afspraak"</item>
- <item>"Deze en toekomstige afspraken"</item>
- <item>"Alle afspraken"</item>
- </string-array>
- <string-array name="delete_repeating_labels_no_selected">
- <item>"Deze en toekomstige afspraken"</item>
- <item>"Alle afspraken"</item>
- </string-array>
- <string-array name="change_response_labels">
- <item>"Alleen deze keer"</item>
- <item>"Alle gebeurtenissen in de reeks"</item>
- </string-array>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label">"Agenda"</string>
- <string name="calendar_plug"><font fgcolor="#ffffffff">"Welkom bij Google Agenda!"</font>" "\n" Een Google-benadering om uw planning te beheren, gebaseerd op het idee dat het plannen van afspraken intuïtiever, efficiënter en toegankelijker kan."</string>
- <string name="what_label">"Wat"</string>
- <string name="when_label">"Wanneer"</string>
- <string name="where_label">"Waar"</string>
- <string name="repeats_label">"Herhaling"</string>
- <string name="no_title_label">"(Geen onderwerp)"</string>
- <plurals name="Nminutes">
- <item quantity="one">"1 minuut"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> minuten"</item>
- </plurals>
- <plurals name="Nmins">
- <item quantity="one">"1 min."</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> min."</item>
- </plurals>
- <plurals name="Nhours">
- <item quantity="one">"1 uur"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> uur"</item>
- </plurals>
- <plurals name="Ndays">
- <item quantity="one">"1 dag"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> dagen"</item>
- </plurals>
- <string name="show_agenda_view">"Geef agenda weer"</string>
- <string name="show_day_view">"Geef dag weer"</string>
- <string name="agenda_view">"Agenda"</string>
- <string name="day_view">"Dag"</string>
- <string name="week_view">"Week"</string>
- <string name="month_view">"Maand"</string>
- <string name="event_view">"Afspraak weergeven"</string>
- <string name="event_create">"Nieuwe afspraak"</string>
- <string name="event_edit">"Afspraak bewerken"</string>
- <string name="event_delete">"Afspraak verwijderen"</string>
- <string name="goto_today">"Vandaag"</string>
- <string name="menu_select_calendars">"Mijn agenda\'s"</string>
- <string name="menu_preferences">"Instellingen"</string>
- <string name="plus_N_more">"(plus <xliff:g id="MORE_COUNT">%d</xliff:g> extra …)"</string>
- <string name="calendars_title">"Mijn agenda\'s"</string>
- <string name="add_calendars">"Agenda\'s toevoegen"</string>
- <string name="remove_calendars">"Agenda\'s verwijderen"</string>
- <string name="event_edit_title">"Afspraakgegevens"</string>
- <string name="hint_what">"Afspraaknaam"</string>
- <string name="hint_where">"Locatie van de afspraak"</string>
- <string name="hint_description">"Beschrijving van afspraak"</string>
- <string name="creating_event">"Afspraak wordt gemaakt…"</string>
- <string name="saving_event">"Afspraak wordt opgeslagen..."</string>
- <string name="loading_calendars_title">"Agenda\'s worden geladen"</string>
- <string name="loading_calendars_message">"Agenda\'s worden geladen"</string>
- <string name="alert_when_label">"Wanneer:"</string>
- <string name="alert_where_label">"Waar:"</string>
- <string name="alert_missed_events_single">"(<xliff:g id="REMINDER_COUNT">%s</xliff:g> extra herinnering)"</string>
- <string name="alert_missed_events_multiple">"(<xliff:g id="REMINDER_COUNT">%s</xliff:g> extra herinneringen)"</string>
- <string name="event_info_title">"Afspraak weergeven"</string>
- <string name="event_info_title_invite">"Uitnodiging voor vergadering"</string>
- <string name="add_new_reminder">"Herinnering toevoegen"</string>
- <string name="edit_event_to_label">"Tot"</string>
- <string name="edit_event_from_label">"Van"</string>
- <string name="edit_event_all_day_label">"De hele dag"</string>
- <string name="edit_event_calendar_label">"Agenda"</string>
- <string name="edit_event_show_extra_options">"Extra opties weergeven"</string>
- <string name="edit_event_hide_extra_options">"Extra opties verbergen"</string>
- <string name="description_label">"Beschrijving"</string>
- <string name="presence_label">"Beschikbaarheid"</string>
- <string name="privacy_label">"Privacy"</string>
- <string name="reminders_label">"Herinneringen"</string>
- <string name="no_syncable_calendars">"Geen agenda\'s"</string>
- <string name="no_calendars_found">"U heeft geen agenda\'s."</string>
- <string name="view_event_calendar_label">"Agenda"</string>
- <string name="view_event_timezone_label">"Lokale tijdzone"</string>
- <string name="view_event_response_label">"Aanwezig?"</string>
- <string name="agenda_today">"Vandaag"</string>
- <string name="num_events">"Aantal afspraken"</string>
- <string name="edit_event_label">"Afspraak bewerken"</string>
- <string name="delete_label">"Verwijderen"</string>
- <string name="delete_event_label">"Afspraak verwijderen"</string>
- <string name="save_label">"Opslaan"</string>
- <string name="discard_label">"Wijzigingen annuleren"</string>
- <string name="import_label">"Importeren"</string>
- <string name="snooze_all_label">"5 min. uitstellen"</string>
- <string name="dismiss_all_label">"Allemaal verwijderen"</string>
- <string name="does_not_repeat">"Eenmalige afspraak"</string>
- <string name="daily">"Dagelijks"</string>
- <string name="every_weekday">"Elke werkdag (ma - vr)"</string>
- <string name="weekly">"Wekelijks (elke <xliff:g id="DAYS_OF_WEEK">%s</xliff:g>)"</string>
- <string name="monthly_on_day_count">"Maandelijks (elke <xliff:g id="ORDINAL_NUMBER">%1$s</xliff:g><xliff:g id="DAY_OF_WEEK">%2$s</xliff:g>)"</string>
- <string name="monthly_on_day">"Maandelijks (op dag <xliff:g id="DAY_OF_MONTH">%s</xliff:g>)"</string>
- <string name="yearly">"Jaarlijks (op <xliff:g id="DATES">%s</xliff:g>)"</string>
- <string name="custom">"Aangepast… (kan niet op de telefoon worden aangepast)"</string>
- <string name="modify_event">"Alleen deze afspraak wijzigen."</string>
- <string name="modify_all">"Alle afspraken in de reeks wijzigen."</string>
- <string name="modify_all_following">"Deze en alle toekomstige afspraken wijzigen."</string>
- <string name="delete_this_event_title">"Deze afspraak wordt verwijderd."</string>
- <string name="delete_title">"Verwijderen"</string>
- <string name="change_response_title">"Reactie wijzigen"</string>
- <string name="preferences_title">"Instellingen"</string>
- <string name="preferences_general_title">"Instelling agendaweergave"</string>
- <string name="preferences_alerts_title">"Instellingen voor herinneringen"</string>
- <string name="preferences_hide_declined_title">"Geweigerde afspraken verbergen"</string>
- <string name="preferences_alerts_type_title">"Meldingen instellen"</string>
- <string name="preferences_alerts_type_dialog">"Meldingen en berichten"</string>
- <string name="preferences_alerts_vibrate_title">"Trillen"</string>
- <string name="preferences_alerts_ringtone_title">"Ringtone selecteren"</string>
- <string name="preferences_default_reminder_title">"Standaardherinnering instellen"</string>
- <string name="preferences_default_reminder_dialog">"Standaard herinneringstijd"</string>
- <string name="preferences_default_reminder_default">"10"</string>
- <string name="gadget_calendar">"Kalender:"</string>
- <string name="gadget_now_event">"Nu: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_next_event">"Volgende: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_later_event">"Later: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <plurals name="gadget_more_events">
- <item quantity="one">"nog 1 gebeurtenis"</item>
- <item quantity="other">"nog <xliff:g id="NUMBER">%d</xliff:g> gebeurtenissen"</item>
- </plurals>
- <string name="gadget_no_events">"Geen geplande afspraken"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="reminder_minutes_labels">
- <item>"5 min"</item>
- <item>"10 min"</item>
- <item>"15 min"</item>
- <item>"20 min"</item>
- <item>"25 min"</item>
- <item>"30 min"</item>
- <item>"45 min"</item>
- <item>"1 godzina"</item>
- <item>"2 godziny"</item>
- <item>"3 godziny"</item>
- <item>"12 godzin"</item>
- <item>"24 godziny"</item>
- <item>"2 dni"</item>
- <item>"1 tydzień"</item>
- </string-array>
- <string-array name="reminder_minutes_values">
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_default_reminder_labels">
- <item>"Brak"</item>
- <item>"5 min"</item>
- <item>"10 min"</item>
- <item>"15 min"</item>
- <item>"20 min"</item>
- <item>"25 min"</item>
- <item>"30 min"</item>
- <item>"45 min"</item>
- <item>"1 godzina"</item>
- <item>"2 godziny"</item>
- <item>"3 godziny"</item>
- <item>"12 godzin"</item>
- <item>"24 godziny"</item>
- <item>"2 dni"</item>
- <item>"1 tydzień"</item>
- </string-array>
- <string-array name="preferences_default_reminder_values">
- <item>"0"</item>
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_alert_type_labels">
- <item>"Alert"</item>
- <item>"Powiadomienie na pasku stanu"</item>
- <item>"Wyłączone"</item>
- </string-array>
- <string-array name="preferences_alert_type_values">
- <item>"0"</item>
- <item>"1"</item>
- <item>"2"</item>
- </string-array>
- <string-array name="availability">
- <item>"Zajęty"</item>
- <item>"Dostępny"</item>
- </string-array>
- <string-array name="visibility">
- <item>"Domyślne"</item>
- <item>"Prywatny"</item>
- <item>"Publiczny"</item>
- </string-array>
- <string-array name="day_labels">
- <item>"Niedziela"</item>
- <item>"Poniedziałek"</item>
- <item>"Wtorek"</item>
- <item>"Środa"</item>
- <item>"Czwartek"</item>
- <item>"Piątek"</item>
- <item>"Sobota"</item>
- </string-array>
- <string-array name="ordinal_labels">
- <item>"1."</item>
- <item>"2."</item>
- <item>"3."</item>
- <item>"4."</item>
- <item>"ostatni"</item>
- </string-array>
- <string-array name="response_labels1">
- <item>"(Brak odpowiedzi)"</item>
- <item>"Tak"</item>
- <item>"Możliwe"</item>
- <item>"Nie"</item>
- </string-array>
- <string-array name="response_labels2">
- <item>"Tak"</item>
- <item>"Możliwe"</item>
- <item>"Nie"</item>
- </string-array>
- <string-array name="delete_repeating_labels">
- <item>"Tylko to wydarzenie"</item>
- <item>"To i przyszłe wydarzenia"</item>
- <item>"Wszystkie wydarzenia"</item>
- </string-array>
- <string-array name="delete_repeating_labels_no_selected">
- <item>"To i przyszłe wydarzenia"</item>
- <item>"Wszystkie wydarzenia"</item>
- </string-array>
- <string-array name="change_response_labels">
- <item>"Tylko to wystąpienie"</item>
- <item>"Wszystkie wydarzenia w serii"</item>
- </string-array>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label">"Kalendarz"</string>
- <string name="calendar_plug"><font fgcolor="#ffffffff">"Witamy w Kalendarzu Google!"</font>" "\n"Intuicyjne, wydajne i dostępne planowanie wydarzeń w celu zarządzania terminami według Google."</string>
- <string name="what_label">"Co"</string>
- <string name="when_label">"Kiedy"</string>
- <string name="where_label">"Gdzie"</string>
- <string name="repeats_label">"Powtórzenie"</string>
- <string name="no_title_label">"(Brak tematu)"</string>
- <plurals name="Nminutes">
- <item quantity="one">"1 min"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> min"</item>
- </plurals>
- <plurals name="Nmins">
- <item quantity="one">"1 min"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> min"</item>
- </plurals>
- <plurals name="Nhours">
- <item quantity="one">"1 godzina"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> godz."</item>
- </plurals>
- <plurals name="Ndays">
- <item quantity="one">"1 dzień"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> dni"</item>
- </plurals>
- <string name="show_agenda_view">"Pokaż plan dnia"</string>
- <string name="show_day_view">"Pokaż dzień"</string>
- <string name="agenda_view">"Plan dnia"</string>
- <string name="day_view">"Dzień"</string>
- <string name="week_view">"Tydzień"</string>
- <string name="month_view">"Miesiąc"</string>
- <string name="event_view">"Wyświetl wydarzenie"</string>
- <string name="event_create">"Nowe wydarzenie"</string>
- <string name="event_edit">"Edytuj wydarzenie"</string>
- <string name="event_delete">"Usuń wydarzenie"</string>
- <string name="goto_today">"Dzisiaj"</string>
- <string name="menu_select_calendars">"Moje kalendarze"</string>
- <string name="menu_preferences">"Ustawienia"</string>
- <string name="plus_N_more">"(i <xliff:g id="MORE_COUNT">%d</xliff:g> więcej …)"</string>
- <string name="calendars_title">"Moje kalendarze"</string>
- <string name="add_calendars">"Dodaj kalendarze"</string>
- <string name="remove_calendars">"Usuń kalendarze"</string>
- <string name="event_edit_title">"Szczegóły wydarzenia"</string>
- <string name="hint_what">"Nazwa wydarzenia"</string>
- <string name="hint_where">"Lokalizacja wydarzenia"</string>
- <string name="hint_description">"Opis wydarzenia"</string>
- <string name="creating_event">"Tworzenie wydarzenia..."</string>
- <string name="saving_event">"Zapisywanie wydarzenia..."</string>
- <string name="loading_calendars_title">"Ładowanie kalendarzy"</string>
- <string name="loading_calendars_message">"Ładowanie kalendarzy..."</string>
- <string name="alert_when_label">"Kiedy:"</string>
- <string name="alert_where_label">"Gdzie:"</string>
- <string name="alert_missed_events_single">"(więcej przypomnień: <xliff:g id="REMINDER_COUNT">%s</xliff:g>)"</string>
- <string name="alert_missed_events_multiple">"(więcej przypomnień: <xliff:g id="REMINDER_COUNT">%s</xliff:g>)"</string>
- <string name="event_info_title">"Wyświetl wydarzenie"</string>
- <string name="event_info_title_invite">"Zaproszenie na spotkanie"</string>
- <string name="add_new_reminder">"Dodaj przypomnienie"</string>
- <string name="edit_event_to_label">"Do"</string>
- <string name="edit_event_from_label">"Od"</string>
- <string name="edit_event_all_day_label">"Cały dzień"</string>
- <string name="edit_event_calendar_label">"Kalendarz"</string>
- <string name="edit_event_show_extra_options">"Pokaż dodatkowe opcje"</string>
- <string name="edit_event_hide_extra_options">"Ukryj dodatkowe opcje"</string>
- <string name="description_label">"Opis"</string>
- <string name="presence_label">"Obecność"</string>
- <string name="privacy_label">"Prywatność"</string>
- <string name="reminders_label">"Przypomnienia"</string>
- <string name="no_syncable_calendars">"Brak kalendarzy"</string>
- <string name="no_calendars_found">"Nie masz kalendarzy."</string>
- <string name="view_event_calendar_label">"Kalendarz"</string>
- <string name="view_event_timezone_label">"Lokalna strefa czasowa"</string>
- <string name="view_event_response_label">"Uczestnictwo"</string>
- <string name="agenda_today">"Dzisiaj"</string>
- <string name="num_events">"Liczba wydarzeń"</string>
- <string name="edit_event_label">"Edytuj wydarzenie"</string>
- <string name="delete_label">"Usuń"</string>
- <string name="delete_event_label">"Usuń wydarzenie"</string>
- <string name="save_label">"Zapisz"</string>
- <string name="discard_label">"Odrzuć zmiany"</string>
- <string name="import_label">"Importuj"</string>
- <string name="snooze_all_label">"Odłóż wszystkie"</string>
- <string name="dismiss_all_label">"Odrzuć wszystkie"</string>
- <string name="does_not_repeat">"Wydarzenie jednorazowe"</string>
- <string name="daily">"Codziennie"</string>
- <string name="every_weekday">"Codziennie (pn-pt)"</string>
- <string name="weekly">"Co tydzień (<xliff:g id="DAYS_OF_WEEK">%s</xliff:g>)"</string>
- <string name="monthly_on_day_count">"Co miesiąc (<xliff:g id="ORDINAL_NUMBER">%1$s</xliff:g> <xliff:g id="DAY_OF_WEEK">%2$s</xliff:g>)"</string>
- <string name="monthly_on_day">"Co miesiąc (<xliff:g id="DAY_OF_MONTH">%s</xliff:g> każdego miesiąca)"</string>
- <string name="yearly">"Co rok (<xliff:g id="DATES">%s</xliff:g>)"</string>
- <string name="custom">"Niestandardowo… (nie można dostosować na telefonie)"</string>
- <string name="modify_event">"Zmień tylko to wydarzenie."</string>
- <string name="modify_all">"Zmień wszystkie wydarzenia w serii."</string>
- <string name="modify_all_following">"Zmień to i wszystkie przyszłe wydarzenia."</string>
- <string name="delete_this_event_title">"To wydarzenie zostanie usunięte."</string>
- <string name="delete_title">"Usuń"</string>
- <string name="change_response_title">"Zmień odpowiedź"</string>
- <string name="preferences_title">"Ustawienia"</string>
- <string name="preferences_general_title">"Ustawienie widoku kalendarza"</string>
- <string name="preferences_alerts_title">"Ustawienia przypomnień"</string>
- <string name="preferences_hide_declined_title">"Ukryj odrzucone wydarzenia"</string>
- <string name="preferences_alerts_type_title">"Ustaw alerty i powiadomienia"</string>
- <string name="preferences_alerts_type_dialog">"Alerty i powiadomienia"</string>
- <string name="preferences_alerts_vibrate_title">"Wibracje"</string>
- <string name="preferences_alerts_ringtone_title">"Wybierz dzwonek"</string>
- <string name="preferences_default_reminder_title">"Ustaw domyślne przypomnienie"</string>
- <string name="preferences_default_reminder_dialog">"Domyślna godzina przypomnienia"</string>
- <string name="preferences_default_reminder_default">"10"</string>
- <string name="gadget_calendar">"Kalendarz:"</string>
- <string name="gadget_now_event">"Teraz: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_next_event">"Następne: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_later_event">"Później: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <plurals name="gadget_more_events">
- <item quantity="one">"Więcej wydarzeń: 1"</item>
- <item quantity="other">"Więcej wydarzeń: <xliff:g id="NUMBER">%d</xliff:g>"</item>
- </plurals>
- <string name="gadget_no_events">"Brak zbliżających się wydarzeń w kalendarzu"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="reminder_minutes_labels">
- <item>"5 минут"</item>
- <item>"10 минут"</item>
- <item>"15 минут"</item>
- <item>"20 минут"</item>
- <item>"25 минут"</item>
- <item>"30 минут"</item>
- <item>"45 минут"</item>
- <item>"1 час"</item>
- <item>"2 часа"</item>
- <item>"3 часа"</item>
- <item>"12 часов"</item>
- <item>"24 часа"</item>
- <item>"2 дня"</item>
- <item>"1 неделя"</item>
- </string-array>
- <string-array name="reminder_minutes_values">
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_default_reminder_labels">
- <item>"Нет"</item>
- <item>"5 минут"</item>
- <item>"10 минут"</item>
- <item>"15 минут"</item>
- <item>"20 минут"</item>
- <item>"25 минут"</item>
- <item>"30 минут"</item>
- <item>"45 минут"</item>
- <item>"1 час"</item>
- <item>"2 часа"</item>
- <item>"3 часа"</item>
- <item>"12 часов"</item>
- <item>"24 часа"</item>
- <item>"2 дня"</item>
- <item>"1 неделя"</item>
- </string-array>
- <string-array name="preferences_default_reminder_values">
- <item>"0"</item>
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_alert_type_labels">
- <item>"Оповещение"</item>
- <item>"Уведомление в строке состояния"</item>
- <item>"Выкл"</item>
- </string-array>
- <string-array name="preferences_alert_type_values">
- <item>"0"</item>
- <item>"1"</item>
- <item>"2"</item>
- </string-array>
- <string-array name="availability">
- <item>"Занято"</item>
- <item>"Свободно"</item>
- </string-array>
- <string-array name="visibility">
- <item>"По умолчанию"</item>
- <item>"Закрыт."</item>
- <item>"Открыт."</item>
- </string-array>
- <string-array name="day_labels">
- <item>"Воскресенье"</item>
- <item>"Понедельник"</item>
- <item>"Вторник"</item>
- <item>"Среда"</item>
- <item>"Четверг"</item>
- <item>"Пятница"</item>
- <item>"Суббота"</item>
- </string-array>
- <string-array name="ordinal_labels">
- <item>"перв."</item>
- <item>"втор."</item>
- <item>"трет."</item>
- <item>"четверт."</item>
- <item>"посл."</item>
- </string-array>
- <string-array name="response_labels1">
- <item>"(нет ответа)"</item>
- <item>"Да"</item>
- <item>"Может быть"</item>
- <item>"Нет"</item>
- </string-array>
- <string-array name="response_labels2">
- <item>"Да"</item>
- <item>"Может быть"</item>
- <item>"Нет"</item>
- </string-array>
- <string-array name="delete_repeating_labels">
- <item>"Только это мероприятие"</item>
- <item>"Это и будущие события"</item>
- <item>"Все мероприятия"</item>
- </string-array>
- <string-array name="delete_repeating_labels_no_selected">
- <item>"Это и будущие мероприятия"</item>
- <item>"Все мероприятия"</item>
- </string-array>
- <string-array name="change_response_labels">
- <item>"Только этот экземпляр"</item>
- <item>"Все экземпляры события"</item>
- </string-array>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label">"Календарь"</string>
- <string name="calendar_plug"><font fgcolor="#ffffffff">"Добро пожаловать в Календарь Google!"</font>" "\n"Средство Google для управления расписаниями, основанное на идее о том, что планирование мероприятий может быть более интуитивным, эффективным и доступным."</string>
- <string name="what_label">"Что"</string>
- <string name="when_label">"Когда"</string>
- <string name="where_label">"Где"</string>
- <string name="repeats_label">"Повторение"</string>
- <string name="no_title_label">"(Без темы)"</string>
- <plurals name="Nminutes">
- <item quantity="one">"1 минут"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> мин."</item>
- </plurals>
- <plurals name="Nmins">
- <item quantity="one">"1 мин."</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> мин."</item>
- </plurals>
- <plurals name="Nhours">
- <item quantity="one">"1 час"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> ч."</item>
- </plurals>
- <plurals name="Ndays">
- <item quantity="one">"1 день"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> дн."</item>
- </plurals>
- <string name="show_agenda_view">"Показать в режиме просмотра повестки дня"</string>
- <string name="show_day_view">"Показать в режиме просмотра дня"</string>
- <string name="agenda_view">"Повестка дня"</string>
- <string name="day_view">"День"</string>
- <string name="week_view">"Неделя"</string>
- <string name="month_view">"Месяц"</string>
- <string name="event_view">"Просмотреть мероприятие"</string>
- <string name="event_create">"Создать мероприятие"</string>
- <string name="event_edit">"Изменить мероприятие"</string>
- <string name="event_delete">"Удалить мероприятие"</string>
- <string name="goto_today">"Сегодня"</string>
- <string name="menu_select_calendars">"Мои календари"</string>
- <string name="menu_preferences">"Настройки"</string>
- <string name="plus_N_more">"(и еще <xliff:g id="MORE_COUNT">%d</xliff:g>)"</string>
- <string name="calendars_title">"Мои календари"</string>
- <string name="add_calendars">"Добавить календари"</string>
- <string name="remove_calendars">"Удаление календарей"</string>
- <string name="event_edit_title">"Сведения о мероприятии"</string>
- <string name="hint_what">"Название мероприятия"</string>
- <string name="hint_where">"Место для мероприятия"</string>
- <string name="hint_description">"Описание мероприятия"</string>
- <string name="creating_event">"Идет создание мероприятия..."</string>
- <string name="saving_event">"Идет сохранение мероприятия..."</string>
- <string name="loading_calendars_title">"Загрузка календарей"</string>
- <string name="loading_calendars_message">"Идет загрузка календарей..."</string>
- <string name="alert_when_label">"Когда:"</string>
- <string name="alert_where_label">"Где:"</string>
- <string name="alert_missed_events_single">"(дополнительное уведомление: <xliff:g id="REMINDER_COUNT">%s</xliff:g>)"</string>
- <string name="alert_missed_events_multiple">"(дополнительные уведомления: <xliff:g id="REMINDER_COUNT">%s</xliff:g>)"</string>
- <string name="event_info_title">"Просмотр мероприятия"</string>
- <string name="event_info_title_invite">"Приглашение на встречу"</string>
- <string name="add_new_reminder">"Добавить напоминание"</string>
- <string name="edit_event_to_label">"по"</string>
- <string name="edit_event_from_label">"С"</string>
- <string name="edit_event_all_day_label">"Весь день"</string>
- <string name="edit_event_calendar_label">"Календарь"</string>
- <string name="edit_event_show_extra_options">"Показать дополнительные параметры"</string>
- <string name="edit_event_hide_extra_options">"Скрыть дополнительные параметры"</string>
- <string name="description_label">"Описание"</string>
- <string name="presence_label">"Наличие"</string>
- <string name="privacy_label">"Конфиденциальность"</string>
- <string name="reminders_label">"Напоминания"</string>
- <string name="no_syncable_calendars">"Нет календарей"</string>
- <string name="no_calendars_found">"Календари отсутствуют."</string>
- <string name="view_event_calendar_label">"Календарь"</string>
- <string name="view_event_timezone_label">"Локальный часовой пояс"</string>
- <string name="view_event_response_label">"Идете?"</string>
- <string name="agenda_today">"Сегодня"</string>
- <string name="num_events">"Количество мероприятий"</string>
- <string name="edit_event_label">"Изменить мероприятие"</string>
- <string name="delete_label">"Удалить"</string>
- <string name="delete_event_label">"Удалить мероприятие"</string>
- <string name="save_label">"Сохранить"</string>
- <string name="discard_label">"Не сохранять изменения"</string>
- <string name="import_label">"Импорт"</string>
- <string name="snooze_all_label">"Отложить все"</string>
- <string name="dismiss_all_label">"Отклонить все"</string>
- <string name="does_not_repeat">"Однократное мероприятие"</string>
- <string name="daily">"Каждый день"</string>
- <string name="every_weekday">"Каждый рабочий день (понедельник—пятница)"</string>
- <string name="weekly">"Каждую неделю (день недели: <xliff:g id="DAYS_OF_WEEK">%s</xliff:g>)"</string>
- <string name="monthly_on_day_count">"Каждый месяц (кажд. <xliff:g id="ORDINAL_NUMBER">%1$s</xliff:g> <xliff:g id="DAY_OF_WEEK">%2$s</xliff:g>)"</string>
- <string name="monthly_on_day">"Ежемесячно (в <xliff:g id="DAY_OF_MONTH">%s</xliff:g> день)"</string>
- <string name="yearly">"Каждый год (<xliff:g id="DATES">%s</xliff:g>)"</string>
- <string name="custom">"Пользовательский вариант... (настройка на телефоне невозможна)"</string>
- <string name="modify_event">"Изменить только это мероприятие."</string>
- <string name="modify_all">"Изменить все мероприятия серии."</string>
- <string name="modify_all_following">"Изменить это и все будущие мероприятия"</string>
- <string name="delete_this_event_title">"Это мероприятие будет удалено."</string>
- <string name="delete_title">"Удалить"</string>
- <string name="change_response_title">"Изменение ответа"</string>
- <string name="preferences_title">"Настройки"</string>
- <string name="preferences_general_title">"Настройка режимов просмотра календаря"</string>
- <string name="preferences_alerts_title">"Настройки напоминания"</string>
- <string name="preferences_hide_declined_title">"Скрыть отклоненные мероприятия"</string>
- <string name="preferences_alerts_type_title">"Настроить оповещения и уведомления"</string>
- <string name="preferences_alerts_type_dialog">"Оповещения и уведомления"</string>
- <string name="preferences_alerts_vibrate_title">"Вибрировать"</string>
- <string name="preferences_alerts_ringtone_title">"Выбор мелодию звонка"</string>
- <string name="preferences_default_reminder_title">"Установить напоминание по умолчанию"</string>
- <string name="preferences_default_reminder_dialog">"Время напоминания по умолчанию"</string>
- <string name="preferences_default_reminder_default">"10"</string>
- <string name="gadget_calendar">"Календарь:"</string>
- <string name="gadget_now_event">"Сейчас: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_next_event">"Далее: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_later_event">"Позже: <xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <plurals name="gadget_more_events">
- <item quantity="one">"Еще одно событие"</item>
- <item quantity="other">"Еще событий: <xliff:g id="NUMBER">%d</xliff:g>"</item>
- </plurals>
- <string name="gadget_no_events">"Нет предстоящих событий календаря"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="reminder_minutes_labels">
- <item>"5 分钟"</item>
- <item>"10 分钟"</item>
- <item>"15 分钟"</item>
- <item>"20 分钟"</item>
- <item>"25 分钟"</item>
- <item>"30 分钟"</item>
- <item>"45 分钟"</item>
- <item>"1 小时"</item>
- <item>"2 小时"</item>
- <item>"3 小时"</item>
- <item>"12 小时"</item>
- <item>"24 小时"</item>
- <item>"2 天"</item>
- <item>"1 周"</item>
- </string-array>
- <string-array name="reminder_minutes_values">
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_default_reminder_labels">
- <item>"无"</item>
- <item>"5 分钟"</item>
- <item>"10 分钟"</item>
- <item>"15 分钟"</item>
- <item>"20 分钟"</item>
- <item>"25 分钟"</item>
- <item>"30 分钟"</item>
- <item>"45 分钟"</item>
- <item>"1 小时"</item>
- <item>"2 小时"</item>
- <item>"3 小时"</item>
- <item>"12 小时"</item>
- <item>"24 小时"</item>
- <item>"2 天"</item>
- <item>"1 周"</item>
- </string-array>
- <string-array name="preferences_default_reminder_values">
- <item>"0"</item>
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_alert_type_labels">
- <item>"提醒"</item>
- <item>"状态栏通知"</item>
- <item>"关闭"</item>
- </string-array>
- <string-array name="preferences_alert_type_values">
- <item>"0"</item>
- <item>"1"</item>
- <item>"2"</item>
- </string-array>
- <string-array name="availability">
- <item>"忙碌"</item>
- <item>"有空"</item>
- </string-array>
- <string-array name="visibility">
- <item>"默认"</item>
- <item>"私人"</item>
- <item>"公共"</item>
- </string-array>
- <string-array name="day_labels">
- <item>"星期日"</item>
- <item>"星期一"</item>
- <item>"星期二"</item>
- <item>"星期三"</item>
- <item>"星期四"</item>
- <item>"星期五"</item>
- <item>"星期六"</item>
- </string-array>
- <string-array name="ordinal_labels">
- <item>"第一个"</item>
- <item>"第二个"</item>
- <item>"第三个"</item>
- <item>"第四个"</item>
- <item>"上一"</item>
- </string-array>
- <string-array name="response_labels1">
- <item>"(未响应)"</item>
- <item>"是"</item>
- <item>"不确定"</item>
- <item>"否"</item>
- </string-array>
- <string-array name="response_labels2">
- <item>"是"</item>
- <item>"不确定"</item>
- <item>"否"</item>
- </string-array>
- <string-array name="delete_repeating_labels">
- <item>"仅此活动"</item>
- <item>"此活动和将来的活动"</item>
- <item>"所有活动"</item>
- </string-array>
- <string-array name="delete_repeating_labels_no_selected">
- <item>"此活动和将来的活动"</item>
- <item>"所有活动"</item>
- </string-array>
- <string-array name="change_response_labels">
- <item>"仅此例"</item>
- <item>"所有此类活动"</item>
- </string-array>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label">"日历"</string>
- <string name="calendar_plug"><font fgcolor="#ffffffff">"欢迎使用 Google 日历!"</font>" "\n"Google 日历是一种用于管理您的日程安排的工具,它独到的设计理念能让您更加直接、高效和方便地安排活动。"</string>
- <string name="what_label">"活动"</string>
- <string name="when_label">"时间"</string>
- <string name="where_label">"地点"</string>
- <string name="repeats_label">"重复频率"</string>
- <string name="no_title_label">"(无主题)"</string>
- <plurals name="Nminutes">
- <item quantity="one">"1 分钟"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 分钟"</item>
- </plurals>
- <plurals name="Nmins">
- <item quantity="one">"1 分钟"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 分钟"</item>
- </plurals>
- <plurals name="Nhours">
- <item quantity="one">"1 小时"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 小时"</item>
- </plurals>
- <plurals name="Ndays">
- <item quantity="one">"1 天"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 天"</item>
- </plurals>
- <string name="show_agenda_view">"显示日程"</string>
- <string name="show_day_view">"显示日期"</string>
- <string name="agenda_view">"日程"</string>
- <string name="day_view">"天"</string>
- <string name="week_view">"周"</string>
- <string name="month_view">"月"</string>
- <string name="event_view">"查看活动"</string>
- <string name="event_create">"新建活动"</string>
- <string name="event_edit">"编辑活动"</string>
- <string name="event_delete">"删除活动"</string>
- <string name="goto_today">"今天"</string>
- <string name="menu_select_calendars">"我的日历"</string>
- <string name="menu_preferences">"设置"</string>
- <string name="plus_N_more">"(还有 <xliff:g id="MORE_COUNT">%d</xliff:g> 个未显示...)"</string>
- <string name="calendars_title">"我的日历"</string>
- <string name="add_calendars">"添加日历"</string>
- <string name="remove_calendars">"删除日历"</string>
- <string name="event_edit_title">"活动详情"</string>
- <string name="hint_what">"活动名称"</string>
- <string name="hint_where">"活动地点"</string>
- <string name="hint_description">"活动描述"</string>
- <string name="creating_event">"正在创建活动..."</string>
- <string name="saving_event">"正在保存活动..."</string>
- <string name="loading_calendars_title">"载入日历"</string>
- <string name="loading_calendars_message">"正在载入日历..."</string>
- <string name="alert_when_label">"时间:"</string>
- <string name="alert_where_label">"地点:"</string>
- <string name="alert_missed_events_single">"(还有 <xliff:g id="REMINDER_COUNT">%s</xliff:g> 个提醒)"</string>
- <string name="alert_missed_events_multiple">"(还有 <xliff:g id="REMINDER_COUNT">%s</xliff:g> 个提醒)"</string>
- <string name="event_info_title">"查看活动"</string>
- <string name="event_info_title_invite">"会议邀请"</string>
- <string name="add_new_reminder">"添加提醒"</string>
- <string name="edit_event_to_label">"结束日期"</string>
- <string name="edit_event_from_label">"开始日期"</string>
- <string name="edit_event_all_day_label">"全天"</string>
- <string name="edit_event_calendar_label">"日历"</string>
- <string name="edit_event_show_extra_options">"显示其他选项"</string>
- <string name="edit_event_hide_extra_options">"隐藏其他选项"</string>
- <string name="description_label">"描述"</string>
- <string name="presence_label">"现状"</string>
- <string name="privacy_label">"隐私性"</string>
- <string name="reminders_label">"提醒"</string>
- <string name="no_syncable_calendars">"无日历"</string>
- <string name="no_calendars_found">"您没有日历。"</string>
- <string name="view_event_calendar_label">"日历"</string>
- <string name="view_event_timezone_label">"本地时区"</string>
- <string name="view_event_response_label">"是否参加?"</string>
- <string name="agenda_today">"今天"</string>
- <string name="num_events">"活动数"</string>
- <string name="edit_event_label">"编辑活动"</string>
- <string name="delete_label">"删除"</string>
- <string name="delete_event_label">"删除活动"</string>
- <string name="save_label">"保存"</string>
- <string name="discard_label">"放弃更改"</string>
- <string name="import_label">"导入"</string>
- <string name="snooze_all_label">"全部暂停"</string>
- <string name="dismiss_all_label">"全部解除"</string>
- <string name="does_not_repeat">"一次性活动"</string>
- <string name="daily">"每天"</string>
- <string name="every_weekday">"每个工作日(周一至周五)"</string>
- <string name="weekly">"每周(每个<xliff:g id="DAYS_OF_WEEK">%s</xliff:g>)"</string>
- <string name="monthly_on_day_count">"每月(第 <xliff:g id="ORDINAL_NUMBER">%1$s</xliff:g> 个<xliff:g id="DAY_OF_WEEK">%2$s</xliff:g>)"</string>
- <string name="monthly_on_day">"每月(<xliff:g id="DAY_OF_MONTH">%s</xliff:g> 日)"</string>
- <string name="yearly">"每年(<xliff:g id="DATES">%s</xliff:g>)"</string>
- <string name="custom">"自定义...(无法通过电话自定义)"</string>
- <string name="modify_event">"仅更改此活动。"</string>
- <string name="modify_all">"更改此系列的所有活动。"</string>
- <string name="modify_all_following">"更改此活动和将来的所有活动。"</string>
- <string name="delete_this_event_title">"系统将删除此活动。"</string>
- <string name="delete_title">"删除"</string>
- <string name="change_response_title">"更改响应"</string>
- <string name="preferences_title">"设置"</string>
- <string name="preferences_general_title">"日历视图设置"</string>
- <string name="preferences_alerts_title">"提醒设置"</string>
- <string name="preferences_hide_declined_title">"隐藏拒绝的活动"</string>
- <string name="preferences_alerts_type_title">"设置提醒和通知"</string>
- <string name="preferences_alerts_type_dialog">"警报和通知"</string>
- <string name="preferences_alerts_vibrate_title">"振动"</string>
- <string name="preferences_alerts_ringtone_title">"选择铃声"</string>
- <string name="preferences_default_reminder_title">"设置默认提醒"</string>
- <string name="preferences_default_reminder_dialog">"默认提醒时间"</string>
- <string name="preferences_default_reminder_default">"10"</string>
- <string name="gadget_calendar">"日历:"</string>
- <string name="gadget_now_event">"当前活动:<xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_next_event">"下一个活动:<xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_later_event">"稍后的活动:<xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <plurals name="gadget_more_events">
- <item quantity="one">"另外 1 个活动"</item>
- <item quantity="other">"另外 <xliff:g id="NUMBER">%d</xliff:g> 个活动"</item>
- </plurals>
- <string name="gadget_no_events">"近期没有日历活动"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string-array name="reminder_minutes_labels">
- <item>"5 分鐘"</item>
- <item>"10 分鐘"</item>
- <item>"15 分鐘"</item>
- <item>"20 分鐘"</item>
- <item>"25 分鐘"</item>
- <item>"30 分鐘"</item>
- <item>"45 分鐘"</item>
- <item>"1 小時"</item>
- <item>"2 小時"</item>
- <item>"3 小時"</item>
- <item>"12 小時"</item>
- <item>"24 小時"</item>
- <item>"2 天"</item>
- <item>"1 週"</item>
- </string-array>
- <string-array name="reminder_minutes_values">
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_default_reminder_labels">
- <item>"無"</item>
- <item>"5 分鐘"</item>
- <item>"10 分鐘"</item>
- <item>"15 分鐘"</item>
- <item>"20 分鐘"</item>
- <item>"25 分鐘"</item>
- <item>"30 分鐘"</item>
- <item>"45 分鐘"</item>
- <item>"1 小時"</item>
- <item>"2 小時"</item>
- <item>"3 小時"</item>
- <item>"12 小時"</item>
- <item>"24 小時"</item>
- <item>"2 天"</item>
- <item>"1 週"</item>
- </string-array>
- <string-array name="preferences_default_reminder_values">
- <item>"0"</item>
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
- <string-array name="preferences_alert_type_labels">
- <item>"警示"</item>
- <item>"狀態列通知"</item>
- <item>"關閉"</item>
- </string-array>
- <string-array name="preferences_alert_type_values">
- <item>"0"</item>
- <item>"1"</item>
- <item>"2"</item>
- </string-array>
- <string-array name="availability">
- <item>"忙碌"</item>
- <item>"有空"</item>
- </string-array>
- <string-array name="visibility">
- <item>"預設"</item>
- <item>"私人"</item>
- <item>"公開"</item>
- </string-array>
- <string-array name="day_labels">
- <item>"星期日"</item>
- <item>"星期一"</item>
- <item>"星期二"</item>
- <item>"星期三"</item>
- <item>"星期四"</item>
- <item>"星期五"</item>
- <item>"星期六"</item>
- </string-array>
- <string-array name="ordinal_labels">
- <item>"第一個"</item>
- <item>"第二個"</item>
- <item>"第三個"</item>
- <item>"第四個"</item>
- <item>"最後一個"</item>
- </string-array>
- <string-array name="response_labels1">
- <item>"(無回應)"</item>
- <item>"是"</item>
- <item>"不確定"</item>
- <item>"否"</item>
- </string-array>
- <string-array name="response_labels2">
- <item>"是"</item>
- <item>"不確定"</item>
- <item>"否"</item>
- </string-array>
- <string-array name="delete_repeating_labels">
- <item>"僅限此活動"</item>
- <item>"此活動及未來活動"</item>
- <item>"所有活動"</item>
- </string-array>
- <string-array name="delete_repeating_labels_no_selected">
- <item>"此活動及未來活動"</item>
- <item>"所有活動"</item>
- </string-array>
- <string-array name="change_response_labels">
- <item>"僅適用於這一次"</item>
- <item>"所有後續活動"</item>
- </string-array>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label">"Google 日曆"</string>
- <string name="calendar_plug"><font fgcolor="#ffffffff">"歡迎使用 Google 日曆!"</font>\n"Google 提供您管理每日行程的方法,讓您憑直覺快速安排活動,輕鬆存取所有行程。"</string>
- <string name="what_label">"主題"</string>
- <string name="when_label">"時間"</string>
- <string name="where_label">"地點"</string>
- <string name="repeats_label">"重複頻率"</string>
- <string name="no_title_label">"(無主題)"</string>
- <plurals name="Nminutes">
- <item quantity="one">"1 分鐘"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 分鐘"</item>
- </plurals>
- <plurals name="Nmins">
- <item quantity="one">"1 分鐘"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 分鐘"</item>
- </plurals>
- <plurals name="Nhours">
- <item quantity="one">"1 小時"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 小時"</item>
- </plurals>
- <plurals name="Ndays">
- <item quantity="one">"1 天"</item>
- <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 天"</item>
- </plurals>
- <string name="show_agenda_view">"顯示待辦事項"</string>
- <string name="show_day_view">"顯示天"</string>
- <string name="agenda_view">"待辦事項"</string>
- <string name="day_view">"日"</string>
- <string name="week_view">"週"</string>
- <string name="month_view">"月"</string>
- <string name="event_view">"檢視活動"</string>
- <string name="event_create">"新活動"</string>
- <string name="event_edit">"編輯活動"</string>
- <string name="event_delete">"刪除活動"</string>
- <string name="goto_today">"今日"</string>
- <string name="menu_select_calendars">"我的日曆"</string>
- <string name="menu_preferences">"設定"</string>
- <string name="plus_N_more">"(還有 <xliff:g id="MORE_COUNT">%d</xliff:g> 個...)"</string>
- <string name="calendars_title">"我的日曆"</string>
- <string name="add_calendars">"新增日曆"</string>
- <string name="remove_calendars">"移除日曆"</string>
- <string name="event_edit_title">"活動詳細資訊"</string>
- <string name="hint_what">"活動名稱"</string>
- <string name="hint_where">"活動地點"</string>
- <string name="hint_description">"活動說明"</string>
- <string name="creating_event">"正在建立活動..."</string>
- <string name="saving_event">"正在儲存活動..."</string>
- <string name="loading_calendars_title">"正在載入日曆"</string>
- <string name="loading_calendars_message">"正在載入日曆..."</string>
- <string name="alert_when_label">"時間:"</string>
- <string name="alert_where_label">"地點:"</string>
- <string name="alert_missed_events_single">"(還有 <xliff:g id="REMINDER_COUNT">%s</xliff:g> 則提醒)"</string>
- <string name="alert_missed_events_multiple">"(還有 <xliff:g id="REMINDER_COUNT">%s</xliff:g> 則提醒)"</string>
- <string name="event_info_title">"檢視活動"</string>
- <string name="event_info_title_invite">"會議邀請"</string>
- <string name="add_new_reminder">"新增提醒"</string>
- <string name="edit_event_to_label">"到"</string>
- <string name="edit_event_from_label">"從"</string>
- <string name="edit_event_all_day_label">"全天"</string>
- <string name="edit_event_calendar_label">"日曆"</string>
- <string name="edit_event_show_extra_options">"顯示少用選項"</string>
- <string name="edit_event_hide_extra_options">"隱藏少用選項"</string>
- <string name="description_label">"說明"</string>
- <string name="presence_label">"狀態"</string>
- <string name="privacy_label">"隱私權"</string>
- <string name="reminders_label">"提醒"</string>
- <string name="no_syncable_calendars">"無日曆"</string>
- <string name="no_calendars_found">"您沒有日曆。"</string>
- <string name="view_event_calendar_label">"日曆"</string>
- <string name="view_event_timezone_label">"當地時區"</string>
- <string name="view_event_response_label">"是否參加?"</string>
- <string name="agenda_today">"今日"</string>
- <string name="num_events">"活動數"</string>
- <string name="edit_event_label">"編輯活動"</string>
- <string name="delete_label">"刪除"</string>
- <string name="delete_event_label">"刪除活動"</string>
- <string name="save_label">"儲存"</string>
- <string name="discard_label">"捨棄變更"</string>
- <string name="import_label">"匯入"</string>
- <string name="snooze_all_label">"全部關閉"</string>
- <string name="dismiss_all_label">"全部關閉"</string>
- <string name="does_not_repeat">"單次活動"</string>
- <string name="daily">"每日"</string>
- <string name="every_weekday">"平日 (週一至週五)"</string>
- <string name="weekly">"每週 (每<xliff:g id="DAYS_OF_WEEK">%s</xliff:g>)"</string>
- <string name="monthly_on_day_count">"每月 (<xliff:g id="ORDINAL_NUMBER">%1$s</xliff:g><xliff:g id="DAY_OF_WEEK">%2$s</xliff:g>)"</string>
- <string name="monthly_on_day">"每月 (<xliff:g id="DAY_OF_MONTH">%s</xliff:g> 日)"</string>
- <string name="yearly">"每年 (<xliff:g id="DATES">%s</xliff:g> 日)"</string>
- <string name="custom">"自訂... (無法在手機上自訂)"</string>
- <string name="modify_event">"僅變更此活動。"</string>
- <string name="modify_all">"變更所有重複的活動。"</string>
- <string name="modify_all_following">"變更此活動及所有未來活動。"</string>
- <string name="delete_this_event_title">"系統會刪除此活動。"</string>
- <string name="delete_title">"刪除"</string>
- <string name="change_response_title">"變更回應"</string>
- <string name="preferences_title">"設定"</string>
- <string name="preferences_general_title">"日曆檢視設定"</string>
- <string name="preferences_alerts_title">"提醒設定"</string>
- <string name="preferences_hide_declined_title">"隱藏已拒絕的活動"</string>
- <string name="preferences_alerts_type_title">"設定警示及通知"</string>
- <string name="preferences_alerts_type_dialog">"警示及通知"</string>
- <string name="preferences_alerts_vibrate_title">"振動"</string>
- <string name="preferences_alerts_ringtone_title">"選取鈴聲"</string>
- <string name="preferences_default_reminder_title">"設定預設提醒"</string>
- <string name="preferences_default_reminder_dialog">"預設提醒時間"</string>
- <string name="preferences_default_reminder_default">"10"</string>
- <string name="gadget_calendar">"日曆:"</string>
- <string name="gadget_now_event">"目前活動:<xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_next_event">"下個活動:<xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <string name="gadget_later_event">"稍後活動:<xliff:g id="TIME_DATE">%s</xliff:g>"</string>
- <plurals name="gadget_more_events">
- <item quantity="one">"還有 1 個活動"</item>
- <item quantity="other">"還有 <xliff:g id="NUMBER">%d</xliff:g> 個活動"</item>
- </plurals>
- <string name="gadget_no_events">"沒有即將開始的日曆活動"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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.
--->
-
-<resources>
- <!-- Choices for the "Reminder minutes" spinner.
- These must be kept in sync with the reminder_minutes_values array.
- -->
- <string-array name="reminder_minutes_labels">
- <item>5 minutes</item>
- <item>10 minutes</item>
- <item>15 minutes</item>
- <item>20 minutes</item>
- <item>25 minutes</item>
- <item>30 minutes</item>
- <item>45 minutes</item>
- <item>1 hour</item>
- <item>2 hours</item>
- <item>3 hours</item>
- <item>12 hours</item>
- <item>24 hours</item>
- <item>2 days</item>
- <item>1 week</item>
- </string-array>
-
- <string-array name="reminder_minutes_values">
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
-
- <string-array name="preferences_default_reminder_labels">
- <item>None</item>
- <item>5 minutes</item>
- <item>10 minutes</item>
- <item>15 minutes</item>
- <item>20 minutes</item>
- <item>25 minutes</item>
- <item>30 minutes</item>
- <item>45 minutes</item>
- <item>1 hour</item>
- <item>2 hours</item>
- <item>3 hours</item>
- <item>12 hours</item>
- <item>24 hours</item>
- <item>2 days</item>
- <item>1 week</item>
- </string-array>
-
- <string-array name="preferences_default_reminder_values">
- <item>"0"</item>
- <item>"5"</item>
- <item>"10"</item>
- <item>"15"</item>
- <item>"20"</item>
- <item>"25"</item>
- <item>"30"</item>
- <item>"45"</item>
- <item>"60"</item>
- <item>"120"</item>
- <item>"180"</item>
- <item>"720"</item>
- <item>"1440"</item>
- <item>"2880"</item>
- <item>"10080"</item>
- </string-array>
-
- <string-array name="preferences_alert_type_labels">
- <item>Alert</item>
- <item>Status bar notification</item>
- <item>Off</item>
- </string-array>
-
- <string-array name="preferences_alert_type_values">
- <item>"0"</item>
- <item>"1"</item>
- <item>"2"</item>
- </string-array>
-
- <string-array name="availability">
- <item>Busy</item>
- <item>Available</item>
- </string-array>
-
- <string-array name="visibility">
- <item>Default</item>
- <item>Private</item>
- <item>Public</item>
- </string-array>
-
- <!-- Order matters, and note that the preference for which day the week starts on is handled
- elsewhere (and needn't be addressed here). -->
- <string-array name="day_labels">
- <item>Sunday</item>
- <item>Monday</item>
- <item>Tuesday</item>
- <item>Wednesday</item>
- <item>Thursday</item>
- <item>Friday</item>
- <item>Saturday</item>
- </string-array>
-
- <string-array name="ordinal_labels">
- <item>first</item>
- <item>second</item>
- <item>third</item>
- <item>fourth</item>
- <item>last</item>
- </string-array>
-
- <!-- Invitation responses -->
- <string-array name="response_labels1">
- <item>(No response)</item>
- <item>Yes</item>
- <item>Maybe</item>
- <item>No</item>
- </string-array>
- <string-array name="response_labels2">
- <item>Yes</item>
- <item>Maybe</item>
- <item>No</item>
- </string-array>
-
- <!-- The corresponding indices are defined in DeleteEventHelper.java -->
- <skip />
- <string-array name="delete_repeating_labels">
- <item>Only this event</item>
- <item>This & future events</item>
- <item>All events</item>
- </string-array>
-
- <!-- The corresponding indices are defined in DeleteEventHelper.java -->
- <!-- This is the same array as above (the "delete_repeating_labels" array,
- except that the first element "Only this event" is removed. This
- array exists to work-around a bug in the CalendarProvider and sync
- code where you can't delete one instance of a repeating event that
- was created on the phone until that event has been synced to the server.
- -->
- <skip />
- <string-array name="delete_repeating_labels_no_selected">
- <item>This & future events</item>
- <item>All events</item>
- </string-array>
-
- <!-- The corresponding array indices are defined in EventInfoActivity.java -->
- <skip />
- <!-- The list of choices displayed in a dialog box when the user wants to
- respond to an invitation that repeats. -->
- <string-array name="change_response_labels">
- <!-- The choice for responding to only one instance of a repeating event -->
- <item>Only this instance</item>
- <!-- The choice for responding to all instances of a repeating event -->
- <item>All events in the series</item>
- </string-array>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/Calendar/assets/res/any/colors.xml
-**
-** Copyright 2006, 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.
-*/
--->
-<resources>
- <color name="event_background">#ffc3d9ff</color>
- <color name="panel_text_foreground">#ffffffff</color>
- <color name="daynames_background">#ffc3d9ff</color>
- <color name="daynames_text_color">#ff112abb</color>
- <color name="calendar_event_selected_text_color">#ff000000</color>
- <color name="calendar_event_text_color">#ffffffff</color>
-
- <color name="calendar_all_day_background">#ffe8eef7</color>
- <color name="week_weekend">#ff446688</color>
- <color name="calendar_hour_label">#ff446688</color>
- <color name="calendar_ampm_label">#ff446688</color>
- <color name="calendar_hour_background">#ffe8eef7</color>
- <color name="calendar_hour_selected">#ffB0B0B0</color>
- <color name="calendar_date_banner_background">#ffc3d9ff</color>
- <color name="calendar_date_selected">#ffB0B0B0</color>
- <color name="calendar_date_banner_text_color">#ff446688</color>
- <color name="calendar_grid_area_background">#ffffffff</color>
- <color name="calendar_grid_area_selected">#ffffffcc</color>
- <color name="calendar_grid_line_horizontal_color">#ffdddddd</color>
- <color name="calendar_grid_line_vertical_color">#ff5a5a5a</color>
- <color name="calendar_grid_line_highlight_color">#ff707070</color>
- <color name="selection">#ffffaa00</color>
- <color name="pressed">#fffab400</color>
-
- <color name="month_day_number">#ff404040</color>
- <color name="month_today_number">#ffffffff</color>
- <color name="month_other_month">#ff595959</color>
- <color name="month_other_month_day_number">#ffa0a0a0</color>
- <color name="month_other_month_banner">#80595959</color>
- <color name="month_week_banner">#20595959</color>
-
- <color name="event_center">#ff6bd697</color>
-
- <color name="gadget_when">#ffffffff</color>
- <color name="gadget_reminder">#ffffffff</color>
- <color name="gadget_title">#ff000000</color>
- <color name="gadget_where">#ff000000</color>
- <color name="gadget_calendar">#ff000000</color>
-
- <color name="gadget_no_events">#bb000000</color>
-
- <drawable name="agenda_item_declined">#88ffffff</drawable>
-</resources>
-
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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.
--->
-
-<resources>
- <integer name="number_of_hours">10</integer>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2006 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.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- This is the label underneath the icon for Calendar -->
- <string name="app_label">Calendar</string>
- <!-- This is the welcome message when a user starts Calendar for the first time -->
- <string name="calendar_plug"><font fgcolor="#ffffffff">Welcome to Google Calendar!</font>
- \nA Google approach to managing your schedule built on the idea that scheduling events can be more intuitive, efficient and accessible.
- </string>
-
- <!-- Shared Labels. These labels are shared among the activities. -->
- <skip />
- <!-- This is the label for the title or name of an event -->
- <string name="what_label">What</string>
- <!-- This is the label for the date and time of an event -->
- <string name="when_label">When</string>
- <!-- This is the label for the location of an event -->
- <string name="where_label">Where</string>
- <!-- Some events repeat daily, weekly, monthly, or yearly. This is the label
- for all the choices about how often an event repeats (including the choice
- of not repeating). -->
- <string name="repeats_label">Repetition</string>
- <!-- Title of event when no explicit title is specified by the user -->
- <string name="no_title_label">(No subject)</string>
-
- <!-- Reminder format strings -->
- <plurals name="Nminutes">
- <!-- This is the label for a 1-minute reminder. -->
- <item quantity="one">1 minute</item>
- <!-- This is the label for 2 or more minutes. The actual number of
- minutes is a parameter. -->
- <item quantity="other"><xliff:g id="count">%d</xliff:g> minutes</item>
- </plurals>
- <!-- We use the abbreviation "mins" instead of "minutes" to keep the string short.
- This is the number of minutes displayed for a calendar reminder. For example,
- a reminder of 10 minutes would be displayed as '10 mins'. The translation
- should use the shortest acceptable abbreviation to save space. -->
- <plurals name="Nmins">
- <!-- This is the label for a 1-minute reminder. -->
- <item quantity="one">1 min</item>
- <!-- This is the label for 2 or more minutes. The actual number of
- minutes is a parameter. -->
- <item quantity="other"><xliff:g id="count">%d</xliff:g> mins</item>
- </plurals>
- <!-- This is the number of hours displayed for a calendar reminder. For example,
- a reminder of 1 hour would be displayed as '1 hour'. The translation
- should use the shortest acceptable abbreviation of 'hour' to save space. -->
- <plurals name="Nhours">
- <!-- This is the label for a 1-hour reminder. -->
- <item quantity="one">1 hour</item>
- <!-- This is the label for a reminder of 2 or more hours. The actual number of
- hours is a parameter. -->
- <item quantity="other"><xliff:g id="count">%d</xliff:g> hours</item>
- </plurals>
- <!-- This is the number of days displayed for a calendar reminder. For example,
- a reminder of 2 days would be displayed as '2 days'. The translation
- should use the shortest acceptable abbreviation of 'day' to save space. -->
- <plurals name="Ndays">
- <!-- This is the label for a reminder of 1 day. -->
- <item quantity="one">1 day</item>
- <!-- This is the label for a reminder of 2 or more days. The actual number of
- days is a parameter. -->
- <item quantity="other"><xliff:g id="count">%d</xliff:g> days</item>
- </plurals>
-
- <!-- Menu items: -->
- <skip />
- <!-- This is a label on a context menu item. Pressing this menu item displays the
- Agenda view. -->
- <string name="show_agenda_view">"Show agenda"</string>
- <!-- This is a label on a context menu item. Pressing this menu item displays the
- Day view. -->
- <string name="show_day_view">"Show day"</string>
- <!-- This is a label on a menu item. Pressing this menu item displays the
- Agenda view. -->
- <string name="agenda_view">"Agenda"</string>
- <!-- This is a label on a menu item. Pressing this menu item displays the
- Day view. -->
- <string name="day_view">"Day"</string>
- <!-- This is a label on a menu item. Pressing this menu item displays the
- Week view. -->
- <string name="week_view">"Week"</string>
- <!-- This is a label on a menu item. Pressing this menu item displays the
- Month view. -->
- <string name="month_view">"Month"</string>
- <!-- This is a label on a menu item. Pressing this menu item displays the
- details of an event. -->
- <string name="event_view">"View event"</string>
- <!-- This is a label on a menu item. Pressing this menu item allows the
- user to create a new event. -->
- <string name="event_create">"New event"</string>
- <!-- This is a label on a menu item in a popup window. Pressing this menu
- item allows the user to edit or change an existing event. -->
- <string name="event_edit">"Edit event"</string>
- <!-- This is a label on a menu item in a popup window. Pressing this menu
- item allows the user to delete an existing event. -->
- <string name="event_delete">"Delete event"</string>
- <!-- This is a label on a menu item. Pressing this menu
- item takes the user to the current day (today) in whatever view
- (Day view, Week view, Agenda view, Month view) they are currently in. -->
- <string name="goto_today">"Today"</string>
- <!-- This is a label on a menu item. Pressing this menu item allows the
- user to see the list of calendars that he is viewing and to then add
- or remove selected calendars. -->
- <string name="menu_select_calendars">"My calendars"</string>
- <!-- This is a label on a menu item. Pressing this menu item allows the
- user to view and edit his Settings (or Preferences) -->
- <string name="menu_preferences">"Settings"</string>
-
- <!-- Month view -->
- <skip />
- <!-- This string is used in a popup window when there are more events than
- can be displayed so it displays the events that it can and then displays
- this line so that the user knows how many more events there are that
- could not be displayed. For example, if there are 6 events but we can
- only display 4 events then we will display the first 4 events and then
- show 'plus 2 more' to indicate that there are two more events that we
- could not display because of lack of room. -->
- <string name="plus_N_more">"(plus <xliff:g id="more_count">%d</xliff:g> more \u2026)"</string>
-
- <!-- Select Calendars activity -->
- <skip />
- <!-- Title of "My calendars" screen -->
- <string name="calendars_title">"My calendars"</string>
- <!-- Menu option for selecting calendars to add -->
- <string name="add_calendars">"Add calendars"</string>
- <!-- Menu option for selecting calendars to remove -->
- <string name="remove_calendars">"Remove calendars"</string>
-
- <!-- Event edit activity -->
- <skip />
- <!-- The title of the screen where the user edits an event -->
- <string name="event_edit_title">"Event details"</string>
- <!-- Default value of What field (as a hint to the user) -->
- <string name="hint_what">"Event name"</string>
- <!-- Default value of Where field (as a hint to the user) -->
- <string name="hint_where">"Event location"</string>
- <!-- Default value of Description field (as a hint to the user) -->
- <string name="hint_description">"Event description"</string>
- <string name="creating_event">"Creating event\u2026"</string>
- <string name="saving_event">"Saving event\u2026"</string>
- <string name="loading_calendars_title">"Loading calendars"</string>
- <string name="loading_calendars_message">"Loading calendars\u2026"</string>
-
- <!-- The alert toast is not actually being displayed for some reason. -->
- <skip />
- <!-- The label for the date/time of an event in a popup window -->
- <string name="alert_when_label">When:</string>
- <!-- The label for the location of an event in a popup window -->
- <string name="alert_where_label">Where:</string>
- <!-- Notification window messages: -->
- <skip />
- <!-- This shows the number of additional reminders that were missed. This
- is the singular case so it displays '1 more reminder' -->
- <string name="alert_missed_events_single">(<xliff:g id="reminder_count">%s</xliff:g> more reminder)</string>
- <!-- This shows the number of additional reminders that were missed. For example,
- if there were two additional reminders then this would show
- '2 more reminders' -->
- <string name="alert_missed_events_multiple">(<xliff:g id="reminder_count">%s</xliff:g> more reminders)</string>
-
- <!-- Event info/edit screen labels:-->
- <skip />
- <!-- This is the title of the screen used to view the details of an event -->
- <string name="event_info_title">View event</string>
- <!-- This is the title of the screen used to view the details of an invitation
- to a meeting or event -->
- <string name="event_info_title_invite">Meeting invitation</string>
- <!-- Menu item to allow the user to add a reminder to an event -->
- <string name="add_new_reminder">Add reminder</string>
-
- <!-- EditEventActivity specific strings: -->
- <skip />
- <!-- Events have a start date/time and an end date/time. The display shows
- the start and end times like 'From start date To end date'. This is the
- label before the 'end date'. -->
- <string name="edit_event_to_label">To</string>
- <!-- Events have a start date/time and an end date/time. The display shows
- the start and end times like 'From start date To end date'. This is the
- label before the 'start date'. -->
- <string name="edit_event_from_label">From</string>
- <!-- Check box label that specifies if this is an all-day event -->
- <string name="edit_event_all_day_label">All day</string>
- <!-- Label for choosing one of the calendars -->
- <string name="edit_event_calendar_label">Calendar</string>
- <!-- Menu item to show extra options that are used less often -->
- <string name="edit_event_show_extra_options">Show extra options</string>
- <!-- Menu item to hide extra options that are used less often -->
- <string name="edit_event_hide_extra_options">Hide extra options</string>
- <!-- Label for the event description -->
- <string name="description_label">Description</string>
- <!-- Label for the 'Presence' of an event, which can be either 'busy' (the default)
- or 'available' -->
- <string name="presence_label">Presence</string>
- <!-- Label for the 'Privacy' of an event, which can be either 'private'
- or 'public' -->
- <string name="privacy_label">Privacy</string>
- <!-- Label for the list of reminders for an event -->
- <string name="reminders_label">Reminders</string>
- <string name="no_syncable_calendars">No calendars</string>
- <string name="no_calendars_found">You have no calendars.</string>
-
- <!-- View Event -->
- <skip />
- <!-- Label for which calendar an event is part of -->
- <string name="view_event_calendar_label">Calendar</string>
- <!-- Label for the local timezone -->
- <string name="view_event_timezone_label">Local time zone</string>
- <!-- Label for whether the user is attending this event. This is shown when
- a user is invited to a meeting or event. The possible answers are
- 'yes', 'no', and 'maybe' (and, initially, 'no response'). -->
- <string name="view_event_response_label">Attending?</string>
-
- <!-- Agenda View strings -->
- <skip />
- <!-- This is shown as part of the heading at the top of a list of today's events. -->
- <string name="agenda_today">Today</string>
-
- <!-- ICS Import activity -->
- <skip />
- <!-- This is a abbreviation for 'Number of events' and is a label next to
- an input for the user to enter the number of events to import. -->
- <string name="num_events">"Num events"</string>
-
- <!-- Button labels: -->
- <skip />
- <!-- This is the title of a popup window that is displayed when the user
- edits a repeating event. -->
- <string name="edit_event_label">"Edit event"</string>
- <!-- The button label for deleting an event -->
- <string name="delete_label">"Delete"</string>
- <!-- A menu item for deleting an event -->
- <string name="delete_event_label">"Delete event"</string>
- <!-- The button label for saving an event -->
- <string name="save_label">Save</string>
- <!-- The button label for discarding changes to an event -->
- <string name="discard_label">Discard changes</string>
- <!-- The button label for importing events from another source to the phone -->
- <string name="import_label">"Import"</string>
-
- <!-- Button labels on expanded notification reminders: -->
- <skip />
- <!-- The button label for making the reminder alarms go away temporarily.
- The reminder alarms will fire off again in 5 minutes. -->
- <string name="snooze_all_label">"Snooze all"</string>
- <!-- The button label for dismissing all the current reminder alarms. This
- causes them to disappear from the notification screen. -->
- <string name="dismiss_all_label">"Dismiss all"</string>
-
- <!-- Repetition dialog options: -->
- <skip />
- <!-- A label in a multiple-choice list for the specifying that an event does
- not repeat -->
- <string name="does_not_repeat">One-time event</string>
- <!-- A label in a multiple-choice list for the specifying that an event
- repeats daily -->
- <string name="daily">Daily</string>
- <!-- A label in a multiple-choice list for the specifying that an event
- repeats every weekday (Monday through Friday) -->
- <string name="every_weekday">"Every weekday (Mon\u2013Fri)"</string>
- <!-- A label in a multiple-choice list for the specifying that an event
- repeats weekly on some day of the week. For example,
- 'Weekly (every Tuesday)'. -->
- <string name="weekly">"Weekly (every <xliff:g id="days_of_week">%s</xliff:g>)"</string>
-
- <!-- Example: 'Monthly (every first Sunday)' -->
- <!-- 1st parameter is an ordinal number, like 'first' -->
- <!-- 2nd parameter is a day of the week, like 'Sunday' -->
- <string name="monthly_on_day_count">"Monthly (every <xliff:g id="ordinal_number">%1$s</xliff:g> <xliff:g id="day_of_week">%2$s</xliff:g>)"</string>
-
- <!-- Example: "Monthly (on day 15)" -->
- <string name="monthly_on_day">"Monthly (on day <xliff:g id="day_of_month">%s</xliff:g>)"</string>
- <!-- Example: "Yearly (on April 15)" -->
- <string name="yearly">"Yearly (on <xliff:g id="dates">%s</xliff:g>)"</string>
- <!-- This is a label for telling the user that this event repeats in
- custom (non-standard) way from the usual repeat rates (such as daily,
- weekly, etc.) and that the user cannot change this on the phone
- (but only on the web). -->
- <string name="custom">"Custom\u2026 (cannot customize on phone)"</string>
-
- <!-- This is a choice in a list that the user sees when he tries to modify
- a repeating event. This choice says to change just this one instance
- of this repeating event. -->
- <string name="modify_event">Change only this event.</string>
- <!-- This is a choice in a list that the user sees when he tries to modify
- a repeating event. This choice says to change all occurrences of
- this repeating event. -->
- <string name="modify_all">Change all events in the series.</string>
- <!-- This is a choice in a list that the user sees when he tries to modify
- a repeating event. This choice says to change this instance and all
- future occurrences of this repeating event. -->
- <string name="modify_all_following">Change this and all future events.</string>
-
- <!-- Dialogs -->
- <!-- Confirmation dialog message -->
- <skip />
- <!-- This is a confirmation message in a popup dialog that appears when the
- user has asked to delete an event. The user still has a chance to cancel
- this operation. -->
- <string name="delete_this_event_title">This event will be deleted.</string>
- <!-- This is the title of a popup dialog that asks for confirmation before
- deleting an event. -->
- <string name="delete_title">Delete</string>
- <!-- This is the title of a popup dialog that asks for confirmation before
- changing the response to an invitation. -->
- <string name="change_response_title">Change response</string>
-
- <!-- This is the title of the screen for setting user preferences. -->
- <string name="preferences_title">"Settings"</string>
- <!-- This is the title of a section in the Settings screen for settings
- related to viewing calendar events -->
- <string name="preferences_general_title">Calendar view setting</string>
- <!-- This is the title of a section in the Settings screen for settings
- related to reminders for calendar events -->
- <string name="preferences_alerts_title">Reminder settings</string>
- <!-- Settings check box label to hide events that the user has declined to attend -->
- <string name="preferences_hide_declined_title">Hide declined events</string>
- <!-- Settings option to bring up a dialog that lets the user choose how
- reminder notifications should occur. -->
- <string name="preferences_alerts_type_title">Set alerts & notifications</string>
- <!-- The title of a popup dialog that lets the user choose how
- reminder notifications should occur. -->
- <string name="preferences_alerts_type_dialog">Alerts & notifications</string>
- <!-- DO NOT TRANSLATE -->
- <string name="preferences_alerts_type_default">1</string>
- <!-- Settings check box label that specifies whether the phone should vibrate -->
- <string name="preferences_alerts_vibrate_title">Vibrate</string>
- <!-- Title of ringtone selector dialog -->
- <string name="preferences_alerts_ringtone_title">Select ringtone</string>
- <!-- List item label for setting the default number of reminder minutes -->
- <string name="preferences_default_reminder_title">Set default reminder</string>
- <!-- Title of dialog for setting the default number of reminder minutes -->
- <string name="preferences_default_reminder_dialog">Default reminder time</string>
- <!-- Default value for the number of reminder minutes -->
- <string name="preferences_default_reminder_default">10</string>
-
- <!-- Bold prefix for gadget that identifies the calendar display name -->
- <string name="gadget_calendar">Calendar:</string>
-
- <!-- Prefix for date/time of currently happening event in gadget -->
- <string name="gadget_now_event">Now: <xliff:g id="time_date">%s</xliff:g></string>
- <!-- Prefix for date/time of next upcoming event in gadget -->
- <string name="gadget_next_event">Next: <xliff:g id="time_date">%s</xliff:g></string>
- <!-- Prefix for date/time of later upcoming event in gadget -->
- <string name="gadget_later_event">Later: <xliff:g id="time_date">%s</xliff:g></string>
-
- <!-- Shown in gadget when additional events are available for display, but no room remaining -->
- <plurals name="gadget_more_events">
- <!-- additional events message for 1 event -->
- <item quantity="one">1 more event</item>
- <!-- additional events message for multiple events -->
- <item quantity="other"><xliff:g id="number">%d</xliff:g> more events</item>
- </plurals>
-
- <!-- Caption to show on gadget when there are no upcoming calendar events -->
- <string name="gadget_no_events">No upcoming calendar events</string>
-
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/Calendar/assets/res/any/styles.xml
-**
-** Copyright 2006, 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.
-*/
--->
-<resources>
-
- <style name="Alert" parent="android:Theme.Dialog">
- <item name="android:windowBackground">@null</item>
- </style>
-
- <style name="MonthView_DayLabel">
- <item name="android:layout_width">29dip</item>
- <item name="android:layout_height">fill_parent</item>
- <item name="android:layout_weight">1</item>
- <item name="android:gravity">center</item>
- <item name="android:paddingTop">2dip</item>
- <item name="android:paddingBottom">2dip</item>
- <item name="android:textAppearance">@style/TextAppearance.MonthView_DayLabel</item>
- </style>
-
- <style name="TextAppearance" parent="android:TextAppearance">
- </style>
-
- <style name="TextAppearance.MonthView_DayLabel">
- <item name="android:textSize">14sp</item>
- <item name="android:textStyle">bold</item>
- <item name="android:textColor">@color/daynames_text_color</item>
- </style>
-
- <style name="TextAppearance.AgendaView_ValueLabel">
- <item name="android:textSize">14sp</item>
- <item name="android:textColor">@android:color/black</item>
- </style>
-
- <style name="TextAppearance.EditEvent_Label">
- <item name="android:textSize">14sp</item>
- <item name="android:textStyle">bold</item>
- </style>
-
- <style name="TextAppearance.Alert_Title">
- <item name="android:textSize">18sp</item>
- <item name="android:textColor">@android:color/white</item>
- </style>
-
- <style name="TextAppearance.Alert_Label">
- <item name="android:textSize">14sp</item>
- <item name="android:textStyle">bold</item>
- <item name="android:textColor">@android:color/white</item>
- </style>
-
- <style name="TextAppearance.Alert_Value">
- <item name="android:textSize">14sp</item>
- <item name="android:textColor">@android:color/white</item>
- </style>
-
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<gadget-provider xmlns:android="http://schemas.android.com/apk/res/android"
- android:minWidth="294dip"
- android:minHeight="72dip"
- android:updatePeriodMillis="0"
- android:initialLayout="@layout/gadget_item"
- >
-</gadget-provider>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
- <PreferenceCategory android:title="@string/preferences_general_title">
- <CheckBoxPreference
- android:key="preferences_hide_declined"
- android:defaultValue="false"
- android:title="@string/preferences_hide_declined_title" />
- </PreferenceCategory>
-
- <PreferenceCategory android:title="@string/preferences_alerts_title">
- <ListPreference
- android:key="preferences_alerts_type"
- android:defaultValue="@string/preferences_alerts_type_default"
- android:title="@string/preferences_alerts_type_title"
- android:entries="@array/preferences_alert_type_labels"
- android:entryValues="@array/preferences_alert_type_values"
- android:dialogTitle="@string/preferences_alerts_type_dialog" />
-
- <RingtonePreference
- android:layout="?android:attr/preferenceLayoutChild"
- android:key="preferences_alerts_ringtone"
- android:title="@string/preferences_alerts_ringtone_title"
- android:ringtoneType="notification"
- android:defaultValue="content://settings/system/notification_sound" />
-
- <CheckBoxPreference
- android:layout="?android:attr/preferenceLayoutChild"
- android:key="preferences_alerts_vibrate"
- android:defaultValue="false"
- android:title="@string/preferences_alerts_vibrate_title" />
-
- <ListPreference
- android:key="preferences_default_reminder"
- android:defaultValue="@string/preferences_default_reminder_default"
- android:title="@string/preferences_default_reminder_title"
- android:entries="@array/preferences_default_reminder_labels"
- android:entryValues="@array/preferences_default_reminder_values"
- android:dialogTitle="@string/preferences_default_reminder_dialog" />
- </PreferenceCategory>
-</PreferenceScreen>
+++ /dev/null
-/*
- * Copyright (C) 2007 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.app.Activity;
-import android.content.AsyncQueryHandler;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.preference.PreferenceManager;
-import android.provider.Calendar;
-import android.provider.Calendar.Attendees;
-import android.provider.Calendar.Calendars;
-import android.provider.Calendar.Events;
-import android.provider.Calendar.Instances;
-import android.text.format.Time;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.widget.AdapterView;
-import android.widget.ListView;
-import android.widget.ViewSwitcher;
-import dalvik.system.VMRuntime;
-
-public class AgendaActivity extends Activity implements ViewSwitcher.ViewFactory, Navigator {
-
- protected static final String BUNDLE_KEY_RESTORE_TIME = "key_restore_time";
-
- static final String[] PROJECTION = new String[] {
- Instances._ID, // 0
- Instances.TITLE, // 1
- Instances.EVENT_LOCATION, // 2
- Instances.ALL_DAY, // 3
- Instances.HAS_ALARM, // 4
- Instances.COLOR, // 5
- Instances.RRULE, // 6
- Instances.BEGIN, // 7
- Instances.END, // 8
- Instances.EVENT_ID, // 9
- Instances.START_DAY, // 10 Julian start day
- Instances.END_DAY, // 11 Julian end day
- Instances.SELF_ATTENDEE_STATUS, // 12
- };
-
- public static final int INDEX_TITLE = 1;
- public static final int INDEX_EVENT_LOCATION = 2;
- public static final int INDEX_ALL_DAY = 3;
- public static final int INDEX_HAS_ALARM = 4;
- public static final int INDEX_COLOR = 5;
- public static final int INDEX_RRULE = 6;
- public static final int INDEX_BEGIN = 7;
- public static final int INDEX_END = 8;
- public static final int INDEX_EVENT_ID = 9;
- public static final int INDEX_START_DAY = 10;
- public static final int INDEX_END_DAY = 11;
- public static final int INDEX_SELF_ATTENDEE_STATUS = 12;
-
- public static final String AGENDA_SORT_ORDER = "startDay ASC, begin ASC, title ASC";
-
- private static final long INITIAL_HEAP_SIZE = 4*1024*1024;
-
- private ContentResolver mContentResolver;
-
- private ViewSwitcher mViewSwitcher;
-
- private QueryHandler mQueryHandler;
- private DeleteEventHelper mDeleteEventHelper;
- private Time mTime;
-
- /**
- * This records the start time parameter for the last query sent to the
- * AsyncQueryHandler so that we don't send it duplicate query requests.
- */
- private Time mLastQueryTime = new Time();
-
- private class QueryHandler extends AsyncQueryHandler {
- public QueryHandler(ContentResolver cr) {
- super(cr);
- }
-
- @Override
- protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
-
- // Only set mCursor if the Activity is not finishing. Otherwise close the cursor.
- if (!isFinishing()) {
- AgendaListView next = (AgendaListView) mViewSwitcher.getNextView();
- next.setCursor(cursor);
- mViewSwitcher.showNext();
- selectTime();
- } else {
- cursor.close();
- }
- }
- }
-
- private class AgendaListView extends ListView {
- private Cursor mCursor;
- private AgendaByDayAdapter mDayAdapter;
- private AgendaAdapter mAdapter;
-
- public AgendaListView(Context context) {
- super(context, null);
- setOnItemClickListener(mOnItemClickListener);
- setChoiceMode(ListView.CHOICE_MODE_SINGLE);
- mAdapter = new AgendaAdapter(AgendaActivity.this, R.layout.agenda_item);
- mDayAdapter = new AgendaByDayAdapter(AgendaActivity.this, mAdapter);
- }
-
- public void setCursor(Cursor cursor) {
- if (mCursor != null) {
- mCursor.close();
- }
- mCursor = cursor;
- mDayAdapter.calculateDays(cursor);
- mAdapter.changeCursor(cursor);
- setAdapter(mDayAdapter);
- }
-
- public Cursor getCursor() {
- return mCursor;
- }
-
- public AgendaByDayAdapter getDayAdapter() {
- return mDayAdapter;
- }
-
- @Override protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- if (mCursor != null) {
- mCursor.close();
- }
- }
-
- private OnItemClickListener mOnItemClickListener = new OnItemClickListener() {
- public void onItemClick(AdapterView a, View v, int position, long id) {
- if (id != -1) {
- // Switch to the EventInfo view
- mCursor.moveToPosition(mDayAdapter.getCursorPosition(position));
- long eventId = mCursor.getLong(INDEX_EVENT_ID);
- Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId);
- Intent intent = new Intent(Intent.ACTION_VIEW, uri);
- intent.putExtra(Calendar.EVENT_BEGIN_TIME, mCursor.getLong(INDEX_BEGIN));
- intent.putExtra(Calendar.EVENT_END_TIME, mCursor.getLong(INDEX_END));
- startActivity(intent);
- }
- }
- };
- }
-
- private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_TIME_CHANGED)
- || action.equals(Intent.ACTION_DATE_CHANGED)
- || action.equals(Intent.ACTION_TIMEZONE_CHANGED)) {
- clearLastQueryTime();
- renewCursor();
- }
- }
- };
-
- private ContentObserver mObserver = new ContentObserver(new Handler()) {
- @Override
- public boolean deliverSelfNotifications() {
- return true;
- }
-
- @Override
- public void onChange(boolean selfChange) {
- clearLastQueryTime();
- renewCursor();
- }
- };
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- // Eliminate extra GCs during startup by setting the initial heap size to 4MB.
- // TODO: We should restore the old heap size once the activity reaches the idle state
- long oldHeapSize = VMRuntime.getRuntime().setMinimumHeapSize(INITIAL_HEAP_SIZE);
-
- getWindow().requestFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.agenda_activity);
-
- mContentResolver = getContentResolver();
- mQueryHandler = new QueryHandler(mContentResolver);
-
- // Preserve the same month and event selection if this activity is
- // being restored due to an orientation change
- mTime = new Time();
- if (icicle != null) {
- mTime.set(icicle.getLong(BUNDLE_KEY_RESTORE_TIME));
- } else {
- mTime.set(Utils.timeFromIntent(getIntent()));
- }
- setTitle(Utils.formatMonthYear(mTime));
-
- mViewSwitcher = (ViewSwitcher) findViewById(R.id.switcher);
- mViewSwitcher.setFactory(this);
-
- // Record Agenda View as the (new) default detailed view.
- String activityString = CalendarApplication.ACTIVITY_NAMES[CalendarApplication.AGENDA_VIEW_ID];
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- SharedPreferences.Editor editor = prefs.edit();
- editor.putString(CalendarPreferenceActivity.KEY_DETAILED_VIEW, activityString);
-
- // Record Agenda View as the (new) start view
- editor.putString(CalendarPreferenceActivity.KEY_START_VIEW, activityString);
- editor.commit();
-
- mDeleteEventHelper = new DeleteEventHelper(this, false /* don't exit when done */);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
-
- clearLastQueryTime();
- renewCursor();
-
- // Register for Intent broadcasts
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_TIME_CHANGED);
- filter.addAction(Intent.ACTION_DATE_CHANGED);
- filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
- registerReceiver(mIntentReceiver, filter);
-
- mContentResolver.registerContentObserver(Events.CONTENT_URI, true, mObserver);
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
-
- outState.putLong(BUNDLE_KEY_RESTORE_TIME, getSelectedTime());
- }
-
- @Override
- protected void onPause() {
- super.onPause();
-
- mContentResolver.unregisterContentObserver(mObserver);
- unregisterReceiver(mIntentReceiver);
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- MenuHelper.onPrepareOptionsMenu(this, menu);
- return super.onPrepareOptionsMenu(menu);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuHelper.onCreateOptionsMenu(menu);
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- MenuHelper.onOptionsItemSelected(this, item, this);
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_DEL: {
- // Delete the currently selected event (if any)
- AgendaListView current = (AgendaListView) mViewSwitcher.getCurrentView();
- Cursor cursor = current.getCursor();
- if (cursor != null) {
- int position = current.getSelectedItemPosition();
- position = current.getDayAdapter().getCursorPosition(position);
- if (position >= 0) {
- cursor.moveToPosition(position);
- long begin = cursor.getLong(INDEX_BEGIN);
- long end = cursor.getLong(INDEX_END);
- long eventId = cursor.getLong(INDEX_EVENT_ID);
- mDeleteEventHelper.delete(begin, end, eventId, -1);
- }
- }
- }
- break;
-
- case KeyEvent.KEYCODE_BACK:
- finish();
- return true;
- }
- return super.onKeyDown(keyCode, event);
- }
-
- /**
- * Clears the cached value for the last query time so that renewCursor()
- * will force a requery of the Calendar events.
- */
- private void clearLastQueryTime() {
- mLastQueryTime.year = 0;
- mLastQueryTime.month = 0;
- }
-
- private void renewCursor() {
- // Avoid batching up repeated queries for the same month. This can
- // happen if the user scrolls with the trackball too fast.
- if (mLastQueryTime.month == mTime.month && mLastQueryTime.year == mTime.year) {
- return;
- }
-
- // Query all instances for the current month
- Time time = new Time();
- time.year = mTime.year;
- time.month = mTime.month;
- long start = time.normalize(true);
-
- time.month++;
- long end = time.normalize(true);
-
- StringBuilder path = new StringBuilder();
- path.append(start);
- path.append('/');
- path.append(end);
-
- // Respect the preference to show/hide declined events
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- boolean hideDeclined = prefs.getBoolean(CalendarPreferenceActivity.KEY_HIDE_DECLINED,
- false);
-
- Uri uri = Uri.withAppendedPath(Instances.CONTENT_URI, path.toString());
-
- String selection;
- if (hideDeclined) {
- selection = Calendars.SELECTED + "=1 AND " +
- Instances.SELF_ATTENDEE_STATUS + "!=" + Attendees.ATTENDEE_STATUS_DECLINED;
- } else {
- selection = Calendars.SELECTED + "=1";
- }
-
- // Cancel any previous queries that haven't started yet. This
- // isn't likely to happen since we already avoid sending
- // a duplicate query for the same month as the previous query.
- // But if the user quickly wiggles the trackball back and forth,
- // he could generate a stream of queries.
- mQueryHandler.cancelOperation(0);
-
- mLastQueryTime.month = mTime.month;
- mLastQueryTime.year = mTime.year;
- mQueryHandler.startQuery(0, null, uri, PROJECTION, selection, null,
- AGENDA_SORT_ORDER);
- }
-
- private void selectTime() {
- // Selects the first event of the day
- AgendaListView current = (AgendaListView) mViewSwitcher.getCurrentView();
- if (current.getCursor() == null) {
- return;
- }
-
- int position = current.getDayAdapter().findDayPositionNearestTime(mTime);
- current.setSelection(position);
- }
-
- /* ViewSwitcher.ViewFactory interface methods */
- public View makeView() {
- AgendaListView agendaListView = new AgendaListView(this);
- return agendaListView;
- }
-
- /* Navigator interface methods */
- public void goToToday() {
- Time now = new Time();
- now.set(System.currentTimeMillis());
- goTo(now);
- }
-
- public void goTo(Time time) {
- if (mTime.year == time.year && mTime.month == time.month) {
- mTime = time;
- selectTime();
- } else {
- mTime = time;
- }
- }
-
- public long getSelectedTime() {
- // Update the current time based on the selected event
- AgendaListView current = (AgendaListView) mViewSwitcher.getCurrentView();
- int position = current.getSelectedItemPosition();
- position = current.getDayAdapter().getCursorPosition(position);
- Cursor cursor = current.getCursor();
- if (position >= 0 && position < cursor.getCount()) {
- cursor.moveToPosition(position);
- mTime.set(cursor.getLong(INDEX_BEGIN));
- }
-
- return mTime.toMillis(true);
- }
-
- public boolean getAllDay() {
- return false;
- }
-}
-
+++ /dev/null
-/*
- * Copyright (C) 2007 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.Resources;
-import android.database.Cursor;
-import android.provider.Calendar.Attendees;
-import android.provider.Calendar.Reminders;
-import android.text.format.DateFormat;
-import android.text.format.DateUtils;
-import android.view.View;
-import android.widget.FrameLayout;
-import android.widget.ResourceCursorAdapter;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-
-public class AgendaAdapter extends ResourceCursorAdapter {
-
- static final String[] REMINDERS_PROJECTION = new String[] {
- Reminders._ID, // 0
- Reminders.MINUTES, // 1
- };
- static final int REMINDERS_INDEX_MINUTES = 1;
- static final String REMINDERS_WHERE = Reminders.EVENT_ID + "=%d AND (" +
- Reminders.METHOD + "=" + Reminders.METHOD_ALERT + " OR " + Reminders.METHOD + "=" +
- Reminders.METHOD_DEFAULT + ")";
-
- private Resources mResources;
- private static ArrayList<Integer> sReminderValues;
- private static String[] sReminderLabels;
-
- public AgendaAdapter(Context context, int resource) {
- super(context, resource, null);
- mResources = context.getResources();
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- // Fade text if event was declined.
- int selfAttendeeStatus = cursor.getInt(AgendaActivity.INDEX_SELF_ATTENDEE_STATUS);
- boolean declined = (selfAttendeeStatus == Attendees.ATTENDEE_STATUS_DECLINED);
-
- View stripe = view.findViewById(R.id.vertical_stripe);
- int color = cursor.getInt(AgendaActivity.INDEX_COLOR);
- ((FrameLayout) view).setForeground(declined ?
- mResources.getDrawable(R.drawable.agenda_item_declined) : null);
-
- stripe.setBackgroundColor(color);
-
- // What
- TextView title = (TextView) view.findViewById(R.id.title);
- String titleString = cursor.getString(AgendaActivity.INDEX_TITLE);
- if (titleString == null || titleString.length() == 0) {
- titleString = mResources.getString(R.string.no_title_label);
- }
- title.setText(titleString);
- title.setTextColor(color);
-
- // When
- TextView when = (TextView) view.findViewById(R.id.when);
- long begin = cursor.getLong(AgendaActivity.INDEX_BEGIN);
- long end = cursor.getLong(AgendaActivity.INDEX_END);
- boolean allDay = cursor.getInt(AgendaActivity.INDEX_ALL_DAY) != 0;
- int flags;
- String whenString;
- if (allDay) {
- flags = DateUtils.FORMAT_UTC;
- } else {
- flags = DateUtils.FORMAT_SHOW_TIME;
- }
- if (DateFormat.is24HourFormat(context)) {
- flags |= DateUtils.FORMAT_24HOUR;
- }
- whenString = DateUtils.formatDateRange(context, begin, end, flags);
- when.setText(whenString);
-
- String rrule = cursor.getString(AgendaActivity.INDEX_RRULE);
- if (rrule != null) {
- when.setCompoundDrawablesWithIntrinsicBounds(null, null,
- context.getResources().getDrawable(R.drawable.ic_repeat_dark), null);
- when.setCompoundDrawablePadding(5);
- } else {
- when.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
- }
-
- /*
- // Repeating info
- View repeatContainer = view.findViewById(R.id.repeat_icon);
- String rrule = cursor.getString(AgendaActivity.INDEX_RRULE);
- if (rrule != null) {
- repeatContainer.setVisibility(View.VISIBLE);
- } else {
- repeatContainer.setVisibility(View.GONE);
- }
- */
-
- /*
- // Reminder
- boolean hasAlarm = cursor.getInt(AgendaActivity.INDEX_HAS_ALARM) != 0;
- if (hasAlarm) {
- updateReminder(view, context, begin, cursor.getLong(AgendaActivity.INDEX_EVENT_ID));
- }
- */
-
- // Where
- TextView where = (TextView) view.findViewById(R.id.where);
- String whereString = cursor.getString(AgendaActivity.INDEX_EVENT_LOCATION);
- if (whereString != null && whereString.length() > 0) {
- where.setVisibility(View.VISIBLE);
- where.setText(whereString);
- } else {
- where.setVisibility(View.GONE);
- }
- }
-
- /*
- public static void updateReminder(View view, Context context, long begin, long eventId) {
- ContentResolver cr = context.getContentResolver();
- Uri uri = Reminders.CONTENT_URI;
- String where = String.format(REMINDERS_WHERE, eventId);
-
- Cursor remindersCursor = cr.query(uri, REMINDERS_PROJECTION, where, null, null);
- if (remindersCursor != null) {
- LayoutInflater inflater =
- (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- LinearLayout parent = (LinearLayout) view.findViewById(R.id.reminders_container);
- parent.removeAllViews();
- while (remindersCursor.moveToNext()) {
- int alarm = remindersCursor.getInt(REMINDERS_INDEX_MINUTES);
- String before = EditEvent.constructReminderLabel(context, alarm, true);
- LinearLayout reminderItem = (LinearLayout)
- inflater.inflate(R.layout.agenda_reminder_item, null);
- TextView reminderItemText = (TextView) reminderItem.findViewById(R.id.reminder);
- reminderItemText.setText(before);
- parent.addView(reminderItem);
- }
- }
- remindersCursor.close();
- }
- */
-}
-
+++ /dev/null
-/*
- * Copyright (C) 2008 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.database.Cursor;
-import android.text.format.DateUtils;
-import android.text.format.Time;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Iterator;
-import java.util.LinkedList;
-
-public class AgendaByDayAdapter extends BaseAdapter {
- private static final int TYPE_DAY = 0;
- private static final int TYPE_MEETING = 1;
- private static final int TYPE_LAST = 2;
-
- private final Context mContext;
- private final AgendaAdapter mAgendaAdapter;
- private final LayoutInflater mInflater;
- private ArrayList<RowInfo> mRowInfo;
- private int mTodayJulianDay;
- private Time mTime = new Time();
-
- public AgendaByDayAdapter(Context context, AgendaAdapter agendaAdapter) {
- mContext = context;
- mAgendaAdapter = agendaAdapter;
- mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- }
-
- public int getCount() {
- if (mRowInfo != null) {
- return mRowInfo.size();
- }
- return mAgendaAdapter.getCount();
- }
-
- public Object getItem(int position) {
- if (mRowInfo != null) {
- RowInfo row = mRowInfo.get(position);
- if (row.mType == TYPE_DAY) {
- return row;
- } else {
- return mAgendaAdapter.getItem(row.mData);
- }
- }
- return mAgendaAdapter.getItem(position);
- }
-
- public long getItemId(int position) {
- if (mRowInfo != null) {
- RowInfo row = mRowInfo.get(position);
- if (row.mType == TYPE_DAY) {
- return position;
- } else {
- return mAgendaAdapter.getItemId(row.mData);
- }
- }
- return mAgendaAdapter.getItemId(position);
- }
-
- @Override
- public int getViewTypeCount() {
- return TYPE_LAST;
- }
-
- @Override
- public int getItemViewType(int position) {
- return mRowInfo != null && mRowInfo.size() > position ?
- mRowInfo.get(position).mType : TYPE_DAY;
- }
-
- private static class ViewHolder {
- TextView dateView;
- TextView dayOfWeekView;
- }
-
- 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.
- return mAgendaAdapter.getView(position, convertView, parent);
- }
-
- RowInfo row = mRowInfo.get(position);
- if (row.mType == TYPE_DAY) {
- ViewHolder holder;
- View agendaDayView;
- if ((convertView == null) || (convertView.getTag() == null)) {
- // Create a new AgendaView with a ViewHolder for fast access to
- // views w/o calling findViewById()
- holder = new ViewHolder();
- agendaDayView = mInflater.inflate(R.layout.agenda_day, parent, false);
- holder.dateView = (TextView) agendaDayView.findViewById(R.id.date);
- holder.dayOfWeekView = (TextView) agendaDayView.findViewById(R.id.day_of_week);
- agendaDayView.setTag(holder);
- } else {
- agendaDayView = convertView;
- holder = (ViewHolder) convertView.getTag();
- }
-
- // Re-use the member variable "mTime" which is set to the local timezone.
- Time date = mTime;
- long millis = date.setJulianDay(row.mData);
- int flags = DateUtils.FORMAT_NUMERIC_DATE;
- holder.dateView.setText(DateUtils.formatDateRange(mContext, millis, millis, flags));
-
- if (row.mData == mTodayJulianDay) {
- holder.dayOfWeekView.setText(R.string.agenda_today);
- } else {
- int weekDay = date.weekDay + Calendar.SUNDAY;
- holder.dayOfWeekView.setText(DateUtils.getDayOfWeekString(weekDay,
- DateUtils.LENGTH_LONG));
- }
- return agendaDayView;
- } else if (row.mType == TYPE_MEETING) {
- return mAgendaAdapter.getView(row.mData, convertView, parent);
- } else {
- // Error
- throw new IllegalStateException("Unknown event type:" + row.mType);
- }
- }
-
- public void clearDayHeaderInfo() {
- mRowInfo = null;
- }
-
- public void calculateDays(Cursor cursor) {
- ArrayList<RowInfo> rowInfo = new ArrayList<RowInfo>();
- int prevStartDay = -1;
- Time time = new Time();
- long now = System.currentTimeMillis();
- time.set(now);
- mTodayJulianDay = Time.getJulianDay(now, time.gmtoff);
- LinkedList<MultipleDayInfo> multipleDayList = new LinkedList<MultipleDayInfo>();
- for (int position = 0; cursor.moveToNext(); position++) {
- boolean allDay = cursor.getInt(AgendaActivity.INDEX_ALL_DAY) != 0;
- int startDay = cursor.getInt(AgendaActivity.INDEX_START_DAY);
-
- if (startDay != prevStartDay) {
- // Check if we skipped over any empty days
- if (prevStartDay == -1) {
- rowInfo.add(new RowInfo(TYPE_DAY, startDay));
- } else {
- // If there are any multiple-day events that span the empty
- // range of days, then create day headers and events for
- // those multiple-day events.
- boolean dayHeaderAdded = false;
- for (int currentDay = prevStartDay + 1; currentDay <= startDay; currentDay++) {
- dayHeaderAdded = false;
- Iterator<MultipleDayInfo> iter = multipleDayList.iterator();
- while (iter.hasNext()) {
- MultipleDayInfo info = iter.next();
- // If this event has ended then remove it from the
- // list.
- if (info.mEndDay < currentDay) {
- iter.remove();
- continue;
- }
-
- // If this is the first event for the day, then
- // insert a day header.
- if (!dayHeaderAdded) {
- rowInfo.add(new RowInfo(TYPE_DAY, currentDay));
- dayHeaderAdded = true;
- }
- rowInfo.add(new RowInfo(TYPE_MEETING, info.mPosition));
- }
- }
-
- // If the day header was not added for the start day, then
- // add it now.
- if (!dayHeaderAdded) {
- rowInfo.add(new RowInfo(TYPE_DAY, startDay));
- }
- }
- prevStartDay = startDay;
- }
-
- // Add in the event for this cursor position
- rowInfo.add(new RowInfo(TYPE_MEETING, position));
-
- // If this event spans multiple days, then add it to the multipleDay
- // list.
- int endDay = cursor.getInt(AgendaActivity.INDEX_END_DAY);
- if (endDay > startDay) {
- multipleDayList.add(new MultipleDayInfo(position, endDay));
- }
- }
-
- // There are no more cursor events but we might still have multiple-day
- // events left. So create day headers and events for those.
- if (prevStartDay > 0) {
- // Get the Julian day for the last day of this month. To do that,
- // we set the date to one less than the first day of the next month,
- // and then normalize.
- time.setJulianDay(prevStartDay);
- time.month += 1;
- time.monthDay = 0; // monthDay starts with 1, so this is the previous day
- long millis = time.normalize(true /* ignore isDst */);
- int lastDayOfMonth = Time.getJulianDay(millis, time.gmtoff);
-
- for (int currentDay = prevStartDay + 1; currentDay <= lastDayOfMonth; currentDay++) {
- boolean dayHeaderAdded = false;
- Iterator<MultipleDayInfo> iter = multipleDayList.iterator();
- while (iter.hasNext()) {
- MultipleDayInfo info = iter.next();
- // If this event has ended then remove it from the
- // list.
- if (info.mEndDay < currentDay) {
- iter.remove();
- continue;
- }
-
- // If this is the first event for the day, then
- // insert a day header.
- if (!dayHeaderAdded) {
- rowInfo.add(new RowInfo(TYPE_DAY, currentDay));
- dayHeaderAdded = true;
- }
- rowInfo.add(new RowInfo(TYPE_MEETING, info.mPosition));
- }
- }
- }
- mRowInfo = rowInfo;
- }
-
- private static class RowInfo {
- // mType is either a day header (TYPE_DAY) or an event (TYPE_MEETING)
- final int mType;
-
- // If mType is TYPE_DAY, then mData is the Julian day. Otherwise
- // mType is TYPE_MEETING and mData is the cursor position.
- final int mData;
-
- RowInfo(int type, int data) {
- mType = type;
- mData = data;
- }
- }
-
- private static class MultipleDayInfo {
- final int mPosition;
- final int mEndDay;
-
- MultipleDayInfo(int position, int endDay) {
- mPosition = position;
- mEndDay = endDay;
- }
- }
-
- /**
- * Searches for the day that matches the given Time object and returns the
- * list position of that day. If there are no events for that day, then it
- * finds the nearest day (before or after) that has events and returns the
- * list position for that day.
- *
- * @param time the date to search for
- * @return the cursor position of the first event for that date, or zero
- * if no match was found
- */
- public int findDayPositionNearestTime(Time time) {
- if (mRowInfo == null) {
- return 0;
- }
- long millis = time.toMillis(false /* use isDst */);
- int julianDay = Time.getJulianDay(millis, time.gmtoff);
- int minDistance = 1000; // some big number
- int minIndex = 0;
- int len = mRowInfo.size();
- for (int index = 0; index < len; index++) {
- RowInfo row = mRowInfo.get(index);
- if (row.mType == TYPE_DAY) {
- int distance = Math.abs(julianDay - row.mData);
- if (distance == 0) {
- return index;
- }
- if (distance < minDistance) {
- minDistance = distance;
- minIndex = index;
- }
- }
- }
-
- // We didn't find an exact match so take the nearest day that had
- // events.
- return minIndex;
- }
-
- /**
- * Finds the Julian day containing the event at the given position.
- *
- * @param position the list position of an event
- * @return the Julian day containing that event
- */
- public int findJulianDayFromPosition(int position) {
- if (mRowInfo == null || position < 0) {
- return 0;
- }
-
- int len = mRowInfo.size();
- if (position >= len) return 0; // no row info at this position
-
- for (int index = position; index >= 0; index--) {
- RowInfo row = mRowInfo.get(index);
- if (row.mType == TYPE_DAY) {
- return row.mData;
- }
- }
- return 0;
- }
-
- /**
- * Converts a list position to a cursor position. The list contains
- * day headers as well as events. The cursor contains only events.
- *
- * @param listPos the list position of an event
- * @return the corresponding cursor position of that event
- */
- public int getCursorPosition(int listPos) {
- if (mRowInfo != null && listPos >= 0) {
- RowInfo row = mRowInfo.get(listPos);
- if (row.mType == TYPE_MEETING) {
- return row.mData;
- }
- }
- return listPos;
- }
-
- @Override
- public boolean areAllItemsEnabled() {
- return false;
- }
-
- @Override
- public boolean isEnabled(int position) {
- if (mRowInfo != null && position < mRowInfo.size()) {
- RowInfo row = mRowInfo.get(position);
- return row.mType == TYPE_MEETING;
- }
- return true;
- }
-}
-
+++ /dev/null
-/*
- * Copyright (C) 2007 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 static android.provider.Calendar.EVENT_BEGIN_TIME;
-import static android.provider.Calendar.EVENT_END_TIME;
-
-import android.app.Activity;
-import android.app.AlarmManager;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.AsyncQueryHandler;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.TypedArray;
-import android.database.Cursor;
-import android.graphics.PixelFormat;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.Calendar;
-import android.provider.Calendar.CalendarAlerts;
-import android.provider.Calendar.Events;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.View.OnClickListener;
-import android.widget.AdapterView;
-import android.widget.Button;
-import android.widget.ListView;
-import android.widget.AdapterView.OnItemClickListener;
-
-/**
- * The alert panel that pops up when there is a calendar event alarm.
- * This activity is started by an intent that specifies an event id.
- */
-public class AlertActivity extends Activity {
-
- // The default snooze delay: 5 minutes
- public static final long SNOOZE_DELAY = 5 * 60 * 1000L;
-
- private static final String[] PROJECTION = new String[] {
- CalendarAlerts._ID, // 0
- CalendarAlerts.TITLE, // 1
- CalendarAlerts.EVENT_LOCATION, // 2
- CalendarAlerts.ALL_DAY, // 3
- CalendarAlerts.BEGIN, // 4
- CalendarAlerts.END, // 5
- CalendarAlerts.EVENT_ID, // 6
- CalendarAlerts.COLOR, // 7
- CalendarAlerts.RRULE, // 8
- CalendarAlerts.HAS_ALARM, // 9
- CalendarAlerts.STATE, // 10
- CalendarAlerts.ALARM_TIME, // 11
- };
-
- public static final int INDEX_TITLE = 1;
- public static final int INDEX_EVENT_LOCATION = 2;
- public static final int INDEX_ALL_DAY = 3;
- public static final int INDEX_BEGIN = 4;
- public static final int INDEX_END = 5;
- public static final int INDEX_EVENT_ID = 6;
- public static final int INDEX_COLOR = 7;
- public static final int INDEX_RRULE = 8;
- public static final int INDEX_HAS_ALARM = 9;
- public static final int INDEX_STATE = 10;
- public static final int INDEX_ALARM_TIME = 11;
-
- // We use one notification id for all events so that we don't clutter
- // the notification screen. It doesn't matter what the id is, as long
- // as it is used consistently everywhere.
- public static final int NOTIFICATION_ID = 0;
-
- private ContentResolver mResolver;
- private AlertAdapter mAdapter;
- private QueryHandler mQueryHandler;
- private Cursor mCursor;
- private ListView mListView;
- private Button mSnoozeAllButton;
- private Button mDismissAllButton;
-
- private class QueryHandler extends AsyncQueryHandler {
- public QueryHandler(ContentResolver cr) {
- super(cr);
- }
-
- @Override
- protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
- // Only set mCursor if the Activity is not finishing. Otherwise close the cursor.
- if (!isFinishing()) {
- mCursor = cursor;
- mAdapter.changeCursor(cursor);
-
- // The results are in, enable the buttons
- mSnoozeAllButton.setEnabled(true);
- mDismissAllButton.setEnabled(true);
- } else {
- cursor.close();
- }
- }
-
- }
-
- private OnItemClickListener mViewListener = new OnItemClickListener() {
-
- public void onItemClick(AdapterView parent, View view, int position,
- long i) {
- AlertActivity alertActivity = AlertActivity.this;
- Cursor cursor = alertActivity.getItemForView(view);
-
- long id = cursor.getInt(AlertActivity.INDEX_EVENT_ID);
- long startMillis = cursor.getLong(AlertActivity.INDEX_BEGIN);
- long endMillis = cursor.getLong(AlertActivity.INDEX_END);
-
- Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, id);
- Intent intent = new Intent(Intent.ACTION_VIEW, uri);
- intent.setClass(alertActivity, EventInfoActivity.class);
- intent.putExtra(EVENT_BEGIN_TIME, startMillis);
- intent.putExtra(EVENT_END_TIME, endMillis);
-
- // Mark this alarm as DISMISSED
- cursor.updateInt(INDEX_STATE, CalendarAlerts.DISMISSED);
- cursor.commitUpdates();
-
- startActivity(intent);
- alertActivity.finish();
- }
- };
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.alert_activity);
-
- WindowManager.LayoutParams lp = getWindow().getAttributes();
- lp.width = ViewGroup.LayoutParams.FILL_PARENT;
- lp.height = ViewGroup.LayoutParams.FILL_PARENT;
-
- // Get the dim amount from the theme
- TypedArray a = obtainStyledAttributes(com.android.internal.R.styleable.Theme);
- lp.dimAmount = a.getFloat(android.R.styleable.Theme_backgroundDimAmount, 0.5f);
- a.recycle();
-
- getWindow().setAttributes(lp);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
-
- mResolver = getContentResolver();
- mQueryHandler = new QueryHandler(mResolver);
- mAdapter = new AlertAdapter(this, R.layout.alert_item);
-
- mListView = (ListView) findViewById(R.id.alert_container);
- mListView.setItemsCanFocus(true);
- mListView.setAdapter(mAdapter);
- mListView.setOnItemClickListener(mViewListener);
-
- mSnoozeAllButton = (Button) findViewById(R.id.snooze_all);
- mSnoozeAllButton.setOnClickListener(mSnoozeAllListener);
- mDismissAllButton = (Button) findViewById(R.id.dismiss_all);
- mDismissAllButton.setOnClickListener(mDismissAllListener);
-
- // Disable the buttons, since they need mCursor, which is created asynchronously
- mSnoozeAllButton.setEnabled(false);
- mDismissAllButton.setEnabled(false);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
-
- // If the cursor is null, start the async handler. If it is not null just requery.
- if (mCursor == null) {
- Uri uri = CalendarAlerts.CONTENT_URI_BY_INSTANCE;
- String selection = CalendarAlerts.STATE + "=" + CalendarAlerts.FIRED;
- mQueryHandler.startQuery(0, null, uri, PROJECTION, selection,
- null /* selection args */, CalendarAlerts.DEFAULT_SORT_ORDER);
- } else {
- mCursor.requery();
- }
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- AlertReceiver.updateAlertNotification(this);
-
- if (mCursor != null) {
- mCursor.deactivate();
- }
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- if (mCursor != null) {
- mCursor.close();
- }
- }
-
- private OnClickListener mSnoozeAllListener = new OnClickListener() {
- public void onClick(View v) {
- NotificationManager nm =
- (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- nm.cancel(NOTIFICATION_ID);
- mCursor.moveToPosition(-1);
- while (mCursor.moveToNext()) {
- long eventId = mCursor.getLong(INDEX_EVENT_ID);
- long begin = mCursor.getLong(INDEX_BEGIN);
- long end = mCursor.getLong(INDEX_END);
- long alarmTime = mCursor.getLong(INDEX_ALARM_TIME);
-
- // Mark this alarm as DISMISSED
- mCursor.updateInt(INDEX_STATE, CalendarAlerts.DISMISSED);
-
- // Create a new alarm entry in the CalendarAlerts table
- long now = System.currentTimeMillis();
- alarmTime = now + SNOOZE_DELAY;
-
- // Set the "minutes" to zero to indicate this is a snoozed
- // alarm. There is code in AlertService.java that checks
- // this field.
- Uri uri = CalendarAlerts.insert(mResolver, eventId,
- begin, end, alarmTime, 0 /* minutes */);
-
- // Set a new alarm to go off after the snooze delay.
- Intent intent = new Intent(Calendar.EVENT_REMINDER_ACTION);
- intent.setData(uri);
- intent.putExtra(Calendar.EVENT_BEGIN_TIME, begin);
- intent.putExtra(Calendar.EVENT_END_TIME, end);
-
- PendingIntent sender = PendingIntent.getBroadcast(AlertActivity.this,
- 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
- Object service = getSystemService(Context.ALARM_SERVICE);
- AlarmManager alarmManager = (AlarmManager) service;
- alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, sender);
- }
- mCursor.commitUpdates();
- finish();
- }
- };
-
- private OnClickListener mDismissAllListener = new OnClickListener() {
- public void onClick(View v) {
- NotificationManager nm =
- (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- nm.cancel(NOTIFICATION_ID);
- mCursor.moveToPosition(-1);
- while (mCursor.moveToNext()) {
- mCursor.updateInt(INDEX_STATE, CalendarAlerts.DISMISSED);
- }
- mCursor.commitUpdates();
- finish();
- }
- };
-
- public boolean isEmpty() {
- return (mCursor.getCount() == 0);
- }
-
- public Cursor getItemForView(View view) {
- int index = mListView.getPositionForView(view);
- if (index < 0) {
- return null;
- }
- return (Cursor) mListView.getAdapter().getItem(index);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2008 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.Resources;
-import android.database.Cursor;
-import android.graphics.PorterDuff;
-import android.text.format.DateFormat;
-import android.text.format.DateUtils;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.ResourceCursorAdapter;
-import android.widget.TextView;
-
-public class AlertAdapter extends ResourceCursorAdapter {
-
- public AlertAdapter(Context context, int resource) {
- super(context, resource, null);
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- TextView textView;
-
- ImageView stripe = (ImageView) view.findViewById(R.id.vertical_stripe);
- int color = cursor.getInt(AlertActivity.INDEX_COLOR) & 0xbbffffff;
- stripe.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_IN);
-
- // Repeating info
- View repeatContainer = view.findViewById(R.id.repeat_icon);
- String rrule = cursor.getString(AlertActivity.INDEX_RRULE);
- if (rrule != null) {
- repeatContainer.setVisibility(View.VISIBLE);
- } else {
- repeatContainer.setVisibility(View.GONE);
- }
-
- /*
- // Reminder
- boolean hasAlarm = cursor.getInt(AlertActivity.INDEX_HAS_ALARM) != 0;
- if (hasAlarm) {
- AgendaAdapter.updateReminder(view, context, cursor.getLong(AlertActivity.INDEX_BEGIN),
- cursor.getLong(AlertActivity.INDEX_EVENT_ID));
- }
- */
-
- String eventName = cursor.getString(AlertActivity.INDEX_TITLE);
- String location = cursor.getString(AlertActivity.INDEX_EVENT_LOCATION);
- long startMillis = cursor.getLong(AlertActivity.INDEX_BEGIN);
- long endMillis = cursor.getLong(AlertActivity.INDEX_END);
- boolean allDay = cursor.getInt(AlertActivity.INDEX_ALL_DAY) != 0;
-
- updateView(context, view, eventName, location, startMillis, endMillis, allDay);
- }
-
- public static void updateView(Context context, View view, String eventName, String location,
- long startMillis, long endMillis, boolean allDay) {
-
- Resources res = context.getResources();
- TextView textView;
-
- // What
- if (eventName == null || eventName.length() == 0) {
- eventName = res.getString(R.string.no_title_label);
- }
- textView = (TextView) view.findViewById(R.id.event_title);
- textView.setText(eventName);
-
- // When
- String when;
- int flags;
- if (allDay) {
- flags = DateUtils.FORMAT_UTC | DateUtils.FORMAT_SHOW_WEEKDAY |
- DateUtils.FORMAT_SHOW_DATE;
- } else {
- flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE;
- }
- if (DateFormat.is24HourFormat(context)) {
- flags |= DateUtils.FORMAT_24HOUR;
- }
- when = DateUtils.formatDateRange(context, startMillis, endMillis, flags);
- textView = (TextView) view.findViewById(R.id.when);
- textView.setText(when);
-
- // Where
- textView = (TextView) view.findViewById(R.id.where);
- if (location == null || location.length() == 0) {
- textView.setVisibility(View.GONE);
- } else {
- textView.setText(location);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007 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.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.PowerManager;
-import android.preference.PreferenceManager;
-import android.provider.Calendar.CalendarAlerts;
-
-/**
- * Receives android.intent.action.EVENT_REMINDER intents and handles
- * event reminders. The intent URI specifies an alert id in the
- * CalendarAlerts database table. This class also receives the
- * BOOT_COMPLETED intent so that it can add a status bar notification
- * if there are Calendar event alarms that have not been dismissed.
- * It also receives the TIME_CHANGED action so that it can fire off
- * snoozed alarms that have become ready. The real work is done in
- * the AlertService class.
- */
-public class AlertReceiver extends BroadcastReceiver {
- private static final String[] ALERT_PROJECTION = new String[] {
- CalendarAlerts.TITLE, // 0
- CalendarAlerts.EVENT_LOCATION, // 1
- };
- private static final int ALERT_INDEX_TITLE = 0;
- private static final int ALERT_INDEX_EVENT_LOCATION = 1;
-
- private static final String DELETE_ACTION = "delete";
-
- private static final String[] PROJECTION = new String[] {
- CalendarAlerts._ID, // 0
- CalendarAlerts.STATE, // 1
- };
-
- public static final int INDEX_STATE = 1;
-
- static final Object mStartingServiceSync = new Object();
- static PowerManager.WakeLock mStartingService;
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (DELETE_ACTION.equals(intent.getAction())) {
-
- /* The user has clicked the "Clear All Notifications"
- * buttons so dismiss all Calendar alerts.
- */
- dismissAllEvents(context);
- } else {
- Intent i = new Intent();
- i.setClass(context, AlertService.class);
- i.putExtras(intent);
- i.putExtra("action", intent.getAction());
- Uri uri = intent.getData();
-
- // This intent might be a BOOT_COMPLETED so it might not have a Uri.
- if (uri != null) {
- i.putExtra("uri", uri.toString());
-
- // Record the received time in the CalendarAlerts table.
- // This is useful for finding bugs that cause alarms to be
- // missed or delayed.
- ContentResolver cr = context.getContentResolver();
- ContentValues values = new ContentValues();
- long currentTime = System.currentTimeMillis();
- values.put(CalendarAlerts.RECEIVED_TIME, currentTime);
- cr.update(uri, values, null /* where */, null /* args */);
- }
- beginStartingService(context, i);
- }
- }
-
- private void dismissAllEvents(Context context) {
- Uri uri = CalendarAlerts.CONTENT_URI_BY_INSTANCE;
- String selection = CalendarAlerts.STATE + "=" + CalendarAlerts.FIRED;
- ContentResolver resolver = context.getContentResolver();
- Cursor cursor = resolver.query(uri, PROJECTION, selection, null, null);
- if (cursor != null) {
- cursor.moveToPosition(-1);
- while (cursor.moveToNext()) {
- cursor.updateInt(INDEX_STATE, CalendarAlerts.DISMISSED);
- }
- cursor.commitUpdates();
- cursor.close();
- }
- }
-
- /**
- * Start the service to process the current event notifications, acquiring
- * the wake lock before returning to ensure that the service will run.
- */
- public static void beginStartingService(Context context, Intent intent) {
- synchronized (mStartingServiceSync) {
- if (mStartingService == null) {
- PowerManager pm =
- (PowerManager)context.getSystemService(Context.POWER_SERVICE);
- mStartingService = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
- "StartingAlertService");
- mStartingService.setReferenceCounted(false);
- }
- mStartingService.acquire();
- context.startService(intent);
- }
- }
-
- /**
- * Called back by the service when it has finished processing notifications,
- * releasing the wake lock if the service is now stopping.
- */
- public static void finishStartingService(Service service, int startId) {
- synchronized (mStartingServiceSync) {
- if (mStartingService != null) {
- if (service.stopSelfResult(startId)) {
- mStartingService.release();
- }
- }
- }
- }
-
- public static void updateAlertNotification(Context context) {
- // This can be called regularly to synchronize the alert notification
- // with the contents of the CalendarAlerts table.
-
- ContentResolver cr = context.getContentResolver();
-
- if (cr == null) {
- return;
- }
-
- String selection = CalendarAlerts.STATE + "=" + CalendarAlerts.FIRED;
- Cursor alertCursor = CalendarAlerts.query(cr, ALERT_PROJECTION, selection, null);
-
- NotificationManager nm =
- (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
-
- if (alertCursor == null) {
- nm.cancel(AlertActivity.NOTIFICATION_ID);
- return;
- }
-
- if (!alertCursor.moveToFirst()) {
- alertCursor.close();
- nm.cancel(AlertActivity.NOTIFICATION_ID);
- return;
- }
-
- // Check the settings to see if alerts are disabled
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
- String reminderType = prefs.getString(CalendarPreferenceActivity.KEY_ALERTS_TYPE,
- CalendarPreferenceActivity.ALERT_TYPE_STATUS_BAR);
- if (reminderType.equals(CalendarPreferenceActivity.ALERT_TYPE_OFF)) {
- return;
- }
-
- String title = alertCursor.getString(ALERT_INDEX_TITLE);
- String location = alertCursor.getString(ALERT_INDEX_EVENT_LOCATION);
-
- Notification notification = AlertReceiver.makeNewAlertNotification(context, title,
- location, alertCursor.getCount());
- alertCursor.close();
-
- nm.notify(0, notification);
- }
-
- public static Notification makeNewAlertNotification(Context context, String title,
- String location, int numReminders) {
- Resources res = context.getResources();
-
- // Create an intent triggered by clicking on the status icon.
- Intent clickIntent = new Intent();
- clickIntent.setClass(context, AlertActivity.class);
- clickIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
- // Create an intent triggered by clicking on the "Clear All Notifications" button
- Intent deleteIntent = new Intent();
- deleteIntent.setClass(context, AlertReceiver.class);
- deleteIntent.setAction(DELETE_ACTION);
-
- if (title == null || title.length() == 0) {
- title = res.getString(R.string.no_title_label);
- }
-
- String helperString;
- if (numReminders > 1) {
- String format;
- if (numReminders == 2) {
- format = res.getString(R.string.alert_missed_events_single);
- } else {
- format = res.getString(R.string.alert_missed_events_multiple);
- }
- helperString = String.format(format, numReminders - 1);
- } else {
- helperString = location;
- }
-
- Notification notification = new Notification(
- R.drawable.stat_notify_calendar,
- null,
- System.currentTimeMillis());
- notification.setLatestEventInfo(context,
- title,
- helperString,
- PendingIntent.getActivity(context, 0, clickIntent, 0));
- notification.deleteIntent = PendingIntent.getBroadcast(context, 0, deleteIntent, 0);
-
- return notification;
- }
-}
-
+++ /dev/null
-/*
- * Copyright (C) 2008 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.app.AlarmManager;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.Service;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Process;
-import android.preference.PreferenceManager;
-import android.provider.Calendar;
-import android.provider.Calendar.Attendees;
-import android.provider.Calendar.CalendarAlerts;
-import android.provider.Calendar.Instances;
-import android.provider.Calendar.Reminders;
-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;
-
-/**
- * This service is used to handle calendar event reminders.
- */
-public class AlertService extends Service {
- private static final String TAG = "AlertService";
-
- private volatile Looper mServiceLooper;
- private volatile ServiceHandler mServiceHandler;
-
- private static final String[] ALERT_PROJECTION = new String[] {
- CalendarAlerts._ID, // 0
- CalendarAlerts.EVENT_ID, // 1
- CalendarAlerts.STATE, // 2
- CalendarAlerts.TITLE, // 3
- CalendarAlerts.EVENT_LOCATION, // 4
- CalendarAlerts.SELF_ATTENDEE_STATUS, // 5
- CalendarAlerts.ALL_DAY, // 6
- CalendarAlerts.ALARM_TIME, // 7
- CalendarAlerts.MINUTES, // 8
- CalendarAlerts.BEGIN, // 9
- };
-
- // We just need a simple projection that returns any column
- private static final String[] ALERT_PROJECTION_SMALL = new String[] {
- CalendarAlerts._ID, // 0
- };
-
- private static final int ALERT_INDEX_ID = 0;
- private static final int ALERT_INDEX_EVENT_ID = 1;
- private static final int ALERT_INDEX_STATE = 2;
- private static final int ALERT_INDEX_TITLE = 3;
- private static final int ALERT_INDEX_EVENT_LOCATION = 4;
- private static final int ALERT_INDEX_SELF_ATTENDEE_STATUS = 5;
- private static final int ALERT_INDEX_ALL_DAY = 6;
- private static final int ALERT_INDEX_ALARM_TIME = 7;
- private static final int ALERT_INDEX_MINUTES = 8;
- private static final int ALERT_INDEX_BEGIN = 9;
-
- private String[] INSTANCE_PROJECTION = { Instances.BEGIN, Instances.END };
- private static final int INSTANCES_INDEX_BEGIN = 0;
- private static final int INSTANCES_INDEX_END = 1;
-
- // We just need a simple projection that returns any column
- private static final String[] REMINDER_PROJECTION_SMALL = new String[] {
- Reminders._ID, // 0
- };
-
- private void processMessage(Message msg) {
- Bundle bundle = (Bundle) msg.obj;
-
- // On reboot, update the notification bar with the contents of the
- // CalendarAlerts table.
- String action = bundle.getString("action");
- if (action.equals(Intent.ACTION_BOOT_COMPLETED)
- || action.equals(Intent.ACTION_TIME_CHANGED)) {
- doTimeChanged();
- return;
- }
-
- // The Uri specifies an entry in the CalendarAlerts table
- Uri alertUri = Uri.parse(bundle.getString("uri"));
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "uri: " + alertUri);
- }
-
- ContentResolver cr = getContentResolver();
- Cursor alertCursor = cr.query(alertUri, ALERT_PROJECTION,
- null /* selection */, null, null /* sort order */);
-
- long alertId, eventId, instanceId, alarmTime;
- int minutes;
- String eventName;
- String location;
- boolean allDay;
- boolean declined = false;
- try {
- if (alertCursor == null || !alertCursor.moveToFirst()) {
- // This can happen if the event was deleted.
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "alert not found");
- }
- return;
- }
- alertId = alertCursor.getLong(ALERT_INDEX_ID);
- eventId = alertCursor.getLong(ALERT_INDEX_EVENT_ID);
- minutes = alertCursor.getInt(ALERT_INDEX_MINUTES);
- eventName = alertCursor.getString(ALERT_INDEX_TITLE);
- location = alertCursor.getString(ALERT_INDEX_EVENT_LOCATION);
- allDay = alertCursor.getInt(ALERT_INDEX_ALL_DAY) != 0;
- alarmTime = alertCursor.getLong(ALERT_INDEX_ALARM_TIME);
- declined = alertCursor.getInt(ALERT_INDEX_SELF_ATTENDEE_STATUS) ==
- Attendees.ATTENDEE_STATUS_DECLINED;
-
- // If the event was declined, then mark the alarm DISMISSED,
- // otherwise, mark the alarm FIRED.
- int newState = CalendarAlerts.FIRED;
- if (declined) {
- newState = CalendarAlerts.DISMISSED;
- }
- alertCursor.updateInt(ALERT_INDEX_STATE, newState);
- alertCursor.commitUpdates();
- } finally {
- if (alertCursor != null) {
- alertCursor.close();
- }
- }
-
- // Do not show an alert if the event was declined
- if (declined) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "event declined, alert cancelled");
- }
- return;
- }
-
- long beginTime = bundle.getLong(Calendar.EVENT_BEGIN_TIME, 0);
- long endTime = bundle.getLong(Calendar.EVENT_END_TIME, 0);
-
- // Check if this alarm is still valid. The time of the event may
- // have been changed, or the reminder may have been changed since
- // this alarm was set. First, search for an instance in the Instances
- // that has the same event id and the same begin and end time.
- // Then check for a reminder in the Reminders table to ensure that
- // the reminder minutes is consistent with this alarm.
- String selection = Instances.EVENT_ID + "=" + eventId;
- Cursor instanceCursor = Instances.query(cr, INSTANCE_PROJECTION,
- beginTime, endTime, selection, Instances.DEFAULT_SORT_ORDER);
- long instanceBegin = 0, instanceEnd = 0;
- try {
- if (instanceCursor == null || !instanceCursor.moveToFirst()) {
- // Delete this alarm from the CalendarAlerts table
- cr.delete(alertUri, null /* selection */, null /* selection args */);
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "instance not found, alert cancelled");
- }
- return;
- }
- instanceBegin = instanceCursor.getLong(INSTANCES_INDEX_BEGIN);
- instanceEnd = instanceCursor.getLong(INSTANCES_INDEX_END);
- } finally {
- if (instanceCursor != null) {
- instanceCursor.close();
- }
- }
-
- // Check that a reminder for this event exists with the same number
- // of minutes. But snoozed alarms have minutes = 0, so don't do this
- // check for snoozed alarms.
- if (minutes > 0) {
- selection = Reminders.EVENT_ID + "=" + eventId
- + " AND " + Reminders.MINUTES + "=" + minutes;
- Cursor reminderCursor = cr.query(Reminders.CONTENT_URI, REMINDER_PROJECTION_SMALL,
- selection, null /* selection args */, null /* sort order */);
- try {
- if (reminderCursor == null || reminderCursor.getCount() == 0) {
- // Delete this alarm from the CalendarAlerts table
- cr.delete(alertUri, null /* selection */, null /* selection args */);
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "reminder not found, alert cancelled");
- }
- return;
- }
- } finally {
- if (reminderCursor != null) {
- reminderCursor.close();
- }
- }
- }
-
- // If the event time was changed and the event has already ended,
- // then don't sound the alarm.
- if (alarmTime > instanceEnd) {
- // Delete this alarm from the CalendarAlerts table
- cr.delete(alertUri, null /* selection */, null /* selection args */);
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "event ended, alert cancelled");
- }
- return;
- }
-
- // If minutes > 0, then this is a normal alarm (not a snoozed alarm)
- // so check for duplicate alarms. A duplicate alarm can occur when
- // the start time of an event is changed to an earlier time. The
- // later alarm (that was first scheduled for the later event time)
- // should be discarded.
- long computedAlarmTime = instanceBegin - minutes * DateUtils.MINUTE_IN_MILLIS;
- if (minutes > 0 && computedAlarmTime != alarmTime) {
- // If the event time was changed to a later time, then the computed
- // alarm time is in the future and we shouldn't sound this alarm.
- if (computedAlarmTime > alarmTime) {
- // Delete this alarm from the CalendarAlerts table
- cr.delete(alertUri, null /* selection */, null /* selection args */);
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "event postponed, alert cancelled");
- }
- return;
- }
-
- // Check for another alarm in the CalendarAlerts table that has the
- // same event id and the same "minutes". This can occur
- // if the event start time was changed to an earlier time and the
- // alarm for the later time goes off. To avoid discarding alarms
- // for repeating events (that have the same event id), we check
- // that the other alarm fired recently (within an hour of this one).
- long recently = alarmTime - 60 * DateUtils.MINUTE_IN_MILLIS;
- selection = CalendarAlerts.EVENT_ID + "=" + eventId
- + " AND " + CalendarAlerts.TABLE_NAME + "." + CalendarAlerts._ID
- + "!=" + alertId
- + " AND " + CalendarAlerts.MINUTES + "=" + minutes
- + " AND " + CalendarAlerts.ALARM_TIME + ">" + recently
- + " AND " + CalendarAlerts.ALARM_TIME + "<=" + alarmTime;
- alertCursor = CalendarAlerts.query(cr, ALERT_PROJECTION_SMALL, selection, null);
- if (alertCursor != null) {
- try {
- if (alertCursor.getCount() > 0) {
- // Delete this alarm from the CalendarAlerts table
- cr.delete(alertUri, null /* selection */, null /* selection args */);
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "duplicate alarm, alert cancelled");
- }
- return;
- }
- } finally {
- alertCursor.close();
- }
- }
- }
-
- // Find all the alerts that have fired but have not been dismissed
- selection = CalendarAlerts.STATE + "=" + CalendarAlerts.FIRED;
- alertCursor = CalendarAlerts.query(cr, ALERT_PROJECTION, selection, null);
-
- if (alertCursor == null || alertCursor.getCount() == 0) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "no fired alarms found");
- }
- return;
- }
-
- int numReminders = alertCursor.getCount();
- try {
- while (alertCursor.moveToNext()) {
- long otherEventId = alertCursor.getLong(ALERT_INDEX_EVENT_ID);
- long otherAlertId = alertCursor.getLong(ALERT_INDEX_ID);
- int otherAlarmState = alertCursor.getInt(ALERT_INDEX_STATE);
- long otherBeginTime = alertCursor.getLong(ALERT_INDEX_BEGIN);
- if (otherEventId == eventId && otherAlertId != alertId
- && otherAlarmState == CalendarAlerts.FIRED
- && otherBeginTime == beginTime) {
- // This event already has an alert that fired and has not
- // been dismissed. This can happen if an event has
- // multiple reminders. Do not count this as a separate
- // reminder. But we do want to sound the alarm and vibrate
- // the phone, if necessary.
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "multiple alarms for this event");
- }
- numReminders -= 1;
- }
- }
- } finally {
- alertCursor.close();
- }
-
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "creating new alarm notification, numReminders: " + numReminders);
- }
- Notification notification = AlertReceiver.makeNewAlertNotification(this, eventName,
- location, numReminders);
-
- // Generate either a pop-up dialog, status bar notification, or
- // neither. Pop-up dialog and status bar notification may include a
- // sound, an alert, or both. A status bar notification also includes
- // a toast.
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- String reminderType = prefs.getString(CalendarPreferenceActivity.KEY_ALERTS_TYPE,
- CalendarPreferenceActivity.ALERT_TYPE_STATUS_BAR);
-
- if (reminderType.equals(CalendarPreferenceActivity.ALERT_TYPE_OFF)) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "alert preference is OFF");
- }
- return;
- }
-
- NotificationManager nm =
- (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- boolean reminderVibrate =
- prefs.getBoolean(CalendarPreferenceActivity.KEY_ALERTS_VIBRATE, false);
- String reminderRingtone =
- prefs.getString(CalendarPreferenceActivity.KEY_ALERTS_RINGTONE, null);
-
- // Possibly generate a vibration
- if (reminderVibrate) {
- notification.defaults |= Notification.DEFAULT_VIBRATE;
- }
-
- // Possibly generate a sound. If 'Silent' is chosen, the ringtone string will be empty.
- notification.sound = TextUtils.isEmpty(reminderRingtone) ? null : Uri
- .parse(reminderRingtone);
-
- if (reminderType.equals(CalendarPreferenceActivity.ALERT_TYPE_ALERTS)) {
- Intent alertIntent = new Intent();
- alertIntent.setClass(this, AlertActivity.class);
- alertIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(alertIntent);
- } else {
- LayoutInflater inflater;
- inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View view = inflater.inflate(R.layout.alert_toast, null);
-
- AlertAdapter.updateView(this, view, eventName, location, beginTime, endTime, allDay);
- }
-
- // Record the notify time in the CalendarAlerts table.
- // This is used for debugging missed alarms.
- ContentValues values = new ContentValues();
- long currentTime = System.currentTimeMillis();
- values.put(CalendarAlerts.NOTIFY_TIME, currentTime);
- cr.update(alertUri, values, null /* where */, null /* args */);
-
- // The notification time should be pretty close to the reminder time
- // that the user set for this event. If the notification is late, then
- // that's a bug and we should log an error.
- if (currentTime > alarmTime + DateUtils.MINUTE_IN_MILLIS) {
- long minutesLate = (currentTime - alarmTime) / DateUtils.MINUTE_IN_MILLIS;
- int flags = DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_TIME;
- String alarmTimeStr = DateUtils.formatDateTime(this, alarmTime, flags);
- String currentTimeStr = DateUtils.formatDateTime(this, currentTime, flags);
- Log.w(TAG, "Calendar reminder alarm for event id " + eventId
- + " is " + minutesLate + " minute(s) late;"
- + " expected alarm at: " + alarmTimeStr
- + " but got it at: " + currentTimeStr);
- }
-
- nm.notify(0, notification);
- }
-
- private void doTimeChanged() {
- ContentResolver cr = getContentResolver();
- Object service = getSystemService(Context.ALARM_SERVICE);
- AlarmManager manager = (AlarmManager) service;
- CalendarAlerts.rescheduleMissedAlarms(cr, this, manager);
- AlertReceiver.updateAlertNotification(this);
- }
-
- private final class ServiceHandler extends Handler {
- public ServiceHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- processMessage(msg);
- // NOTE: We MUST not call stopSelf() directly, since we need to
- // make sure the wake lock acquired by AlertReceiver is released.
- AlertReceiver.finishStartingService(AlertService.this, msg.arg1);
- }
- };
-
- @Override
- public void onCreate() {
- HandlerThread thread = new HandlerThread("AlertService",
- Process.THREAD_PRIORITY_BACKGROUND);
- thread.start();
-
- mServiceLooper = thread.getLooper();
- mServiceHandler = new ServiceHandler(mServiceLooper);
- }
-
- @Override
- public void onStart(Intent intent, int startId) {
- Message msg = mServiceHandler.obtainMessage();
- msg.arg1 = startId;
- msg.obj = intent.getExtras();
- mServiceHandler.sendMessage(msg);
- }
-
- @Override
- public void onDestroy() {
- mServiceLooper.quit();
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007 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 dalvik.system.VMRuntime;
-
-import android.accounts.AccountMonitor;
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.os.Bundle;
-import android.os.Handler;
-import android.provider.Calendar;
-import android.text.format.Time;
-import android.view.GestureDetector;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-import android.widget.ProgressBar;
-import android.widget.ViewSwitcher;
-
-/**
- * This is the base class for Day and Week Activities.
- */
-public class CalendarActivity extends Activity implements Navigator {
-
- private static final long INITIAL_HEAP_SIZE = 4*1024*1024;
-
- protected static final String BUNDLE_KEY_RESTORE_TIME = "key_restore_time";
-
- private ContentResolver mContentResolver;
-
- private AccountMonitor mAccountMonitor;
-
- protected ProgressBar mProgressBar;
- protected ViewSwitcher mViewSwitcher;
- protected Animation mInAnimationForward;
- protected Animation mOutAnimationForward;
- protected Animation mInAnimationBackward;
- protected Animation mOutAnimationBackward;
- EventLoader mEventLoader;
-
- Time mSelectedDay = new Time();
-
- /* package */ GestureDetector mGestureDetector;
-
- /**
- * Listens for intent broadcasts
- */
- private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_TIME_CHANGED)
- || action.equals(Intent.ACTION_DATE_CHANGED)
- || action.equals(Intent.ACTION_TIMEZONE_CHANGED)) {
- eventsChanged();
- }
- }
- };
-
- // Create an observer so that we can update the views whenever a
- // Calendar event changes.
- private ContentObserver mObserver = new ContentObserver(new Handler())
- {
- @Override
- public boolean deliverSelfNotifications() {
- return true;
- }
-
- @Override
- public void onChange(boolean selfChange) {
- eventsChanged();
- }
- };
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- // Eliminate extra GCs during startup by setting the initial heap size to 4MB.
- // TODO: We should restore the old heap size once the activity reaches the idle state
- long oldHeapSize = VMRuntime.getRuntime().setMinimumHeapSize(INITIAL_HEAP_SIZE);
-
- setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
- mContentResolver = getContentResolver();
-
- mInAnimationForward = AnimationUtils.loadAnimation(this, R.anim.slide_left_in);
- mOutAnimationForward = AnimationUtils.loadAnimation(this, R.anim.slide_left_out);
- mInAnimationBackward = AnimationUtils.loadAnimation(this, R.anim.slide_right_in);
- mOutAnimationBackward = AnimationUtils.loadAnimation(this, R.anim.slide_right_out);
-
- mGestureDetector = new GestureDetector(this, new CalendarGestureListener());
- mEventLoader = new EventLoader(this);
- }
-
- @Override
- protected void onRestoreInstanceState(Bundle savedInstanceState) {
- super.onRestoreInstanceState(savedInstanceState);
-
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- Time time = new Time();
- time.set(savedInstanceState.getLong(BUNDLE_KEY_RESTORE_TIME));
- view.setSelectedDay(time);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- mEventLoader.startBackgroundThread();
- eventsChanged();
-
- // Register for Intent broadcasts
- IntentFilter filter = new IntentFilter();
-
- filter.addAction(Intent.ACTION_TIME_CHANGED);
- filter.addAction(Intent.ACTION_DATE_CHANGED);
- filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
- registerReceiver(mIntentReceiver, filter);
-
- mContentResolver.registerContentObserver(Calendar.Events.CONTENT_URI,
- true, mObserver);
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
-
- outState.putLong(BUNDLE_KEY_RESTORE_TIME, getSelectedTimeInMillis());
- }
-
- @Override
- protected void onDestroy() {
- if (mAccountMonitor != null) {
- mAccountMonitor.close();
- }
- super.onDestroy();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- mContentResolver.unregisterContentObserver(mObserver);
- unregisterReceiver(mIntentReceiver);
-
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- view.cleanup();
- view = (CalendarView) mViewSwitcher.getNextView();
- view.cleanup();
- mEventLoader.stopBackgroundThread();
- }
-
- void startProgressSpinner() {
- // start the progress spinner
- mProgressBar.setVisibility(View.VISIBLE);
- }
-
- void stopProgressSpinner() {
- // stop the progress spinner
- mProgressBar.setVisibility(View.GONE);
- }
-
- /* Navigator interface methods */
- public void goTo(Time time) {
- CalendarView current = (CalendarView) mViewSwitcher.getCurrentView();
-
- if (current.getSelectedTime().before(time)) {
- mViewSwitcher.setInAnimation(mInAnimationForward);
- mViewSwitcher.setOutAnimation(mOutAnimationForward);
- } else {
- mViewSwitcher.setInAnimation(mInAnimationBackward);
- mViewSwitcher.setOutAnimation(mOutAnimationBackward);
- }
-
- CalendarView next = (CalendarView) mViewSwitcher.getNextView();
- next.setSelectedDay(time);
- next.reloadEvents();
- mViewSwitcher.showNext();
- next.requestFocus();
- }
-
- /**
- * Returns the selected time in milliseconds. The milliseconds are measured
- * in UTC milliseconds from the epoch and uniquely specifies any selectable
- * time.
- *
- * @return the selected time in milliseconds
- */
- public long getSelectedTimeInMillis() {
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- return view.getSelectedTimeInMillis();
- }
-
- public long getSelectedTime() {
- return getSelectedTimeInMillis();
- }
-
- public void goToToday() {
- mSelectedDay.set(System.currentTimeMillis());
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- view.setSelectedDay(mSelectedDay);
- view.reloadEvents();
- }
-
- public boolean getAllDay() {
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- return view.mSelectionAllDay;
- }
-
- void eventsChanged() {
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- view.clearCachedEvents();
- view.reloadEvents();
- }
-
- Event getSelectedEvent() {
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- return view.getSelectedEvent();
- }
-
- boolean isEventSelected() {
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- return view.isEventSelected();
- }
-
- Event getNewEvent() {
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- return view.getNewEvent();
- }
-
- public CalendarView getNextView() {
- return (CalendarView) mViewSwitcher.getNextView();
- }
-
- public View switchViews(boolean forward, float xOffSet, float width) {
- long offset = 0;
- if (xOffSet != 0) {
-
- // The user might have scrolled the view to the left or right
- // in which case we just want to animate the bit left over
- // instead of animating all of it. So calculate how much
- // it's been moved already and animate the remaining portion
- double progress = ((width - (Math.abs(xOffSet))) / width);
- long duration = mInAnimationForward.getDuration();
- offset = -1 * (long) (duration - (duration * progress));
- }
- if (forward) {
- mInAnimationForward.setStartOffset(offset);
- mOutAnimationForward.setStartOffset(offset);
- mViewSwitcher.setInAnimation(mInAnimationForward);
- mViewSwitcher.setOutAnimation(mOutAnimationForward);
- } else {
- mInAnimationBackward.setStartOffset(offset);
- mOutAnimationBackward.setStartOffset(offset);
- mViewSwitcher.setInAnimation(mInAnimationBackward);
- mViewSwitcher.setOutAnimation(mOutAnimationBackward);
- }
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- view.cleanup();
- mViewSwitcher.showNext();
- view = (CalendarView) mViewSwitcher.getCurrentView();
- view.requestFocus();
- view.reloadEvents();
- return view;
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- MenuHelper.onPrepareOptionsMenu(this, menu);
- return super.onPrepareOptionsMenu(menu);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- if (! MenuHelper.onCreateOptionsMenu(menu)) {
- return false;
- }
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (MenuHelper.onOptionsItemSelected(this, item, this)) {
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- if (mGestureDetector.onTouchEvent(ev)) {
- return true;
- }
- return super.onTouchEvent(ev);
- }
-
- class CalendarGestureListener extends GestureDetector.SimpleOnGestureListener {
- @Override
- public boolean onSingleTapUp(MotionEvent ev) {
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- view.doSingleTapUp(ev);
- return true;
- }
-
- @Override
- public void onShowPress(MotionEvent ev) {
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- view.doShowPress(ev);
- }
-
- @Override
- public void onLongPress(MotionEvent ev) {
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- view.doLongPress(ev);
- }
-
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- view.doScroll(e1, e2, distanceX, distanceY);
- return true;
- }
-
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- view.doFling(e1, e2, velocityX, velocityY);
- return true;
- }
-
- @Override
- public boolean onDown(MotionEvent ev) {
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- view.doDown(ev);
- return true;
- }
- }
-}
-
+++ /dev/null
-/*
- * Copyright (C) 2007 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.app.Application;
-import android.preference.PreferenceManager;
-import android.util.Log;
-
-public class CalendarApplication extends Application {
-
- // TODO: get rid of this global member.
- public Event currentEvent = null;
-
- /**
- * The Screen class defines a node in a linked list. This list contains
- * the screens that were visited, with the more recently visited screens
- * coming earlier in the list. The "next" pointer of the head node
- * points to the first element in the list (the most recently visited
- * screen).
- */
- /* package */ class Screen {
- public int id;
- public Screen next;
- public Screen previous;
-
- public Screen(int id) {
- this.id = id;
- next = this;
- previous = this;
- }
-
- // Adds the given node to the list after this one
- public void insert(Screen node) {
- node.next = next;
- node.previous = this;
- next.previous = node;
- next = node;
- }
-
- // Removes this node from the list it is in.
- public void unlink() {
- next.previous = previous;
- previous.next = next;
- }
- }
-
- public static final int MONTH_VIEW_ID = 0;
- public static final int WEEK_VIEW_ID = 1;
- public static final int DAY_VIEW_ID = 2;
- public static final int AGENDA_VIEW_ID = 3;
-
- public static final String[] ACTIVITY_NAMES = new String[] {
- MonthActivity.class.getName(),
- WeekActivity.class.getName(),
- DayActivity.class.getName(),
- AgendaActivity.class.getName(),
- };
-
- @Override
- public void onCreate() {
- super.onCreate();
-
- /*
- * Ensure the default values are set for any receiver, activity,
- * service, etc. of Calendar
- */
- PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2006 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;
-
-public final class CalendarData {
- static final String[] sDateStrings = { "0", "1", "2", "3", "4", "5", "6",
- "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17",
- "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28",
- "29", "30", "31" };
-
- static final String[] sMonthNumStrings = { "1", "2", "3", "4", "5", "6",
- "7", "8", "9", "10", "11", "12" };
-
- static final String[] s12Hours = { "12 AM", "1 AM", "2 AM", "3 AM", "4 AM",
- "5 AM", "6 AM", "7 AM", "8 AM", "9 AM", "10 AM", "11 AM", "Noon",
- "1 PM", "2 PM", "3 PM", "4 PM", "5 PM", "6 PM", "7 PM", "8 PM",
- "9 PM", "10 PM", "11 PM", "12 AM" };
-
- static final String[] s12AmPm = { "AM", "AM", "AM", "AM", "AM",
- "AM", "AM", "AM", "AM", "AM", "AM", "AM", "PM",
- "PM", "PM", "PM", "PM", "PM", "PM", "PM", "PM",
- "PM", "PM", "PM", "AM" };
-
- static final String[] s12HoursNoAmPm = { "12", "1", "2", "3", "4",
- "5", "6", "7", "8", "9", "10", "11", "12",
- "1", "2", "3", "4", "5", "6", "7", "8",
- "9", "10", "11", "12" };
-
- static final String[] s24Hours = { "00", "01", "02", "03", "04", "05",
- "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16",
- "17", "18", "19", "20", "21", "22", "23", "00" };
-
- static final String[] sMinutes = {
- ":00", ":01", ":02", ":03", ":04", ":05", ":06", ":07", ":08", ":09",
- ":10", ":11", ":12", ":13", ":14", ":15", ":16", ":17", ":18", ":19",
- ":20", ":21", ":22", ":23", ":24", ":25", ":26", ":27", ":28", ":29",
- ":30", ":31", ":32", ":33", ":34", ":35", ":36", ":37", ":38", ":39",
- ":40", ":41", ":42", ":43", ":44", ":45", ":46", ":47", ":48", ":49",
- ":50", ":51", ":52", ":53", ":54", ":55", ":56", ":57", ":58", ":59"
- };
-}
+++ /dev/null
-/*
- * Copyright (C) 2009 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.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.gadget.GadgetManager;
-import android.gadget.GadgetProvider;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.provider.Calendar;
-import android.provider.Calendar.Attendees;
-import android.provider.Calendar.Calendars;
-import android.provider.Calendar.EventsColumns;
-import android.provider.Calendar.Instances;
-import android.provider.Calendar.Reminders;
-import android.text.format.DateFormat;
-import android.text.format.DateUtils;
-import android.text.format.Time;
-import android.util.Config;
-import android.util.Log;
-import android.view.View;
-import android.widget.RemoteViews;
-
-import java.util.Arrays;
-import java.util.Date;
-import java.util.GregorianCalendar;
-
-/**
- * Simple gadget to show next upcoming calendar event.
- */
-public class CalendarGadgetProvider extends GadgetProvider {
- static final String TAG = "CalendarGadgetProvider";
- static final boolean LOGD = false;
-
- // TODO: listen for timezone and system time changes to update date icon
-
- static final String EVENT_SORT_ORDER = "startDay ASC, allDay ASC, begin ASC";
-
- static final String[] EVENT_PROJECTION = new String[] {
- Instances.ALL_DAY,
- Instances.BEGIN,
- Instances.END,
- Instances.COLOR,
- Instances.TITLE,
- Instances.RRULE,
- Instances.HAS_ALARM,
- Instances.EVENT_LOCATION,
- Instances.CALENDAR_ID,
- Instances.EVENT_ID,
- };
-
- static final int INDEX_ALL_DAY = 0;
- static final int INDEX_BEGIN = 1;
- static final int INDEX_END = 2;
- static final int INDEX_COLOR = 3;
- static final int INDEX_TITLE = 4;
- static final int INDEX_RRULE = 5;
- static final int INDEX_HAS_ALARM = 6;
- static final int INDEX_EVENT_LOCATION = 7;
- static final int INDEX_CALENDAR_ID = 8;
- static final int INDEX_EVENT_ID = 9;
-
- static final long SEARCH_DURATION = DateUtils.WEEK_IN_MILLIS;
-
- static final long UPDATE_DELAY_TRIGGER_DURATION = DateUtils.MINUTE_IN_MILLIS * 30;
- static final long UPDATE_DELAY_DURATION = DateUtils.MINUTE_IN_MILLIS * 5;
-
- static final long UPDATE_NO_EVENTS = DateUtils.DAY_IN_MILLIS;
-
- private static final int[] DATE_ICONS = new int[] {
- R.drawable.ic_date_01, R.drawable.ic_date_02, R.drawable.ic_date_03,
- R.drawable.ic_date_04, R.drawable.ic_date_05, R.drawable.ic_date_06,
- R.drawable.ic_date_07, R.drawable.ic_date_08, R.drawable.ic_date_09,
- R.drawable.ic_date_10, R.drawable.ic_date_11, R.drawable.ic_date_12,
- R.drawable.ic_date_13, R.drawable.ic_date_14, R.drawable.ic_date_15,
- R.drawable.ic_date_16, R.drawable.ic_date_17, R.drawable.ic_date_18,
- R.drawable.ic_date_19, R.drawable.ic_date_20, R.drawable.ic_date_21,
- R.drawable.ic_date_22, R.drawable.ic_date_23, R.drawable.ic_date_24,
- R.drawable.ic_date_25, R.drawable.ic_date_26, R.drawable.ic_date_27,
- R.drawable.ic_date_28, R.drawable.ic_date_29, R.drawable.ic_date_30,
- R.drawable.ic_date_31,
- };
-
- @Override
- public void onDisabled(Context context) {
- // Unsubscribe from all AlarmManager updates
- AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- PendingIntent pendingUpdate = getUpdateIntent(context);
- am.cancel(pendingUpdate);
- }
-
- @Override
- public void onUpdate(Context context, GadgetManager gadgetManager, int[] gadgetIds) {
- performUpdate(context, gadgetIds);
- }
-
- static void performUpdate(Context context, int[] gadgetIds) {
- performUpdate(context, gadgetIds, Long.MIN_VALUE, Long.MAX_VALUE);
- }
-
- /**
- * Process and push out an update for the given gadgetIds.
- */
- static void performUpdate(Context context, int[] gadgetIds,
- long changedStart, long changedEnd) {
- ContentResolver resolver = context.getContentResolver();
-
- Cursor cursor = null;
- RemoteViews views = null;
- long triggerTime = -1;
-
- try {
- cursor = getUpcomingInstancesCursor(resolver, SEARCH_DURATION);
- if (cursor != null) {
- MarkedEvents events = buildMarkedEvents(cursor);
- if (events.primaryCount == 0) {
- views = getGadgetNoEvents(context);
- } else if (causesUpdate(events, changedStart, changedEnd)) {
- views = getGadgetUpdate(context, cursor, events);
- triggerTime = calculateUpdateTime(context, cursor, events);
- }
- } else {
- views = getGadgetNoEvents(context);
- }
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
-
- // Bail out early if no update built
- if (views == null) {
- return;
- }
-
- GadgetManager gm = GadgetManager.getInstance(context);
- if (gadgetIds != null) {
- gm.updateGadget(gadgetIds, views);
- } else {
- ComponentName thisGadget = new ComponentName(context, CalendarGadgetProvider.class);
- gm.updateGadget(thisGadget, views);
- }
-
- // Schedule an alarm to wake ourselves up for the next update. We also cancel
- // all existing wake-ups because PendingIntents don't match against extras.
-
- // If no next-update calculated, schedule update about a day from now
- long now = System.currentTimeMillis();
- if (triggerTime == -1) {
- triggerTime = now + UPDATE_NO_EVENTS;
- }
-
- // If requested update in past then bail out. This means we lose future
- // updates, but it's better than possibly looping to death.
- if (triggerTime <= now) {
- Log.w(TAG, String.format(
- "Encountered a bad triggerTime=%d, so bailing on future updates", triggerTime));
- }
-
- // Force early update at midnight to change date, if needed
- long nextMidnight = getNextMidnight();
- if (triggerTime > nextMidnight) {
- triggerTime = nextMidnight;
- }
-
- AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- PendingIntent pendingUpdate = getUpdateIntent(context);
-
- am.cancel(pendingUpdate);
- am.set(AlarmManager.RTC, triggerTime, pendingUpdate);
-
- if (LOGD) {
- long seconds = (triggerTime - System.currentTimeMillis()) /
- DateUtils.SECOND_IN_MILLIS;
- Log.d(TAG, String.format("Scheduled next update at %d (%d seconds from now)",
- triggerTime, seconds));
- }
- }
-
- static PendingIntent getUpdateIntent(Context context) {
- Intent updateIntent = new Intent(GadgetManager.ACTION_GADGET_UPDATE);
- return PendingIntent.getBroadcast(context, 0 /* no requestCode */,
- updateIntent, 0 /* no flags */);
- }
-
- /**
- * Figure out the best time to push gadget updates. If the event is longer
- * than 30 minutes, we should wait until 5 minutes after it starts to
- * replace it with next event. Otherwise we replace at start time.
- * <p>
- * Absolute worst case is that we don't have an upcoming event in the next
- * week, so we should wait an entire day before the next push.
- */
- static long calculateUpdateTime(Context context, Cursor cursor, MarkedEvents events) {
- ContentResolver resolver = context.getContentResolver();
- long result = System.currentTimeMillis() + DateUtils.DAY_IN_MILLIS;
-
- if (events.primaryRow != -1) {
- cursor.moveToPosition(events.primaryRow);
- long start = cursor.getLong(INDEX_BEGIN);
- long end = cursor.getLong(INDEX_END);
-
- // If event is longer than our trigger, avoid pushing an update
- // for next event until a few minutes after it starts. (Otherwise
- // just push the update right as the event starts.)
- long length = end - start;
- if (length >= UPDATE_DELAY_TRIGGER_DURATION) {
- result = start + UPDATE_DELAY_DURATION;
- } else {
- result = start;
- }
- }
- return result;
- }
-
- /**
- * Return next midnight in current timezone.
- */
- static long getNextMidnight() {
- Time time = new Time();
- time.set(System.currentTimeMillis() + DateUtils.DAY_IN_MILLIS);
- time.hour = 0;
- time.minute = 0;
- time.second = 0;
- return time.toMillis(true /* ignore DST */);
- }
-
- /**
- * Build a set of {@link RemoteViews} that describes how to update any
- * gadget for a specific event instance.
- *
- * @param cursor Valid cursor on {@link Instances#CONTENT_URI}
- * @param events {@link MarkedEvents} parsed from the cursor
- */
- static RemoteViews getGadgetUpdate(Context context, Cursor cursor, MarkedEvents events) {
- Resources res = context.getResources();
- ContentResolver resolver = context.getContentResolver();
-
- RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.gadget_item);
-
- // Clicking on gadget launches the agenda view in Calendar
- // TODO: launch to specific primaryEventTime (bug 1648608)
- Intent agendaIntent = new Intent(context, AgendaActivity.class);
- PendingIntent pendingIntent = PendingIntent.getActivity(context, 0 /* no requestCode */,
- agendaIntent, 0 /* no flags */);
-
- views.setOnClickPendingIntent(R.id.gadget, pendingIntent);
-
- // Build calendar icon with actual date
- Bitmap dateIcon = buildDateIcon(context);
- views.setImageViewBitmap(R.id.icon, dateIcon);
- views.setViewVisibility(R.id.icon, View.VISIBLE);
- views.setViewVisibility(R.id.no_events, View.GONE);
-
- long nextMidnight = getNextMidnight();
-
- // Fill primary event details
- if (events.primaryRow != -1) {
- views.setViewVisibility(R.id.primary_card, View.VISIBLE);
- cursor.moveToPosition(events.primaryRow);
-
- // Color stripe
- int colorFilter = cursor.getInt(INDEX_COLOR);
- views.setDrawableParameters(R.id.when, true, -1, colorFilter,
- PorterDuff.Mode.SRC_IN, -1);
- views.setTextColor(R.id.title, colorFilter);
- views.setTextColor(R.id.where, colorFilter);
- views.setDrawableParameters(R.id.divider, true, -1, colorFilter,
- PorterDuff.Mode.SRC_IN, -1);
- views.setTextColor(R.id.title2, colorFilter);
-
- // When
- long start = cursor.getLong(INDEX_BEGIN);
- boolean allDay = cursor.getInt(INDEX_ALL_DAY) != 0;
-
- int flags;
- String whenString;
- if (allDay) {
- flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_UTC
- | DateUtils.FORMAT_SHOW_DATE;
- } else {
- flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_TIME;
- // Show date if starts beyond next midnight
- if (start > nextMidnight) {
- flags = flags | DateUtils.FORMAT_SHOW_DATE;
- }
- }
- if (DateFormat.is24HourFormat(context)) {
- flags |= DateUtils.FORMAT_24HOUR;
- }
- whenString = DateUtils.formatDateRange(context, start, start, flags);
- views.setTextViewText(R.id.when, whenString);
-
- // What
- String titleString = cursor.getString(INDEX_TITLE);
- if (titleString == null || titleString.length() == 0) {
- titleString = context.getString(R.string.no_title_label);
- }
- views.setTextViewText(R.id.title, titleString);
-
- // Where
- String whereString = cursor.getString(INDEX_EVENT_LOCATION);
- if (whereString != null && whereString.length() > 0) {
- views.setViewVisibility(R.id.where, View.VISIBLE);
- views.setViewVisibility(R.id.stub_where, View.INVISIBLE);
- views.setTextViewText(R.id.where, whereString);
- } else {
- views.setViewVisibility(R.id.where, View.GONE);
- views.setViewVisibility(R.id.stub_where, View.GONE);
- }
- }
-
- // Fill other primary events, if present
- if (events.primaryConflictRow != -1) {
- views.setViewVisibility(R.id.divider, View.VISIBLE);
- views.setViewVisibility(R.id.title2, View.VISIBLE);
-
- if (events.primaryCount > 2) {
- // If more than two primary conflicts, format multiple message
- int count = events.primaryCount - 1;
- String titleString = String.format(res.getQuantityString(
- R.plurals.gadget_more_events, count), count);
- views.setTextViewText(R.id.title2, titleString);
- } else {
- cursor.moveToPosition(events.primaryConflictRow);
-
- // What
- String titleString = cursor.getString(INDEX_TITLE);
- if (titleString == null || titleString.length() == 0) {
- titleString = context.getString(R.string.no_title_label);
- }
- views.setTextViewText(R.id.title2, titleString);
- }
- } else {
- views.setViewVisibility(R.id.divider, View.GONE);
- views.setViewVisibility(R.id.title2, View.GONE);
- }
-
- // Fill secondary event
- if (events.secondaryRow != -1) {
- views.setViewVisibility(R.id.secondary_card, View.VISIBLE);
- views.setViewVisibility(R.id.secondary_when, View.VISIBLE);
- views.setViewVisibility(R.id.secondary_title, View.VISIBLE);
-
- cursor.moveToPosition(events.secondaryRow);
-
- // Color stripe
- int colorFilter = cursor.getInt(INDEX_COLOR);
- views.setDrawableParameters(R.id.secondary_when, true, -1, colorFilter,
- PorterDuff.Mode.SRC_IN, -1);
- views.setTextColor(R.id.secondary_title, colorFilter);
-
- // When
- long start = cursor.getLong(INDEX_BEGIN);
- boolean allDay = cursor.getInt(INDEX_ALL_DAY) != 0;
-
- int flags;
- String whenString;
- if (allDay) {
- flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_UTC
- | DateUtils.FORMAT_SHOW_DATE;
- } else {
- flags = DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_TIME;
- // Show date if starts beyond next midnight
- if (start > nextMidnight) {
- flags = flags | DateUtils.FORMAT_SHOW_DATE;
- }
- }
- if (DateFormat.is24HourFormat(context)) {
- flags |= DateUtils.FORMAT_24HOUR;
- }
- whenString = DateUtils.formatDateRange(context, start, start, flags);
- views.setTextViewText(R.id.secondary_when, whenString);
-
- if (events.secondaryCount > 1) {
- // If more than two secondary conflicts, format multiple message
- int count = events.secondaryCount;
- String titleString = String.format(res.getQuantityString(
- R.plurals.gadget_more_events, count), count);
- views.setTextViewText(R.id.secondary_title, titleString);
- } else {
- // What
- String titleString = cursor.getString(INDEX_TITLE);
- if (titleString == null || titleString.length() == 0) {
- titleString = context.getString(R.string.no_title_label);
- }
- views.setTextViewText(R.id.secondary_title, titleString);
- }
- } else {
- views.setViewVisibility(R.id.secondary_when, View.GONE);
- views.setViewVisibility(R.id.secondary_title, View.GONE);
- }
-
- return views;
- }
-
- /**
- * Build a set of {@link RemoteViews} that describes an error state.
- */
- static RemoteViews getGadgetNoEvents(Context context) {
- RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.gadget_item);
-
- views.setViewVisibility(R.id.icon, View.GONE);
- views.setViewVisibility(R.id.no_events, View.VISIBLE);
-
- views.setViewVisibility(R.id.primary_card, View.GONE);
- views.setViewVisibility(R.id.secondary_card, View.GONE);
-
- // Clicking on gadget launches the agenda view in Calendar
- Intent agendaIntent = new Intent(context, AgendaActivity.class);
- PendingIntent pendingIntent = PendingIntent.getActivity(context, 0 /* no requestCode */,
- agendaIntent, 0 /* no flags */);
-
- views.setOnClickPendingIntent(R.id.gadget, pendingIntent);
-
- return views;
- }
-
- /**
- * Build super-awesome calendar icon with actual date overlay. Uses current
- * system date to generate.
- */
- static Bitmap buildDateIcon(Context context) {
- Time time = new Time();
- time.setToNow();
- int dateNumber = time.monthDay;
-
- Resources res = context.getResources();
- Bitmap blankIcon = BitmapFactory.decodeResource(res, R.drawable.app_icon_blank);
- Bitmap overlay = BitmapFactory.decodeResource(res, DATE_ICONS[dateNumber - 1]);
-
- Bitmap result = Bitmap.createBitmap(blankIcon.getWidth(),
- blankIcon.getHeight(), blankIcon.getConfig());
-
- Canvas canvas = new Canvas(result);
- Paint paint = new Paint();
-
- canvas.drawBitmap(blankIcon, 0f, 0f, paint);
- canvas.drawBitmap(overlay, 0f, 0f, paint);
-
- return result;
- }
-
- static class MarkedEvents {
- long primaryTime = -1;
- int primaryRow = -1;
- int primaryConflictRow = -1;
- int primaryCount = 0;
- long secondaryTime = -1;
- int secondaryRow = -1;
- int secondaryCount = 0;
- }
-
- /**
- * Check if the given {@link MarkedEvents} should cause an update based on a
- * time span, usually coming from a calendar changed event.
- */
- static boolean causesUpdate(MarkedEvents events, long changedStart, long changedEnd) {
- boolean primaryTouched =
- (events.primaryTime >= changedStart && events.primaryTime <= changedEnd);
- boolean secondaryTouched =
- (events.secondaryTime >= changedStart && events.secondaryTime <= changedEnd);
- return (primaryTouched || secondaryTouched);
- }
-
- /**
- * Walk the given instances cursor and build a list of marked events to be
- * used when updating the gadget. This structure is also used to check if
- * updates are needed. Assumes the incoming cursor is valid.
- */
- static MarkedEvents buildMarkedEvents(Cursor cursor) {
- MarkedEvents events = new MarkedEvents();
- long now = System.currentTimeMillis();
-
- cursor.moveToPosition(-1);
- while (cursor.moveToNext()) {
- int row = cursor.getPosition();
- long begin = cursor.getLong(INDEX_BEGIN);
- boolean allDay = cursor.getInt(INDEX_ALL_DAY) != 0;
-
- // Skip all-day events that have already started
- if (allDay && begin < now) {
- continue;
- }
-
- if (events.primaryRow == -1) {
- // Found first event
- events.primaryRow = row;
- events.primaryTime = begin;
- events.primaryCount = 1;
- } else if (events.primaryTime == begin) {
- // Found conflicting primary event
- if (events.primaryConflictRow == -1) {
- events.primaryConflictRow = row;
- }
- events.primaryCount += 1;
- } else if (events.secondaryRow == -1) {
- // Found second event
- events.secondaryRow = row;
- events.secondaryTime = begin;
- events.secondaryCount = 1;
- } else if (events.secondaryTime == begin) {
- // Found conflicting secondary event
- events.secondaryCount += 1;
- } else {
- // Nothing interesting about this event, so bail out
- }
- }
- return events;
- }
-
- /**
- * Query across all calendars for upcoming event instances from now until
- * some time in the future.
- *
- * @param searchDuration Distance into the future to look for event
- * instances, in milliseconds.
- */
- static Cursor getUpcomingInstancesCursor(ContentResolver resolver, long searchDuration) {
- // Search for events from now until some time in the future
- long start = System.currentTimeMillis();
- long end = start + searchDuration;
-
- Uri uri = Uri.withAppendedPath(Instances.CONTENT_URI,
- String.format("%d/%d", start, end));
-
- // Make sure we only look at events *starting* after now
- String selection = String.format("%s=1 AND %s!=%d AND %s>=%d",
- Calendars.SELECTED, Instances.SELF_ATTENDEE_STATUS,
- Attendees.ATTENDEE_STATUS_DECLINED, Instances.BEGIN, start);
-
- return resolver.query(uri, EVENT_PROJECTION, selection, null,
- EVENT_SORT_ORDER);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007 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.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.os.Bundle;
-import android.preference.ListPreference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceScreen;
-import android.preference.CheckBoxPreference;
-import android.preference.RingtonePreference;
-
-public class CalendarPreferenceActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
- // Preference keys
- static final String KEY_HIDE_DECLINED = "preferences_hide_declined";
- static final String KEY_ALERTS_TYPE = "preferences_alerts_type";
- static final String KEY_ALERTS_VIBRATE = "preferences_alerts_vibrate";
- static final String KEY_ALERTS_RINGTONE = "preferences_alerts_ringtone";
- static final String KEY_DEFAULT_REMINDER = "preferences_default_reminder";
- static final String KEY_START_VIEW = "startView";
- static final String KEY_DETAILED_VIEW = "preferredDetailedView";
-
- // These must be in sync with the array preferences_alert_type_values
- static final String ALERT_TYPE_ALERTS = "0";
- static final String ALERT_TYPE_STATUS_BAR = "1";
- static final String ALERT_TYPE_OFF = "2";
-
- // Default preference values
- static final String DEFAULT_START_VIEW =
- CalendarApplication.ACTIVITY_NAMES[CalendarApplication.MONTH_VIEW_ID];
- static final String DEFAULT_DETAILED_VIEW =
- CalendarApplication.ACTIVITY_NAMES[CalendarApplication.DAY_VIEW_ID];
-
- ListPreference mAlertType;
- CheckBoxPreference mVibrate;
- RingtonePreference mRingtone;
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- // Load the preferences from an XML resource
- addPreferencesFromResource(R.xml.preferences);
-
- PreferenceScreen preferenceScreen = getPreferenceScreen();
- preferenceScreen.getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
- mAlertType = (ListPreference) preferenceScreen.findPreference(KEY_ALERTS_TYPE);
- mVibrate = (CheckBoxPreference) preferenceScreen.findPreference(KEY_ALERTS_VIBRATE);
- mRingtone = (RingtonePreference) preferenceScreen.findPreference(KEY_ALERTS_RINGTONE);
-
- updateChildPreferences();
- }
-
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if (key.equals(KEY_ALERTS_TYPE)) {
- updateChildPreferences();
- }
- }
-
- private void updateChildPreferences() {
- if (mAlertType.getValue().equals(ALERT_TYPE_OFF)) {
- mVibrate.setChecked(false);
- mVibrate.setEnabled(false);
- mRingtone.setEnabled(false);
- } else {
- mVibrate.setEnabled(true);
- mRingtone.setEnabled(true);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007 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 static android.provider.Calendar.EVENT_BEGIN_TIME;
-import static android.provider.Calendar.EVENT_END_TIME;
-
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.PorterDuff;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Typeface;
-import android.graphics.Paint.Style;
-import android.graphics.Path.Direction;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Handler;
-import android.provider.Calendar.Attendees;
-import android.provider.Calendar.Calendars;
-import android.provider.Calendar.Events;
-import android.text.format.DateFormat;
-import android.text.format.DateUtils;
-import android.text.format.Time;
-import android.util.Log;
-import android.view.ContextMenu;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.widget.ImageView;
-import android.widget.PopupWindow;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-
-/**
- * This is the base class for a set of classes that implement views (day view
- * and week view to start with) that share some common code.
- */
-public class CalendarView extends View
- implements View.OnCreateContextMenuListener, View.OnClickListener {
-
- private boolean mOnFlingCalled;
-
- protected CalendarApplication mCalendarApp;
- protected CalendarActivity mParentActivity;
-
- private static final String[] CALENDARS_PROJECTION = new String[] {
- Calendars._ID, // 0
- Calendars.ACCESS_LEVEL, // 1
- };
- private static final int CALENDARS_INDEX_ACCESS_LEVEL = 1;
- private static final String CALENDARS_WHERE = Calendars._ID + "=%d";
-
- private static final String[] ATTENDEES_PROJECTION = new String[] {
- Attendees._ID, // 0
- Attendees.ATTENDEE_RELATIONSHIP, // 1
- };
- private static final int ATTENDEES_INDEX_RELATIONSHIP = 1;
- private static final String ATTENDEES_WHERE = Attendees.EVENT_ID + "=%d";
-
- private static final float SMALL_ROUND_RADIUS = 3.0F;
-
- private static final int FROM_NONE = 0;
- private static final int FROM_ABOVE = 1;
- private static final int FROM_BELOW = 2;
- private static final int FROM_LEFT = 4;
- private static final int FROM_RIGHT = 8;
-
- private static final int HORIZONTAL_SCROLL_THRESHOLD = 50;
-
- private ContinueScroll mContinueScroll = new ContinueScroll();
-
- // Make this visible within the package for more informative debugging
- Time mBaseDate;
-
- private Typeface mBold = Typeface.DEFAULT_BOLD;
- private int mFirstJulianDay;
- private int mLastJulianDay;
-
- private int mMonthLength;
- private int mFirstDate;
- private int[] mEarliestStartHour; // indexed by the week day offset
- private boolean[] mHasAllDayEvent; // indexed by the week day offset
-
- private String mDetailedView = CalendarPreferenceActivity.DEFAULT_DETAILED_VIEW;
-
- /**
- * This variable helps to avoid unnecessarily reloading events by keeping
- * track of the start millis parameter used for the most recent loading
- * of events. If the next reload matches this, then the events are not
- * reloaded. To force a reload, set this to zero (this is set to zero
- * in the method clearCachedEvents()).
- */
- private long mLastReloadMillis;
-
- private ArrayList<Event> mEvents = new ArrayList<Event>();
- private Drawable mBoxNormal;
- private Drawable mBoxSelected;
- private Drawable mBoxPressed;
- private Drawable mBoxLongPressed;
- private int mSelectionDay; // Julian day
- private int mSelectionHour;
-
- /* package private so that CalendarActivity can read it when creating new
- * events
- */
- boolean mSelectionAllDay;
-
- private int mCellWidth;
- private boolean mLaunchNewView;
-
- // Pre-allocate these objects and re-use them
- private Rect mRect = new Rect();
- private RectF mRectF = new RectF();
- private Rect mSrcRect = new Rect();
- private Rect mDestRect = new Rect();
- private Paint mPaint = new Paint();
- private Paint mEventTextPaint = new Paint();
- private Paint mSelectionPaint = new Paint();
- private Path mPath = new Path();
-
- protected boolean mDrawTextInEventRect;
- private int mStartDay;
-
- private PopupWindow mPopup;
- private View mPopupView;
- private static final int POPUP_HEIGHT = 67;
-
- // The number of milliseconds to show the popup window
- private static final int POPUP_DISMISS_DELAY = 3000;
- private DismissPopup mDismissPopup = new DismissPopup();
-
- // For drawing to an off-screen Canvas
- private Bitmap mBitmap;
- private Canvas mCanvas;
- private boolean mRedrawScreen = true;
- private boolean mRemeasure = true;
-
- private final EventLoader mEventLoader;
- protected final EventGeometry mEventGeometry;
-
- private static final int DAY_GAP = 1;
- private static final int HOUR_GAP = 1;
- private static final int SINGLE_ALLDAY_HEIGHT = 20;
- private static final int MAX_ALLDAY_HEIGHT = 72;
- private static final int ALLDAY_TOP_MARGIN = 3;
- private static final int MAX_ALLDAY_EVENT_HEIGHT = 18;
-
- /* The extra space to leave above the text in all-day events */
- private static final int ALL_DAY_TEXT_TOP_MARGIN = 0;
-
- /* The extra space to leave above the text in normal events */
- private static final int NORMAL_TEXT_TOP_MARGIN = 2;
-
- private static final int HOURS_LEFT_MARGIN = 2;
- private static final int HOURS_RIGHT_MARGIN = 4;
- private static final int HOURS_MARGIN = HOURS_LEFT_MARGIN + HOURS_RIGHT_MARGIN;
-
- /* package */ static final int MINUTES_PER_HOUR = 60;
- /* package */ static final int MINUTES_PER_DAY = MINUTES_PER_HOUR * 24;
- /* package */ static final int MILLIS_PER_MINUTE = 60 * 1000;
- /* package */ static final int MILLIS_PER_HOUR = (3600 * 1000);
- /* package */ static final int MILLIS_PER_DAY = MILLIS_PER_HOUR * 24;
-
- private static final int NORMAL_FONT_SIZE = 12;
- private static final int EVENT_TEXT_FONT_SIZE = 12;
- private static final int HOURS_FONT_SIZE = 12;
- private static final int AMPM_FONT_SIZE = 9;
- private static final int MIN_CELL_WIDTH_FOR_TEXT = 10;
- private static final int MAX_EVENT_TEXT_LEN = 500;
- private static final float MIN_EVENT_HEIGHT = 15.0F; // in pixels
-
- private static int mSelectionColor;
- private static int mPressedColor;
- private static int mSelectedEventTextColor;
- private static int mEventTextColor;
-
- private int mViewStartX;
- private int mViewStartY;
- private int mMaxViewStartY;
- private int mBitmapHeight;
- private int mViewHeight;
- private int mViewWidth;
- private int mGridAreaHeight;
- private int mGridAreaWidth;
- private int mCellHeight;
- private int mScrollStartY;
- private int mPreviousDirection;
- private int mPreviousDistanceX;
-
- private int mHoursTextHeight;
- private int mEventTextAscent;
- private int mEventTextHeight;
- private int mAllDayHeight;
- private int mBannerPlusMargin;
- private int mMaxAllDayEvents;
-
- protected int mNumDays = 7;
- private int mNumHours = 10;
- private int mHoursWidth;
- private int mDateStrWidth;
- private int mFirstCell;
- private int mFirstHour = -1;
- private int mFirstHourOffset;
- private String[] mHourStrs;
- private String[] mDayStrs;
- private String[] mDayStrs2Letter;
- private boolean mIs24HourFormat;
-
- private float[] mCharWidths = new float[MAX_EVENT_TEXT_LEN];
- private ArrayList<Event> mSelectedEvents = new ArrayList<Event>();
- private boolean mComputeSelectedEvents;
- private Event mSelectedEvent;
- private Event mPrevSelectedEvent;
- private Rect mPrevBox = new Rect();
- protected final Resources mResources;
- private String mAmString;
- private String mPmString;
- private DeleteEventHelper mDeleteEventHelper;
-
- private ContextMenuHandler mContextMenuHandler = new ContextMenuHandler();
-
- /**
- * The initial state of the touch mode when we enter this view.
- */
- private static final int TOUCH_MODE_INITIAL_STATE = 0;
-
- /**
- * Indicates we just received the touch event and we are waiting to see if
- * it is a tap or a scroll gesture.
- */
- private static final int TOUCH_MODE_DOWN = 1;
-
- /**
- * Indicates the touch gesture is a vertical scroll
- */
- private static final int TOUCH_MODE_VSCROLL = 0x20;
-
- /**
- * Indicates the touch gesture is a horizontal scroll
- */
- private static final int TOUCH_MODE_HSCROLL = 0x40;
-
- private int mTouchMode = TOUCH_MODE_INITIAL_STATE;
-
- /**
- * The selection modes are HIDDEN, PRESSED, SELECTED, and LONGPRESS.
- */
- private static final int SELECTION_HIDDEN = 0;
- private static final int SELECTION_PRESSED = 1;
- private static final int SELECTION_SELECTED = 2;
- private static final int SELECTION_LONGPRESS = 3;
-
- private int mSelectionMode = SELECTION_HIDDEN;
-
- private boolean mScrolling = false;
-
- private String mDateRange;
- private TextView mTitleTextView;
-
- public CalendarView(CalendarActivity activity) {
- super(activity);
- mResources = activity.getResources();
- mEventLoader = activity.mEventLoader;
- mEventGeometry = new EventGeometry();
- mEventGeometry.setMinEventHeight(MIN_EVENT_HEIGHT);
- mEventGeometry.setHourGap(HOUR_GAP);
- mParentActivity = activity;
- mCalendarApp = (CalendarApplication) mParentActivity.getApplication();
- mDeleteEventHelper = new DeleteEventHelper(activity, false /* don't exit when done */);
-
- init(activity);
- }
-
- private void init(Context context) {
- setFocusable(true);
-
- // Allow focus in touch mode so that we can do keyboard shortcuts
- // even after we've entered touch mode.
- setFocusableInTouchMode(true);
- setClickable(true);
- setOnCreateContextMenuListener(this);
-
- mStartDay = Calendar.getInstance().getFirstDayOfWeek();
- if (mStartDay == Calendar.SATURDAY) {
- mStartDay = Time.SATURDAY;
- } else if (mStartDay == Calendar.MONDAY) {
- mStartDay = Time.MONDAY;
- } else {
- mStartDay = Time.SUNDAY;
- }
-
- mSelectionColor = mResources.getColor(R.color.selection);
- mPressedColor = mResources.getColor(R.color.pressed);
- mSelectedEventTextColor = mResources.getColor(R.color.calendar_event_selected_text_color);
- mEventTextColor = mResources.getColor(R.color.calendar_event_text_color);
- mEventTextPaint.setColor(mEventTextColor);
- mEventTextPaint.setTextSize(EVENT_TEXT_FONT_SIZE);
- mEventTextPaint.setTextAlign(Paint.Align.LEFT);
- mEventTextPaint.setAntiAlias(true);
-
- int gridLineColor = mResources.getColor(R.color.calendar_grid_line_highlight_color);
- Paint p = mSelectionPaint;
- p.setColor(gridLineColor);
- p.setStyle(Style.STROKE);
- p.setStrokeWidth(2.0f);
- p.setAntiAlias(false);
-
- p = mPaint;
- p.setAntiAlias(true);
-
- // Allocate space for 2 weeks worth of weekday names so that we can
- // easily start the week display at any week day.
- mDayStrs = new String[14];
-
- // Also create an array of 2-letter abbreviations.
- mDayStrs2Letter = new String[14];
-
- for (int i = Calendar.SUNDAY; i <= Calendar.SATURDAY; i++) {
- int index = i - Calendar.SUNDAY;
- // e.g. Tue for Tuesday
- mDayStrs[index] = DateUtils.getDayOfWeekString(i, DateUtils.LENGTH_MEDIUM);
- mDayStrs[index + 7] = mDayStrs[index];
- // e.g. Tu for Tuesday
- mDayStrs2Letter[index] = DateUtils.getDayOfWeekString(i, DateUtils.LENGTH_SHORT);
- mDayStrs2Letter[index + 7] = mDayStrs2Letter[index];
- }
-
- // Figure out how much space we need for the 3-letter abbrev names
- // in the worst case.
- p.setTextSize(NORMAL_FONT_SIZE);
- p.setTypeface(mBold);
- String[] dateStrs = {" 28", " 30"};
- mDateStrWidth = computeMaxStringWidth(0, dateStrs, p);
- mDateStrWidth += computeMaxStringWidth(0, mDayStrs, p);
-
- p.setTextSize(HOURS_FONT_SIZE);
- p.setTypeface(null);
- mIs24HourFormat = DateFormat.is24HourFormat(context);
- mHourStrs = mIs24HourFormat ? CalendarData.s24Hours : CalendarData.s12HoursNoAmPm;
- mHoursWidth = computeMaxStringWidth(0, mHourStrs, p);
-
- mAmString = DateUtils.getAMPMString(Calendar.AM);
- mPmString = DateUtils.getAMPMString(Calendar.PM);
- String[] ampm = {mAmString, mPmString};
- p.setTextSize(AMPM_FONT_SIZE);
- mHoursWidth = computeMaxStringWidth(mHoursWidth, ampm, p);
- mHoursWidth += HOURS_MARGIN;
- mBoxNormal = mResources.getDrawable(R.drawable.box_appointment_normal);
- mBoxSelected = mResources.getDrawable(R.drawable.box_appointment_selected);
- mBoxPressed = mResources.getDrawable(R.drawable.box_appointment_pressed);
- mBoxLongPressed = mResources.getDrawable(R.drawable.box_appointment_longpress);
-
- LayoutInflater inflater;
- inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mPopupView = inflater.inflate(R.layout.bubble_event, null);
- mPopup = new PopupWindow(context);
- mPopup.setContentView(mPopupView);
- Resources.Theme dialogTheme = getResources().newTheme();
- dialogTheme.applyStyle(android.R.style.Theme_Dialog, true);
- TypedArray ta = dialogTheme.obtainStyledAttributes(new int[] {
- android.R.attr.windowBackground });
- mPopup.setBackgroundDrawable(ta.getDrawable(0));
- ta.recycle();
-
- // Enable touching the popup window
- mPopupView.setOnClickListener(this);
-
- mBaseDate = new Time();
- long millis = System.currentTimeMillis();
- mBaseDate.set(millis);
-
- mEarliestStartHour = new int[mNumDays];
- mHasAllDayEvent = new boolean[mNumDays];
-
- mNumHours = context.getResources().getInteger(R.integer.number_of_hours);
- mTitleTextView = (TextView) mParentActivity.findViewById(R.id.title);
- }
-
- /**
- * This is called when the popup window is pressed.
- */
- public void onClick(View v) {
- if (v == mPopupView) {
- // Pretend it was a trackball click because that will always
- // jump to the "View event" screen.
- switchViews(true /* trackball */);
- }
- }
-
- /**
- * Returns the start of the selected time in milliseconds since the epoch.
- *
- * @return selected time in UTC milliseconds since the epoch.
- */
- long getSelectedTimeInMillis() {
- Time time = new Time(mBaseDate);
- time.setJulianDay(mSelectionDay);
- time.hour = mSelectionHour;
-
- // We ignore the "isDst" field because we want normalize() to figure
- // out the correct DST value and not adjust the selected time based
- // on the current setting of DST.
- return time.normalize(true /* ignore isDst */);
- }
-
- Time getSelectedTime() {
- Time time = new Time(mBaseDate);
- time.setJulianDay(mSelectionDay);
- time.hour = mSelectionHour;
-
- // We ignore the "isDst" field because we want normalize() to figure
- // out the correct DST value and not adjust the selected time based
- // on the current setting of DST.
- time.normalize(true /* ignore isDst */);
- return time;
- }
-
- /**
- * Returns the start of the selected time in minutes since midnight,
- * local time. The derived class must ensure that this is consistent
- * with the return value from getSelectedTimeInMillis().
- */
- int getSelectedMinutesSinceMidnight() {
- return mSelectionHour * MINUTES_PER_HOUR;
- }
-
- public void setSelectedDay(Time time) {
- mBaseDate.set(time);
- mSelectionHour = mBaseDate.hour;
- mSelectedEvent = null;
- mPrevSelectedEvent = null;
- long millis = mBaseDate.toMillis(false /* use isDst */);
- mSelectionDay = Time.getJulianDay(millis, mBaseDate.gmtoff);
- mSelectedEvents.clear();
- mComputeSelectedEvents = true;
-
- // Force a recalculation of the first visible hour
- mFirstHour = -1;
- recalc();
- mTitleTextView.setText(mDateRange);
-
- // Force a redraw of the selection box.
- mSelectionMode = SELECTION_SELECTED;
- mRedrawScreen = true;
- mRemeasure = true;
- invalidate();
- }
-
- public Time getSelectedDay() {
- Time time = new Time(mBaseDate);
- time.setJulianDay(mSelectionDay);
- time.hour = mSelectionHour;
-
- // We ignore the "isDst" field because we want normalize() to figure
- // out the correct DST value and not adjust the selected time based
- // on the current setting of DST.
- time.normalize(true /* ignore isDst */);
- return time;
- }
-
- private void recalc() {
- // Set the base date to the beginning of the week if we are displaying
- // 7 days at a time.
- if (mNumDays == 7) {
- int dayOfWeek = mBaseDate.weekDay;
- int diff = dayOfWeek - mStartDay;
- if (diff != 0) {
- if (diff < 0) {
- diff += 7;
- }
- mBaseDate.monthDay -= diff;
- mBaseDate.normalize(true /* ignore isDst */);
- }
- }
-
- final long start = mBaseDate.toMillis(false /* use isDst */);
- long end = start;
- mFirstJulianDay = Time.getJulianDay(start, mBaseDate.gmtoff);
- mLastJulianDay = mFirstJulianDay + mNumDays - 1;
-
- mMonthLength = mBaseDate.getActualMaximum(Time.MONTH_DAY);
- mFirstDate = mBaseDate.monthDay;
-
- int flags = DateUtils.FORMAT_SHOW_YEAR;
- if (DateFormat.is24HourFormat(mContext)) {
- flags |= DateUtils.FORMAT_24HOUR;
- }
- if (mNumDays > 1) {
- mBaseDate.monthDay += mNumDays - 1;
- end = mBaseDate.toMillis(true /* ignore isDst */);
- mBaseDate.monthDay -= mNumDays - 1;
- flags |= DateUtils.FORMAT_NO_MONTH_DAY;
- } else {
- flags |= DateUtils.FORMAT_SHOW_WEEKDAY
- | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH;
- }
-
- mDateRange = DateUtils.formatDateRange(mParentActivity, start, end, flags);
- // Do not set the title here because this is called when executing
- // initNextView() to prepare the Day view when sliding the finger
- // horizontally but we don't always want to change the title. And
- // if we change the title here and then change it back in the caller
- // then we get an annoying flicker.
- }
-
- void setDetailedView(String detailedView) {
- mDetailedView = detailedView;
- }
-
- @Override
- protected void onSizeChanged(int width, int height, int oldw, int oldh) {
- mViewWidth = width;
- mViewHeight = height;
- mGridAreaWidth = width - mHoursWidth;
- mCellWidth = (mGridAreaWidth - (mNumDays * DAY_GAP)) / mNumDays;
-
- Paint p = new Paint();
- p.setTextSize(NORMAL_FONT_SIZE);
- int bannerTextHeight = (int) Math.abs(p.ascent());
-
- p.setTextSize(HOURS_FONT_SIZE);
- mHoursTextHeight = (int) Math.abs(p.ascent());
-
- p.setTextSize(EVENT_TEXT_FONT_SIZE);
- float ascent = -p.ascent();
- mEventTextAscent = (int) Math.ceil(ascent);
- float totalHeight = ascent + p.descent();
- mEventTextHeight = (int) Math.ceil(totalHeight);
-
- if (mNumDays > 1) {
- mBannerPlusMargin = bannerTextHeight + 14;
- } else {
- mBannerPlusMargin = 0;
- }
-
- remeasure(width, height);
- }
-
- // Measures the space needed for various parts of the view after
- // loading new events. This can change if there are all-day events.
- private void remeasure(int width, int height) {
-
- // First, clear the array of earliest start times, and the array
- // indicating presence of an all-day event.
- for (int day = 0; day < mNumDays; day++) {
- mEarliestStartHour[day] = 25; // some big number
- mHasAllDayEvent[day] = false;
- }
-
- // Compute the space needed for the all-day events, if any.
- // Make a pass over all the events, and keep track of the maximum
- // number of all-day events in any one day. Also, keep track of
- // the earliest event in each day.
- int maxAllDayEvents = 0;
- ArrayList<Event> events = mEvents;
- int len = events.size();
- for (int ii = 0; ii < len; ii++) {
- Event event = events.get(ii);
- if (event.startDay > mLastJulianDay || event.endDay < mFirstJulianDay)
- continue;
- if (event.allDay) {
- int max = event.getColumn() + 1;
- if (maxAllDayEvents < max) {
- maxAllDayEvents = max;
- }
- int daynum = event.startDay - mFirstJulianDay;
- int durationDays = event.endDay - event.startDay + 1;
- if (daynum < 0) {
- durationDays += daynum;
- daynum = 0;
- }
- if (daynum + durationDays > mNumDays) {
- durationDays = mNumDays - daynum;
- }
- for (int day = daynum; durationDays > 0; day++, durationDays--) {
- mHasAllDayEvent[day] = true;
- }
- } else {
- int daynum = event.startDay - mFirstJulianDay;
- int hour = event.startTime / 60;
- if (daynum >= 0 && hour < mEarliestStartHour[daynum]) {
- mEarliestStartHour[daynum] = hour;
- }
-
- // Also check the end hour in case the event spans more than
- // one day.
- daynum = event.endDay - mFirstJulianDay;
- hour = event.endTime / 60;
- if (daynum < mNumDays && hour < mEarliestStartHour[daynum]) {
- mEarliestStartHour[daynum] = hour;
- }
- }
- }
- mMaxAllDayEvents = maxAllDayEvents;
-
- mFirstCell = mBannerPlusMargin;
- int allDayHeight = 0;
- if (maxAllDayEvents > 0) {
- // If there is at most one all-day event per day, then use less
- // space (but more than the space for a single event).
- if (maxAllDayEvents == 1) {
- allDayHeight = SINGLE_ALLDAY_HEIGHT;
- } else {
- // Allow the all-day area to grow in height depending on the
- // number of all-day events we need to show, up to a limit.
- allDayHeight = maxAllDayEvents * MAX_ALLDAY_EVENT_HEIGHT;
- if (allDayHeight > MAX_ALLDAY_HEIGHT) {
- allDayHeight = MAX_ALLDAY_HEIGHT;
- }
- }
- mFirstCell = mBannerPlusMargin + allDayHeight + ALLDAY_TOP_MARGIN;
- } else {
- mSelectionAllDay = false;
- }
- mAllDayHeight = allDayHeight;
-
- mGridAreaHeight = height - mFirstCell;
- mCellHeight = (mGridAreaHeight - ((mNumHours + 1) * HOUR_GAP)) / mNumHours;
- int usedGridAreaHeight = (mCellHeight + HOUR_GAP) * mNumHours + HOUR_GAP;
- int bottomSpace = mGridAreaHeight - usedGridAreaHeight;
- mEventGeometry.setHourHeight(mCellHeight);
-
- // Create an off-screen bitmap that we can draw into.
- mBitmapHeight = HOUR_GAP + 24 * (mCellHeight + HOUR_GAP) + bottomSpace;
- if ((mBitmap == null || mBitmap.getHeight() < mBitmapHeight) && width > 0 &&
- mBitmapHeight > 0) {
- if (mBitmap != null) {
- mBitmap.recycle();
- }
- mBitmap = Bitmap.createBitmap(width, mBitmapHeight, Bitmap.Config.RGB_565);
- mCanvas = new Canvas(mBitmap);
- }
- mMaxViewStartY = mBitmapHeight - mGridAreaHeight;
-
- if (mFirstHour == -1) {
- initFirstHour();
- mFirstHourOffset = 0;
- }
-
- // When we change the base date, the number of all-day events may
- // change and that changes the cell height. When we switch dates,
- // we use the mFirstHourOffset from the previous view, but that may
- // be too large for the new view if the cell height is smaller.
- if (mFirstHourOffset >= mCellHeight + HOUR_GAP) {
- mFirstHourOffset = mCellHeight + HOUR_GAP - 1;
- }
- mViewStartY = mFirstHour * (mCellHeight + HOUR_GAP) - mFirstHourOffset;
-
- int eventAreaWidth = mNumDays * (mCellWidth + DAY_GAP);
- mPopup.dismiss();
- mPopup.setWidth(eventAreaWidth - 20);
- mPopup.setHeight(POPUP_HEIGHT);
- }
-
- /**
- * Initialize the state for another view. The given view is one that has
- * its own bitmap and will use an animation to replace the current view.
- * The current view and new view are either both Week views or both Day
- * views. They differ in their base date.
- *
- * @param view the view to initialize.
- */
- private void initView(CalendarView view) {
- view.mSelectionHour = mSelectionHour;
- view.mSelectedEvents.clear();
- view.mComputeSelectedEvents = true;
- view.mFirstHour = mFirstHour;
- view.mFirstHourOffset = mFirstHourOffset;
- view.remeasure(getWidth(), getHeight());
-
- view.mSelectedEvent = null;
- view.mPrevSelectedEvent = null;
- view.mStartDay = mStartDay;
- if (view.mEvents.size() > 0) {
- view.mSelectionAllDay = mSelectionAllDay;
- } else {
- view.mSelectionAllDay = false;
- }
-
- // Redraw the screen so that the selection box will be redrawn. We may
- // have scrolled to a different part of the day in some other view
- // so the selection box in this view may no longer be visible.
- view.mRedrawScreen = true;
- view.recalc();
- }
-
- /**
- * Switch to another view based on what was selected (an event or a free
- * slot) and how it was selected (by touch or by trackball).
- *
- * @param trackBallSelection true if the selection was made using the
- * trackball.
- */
- private void switchViews(boolean trackBallSelection) {
- Event selectedEvent = mSelectedEvent;
-
- mPopup.dismiss();
- if (mNumDays > 1) {
- // This is the Week view.
- // With touch, we always switch to Day/Agenda View
- // With track ball, if we selected a free slot, then create an event.
- // If we selected a specific event, switch to EventInfo view.
- if (trackBallSelection) {
- if (selectedEvent == null) {
- // Switch to the EditEvent view
- long startMillis = getSelectedTimeInMillis();
- long endMillis = startMillis + DateUtils.HOUR_IN_MILLIS;
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setClassName(mContext, EditEvent.class.getName());
- intent.putExtra(EVENT_BEGIN_TIME, startMillis);
- intent.putExtra(EVENT_END_TIME, endMillis);
- mParentActivity.startActivity(intent);
- } else {
- // Switch to the EventInfo view
- Intent intent = new Intent(Intent.ACTION_VIEW);
- Uri eventUri = ContentUris.withAppendedId(Events.CONTENT_URI,
- selectedEvent.id);
- intent.setData(eventUri);
- intent.setClassName(mContext, EventInfoActivity.class.getName());
- intent.putExtra(EVENT_BEGIN_TIME, selectedEvent.startMillis);
- intent.putExtra(EVENT_END_TIME, selectedEvent.endMillis);
- mParentActivity.startActivity(intent);
- }
- } else {
- // This was a touch selection. If the touch selected a single
- // unambiguous event, then view that event. Otherwise go to
- // Day/Agenda view.
- if (mSelectedEvents.size() == 1) {
- // Switch to the EventInfo view
- Intent intent = new Intent(Intent.ACTION_VIEW);
- Uri eventUri = ContentUris.withAppendedId(Events.CONTENT_URI,
- selectedEvent.id);
- intent.setData(eventUri);
- intent.setClassName(mContext, EventInfoActivity.class.getName());
- intent.putExtra(EVENT_BEGIN_TIME, selectedEvent.startMillis);
- intent.putExtra(EVENT_END_TIME, selectedEvent.endMillis);
- mParentActivity.startActivity(intent);
- } else {
- // Switch to the Day/Agenda view.
- long millis = getSelectedTimeInMillis();
- MenuHelper.switchTo(mParentActivity, mDetailedView, millis);
- mParentActivity.finish();
- }
- }
- } else {
- // This is the Day view.
- // If we selected a free slot, then create an event.
- // If we selected an event, then go to the EventInfo view.
- if (selectedEvent == null) {
- // Switch to the EditEvent view
- long startMillis = getSelectedTimeInMillis();
- long endMillis = startMillis + DateUtils.HOUR_IN_MILLIS;
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setClassName(mContext, EditEvent.class.getName());
- intent.putExtra(EVENT_BEGIN_TIME, startMillis);
- intent.putExtra(EVENT_END_TIME, endMillis);
- mParentActivity.startActivity(intent);
- } else {
- // Switch to the EventInfo view
- Intent intent = new Intent(Intent.ACTION_VIEW);
- Uri eventUri = ContentUris.withAppendedId(Events.CONTENT_URI, selectedEvent.id);
- intent.setData(eventUri);
- intent.setClassName(mContext, EventInfoActivity.class.getName());
- intent.putExtra(EVENT_BEGIN_TIME, selectedEvent.startMillis);
- intent.putExtra(EVENT_END_TIME, selectedEvent.endMillis);
- mParentActivity.startActivity(intent);
- }
- }
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- mScrolling = false;
- long duration = event.getEventTime() - event.getDownTime();
-
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_CENTER:
- if (mSelectionMode == SELECTION_HIDDEN) {
- // Don't do anything unless the selection is visible.
- break;
- }
-
- if (mSelectionMode == SELECTION_PRESSED) {
- // This was the first press when there was nothing selected.
- // Change the selection from the "pressed" state to the
- // the "selected" state. We treat short-press and
- // long-press the same here because nothing was selected.
- mSelectionMode = SELECTION_SELECTED;
- mRedrawScreen = true;
- invalidate();
- break;
- }
-
- // Check the duration to determine if this was a short press
- if (duration < ViewConfiguration.getLongPressTimeout()) {
- switchViews(true /* trackball */);
- } else {
- mSelectionMode = SELECTION_LONGPRESS;
- mRedrawScreen = true;
- invalidate();
- performLongClick();
- }
- break;
- }
- return super.onKeyUp(keyCode, event);
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (mSelectionMode == SELECTION_HIDDEN) {
- if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT
- || keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_UP
- || keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
- // Display the selection box but don't move or select it
- // on this key press.
- mSelectionMode = SELECTION_SELECTED;
- mRedrawScreen = true;
- invalidate();
- return true;
- } else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
- // Display the selection box but don't select it
- // on this key press.
- mSelectionMode = SELECTION_PRESSED;
- mRedrawScreen = true;
- invalidate();
- return true;
- }
- }
-
- mSelectionMode = SELECTION_SELECTED;
- mScrolling = false;
- boolean redraw = false;
- int selectionDay = mSelectionDay;
-
- switch (keyCode) {
- case KeyEvent.KEYCODE_DEL:
- // Delete the selected event, if any
- Event selectedEvent = mSelectedEvent;
- if (selectedEvent == null) {
- return false;
- }
- mPopup.dismiss();
-
- long begin = selectedEvent.startMillis;
- long end = selectedEvent.endMillis;
- long id = selectedEvent.id;
- mDeleteEventHelper.delete(begin, end, id, -1);
- return true;
- case KeyEvent.KEYCODE_ENTER:
- switchViews(true /* trackball or keyboard */);
- return true;
- case KeyEvent.KEYCODE_BACK:
- mPopup.dismiss();
- mParentActivity.finish();
- return true;
- case KeyEvent.KEYCODE_DPAD_LEFT:
- if (mSelectedEvent != null) {
- mSelectedEvent = mSelectedEvent.nextLeft;
- }
- if (mSelectedEvent == null) {
- selectionDay -= 1;
- }
- redraw = true;
- break;
-
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- if (mSelectedEvent != null) {
- mSelectedEvent = mSelectedEvent.nextRight;
- }
- if (mSelectedEvent == null) {
- selectionDay += 1;
- }
- redraw = true;
- break;
-
- case KeyEvent.KEYCODE_DPAD_UP:
- if (mSelectedEvent != null) {
- mSelectedEvent = mSelectedEvent.nextUp;
- }
- if (mSelectedEvent == null) {
- if (!mSelectionAllDay) {
- mSelectionHour -= 1;
- adjustHourSelection();
- mSelectedEvents.clear();
- mComputeSelectedEvents = true;
- }
- }
- redraw = true;
- break;
-
- case KeyEvent.KEYCODE_DPAD_DOWN:
- if (mSelectedEvent != null) {
- mSelectedEvent = mSelectedEvent.nextDown;
- }
- if (mSelectedEvent == null) {
- if (mSelectionAllDay) {
- mSelectionAllDay = false;
- } else {
- mSelectionHour++;
- adjustHourSelection();
- mSelectedEvents.clear();
- mComputeSelectedEvents = true;
- }
- }
- redraw = true;
- break;
-
- default:
- return super.onKeyDown(keyCode, event);
- }
-
- if ((selectionDay < mFirstJulianDay) || (selectionDay > mLastJulianDay)) {
- boolean forward;
- CalendarView view = mParentActivity.getNextView();
- Time date = view.mBaseDate;
- date.set(mBaseDate);
- if (selectionDay < mFirstJulianDay) {
- date.monthDay -= mNumDays;
- forward = false;
- } else {
- date.monthDay += mNumDays;
- forward = true;
- }
- date.normalize(true /* ignore isDst */);
- view.mSelectionDay = selectionDay;
-
- initView(view);
- mTitleTextView.setText(view.mDateRange);
- mParentActivity.switchViews(forward, 0, 0);
- return true;
- }
- mSelectionDay = selectionDay;
- mSelectedEvents.clear();
- mComputeSelectedEvents = true;
-
- if (redraw) {
- mRedrawScreen = true;
- invalidate();
- return true;
- }
-
- return super.onKeyDown(keyCode, event);
- }
-
- // This is called after scrolling stops to move the selected hour
- // to the visible part of the screen.
- private void resetSelectedHour() {
- if (mSelectionHour < mFirstHour + 1) {
- mSelectionHour = mFirstHour + 1;
- mSelectedEvent = null;
- mSelectedEvents.clear();
- mComputeSelectedEvents = true;
- } else if (mSelectionHour > mFirstHour + mNumHours - 3) {
- mSelectionHour = mFirstHour + mNumHours - 3;
- mSelectedEvent = null;
- mSelectedEvents.clear();
- mComputeSelectedEvents = true;
- }
- }
-
- private void initFirstHour() {
- mFirstHour = mSelectionHour - mNumHours / 2;
- if (mFirstHour < 0) {
- mFirstHour = 0;
- } else if (mFirstHour + mNumHours > 24) {
- mFirstHour = 24 - mNumHours;
- }
- }
-
- /**
- * Recomputes the first full hour that is visible on screen after the
- * screen is scrolled.
- */
- private void computeFirstHour() {
- // Compute the first full hour that is visible on screen
- mFirstHour = (mViewStartY + mCellHeight + HOUR_GAP - 1) / (mCellHeight + HOUR_GAP);
- mFirstHourOffset = mFirstHour * (mCellHeight + HOUR_GAP) - mViewStartY;
- }
-
- private void adjustHourSelection() {
- if (mSelectionHour < 0) {
- mSelectionHour = 0;
- if (mMaxAllDayEvents > 0) {
- mPrevSelectedEvent = null;
- mSelectionAllDay = true;
- }
- }
-
- if (mSelectionHour > 23) {
- mSelectionHour = 23;
- }
-
- // If the selected hour is at least 2 time slots from the top and
- // bottom of the screen, then don't scroll the view.
- if (mSelectionHour < mFirstHour + 1) {
- // If there are all-days events for the selected day but there
- // are no more normal events earlier in the day, then jump to
- // the all-day event area.
- // Exception 1: allow the user to scroll to 8am with the trackball
- // before jumping to the all-day event area.
- // Exception 2: if 12am is on screen, then allow the user to select
- // 12am before going up to the all-day event area.
- int daynum = mSelectionDay - mFirstJulianDay;
- if (mMaxAllDayEvents > 0 && mEarliestStartHour[daynum] > mSelectionHour
- && mFirstHour > 0 && mFirstHour < 8) {
- mPrevSelectedEvent = null;
- mSelectionAllDay = true;
- mSelectionHour = mFirstHour + 1;
- return;
- }
-
- if (mFirstHour > 0) {
- mFirstHour -= 1;
- mViewStartY -= (mCellHeight + HOUR_GAP);
- if (mViewStartY < 0) {
- mViewStartY = 0;
- }
- return;
- }
- }
-
- if (mSelectionHour > mFirstHour + mNumHours - 3) {
- if (mFirstHour < 24 - mNumHours) {
- mFirstHour += 1;
- mViewStartY += (mCellHeight + HOUR_GAP);
- if (mViewStartY > mBitmapHeight - mGridAreaHeight) {
- mViewStartY = mBitmapHeight - mGridAreaHeight;
- }
- return;
- } else if (mFirstHour == 24 - mNumHours && mFirstHourOffset > 0) {
- mViewStartY = mBitmapHeight - mGridAreaHeight;
- }
- }
- }
-
- void clearCachedEvents() {
- mLastReloadMillis = 0;
- }
-
- private Runnable mCancelCallback = new Runnable() {
- public void run() {
- clearCachedEvents();
- }
- };
-
- void reloadEvents() {
- // Protect against this being called before this view has been
- // initialized.
- if (mParentActivity == null) {
- return;
- }
-
- mSelectedEvent = null;
- mPrevSelectedEvent = null;
- mSelectedEvents.clear();
-
- // The start date is the beginning of the week at 12am
- Time weekStart = new Time();
- weekStart.set(mBaseDate);
- weekStart.hour = 0;
- weekStart.minute = 0;
- weekStart.second = 0;
- long millis = weekStart.normalize(true /* ignore isDst */);
-
- // Avoid reloading events unnecessarily.
- if (millis == mLastReloadMillis) {
- return;
- }
- mLastReloadMillis = millis;
-
- // load events in the background
- mParentActivity.startProgressSpinner();
- final ArrayList<Event> events = new ArrayList<Event>();
- mEventLoader.loadEventsInBackground(mNumDays, events, millis, new Runnable() {
- public void run() {
- mEvents = events;
- mRemeasure = true;
- mRedrawScreen = true;
- mComputeSelectedEvents = true;
- recalc();
- mParentActivity.stopProgressSpinner();
- invalidate();
- }
- }, mCancelCallback);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- if (mRemeasure) {
- remeasure(getWidth(), getHeight());
- mRemeasure = false;
- }
-
- if (mRedrawScreen && mCanvas != null) {
- doDraw(mCanvas);
- mRedrawScreen = false;
- }
-
- if ((mTouchMode & TOUCH_MODE_HSCROLL) != 0) {
- canvas.save();
- if (mViewStartX > 0) {
- canvas.translate(mViewWidth - mViewStartX, 0);
- } else {
- canvas.translate(-(mViewWidth + mViewStartX), 0);
- }
- CalendarView nextView = mParentActivity.getNextView();
-
- // Prevent infinite recursive calls to onDraw().
- nextView.mTouchMode = TOUCH_MODE_INITIAL_STATE;
-
- nextView.onDraw(canvas);
- canvas.restore();
- canvas.save();
- canvas.translate(-mViewStartX, 0);
- }
-
- if (mBitmap != null) {
- drawCalendarView(canvas);
- }
-
- // Draw the fixed areas (that don't scroll) directly to the canvas.
- drawAfterScroll(canvas);
- mComputeSelectedEvents = false;
-
- if ((mTouchMode & TOUCH_MODE_HSCROLL) != 0) {
- canvas.restore();
- }
- }
-
- private void drawCalendarView(Canvas canvas) {
-
- // Copy the scrollable region from the big bitmap to the canvas.
- Rect src = mSrcRect;
- Rect dest = mDestRect;
-
- src.top = mViewStartY;
- src.bottom = mViewStartY + mGridAreaHeight;
- src.left = 0;
- src.right = mViewWidth;
-
- dest.top = mFirstCell;
- dest.bottom = mViewHeight;
- dest.left = 0;
- dest.right = mViewWidth;
- canvas.save();
- canvas.clipRect(dest);
- canvas.drawColor(0, PorterDuff.Mode.CLEAR);
- canvas.drawBitmap(mBitmap, src, dest, null);
- canvas.restore();
- }
-
- private void drawAfterScroll(Canvas canvas) {
- Paint p = mPaint;
- Rect r = mRect;
-
- if (mMaxAllDayEvents != 0) {
- drawAllDayEvents(mFirstJulianDay, mNumDays, r, canvas, p);
- drawUpperLeftCorner(r, canvas, p);
- }
-
- if (mNumDays > 1) {
- drawDayHeaderLoop(r, canvas, p);
- }
-
- // Draw the AM and PM indicators if we're in 12 hour mode
- if (!mIs24HourFormat) {
- drawAmPm(canvas, p);
- }
-
- // Update the popup window showing the event details, but only if
- // we are not scrolling and we have focus.
- if (!mScrolling && isFocused()) {
- updateEventDetails();
- }
- }
-
- // This isn't really the upper-left corner. It's the square area just
- // below the upper-left corner, above the hours and to the left of the
- // all-day area.
- private void drawUpperLeftCorner(Rect r, Canvas canvas, Paint p) {
- p.setColor(mResources.getColor(R.color.calendar_hour_background));
- r.top = mBannerPlusMargin;
- r.bottom = r.top + mAllDayHeight + ALLDAY_TOP_MARGIN;
- r.left = 0;
- r.right = mHoursWidth;
- canvas.drawRect(r, p);
- }
-
- private void drawDayHeaderLoop(Rect r, Canvas canvas, Paint p) {
- // Draw the horizontal day background banner
- p.setColor(mResources.getColor(R.color.calendar_date_banner_background));
- r.top = 0;
- r.bottom = mBannerPlusMargin;
- r.left = 0;
- r.right = mHoursWidth + mNumDays * (mCellWidth + DAY_GAP);
- canvas.drawRect(r, p);
-
- // Fill the extra space on the right side with the default background
- r.left = r.right;
- r.right = mViewWidth;
- p.setColor(mResources.getColor(R.color.calendar_grid_area_background));
- canvas.drawRect(r, p);
-
- // Draw a highlight on the selected day (if any), but only if we are
- // displaying more than one day.
- if (mSelectionMode != SELECTION_HIDDEN) {
- if (mNumDays > 1) {
- p.setColor(mResources.getColor(R.color.calendar_date_selected));
- r.top = 0;
- r.bottom = mBannerPlusMargin;
- int daynum = mSelectionDay - mFirstJulianDay;
- r.left = mHoursWidth + daynum * (mCellWidth + DAY_GAP);
- r.right = r.left + mCellWidth;
- canvas.drawRect(r, p);
- }
- }
-
- p.setTextSize(NORMAL_FONT_SIZE);
- p.setTextAlign(Paint.Align.CENTER);
- int x = mHoursWidth;
- int deltaX = mCellWidth + DAY_GAP;
- int cell = mFirstJulianDay;
-
- String[] dayNames;
- if (mDateStrWidth < mCellWidth) {
- dayNames = mDayStrs;
- } else {
- dayNames = mDayStrs2Letter;
- }
-
- for (int day = 0; day < mNumDays; day++, cell++) {
- drawDayHeader(dayNames[day + mStartDay], day, cell, x, canvas, p);
- x += deltaX;
- }
- }
-
- private void drawAmPm(Canvas canvas, Paint p) {
- p.setColor(mResources.getColor(R.color.calendar_ampm_label));
- p.setTextSize(AMPM_FONT_SIZE);
- p.setTypeface(mBold);
- p.setAntiAlias(true);
- mPaint.setTextAlign(Paint.Align.RIGHT);
- String text = mAmString;
- if (mFirstHour >= 12) {
- text = mPmString;
- }
- int y = mFirstCell + mFirstHourOffset + 2 * mHoursTextHeight + HOUR_GAP;
- int right = mHoursWidth - HOURS_RIGHT_MARGIN;
- canvas.drawText(text, right, y, p);
-
- if (mFirstHour < 12 && mFirstHour + mNumHours > 12) {
- // Also draw the "PM"
- text = mPmString;
- y = mFirstCell + mFirstHourOffset + (12 - mFirstHour) * (mCellHeight + HOUR_GAP)
- + 2 * mHoursTextHeight + HOUR_GAP;
- canvas.drawText(text, right, y, p);
- }
- }
-
- private void doDraw(Canvas canvas) {
- Paint p = mPaint;
- Rect r = mRect;
-
- drawGridBackground(r, canvas, p);
- drawHours(r, canvas, p);
-
- // Draw each day
- int x = mHoursWidth;
- int deltaX = mCellWidth + DAY_GAP;
- int cell = mFirstJulianDay;
- for (int day = 0; day < mNumDays; day++, cell++) {
- drawEvents(cell, x, HOUR_GAP, canvas, p);
- x += deltaX;
- }
- }
-
- private void drawHours(Rect r, Canvas canvas, Paint p) {
- // Draw the background for the hour labels
- p.setColor(mResources.getColor(R.color.calendar_hour_background));
- r.top = 0;
- r.bottom = 24 * (mCellHeight + HOUR_GAP) + HOUR_GAP;
- r.left = 0;
- r.right = mHoursWidth;
- canvas.drawRect(r, p);
-
- // Fill the bottom left corner with the default grid background
- r.top = r.bottom;
- r.bottom = mBitmapHeight;
- p.setColor(mResources.getColor(R.color.calendar_grid_area_background));
- canvas.drawRect(r, p);
-
- // Draw a highlight on the selected hour (if needed)
- if (mSelectionMode != SELECTION_HIDDEN && !mSelectionAllDay) {
- p.setColor(mResources.getColor(R.color.calendar_hour_selected));
- r.top = mSelectionHour * (mCellHeight + HOUR_GAP);
- r.bottom = r.top + mCellHeight + 2 * HOUR_GAP;
- r.left = 0;
- r.right = mHoursWidth;
- canvas.drawRect(r, p);
-
- // Also draw the highlight on the grid
- p.setColor(mResources.getColor(R.color.calendar_grid_area_selected));
- int daynum = mSelectionDay - mFirstJulianDay;
- r.left = mHoursWidth + daynum * (mCellWidth + DAY_GAP);
- r.right = r.left + mCellWidth;
- canvas.drawRect(r, p);
-
- // Draw a border around the highlighted grid hour.
- Path path = mPath;
- r.top += HOUR_GAP;
- r.bottom -= HOUR_GAP;
- path.reset();
- path.addRect(r.left, r.top, r.right, r.bottom, Direction.CW);
- canvas.drawPath(path, mSelectionPaint);
- saveSelectionPosition(r.left, r.top, r.right, r.bottom);
- }
-
- p.setColor(mResources.getColor(R.color.calendar_hour_label));
- p.setTextSize(HOURS_FONT_SIZE);
- p.setTypeface(mBold);
- p.setTextAlign(Paint.Align.RIGHT);
- p.setAntiAlias(true);
-
- int right = mHoursWidth - HOURS_RIGHT_MARGIN;
- int y = HOUR_GAP + mHoursTextHeight;
-
- for (int i = 0; i < 24; i++) {
- String time = mHourStrs[i];
- canvas.drawText(time, right, y, p);
- y += mCellHeight + HOUR_GAP;
- }
- }
-
- private void drawDayHeader(String dateStr, int day, int cell, int x, Canvas canvas, Paint p) {
- float xCenter = x + mCellWidth / 2.0f;
-
- p.setTypeface(mBold);
- p.setAntiAlias(true);
-
- boolean isWeekend = false;
- if ((mStartDay == Time.SUNDAY && (day == 0 || day == 6))
- || (mStartDay == Time.MONDAY && (day == 5 || day == 6))
- || (mStartDay == Time.SATURDAY && (day == 0 || day == 1))) {
- isWeekend = true;
- }
-
- if (isWeekend) {
- p.setColor(mResources.getColor(R.color.week_weekend));
- } else {
- p.setColor(mResources.getColor(R.color.calendar_date_banner_text_color));
- }
-
- int dateNum = mFirstDate + day;
- if (dateNum > mMonthLength) {
- dateNum -= mMonthLength;
- }
-
- // Add a leading zero if the date is a single digit
- if (dateNum < 10) {
- dateStr += " 0" + dateNum;
- } else {
- dateStr += " " + dateNum;
- }
-
- float y = mBannerPlusMargin - 7;
- canvas.drawText(dateStr, xCenter, y, p);
- }
-
- private void drawGridBackground(Rect r, Canvas canvas, Paint p) {
- Paint.Style savedStyle = p.getStyle();
-
- // Clear the background
- p.setColor(mResources.getColor(R.color.calendar_grid_area_background));
- r.top = 0;
- r.bottom = mBitmapHeight;
- r.left = 0;
- r.right = mViewWidth;
- canvas.drawRect(r, p);
-
- // Draw the horizontal grid lines
- p.setColor(mResources.getColor(R.color.calendar_grid_line_horizontal_color));
- p.setStyle(Style.STROKE);
- p.setStrokeWidth(0);
- p.setAntiAlias(false);
- float startX = mHoursWidth;
- float stopX = mHoursWidth + (mCellWidth + DAY_GAP) * mNumDays;
- float y = 0;
- float deltaY = mCellHeight + HOUR_GAP;
- for (int hour = 0; hour <= 24; hour++) {
- canvas.drawLine(startX, y, stopX, y, p);
- y += deltaY;
- }
-
- // Draw the vertical grid lines
- p.setColor(mResources.getColor(R.color.calendar_grid_line_vertical_color));
- float startY = 0;
- float stopY = HOUR_GAP + 24 * (mCellHeight + HOUR_GAP);
- float deltaX = mCellWidth + DAY_GAP;
- float x = mHoursWidth + mCellWidth;
- for (int day = 0; day < mNumDays; day++) {
- canvas.drawLine(x, startY, x, stopY, p);
- x += deltaX;
- }
-
- // Restore the saved style.
- p.setStyle(savedStyle);
- p.setAntiAlias(true);
- }
-
- Event getSelectedEvent() {
- if (mSelectedEvent == null) {
- // There is no event at the selected hour, so create a new event.
- return getNewEvent(mSelectionDay, getSelectedTimeInMillis(),
- getSelectedMinutesSinceMidnight());
- }
- return mSelectedEvent;
- }
-
- boolean isEventSelected() {
- return (mSelectedEvent != null);
- }
-
- Event getNewEvent() {
- return getNewEvent(mSelectionDay, getSelectedTimeInMillis(),
- getSelectedMinutesSinceMidnight());
- }
-
- static Event getNewEvent(int julianDay, long utcMillis,
- int minutesSinceMidnight) {
- Event event = Event.newInstance();
- event.startDay = julianDay;
- event.endDay = julianDay;
- event.startMillis = utcMillis;
- event.endMillis = event.startMillis + MILLIS_PER_HOUR;
- event.startTime = minutesSinceMidnight;
- event.endTime = event.startTime + MINUTES_PER_HOUR;
- return event;
- }
-
- private int computeMaxStringWidth(int currentMax, String[] strings, Paint p) {
- float maxWidthF = 0.0f;
-
- int len = strings.length;
- for (int i = 0; i < len; i++) {
- float width = p.measureText(strings[i]);
- maxWidthF = Math.max(width, maxWidthF);
- }
- int maxWidth = (int) (maxWidthF + 0.5);
- if (maxWidth < currentMax) {
- maxWidth = currentMax;
- }
- return maxWidth;
- }
-
- private void saveSelectionPosition(float left, float top, float right, float bottom) {
- mPrevBox.left = (int) left;
- mPrevBox.right = (int) right;
- mPrevBox.top = (int) top;
- mPrevBox.bottom = (int) bottom;
- }
-
- private Rect getCurrentSelectionPosition() {
- Rect box = new Rect();
- box.top = mSelectionHour * (mCellHeight + HOUR_GAP);
- box.bottom = box.top + mCellHeight + HOUR_GAP;
- int daynum = mSelectionDay - mFirstJulianDay;
- box.left = mHoursWidth + daynum * (mCellWidth + DAY_GAP);
- box.right = box.left + mCellWidth + DAY_GAP;
- return box;
- }
-
- private void drawAllDayEvents(int firstDay, int numDays,
- Rect r, Canvas canvas, Paint p) {
- p.setTextSize(NORMAL_FONT_SIZE);
- p.setTextAlign(Paint.Align.LEFT);
- Paint eventTextPaint = mEventTextPaint;
-
- // Draw the background for the all-day events area
- r.top = mBannerPlusMargin;
- r.bottom = r.top + mAllDayHeight + ALLDAY_TOP_MARGIN;
- r.left = mHoursWidth;
- r.right = r.left + mNumDays * (mCellWidth + DAY_GAP);
- p.setColor(mResources.getColor(R.color.calendar_all_day_background));
- canvas.drawRect(r, p);
-
- // Fill the extra space on the right side with the default background
- r.left = r.right;
- r.right = mViewWidth;
- p.setColor(mResources.getColor(R.color.calendar_grid_area_background));
- canvas.drawRect(r, p);
-
- // Draw the vertical grid lines
- p.setColor(mResources.getColor(R.color.calendar_grid_line_vertical_color));
- p.setStyle(Style.STROKE);
- p.setStrokeWidth(0);
- p.setAntiAlias(false);
- float startY = r.top;
- float stopY = r.bottom;
- float deltaX = mCellWidth + DAY_GAP;
- float x = mHoursWidth + mCellWidth;
- for (int day = 0; day <= mNumDays; day++) {
- canvas.drawLine(x, startY, x, stopY, p);
- x += deltaX;
- }
- p.setAntiAlias(true);
- p.setStyle(Style.FILL);
-
- int y = mBannerPlusMargin + ALLDAY_TOP_MARGIN;
- float left = mHoursWidth;
- int lastDay = firstDay + numDays - 1;
- ArrayList<Event> events = mEvents;
- int numEvents = events.size();
- float drawHeight = mAllDayHeight;
- float numRectangles = mMaxAllDayEvents;
- for (int i = 0; i < numEvents; i++) {
- Event event = events.get(i);
- if (!event.allDay)
- continue;
- int startDay = event.startDay;
- int endDay = event.endDay;
- if (startDay > lastDay || endDay < firstDay)
- continue;
- if (startDay < firstDay)
- startDay = firstDay;
- if (endDay > lastDay)
- endDay = lastDay;
- int startIndex = startDay - firstDay;
- int endIndex = endDay - firstDay;
- float height = drawHeight / numRectangles;
-
- // Prevent a single event from getting too big
- if (height > MAX_ALLDAY_EVENT_HEIGHT) {
- height = MAX_ALLDAY_EVENT_HEIGHT;
- }
-
- // Leave a one-pixel space between the vertical day lines and the
- // event rectangle.
- event.left = left + startIndex * (mCellWidth + DAY_GAP) + 2;
- event.right = left + endIndex * (mCellWidth + DAY_GAP) + mCellWidth - 1;
- event.top = y + height * event.getColumn();
-
- // Multiply the height by 0.9 to leave a little gap between events
- event.bottom = event.top + height * 0.9f;
-
- RectF rf = drawAllDayEventRect(event, canvas, p, eventTextPaint);
- drawEventText(event, rf, canvas, eventTextPaint, ALL_DAY_TEXT_TOP_MARGIN);
-
- // Check if this all-day event intersects the selected day
- if (mSelectionAllDay && mComputeSelectedEvents) {
- if (startDay <= mSelectionDay && endDay >= mSelectionDay) {
- mSelectedEvents.add(event);
- }
- }
- }
-
- if (mSelectionAllDay) {
- // Compute the neighbors for the list of all-day events that
- // intersect the selected day.
- computeAllDayNeighbors();
- if (mSelectedEvent != null) {
- Event event = mSelectedEvent;
- RectF rf = drawAllDayEventRect(event, canvas, p, eventTextPaint);
- drawEventText(event, rf, canvas, eventTextPaint, ALL_DAY_TEXT_TOP_MARGIN);
- }
-
- // Draw the highlight on the selected all-day area
- float top = mBannerPlusMargin + 1;
- float bottom = top + mAllDayHeight + ALLDAY_TOP_MARGIN - 1;
- int daynum = mSelectionDay - mFirstJulianDay;
- left = mHoursWidth + daynum * (mCellWidth + DAY_GAP) + 1;
- float right = left + mCellWidth + DAY_GAP - 1;
- if (mNumDays == 1) {
- // The Day view doesn't have a vertical line on the right.
- right -= 1;
- }
- Path path = mPath;
- path.reset();
- path.addRect(left, top, right, bottom, Direction.CW);
- canvas.drawPath(path, mSelectionPaint);
-
- // Set the selection position to zero so that when we move down
- // to the normal event area, we will highlight the topmost event.
- saveSelectionPosition(0f, 0f, 0f, 0f);
- }
- }
-
- private void computeAllDayNeighbors() {
- int len = mSelectedEvents.size();
- if (len == 0 || mSelectedEvent != null) {
- return;
- }
-
- // First, clear all the links
- for (int ii = 0; ii < len; ii++) {
- Event ev = mSelectedEvents.get(ii);
- ev.nextUp = null;
- ev.nextDown = null;
- ev.nextLeft = null;
- ev.nextRight = null;
- }
-
- // For each event in the selected event list "mSelectedEvents", find
- // its neighbors in the up and down directions. This could be done
- // more efficiently by sorting on the Event.getColumn() field, but
- // the list is expected to be very small.
-
- // Find the event in the same row as the previously selected all-day
- // event, if any.
- int startPosition = -1;
- if (mPrevSelectedEvent != null && mPrevSelectedEvent.allDay) {
- startPosition = mPrevSelectedEvent.getColumn();
- }
- int maxPosition = -1;
- Event startEvent = null;
- Event maxPositionEvent = null;
- for (int ii = 0; ii < len; ii++) {
- Event ev = mSelectedEvents.get(ii);
- int position = ev.getColumn();
- if (position == startPosition) {
- startEvent = ev;
- } else if (position > maxPosition) {
- maxPositionEvent = ev;
- maxPosition = position;
- }
- for (int jj = 0; jj < len; jj++) {
- if (jj == ii) {
- continue;
- }
- Event neighbor = mSelectedEvents.get(jj);
- int neighborPosition = neighbor.getColumn();
- if (neighborPosition == position - 1) {
- ev.nextUp = neighbor;
- } else if (neighborPosition == position + 1) {
- ev.nextDown = neighbor;
- }
- }
- }
- if (startEvent != null) {
- mSelectedEvent = startEvent;
- } else {
- mSelectedEvent = maxPositionEvent;
- }
- }
-
- RectF drawAllDayEventRect(Event event, Canvas canvas, Paint p, Paint eventTextPaint) {
- // If this event is selected, then use the selection color
- if (mSelectedEvent == event) {
- // Also, remember the last selected event that we drew
- mPrevSelectedEvent = event;
- p.setColor(mSelectionColor);
- eventTextPaint.setColor(mSelectedEventTextColor);
- } else {
- // Use the normal color for all-day events
- p.setColor(event.color);
- eventTextPaint.setColor(mEventTextColor);
- }
-
- RectF rf = mRectF;
- rf.top = event.top;
- rf.bottom = event.bottom;
- rf.left = event.left;
- rf.right = event.right;
- canvas.drawRoundRect(rf, SMALL_ROUND_RADIUS, SMALL_ROUND_RADIUS, p);
-
- rf.left += 2;
- rf.right -= 2;
- return rf;
- }
-
- private void drawEvents(int date, int left, int top, Canvas canvas, Paint p) {
- Paint eventTextPaint = mEventTextPaint;
- int cellWidth = mCellWidth;
- int cellHeight = mCellHeight;
-
- // Use the selected hour as the selection region
- Rect selectionArea = mRect;
- selectionArea.top = top + mSelectionHour * (cellHeight + HOUR_GAP);
- selectionArea.bottom = selectionArea.top + cellHeight;
- selectionArea.left = left;
- selectionArea.right = selectionArea.left + cellWidth;
-
- ArrayList<Event> events = mEvents;
- int numEvents = events.size();
- EventGeometry geometry = mEventGeometry;
-
- for (int i = 0; i < numEvents; i++) {
- Event event = events.get(i);
- if (!geometry.computeEventRect(date, left, top, cellWidth, event)) {
- continue;
- }
-
- if (date == mSelectionDay && !mSelectionAllDay && mComputeSelectedEvents
- && geometry.eventIntersectsSelection(event, selectionArea)) {
- mSelectedEvents.add(event);
- }
-
- RectF rf = drawEventRect(event, canvas, p, eventTextPaint);
- drawEventText(event, rf, canvas, eventTextPaint, NORMAL_TEXT_TOP_MARGIN);
- }
-
- if (date == mSelectionDay && !mSelectionAllDay && isFocused()
- && mSelectionMode != SELECTION_HIDDEN) {
- computeNeighbors();
- if (mSelectedEvent != null) {
- RectF rf = drawEventRect(mSelectedEvent, canvas, p, eventTextPaint);
- drawEventText(mSelectedEvent, rf, canvas, eventTextPaint, NORMAL_TEXT_TOP_MARGIN);
- }
- }
- }
-
- // Computes the "nearest" neighbor event in four directions (left, right,
- // up, down) for each of the events in the mSelectedEvents array.
- private void computeNeighbors() {
- int len = mSelectedEvents.size();
- if (len == 0 || mSelectedEvent != null) {
- return;
- }
-
- // First, clear all the links
- for (int ii = 0; ii < len; ii++) {
- Event ev = mSelectedEvents.get(ii);
- ev.nextUp = null;
- ev.nextDown = null;
- ev.nextLeft = null;
- ev.nextRight = null;
- }
-
- Event startEvent = mSelectedEvents.get(0);
- int startEventDistance1 = 100000; // any large number
- int startEventDistance2 = 100000; // any large number
- int prevLocation = FROM_NONE;
- int prevTop = 0;
- int prevBottom = 0;
- int prevLeft = 0;
- int prevRight = 0;
- int prevCenter = 0;
- Rect box = getCurrentSelectionPosition();
- if (mPrevSelectedEvent != null) {
- prevTop = (int) mPrevSelectedEvent.top;
- prevBottom = (int) mPrevSelectedEvent.bottom;
- prevLeft = (int) mPrevSelectedEvent.left;
- prevRight = (int) mPrevSelectedEvent.right;
- // Check if the previously selected event intersects the previous
- // selection box. (The previously selected event may be from a
- // much older selection box.)
- if (prevTop >= mPrevBox.bottom || prevBottom <= mPrevBox.top
- || prevRight <= mPrevBox.left || prevLeft >= mPrevBox.right) {
- mPrevSelectedEvent = null;
- prevTop = mPrevBox.top;
- prevBottom = mPrevBox.bottom;
- prevLeft = mPrevBox.left;
- prevRight = mPrevBox.right;
- } else {
- // Clip the top and bottom to the previous selection box.
- if (prevTop < mPrevBox.top) {
- prevTop = mPrevBox.top;
- }
- if (prevBottom > mPrevBox.bottom) {
- prevBottom = mPrevBox.bottom;
- }
- }
- } else {
- // Just use the previously drawn selection box
- prevTop = mPrevBox.top;
- prevBottom = mPrevBox.bottom;
- prevLeft = mPrevBox.left;
- prevRight = mPrevBox.right;
- }
-
- // Figure out where we came from and compute the center of that area.
- if (prevLeft >= box.right) {
- // The previously selected event was to the right of us.
- prevLocation = FROM_RIGHT;
- prevCenter = (prevTop + prevBottom) / 2;
- } else if (prevRight <= box.left) {
- // The previously selected event was to the left of us.
- prevLocation = FROM_LEFT;
- prevCenter = (prevTop + prevBottom) / 2;
- } else if (prevBottom <= box.top) {
- // The previously selected event was above us.
- prevLocation = FROM_ABOVE;
- prevCenter = (prevLeft + prevRight) / 2;
- } else if (prevTop >= box.bottom) {
- // The previously selected event was below us.
- prevLocation = FROM_BELOW;
- prevCenter = (prevLeft + prevRight) / 2;
- }
-
- // For each event in the selected event list "mSelectedEvents", search
- // all the other events in that list for the nearest neighbor in 4
- // directions.
- for (int ii = 0; ii < len; ii++) {
- Event ev = mSelectedEvents.get(ii);
-
- int startTime = ev.startTime;
- int endTime = ev.endTime;
- int left = (int) ev.left;
- int right = (int) ev.right;
- int top = (int) ev.top;
- if (top < box.top) {
- top = box.top;
- }
- int bottom = (int) ev.bottom;
- if (bottom > box.bottom) {
- bottom = box.bottom;
- }
- if (false) {
- int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL
- | DateUtils.FORMAT_CAP_NOON_MIDNIGHT;
- if (DateFormat.is24HourFormat(mContext)) {
- flags |= DateUtils.FORMAT_24HOUR;
- }
- String timeRange = DateUtils.formatDateRange(mParentActivity,
- ev.startMillis, ev.endMillis, flags);
- Log.i("Cal", "left: " + left + " right: " + right + " top: " + top
- + " bottom: " + bottom + " ev: " + timeRange + " " + ev.title);
- }
- int upDistanceMin = 10000; // any large number
- int downDistanceMin = 10000; // any large number
- int leftDistanceMin = 10000; // any large number
- int rightDistanceMin = 10000; // any large number
- Event upEvent = null;
- Event downEvent = null;
- Event leftEvent = null;
- Event rightEvent = null;
-
- // Pick the starting event closest to the previously selected event,
- // if any. distance1 takes precedence over distance2.
- int distance1 = 0;
- int distance2 = 0;
- if (prevLocation == FROM_ABOVE) {
- if (left >= prevCenter) {
- distance1 = left - prevCenter;
- } else if (right <= prevCenter) {
- distance1 = prevCenter - right;
- }
- distance2 = top - prevBottom;
- } else if (prevLocation == FROM_BELOW) {
- if (left >= prevCenter) {
- distance1 = left - prevCenter;
- } else if (right <= prevCenter) {
- distance1 = prevCenter - right;
- }
- distance2 = prevTop - bottom;
- } else if (prevLocation == FROM_LEFT) {
- if (bottom <= prevCenter) {
- distance1 = prevCenter - bottom;
- } else if (top >= prevCenter) {
- distance1 = top - prevCenter;
- }
- distance2 = left - prevRight;
- } else if (prevLocation == FROM_RIGHT) {
- if (bottom <= prevCenter) {
- distance1 = prevCenter - bottom;
- } else if (top >= prevCenter) {
- distance1 = top - prevCenter;
- }
- distance2 = prevLeft - right;
- }
- if (distance1 < startEventDistance1
- || (distance1 == startEventDistance1 && distance2 < startEventDistance2)) {
- startEvent = ev;
- startEventDistance1 = distance1;
- startEventDistance2 = distance2;
- }
-
- // For each neighbor, figure out if it is above or below or left
- // or right of me and compute the distance.
- for (int jj = 0; jj < len; jj++) {
- if (jj == ii) {
- continue;
- }
- Event neighbor = mSelectedEvents.get(jj);
- int neighborLeft = (int) neighbor.left;
- int neighborRight = (int) neighbor.right;
- if (neighbor.endTime <= startTime) {
- // This neighbor is entirely above me.
- // If we overlap the same column, then compute the distance.
- if (neighborLeft < right && neighborRight > left) {
- int distance = startTime - neighbor.endTime;
- if (distance < upDistanceMin) {
- upDistanceMin = distance;
- upEvent = neighbor;
- } else if (distance == upDistanceMin) {
- int center = (left + right) / 2;
- int currentDistance = 0;
- int currentLeft = (int) upEvent.left;
- int currentRight = (int) upEvent.right;
- if (currentRight <= center) {
- currentDistance = center - currentRight;
- } else if (currentLeft >= center) {
- currentDistance = currentLeft - center;
- }
-
- int neighborDistance = 0;
- if (neighborRight <= center) {
- neighborDistance = center - neighborRight;
- } else if (neighborLeft >= center) {
- neighborDistance = neighborLeft - center;
- }
- if (neighborDistance < currentDistance) {
- upDistanceMin = distance;
- upEvent = neighbor;
- }
- }
- }
- } else if (neighbor.startTime >= endTime) {
- // This neighbor is entirely below me.
- // If we overlap the same column, then compute the distance.
- if (neighborLeft < right && neighborRight > left) {
- int distance = neighbor.startTime - endTime;
- if (distance < downDistanceMin) {
- downDistanceMin = distance;
- downEvent = neighbor;
- } else if (distance == downDistanceMin) {
- int center = (left + right) / 2;
- int currentDistance = 0;
- int currentLeft = (int) downEvent.left;
- int currentRight = (int) downEvent.right;
- if (currentRight <= center) {
- currentDistance = center - currentRight;
- } else if (currentLeft >= center) {
- currentDistance = currentLeft - center;
- }
-
- int neighborDistance = 0;
- if (neighborRight <= center) {
- neighborDistance = center - neighborRight;
- } else if (neighborLeft >= center) {
- neighborDistance = neighborLeft - center;
- }
- if (neighborDistance < currentDistance) {
- downDistanceMin = distance;
- downEvent = neighbor;
- }
- }
- }
- }
-
- if (neighborLeft >= right) {
- // This neighbor is entirely to the right of me.
- // Take the closest neighbor in the y direction.
- int center = (top + bottom) / 2;
- int distance = 0;
- int neighborBottom = (int) neighbor.bottom;
- int neighborTop = (int) neighbor.top;
- if (neighborBottom <= center) {
- distance = center - neighborBottom;
- } else if (neighborTop >= center) {
- distance = neighborTop - center;
- }
- if (distance < rightDistanceMin) {
- rightDistanceMin = distance;
- rightEvent = neighbor;
- } else if (distance == rightDistanceMin) {
- // Pick the closest in the x direction
- int neighborDistance = neighborLeft - right;
- int currentDistance = (int) rightEvent.left - right;
- if (neighborDistance < currentDistance) {
- rightDistanceMin = distance;
- rightEvent = neighbor;
- }
- }
- } else if (neighborRight <= left) {
- // This neighbor is entirely to the left of me.
- // Take the closest neighbor in the y direction.
- int center = (top + bottom) / 2;
- int distance = 0;
- int neighborBottom = (int) neighbor.bottom;
- int neighborTop = (int) neighbor.top;
- if (neighborBottom <= center) {
- distance = center - neighborBottom;
- } else if (neighborTop >= center) {
- distance = neighborTop - center;
- }
- if (distance < leftDistanceMin) {
- leftDistanceMin = distance;
- leftEvent = neighbor;
- } else if (distance == leftDistanceMin) {
- // Pick the closest in the x direction
- int neighborDistance = left - neighborRight;
- int currentDistance = left - (int) leftEvent.right;
- if (neighborDistance < currentDistance) {
- leftDistanceMin = distance;
- leftEvent = neighbor;
- }
- }
- }
- }
- ev.nextUp = upEvent;
- ev.nextDown = downEvent;
- ev.nextLeft = leftEvent;
- ev.nextRight = rightEvent;
- }
- mSelectedEvent = startEvent;
- }
-
-
- private RectF drawEventRect(Event event, Canvas canvas, Paint p, Paint eventTextPaint) {
-
- int color = event.color;
-
- // Fade visible boxes if event was declined.
- boolean declined = (event.selfAttendeeStatus == Attendees.ATTENDEE_STATUS_DECLINED);
- if (declined) {
- int alpha = color & 0xff000000;
- color &= 0x00ffffff;
- int red = (color & 0x00ff0000) >> 16;
- int green = (color & 0x0000ff00) >> 8;
- int blue = (color & 0x0000ff);
- color = ((red >> 1) << 16) | ((green >> 1) << 8) | (blue >> 1);
- color += 0x7F7F7F + alpha;
- }
-
- // If this event is selected, then use the selection color
- if (mSelectedEvent == event) {
- if (mSelectionMode == SELECTION_PRESSED) {
- // Also, remember the last selected event that we drew
- mPrevSelectedEvent = event;
- // box = mBoxPressed;
- p.setColor(mPressedColor); // FIXME:pressed
- eventTextPaint.setColor(this.mSelectedEventTextColor);
- } else if (mSelectionMode == SELECTION_SELECTED) {
- // Also, remember the last selected event that we drew
- mPrevSelectedEvent = event;
- // box = mBoxSelected;
- p.setColor(mSelectionColor);
- eventTextPaint.setColor(this.mSelectedEventTextColor);
- } else if (mSelectionMode == SELECTION_LONGPRESS) {
- // box = mBoxLongPressed;
- p.setColor(mPressedColor); // FIXME: longpressed (maybe -- this doesn't seem to work)
- eventTextPaint.setColor(this.mSelectedEventTextColor);
- } else {
- p.setColor(color);
- eventTextPaint.setColor(mEventTextColor);
- }
- } else {
- p.setColor(color);
- eventTextPaint.setColor(mEventTextColor);
- }
-
-
- RectF rf = mRectF;
- rf.top = event.top;
- rf.bottom = event.bottom;
- rf.left = event.left;
- rf.right = event.right - 1;
-
- canvas.drawRoundRect(rf, SMALL_ROUND_RADIUS, SMALL_ROUND_RADIUS, p);
-
- rf.left += 2;
- rf.right -= 2;
-
- return rf;
- }
-
- private void drawEventText(Event event, RectF rf, Canvas canvas, Paint p, int topMargin) {
- if (mDrawTextInEventRect == false) {
- return;
- }
-
- float width = rf.right - rf.left;
- float height = rf.bottom - rf.top;
-
- // Leave one pixel extra space between lines
- int lineHeight = mEventTextHeight + 1;
-
- // If the rectangle is too small for text, then return
- if (width < MIN_CELL_WIDTH_FOR_TEXT || height <= lineHeight) {
- return;
- }
-
- // Truncate the event title to a known (large enough) limit
- String text = event.getTitleAndLocation();
- int len = text.length();
- if (len > MAX_EVENT_TEXT_LEN) {
- text = text.substring(0, MAX_EVENT_TEXT_LEN);
- len = MAX_EVENT_TEXT_LEN;
- }
-
- // Figure out how much space the event title will take, and create a
- // String fragment that will fit in the rectangle. Use multiple lines,
- // if available.
- p.getTextWidths(text, mCharWidths);
- String fragment = text;
- float top = rf.top + mEventTextAscent + topMargin;
- int start = 0;
-
- // Leave one pixel extra space at the bottom
- while (start < len && height >= (lineHeight + 1)) {
- boolean lastLine = (height < 2 * lineHeight + 1);
- // Skip leading spaces at the beginning of each line
- do {
- char c = text.charAt(start);
- if (c != ' ') break;
- start += 1;
- } while (start < len);
-
- float sum = 0;
- int end = start;
- for (int ii = start; ii < len; ii++) {
- char c = text.charAt(ii);
-
- // If we found the end of a word, then remember the ending
- // position.
- if (c == ' ') {
- end = ii;
- }
- sum += mCharWidths[ii];
- // If adding this character would exceed the width and this
- // isn't the last line, then break the line at the previous
- // word. If there was no previous word, then break this word.
- if (sum > width) {
- if (end > start && !lastLine) {
- // There was a previous word on this line.
- fragment = text.substring(start, end);
- start = end;
- break;
- }
-
- // This is the only word and it is too long to fit on
- // the line (or this is the last line), so take as many
- // characters of this word as will fit.
- fragment = text.substring(start, ii);
- start = ii;
- break;
- }
- }
-
- // If sum <= width, then we can fit the rest of the text on
- // this line.
- if (sum <= width) {
- fragment = text.substring(start, len);
- start = len;
- }
-
- canvas.drawText(fragment, rf.left + 1, top, p);
-
- top += lineHeight;
- height -= lineHeight;
- }
- }
-
- private void updateEventDetails() {
- if (mSelectedEvent == null || mSelectionMode == SELECTION_HIDDEN
- || mSelectionMode == SELECTION_LONGPRESS) {
- mPopup.dismiss();
- return;
- }
-
- // Remove any outstanding callbacks to dismiss the popup.
- getHandler().removeCallbacks(mDismissPopup);
-
- Event event = mSelectedEvent;
- TextView titleView = (TextView) mPopupView.findViewById(R.id.event_title);
- titleView.setText(event.title);
-
- ImageView imageView = (ImageView) mPopupView.findViewById(R.id.reminder_icon);
- imageView.setVisibility(event.hasAlarm ? View.VISIBLE : View.GONE);
-
- imageView = (ImageView) mPopupView.findViewById(R.id.repeat_icon);
- imageView.setVisibility(event.isRepeating ? View.VISIBLE : View.GONE);
-
- int flags;
- if (event.allDay) {
- flags = DateUtils.FORMAT_UTC | DateUtils.FORMAT_SHOW_DATE |
- DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_ALL;
- } else {
- flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE
- | DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_ALL
- | DateUtils.FORMAT_CAP_NOON_MIDNIGHT;
- }
- if (DateFormat.is24HourFormat(mContext)) {
- flags |= DateUtils.FORMAT_24HOUR;
- }
- String timeRange = DateUtils.formatDateRange(mParentActivity,
- event.startMillis, event.endMillis, flags);
- TextView timeView = (TextView) mPopupView.findViewById(R.id.time);
- timeView.setText(timeRange);
-
- TextView whereView = (TextView) mPopupView.findViewById(R.id.where);
- whereView.setText(event.location);
-
- mPopup.showAtLocation(this, Gravity.BOTTOM | Gravity.LEFT, mHoursWidth, 5);
- postDelayed(mDismissPopup, POPUP_DISMISS_DELAY);
- }
-
- // The following routines are called from the parent activity when certain
- // touch events occur.
-
- void doDown(MotionEvent ev) {
- mTouchMode = TOUCH_MODE_DOWN;
- mViewStartX = 0;
- mOnFlingCalled = false;
- mLaunchNewView = false;
- getHandler().removeCallbacks(mContinueScroll);
- }
-
- void doSingleTapUp(MotionEvent ev) {
- mSelectionMode = SELECTION_SELECTED;
- mRedrawScreen = true;
- invalidate();
- if (mLaunchNewView) {
- mLaunchNewView = false;
- switchViews(false /* not the trackball */);
- }
- }
-
- void doShowPress(MotionEvent ev) {
- int x = (int) ev.getX();
- int y = (int) ev.getY();
- Event selectedEvent = mSelectedEvent;
- int selectedDay = mSelectionDay;
- int selectedHour = mSelectionHour;
-
- boolean validPosition = setSelectionFromPosition(x, y);
- if (!validPosition) {
- return;
- }
-
- mSelectionMode = SELECTION_PRESSED;
- mRedrawScreen = true;
- invalidate();
-
- // If the tap is on an already selected event or hour slot,
- // then launch a new view. Otherwise, just select the event.
- if (selectedEvent != null && selectedEvent == mSelectedEvent) {
- // Launch the "View event" view when the finger lifts up,
- // unless the finger moves before lifting up.
- mLaunchNewView = true;
- } else if (selectedEvent == null && selectedDay == mSelectionDay
- && selectedHour == mSelectionHour) {
- // Launch the Day/Agenda view when the finger lifts up,
- // unless the finger moves before lifting up.
- mLaunchNewView = true;
- }
- }
-
- void doLongPress(MotionEvent ev) {
- mLaunchNewView = false;
- mSelectionMode = SELECTION_LONGPRESS;
- mRedrawScreen = true;
- invalidate();
- performLongClick();
- }
-
- void doScroll(MotionEvent e1, MotionEvent e2, float deltaX, float deltaY) {
- mLaunchNewView = false;
- // Use the distance from the current point to the initial touch instead
- // of deltaX and deltaY to avoid accumulating floating-point rounding
- // errors. Also, we don't need floats, we can use ints.
- int distanceX = (int) e1.getX() - (int) e2.getX();
- int distanceY = (int) e1.getY() - (int) e2.getY();
-
- // If we haven't figured out the predominant scroll direction yet,
- // then do it now.
- if (mTouchMode == TOUCH_MODE_DOWN) {
- int absDistanceX = Math.abs(distanceX);
- int absDistanceY = Math.abs(distanceY);
- mScrollStartY = mViewStartY;
- mPreviousDistanceX = 0;
- mPreviousDirection = 0;
-
- // If the x distance is at least twice the y distance, then lock
- // the scroll horizontally. Otherwise scroll vertically.
- if (absDistanceX >= 2 * absDistanceY) {
- mTouchMode = TOUCH_MODE_HSCROLL;
- mViewStartX = distanceX;
- initNextView(-mViewStartX);
- } else {
- mTouchMode = TOUCH_MODE_VSCROLL;
- }
- } else if ((mTouchMode & TOUCH_MODE_HSCROLL) != 0) {
- // We are already scrolling horizontally, so check if we
- // changed the direction of scrolling so that the other week
- // is now visible.
- mViewStartX = distanceX;
- if (distanceX != 0) {
- int direction = (distanceX > 0) ? 1 : -1;
- if (direction != mPreviousDirection) {
- // The user has switched the direction of scrolling
- // so re-init the next view
- initNextView(-mViewStartX);
- mPreviousDirection = direction;
- }
- }
-
- // If we have moved at least the HORIZONTAL_SCROLL_THRESHOLD,
- // then change the title to the new day (or week), but only
- // if we haven't already changed the title.
- if (distanceX >= HORIZONTAL_SCROLL_THRESHOLD) {
- if (mPreviousDistanceX < HORIZONTAL_SCROLL_THRESHOLD) {
- CalendarView view = mParentActivity.getNextView();
- mTitleTextView.setText(view.mDateRange);
- }
- } else if (distanceX <= -HORIZONTAL_SCROLL_THRESHOLD) {
- if (mPreviousDistanceX > -HORIZONTAL_SCROLL_THRESHOLD) {
- CalendarView view = mParentActivity.getNextView();
- mTitleTextView.setText(view.mDateRange);
- }
- } else {
- if (mPreviousDistanceX >= HORIZONTAL_SCROLL_THRESHOLD
- || mPreviousDistanceX <= -HORIZONTAL_SCROLL_THRESHOLD) {
- mTitleTextView.setText(mDateRange);
- }
- }
- mPreviousDistanceX = distanceX;
- }
-
- if ((mTouchMode & TOUCH_MODE_VSCROLL) != 0) {
- mViewStartY = mScrollStartY + distanceY;
- if (mViewStartY < 0) {
- mViewStartY = 0;
- } else if (mViewStartY > mMaxViewStartY) {
- mViewStartY = mMaxViewStartY;
- }
- computeFirstHour();
- }
-
- mScrolling = true;
-
- if (mSelectionMode != SELECTION_HIDDEN) {
- mSelectionMode = SELECTION_HIDDEN;
- mRedrawScreen = true;
- }
- invalidate();
- }
-
- void doFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- mTouchMode = TOUCH_MODE_INITIAL_STATE;
- mSelectionMode = SELECTION_HIDDEN;
- mOnFlingCalled = true;
- int deltaX = (int) e2.getX() - (int) e1.getX();
- int distanceX = Math.abs(deltaX);
- int deltaY = (int) e2.getY() - (int) e1.getY();
- int distanceY = Math.abs(deltaY);
-
- if ((distanceX >= HORIZONTAL_SCROLL_THRESHOLD) && (distanceX > distanceY)) {
- boolean switchForward = initNextView(deltaX);
- CalendarView view = mParentActivity.getNextView();
- mTitleTextView.setText(view.mDateRange);
- mParentActivity.switchViews(switchForward, mViewStartX, mViewWidth);
- mViewStartX = 0;
- return;
- }
-
- // Continue scrolling vertically
- mContinueScroll.init((int) velocityY / 20);
- post(mContinueScroll);
- }
-
- private boolean initNextView(int deltaX) {
- // Change the view to the previous day or week
- CalendarView view = mParentActivity.getNextView();
- Time date = view.mBaseDate;
- date.set(mBaseDate);
- int selectionDay;
- boolean switchForward;
- if (deltaX > 0) {
- date.monthDay -= mNumDays;
- view.mSelectionDay = mSelectionDay - mNumDays;
- switchForward = false;
- } else {
- date.monthDay += mNumDays;
- view.mSelectionDay = mSelectionDay + mNumDays;
- switchForward = true;
- }
- date.normalize(true /* ignore isDst */);
- initView(view);
- view.setFrame(getLeft(), getTop(), getRight(), getBottom());
- view.reloadEvents();
- return switchForward;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- int action = ev.getAction();
-
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- mParentActivity.mGestureDetector.onTouchEvent(ev);
- return true;
-
- case MotionEvent.ACTION_MOVE:
- mParentActivity.mGestureDetector.onTouchEvent(ev);
- return true;
-
- case MotionEvent.ACTION_UP:
- mParentActivity.mGestureDetector.onTouchEvent(ev);
- if (mOnFlingCalled) {
- return true;
- }
- if ((mTouchMode & TOUCH_MODE_HSCROLL) != 0) {
- mTouchMode = TOUCH_MODE_INITIAL_STATE;
- if (Math.abs(mViewStartX) > HORIZONTAL_SCROLL_THRESHOLD) {
- // The user has gone beyond the threshold so switch views
- mParentActivity.switchViews(mViewStartX > 0, mViewStartX, mViewWidth);
- } else {
- // Not beyond the threshold so invalidate which will cause
- // the view to snap back. Also call recalc() to ensure
- // that we have the correct starting date and title.
- recalc();
- mTitleTextView.setText(mDateRange);
- invalidate();
- }
- mViewStartX = 0;
- }
-
- // If we were scrolling, then reset the selected hour so that it
- // is visible.
- if (mScrolling) {
- mScrolling = false;
- resetSelectedHour();
- mRedrawScreen = true;
- invalidate();
- }
- return true;
-
- // This case isn't expected to happen.
- case MotionEvent.ACTION_CANCEL:
- mParentActivity.mGestureDetector.onTouchEvent(ev);
- mScrolling = false;
- resetSelectedHour();
- return true;
-
- default:
- if (mParentActivity.mGestureDetector.onTouchEvent(ev)) {
- return true;
- }
- return super.onTouchEvent(ev);
- }
- }
-
- public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
- MenuItem item;
-
- // If the trackball is held down, then the context menu pops up and
- // we never get onKeyUp() for the long-press. So check for it here
- // and change the selection to the long-press state.
- if (mSelectionMode != SELECTION_LONGPRESS) {
- mSelectionMode = SELECTION_LONGPRESS;
- mRedrawScreen = true;
- invalidate();
- }
-
- final long startMillis = getSelectedTimeInMillis();
- int flags = DateUtils.FORMAT_SHOW_TIME
- | DateUtils.FORMAT_CAP_NOON_MIDNIGHT
- | DateUtils.FORMAT_SHOW_WEEKDAY;
- final String title = DateUtils.formatDateTime(mParentActivity, startMillis, flags);
- menu.setHeaderTitle(title);
-
- int numSelectedEvents = mSelectedEvents.size();
- if (mNumDays == 1) {
- // Day view.
-
- // If there is a selected event, then allow it to be viewed and
- // edited.
- if (numSelectedEvents >= 1) {
- item = menu.add(0, MenuHelper.MENU_EVENT_VIEW, 0, R.string.event_view);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_info_details);
-
- if (isEventEditable(mContext, mSelectedEvent)) {
- item = menu.add(0, MenuHelper.MENU_EVENT_EDIT, 0, R.string.event_edit);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_edit);
- item.setAlphabeticShortcut('e');
-
- item = menu.add(0, MenuHelper.MENU_EVENT_DELETE, 0, R.string.event_delete);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_delete);
- }
-
- item = menu.add(0, MenuHelper.MENU_EVENT_CREATE, 0, R.string.event_create);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_add);
- item.setAlphabeticShortcut('n');
- } else {
- // Otherwise, if the user long-pressed on a blank hour, allow
- // them to create an event. They can also do this by tapping.
- item = menu.add(0, MenuHelper.MENU_EVENT_CREATE, 0, R.string.event_create);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_add);
- item.setAlphabeticShortcut('n');
- }
- } else {
- // Week view.
-
- // If there is a selected event, then allow it to be viewed and
- // edited.
- if (numSelectedEvents >= 1) {
- item = menu.add(0, MenuHelper.MENU_EVENT_VIEW, 0, R.string.event_view);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_info_details);
-
- if (isEventEditable(mContext, mSelectedEvent)) {
- item = menu.add(0, MenuHelper.MENU_EVENT_EDIT, 0, R.string.event_edit);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_edit);
- item.setAlphabeticShortcut('e');
-
- item = menu.add(0, MenuHelper.MENU_EVENT_DELETE, 0, R.string.event_delete);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_delete);
- }
-
- item = menu.add(0, MenuHelper.MENU_EVENT_CREATE, 0, R.string.event_create);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_add);
- item.setAlphabeticShortcut('n');
-
- item = menu.add(0, MenuHelper.MENU_DAY, 0, R.string.show_day_view);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_day);
- item.setAlphabeticShortcut('d');
-
- item = menu.add(0, MenuHelper.MENU_AGENDA, 0, R.string.show_agenda_view);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_agenda);
- item.setAlphabeticShortcut('a');
- } else {
- // No events are selected
- item = menu.add(0, MenuHelper.MENU_EVENT_CREATE, 0, R.string.event_create);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_add);
- item.setAlphabeticShortcut('n');
-
- item = menu.add(0, MenuHelper.MENU_DAY, 0, R.string.show_day_view);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_day);
- item.setAlphabeticShortcut('d');
-
- item = menu.add(0, MenuHelper.MENU_AGENDA, 0, R.string.show_agenda_view);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_agenda);
- item.setAlphabeticShortcut('a');
- }
- }
-
- mPopup.dismiss();
- }
-
- private class ContextMenuHandler implements MenuItem.OnMenuItemClickListener {
- public boolean onMenuItemClick(MenuItem item) {
- switch (item.getItemId()) {
- case MenuHelper.MENU_EVENT_VIEW: {
- if (mSelectedEvent != null) {
- long id = mSelectedEvent.id;
- Uri eventUri = ContentUris.withAppendedId(Events.CONTENT_URI, id);
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(eventUri);
- intent.setClassName(mContext, EventInfoActivity.class.getName());
- intent.putExtra(EVENT_BEGIN_TIME, mSelectedEvent.startMillis);
- intent.putExtra(EVENT_END_TIME, mSelectedEvent.endMillis);
- mParentActivity.startActivity(intent);
- }
- break;
- }
- case MenuHelper.MENU_EVENT_EDIT: {
- if (mSelectedEvent != null) {
- long id = mSelectedEvent.id;
- Uri eventUri = ContentUris.withAppendedId(Events.CONTENT_URI, id);
- Intent intent = new Intent(Intent.ACTION_EDIT);
- intent.setData(eventUri);
- intent.setClassName(mContext, EditEvent.class.getName());
- intent.putExtra(EVENT_BEGIN_TIME, mSelectedEvent.startMillis);
- intent.putExtra(EVENT_END_TIME, mSelectedEvent.endMillis);
- mParentActivity.startActivity(intent);
- }
- break;
- }
- case MenuHelper.MENU_DAY: {
- long startMillis = getSelectedTimeInMillis();
- MenuHelper.switchTo(mParentActivity, DayActivity.class.getName(), startMillis);
- mParentActivity.finish();
- break;
- }
- case MenuHelper.MENU_AGENDA: {
- long startMillis = getSelectedTimeInMillis();
- MenuHelper.switchTo(mParentActivity, AgendaActivity.class.getName(), startMillis);
- mParentActivity.finish();
- break;
- }
- case MenuHelper.MENU_EVENT_CREATE: {
- long startMillis = getSelectedTimeInMillis();
- long endMillis = startMillis + DateUtils.HOUR_IN_MILLIS;
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setClassName(mContext, EditEvent.class.getName());
- intent.putExtra(EVENT_BEGIN_TIME, startMillis);
- intent.putExtra(EVENT_END_TIME, endMillis);
- intent.putExtra(EditEvent.EVENT_ALL_DAY, mSelectionAllDay);
- mParentActivity.startActivity(intent);
- break;
- }
- case MenuHelper.MENU_EVENT_DELETE: {
- if (mSelectedEvent != null) {
- Event selectedEvent = mSelectedEvent;
- long begin = selectedEvent.startMillis;
- long end = selectedEvent.endMillis;
- long id = selectedEvent.id;
- mDeleteEventHelper.delete(begin, end, id, -1);
- }
- break;
- }
- default: {
- return false;
- }
- }
- return true;
- }
- }
-
- private static boolean isEventEditable(Context context, Event e) {
- ContentResolver cr = context.getContentResolver();
-
- int visibility = Calendars.NO_ACCESS;
- int relationship = Attendees.RELATIONSHIP_ORGANIZER;
-
- // Get the calendar id for this event
- Cursor cursor = cr.query(ContentUris.withAppendedId(Events.CONTENT_URI, e.id),
- new String[] { Events.CALENDAR_ID },
- null /* selection */,
- null /* selectionArgs */,
- null /* sort */);
- if ((cursor == null) || (cursor.getCount() == 0)) {
- return false;
- }
- cursor.moveToFirst();
- long calId = cursor.getLong(0);
- cursor.deactivate();
-
- Uri uri = Calendars.CONTENT_URI;
- String where = String.format(CALENDARS_WHERE, calId);
- cursor = cr.query(uri, CALENDARS_PROJECTION, where, null, null);
-
- if (cursor != null) {
- cursor.moveToFirst();
- visibility = cursor.getInt(CALENDARS_INDEX_ACCESS_LEVEL);
- cursor.close();
- }
-
- // Attendees cursor
- uri = Attendees.CONTENT_URI;
- where = String.format(ATTENDEES_WHERE, e.id);
- Cursor attendeesCursor = cr.query(uri, ATTENDEES_PROJECTION, where, null, null);
- if (attendeesCursor != null) {
- if (attendeesCursor.moveToFirst()) {
- relationship = attendeesCursor.getInt(ATTENDEES_INDEX_RELATIONSHIP);
- }
- }
- attendeesCursor.close();
-
- if (visibility >= Calendars.CONTRIBUTOR_ACCESS &&
- relationship >= Attendees.RELATIONSHIP_ORGANIZER) {
- return true;
- }
-
- return false;
- }
-
- /**
- * Sets mSelectionDay and mSelectionHour based on the (x,y) touch position.
- * If the touch position is not within the displayed grid, then this
- * method returns false.
- *
- * @param x the x position of the touch
- * @param y the y position of the touch
- * @return true if the touch position is valid
- */
- private boolean setSelectionFromPosition(int x, int y) {
- if (x < mHoursWidth) {
- return false;
- }
-
- int day = (x - mHoursWidth) / (mCellWidth + DAY_GAP);
- if (day >= mNumDays) {
- day = mNumDays - 1;
- }
- day += mFirstJulianDay;
- int hour;
- if (y < mFirstCell + mFirstHourOffset) {
- mSelectionAllDay = true;
- } else {
- hour = (y - mFirstCell - mFirstHourOffset) / (mCellHeight + HOUR_GAP);
- hour += mFirstHour;
- mSelectionHour = hour;
- mSelectionAllDay = false;
- }
- mSelectionDay = day;
- findSelectedEvent(x, y);
-// Log.i("Cal", "setSelectionFromPosition( " + x + ", " + y + " ) day: " + day
-// + " hour: " + hour
-// + " mFirstCell: " + mFirstCell + " mFirstHourOffset: " + mFirstHourOffset);
-// if (mSelectedEvent != null) {
-// Log.i("Cal", " num events: " + mSelectedEvents.size() + " event: " + mSelectedEvent.title);
-// for (Event ev : mSelectedEvents) {
-// int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL
-// | DateUtils.FORMAT_CAP_NOON_MIDNIGHT;
-// String timeRange = formatDateRange(mParentActivity,
-// ev.startMillis, ev.endMillis, flags);
-//
-// Log.i("Cal", " " + timeRange + " " + ev.title);
-// }
-// }
- return true;
- }
-
- private void findSelectedEvent(int x, int y) {
- int date = mSelectionDay;
- int cellWidth = mCellWidth;
- ArrayList<Event> events = mEvents;
- int numEvents = events.size();
- int left = mHoursWidth + (mSelectionDay - mFirstJulianDay) * (cellWidth + DAY_GAP);
- int top = 0;
- mSelectedEvent = null;
-
- mSelectedEvents.clear();
- if (mSelectionAllDay) {
- float yDistance;
- float minYdistance = 10000.0f; // any large number
- Event closestEvent = null;
- float drawHeight = mAllDayHeight;
- int yOffset = mBannerPlusMargin + ALLDAY_TOP_MARGIN;
- for (int i = 0; i < numEvents; i++) {
- Event event = events.get(i);
- if (!event.allDay) {
- continue;
- }
-
- if (event.startDay <= mSelectionDay && event.endDay >= mSelectionDay) {
- float numRectangles = event.getMaxColumns();
- float height = drawHeight / numRectangles;
- if (height > MAX_ALLDAY_EVENT_HEIGHT) {
- height = MAX_ALLDAY_EVENT_HEIGHT;
- }
- float eventTop = yOffset + height * event.getColumn();
- float eventBottom = eventTop + height;
- if (eventTop < y && eventBottom > y) {
- // If the touch is inside the event rectangle, then
- // add the event.
- mSelectedEvents.add(event);
- closestEvent = event;
- break;
- } else {
- // Find the closest event
- if (eventTop >= y) {
- yDistance = eventTop - y;
- } else {
- yDistance = y - eventBottom;
- }
- if (yDistance < minYdistance) {
- minYdistance = yDistance;
- closestEvent = event;
- }
- }
- }
- }
- mSelectedEvent = closestEvent;
- return;
- }
-
- // Adjust y for the scrollable bitmap
- y += mViewStartY - mFirstCell;
-
- // Use a region around (x,y) for the selection region
- Rect region = mRect;
- region.left = x - 10;
- region.right = x + 10;
- region.top = y - 10;
- region.bottom = y + 10;
-
- EventGeometry geometry = mEventGeometry;
-
- for (int i = 0; i < numEvents; i++) {
- Event event = events.get(i);
- // Compute the event rectangle.
- if (!geometry.computeEventRect(date, left, top, cellWidth, event)) {
- continue;
- }
-
- // If the event intersects the selection region, then add it to
- // mSelectedEvents.
- if (geometry.eventIntersectsSelection(event, region)) {
- mSelectedEvents.add(event);
- }
- }
-
- // If there are any events in the selected region, then assign the
- // closest one to mSelectedEvent.
- if (mSelectedEvents.size() > 0) {
- int len = mSelectedEvents.size();
- Event closestEvent = null;
- float minDist = mViewWidth + mViewHeight; // some large distance
- for (int index = 0; index < len; index++) {
- Event ev = mSelectedEvents.get(index);
- float dist = geometry.pointToEvent(x, y, ev);
- if (dist < minDist) {
- minDist = dist;
- closestEvent = ev;
- }
- }
- mSelectedEvent = closestEvent;
-
- // Keep the selected hour and day consistent with the selected
- // event. They could be different if we touched on an empty hour
- // slot very close to an event in the previous hour slot. In
- // that case we will select the nearby event.
- int startDay = mSelectedEvent.startDay;
- int endDay = mSelectedEvent.endDay;
- if (mSelectionDay < startDay) {
- mSelectionDay = startDay;
- } else if (mSelectionDay > endDay) {
- mSelectionDay = endDay;
- }
-
- int startHour = mSelectedEvent.startTime / 60;
- int endHour;
- if (mSelectedEvent.startTime < mSelectedEvent.endTime) {
- endHour = (mSelectedEvent.endTime - 1) / 60;
- } else {
- endHour = mSelectedEvent.endTime / 60;
- }
-
- if (mSelectionHour < startHour) {
- mSelectionHour = startHour;
- } else if (mSelectionHour > endHour) {
- mSelectionHour = endHour;
- }
- }
- }
-
- // Encapsulates the code to continue the scrolling after the
- // finger is lifted. Instead of stopping the scroll immediately,
- // the scroll continues to "free spin" and gradually slows down.
- private class ContinueScroll implements Runnable {
- int mSignDeltaY;
- int mAbsDeltaY;
- float mFloatDeltaY;
- long mFreeSpinTime;
- private static final float FRICTION_COEF = 0.7F;
- private static final long FREE_SPIN_MILLIS = 180;
- private static final int MAX_DELTA = 60;
- private static final int SCROLL_REPEAT_INTERVAL = 30;
-
- public void init(int deltaY) {
- mSignDeltaY = 0;
- if (deltaY > 0) {
- mSignDeltaY = 1;
- } else if (deltaY < 0) {
- mSignDeltaY = -1;
- }
- mAbsDeltaY = Math.abs(deltaY);
-
- // Limit the maximum speed
- if (mAbsDeltaY > MAX_DELTA) {
- mAbsDeltaY = MAX_DELTA;
- }
- mFloatDeltaY = mAbsDeltaY;
- mFreeSpinTime = System.currentTimeMillis() + FREE_SPIN_MILLIS;
-// Log.i("Cal", "init scroll: mAbsDeltaY: " + mAbsDeltaY
-// + " mViewStartY: " + mViewStartY);
- }
-
- public void run() {
- long time = System.currentTimeMillis();
-
- // Start out with a frictionless "free spin"
- if (time > mFreeSpinTime) {
- // If the delta is small, then apply a fixed deceleration.
- // Otherwise
- if (mAbsDeltaY <= 10) {
- mAbsDeltaY -= 2;
- } else {
- mFloatDeltaY *= FRICTION_COEF;
- mAbsDeltaY = (int) mFloatDeltaY;
- }
-
- if (mAbsDeltaY < 0) {
- mAbsDeltaY = 0;
- }
- }
-
- if (mSignDeltaY == 1) {
- mViewStartY -= mAbsDeltaY;
- } else {
- mViewStartY += mAbsDeltaY;
- }
-// Log.i("Cal", " scroll: mAbsDeltaY: " + mAbsDeltaY
-// + " mViewStartY: " + mViewStartY);
-
- if (mViewStartY < 0) {
- mViewStartY = 0;
- mAbsDeltaY = 0;
- } else if (mViewStartY > mMaxViewStartY) {
- mViewStartY = mMaxViewStartY;
- mAbsDeltaY = 0;
- }
-
- computeFirstHour();
-
- if (mAbsDeltaY > 0) {
- postDelayed(this, SCROLL_REPEAT_INTERVAL);
- } else {
- // Done scrolling.
- mScrolling = false;
- resetSelectedHour();
- mRedrawScreen = true;
- }
-
- invalidate();
- }
- }
-
- /**
- * Cleanup the pop-up.
- */
- public void cleanup() {
- // Protect against null-pointer exceptions
- if (mPopup != null) {
- mPopup.dismiss();
- }
- Handler handler = getHandler();
- if (handler != null) {
- handler.removeCallbacks(mDismissPopup);
- }
- }
-
- @Override protected void onDetachedFromWindow() {
- cleanup();
- if (mBitmap != null) {
- mBitmap.recycle();
- mBitmap = null;
- }
- super.onDetachedFromWindow();
- }
-
- class DismissPopup implements Runnable {
- public void run() {
- // Protect against null-pointer exceptions
- if (mPopup != null) {
- mPopup.dismiss();
- }
- }
- }
-}
-
+++ /dev/null
-/*
- * Copyright (C) 2006 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.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.ProgressBar;
-import android.widget.ViewSwitcher;
-
-public class DayActivity extends CalendarActivity implements ViewSwitcher.ViewFactory {
- /**
- * The view id used for all the views we create. It's OK to have all child
- * views have the same ID. This ID is used to pick which view receives
- * focus when a view hierarchy is saved / restore
- */
- private static final int VIEW_ID = 1;
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- setContentView(R.layout.day_activity);
-
- mSelectedDay = Utils.timeFromIntent(getIntent());
- mViewSwitcher = (ViewSwitcher) findViewById(R.id.switcher);
- mViewSwitcher.setFactory(this);
- mViewSwitcher.getCurrentView().requestFocus();
- mProgressBar = (ProgressBar) findViewById(R.id.progress_circular);
-
- // Record Day View as the (new) default detailed view.
- String activityString = CalendarApplication.ACTIVITY_NAMES[CalendarApplication.DAY_VIEW_ID];
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- SharedPreferences.Editor editor = prefs.edit();
- editor.putString(CalendarPreferenceActivity.KEY_DETAILED_VIEW, activityString);
-
- // Record Day View as the (new) start view
- editor.putString(CalendarPreferenceActivity.KEY_START_VIEW, activityString);
- editor.commit();
- }
-
- public View makeView() {
- DayView view = new DayView(this);
- view.setId(VIEW_ID);
- view.setLayoutParams(new ViewSwitcher.LayoutParams(
- LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
- view.setSelectedDay(mSelectedDay);
- return view;
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- mSelectedDay = view.getSelectedDay();
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2006 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;
-
-
-public class DayView extends CalendarView {
- private static final int CELL_MARGIN = 10;
-
- public DayView(CalendarActivity activity) {
- super(activity);
- init();
- }
-
- private void init() {
- mDrawTextInEventRect = true;
- mNumDays = 1;
- mEventGeometry.setCellMargin(CELL_MARGIN);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2008 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.app.Activity;
-import android.app.AlertDialog;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.DialogInterface;
-import android.database.Cursor;
-import android.net.Uri;
-import android.pim.EventRecurrence;
-import android.provider.Calendar;
-import android.provider.Calendar.Events;
-import android.text.format.Time;
-import android.widget.Button;
-
-/**
- * A helper class for deleting events. If a normal event is selected for
- * deletion, then this pops up a confirmation dialog. If the user confirms,
- * then the normal event is deleted.
- *
- * <p>
- * If a repeating event is selected for deletion, then this pops up dialog
- * asking if the user wants to delete just this one instance, or all the
- * events in the series, or this event plus all following events. The user
- * may also cancel the delete.
- * </p>
- *
- * <p>
- * To use this class, create an instance, passing in the parent activity
- * and a boolean that determines if the parent activity should exit if the
- * event is deleted. Then to use the instance, call one of the
- * {@link delete()} methods on this class.
- *
- * An instance of this class may be created once and reused (by calling
- * {@link #delete()} multiple times).
- */
-public class DeleteEventHelper {
-
- private static final String TAG = "DeleteEventHelper";
- private final Activity mParent;
- private final ContentResolver mContentResolver;
-
- private long mStartMillis;
- private long mEndMillis;
- private Cursor mCursor;
-
- /**
- * If true, then call finish() on the parent activity when done.
- */
- private boolean mExitWhenDone;
-
- /**
- * These are the corresponding indices into the array of strings
- * "R.array.delete_repeating_labels" in the resource file.
- */
- static final int DELETE_SELECTED = 0;
- static final int DELETE_ALL_FOLLOWING = 1;
- static final int DELETE_ALL = 2;
-
- private int mWhichDelete;
- private AlertDialog mAlertDialog;
-
- private static final String[] EVENT_PROJECTION = new String[] {
- Events._ID,
- Events.TITLE,
- Events.ALL_DAY,
- Events.CALENDAR_ID,
- Events.RRULE,
- Events.DTSTART,
- Events._SYNC_ID,
- Events.EVENT_TIMEZONE,
- };
-
- private int mEventIndexId;
- private int mEventIndexRrule;
- private String mSyncId;
-
- public DeleteEventHelper(Activity parent, boolean exitWhenDone) {
- mParent = parent;
- mContentResolver = mParent.getContentResolver();
- mExitWhenDone = exitWhenDone;
- }
-
- public void setExitWhenDone(boolean exitWhenDone) {
- mExitWhenDone = exitWhenDone;
- }
-
- /**
- * This callback is used when a normal event is deleted.
- */
- private DialogInterface.OnClickListener mDeleteNormalDialogListener =
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int button) {
- long id = mCursor.getInt(mEventIndexId);
- Uri uri = ContentUris.withAppendedId(Calendar.Events.CONTENT_URI, id);
- mContentResolver.delete(uri, null /* where */, null /* selectionArgs */);
- if (mExitWhenDone) {
- mParent.finish();
- }
- }
- };
-
- /**
- * This callback is used when a list item for a repeating event is selected
- */
- private DialogInterface.OnClickListener mDeleteListListener =
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int button) {
- mWhichDelete = button;
-
- // Enable the "ok" button now that the user has selected which
- // events in the series to delete.
- Button ok = mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
- ok.setEnabled(true);
- }
- };
-
- /**
- * This callback is used when a repeating event is deleted.
- */
- private DialogInterface.OnClickListener mDeleteRepeatingDialogListener =
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int button) {
- if (mWhichDelete != -1) {
- deleteRepeatingEvent(mWhichDelete);
- }
- }
- };
-
- /**
- * Does the required processing for deleting an event, which includes
- * first popping up a dialog asking for confirmation (if the event is
- * a normal event) or a dialog asking which events to delete (if the
- * event is a repeating event). The "which" parameter is used to check
- * the initial selection and is only used for repeating events. Set
- * "which" to -1 to have nothing selected initially.
- *
- * @param begin the begin time of the event, in UTC milliseconds
- * @param end the end time of the event, in UTC milliseconds
- * @param eventId the event id
- * @param which one of the values {@link DELETE_SELECTED},
- * {@link DELETE_ALL_FOLLOWING}, {@link DELETE_ALL}, or -1
- */
- public void delete(long begin, long end, long eventId, int which) {
- Uri uri = ContentUris.withAppendedId(Calendar.Events.CONTENT_URI, eventId);
- Cursor cursor = mParent.managedQuery(uri, EVENT_PROJECTION, null, null);
- if (cursor == null) {
- return;
- }
- cursor.moveToFirst();
- delete(begin, end, cursor, which);
- }
-
- /**
- * Does the required processing for deleting an event. This method
- * takes a {@link Cursor} object as a parameter, which must point to
- * a row in the Events table containing the required database fields.
- * The required fields for a normal event are:
- *
- * <ul>
- * <li> Events._ID </li>
- * <li> Events.TITLE </li>
- * <li> Events.RRULE </li>
- * </ul>
- *
- * The required fields for a repeating event include the above plus the
- * following fields:
- *
- * <ul>
- * <li> Events.ALL_DAY </li>
- * <li> Events.CALENDAR_ID </li>
- * <li> Events.DTSTART </li>
- * <li> Events._SYNC_ID </li>
- * <li> Events.EVENT_TIMEZONE </li>
- * </ul>
- *
- * @param begin the begin time of the event, in UTC milliseconds
- * @param end the end time of the event, in UTC milliseconds
- * @param cursor the database cursor containing the required fields
- * @param which one of the values {@link DELETE_SELECTED},
- * {@link DELETE_ALL_FOLLOWING}, {@link DELETE_ALL}, or -1
- */
- public void delete(long begin, long end, Cursor cursor, int which) {
- mWhichDelete = which;
- mStartMillis = begin;
- mEndMillis = end;
- mCursor = cursor;
- mEventIndexId = mCursor.getColumnIndexOrThrow(Events._ID);
- mEventIndexRrule = mCursor.getColumnIndexOrThrow(Events.RRULE);
- int eventIndexSyncId = mCursor.getColumnIndexOrThrow(Events._SYNC_ID);
- mSyncId = mCursor.getString(eventIndexSyncId);
-
- // If this is a repeating event, then pop up a dialog asking the
- // user if they want to delete all of the repeating events or
- // just some of them.
- String rRule = mCursor.getString(mEventIndexRrule);
- if (rRule == null) {
- // This is a normal event. Pop up a confirmation dialog.
- new AlertDialog.Builder(mParent)
- .setTitle(R.string.delete_title)
- .setMessage(R.string.delete_this_event_title)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setPositiveButton(android.R.string.ok, mDeleteNormalDialogListener)
- .setNegativeButton(android.R.string.cancel, null)
- .show();
- } else {
- // This is a repeating event. Pop up a dialog asking which events
- // to delete.
- int labelsArrayId = R.array.delete_repeating_labels;
- if (mSyncId == null) {
- labelsArrayId = R.array.delete_repeating_labels_no_selected;
- }
- AlertDialog dialog = new AlertDialog.Builder(mParent)
- .setTitle(R.string.delete_title)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setSingleChoiceItems(labelsArrayId, which, mDeleteListListener)
- .setPositiveButton(android.R.string.ok, mDeleteRepeatingDialogListener)
- .setNegativeButton(android.R.string.cancel, null)
- .show();
- mAlertDialog = dialog;
-
- // Disable the "Ok" button until the user selects which events to
- // delete.
- Button ok = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
- ok.setEnabled(false);
- }
- }
-
- private void deleteRepeatingEvent(int which) {
- int indexDtstart = mCursor.getColumnIndexOrThrow(Events.DTSTART);
- int indexAllDay = mCursor.getColumnIndexOrThrow(Events.ALL_DAY);
- int indexTitle = mCursor.getColumnIndexOrThrow(Events.TITLE);
- int indexTimezone = mCursor.getColumnIndexOrThrow(Events.EVENT_TIMEZONE);
- int indexCalendarId = mCursor.getColumnIndexOrThrow(Events.CALENDAR_ID);
-
- String rRule = mCursor.getString(mEventIndexRrule);
- boolean allDay = mCursor.getInt(indexAllDay) != 0;
- long dtstart = mCursor.getLong(indexDtstart);
- long id = mCursor.getInt(mEventIndexId);
-
- // If the repeating event has not been given a sync id from the server
- // yet, then we can't delete a single instance of this event. (This is
- // a deficiency in the CalendarProvider and sync code.) We checked for
- // that when creating the list of items in the dialog and we removed
- // the first element ("DELETE_SELECTED") from the dialog in that case.
- // The "which" value is a 0-based index into the list of items, where
- // the "DELETE_SELECTED" item is at index 0.
- if (mSyncId == null) {
- which += 1;
- }
-
- switch (which) {
- case DELETE_SELECTED:
- {
- // If we are deleting the first event in the series, then
- // instead of creating a recurrence exception, just change
- // the start time of the recurrence.
- if (dtstart == mStartMillis) {
- // TODO
- }
-
- // Create a recurrence exception by creating a new event
- // with the status "cancelled".
- ContentValues values = new ContentValues();
-
- // The title might not be necessary, but it makes it easier
- // to find this entry in the database when there is a problem.
- String title = mCursor.getString(indexTitle);
- values.put(Events.TITLE, title);
-
- String timezone = mCursor.getString(indexTimezone);
- int calendarId = mCursor.getInt(indexCalendarId);
- values.put(Events.EVENT_TIMEZONE, timezone);
- values.put(Events.ALL_DAY, allDay ? 1 : 0);
- values.put(Events.CALENDAR_ID, calendarId);
- values.put(Events.DTSTART, mStartMillis);
- values.put(Events.DTEND, mEndMillis);
- values.put(Events.ORIGINAL_EVENT, mSyncId);
- values.put(Events.ORIGINAL_INSTANCE_TIME, mStartMillis);
- values.put(Events.STATUS, Events.STATUS_CANCELED);
-
- mContentResolver.insert(Events.CONTENT_URI, values);
- break;
- }
- case DELETE_ALL: {
- Uri uri = ContentUris.withAppendedId(Calendar.Events.CONTENT_URI, id);
- mContentResolver.delete(uri, null /* where */, null /* selectionArgs */);
- break;
- }
- case DELETE_ALL_FOLLOWING: {
- // If we are deleting the first event in the series and all
- // following events, then delete them all.
- if (dtstart == mStartMillis) {
- Uri uri = ContentUris.withAppendedId(Calendar.Events.CONTENT_URI, id);
- mContentResolver.delete(uri, null /* where */, null /* selectionArgs */);
- break;
- }
-
- // Modify the repeating event to end just before this event time
- EventRecurrence eventRecurrence = new EventRecurrence();
- eventRecurrence.parse(rRule);
- Time date = new Time();
- if (allDay) {
- date.timezone = Time.TIMEZONE_UTC;
- }
- date.set(mStartMillis);
- date.second--;
- date.normalize(false);
-
- // Google calendar seems to require the UNTIL string to be
- // in UTC.
- date.switchTimezone(Time.TIMEZONE_UTC);
- eventRecurrence.until = date.format2445();
-
- ContentValues values = new ContentValues();
- values.put(Events.DTSTART, dtstart);
- values.put(Events.RRULE, eventRecurrence.toString());
- Uri uri = ContentUris.withAppendedId(Calendar.Events.CONTENT_URI, id);
- mContentResolver.update(uri, values, null, null);
- break;
- }
- }
- if (mExitWhenDone) {
- mParent.finish();
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2008 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 static android.provider.Calendar.EVENT_BEGIN_TIME;
-import static android.provider.Calendar.EVENT_END_TIME;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.DatePickerDialog;
-import android.app.ProgressDialog;
-import android.app.TimePickerDialog;
-import android.app.DatePickerDialog.OnDateSetListener;
-import android.app.TimePickerDialog.OnTimeSetListener;
-import android.content.AsyncQueryHandler;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnClickListener;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.pim.EventRecurrence;
-import android.preference.PreferenceManager;
-import android.provider.Calendar.Calendars;
-import android.provider.Calendar.Events;
-import android.provider.Calendar.Reminders;
-import android.text.TextUtils;
-import android.text.format.DateFormat;
-import android.text.format.DateUtils;
-import android.text.format.Time;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.DatePicker;
-import android.widget.ImageButton;
-import android.widget.LinearLayout;
-import android.widget.ResourceCursorAdapter;
-import android.widget.Spinner;
-import android.widget.TextView;
-import android.widget.TimePicker;
-import android.widget.Toast;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.TimeZone;
-
-public class EditEvent extends Activity implements View.OnClickListener,
- DialogInterface.OnCancelListener, DialogInterface.OnClickListener {
- /**
- * This is the symbolic name for the key used to pass in the boolean
- * for creating all-day events that is part of the extra data of the intent.
- * This is used only for creating new events and is set to true if
- * the default for the new event should be an all-day event.
- */
- public static final String EVENT_ALL_DAY = "allDay";
-
- private static final int MAX_REMINDERS = 5;
-
- private static final int MENU_GROUP_REMINDER = 1;
- private static final int MENU_GROUP_SHOW_OPTIONS = 2;
- private static final int MENU_GROUP_HIDE_OPTIONS = 3;
-
- private static final int MENU_ADD_REMINDER = 1;
- private static final int MENU_SHOW_EXTRA_OPTIONS = 2;
- private static final int MENU_HIDE_EXTRA_OPTIONS = 3;
-
- private static final String[] EVENT_PROJECTION = new String[] {
- Events._ID, // 0
- Events.TITLE, // 1
- Events.DESCRIPTION, // 2
- Events.EVENT_LOCATION, // 3
- Events.ALL_DAY, // 4
- Events.HAS_ALARM, // 5
- Events.CALENDAR_ID, // 6
- Events.DTSTART, // 7
- Events.DURATION, // 8
- Events.EVENT_TIMEZONE, // 9
- Events.RRULE, // 10
- Events._SYNC_ID, // 11
- Events.TRANSPARENCY, // 12
- Events.VISIBILITY, // 13
- };
- private static final int EVENT_INDEX_ID = 0;
- private static final int EVENT_INDEX_TITLE = 1;
- private static final int EVENT_INDEX_DESCRIPTION = 2;
- private static final int EVENT_INDEX_EVENT_LOCATION = 3;
- private static final int EVENT_INDEX_ALL_DAY = 4;
- private static final int EVENT_INDEX_HAS_ALARM = 5;
- private static final int EVENT_INDEX_CALENDAR_ID = 6;
- private static final int EVENT_INDEX_DTSTART = 7;
- private static final int EVENT_INDEX_DURATION = 8;
- private static final int EVENT_INDEX_TIMEZONE = 9;
- private static final int EVENT_INDEX_RRULE = 10;
- private static final int EVENT_INDEX_SYNC_ID = 11;
- private static final int EVENT_INDEX_TRANSPARENCY = 12;
- private static final int EVENT_INDEX_VISIBILITY = 13;
-
- private static final String[] CALENDARS_PROJECTION = new String[] {
- Calendars._ID, // 0
- Calendars.DISPLAY_NAME, // 1
- Calendars.TIMEZONE, // 2
- };
- private static final int CALENDARS_INDEX_DISPLAY_NAME = 1;
- private static final int CALENDARS_INDEX_TIMEZONE = 2;
- private static final String CALENDARS_WHERE = Calendars.ACCESS_LEVEL + ">=" +
- Calendars.CONTRIBUTOR_ACCESS + " AND " + Calendars.SYNC_EVENTS + "=1";
-
- private static final String[] REMINDERS_PROJECTION = new String[] {
- Reminders._ID, // 0
- Reminders.MINUTES, // 1
- };
- private static final int REMINDERS_INDEX_MINUTES = 1;
- private static final String REMINDERS_WHERE = Reminders.EVENT_ID + "=%d AND (" +
- Reminders.METHOD + "=" + Reminders.METHOD_ALERT + " OR " + Reminders.METHOD + "=" +
- Reminders.METHOD_DEFAULT + ")";
-
- private static final int DOES_NOT_REPEAT = 0;
- private static final int REPEATS_DAILY = 1;
- private static final int REPEATS_EVERY_WEEKDAY = 2;
- private static final int REPEATS_WEEKLY_ON_DAY = 3;
- private static final int REPEATS_MONTHLY_ON_DAY_COUNT = 4;
- private static final int REPEATS_MONTHLY_ON_DAY = 5;
- private static final int REPEATS_YEARLY = 6;
- private static final int REPEATS_CUSTOM = 7;
-
- private static final int MODIFY_UNINITIALIZED = 0;
- private static final int MODIFY_SELECTED = 1;
- private static final int MODIFY_ALL = 2;
- private static final int MODIFY_ALL_FOLLOWING = 3;
-
- private static final int DAY_IN_SECONDS = 24 * 60 * 60;
-
- private int mFirstDayOfWeek; // cached in onCreate
- private Uri mUri;
- private Cursor mEventCursor;
- private Cursor mCalendarsCursor;
-
- private Button mStartDateButton;
- private Button mEndDateButton;
- private Button mStartTimeButton;
- private Button mEndTimeButton;
- private Button mSaveButton;
- private Button mDeleteButton;
- private Button mDiscardButton;
- private CheckBox mAllDayCheckBox;
- private Spinner mCalendarsSpinner;
- private Spinner mRepeatsSpinner;
- private Spinner mAvailabilitySpinner;
- private Spinner mVisibilitySpinner;
- private TextView mTitleTextView;
- private TextView mLocationTextView;
- private TextView mDescriptionTextView;
- private View mRemindersSeparator;
- private LinearLayout mRemindersContainer;
- private LinearLayout mExtraOptions;
- private ArrayList<Integer> mOriginalMinutes = new ArrayList<Integer>();
- private ArrayList<LinearLayout> mReminderItems = new ArrayList<LinearLayout>(0);
-
- private EventRecurrence mEventRecurrence = new EventRecurrence();
- private String mRrule;
- private boolean mCalendarsQueryComplete;
- private boolean mSaveAfterQueryComplete;
- private ProgressDialog mLoadingCalendarsDialog;
- private AlertDialog mNoCalendarsDialog;
- private ContentValues mInitialValues;
-
- /**
- * If the repeating event is created on the phone and it hasn't been
- * synced yet to the web server, then there is a bug where you can't
- * delete or change an instance of the repeating event. This case
- * can be detected with mSyncId. If mSyncId == null, then the repeating
- * event has not been synced to the phone, in which case we won't allow
- * the user to change one instance.
- */
- private String mSyncId;
-
- private ArrayList<Integer> mRecurrenceIndexes = new ArrayList<Integer> (0);
- private ArrayList<Integer> mReminderValues;
- private ArrayList<String> mReminderLabels;
-
- private Time mStartTime;
- private Time mEndTime;
- private int mModification = MODIFY_UNINITIALIZED;
- private int mDefaultReminderMinutes;
-
- private DeleteEventHelper mDeleteEventHelper;
- private QueryHandler mQueryHandler;
-
- /* This class is used to update the time buttons. */
- private class TimeListener implements OnTimeSetListener {
- private View mView;
-
- public TimeListener(View view) {
- mView = view;
- }
-
- public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
- // Cache the member variables locally to avoid inner class overhead.
- Time startTime = mStartTime;
- Time endTime = mEndTime;
-
- // Cache the start and end millis so that we limit the number
- // of calls to normalize() and toMillis(), which are fairly
- // expensive.
- long startMillis;
- long endMillis;
- if (mView == mStartTimeButton) {
- // The start time was changed.
- int hourDuration = endTime.hour - startTime.hour;
- int minuteDuration = endTime.minute - startTime.minute;
-
- startTime.hour = hourOfDay;
- startTime.minute = minute;
- startMillis = startTime.normalize(true);
-
- // Also update the end time to keep the duration constant.
- endTime.hour = hourOfDay + hourDuration;
- endTime.minute = minute + minuteDuration;
- endMillis = endTime.normalize(true);
- } else {
- // The end time was changed.
- startMillis = startTime.toMillis(true);
- endTime.hour = hourOfDay;
- endTime.minute = minute;
- endMillis = endTime.normalize(true);
-
- // Do not allow an event to have an end time before the start time.
- if (endTime.before(startTime)) {
- endTime.set(startTime);
- endMillis = startMillis;
- }
- }
-
- setDate(mEndDateButton, endMillis);
- setTime(mStartTimeButton, startMillis);
- setTime(mEndTimeButton, endMillis);
- }
- }
-
- private class TimeClickListener implements View.OnClickListener {
- private Time mTime;
-
- public TimeClickListener(Time time) {
- mTime = time;
- }
-
- public void onClick(View v) {
- new TimePickerDialog(EditEvent.this, new TimeListener(v),
- mTime.hour, mTime.minute,
- DateFormat.is24HourFormat(EditEvent.this)).show();
- }
- }
-
- private class DateListener implements OnDateSetListener {
- View mView;
-
- public DateListener(View view) {
- mView = view;
- }
-
- public void onDateSet(DatePicker view, int year, int month, int monthDay) {
- // Cache the member variables locally to avoid inner class overhead.
- Time startTime = mStartTime;
- Time endTime = mEndTime;
-
- // Cache the start and end millis so that we limit the number
- // of calls to normalize() and toMillis(), which are fairly
- // expensive.
- long startMillis;
- long endMillis;
- if (mView == mStartDateButton) {
- // The start date was changed.
- int yearDuration = endTime.year - startTime.year;
- int monthDuration = endTime.month - startTime.month;
- int monthDayDuration = endTime.monthDay - startTime.monthDay;
-
- startTime.year = year;
- startTime.month = month;
- startTime.monthDay = monthDay;
- startMillis = startTime.normalize(true);
-
- // Also update the end date to keep the duration constant.
- endTime.year = year + yearDuration;
- endTime.month = month + monthDuration;
- endTime.monthDay = monthDay + monthDayDuration;
- endMillis = endTime.normalize(true);
-
- // If the start date has changed then update the repeats.
- populateRepeats();
- } else {
- // The end date was changed.
- startMillis = startTime.toMillis(true);
- endTime.year = year;
- endTime.month = month;
- endTime.monthDay = monthDay;
- endMillis = endTime.normalize(true);
-
- // Do not allow an event to have an end time before the start time.
- if (endTime.before(startTime)) {
- endTime.set(startTime);
- endMillis = startMillis;
- }
- }
-
- setDate(mStartDateButton, startMillis);
- setDate(mEndDateButton, endMillis);
- setTime(mEndTimeButton, endMillis); // In case end time had to be reset
- }
- }
-
- private class DateClickListener implements View.OnClickListener {
- private Time mTime;
-
- public DateClickListener(Time time) {
- mTime = time;
- }
-
- public void onClick(View v) {
- new DatePickerDialog(EditEvent.this, new DateListener(v), mTime.year,
- mTime.month, mTime.monthDay).show();
- }
- }
-
- private class CalendarsAdapter extends ResourceCursorAdapter {
- public CalendarsAdapter(Context context, Cursor c) {
- super(context, R.layout.calendars_item, c);
- setDropDownViewResource(R.layout.calendars_dropdown_item);
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- TextView name = (TextView) view.findViewById(R.id.calendar_name);
- name.setText(cursor.getString(CALENDARS_INDEX_DISPLAY_NAME));
- }
- }
-
- // This is called if the user clicks on one of the buttons: "Save",
- // "Discard", or "Delete". This is also called if the user clicks
- // on the "remove reminder" button.
- public void onClick(View v) {
- if (v == mSaveButton) {
- if (save()) {
- finish();
- }
- return;
- }
-
- if (v == mDeleteButton) {
- long begin = mStartTime.toMillis(false /* use isDst */);
- long end = mEndTime.toMillis(false /* use isDst */);
- int which = -1;
- switch (mModification) {
- case MODIFY_SELECTED:
- which = DeleteEventHelper.DELETE_SELECTED;
- break;
- case MODIFY_ALL_FOLLOWING:
- which = DeleteEventHelper.DELETE_ALL_FOLLOWING;
- break;
- case MODIFY_ALL:
- which = DeleteEventHelper.DELETE_ALL;
- break;
- }
- mDeleteEventHelper.delete(begin, end, mEventCursor, which);
- return;
- }
-
- if (v == mDiscardButton) {
- finish();
- return;
- }
-
- // This must be a click on one of the "remove reminder" buttons
- LinearLayout reminderItem = (LinearLayout) v.getParent();
- LinearLayout parent = (LinearLayout) reminderItem.getParent();
- parent.removeView(reminderItem);
- mReminderItems.remove(reminderItem);
- updateRemindersVisibility();
- }
-
- // This is called if the user cancels a popup dialog. There are two
- // dialogs: the "Loading calendars" dialog, and the "No calendars"
- // dialog. The "Loading calendars" dialog is shown if there is a delay
- // in loading the calendars (needed when creating an event) and the user
- // tries to save the event before the calendars have finished loading.
- // The "No calendars" dialog is shown if there are no syncable calendars.
- public void onCancel(DialogInterface dialog) {
- if (dialog == mLoadingCalendarsDialog) {
- mSaveAfterQueryComplete = false;
- } else if (dialog == mNoCalendarsDialog) {
- finish();
- }
- }
-
- // This is called if the user clicks on a dialog button.
- public void onClick(DialogInterface dialog, int which) {
- if (dialog == mNoCalendarsDialog) {
- finish();
- }
- }
-
- private class QueryHandler extends AsyncQueryHandler {
- public QueryHandler(ContentResolver cr) {
- super(cr);
- }
-
- @Override
- protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
- // If the Activity is finishing, then close the cursor.
- // Otherwise, use the new cursor in the adapter.
- if (isFinishing()) {
- stopManagingCursor(cursor);
- cursor.close();
- } else {
- mCalendarsCursor = cursor;
- startManagingCursor(cursor);
-
- // Stop the spinner
- getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
- Window.PROGRESS_VISIBILITY_OFF);
-
- // If there are no syncable calendars, then we cannot allow
- // creating a new event.
- if (cursor.getCount() == 0) {
- // Cancel the "loading calendars" dialog if it exists
- if (mSaveAfterQueryComplete) {
- mLoadingCalendarsDialog.cancel();
- }
-
- // Create an error message for the user that, when clicked,
- // will exit this activity without saving the event.
- AlertDialog.Builder builder = new AlertDialog.Builder(EditEvent.this);
- builder.setTitle(R.string.no_syncable_calendars)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setMessage(R.string.no_calendars_found)
- .setPositiveButton(android.R.string.ok, EditEvent.this)
- .setOnCancelListener(EditEvent.this);
- mNoCalendarsDialog = builder.show();
- return;
- }
-
- // populate the calendars spinner
- CalendarsAdapter adapter = new CalendarsAdapter(EditEvent.this, mCalendarsCursor);
- mCalendarsSpinner.setAdapter(adapter);
- mCalendarsQueryComplete = true;
- if (mSaveAfterQueryComplete) {
- mLoadingCalendarsDialog.cancel();
- save();
- finish();
- }
- }
- }
- }
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
- setContentView(R.layout.edit_event);
-
- mFirstDayOfWeek = Calendar.getInstance().getFirstDayOfWeek();
-
- mStartTime = new Time();
- mEndTime = new Time();
-
- Intent intent = getIntent();
- mUri = intent.getData();
-
- if (mUri != null) {
- mEventCursor = managedQuery(mUri, EVENT_PROJECTION, null, null);
- if (mEventCursor == null || mEventCursor.getCount() == 0) {
- // The cursor is empty. This can happen if the event was deleted.
- finish();
- return;
- }
- }
-
- long begin = intent.getLongExtra(EVENT_BEGIN_TIME, 0);
- long end = intent.getLongExtra(EVENT_END_TIME, 0);
-
- boolean allDay = false;
- if (mEventCursor != null) {
- // The event already exists so fetch the all-day status
- mEventCursor.moveToFirst();
- allDay = mEventCursor.getInt(EVENT_INDEX_ALL_DAY) != 0;
- String rrule = mEventCursor.getString(EVENT_INDEX_RRULE);
- String timezone = mEventCursor.getString(EVENT_INDEX_TIMEZONE);
- long calendarId = mEventCursor.getInt(EVENT_INDEX_CALENDAR_ID);
-
- // Remember the initial values
- mInitialValues = new ContentValues();
- mInitialValues.put(EVENT_BEGIN_TIME, begin);
- mInitialValues.put(EVENT_END_TIME, end);
- mInitialValues.put(Events.ALL_DAY, allDay ? 1 : 0);
- mInitialValues.put(Events.RRULE, rrule);
- mInitialValues.put(Events.EVENT_TIMEZONE, timezone);
- mInitialValues.put(Events.CALENDAR_ID, calendarId);
- } else {
- // We are creating a new event, so set the default from the
- // intent (if specified).
- allDay = intent.getBooleanExtra(EVENT_ALL_DAY, false);
-
- // Start the spinner
- getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
- Window.PROGRESS_VISIBILITY_ON);
-
- // Start a query in the background to read the list of calendars
- mQueryHandler = new QueryHandler(getContentResolver());
- mQueryHandler.startQuery(0, null, Calendars.CONTENT_URI, CALENDARS_PROJECTION,
- CALENDARS_WHERE, null /* selection args */, null /* sort order */);
- }
-
- // If the event is all-day, read the times in UTC timezone
- if (begin != 0) {
- if (allDay) {
- String tz = mStartTime.timezone;
- mStartTime.timezone = Time.TIMEZONE_UTC;
- mStartTime.set(begin);
- mStartTime.timezone = tz;
-
- // Calling normalize to calculate isDst
- mStartTime.normalize(true);
- } else {
- mStartTime.set(begin);
- }
- }
-
- if (end != 0) {
- if (allDay) {
- String tz = mStartTime.timezone;
- mEndTime.timezone = Time.TIMEZONE_UTC;
- mEndTime.set(end);
- mEndTime.timezone = tz;
-
- // Calling normalize to calculate isDst
- mEndTime.normalize(true);
- } else {
- mEndTime.set(end);
- }
- }
-
- // cache all the widgets
- mTitleTextView = (TextView) findViewById(R.id.title);
- mLocationTextView = (TextView) findViewById(R.id.location);
- mDescriptionTextView = (TextView) findViewById(R.id.description);
- mStartDateButton = (Button) findViewById(R.id.start_date);
- mEndDateButton = (Button) findViewById(R.id.end_date);
- mStartTimeButton = (Button) findViewById(R.id.start_time);
- mEndTimeButton = (Button) findViewById(R.id.end_time);
- mAllDayCheckBox = (CheckBox) findViewById(R.id.is_all_day);
- mCalendarsSpinner = (Spinner) findViewById(R.id.calendars);
- mRepeatsSpinner = (Spinner) findViewById(R.id.repeats);
- mAvailabilitySpinner = (Spinner) findViewById(R.id.availability);
- mVisibilitySpinner = (Spinner) findViewById(R.id.visibility);
- mRemindersSeparator = findViewById(R.id.reminders_separator);
- mRemindersContainer = (LinearLayout) findViewById(R.id.reminders_container);
- mExtraOptions = (LinearLayout) findViewById(R.id.extra_options_container);
-
- mAllDayCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if (isChecked) {
- if (mEndTime.hour == 0 && mEndTime.minute == 0) {
- mEndTime.monthDay--;
- long endMillis = mEndTime.normalize(true);
-
- // Do not allow an event to have an end time before the start time.
- if (mEndTime.before(mStartTime)) {
- mEndTime.set(mStartTime);
- endMillis = mEndTime.normalize(true);
- }
- setDate(mEndDateButton, endMillis);
- setTime(mEndTimeButton, endMillis);
- }
-
- mStartTimeButton.setVisibility(View.GONE);
- mEndTimeButton.setVisibility(View.GONE);
- } else {
- if (mEndTime.hour == 0 && mEndTime.minute == 0) {
- mEndTime.monthDay++;
- long endMillis = mEndTime.normalize(true);
- setDate(mEndDateButton, endMillis);
- setTime(mEndTimeButton, endMillis);
- }
-
- mStartTimeButton.setVisibility(View.VISIBLE);
- mEndTimeButton.setVisibility(View.VISIBLE);
- }
- }
- });
-
- if (allDay) {
- mAllDayCheckBox.setChecked(true);
- } else {
- mAllDayCheckBox.setChecked(false);
- }
-
- mSaveButton = (Button) findViewById(R.id.save);
- mSaveButton.setOnClickListener(this);
-
- mDeleteButton = (Button) findViewById(R.id.delete);
- mDeleteButton.setOnClickListener(this);
-
- mDiscardButton = (Button) findViewById(R.id.discard);
- mDiscardButton.setOnClickListener(this);
-
- // Initialize the reminder values array.
- Resources r = getResources();
- String[] strings = r.getStringArray(R.array.reminder_minutes_values);
- int size = strings.length;
- ArrayList<Integer> list = new ArrayList<Integer>(size);
- for (int i = 0 ; i < size ; i++) {
- list.add(Integer.parseInt(strings[i]));
- }
- mReminderValues = list;
- String[] labels = r.getStringArray(R.array.reminder_minutes_labels);
- mReminderLabels = new ArrayList<String>(Arrays.asList(labels));
-
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- String durationString =
- prefs.getString(CalendarPreferenceActivity.KEY_DEFAULT_REMINDER, "0");
- mDefaultReminderMinutes = Integer.parseInt(durationString);
-
- // Reminders cursor
- boolean hasAlarm = (mEventCursor != null)
- && (mEventCursor.getInt(EVENT_INDEX_HAS_ALARM) != 0);
- if (hasAlarm) {
- Uri uri = Reminders.CONTENT_URI;
- long eventId = mEventCursor.getLong(EVENT_INDEX_ID);
- String where = String.format(REMINDERS_WHERE, eventId);
- ContentResolver cr = getContentResolver();
- Cursor reminderCursor = cr.query(uri, REMINDERS_PROJECTION, where, null, null);
- try {
- // First pass: collect all the custom reminder minutes (e.g.,
- // a reminder of 8 minutes) into a global list.
- while (reminderCursor.moveToNext()) {
- int minutes = reminderCursor.getInt(REMINDERS_INDEX_MINUTES);
- EditEvent.addMinutesToList(this, mReminderValues, mReminderLabels, minutes);
- }
-
- // Second pass: create the reminder spinners
- reminderCursor.moveToPosition(-1);
- while (reminderCursor.moveToNext()) {
- int minutes = reminderCursor.getInt(REMINDERS_INDEX_MINUTES);
- mOriginalMinutes.add(minutes);
- EditEvent.addReminder(this, this, mReminderItems, mReminderValues,
- mReminderLabels, minutes);
- }
- } finally {
- reminderCursor.close();
- }
- }
- updateRemindersVisibility();
-
- mDeleteEventHelper = new DeleteEventHelper(this, true /* exit when done */);
-
- if (mEventCursor == null) {
- // Allow the intent to specify the fields in the event.
- // This will allow other apps to create events easily.
- initFromIntent(intent);
- }
- }
-
- private void initFromIntent(Intent intent) {
- String title = intent.getStringExtra(Events.TITLE);
- if (title != null) {
- mTitleTextView.setText(title);
- }
-
- String location = intent.getStringExtra(Events.EVENT_LOCATION);
- if (location != null) {
- mLocationTextView.setText(location);
- }
-
- String description = intent.getStringExtra(Events.DESCRIPTION);
- if (description != null) {
- mDescriptionTextView.setText(description);
- }
-
- int availability = intent.getIntExtra(Events.TRANSPARENCY, -1);
- if (availability != -1) {
- mAvailabilitySpinner.setSelection(availability);
- }
-
- int visibility = intent.getIntExtra(Events.VISIBILITY, -1);
- if (visibility != -1) {
- mVisibilitySpinner.setSelection(visibility);
- }
-
- String rrule = intent.getStringExtra(Events.RRULE);
- if (rrule != null) {
- mRrule = rrule;
- mEventRecurrence.parse(rrule);
- }
- }
-
- @Override
- protected void onResume() {
- super.onResume();
-
- if (mUri != null) {
- if (mEventCursor == null || mEventCursor.getCount() == 0) {
- // The cursor is empty. This can happen if the event was deleted.
- finish();
- return;
- }
- }
-
- if (mEventCursor != null) {
- Cursor cursor = mEventCursor;
- cursor.moveToFirst();
-
- mRrule = cursor.getString(EVENT_INDEX_RRULE);
- String title = cursor.getString(EVENT_INDEX_TITLE);
- String description = cursor.getString(EVENT_INDEX_DESCRIPTION);
- String location = cursor.getString(EVENT_INDEX_EVENT_LOCATION);
- int availability = cursor.getInt(EVENT_INDEX_TRANSPARENCY);
- int visibility = cursor.getInt(EVENT_INDEX_VISIBILITY);
- if (visibility > 0) {
- // For now we the array contains the values 0, 2, and 3. We subtract one to match.
- visibility--;
- }
-
- if (!TextUtils.isEmpty(mRrule) && mModification == MODIFY_UNINITIALIZED) {
- // If this event has not been synced, then don't allow deleting
- // or changing a single instance.
- mSyncId = cursor.getString(EVENT_INDEX_SYNC_ID);
- mEventRecurrence.parse(mRrule);
-
- // If we haven't synced this repeating event yet, then don't
- // allow the user to change just one instance.
- int itemIndex = 0;
- CharSequence[] items;
- if (mSyncId == null) {
- items = new CharSequence[2];
- } else {
- items = new CharSequence[3];
- items[itemIndex++] = getText(R.string.modify_event);
- }
- items[itemIndex++] = getText(R.string.modify_all);
- items[itemIndex++] = getText(R.string.modify_all_following);
-
- // Display the modification dialog.
- new AlertDialog.Builder(this)
- .setOnCancelListener(new OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- finish();
- }
- })
- .setTitle(R.string.edit_event_label)
- .setItems(items, new OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- if (which == 0) {
- mModification =
- (mSyncId == null) ? MODIFY_ALL : MODIFY_SELECTED;
- } else if (which == 1) {
- mModification =
- (mSyncId == null) ? MODIFY_ALL_FOLLOWING : MODIFY_ALL;
- } else if (which == 2) {
- mModification = MODIFY_ALL_FOLLOWING;
- }
-
- // If we are modifying all the events in a
- // series then disable and ignore the date.
- if (mModification == MODIFY_ALL) {
- mStartDateButton.setEnabled(false);
- mEndDateButton.setEnabled(false);
- } else if (mModification == MODIFY_SELECTED) {
- mRepeatsSpinner.setEnabled(false);
- } else {
- // We could allow changing the Rrule for
- // all following instances but we'll
- // keep it simple for now.
- mRepeatsSpinner.setEnabled(false);
- }
- }
- })
- .show();
- }
-
- mTitleTextView.setText(title);
- mLocationTextView.setText(location);
- mDescriptionTextView.setText(description);
- mAvailabilitySpinner.setSelection(availability);
- mVisibilitySpinner.setSelection(visibility);
-
- // This is an existing event so hide the calendar spinner
- // since we can't change the calendar.
- View calendarSeparator = findViewById(R.id.calendar_separator);
- View calendarLabel = findViewById(R.id.calendar_label);
- calendarSeparator.setVisibility(View.GONE);
- calendarLabel.setVisibility(View.GONE);
- mCalendarsSpinner.setVisibility(View.GONE);
- } else if (Time.isEpoch(mStartTime) && Time.isEpoch(mEndTime)) {
- mStartTime.setToNow();
-
- // Round the time to the nearest half hour.
- mStartTime.second = 0;
- int minute = mStartTime.minute;
- if (minute > 0 && minute <= 30) {
- mStartTime.minute = 30;
- } else {
- mStartTime.minute = 0;
- mStartTime.hour += 1;
- }
-
- long startMillis = mStartTime.normalize(true /* ignore isDst */);
- mEndTime.set(startMillis + DateUtils.HOUR_IN_MILLIS);
- } else {
- // New event - set the default reminder
- if (mDefaultReminderMinutes != 0) {
- addReminder(this, this, mReminderItems, mReminderValues,
- mReminderLabels, mDefaultReminderMinutes);
- }
-
- // Hide delete button
- mDeleteButton.setVisibility(View.GONE);
- }
-
- updateRemindersVisibility();
- populateWhen();
- populateRepeats();
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuItem item;
- item = menu.add(MENU_GROUP_REMINDER, MENU_ADD_REMINDER, 0,
- R.string.add_new_reminder);
- item.setIcon(R.drawable.ic_menu_reminder);
- item.setAlphabeticShortcut('r');
-
- item = menu.add(MENU_GROUP_SHOW_OPTIONS, MENU_SHOW_EXTRA_OPTIONS, 0,
- R.string.edit_event_show_extra_options);
- item.setIcon(R.drawable.ic_menu_show_list);
- item = menu.add(MENU_GROUP_HIDE_OPTIONS, MENU_HIDE_EXTRA_OPTIONS, 0,
- R.string.edit_event_hide_extra_options);
- item.setIcon(R.drawable.ic_menu_show_list);
-
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- if (mReminderItems.size() < MAX_REMINDERS) {
- menu.setGroupVisible(MENU_GROUP_REMINDER, true);
- menu.setGroupEnabled(MENU_GROUP_REMINDER, true);
- } else {
- menu.setGroupVisible(MENU_GROUP_REMINDER, false);
- menu.setGroupEnabled(MENU_GROUP_REMINDER, false);
- }
-
- if (mExtraOptions.getVisibility() == View.VISIBLE) {
- menu.setGroupVisible(MENU_GROUP_SHOW_OPTIONS, false);
- menu.setGroupVisible(MENU_GROUP_HIDE_OPTIONS, true);
- } else {
- menu.setGroupVisible(MENU_GROUP_SHOW_OPTIONS, true);
- menu.setGroupVisible(MENU_GROUP_HIDE_OPTIONS, false);
- }
-
- return super.onPrepareOptionsMenu(menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case MENU_ADD_REMINDER:
- // TODO: when adding a new reminder, make it different from the
- // last one in the list (if any).
- if (mDefaultReminderMinutes == 0) {
- addReminder(this, this, mReminderItems, mReminderValues,
- mReminderLabels, 10 /* minutes */);
- } else {
- addReminder(this, this, mReminderItems, mReminderValues,
- mReminderLabels, mDefaultReminderMinutes);
- }
- updateRemindersVisibility();
- return true;
- case MENU_SHOW_EXTRA_OPTIONS:
- mExtraOptions.setVisibility(View.VISIBLE);
- return true;
- case MENU_HIDE_EXTRA_OPTIONS:
- mExtraOptions.setVisibility(View.GONE);
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_BACK:
- // If we are creating a new event, do not create it if the
- // title, location and description are all empty, in order to
- // prevent accidental "no subject" event creations.
- if (mUri != null || !isEmpty()) {
- if (!save()) {
- // We cannot exit this activity because the calendars
- // are still loading.
- return true;
- }
- }
- break;
- }
-
- return super.onKeyDown(keyCode, event);
- }
-
- private void populateWhen() {
- long startMillis = mStartTime.toMillis(false /* use isDst */);
- long endMillis = mEndTime.toMillis(false /* use isDst */);
- setDate(mStartDateButton, startMillis);
- setDate(mEndDateButton, endMillis);
-
- setTime(mStartTimeButton, startMillis);
- setTime(mEndTimeButton, endMillis);
-
- mStartDateButton.setOnClickListener(new DateClickListener(mStartTime));
- mEndDateButton.setOnClickListener(new DateClickListener(mEndTime));
-
- mStartTimeButton.setOnClickListener(new TimeClickListener(mStartTime));
- mEndTimeButton.setOnClickListener(new TimeClickListener(mEndTime));
- }
-
- private void populateRepeats() {
- Time time = mStartTime;
- Resources r = getResources();
- int resource = android.R.layout.simple_spinner_item;
-
- String[] days = r.getStringArray(R.array.day_labels);
- String[] ordinals = r.getStringArray(R.array.ordinal_labels);
-
- // Only display "Custom" in the spinner if the device does not support the
- // recurrence functionality of the event. Only display every weekday if
- // the event starts on a weekday.
- boolean isCustomRecurrence = isCustomRecurrence();
- boolean isWeekdayEvent = isWeekdayEvent();
-
- ArrayList<String> repeatArray = new ArrayList<String>(0);
- ArrayList<Integer> recurrenceIndexes = new ArrayList<Integer>(0);
-
- repeatArray.add(r.getString(R.string.does_not_repeat));
- recurrenceIndexes.add(DOES_NOT_REPEAT);
-
- repeatArray.add(r.getString(R.string.daily));
- recurrenceIndexes.add(REPEATS_DAILY);
-
- if (isWeekdayEvent) {
- repeatArray.add(r.getString(R.string.every_weekday));
- recurrenceIndexes.add(REPEATS_EVERY_WEEKDAY);
- }
-
- String format = r.getString(R.string.weekly);
- repeatArray.add(String.format(format, time.format("%A")));
- recurrenceIndexes.add(REPEATS_WEEKLY_ON_DAY);
-
- // Calculate whether this is the 1st, 2nd, 3rd, 4th, or last appearance of the given day.
- int dayNumber = (time.monthDay - 1) / 7;
- format = r.getString(R.string.monthly_on_day_count);
- repeatArray.add(String.format(format, ordinals[dayNumber], days[time.weekDay]));
- recurrenceIndexes.add(REPEATS_MONTHLY_ON_DAY_COUNT);
-
- format = r.getString(R.string.monthly_on_day);
- repeatArray.add(String.format(format, time.monthDay));
- recurrenceIndexes.add(REPEATS_MONTHLY_ON_DAY);
-
- long when = time.toMillis(false);
- format = r.getString(R.string.yearly);
- int flags = 0;
- if (DateFormat.is24HourFormat(this)) {
- flags |= DateUtils.FORMAT_24HOUR;
- }
- repeatArray.add(String.format(format, DateUtils.formatDateTime(this, when, flags)));
- recurrenceIndexes.add(REPEATS_YEARLY);
-
- if (isCustomRecurrence) {
- repeatArray.add(r.getString(R.string.custom));
- recurrenceIndexes.add(REPEATS_CUSTOM);
- }
- mRecurrenceIndexes = recurrenceIndexes;
-
- int position = recurrenceIndexes.indexOf(DOES_NOT_REPEAT);
- if (mRrule != null) {
- if (isCustomRecurrence) {
- position = recurrenceIndexes.indexOf(REPEATS_CUSTOM);
- } else {
- switch (mEventRecurrence.freq) {
- case EventRecurrence.DAILY:
- position = recurrenceIndexes.indexOf(REPEATS_DAILY);
- break;
- case EventRecurrence.WEEKLY:
- if (mEventRecurrence.repeatsOnEveryWeekDay()) {
- position = recurrenceIndexes.indexOf(REPEATS_EVERY_WEEKDAY);
- } else {
- position = recurrenceIndexes.indexOf(REPEATS_WEEKLY_ON_DAY);
- }
- break;
- case EventRecurrence.MONTHLY:
- if (mEventRecurrence.repeatsMonthlyOnDayCount()) {
- position = recurrenceIndexes.indexOf(REPEATS_MONTHLY_ON_DAY_COUNT);
- } else {
- position = recurrenceIndexes.indexOf(REPEATS_MONTHLY_ON_DAY);
- }
- break;
- case EventRecurrence.YEARLY:
- position = recurrenceIndexes.indexOf(REPEATS_YEARLY);
- break;
- }
- }
- }
- ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, resource, repeatArray);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- mRepeatsSpinner.setAdapter(adapter);
- mRepeatsSpinner.setSelection(position);
- }
-
- // Adds a reminder to the displayed list of reminders.
- // Returns true if successfully added reminder, false if no reminders can
- // be added.
- static boolean addReminder(Activity activity, View.OnClickListener listener,
- ArrayList<LinearLayout> items, ArrayList<Integer> values,
- ArrayList<String> labels, int minutes) {
-
- if (items.size() >= MAX_REMINDERS) {
- return false;
- }
-
- LayoutInflater inflater = activity.getLayoutInflater();
- LinearLayout parent = (LinearLayout) activity.findViewById(R.id.reminder_items_container);
- LinearLayout reminderItem = (LinearLayout) inflater.inflate(R.layout.edit_reminder_item, null);
- parent.addView(reminderItem);
-
- Spinner spinner = (Spinner) reminderItem.findViewById(R.id.reminder_value);
- Resources res = activity.getResources();
- spinner.setPrompt(res.getString(R.string.reminders_label));
- int resource = android.R.layout.simple_spinner_item;
- ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity, resource, labels);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- spinner.setAdapter(adapter);
-
- ImageButton reminderRemoveButton;
- reminderRemoveButton = (ImageButton) reminderItem.findViewById(R.id.reminder_remove);
- reminderRemoveButton.setOnClickListener(listener);
-
- int index = findMinutesInReminderList(values, minutes);
- spinner.setSelection(index);
- items.add(reminderItem);
-
- return true;
- }
-
- static void addMinutesToList(Context context, ArrayList<Integer> values,
- ArrayList<String> labels, int minutes) {
- int index = values.indexOf(minutes);
- if (index != -1) {
- return;
- }
-
- // The requested "minutes" does not exist in the list, so insert it
- // into the list.
-
- String label = constructReminderLabel(context, minutes, false);
- int len = values.size();
- for (int i = 0; i < len; i++) {
- if (minutes < values.get(i)) {
- values.add(i, minutes);
- labels.add(i, label);
- return;
- }
- }
-
- values.add(minutes);
- labels.add(len, label);
- }
-
- /**
- * Finds the index of the given "minutes" in the "values" list.
- *
- * @param values the list of minutes corresponding to the spinner choices
- * @param minutes the minutes to search for in the values list
- * @return the index of "minutes" in the "values" list
- */
- private static int findMinutesInReminderList(ArrayList<Integer> values, int minutes) {
- int index = values.indexOf(minutes);
- if (index == -1) {
- // This should never happen.
- Log.e("Cal", "Cannot find minutes (" + minutes + ") in list");
- return 0;
- }
- return index;
- }
-
- // Constructs a label given an arbitrary number of minutes. For example,
- // if the given minutes is 63, then this returns the string "63 minutes".
- // As another example, if the given minutes is 120, then this returns
- // "2 hours".
- static String constructReminderLabel(Context context, int minutes, boolean abbrev) {
- Resources resources = context.getResources();
- int value, resId;
-
- if (minutes % 60 != 0) {
- value = minutes;
- if (abbrev) {
- resId = R.plurals.Nmins;
- } else {
- resId = R.plurals.Nminutes;
- }
- } else if (minutes % (24 * 60) != 0) {
- value = minutes / 60;
- resId = R.plurals.Nhours;
- } else {
- value = minutes / ( 24 * 60);
- resId = R.plurals.Ndays;
- }
-
- String format = resources.getQuantityString(resId, value);
- return String.format(format, value);
- }
-
- private void updateRemindersVisibility() {
- if (mReminderItems.size() == 0) {
- mRemindersSeparator.setVisibility(View.GONE);
- mRemindersContainer.setVisibility(View.GONE);
- } else {
- mRemindersSeparator.setVisibility(View.VISIBLE);
- mRemindersContainer.setVisibility(View.VISIBLE);
- }
- }
-
- private void setDate(TextView view, long millis) {
- int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR |
- DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_MONTH |
- DateUtils.FORMAT_ABBREV_WEEKDAY;
- view.setText(DateUtils.formatDateTime(this, millis, flags));
- }
-
- private void setTime(TextView view, long millis) {
- int flags = DateUtils.FORMAT_SHOW_TIME;
- if (DateFormat.is24HourFormat(this)) {
- flags |= DateUtils.FORMAT_24HOUR;
- }
- view.setText(DateUtils.formatDateTime(this, millis, flags));
- }
-
- // Saves the event. Returns true if it is okay to exit this activity.
- private boolean save() {
- // If we are creating a new event, then make sure we wait until the
- // query to fetch the list of calendars has finished.
- if (mEventCursor == null) {
- if (!mCalendarsQueryComplete) {
- // Wait for the calendars query to finish.
- if (mLoadingCalendarsDialog == null) {
- // Create the progress dialog
- mLoadingCalendarsDialog = ProgressDialog.show(this,
- getText(R.string.loading_calendars_title),
- getText(R.string.loading_calendars_message),
- true, true, this);
- mSaveAfterQueryComplete = true;
- }
- return false;
- }
-
- // Avoid creating a new event if the calendars cursor is empty. This
- // shouldn't ever happen since the setup wizard should ensure the user
- // has a calendar.
- if (mCalendarsCursor == null || mCalendarsCursor.getCount() == 0) {
- Log.w("Cal", "The calendars table does not contain any calendars."
- + " New event was not created.");
- return true;
- }
- Toast.makeText(this, R.string.creating_event, Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(this, R.string.saving_event, Toast.LENGTH_SHORT).show();
- }
-
- ContentResolver cr = getContentResolver();
- ContentValues values = getContentValuesFromUi();
- Uri uri = mUri;
-
- // For recurring events, we must make sure that we use duration rather
- // than dtend.
- if (uri == null) {
- // Create new event with new contents
- addRecurrenceRule(values);
- uri = cr.insert(Events.CONTENT_URI, values);
-
- } else if (mRrule == null) {
- // Modify contents of a non-repeating event
- addRecurrenceRule(values);
- checkTimeDependentFields(values);
- cr.update(uri, values, null, null);
-
- } else if (mInitialValues.getAsString(Events.RRULE) == null) {
- // This event was changed from a non-repeating event to a
- // repeating event.
- addRecurrenceRule(values);
- values.remove(Events.DTEND);
- cr.update(uri, values, null, null);
-
- } else if (mModification == MODIFY_SELECTED) {
- // Modify contents of the current instance of repeating event
-
- // Create a recurrence exception
- long begin = mInitialValues.getAsLong(EVENT_BEGIN_TIME);
- values.put(Events.ORIGINAL_EVENT, mEventCursor.getString(EVENT_INDEX_SYNC_ID));
- values.put(Events.ORIGINAL_INSTANCE_TIME, begin);
- boolean allDay = mInitialValues.getAsInteger(Events.ALL_DAY) != 0;
- values.put(Events.ORIGINAL_ALL_DAY, allDay ? 1 : 0);
-
- uri = cr.insert(Events.CONTENT_URI, values);
-
- } else if (mModification == MODIFY_ALL_FOLLOWING) {
- // Modify this instance and all future instances of repeating event
- addRecurrenceRule(values);
-
- if (mRrule == null) {
- // We've changed a recurring event to a non-recurring event.
- // If the event we are editing is the first in the series,
- // then delete the whole series. Otherwise, update the series
- // to end at the new start time.
- if (isFirstEventInSeries()) {
- cr.delete(uri, null, null);
- } else {
- // Update the current repeating event to end at the new
- // start time.
- updatePastEvents(cr, uri);
- }
- uri = cr.insert(Events.CONTENT_URI, values);
- } else {
- if (isFirstEventInSeries()) {
- checkTimeDependentFields(values);
- values.remove(Events.DTEND);
- cr.update(uri, values, null, null);
- } else {
- // Update the current repeating event to end at the new
- // start time.
- updatePastEvents(cr, uri);
-
- // Create a new event with the user-modified fields
- values.remove(Events.DTEND);
- uri = cr.insert(Events.CONTENT_URI, values);
- }
- }
-
- } else if (mModification == MODIFY_ALL) {
-
- // Modify all instances of repeating event
- addRecurrenceRule(values);
-
- if (mRrule == null) {
- // We've changed a recurring event to a non-recurring event.
- // Delete the whole series and replace it with a new
- // non-recurring event.
- cr.delete(uri, null, null);
- uri = cr.insert(Events.CONTENT_URI, values);
- } else {
- checkTimeDependentFields(values);
- values.remove(Events.DTEND);
- cr.update(uri, values, null, null);
- }
- }
-
- if (uri != null) {
- long eventId = ContentUris.parseId(uri);
- ArrayList<Integer> reminderMinutes = reminderItemsToMinutes(mReminderItems,
- mReminderValues);
- saveReminders(cr, eventId, reminderMinutes, mOriginalMinutes);
- }
- return true;
- }
-
- private boolean isFirstEventInSeries() {
- int dtStart = mEventCursor.getColumnIndexOrThrow(Events.DTSTART);
- long start = mEventCursor.getLong(dtStart);
- return start == mStartTime.toMillis(true);
- }
-
- private void updatePastEvents(ContentResolver cr, Uri uri) {
- long oldStartMillis = mEventCursor.getLong(EVENT_INDEX_DTSTART);
- String oldDuration = mEventCursor.getString(EVENT_INDEX_DURATION);
- boolean allDay = mEventCursor.getInt(EVENT_INDEX_ALL_DAY) != 0;
- String oldRrule = mEventCursor.getString(EVENT_INDEX_RRULE);
- mEventRecurrence.parse(oldRrule);
-
- Time untilTime = new Time();
- long begin = mInitialValues.getAsLong(EVENT_BEGIN_TIME);
- ContentValues oldValues = new ContentValues();
-
- // The "until" time must be in UTC time in order for Google calendar
- // to display it properly. For all-day events, the "until" time string
- // must include just the date field, and not the time field. The
- // repeating events repeat up to and including the "until" time.
- untilTime.timezone = Time.TIMEZONE_UTC;
-
- // Subtract one second from the old begin time to get the new
- // "until" time.
- untilTime.set(begin - 1000); // subtract one second (1000 millis)
- if (allDay) {
- untilTime.hour = 0;
- untilTime.minute = 0;
- untilTime.second = 0;
- untilTime.allDay = true;
- untilTime.normalize(false);
-
- // For all-day events, the duration must be in days, not seconds.
- // Otherwise, Google Calendar will (mistakenly) change this event
- // into a non-all-day event.
- int len = oldDuration.length();
- if (oldDuration.charAt(0) == 'P' && oldDuration.charAt(len - 1) == 'S') {
- int seconds = Integer.parseInt(oldDuration.substring(1, len - 1));
- int days = (seconds + DAY_IN_SECONDS - 1) / DAY_IN_SECONDS;
- oldDuration = "P" + days + "D";
- }
- }
- mEventRecurrence.until = untilTime.format2445();
-
- oldValues.put(Events.DTSTART, oldStartMillis);
- oldValues.put(Events.DURATION, oldDuration);
- oldValues.put(Events.RRULE, mEventRecurrence.toString());
- cr.update(uri, oldValues, null, null);
- }
-
- private void checkTimeDependentFields(ContentValues values) {
- long oldBegin = mInitialValues.getAsLong(EVENT_BEGIN_TIME);
- long oldEnd = mInitialValues.getAsLong(EVENT_END_TIME);
- boolean oldAllDay = mInitialValues.getAsInteger(Events.ALL_DAY) != 0;
- String oldRrule = mInitialValues.getAsString(Events.RRULE);
- String oldTimezone = mInitialValues.getAsString(Events.EVENT_TIMEZONE);
-
- long newBegin = values.getAsLong(Events.DTSTART);
- long newEnd = values.getAsLong(Events.DTEND);
- boolean newAllDay = values.getAsInteger(Events.ALL_DAY) != 0;
- String newRrule = values.getAsString(Events.RRULE);
- String newTimezone = values.getAsString(Events.EVENT_TIMEZONE);
-
- // If none of the time-dependent fields changed, then remove them.
- if (oldBegin == newBegin && oldEnd == newEnd && oldAllDay == newAllDay
- && TextUtils.equals(oldRrule, newRrule)
- && TextUtils.equals(oldTimezone, newTimezone)) {
- values.remove(Events.DTSTART);
- values.remove(Events.DTEND);
- values.remove(Events.DURATION);
- values.remove(Events.ALL_DAY);
- values.remove(Events.RRULE);
- values.remove(Events.EVENT_TIMEZONE);
- return;
- }
-
- if (oldRrule == null || newRrule == null) {
- return;
- }
-
- // If we are modifying all events then we need to set DTSTART to the
- // start time of the first event in the series, not the current
- // date and time. If the start time of the event was changed
- // (from, say, 3pm to 4pm), then we want to add the time difference
- // to the start time of the first event in the series (the DTSTART
- // value). If we are modifying one instance or all following instances,
- // then we leave the DTSTART field alone.
- if (mModification == MODIFY_ALL) {
- long oldStartMillis = mEventCursor.getLong(EVENT_INDEX_DTSTART);
- if (oldBegin != newBegin) {
- // The user changed the start time of this event
- long offset = newBegin - oldBegin;
- oldStartMillis += offset;
- }
- values.put(Events.DTSTART, oldStartMillis);
- }
- }
-
- static ArrayList<Integer> reminderItemsToMinutes(ArrayList<LinearLayout> reminderItems,
- ArrayList<Integer> reminderValues) {
- int len = reminderItems.size();
- ArrayList<Integer> reminderMinutes = new ArrayList<Integer>(len);
- for (int index = 0; index < len; index++) {
- LinearLayout layout = reminderItems.get(index);
- Spinner spinner = (Spinner) layout.findViewById(R.id.reminder_value);
- int minutes = reminderValues.get(spinner.getSelectedItemPosition());
- reminderMinutes.add(minutes);
- }
- return reminderMinutes;
- }
-
- /**
- * Saves the reminders, if they changed. Returns true if the database
- * was updated.
- *
- * @param cr the ContentResolver
- * @param eventId the id of the event whose reminders are being updated
- * @param reminderMinutes the array of reminders set by the user
- * @param originalMinutes the original array of reminders
- * @return true if the database was updated
- */
- static boolean saveReminders(ContentResolver cr, long eventId,
- ArrayList<Integer> reminderMinutes, ArrayList<Integer> originalMinutes) {
- // If the reminders have not changed, then don't update the database
- if (reminderMinutes.equals(originalMinutes)) {
- return false;
- }
-
- // Delete all the existing reminders for this event
- String where = Reminders.EVENT_ID + "=?";
- String[] args = new String[] { Long.toString(eventId) };
- cr.delete(Reminders.CONTENT_URI, where, args);
-
- // Update the "hasAlarm" field for the event
- ContentValues values = new ContentValues();
- int len = reminderMinutes.size();
- values.put(Events.HAS_ALARM, (len > 0) ? 1 : 0);
- Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId);
- cr.update(uri, values, null /* where */, null /* selection args */);
-
- // Insert the new reminders, if any
- for (int i = 0; i < len; i++) {
- int minutes = reminderMinutes.get(i);
-
- values.clear();
- values.put(Reminders.MINUTES, minutes);
- values.put(Reminders.METHOD, Reminders.METHOD_ALERT);
- values.put(Reminders.EVENT_ID, eventId);
- cr.insert(Reminders.CONTENT_URI, values);
- }
- return true;
- }
-
- private void addRecurrenceRule(ContentValues values) {
- updateRecurrenceRule();
-
- if (mRrule == null) {
- return;
- }
-
- values.put(Events.RRULE, mRrule);
- long end = mEndTime.toMillis(true /* ignore dst */);
- long start = mStartTime.toMillis(true /* ignore dst */);
- String duration;
-
- boolean isAllDay = mAllDayCheckBox.isChecked();
- if (isAllDay) {
- long days = (end - start + DateUtils.DAY_IN_MILLIS - 1) / DateUtils.DAY_IN_MILLIS;
- duration = "P" + days + "D";
- } else {
- long seconds = (end - start) / DateUtils.SECOND_IN_MILLIS;
- duration = "P" + seconds + "S";
- }
- values.put(Events.DURATION, duration);
- }
-
- private void updateRecurrenceRule() {
- int position = mRepeatsSpinner.getSelectedItemPosition();
- int selection = mRecurrenceIndexes.get(position);
-
- if (selection == DOES_NOT_REPEAT) {
- mRrule = null;
- return;
- } else if (selection == REPEATS_CUSTOM) {
- // Keep custom recurrence as before.
- return;
- } else if (selection == REPEATS_DAILY) {
- mEventRecurrence.freq = EventRecurrence.DAILY;
- } else if (selection == REPEATS_EVERY_WEEKDAY) {
- mEventRecurrence.freq = EventRecurrence.WEEKLY;
- int dayCount = 5;
- int[] byday = new int[dayCount];
- int[] bydayNum = new int[dayCount];
-
- byday[0] = EventRecurrence.MO;
- byday[1] = EventRecurrence.TU;
- byday[2] = EventRecurrence.WE;
- byday[3] = EventRecurrence.TH;
- byday[4] = EventRecurrence.FR;
- for (int day = 0; day < dayCount; day++) {
- bydayNum[day] = 0;
- }
-
- mEventRecurrence.byday = byday;
- mEventRecurrence.bydayNum = bydayNum;
- mEventRecurrence.bydayCount = dayCount;
- } else if (selection == REPEATS_WEEKLY_ON_DAY) {
- mEventRecurrence.freq = EventRecurrence.WEEKLY;
- int[] days = new int[1];
- int dayCount = 1;
- int[] dayNum = new int[dayCount];
-
- days[0] = EventRecurrence.timeDay2Day(mStartTime.weekDay);
- // not sure why this needs to be zero, but set it for now.
- dayNum[0] = 0;
-
- mEventRecurrence.byday = days;
- mEventRecurrence.bydayNum = dayNum;
- mEventRecurrence.bydayCount = dayCount;
- } else if (selection == REPEATS_MONTHLY_ON_DAY) {
- mEventRecurrence.freq = EventRecurrence.MONTHLY;
- mEventRecurrence.bydayCount = 0;
- mEventRecurrence.bymonthdayCount = 1;
- int[] bymonthday = new int[1];
- bymonthday[0] = mStartTime.monthDay;
- mEventRecurrence.bymonthday = bymonthday;
- } else if (selection == REPEATS_MONTHLY_ON_DAY_COUNT) {
- mEventRecurrence.freq = EventRecurrence.MONTHLY;
- mEventRecurrence.bydayCount = 1;
- mEventRecurrence.bymonthdayCount = 0;
-
- int[] byday = new int[1];
- int[] bydayNum = new int[1];
- // Compute the week number (for example, the "2nd" Monday)
- int dayCount = 1 + ((mStartTime.monthDay - 1) / 7);
- if (dayCount == 5) {
- dayCount = -1;
- }
- bydayNum[0] = dayCount;
- byday[0] = EventRecurrence.timeDay2Day(mStartTime.weekDay);
- mEventRecurrence.byday = byday;
- mEventRecurrence.bydayNum = bydayNum;
- } else if (selection == REPEATS_YEARLY) {
- mEventRecurrence.freq = EventRecurrence.YEARLY;
- }
-
- // Set the week start day.
- mEventRecurrence.wkst = EventRecurrence.calendarDay2Day(mFirstDayOfWeek);
- mRrule = mEventRecurrence.toString();
- }
-
- private ContentValues getContentValuesFromUi() {
- String title = mTitleTextView.getText().toString();
- boolean isAllDay = mAllDayCheckBox.isChecked();
- String location = mLocationTextView.getText().toString();
- String description = mDescriptionTextView.getText().toString();
-
- ContentValues values = new ContentValues();
-
- String timezone = null;
- long startMillis;
- long endMillis;
- long calendarId;
- if (isAllDay) {
- // Reset start and end time, increment the monthDay by 1, and set
- // the timezone to UTC, as required for all-day events.
- timezone = Time.TIMEZONE_UTC;
- mStartTime.hour = 0;
- mStartTime.minute = 0;
- mStartTime.second = 0;
- mStartTime.timezone = timezone;
- startMillis = mStartTime.normalize(true);
-
- mEndTime.hour = 0;
- mEndTime.minute = 0;
- mEndTime.second = 0;
- mEndTime.monthDay++;
- mEndTime.timezone = timezone;
- endMillis = mEndTime.normalize(true);
-
- if (mEventCursor == null) {
- // This is a new event
- calendarId = mCalendarsSpinner.getSelectedItemId();
- } else {
- calendarId = mInitialValues.getAsLong(Events.CALENDAR_ID);
- }
- } else {
- startMillis = mStartTime.toMillis(true);
- endMillis = mEndTime.toMillis(true);
- if (mEventCursor != null) {
- // This is an existing event
- timezone = mEventCursor.getString(EVENT_INDEX_TIMEZONE);
-
- // The timezone might be null if we are changing an existing
- // all-day event to a non-all-day event. We need to assign
- // a timezone to the non-all-day event.
- if (TextUtils.isEmpty(timezone)) {
- timezone = TimeZone.getDefault().getID();
- }
- calendarId = mInitialValues.getAsLong(Events.CALENDAR_ID);
- } else {
- // This is a new event
- calendarId = mCalendarsSpinner.getSelectedItemId();
-
- // The timezone for a new event is the currently displayed
- // timezone, NOT the timezone of the containing calendar.
- timezone = TimeZone.getDefault().getID();
- }
- }
-
- values.put(Events.CALENDAR_ID, calendarId);
- values.put(Events.EVENT_TIMEZONE, timezone);
- values.put(Events.TITLE, title);
- values.put(Events.ALL_DAY, isAllDay ? 1 : 0);
- values.put(Events.DTSTART, startMillis);
- values.put(Events.DTEND, endMillis);
- values.put(Events.DESCRIPTION, description);
- values.put(Events.EVENT_LOCATION, location);
- values.put(Events.TRANSPARENCY, mAvailabilitySpinner.getSelectedItemPosition());
-
- int visibility = mVisibilitySpinner.getSelectedItemPosition();
- if (visibility > 0) {
- // For now we the array contains the values 0, 2, and 3. We add one to match.
- visibility++;
- }
- values.put(Events.VISIBILITY, visibility);
-
- return values;
- }
-
- private boolean isEmpty() {
- String title = mTitleTextView.getText().toString();
- if (title.length() > 0) {
- return false;
- }
-
- String location = mLocationTextView.getText().toString();
- if (location.length() > 0) {
- return false;
- }
-
- String description = mDescriptionTextView.getText().toString();
- if (description.length() > 0) {
- return false;
- }
-
- return true;
- }
-
- private boolean isCustomRecurrence() {
-
- if (mEventRecurrence.until != null || mEventRecurrence.interval != 0) {
- return true;
- }
-
- if (mEventRecurrence.freq == 0) {
- return false;
- }
-
- switch (mEventRecurrence.freq) {
- case EventRecurrence.DAILY:
- return false;
- case EventRecurrence.WEEKLY:
- if (mEventRecurrence.repeatsOnEveryWeekDay() && isWeekdayEvent()) {
- return false;
- } else if (mEventRecurrence.bydayCount == 1) {
- return false;
- }
- break;
- case EventRecurrence.MONTHLY:
- if (mEventRecurrence.repeatsMonthlyOnDayCount()) {
- return false;
- } else if (mEventRecurrence.bydayCount == 0 && mEventRecurrence.bymonthdayCount == 1) {
- return false;
- }
- break;
- case EventRecurrence.YEARLY:
- return false;
- }
-
- return true;
- }
-
- private boolean isWeekdayEvent() {
- if (mStartTime.weekDay != Time.SUNDAY && mStartTime.weekDay != Time.SATURDAY) {
- return true;
- }
- return false;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2009 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.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.widget.Button;
-
-/**
- * A helper class for editing the response to an invitation when the invitation
- * is a repeating event.
- */
-public class EditResponseHelper implements DialogInterface.OnClickListener {
- private final Activity mParent;
- private int mWhichEvents = -1;
- private AlertDialog mAlertDialog;
-
- /**
- * This callback is passed in to this object when this object is created
- * and is invoked when the "Ok" button is selected.
- */
- private DialogInterface.OnClickListener mDialogListener;
-
- public EditResponseHelper(Activity parent) {
- mParent = parent;
- }
-
- public void setOnClickListener(DialogInterface.OnClickListener listener) {
- mDialogListener = listener;
- }
-
- public int getWhichEvents() {
- return mWhichEvents;
- }
-
- public void onClick(DialogInterface dialog, int which) {
- }
-
- /**
- * This callback is used when a list item is selected
- */
- private DialogInterface.OnClickListener mListListener =
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- mWhichEvents = which;
-
- // Enable the "ok" button now that the user has selected which
- // events in the series to delete.
- Button ok = mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
- ok.setEnabled(true);
- }
- };
-
- public void showDialog(int whichEvents) {
- // We need to have a non-null listener, otherwise we get null when
- // we try to fetch the "Ok" button.
- if (mDialogListener == null) {
- mDialogListener = this;
- }
- AlertDialog dialog = new AlertDialog.Builder(mParent)
- .setTitle(R.string.change_response_title)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setSingleChoiceItems(R.array.change_response_labels, whichEvents,
- mListListener)
- .setPositiveButton(android.R.string.ok, mDialogListener)
- .setNegativeButton(android.R.string.cancel, null)
- .show();
- mAlertDialog = dialog;
-
- if (whichEvents == -1) {
- // Disable the "Ok" button until the user selects which events to
- // delete.
- Button ok = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
- ok.setEnabled(false);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007 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.SharedPreferences;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.os.Debug;
-import android.preference.PreferenceManager;
-import android.provider.Calendar.Attendees;
-import android.provider.Calendar.Instances;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.text.format.Time;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.concurrent.atomic.AtomicInteger;
-
-// TODO: should Event be Parcelable so it can be passed via Intents?
-public class Event implements Comparable, Cloneable {
-
- private static final boolean PROFILE = false;
-
- private static final String[] PROJECTION = new String[] {
- Instances.TITLE, // 0
- Instances.EVENT_LOCATION, // 1
- Instances.ALL_DAY, // 2
- Instances.COLOR, // 3
- Instances.EVENT_TIMEZONE, // 4
- Instances.EVENT_ID, // 5
- Instances.BEGIN, // 6
- Instances.END, // 7
- Instances._ID, // 8
- Instances.START_DAY, // 9
- Instances.END_DAY, // 10
- Instances.START_MINUTE, // 11
- Instances.END_MINUTE, // 12
- Instances.HAS_ALARM, // 13
- Instances.RRULE, // 14
- Instances.RDATE, // 15
- Instances.SELF_ATTENDEE_STATUS, // 16
- };
-
- // The indices for the projection array above.
- private static final int PROJECTION_TITLE_INDEX = 0;
- private static final int PROJECTION_LOCATION_INDEX = 1;
- private static final int PROJECTION_ALL_DAY_INDEX = 2;
- private static final int PROJECTION_COLOR_INDEX = 3;
- private static final int PROJECTION_TIMEZONE_INDEX = 4;
- private static final int PROJECTION_EVENT_ID_INDEX = 5;
- private static final int PROJECTION_BEGIN_INDEX = 6;
- private static final int PROJECTION_END_INDEX = 7;
- private static final int PROJECTION_START_DAY_INDEX = 9;
- private static final int PROJECTION_END_DAY_INDEX = 10;
- private static final int PROJECTION_START_MINUTE_INDEX = 11;
- private static final int PROJECTION_END_MINUTE_INDEX = 12;
- private static final int PROJECTION_HAS_ALARM_INDEX = 13;
- private static final int PROJECTION_RRULE_INDEX = 14;
- private static final int PROJECTION_RDATE_INDEX = 15;
- private static final int PROJECTION_SELF_ATTENDEE_STATUS_INDEX = 16;
-
- public long id;
- public int color;
- public CharSequence title;
- public CharSequence location;
- public boolean allDay;
-
- public int startDay; // start Julian day
- public int endDay; // end Julian day
- public int startTime; // Start and end time are in minutes since midnight
- public int endTime;
-
- public long startMillis; // UTC milliseconds since the epoch
- public long endMillis; // UTC milliseconds since the epoch
- private int mColumn;
- private int mMaxColumns;
-
- public boolean hasAlarm;
- public boolean isRepeating;
-
- public int selfAttendeeStatus;
-
- // The coordinates of the event rectangle drawn on the screen.
- public float left;
- public float right;
- public float top;
- public float bottom;
-
- // These 4 fields are used for navigating among events within the selected
- // hour in the Day and Week view.
- public Event nextRight;
- public Event nextLeft;
- public Event nextUp;
- public Event nextDown;
-
- private static final int MIDNIGHT_IN_MINUTES = 24 * 60;
-
- @Override
- public final Object clone() {
- Event e = new Event();
-
- e.title = title;
- e.color = color;
- e.location = location;
- e.allDay = allDay;
- e.startDay = startDay;
- e.endDay = endDay;
- e.startTime = startTime;
- e.endTime = endTime;
- e.startMillis = startMillis;
- e.endMillis = endMillis;
- e.hasAlarm = hasAlarm;
- e.isRepeating = isRepeating;
- e.selfAttendeeStatus = selfAttendeeStatus;
-
- return e;
- }
-
- public final void copyTo(Event dest) {
- dest.id = id;
- dest.title = title;
- dest.color = color;
- dest.location = location;
- dest.allDay = allDay;
- dest.startDay = startDay;
- dest.endDay = endDay;
- dest.startTime = startTime;
- dest.endTime = endTime;
- dest.startMillis = startMillis;
- dest.endMillis = endMillis;
- dest.hasAlarm = hasAlarm;
- dest.isRepeating = isRepeating;
- dest.selfAttendeeStatus = selfAttendeeStatus;
- }
-
- public static final Event newInstance() {
- Event e = new Event();
-
- e.id = 0;
- e.title = null;
- e.color = 0;
- e.location = null;
- e.allDay = false;
- e.startDay = 0;
- e.endDay = 0;
- e.startTime = 0;
- e.endTime = 0;
- e.startMillis = 0;
- e.endMillis = 0;
- e.hasAlarm = false;
- e.isRepeating = false;
- e.selfAttendeeStatus = Attendees.ATTENDEE_STATUS_NONE;
-
- return e;
- }
-
- /**
- * Compares this event to the given event. This is just used for checking
- * if two events differ. It's not used for sorting anymore.
- */
- public final int compareTo(Object obj) {
- Event e = (Event) obj;
-
- // The earlier start day and time comes first
- if (startDay < e.startDay) return -1;
- if (startDay > e.startDay) return 1;
- if (startTime < e.startTime) return -1;
- if (startTime > e.startTime) return 1;
-
- // The later end time comes first (in order to put long strips on
- // the left).
- if (endDay < e.endDay) return 1;
- if (endDay > e.endDay) return -1;
- if (endTime < e.endTime) return 1;
- if (endTime > e.endTime) return -1;
-
- // Sort all-day events before normal events.
- if (allDay && !e.allDay) return -1;
- if (!allDay && e.allDay) return 1;
-
- // If two events have the same time range, then sort them in
- // alphabetical order based on their titles.
- int cmp = compareStrings(title, e.title);
- if (cmp != 0) {
- return cmp;
- }
-
- // If the titles are the same then compare the other fields
- // so that we can use this function to check for differences
- // between events.
- cmp = compareStrings(location, e.location);
- if (cmp != 0) {
- return cmp;
- }
- return 0;
- }
-
- /**
- * Compare string a with string b, but if either string is null,
- * then treat it (the null) as if it were the empty string ("").
- *
- * @param a the first string
- * @param b the second string
- * @return the result of comparing a with b after replacing null
- * strings with "".
- */
- private int compareStrings(CharSequence a, CharSequence b) {
- String aStr, bStr;
- if (a != null) {
- aStr = a.toString();
- } else {
- aStr = "";
- }
- if (b != null) {
- bStr = b.toString();
- } else {
- bStr = "";
- }
- return aStr.compareTo(bStr);
- }
-
- /**
- * Loads <i>days</i> days worth of instances starting at <i>start</i>.
- */
- public static void loadEvents(Context context, ArrayList<Event> events,
- long start, int days, int requestId, AtomicInteger sequenceNumber) {
-
- if (PROFILE) {
- Debug.startMethodTracing("loadEvents");
- }
-
- Cursor c = null;
-
- events.clear();
- try {
- Time local = new Time();
- int count;
-
- local.set(start);
- int startDay = Time.getJulianDay(start, local.gmtoff);
- int endDay = startDay + days;
-
- local.monthDay += days;
- long end = local.normalize(true /* ignore isDst */);
-
- // Widen the time range that we query by one day on each end
- // so that we can catch all-day events. All-day events are
- // stored starting at midnight in UTC but should be included
- // in the list of events starting at midnight local time.
- // This may fetch more events than we actually want, so we
- // filter them out below.
- //
- // The sort order is: events with an earlier start time occur
- // first and if the start times are the same, then events with
- // a later end time occur first. The later end time is ordered
- // first so that long rectangles in the calendar views appear on
- // the left side. If the start and end times of two events are
- // the same then we sort alphabetically on the title. This isn't
- // required for correctness, it just adds a nice touch.
-
- String orderBy = Instances.SORT_CALENDAR_VIEW;
-
- // Respect the preference to show/hide declined events
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
- boolean hideDeclined = prefs.getBoolean(CalendarPreferenceActivity.KEY_HIDE_DECLINED,
- false);
-
- String where = null;
- if (hideDeclined) {
- where = Instances.SELF_ATTENDEE_STATUS + "!=" + Attendees.ATTENDEE_STATUS_DECLINED;
- }
-
- c = Instances.query(context.getContentResolver(), PROJECTION,
- start - DateUtils.DAY_IN_MILLIS, end + DateUtils.DAY_IN_MILLIS, where, orderBy);
-
- if (c == null) {
- Log.e("Cal", "loadEvents() returned null cursor!");
- return;
- }
-
- // Check if we should return early because there are more recent
- // load requests waiting.
- if (requestId != sequenceNumber.get()) {
- return;
- }
-
- count = c.getCount();
-
- if (count == 0) {
- return;
- }
-
- Resources res = context.getResources();
- while (c.moveToNext()) {
- Event e = new Event();
-
- e.id = c.getLong(PROJECTION_EVENT_ID_INDEX);
- e.title = c.getString(PROJECTION_TITLE_INDEX);
- e.location = c.getString(PROJECTION_LOCATION_INDEX);
- e.allDay = c.getInt(PROJECTION_ALL_DAY_INDEX) != 0;
- String timezone = c.getString(PROJECTION_TIMEZONE_INDEX);
-
- if (e.title == null || e.title.length() == 0) {
- e.title = res.getString(R.string.no_title_label);
- }
-
- if (!c.isNull(PROJECTION_COLOR_INDEX)) {
- // Read the color from the database
- e.color = c.getInt(PROJECTION_COLOR_INDEX);
- } else {
- e.color = res.getColor(R.color.event_center);
- }
-
- long eStart = c.getLong(PROJECTION_BEGIN_INDEX);
- long eEnd = c.getLong(PROJECTION_END_INDEX);
-
- e.startMillis = eStart;
- e.startTime = c.getInt(PROJECTION_START_MINUTE_INDEX);
- e.startDay = c.getInt(PROJECTION_START_DAY_INDEX);
-
- e.endMillis = eEnd;
- e.endTime = c.getInt(PROJECTION_END_MINUTE_INDEX);
- e.endDay = c.getInt(PROJECTION_END_DAY_INDEX);
-
- if (e.startDay > endDay || e.endDay < startDay) {
- continue;
- }
-
- e.hasAlarm = c.getInt(PROJECTION_HAS_ALARM_INDEX) != 0;
-
- // Check if this is a repeating event
- String rrule = c.getString(PROJECTION_RRULE_INDEX);
- String rdate = c.getString(PROJECTION_RDATE_INDEX);
- if (!TextUtils.isEmpty(rrule) || !TextUtils.isEmpty(rdate)) {
- e.isRepeating = true;
- } else {
- e.isRepeating = false;
- }
-
- e.selfAttendeeStatus = c.getInt(PROJECTION_SELF_ATTENDEE_STATUS_INDEX);
-
- events.add(e);
- }
-
- computePositions(events);
- } finally {
- if (c != null) {
- c.close();
- }
- if (PROFILE) {
- Debug.stopMethodTracing();
- }
- }
- }
-
- /**
- * Computes a position for each event. Each event is displayed
- * as a non-overlapping rectangle. For normal events, these rectangles
- * are displayed in separate columns in the week view and day view. For
- * all-day events, these rectangles are displayed in separate rows along
- * the top. In both cases, each event is assigned two numbers: N, and
- * Max, that specify that this event is the Nth event of Max number of
- * events that are displayed in a group. The width and position of each
- * rectangle depend on the maximum number of rectangles that occur at
- * the same time.
- *
- * @param eventsList the list of events, sorted into increasing time order
- */
- static void computePositions(ArrayList<Event> eventsList) {
- if (eventsList == null)
- return;
-
- // Compute the column positions separately for the all-day events
- doComputePositions(eventsList, false);
- doComputePositions(eventsList, true);
- }
-
- private static void doComputePositions(ArrayList<Event> eventsList,
- boolean doAllDayEvents) {
- ArrayList<Event> activeList = new ArrayList<Event>();
- ArrayList<Event> groupList = new ArrayList<Event>();
-
- long colMask = 0;
- int maxCols = 0;
- for (Event event : eventsList) {
- // Process all-day events separately
- if (event.allDay != doAllDayEvents)
- continue;
-
- long start = event.getStartMillis();
- if (false && event.allDay) {
- Event e = event;
- Log.i("Cal", "event start,end day: " + e.startDay + "," + e.endDay
- + " start,end time: " + e.startTime + "," + e.endTime
- + " start,end millis: " + e.getStartMillis() + "," + e.getEndMillis()
- + " " + e.title);
- }
-
- // Remove the inactive events. An event on the active list
- // becomes inactive when its end time is less than or equal to
- // the current event's start time.
- Iterator<Event> iter = activeList.iterator();
- while (iter.hasNext()) {
- Event active = iter.next();
- if (active.getEndMillis() <= start) {
- if (false && event.allDay) {
- Event e = active;
- Log.i("Cal", " removing: start,end day: " + e.startDay + "," + e.endDay
- + " start,end time: " + e.startTime + "," + e.endTime
- + " start,end millis: " + e.getStartMillis() + "," + e.getEndMillis()
- + " " + e.title);
- }
- colMask &= ~(1L << active.getColumn());
- iter.remove();
- }
- }
-
- // If the active list is empty, then reset the max columns, clear
- // the column bit mask, and empty the groupList.
- if (activeList.isEmpty()) {
- for (Event ev : groupList) {
- ev.setMaxColumns(maxCols);
- }
- maxCols = 0;
- colMask = 0;
- groupList.clear();
- }
-
- // Find the first empty column. Empty columns are represented by
- // zero bits in the column mask "colMask".
- int col = findFirstZeroBit(colMask);
- if (col == 64)
- col = 63;
- colMask |= (1L << col);
- event.setColumn(col);
- activeList.add(event);
- groupList.add(event);
- int len = activeList.size();
- if (maxCols < len)
- maxCols = len;
- }
- for (Event ev : groupList) {
- ev.setMaxColumns(maxCols);
- }
- }
-
- public static int findFirstZeroBit(long val) {
- for (int ii = 0; ii < 64; ++ii) {
- if ((val & (1L << ii)) == 0)
- return ii;
- }
- return 64;
- }
-
- /**
- * Returns a darker version of the given color. It does this by dividing
- * each of the red, green, and blue components by 2. The alpha value is
- * preserved.
- */
- private static final int getDarkerColor(int color) {
- int darker = (color >> 1) & 0x007f7f7f;
- int alpha = color & 0xff000000;
- return alpha | darker;
- }
-
- // For testing. This method can be removed at any time.
- private static ArrayList<Event> createTestEventList() {
- ArrayList<Event> evList = new ArrayList<Event>();
- createTestEvent(evList, 1, 5, 10);
- createTestEvent(evList, 2, 5, 10);
- createTestEvent(evList, 3, 15, 20);
- createTestEvent(evList, 4, 20, 25);
- createTestEvent(evList, 5, 30, 70);
- createTestEvent(evList, 6, 32, 40);
- createTestEvent(evList, 7, 32, 40);
- createTestEvent(evList, 8, 34, 38);
- createTestEvent(evList, 9, 34, 38);
- createTestEvent(evList, 10, 42, 50);
- createTestEvent(evList, 11, 45, 60);
- createTestEvent(evList, 12, 55, 90);
- createTestEvent(evList, 13, 65, 75);
-
- createTestEvent(evList, 21, 105, 130);
- createTestEvent(evList, 22, 110, 120);
- createTestEvent(evList, 23, 115, 130);
- createTestEvent(evList, 24, 125, 140);
- createTestEvent(evList, 25, 127, 135);
-
- createTestEvent(evList, 31, 150, 160);
- createTestEvent(evList, 32, 152, 162);
- createTestEvent(evList, 33, 153, 163);
- createTestEvent(evList, 34, 155, 170);
- createTestEvent(evList, 35, 158, 175);
- createTestEvent(evList, 36, 165, 180);
-
- return evList;
- }
-
- // For testing. This method can be removed at any time.
- private static Event createTestEvent(ArrayList<Event> evList, int id,
- int startMinute, int endMinute) {
- Event ev = new Event();
- ev.title = "ev" + id;
- ev.startDay = 1;
- ev.endDay = 1;
- ev.setStartMillis(startMinute);
- ev.setEndMillis(endMinute);
- evList.add(ev);
- return ev;
- }
-
- public final void dump() {
- Log.e("Cal", "+-----------------------------------------+");
- Log.e("Cal", "+ id = " + id);
- Log.e("Cal", "+ color = " + color);
- Log.e("Cal", "+ title = " + title);
- Log.e("Cal", "+ location = " + location);
- Log.e("Cal", "+ allDay = " + allDay);
- Log.e("Cal", "+ startDay = " + startDay);
- Log.e("Cal", "+ endDay = " + endDay);
- Log.e("Cal", "+ startTime = " + startTime);
- Log.e("Cal", "+ endTime = " + endTime);
- }
-
- public final boolean intersects(int julianDay, int startMinute,
- int endMinute) {
- if (endDay < julianDay) {
- return false;
- }
-
- if (startDay > julianDay) {
- return false;
- }
-
- if (endDay == julianDay) {
- if (endTime < startMinute) {
- return false;
- }
- // An event that ends at the start minute should not be considered
- // as intersecting the given time span, but don't exclude
- // zero-length (or very short) events.
- if (endTime == startMinute
- && (startTime != endTime || startDay != endDay)) {
- return false;
- }
- }
-
- if (startDay == julianDay && startTime > endMinute) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Returns the event title and location separated by a comma. If the
- * location is already part of the title (at the end of the title), then
- * just the title is returned.
- *
- * @return the event title and location as a String
- */
- public String getTitleAndLocation() {
- String text = title.toString();
-
- // Append the location to the title, unless the title ends with the
- // location (for example, "meeting in building 42" ends with the
- // location).
- if (location != null) {
- String locationString = location.toString();
- if (!text.endsWith(locationString)) {
- text += ", " + locationString;
- }
- }
- return text;
- }
-
- public void setColumn(int column) {
- mColumn = column;
- }
-
- public int getColumn() {
- return mColumn;
- }
-
- public void setMaxColumns(int maxColumns) {
- mMaxColumns = maxColumns;
- }
-
- public int getMaxColumns() {
- return mMaxColumns;
- }
-
- public void setStartMillis(long startMillis) {
- this.startMillis = startMillis;
- }
-
- public long getStartMillis() {
- return startMillis;
- }
-
- public void setEndMillis(long endMillis) {
- this.endMillis = endMillis;
- }
-
- public long getEndMillis() {
- return endMillis;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2008 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.graphics.Rect;
-
-public class EventGeometry {
- // This is the space from the grid line to the event rectangle.
- private int mCellMargin = 0;
-
- private float mMinuteHeight;
-
- private float mHourGap;
- private float mMinEventHeight;
-
- void setCellMargin(int cellMargin) {
- mCellMargin = cellMargin;
- }
-
- void setHourGap(float gap) {
- mHourGap = gap;
- }
-
- void setMinEventHeight(float height) {
- mMinEventHeight = height;
- }
-
- void setHourHeight(float height) {
- mMinuteHeight = height / 60.0f;
- }
-
- // Computes the rectangle coordinates of the given event on the screen.
- // Returns true if the rectangle is visible on the screen.
- boolean computeEventRect(int date, int left, int top, int cellWidth, Event event) {
- if (event.allDay) {
- return false;
- }
-
- float cellMinuteHeight = mMinuteHeight;
- int startDay = event.startDay;
- int endDay = event.endDay;
-
- if (startDay > date || endDay < date) {
- return false;
- }
-
- int startTime = event.startTime;
- int endTime = event.endTime;
-
- // If the event started on a previous day, then show it starting
- // at the beginning of this day.
- if (startDay < date) {
- startTime = 0;
- }
-
- // If the event ends on a future day, then show it extending to
- // the end of this day.
- if (endDay > date) {
- endTime = CalendarView.MINUTES_PER_DAY;
- }
-
- int col = event.getColumn();
- int maxCols = event.getMaxColumns();
- int startHour = startTime / 60;
- int endHour = endTime / 60;
-
- // If the end point aligns on a cell boundary then count it as
- // ending in the previous cell so that we don't cross the border
- // between hours.
- if (endHour * 60 == endTime)
- endHour -= 1;
-
- event.top = top;
- event.top += (int) (startTime * cellMinuteHeight);
- event.top += startHour * mHourGap;
-
- event.bottom = top;
- event.bottom += (int) (endTime * cellMinuteHeight);
- event.bottom += endHour * mHourGap;
-
- // Make the rectangle be at least mMinEventHeight pixels high
- if (event.bottom < event.top + mMinEventHeight) {
- event.bottom = event.top + mMinEventHeight;
- }
-
- float colWidth = (float) (cellWidth - 2 * mCellMargin) / (float) maxCols;
- event.left = left + mCellMargin + col * colWidth;
- event.right = event.left + colWidth;
- return true;
- }
-
- // Computes the busy bits. For each interval containing "interval" minutes,
- // the busy bit for that interval is set to 1 if the given event overlaps
- // that interval.
- void computeBusyBits(int firstDate, int numDays, byte[][] busyBits, Event event, int interval) {
- if (event.allDay) {
- return;
- }
-
- int endDate = firstDate + numDays;
- int startDay = event.startDay;
- int endDay = event.endDay;
- if (startDay >= endDate || endDay < firstDate) {
- return;
- }
-
- int startTime = event.startTime;
-
- int day = startDay;
-
- // If the event started on a previous day, then show it starting
- // at the beginning of this day.
- if (day < firstDate) {
- day = firstDate;
- startTime = 0;
- }
-
- if (endDay >= endDate) {
- endDay = endDate - 1;
- }
-
- int dayIndex = day - firstDate;
- while (day <= endDay) {
- int endTime = event.endTime;
- // If the event ends on a future day, then show it extending to
- // the end of this day.
- if (endDay > day) {
- endTime = CalendarView.MINUTES_PER_DAY;
- }
-
- int startInterval = startTime / interval;
- int endInterval = (endTime + interval - 1) / interval;
-
- for (int ii = startInterval; ii < endInterval; ii++) {
- busyBits[dayIndex][ii] = 1;
- }
- day += 1;
- dayIndex += 1;
- startTime = 0;
- }
- }
-
- /**
- * Returns true if this event intersects the selection region.
- */
- boolean eventIntersectsSelection(Event event, Rect selection) {
- if (event.left < selection.right && event.right >= selection.left
- && event.top < selection.bottom && event.bottom >= selection.top) {
- return true;
- }
- return false;
- }
-
- /**
- * Computes the distance from the given point to the given event.
- */
- float pointToEvent(float x, float y, Event event) {
- float left = event.left;
- float right = event.right;
- float top = event.top;
- float bottom = event.bottom;
-
- if (x >= left) {
- if (x <= right) {
- if (y >= top) {
- if (y <= bottom) {
- // x,y is inside the event rectangle
- return 0f;
- }
- // x,y is below the event rectangle
- return y - bottom;
- }
- // x,y is above the event rectangle
- return top - y;
- }
-
- // x > right
- float dx = x - right;
- if (y < top) {
- // the upper right corner
- float dy = top - y;
- return (float) Math.sqrt(dx * dx + dy * dy);
- }
- if (y > bottom) {
- // the lower right corner
- float dy = y - bottom;
- return (float) Math.sqrt(dx * dx + dy * dy);
- }
- // x,y is to the right of the event rectangle
- return dx;
- }
- // x < left
- float dx = left - x;
- if (y < top) {
- // the upper left corner
- float dy = top - y;
- return (float) Math.sqrt(dx * dx + dy * dy);
- }
- if (y > bottom) {
- // the lower left corner
- float dy = y - bottom;
- return (float) Math.sqrt(dx * dx + dy * dy);
- }
- // x,y is to the left of the event rectangle
- return dx;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007 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 static android.provider.Calendar.EVENT_BEGIN_TIME;
-import static android.provider.Calendar.EVENT_END_TIME;
-
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.graphics.PorterDuff;
-import android.net.Uri;
-import android.os.Bundle;
-import android.pim.EventRecurrence;
-import android.preference.PreferenceManager;
-import android.provider.Calendar;
-import android.provider.Calendar.Attendees;
-import android.provider.Calendar.Calendars;
-import android.provider.Calendar.Events;
-import android.provider.Calendar.Reminders;
-import android.text.format.DateFormat;
-import android.text.format.DateUtils;
-import android.text.format.Time;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.Spinner;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-public class EventInfoActivity extends Activity implements View.OnClickListener,
- AdapterView.OnItemSelectedListener {
- private static final int MAX_REMINDERS = 5;
-
- /**
- * These are the corresponding indices into the array of strings
- * "R.array.change_response_labels" in the resource file.
- */
- static final int UPDATE_SINGLE = 0;
- static final int UPDATE_ALL = 1;
-
- private static final String[] EVENT_PROJECTION = new String[] {
- Events._ID, // 0 do not remove; used in DeleteEventHelper
- Events.TITLE, // 1 do not remove; used in DeleteEventHelper
- Events.RRULE, // 2 do not remove; used in DeleteEventHelper
- Events.ALL_DAY, // 3 do not remove; used in DeleteEventHelper
- Events.CALENDAR_ID, // 4 do not remove; used in DeleteEventHelper
- Events.DTSTART, // 5 do not remove; used in DeleteEventHelper
- Events._SYNC_ID, // 6 do not remove; used in DeleteEventHelper
- Events.EVENT_TIMEZONE, // 7 do not remove; used in DeleteEventHelper
- Events.DESCRIPTION, // 8
- Events.EVENT_LOCATION, // 9
- Events.HAS_ALARM, // 10
- Events.ACCESS_LEVEL, // 11
- Events.COLOR, // 12
- };
- 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_SYNC_ID = 6;
- private static final int EVENT_INDEX_EVENT_TIMEZONE = 7;
- private static final int EVENT_INDEX_DESCRIPTION = 8;
- private static final int EVENT_INDEX_EVENT_LOCATION = 9;
- private static final int EVENT_INDEX_HAS_ALARM = 10;
- private static final int EVENT_INDEX_ACCESS_LEVEL = 11;
- private static final int EVENT_INDEX_COLOR = 12;
-
- private static final String[] ATTENDEES_PROJECTION = new String[] {
- Attendees._ID, // 0
- Attendees.ATTENDEE_RELATIONSHIP, // 1
- Attendees.ATTENDEE_STATUS, // 2
- };
- private static final int ATTENDEES_INDEX_ID = 0;
- private static final int ATTENDEES_INDEX_RELATIONSHIP = 1;
- private static final int ATTENDEES_INDEX_STATUS = 2;
- private static final String ATTENDEES_WHERE = Attendees.EVENT_ID + "=%d";
-
- static final String[] CALENDARS_PROJECTION = new String[] {
- Calendars._ID, // 0
- Calendars.DISPLAY_NAME, // 1
- };
- static final int CALENDARS_INDEX_DISPLAY_NAME = 1;
- static final String CALENDARS_WHERE = Calendars._ID + "=%d";
-
- private static final String[] REMINDERS_PROJECTION = new String[] {
- Reminders._ID, // 0
- Reminders.MINUTES, // 1
- };
- private static final int REMINDERS_INDEX_MINUTES = 1;
- private static final String REMINDERS_WHERE = Reminders.EVENT_ID + "=%d AND (" +
- Reminders.METHOD + "=" + Reminders.METHOD_ALERT + " OR " + Reminders.METHOD + "=" +
- Reminders.METHOD_DEFAULT + ")";
-
- private static final int MENU_GROUP_REMINDER = 1;
- private static final int MENU_GROUP_EDIT = 2;
- private static final int MENU_GROUP_DELETE = 3;
-
- private static final int MENU_ADD_REMINDER = 1;
- private static final int MENU_EDIT = 2;
- private static final int MENU_DELETE = 3;
-
- private static final int ATTENDEE_NO_RESPONSE = -1;
- private static final int[] ATTENDEE_VALUES = {
- ATTENDEE_NO_RESPONSE,
- Attendees.ATTENDEE_STATUS_ACCEPTED,
- Attendees.ATTENDEE_STATUS_TENTATIVE,
- Attendees.ATTENDEE_STATUS_DECLINED,
- };
-
- private LinearLayout mRemindersContainer;
-
- private Uri mUri;
- private long mEventId;
- private Cursor mEventCursor;
- private Cursor mAttendeesCursor;
- private Cursor mCalendarsCursor;
-
- private long mStartMillis;
- private long mEndMillis;
- private int mVisibility = Calendars.NO_ACCESS;
- private int mRelationship = Attendees.RELATIONSHIP_ORGANIZER;
-
- private ArrayList<Integer> mOriginalMinutes = new ArrayList<Integer>();
- private ArrayList<LinearLayout> mReminderItems = new ArrayList<LinearLayout>(0);
- private ArrayList<Integer> mReminderValues;
- private ArrayList<String> mReminderLabels;
- private int mDefaultReminderMinutes;
-
- private DeleteEventHelper mDeleteEventHelper;
- private EditResponseHelper mEditResponseHelper;
-
- private int mResponseOffset;
- private int mOriginalAttendeeResponse;
- private boolean mIsRepeating;
-
- // This is called when one of the "remove reminder" buttons is selected.
- public void onClick(View v) {
- LinearLayout reminderItem = (LinearLayout) v.getParent();
- LinearLayout parent = (LinearLayout) reminderItem.getParent();
- parent.removeView(reminderItem);
- mReminderItems.remove(reminderItem);
- updateRemindersVisibility();
- }
-
- public void onItemSelected(AdapterView parent, View v, int position, long id) {
- // If they selected the "No response" option, then don't display the
- // dialog asking which events to change.
- if (id == 0 && mResponseOffset == 0) {
- return;
- }
-
- // If this is not a repeating event, then don't display the dialog
- // asking which events to change.
- if (!mIsRepeating) {
- return;
- }
-
- // If the selection is the same as the original, then don't display the
- // dialog asking which events to change.
- int index = findResponseIndexFor(mOriginalAttendeeResponse);
- if (position == index + mResponseOffset) {
- return;
- }
-
- // This is a repeating event. We need to ask the user if they mean to
- // change just this one instance or all instances.
- mEditResponseHelper.showDialog(mEditResponseHelper.getWhichEvents());
- }
-
- public void onNothingSelected(AdapterView parent) {
- }
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- // Event cursor
- Intent intent = getIntent();
- mUri = intent.getData();
- ContentResolver cr = getContentResolver();
- mStartMillis = intent.getLongExtra(EVENT_BEGIN_TIME, 0);
- mEndMillis = intent.getLongExtra(EVENT_END_TIME, 0);
- mEventCursor = managedQuery(mUri, EVENT_PROJECTION, null, null);
- if (initEventCursor()) {
- // The cursor is empty. This can happen if the event was deleted.
- finish();
- return;
- }
-
- setContentView(R.layout.event_info_activity);
-
- // Attendees cursor
- Uri uri = Attendees.CONTENT_URI;
- String where = String.format(ATTENDEES_WHERE, mEventId);
- mAttendeesCursor = managedQuery(uri, ATTENDEES_PROJECTION, where, null);
- initAttendeesCursor();
-
- // Calendars cursor
- uri = Calendars.CONTENT_URI;
- where = String.format(CALENDARS_WHERE, mEventCursor.getLong(EVENT_INDEX_CALENDAR_ID));
- mCalendarsCursor = managedQuery(uri, CALENDARS_PROJECTION, where, null);
- initCalendarsCursor();
-
- Resources res = getResources();
-
- if (mVisibility >= Calendars.CONTRIBUTOR_ACCESS &&
- mRelationship == Attendees.RELATIONSHIP_ATTENDEE) {
- setTitle(res.getString(R.string.event_info_title_invite));
- } else {
- setTitle(res.getString(R.string.event_info_title));
- }
-
- // Initialize the reminder values array.
- Resources r = getResources();
- String[] strings = r.getStringArray(R.array.reminder_minutes_values);
- int size = strings.length;
- ArrayList<Integer> list = new ArrayList<Integer>(size);
- for (int i = 0 ; i < size ; i++) {
- list.add(Integer.parseInt(strings[i]));
- }
- mReminderValues = list;
- String[] labels = r.getStringArray(R.array.reminder_minutes_labels);
- mReminderLabels = new ArrayList<String>(Arrays.asList(labels));
-
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- String durationString =
- prefs.getString(CalendarPreferenceActivity.KEY_DEFAULT_REMINDER, "0");
- mDefaultReminderMinutes = Integer.parseInt(durationString);
-
- mRemindersContainer = (LinearLayout) findViewById(R.id.reminders_container);
-
- // Reminders cursor
- boolean hasAlarm = mEventCursor.getInt(EVENT_INDEX_HAS_ALARM) != 0;
- if (hasAlarm) {
- uri = Reminders.CONTENT_URI;
- where = String.format(REMINDERS_WHERE, mEventId);
- Cursor reminderCursor = cr.query(uri, REMINDERS_PROJECTION, where, null, null);
- try {
- // First pass: collect all the custom reminder minutes (e.g.,
- // a reminder of 8 minutes) into a global list.
- while (reminderCursor.moveToNext()) {
- int minutes = reminderCursor.getInt(REMINDERS_INDEX_MINUTES);
- EditEvent.addMinutesToList(this, mReminderValues, mReminderLabels, minutes);
- }
-
- // Second pass: create the reminder spinners
- reminderCursor.moveToPosition(-1);
- while (reminderCursor.moveToNext()) {
- int minutes = reminderCursor.getInt(REMINDERS_INDEX_MINUTES);
- mOriginalMinutes.add(minutes);
- EditEvent.addReminder(this, this, mReminderItems, mReminderValues,
- mReminderLabels, minutes);
- }
- } finally {
- reminderCursor.close();
- }
- }
-
- updateView();
- updateRemindersVisibility();
-
- mDeleteEventHelper = new DeleteEventHelper(this, true /* exit when done */);
- mEditResponseHelper = new EditResponseHelper(this);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- if (initEventCursor()) {
- // The cursor is empty. This can happen if the event was deleted.
- finish();
- return;
- }
- initAttendeesCursor();
- initCalendarsCursor();
- }
-
- /**
- * Initializes the event cursor, which is expected to point to the first
- * (and only) result from a query.
- * @return true if the cursor is empty.
- */
- private boolean initEventCursor() {
- if ((mEventCursor == null) || (mEventCursor.getCount() == 0)) {
- return true;
- }
- mEventCursor.moveToFirst();
- mVisibility = mEventCursor.getInt(EVENT_INDEX_ACCESS_LEVEL);
- mEventId = mEventCursor.getInt(EVENT_INDEX_ID);
- String rRule = mEventCursor.getString(EVENT_INDEX_RRULE);
- mIsRepeating = (rRule != null);
- return false;
- }
-
- private void initAttendeesCursor() {
- if (mAttendeesCursor != null) {
- if (mAttendeesCursor.moveToFirst()) {
- mRelationship = mAttendeesCursor.getInt(ATTENDEES_INDEX_RELATIONSHIP);
- }
- }
- }
-
- private void initCalendarsCursor() {
- if (mCalendarsCursor != null) {
- mCalendarsCursor.moveToFirst();
- }
- }
-
- @Override
- public void onPause() {
- super.onPause();
- if (!isFinishing()) {
- return;
- }
- ContentResolver cr = getContentResolver();
- ArrayList<Integer> reminderMinutes = EditEvent.reminderItemsToMinutes(mReminderItems,
- mReminderValues);
- boolean changed = EditEvent.saveReminders(cr, mEventId, reminderMinutes, mOriginalMinutes);
- changed |= saveResponse(cr);
- if (changed) {
- Toast.makeText(this, R.string.saving_event, Toast.LENGTH_SHORT).show();
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuItem item;
- item = menu.add(MENU_GROUP_REMINDER, MENU_ADD_REMINDER, 0,
- R.string.add_new_reminder);
- item.setIcon(R.drawable.ic_menu_reminder);
- item.setAlphabeticShortcut('r');
-
- item = menu.add(MENU_GROUP_EDIT, MENU_EDIT, 0, R.string.edit_event_label);
- item.setIcon(android.R.drawable.ic_menu_edit);
- item.setAlphabeticShortcut('e');
-
- item = menu.add(MENU_GROUP_DELETE, MENU_DELETE, 0, R.string.delete_event_label);
- item.setIcon(android.R.drawable.ic_menu_delete);
-
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- // Cannot add reminders to a shared calendar with only free/busy
- // permissions
- if (mVisibility >= Calendars.READ_ACCESS && mReminderItems.size() < MAX_REMINDERS) {
- menu.setGroupVisible(MENU_GROUP_REMINDER, true);
- menu.setGroupEnabled(MENU_GROUP_REMINDER, true);
- } else {
- menu.setGroupVisible(MENU_GROUP_REMINDER, false);
- menu.setGroupEnabled(MENU_GROUP_REMINDER, false);
- }
-
- if (mVisibility >= Calendars.CONTRIBUTOR_ACCESS &&
- mRelationship >= Attendees.RELATIONSHIP_ORGANIZER) {
- menu.setGroupVisible(MENU_GROUP_EDIT, true);
- menu.setGroupEnabled(MENU_GROUP_EDIT, true);
- menu.setGroupVisible(MENU_GROUP_DELETE, true);
- menu.setGroupEnabled(MENU_GROUP_DELETE, true);
- } else {
- menu.setGroupVisible(MENU_GROUP_EDIT, false);
- menu.setGroupEnabled(MENU_GROUP_EDIT, false);
- menu.setGroupVisible(MENU_GROUP_DELETE, false);
- menu.setGroupEnabled(MENU_GROUP_DELETE, false);
- }
-
- return super.onPrepareOptionsMenu(menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- super.onOptionsItemSelected(item);
- switch (item.getItemId()) {
- case MENU_ADD_REMINDER:
- // TODO: when adding a new reminder, make it different from the
- // last one in the list (if any).
- if (mDefaultReminderMinutes == 0) {
- EditEvent.addReminder(this, this, mReminderItems,
- mReminderValues, mReminderLabels, 10 /* minutes */);
- } else {
- EditEvent.addReminder(this, this, mReminderItems,
- mReminderValues, mReminderLabels, mDefaultReminderMinutes);
- }
- updateRemindersVisibility();
- break;
- case MENU_EDIT:
- doEdit();
- break;
- case MENU_DELETE:
- doDelete();
- break;
- }
- return true;
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_DEL) {
- doDelete();
- return true;
- }
- return super.onKeyDown(keyCode, event);
- }
-
- private void updateRemindersVisibility() {
- if (mReminderItems.size() == 0) {
- mRemindersContainer.setVisibility(View.GONE);
- } else {
- mRemindersContainer.setVisibility(View.VISIBLE);
- }
- }
-
- /**
- * Saves the response to an invitation if the user changed the response.
- * Returns true if the database was updated.
- *
- * @param cr the ContentResolver
- * @return true if the database was changed
- */
- private boolean saveResponse(ContentResolver cr) {
- if (mAttendeesCursor == null || mEventCursor == null) {
- return false;
- }
- Spinner spinner = (Spinner) findViewById(R.id.response_value);
- int position = spinner.getSelectedItemPosition() - mResponseOffset;
- if (position <= 0) {
- return false;
- }
-
- int status = ATTENDEE_VALUES[position];
-
- // If the status has not changed, then don't update the database
- if (status == mOriginalAttendeeResponse) {
- return false;
- }
-
- long attendeeId = mAttendeesCursor.getInt(ATTENDEES_INDEX_ID);
- if (!mIsRepeating) {
- // This is a non-repeating event
- updateResponse(cr, mEventId, attendeeId, status);
- return true;
- }
-
- // This is a repeating event
- int whichEvents = mEditResponseHelper.getWhichEvents();
- switch (whichEvents) {
- case -1:
- return false;
- case UPDATE_SINGLE:
- createExceptionResponse(cr, mEventId, attendeeId, status);
- return true;
- case UPDATE_ALL:
- updateResponse(cr, mEventId, attendeeId, status);
- return true;
- default:
- Log.e("Calendar", "Unexpected choice for updating invitation response");
- break;
- }
- return false;
- }
-
- private void updateResponse(ContentResolver cr, long eventId, long attendeeId, int status) {
- // Update the "selfAttendeeStatus" field for the event
- ContentValues values = new ContentValues();
-
- // Will need to add email when MULTIPLE_ATTENDEES_PER_EVENT supported.
- values.put(Attendees.ATTENDEE_STATUS, status);
- values.put(Attendees.EVENT_ID, eventId);
-
- Uri uri = ContentUris.withAppendedId(Attendees.CONTENT_URI, attendeeId);
- cr.update(uri, values, null /* where */, null /* selection args */);
- }
-
- private void createExceptionResponse(ContentResolver cr, long eventId,
- long attendeeId, int status) {
- // Fetch information about the repeating event.
- Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId);
- Cursor cursor = cr.query(uri, EVENT_PROJECTION, null, null, null);
- if (cursor == null) {
- return;
- }
-
- try {
- cursor.moveToFirst();
- ContentValues values = new ContentValues();
-
- String title = cursor.getString(EVENT_INDEX_TITLE);
- String timezone = cursor.getString(EVENT_INDEX_EVENT_TIMEZONE);
- int calendarId = cursor.getInt(EVENT_INDEX_CALENDAR_ID);
- boolean allDay = cursor.getInt(EVENT_INDEX_ALL_DAY) != 0;
- String syncId = cursor.getString(EVENT_INDEX_SYNC_ID);
-
- values.put(Events.TITLE, title);
- values.put(Events.EVENT_TIMEZONE, timezone);
- values.put(Events.ALL_DAY, allDay ? 1 : 0);
- values.put(Events.CALENDAR_ID, calendarId);
- values.put(Events.DTSTART, mStartMillis);
- values.put(Events.DTEND, mEndMillis);
- values.put(Events.ORIGINAL_EVENT, syncId);
- values.put(Events.ORIGINAL_INSTANCE_TIME, mStartMillis);
- values.put(Events.ORIGINAL_ALL_DAY, allDay ? 1 : 0);
- values.put(Events.STATUS, Events.STATUS_CONFIRMED);
- values.put(Events.SELF_ATTENDEE_STATUS, status);
-
- // Create a recurrence exception
- Uri newUri = cr.insert(Events.CONTENT_URI, values);
- } finally {
- cursor.close();
- }
- }
-
- private int findResponseIndexFor(int response) {
- int size = ATTENDEE_VALUES.length;
- for (int index = 0; index < size; index++) {
- if (ATTENDEE_VALUES[index] == response) {
- return index;
- }
- }
- return 0;
- }
-
- private void doEdit() {
- Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventId);
- Intent intent = new Intent(Intent.ACTION_EDIT, uri);
- intent.putExtra(Calendar.EVENT_BEGIN_TIME, mStartMillis);
- intent.putExtra(Calendar.EVENT_END_TIME, mEndMillis);
- intent.setClass(EventInfoActivity.this, EditEvent.class);
- startActivity(intent);
- finish();
- }
-
- private void doDelete() {
- mDeleteEventHelper.delete(mStartMillis, mEndMillis, mEventCursor, -1);
- }
-
- private void updateView() {
- if (mEventCursor == null) {
- return;
- }
- Resources res = getResources();
- ContentResolver cr = getContentResolver();
-
- String eventName = mEventCursor.getString(EVENT_INDEX_TITLE);
- if (eventName == null || eventName.length() == 0) {
- eventName = res.getString(R.string.no_title_label);
- }
-
- boolean allDay = mEventCursor.getInt(EVENT_INDEX_ALL_DAY) != 0;
- String location = mEventCursor.getString(EVENT_INDEX_EVENT_LOCATION);
- String description = mEventCursor.getString(EVENT_INDEX_DESCRIPTION);
- String rRule = mEventCursor.getString(EVENT_INDEX_RRULE);
- boolean hasAlarm = mEventCursor.getInt(EVENT_INDEX_HAS_ALARM) != 0;
- String eventTimezone = mEventCursor.getString(EVENT_INDEX_EVENT_TIMEZONE);
- int color = mEventCursor.getInt(EVENT_INDEX_COLOR) & 0xbbffffff;
-
- View strip = (View) findViewById(R.id.strip);
- strip.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_IN);
-
- TextView title = (TextView) findViewById(R.id.title);
- title.setTextColor(color);
-
- View divider = (View) findViewById(R.id.divider);
- divider.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_IN);
-
- // What
- if (eventName != null) {
- setTextCommon(R.id.title, eventName);
- }
-
- // When
- String when;
- int flags;
- if (allDay) {
- flags = DateUtils.FORMAT_UTC | DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE;
- } else {
- flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE;
- if (DateFormat.is24HourFormat(this)) {
- flags |= DateUtils.FORMAT_24HOUR;
- }
- }
- when = DateUtils.formatDateRange(this, mStartMillis, mEndMillis, flags);
- setTextCommon(R.id.when, when);
-
- // Show the event timezone if it is different from the local timezone
- Time time = new Time();
- String localTimezone = time.timezone;
- if (allDay) {
- localTimezone = Time.TIMEZONE_UTC;
- }
- if (eventTimezone != null && !localTimezone.equals(eventTimezone) && !allDay) {
- setTextCommon(R.id.timezone, localTimezone);
- } else {
- setVisibilityCommon(R.id.timezone_container, View.GONE);
- }
-
- // Repeat
- if (rRule != null) {
- EventRecurrence eventRecurrence = new EventRecurrence();
- eventRecurrence.parse(rRule);
- Time date = new Time();
- if (allDay) {
- date.timezone = Time.TIMEZONE_UTC;
- }
- date.set(mStartMillis);
- eventRecurrence.setStartDate(date);
- String repeatString = eventRecurrence.getRepeatString();
- setTextCommon(R.id.repeat, repeatString);
- } else {
- setVisibilityCommon(R.id.repeat_container, View.GONE);
- }
-
- // Where
- if (location == null || location.length() == 0) {
- setVisibilityCommon(R.id.where, View.GONE);
- } else {
- setTextCommon(R.id.where, location);
- }
-
- // Description
- if (description == null || description.length() == 0) {
- setVisibilityCommon(R.id.description, View.GONE);
- } else {
- setTextCommon(R.id.description, description);
- }
-
- // Calendar
- if (mCalendarsCursor != null) {
- mCalendarsCursor.moveToFirst();
- String calendarName = mCalendarsCursor.getString(CALENDARS_INDEX_DISPLAY_NAME);
- setTextCommon(R.id.calendar, calendarName);
- } else {
- setVisibilityCommon(R.id.calendar_container, View.GONE);
- }
-
- // Response
- updateResponse();
- }
-
- void updateResponse() {
- if (mVisibility < Calendars.CONTRIBUTOR_ACCESS ||
- mRelationship != Attendees.RELATIONSHIP_ATTENDEE) {
- setVisibilityCommon(R.id.response_container, View.GONE);
- return;
- }
-
- setVisibilityCommon(R.id.response_container, View.VISIBLE);
-
- Spinner spinner = (Spinner) findViewById(R.id.response_value);
-
- mOriginalAttendeeResponse = ATTENDEE_NO_RESPONSE;
- if (mAttendeesCursor != null) {
- mOriginalAttendeeResponse = mAttendeesCursor.getInt(ATTENDEES_INDEX_STATUS);
- }
- mResponseOffset = 0;
-
- /* If the user has previously responded to this event
- * we should not allow them to select no response again.
- * Switch the entries to a set of entries without the
- * no response option.
- */
- if ((mOriginalAttendeeResponse != Attendees.ATTENDEE_STATUS_INVITED)
- && (mOriginalAttendeeResponse != ATTENDEE_NO_RESPONSE)
- && (mOriginalAttendeeResponse != Attendees.ATTENDEE_STATUS_NONE)) {
- CharSequence[] entries;
- entries = getResources().getTextArray(R.array.response_labels2);
- mResponseOffset = -1;
- ArrayAdapter<CharSequence> adapter =
- new ArrayAdapter<CharSequence>(this,
- android.R.layout.simple_spinner_item, entries);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- spinner.setAdapter(adapter);
- }
-
- int index = findResponseIndexFor(mOriginalAttendeeResponse);
- spinner.setSelection(index + mResponseOffset);
- spinner.setOnItemSelectedListener(this);
- }
-
- private void setTextCommon(int id, CharSequence text) {
- TextView textView = (TextView) findViewById(id);
- if (textView == null)
- return;
- textView.setText(text);
- }
-
- private void setVisibilityCommon(int id, int visibility) {
- View v = findViewById(id);
- if (v != null) {
- v.setVisibility(visibility);
- }
- return;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2008 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.ContentResolver;
-import android.content.Context;
-import android.database.Cursor;
-import android.os.Handler;
-import android.os.Process;
-import android.provider.Calendar.BusyBits;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.atomic.AtomicInteger;
-
-public class EventLoader {
-
- private Context mContext;
- private Handler mHandler = new Handler();
- private AtomicInteger mSequenceNumber = new AtomicInteger();
-
- private LinkedBlockingQueue<LoadRequest> mLoaderQueue;
- private LoaderThread mLoaderThread;
- private ContentResolver mResolver;
-
- private static interface LoadRequest {
- public void processRequest(EventLoader eventLoader);
- public void skipRequest(EventLoader eventLoader);
- }
-
- private static class ShutdownRequest implements LoadRequest {
- public void processRequest(EventLoader eventLoader) {
- }
-
- public void skipRequest(EventLoader eventLoader) {
- }
- }
-
- private static class LoadBusyBitsRequest implements LoadRequest {
- public int startDay;
- public int numDays;
- public int[] busybits;
- public int[] allDayCounts;
- public Runnable uiCallback;
-
- public LoadBusyBitsRequest(int startDay, int numDays, int[] busybits, int[] allDayCounts,
- final Runnable uiCallback) {
- this.startDay = startDay;
- this.numDays = numDays;
- this.busybits = busybits;
- this.allDayCounts = allDayCounts;
- this.uiCallback = uiCallback;
- }
-
- public void processRequest(EventLoader eventLoader) {
- final Handler handler = eventLoader.mHandler;
- ContentResolver cr = eventLoader.mResolver;
-
- // Clear the busy bits and all-day counts
- for (int dayIndex = 0; dayIndex < numDays; dayIndex++) {
- busybits[dayIndex] = 0;
- allDayCounts[dayIndex] = 0;
- }
-
- Cursor cursor = BusyBits.query(cr, startDay, numDays);
- try {
- int dayColumnIndex = cursor.getColumnIndexOrThrow(BusyBits.DAY);
- int busybitColumnIndex = cursor.getColumnIndexOrThrow(BusyBits.BUSYBITS);
- int allDayCountColumnIndex = cursor.getColumnIndexOrThrow(BusyBits.ALL_DAY_COUNT);
-
- while (cursor.moveToNext()) {
- int day = cursor.getInt(dayColumnIndex);
- int dayIndex = day - startDay;
- busybits[dayIndex] = cursor.getInt(busybitColumnIndex);
- allDayCounts[dayIndex] = cursor.getInt(allDayCountColumnIndex);
- }
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- handler.post(uiCallback);
- }
-
- public void skipRequest(EventLoader eventLoader) {
- }
- }
-
- private static class LoadEventsRequest implements LoadRequest {
-
- public int id;
- public long startMillis;
- public int numDays;
- public ArrayList<Event> events;
- public Runnable successCallback;
- public Runnable cancelCallback;
-
- public LoadEventsRequest(int id, long startMillis, int numDays, ArrayList<Event> events,
- final Runnable successCallback, final Runnable cancelCallback) {
- this.id = id;
- this.startMillis = startMillis;
- this.numDays = numDays;
- this.events = events;
- this.successCallback = successCallback;
- this.cancelCallback = cancelCallback;
- }
-
- public void processRequest(EventLoader eventLoader) {
- Event.loadEvents(eventLoader.mContext, events, startMillis,
- numDays, id, eventLoader.mSequenceNumber);
-
- // Check if we are still the most recent request.
- if (id == eventLoader.mSequenceNumber.get()) {
- eventLoader.mHandler.post(successCallback);
- } else {
- eventLoader.mHandler.post(cancelCallback);
- }
- }
-
- public void skipRequest(EventLoader eventLoader) {
- eventLoader.mHandler.post(cancelCallback);
- }
- }
-
- private static class LoaderThread extends Thread {
- LinkedBlockingQueue<LoadRequest> mQueue;
- EventLoader mEventLoader;
-
- public LoaderThread(LinkedBlockingQueue<LoadRequest> queue, EventLoader eventLoader) {
- mQueue = queue;
- mEventLoader = eventLoader;
- }
-
- public void shutdown() {
- try {
- mQueue.put(new ShutdownRequest());
- } catch (InterruptedException ex) {
- // The put() method fails with InterruptedException if the
- // queue is full. This should never happen because the queue
- // has no limit.
- Log.e("Cal", "LoaderThread.shutdown() interrupted!");
- }
- }
-
- @Override
- public void run() {
- Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
- while (true) {
- try {
- // Wait for the next request
- LoadRequest request = mQueue.take();
-
- // If there are a bunch of requests already waiting, then
- // skip all but the most recent request.
- while (!mQueue.isEmpty()) {
- // Let the request know that it was skipped
- request.skipRequest(mEventLoader);
-
- // Skip to the next request
- request = mQueue.take();
- }
-
- if (request instanceof ShutdownRequest) {
- return;
- }
- request.processRequest(mEventLoader);
- } catch (InterruptedException ex) {
- Log.e("Cal", "background LoaderThread interrupted!");
- }
- }
- }
- }
-
- public EventLoader(Context context) {
- mContext = context;
- mLoaderQueue = new LinkedBlockingQueue<LoadRequest>();
- mResolver = context.getContentResolver();
- }
-
- /**
- * Call this from the activity's onResume()
- */
- public void startBackgroundThread() {
- mLoaderThread = new LoaderThread(mLoaderQueue, this);
- mLoaderThread.start();
- }
-
- /**
- * Call this from the activity's onPause()
- */
- public void stopBackgroundThread() {
- mLoaderThread.shutdown();
- }
-
- /**
- * Loads "numDays" days worth of events, starting at start, into events.
- * Posts uiCallback to the {@link Handler} for this view, which will run in the UI thread.
- * Reuses an existing background thread, if events were already being loaded in the background.
- * NOTE: events and uiCallback are not used if an existing background thread gets reused --
- * the ones that were passed in on the call that results in the background thread getting
- * created are used, and the most recent call's worth of data is loaded into events and posted
- * via the uiCallback.
- */
- void loadEventsInBackground(final int numDays, final ArrayList<Event> events,
- long start, final Runnable successCallback, final Runnable cancelCallback) {
-
- // Increment the sequence number for requests. We don't care if the
- // sequence numbers wrap around because we test for equality with the
- // latest one.
- int id = mSequenceNumber.incrementAndGet();
-
- // Send the load request to the background thread
- LoadEventsRequest request = new LoadEventsRequest(id, start, numDays,
- events, successCallback, cancelCallback);
-
- try {
- mLoaderQueue.put(request);
- } catch (InterruptedException ex) {
- // The put() method fails with InterruptedException if the
- // queue is full. This should never happen because the queue
- // has no limit.
- Log.e("Cal", "loadEventsInBackground() interrupted!");
- }
- }
-
- void loadBusyBitsInBackground(int startDay, int numDays, int[] busybits, int[] allDayCounts,
- final Runnable uiCallback) {
- // Send the load request to the background thread
- LoadBusyBitsRequest request = new LoadBusyBitsRequest(startDay, numDays, busybits,
- allDayCounts, uiCallback);
-
- try {
- mLoaderQueue.put(request);
- } catch (InterruptedException ex) {
- // The put() method fails with InterruptedException if the
- // queue is full. This should never happen because the queue
- // has no limit.
- Log.e("Cal", "loadBusyBitsInBackground() interrupted!");
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007 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.app.Activity;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.pim.ICalendar;
-import android.provider.Calendar;
-import android.util.Config;
-import android.util.Log;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-
-public class IcsImportActivity extends Activity {
-
- private static final String TAG = "Calendar";
-
- // TODO: consolidate this code with the EventActivity
- private static class CalendarInfo {
- public final long id;
- public final String name;
-
- public CalendarInfo(long id, String name) {
- this.id = id;
- this.name = name;
- }
-
- @Override
- public String toString() {
- return name;
- }
- }
-
- private View mView;
- private Button mImportButton;
- private Button mCancelButton;
- private Spinner mCalendars;
- private ImageView mCalendarIcon;
- private TextView mNumEvents;
-
- private ICalendar.Component mCalendar = null;
-
- private View.OnClickListener mImportListener = new View.OnClickListener() {
- public void onClick(View v) {
- importCalendar();
- finish();
- }
- };
-
- private View.OnClickListener mCancelListener = new View.OnClickListener() {
- public void onClick(View v) {
- finish();
- }
- };
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- setContentView(R.layout.ics_import_activity);
- mView = findViewById(R.id.import_ics);
-
- mCalendarIcon = (ImageView) findViewById(R.id.calendar_icon);
- mCalendars = (Spinner) findViewById(R.id.calendars);
- populateCalendars();
-
- mImportButton = (Button) findViewById(R.id.import_button);
- mImportButton.setOnClickListener(mImportListener);
- mCancelButton = (Button) findViewById(R.id.cancel_button);
- mCancelButton.setOnClickListener(mCancelListener);
-
- mNumEvents = (TextView) findViewById(R.id.num_events);
-
- Intent intent = getIntent();
- String data = intent.getStringExtra("ics");
- if (data == null) {
- Uri content = intent.getData();
- if (content != null) {
- InputStream is = null;
- try {
- is = getContentResolver().openInputStream(content);
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] buf = new byte[8096];
- int bytesRead = -1;
- int pos = 0;
- while ((bytesRead = is.read(buf)) != -1) {
- baos.write(buf, pos, bytesRead);
- pos += bytesRead;
- }
- data = new String(baos.toByteArray(), "UTF-8");
- } catch (FileNotFoundException fnfe) {
- Log.w(TAG, "Could not open data.", fnfe);
- } catch (IOException ioe) {
- Log.w(TAG, "Could not read data.", ioe);
- } finally {
- if (is != null) {
- try {
- is.close();
- } catch (IOException ioe) {
- Log.w(TAG, "Could not close InputStream.", ioe);
- }
- }
- }
- }
- }
- if (data == null) {
- Log.w(TAG, "No iCalendar data to parse.");
- finish();
- return;
- }
- parseCalendar(data);
- }
-
- private void populateCalendars() {
- ContentResolver cr = getContentResolver();
- Cursor c = cr.query(Calendar.Calendars.CONTENT_URI,
- new String[] { Calendar.Calendars._ID,
- Calendar.Calendars.DISPLAY_NAME,
- Calendar.Calendars.SELECTED,
- Calendar.Calendars.ACCESS_LEVEL },
- Calendar.Calendars.SELECTED + "=1 AND "
- + Calendar.Calendars.ACCESS_LEVEL + ">="
- + Calendar.Calendars.CONTRIBUTOR_ACCESS,
- null, null /* sort order */);
-
- ArrayList<CalendarInfo> items = new ArrayList<CalendarInfo>();
- try {
- // TODO: write a custom adapter that wraps the cursor?
- int idColumn = c.getColumnIndex(Calendar.Calendars._ID);
- int nameColumn = c.getColumnIndex(Calendar.Calendars.DISPLAY_NAME);
- while (c.moveToNext()) {
- long id = c.getLong(idColumn);
- String name = c.getString(nameColumn);
- items.add(new CalendarInfo(id, name));
- }
- } finally {
- c.deactivate();
- }
-
- mCalendars.setAdapter(new ArrayAdapter<CalendarInfo>(this,
- android.R.layout.simple_spinner_item, items));
- }
-
- private void parseCalendar(String data) {
- mCalendar = null;
- try {
- mCalendar = ICalendar.parseCalendar(data);
- } catch (ICalendar.FormatException fe) {
- if (Config.LOGD) {
- Log.d(TAG, "Could not parse iCalendar.", fe);
- // TODO: show an error message.
- finish();
- return;
- }
- }
- if (mCalendar.getComponents() == null) {
- Log.d(TAG, "No events in iCalendar.");
- finish();
- return;
- }
- int numEvents = 0;
- for (ICalendar.Component component : mCalendar.getComponents()) {
- if ("VEVENT".equals(component.getName())) {
- // TODO: display a list of the events (start time, title) in
- // the UI?
- ++numEvents;
- }
- }
- // TODO: special-case a single-event calendar. switch to the
- // EventActivity, once the EventActivity supports displaying data that
- // is passed in via the extras.
- // OR, we could flip things around, where the EventActivity handles ICS
- // import by default, and delegates to the IcsImportActivity if it finds
- // that there are more than one event in the iCalendar. that would
- // avoid an extra activity launch for the expected common case of
- // importing a single event.
- mNumEvents.setText(Integer.toString(numEvents));
- }
-
- private void importCalendar() {
-
- ContentResolver cr = getContentResolver();
-
- int numImported = 0;
- ContentValues values = new ContentValues();
-
- for (ICalendar.Component component : mCalendar.getComponents()) {
- if ("VEVENT".equals(component.getName())) {
- CalendarInfo calInfo =
- (CalendarInfo) mCalendars.getSelectedItem();
- if (Calendar.Events.insertVEvent(cr, component, calInfo.id,
- Calendar.Events.STATUS_CONFIRMED, values) != null) {
- ++numImported;
- }
- }
- }
- // TODO: display how many were imported.
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007 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 com.google.android.googlelogin.GoogleLoginServiceConstants;
-import com.google.android.googlelogin.GoogleLoginServiceHelper;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.Uri;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.provider.Gmail;
-
-public class LaunchActivity extends Activity {
-
- // An arbitrary constant to pass to the GoogleLoginHelperService
- private static final int GET_ACCOUNT_REQUEST = 1;
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- // Our UI is not something intended for the user to see. We just
- // stick around until we can figure out what to do next based on
- // the current state of the system.
- setVisible(false);
-
- // Only try looking for an account if this is the first launch.
- if (icicle == null) {
- // This will request a Gmail account and if none are present, it will
- // invoke SetupWizard to login or create one. The result is returned
- // through onActivityResult().
- Bundle bundle = new Bundle();
- bundle.putCharSequence("optional_message", getText(R.string.calendar_plug));
- GoogleLoginServiceHelper.getCredentials(
- this,
- GET_ACCOUNT_REQUEST,
- bundle,
- GoogleLoginServiceConstants.PREFER_HOSTED,
- Gmail.GMAIL_AUTH_SERVICE,
- true);
- }
- }
-
- private void onAccountsLoaded(String account) {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- String startActivity = prefs.getString(CalendarPreferenceActivity.KEY_START_VIEW,
- CalendarPreferenceActivity.DEFAULT_START_VIEW);
-
- // Get the data for from this intent, if any
- Intent myIntent = getIntent();
- Uri myData = myIntent.getData();
-
- // Set up the intent for the start activity
- Intent intent = new Intent();
- if (myData != null) {
- intent.setData(myData);
- }
- intent.setClassName(this, startActivity);
- startActivity(intent);
- finish();
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
- super.onActivityResult(requestCode, resultCode, intent);
- if (requestCode == GET_ACCOUNT_REQUEST) {
- if (resultCode == RESULT_OK) {
- if (intent != null) {
- Bundle extras = intent.getExtras();
- if (extras != null) {
- final String account;
- account = extras.getString(GoogleLoginServiceConstants.AUTH_ACCOUNT_KEY);
- onAccountsLoaded(account);
- }
- }
- } else {
- finish();
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2008 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 static android.provider.Calendar.EVENT_BEGIN_TIME;
-import static android.provider.Calendar.EVENT_END_TIME;
-import android.app.Activity;
-import android.content.Intent;
-import android.text.format.DateUtils;
-import android.view.Menu;
-import android.view.MenuItem;
-
-public class MenuHelper {
- private static final int MENU_GROUP_AGENDA = 1;
- private static final int MENU_GROUP_DAY = 2;
- private static final int MENU_GROUP_WEEK = 3;
- private static final int MENU_GROUP_MONTH = 4;
- private static final int MENU_GROUP_EVENT_CREATE = 5;
- private static final int MENU_GROUP_TODAY = 6;
- private static final int MENU_GROUP_SELECT_CALENDARS = 7;
- private static final int MENU_GROUP_PREFERENCES = 8;
-
- public static final int MENU_GOTO_TODAY = 1;
- public static final int MENU_AGENDA = 2;
- public static final int MENU_DAY = 3;
- public static final int MENU_WEEK = 4;
- public static final int MENU_EVENT_VIEW = 5;
- public static final int MENU_EVENT_CREATE = 6;
- public static final int MENU_EVENT_EDIT = 7;
- public static final int MENU_EVENT_DELETE = 8;
- public static final int MENU_MONTH = 9;
- public static final int MENU_SELECT_CALENDARS = 10;
- public static final int MENU_PREFERENCES = 11;
-
- public static void onPrepareOptionsMenu(Activity activity, Menu menu) {
-
- if (activity instanceof AgendaActivity) {
- menu.setGroupVisible(MENU_GROUP_AGENDA, false);
- menu.setGroupEnabled(MENU_GROUP_AGENDA, false);
- } else {
- menu.setGroupVisible(MENU_GROUP_AGENDA, true);
- menu.setGroupEnabled(MENU_GROUP_AGENDA, true);
- }
-
- if (activity instanceof DayActivity) {
- menu.setGroupVisible(MENU_GROUP_DAY, false);
- menu.setGroupEnabled(MENU_GROUP_DAY, false);
- } else {
- menu.setGroupVisible(MENU_GROUP_DAY, true);
- menu.setGroupEnabled(MENU_GROUP_DAY, true);
- }
-
- if (activity instanceof WeekActivity) {
- menu.setGroupVisible(MENU_GROUP_WEEK, false);
- menu.setGroupEnabled(MENU_GROUP_WEEK, false);
- } else {
- menu.setGroupVisible(MENU_GROUP_WEEK, true);
- menu.setGroupEnabled(MENU_GROUP_WEEK, true);
- }
-
- if (activity instanceof MonthActivity) {
- menu.setGroupVisible(MENU_GROUP_MONTH, false);
- menu.setGroupEnabled(MENU_GROUP_MONTH, false);
- } else {
- menu.setGroupVisible(MENU_GROUP_MONTH, true);
- menu.setGroupEnabled(MENU_GROUP_MONTH, true);
- }
-
- if (activity instanceof EventInfoActivity) {
- menu.setGroupVisible(MENU_GROUP_TODAY, false);
- menu.setGroupEnabled(MENU_GROUP_TODAY, false);
- } else {
- menu.setGroupVisible(MENU_GROUP_TODAY, true);
- menu.setGroupEnabled(MENU_GROUP_TODAY, true);
- }
- }
-
- public static boolean onCreateOptionsMenu(Menu menu) {
-
- MenuItem item;
- item = menu.add(MENU_GROUP_AGENDA, MENU_AGENDA, 0, R.string.agenda_view);
- item.setIcon(android.R.drawable.ic_menu_agenda);
- item.setAlphabeticShortcut('a');
-
- item = menu.add(MENU_GROUP_DAY, MENU_DAY, 0, R.string.day_view);
- item.setIcon(android.R.drawable.ic_menu_day);
- item.setAlphabeticShortcut('d');
-
- item = menu.add(MENU_GROUP_WEEK, MENU_WEEK, 0, R.string.week_view);
- item.setIcon(android.R.drawable.ic_menu_week);
- item.setAlphabeticShortcut('w');
-
- item = menu.add(MENU_GROUP_MONTH, MENU_MONTH, 0, R.string.month_view);
- item.setIcon(android.R.drawable.ic_menu_month);
- item.setAlphabeticShortcut('m');
-
- item = menu.add(MENU_GROUP_EVENT_CREATE, MENU_EVENT_CREATE, 0, R.string.event_create);
- item.setIcon(android.R.drawable.ic_menu_add);
- item.setAlphabeticShortcut('n');
-
- item = menu.add(MENU_GROUP_TODAY, MENU_GOTO_TODAY, 0, R.string.goto_today);
- item.setIcon(android.R.drawable.ic_menu_today);
- item.setAlphabeticShortcut('t');
-
- item = menu.add(MENU_GROUP_SELECT_CALENDARS, MENU_SELECT_CALENDARS,
- 0, R.string.menu_select_calendars);
- item.setIcon(android.R.drawable.ic_menu_manage);
-
- item = menu.add(MENU_GROUP_PREFERENCES, MENU_PREFERENCES, 0, R.string.menu_preferences);
- item.setIcon(android.R.drawable.ic_menu_preferences);
- item.setAlphabeticShortcut('p');
-
- return true;
- }
-
- public static boolean onOptionsItemSelected(Activity activity, MenuItem item, Navigator nav) {
- switch (item.getItemId()) {
- case MENU_SELECT_CALENDARS: {
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setClass(activity, SelectCalendarsActivity.class);
- activity.startActivity(intent);
- return true;
- }
- case MENU_GOTO_TODAY:
- nav.goToToday();
- return true;
- case MENU_PREFERENCES:
- switchTo(activity, CalendarPreferenceActivity.class.getName(), nav.getSelectedTime());
- return true;
- case MENU_AGENDA:
- switchTo(activity, AgendaActivity.class.getName(), nav.getSelectedTime());
- activity.finish();
- return true;
- case MENU_DAY:
- switchTo(activity, DayActivity.class.getName(), nav.getSelectedTime());
- activity.finish();
- return true;
- case MENU_WEEK:
- switchTo(activity, WeekActivity.class.getName(), nav.getSelectedTime());
- activity.finish();
- return true;
- case MENU_MONTH:
- switchTo(activity, MonthActivity.class.getName(), nav.getSelectedTime());
- activity.finish();
- return true;
- case MENU_EVENT_CREATE: {
- long startMillis = nav.getSelectedTime();
- long endMillis = startMillis + DateUtils.HOUR_IN_MILLIS;
- Intent intent = new Intent(Intent.ACTION_EDIT);
- intent.setClassName(activity, EditEvent.class.getName());
- intent.putExtra(EVENT_BEGIN_TIME, startMillis);
- intent.putExtra(EVENT_END_TIME, endMillis);
- intent.putExtra(EditEvent.EVENT_ALL_DAY, nav.getAllDay());
- activity.startActivity(intent);
- return true;
- }
- }
- return false;
- }
-
- /* package */ static void switchTo(Activity activity, String className, long startMillis) {
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setClassName(activity, className);
- intent.putExtra(EVENT_BEGIN_TIME, startMillis);
- activity.startActivity(intent);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2006 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 static android.provider.Calendar.EVENT_BEGIN_TIME;
-import dalvik.system.VMRuntime;
-
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.database.ContentObserver;
-import android.os.Bundle;
-import android.os.Handler;
-import android.preference.PreferenceManager;
-import android.provider.Calendar.Events;
-import android.text.format.DateUtils;
-import android.text.format.Time;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Animation.AnimationListener;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-import android.widget.ViewSwitcher;
-import android.widget.Gallery.LayoutParams;
-
-import java.util.Calendar;
-
-public class MonthActivity extends Activity implements ViewSwitcher.ViewFactory,
- Navigator, AnimationListener {
- private static final int INITIAL_HEAP_SIZE = 4 * 1024 * 1024;
- private Animation mInAnimationPast;
- private Animation mInAnimationFuture;
- private Animation mOutAnimationPast;
- private Animation mOutAnimationFuture;
- private ViewSwitcher mSwitcher;
- private Time mTime;
-
- private ContentResolver mContentResolver;
- EventLoader mEventLoader;
- private int mStartDay;
-
- private ProgressBar mProgressBar;
-
- protected void startProgressSpinner() {
- // start the progress spinner
- mProgressBar.setVisibility(View.VISIBLE);
- }
-
- protected void stopProgressSpinner() {
- // stop the progress spinner
- mProgressBar.setVisibility(View.GONE);
- }
-
- /* ViewSwitcher.ViewFactory interface methods */
- public View makeView() {
- MonthView mv = new MonthView(this, this);
- mv.setLayoutParams(new ViewSwitcher.LayoutParams(
- LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
- mv.setSelectedTime(mTime);
- return mv;
- }
-
- /* Navigator interface methods */
- public void goTo(Time time) {
- TextView title = (TextView) findViewById(R.id.title);
- title.setText(Utils.formatMonthYear(time));
-
- MonthView current = (MonthView) mSwitcher.getCurrentView();
- current.dismissPopup();
-
- Time currentTime = current.getTime();
-
- // Compute a month number that is monotonically increasing for any
- // two adjacent months.
- // This is faster than calling getSelectedTime() because we avoid
- // a call to Time#normalize().
- int currentMonth = currentTime.month + currentTime.year * 12;
- int nextMonth = time.month + time.year * 12;
- if (nextMonth < currentMonth) {
- mSwitcher.setInAnimation(mInAnimationPast);
- mSwitcher.setOutAnimation(mOutAnimationPast);
- } else {
- mSwitcher.setInAnimation(mInAnimationFuture);
- mSwitcher.setOutAnimation(mOutAnimationFuture);
- }
-
- MonthView next = (MonthView) mSwitcher.getNextView();
- next.setSelectionMode(current.getSelectionMode());
- next.setSelectedTime(time);
- next.reloadEvents();
- next.animationStarted();
- mSwitcher.showNext();
- next.requestFocus();
- mTime = time;
- }
-
- public void goToToday() {
- Time now = new Time();
- now.set(System.currentTimeMillis());
-
- TextView title = (TextView) findViewById(R.id.title);
- title.setText(Utils.formatMonthYear(now));
- mTime = now;
-
- MonthView view = (MonthView) mSwitcher.getCurrentView();
- view.setSelectedTime(now);
- view.reloadEvents();
- }
-
- public long getSelectedTime() {
- MonthView mv = (MonthView) mSwitcher.getCurrentView();
- return mv.getSelectedTimeInMillis();
- }
-
- public boolean getAllDay() {
- return false;
- }
-
- int getStartDay() {
- return mStartDay;
- }
-
- void eventsChanged() {
- MonthView view = (MonthView) mSwitcher.getCurrentView();
- view.reloadEvents();
- }
-
- /**
- * Listens for intent broadcasts
- */
- private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_TIME_CHANGED)
- || action.equals(Intent.ACTION_DATE_CHANGED)
- || action.equals(Intent.ACTION_TIMEZONE_CHANGED)) {
- eventsChanged();
- }
- }
- };
-
- // Create an observer so that we can update the views whenever a
- // Calendar event changes.
- private ContentObserver mObserver = new ContentObserver(new Handler())
- {
- @Override
- public boolean deliverSelfNotifications() {
- return true;
- }
-
- @Override
- public void onChange(boolean selfChange) {
- eventsChanged();
- }
- };
-
- public void onAnimationStart(Animation animation) {
- }
-
- // Notifies the MonthView when an animation has finished.
- public void onAnimationEnd(Animation animation) {
- MonthView monthView = (MonthView) mSwitcher.getCurrentView();
- monthView.animationFinished();
- }
-
- public void onAnimationRepeat(Animation animation) {
- }
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- // Eliminate extra GCs during startup by setting the initial heap size to 4MB.
- // TODO: We should restore the old heap size once the activity reaches the idle state
- long oldHeapSize = VMRuntime.getRuntime().setMinimumHeapSize(INITIAL_HEAP_SIZE);
-
- setContentView(R.layout.month_activity);
- mContentResolver = getContentResolver();
-
- long time;
- if (icicle != null) {
- time = icicle.getLong(EVENT_BEGIN_TIME);
- } else {
- time = Utils.timeFromIntentInMillis(getIntent());
- }
-
- mTime = new Time();
- mTime.set(time);
- mTime.normalize(true);
-
- // Get first day of week based on locale and populate the day headers
- mStartDay = Calendar.getInstance().getFirstDayOfWeek();
- int diff = mStartDay - Calendar.SUNDAY - 1;
-
- String dayString = DateUtils.getDayOfWeekString((Calendar.SUNDAY + diff) % 7 + 1,
- DateUtils.LENGTH_MEDIUM);
- ((TextView) findViewById(R.id.day0)).setText(dayString);
- dayString = DateUtils.getDayOfWeekString((Calendar.MONDAY + diff) % 7 + 1,
- DateUtils.LENGTH_MEDIUM);
- ((TextView) findViewById(R.id.day1)).setText(dayString);
- dayString = DateUtils.getDayOfWeekString((Calendar.TUESDAY + diff) % 7 + 1,
- DateUtils.LENGTH_MEDIUM);
- ((TextView) findViewById(R.id.day2)).setText(dayString);
- dayString = DateUtils.getDayOfWeekString((Calendar.WEDNESDAY + diff) % 7 + 1,
- DateUtils.LENGTH_MEDIUM);
- ((TextView) findViewById(R.id.day3)).setText(dayString);
- dayString = DateUtils.getDayOfWeekString((Calendar.THURSDAY + diff) % 7 + 1,
- DateUtils.LENGTH_MEDIUM);
- ((TextView) findViewById(R.id.day4)).setText(dayString);
- dayString = DateUtils.getDayOfWeekString((Calendar.FRIDAY + diff) % 7 + 1,
- DateUtils.LENGTH_MEDIUM);
- ((TextView) findViewById(R.id.day5)).setText(dayString);
- dayString = DateUtils.getDayOfWeekString((Calendar.SATURDAY + diff) % 7 + 1,
- DateUtils.LENGTH_MEDIUM);
- ((TextView) findViewById(R.id.day6)).setText(dayString);
-
- // Set the initial title
- TextView title = (TextView) findViewById(R.id.title);
- title.setText(Utils.formatMonthYear(mTime));
-
- mEventLoader = new EventLoader(this);
- mProgressBar = (ProgressBar) findViewById(R.id.progress_circular);
-
- mSwitcher = (ViewSwitcher) findViewById(R.id.switcher);
- mSwitcher.setFactory(this);
- mSwitcher.getCurrentView().requestFocus();
-
- mInAnimationPast = AnimationUtils.loadAnimation(this, R.anim.slide_down_in);
- mOutAnimationPast = AnimationUtils.loadAnimation(this, R.anim.slide_down_out);
- mInAnimationFuture = AnimationUtils.loadAnimation(this, R.anim.slide_up_in);
- mOutAnimationFuture = AnimationUtils.loadAnimation(this, R.anim.slide_up_out);
-
- mInAnimationPast.setAnimationListener(this);
- mInAnimationFuture.setAnimationListener(this);
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- if (isFinishing()) {
- mEventLoader.stopBackgroundThread();
- }
- mContentResolver.unregisterContentObserver(mObserver);
- unregisterReceiver(mIntentReceiver);
-
- MonthView view = (MonthView) mSwitcher.getCurrentView();
- view.dismissPopup();
- view = (MonthView) mSwitcher.getNextView();
- view.dismissPopup();
- mEventLoader.stopBackgroundThread();
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- mEventLoader.startBackgroundThread();
- eventsChanged();
-
- MonthView view1 = (MonthView) mSwitcher.getCurrentView();
- MonthView view2 = (MonthView) mSwitcher.getNextView();
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- String str = prefs.getString(CalendarPreferenceActivity.KEY_DETAILED_VIEW,
- CalendarPreferenceActivity.DEFAULT_DETAILED_VIEW);
- view1.setDetailedView(str);
- view2.setDetailedView(str);
-
- // Record Month View as the (new) start view
- String activityString = CalendarApplication.ACTIVITY_NAMES[CalendarApplication.MONTH_VIEW_ID];
- SharedPreferences.Editor editor = prefs.edit();
- editor.putString(CalendarPreferenceActivity.KEY_START_VIEW, activityString);
- editor.commit();
-
- // Register for Intent broadcasts
- IntentFilter filter = new IntentFilter();
-
- filter.addAction(Intent.ACTION_TIME_CHANGED);
- filter.addAction(Intent.ACTION_DATE_CHANGED);
- filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
- registerReceiver(mIntentReceiver, filter);
-
- mContentResolver.registerContentObserver(Events.CONTENT_URI,
- true, mObserver);
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putLong(EVENT_BEGIN_TIME, mTime.toMillis(true));
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_BACK:
- finish();
- return true;
- }
- return super.onKeyDown(keyCode, event);
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- MenuHelper.onPrepareOptionsMenu(this, menu);
- return super.onPrepareOptionsMenu(menu);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuHelper.onCreateOptionsMenu(menu);
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- MenuHelper.onOptionsItemSelected(this, item, this);
- return super.onOptionsItemSelected(item);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2006 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 static android.provider.Calendar.EVENT_BEGIN_TIME;
-import static android.provider.Calendar.EVENT_END_TIME;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.provider.Calendar.BusyBits;
-import android.text.format.DateFormat;
-import android.text.format.DateUtils;
-import android.text.format.Time;
-import android.util.DayOfMonthCursor;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.ContextMenu;
-import android.view.GestureDetector;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.widget.PopupWindow;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-
-public class MonthView extends View implements View.OnCreateContextMenuListener {
-
- private static final boolean PROFILE_LOAD_TIME = false;
- private static final boolean DEBUG_BUSYBITS = false;
-
- private static final int WEEK_GAP = 0;
- private static final int MONTH_DAY_GAP = 1;
- private static final float HOUR_GAP = 0.5f;
-
- private static final int MONTH_DAY_TEXT_SIZE = 20;
- private static final int WEEK_BANNER_HEIGHT = 17;
- private static final int WEEK_TEXT_SIZE = 15;
- private static final int WEEK_TEXT_PADDING = 3;
- private static final int BUSYBIT_WIDTH = 10;
- private static final int BUSYBIT_RIGHT_MARGIN = 3;
- private static final int BUSYBIT_TOP_BOTTOM_MARGIN = 7;
-
- private static final int HORIZONTAL_FLING_THRESHOLD = 50;
-
- private int mCellHeight;
- private int mBorder;
- private boolean mLaunchDayView;
-
- private GestureDetector mGestureDetector;
-
- private String mDetailedView = CalendarPreferenceActivity.DEFAULT_DETAILED_VIEW;
-
- private Time mToday;
- private Time mViewCalendar;
- private Time mSavedTime = new Time(); // the time when we entered this view
-
- // This Time object is used to set the time for the other Month view.
- private Time mOtherViewCalendar = new Time();
-
- // This Time object is used for temporary calculations and is allocated
- // once to avoid extra garbage collection
- private Time mTempTime = new Time();
-
- private DayOfMonthCursor mCursor;
-
- private Drawable mBoxSelected;
- private Drawable mBoxPressed;
- private Drawable mBoxLongPressed;
- private Drawable mDnaEmpty;
- private Drawable mDnaTop;
- private Drawable mDnaMiddle;
- private Drawable mDnaBottom;
- private int mCellWidth;
-
- private Resources mResources;
- private MonthActivity mParentActivity;
- private Navigator mNavigator;
- private final EventGeometry mEventGeometry;
-
- // Pre-allocate and reuse
- private Rect mRect = new Rect();
-
- // The number of hours represented by one busy bit
- private static final int HOURS_PER_BUSY_SLOT = 4;
-
- // The number of database intervals represented by one busy bit (slot)
- private static final int INTERVALS_PER_BUSY_SLOT = 4 * 60 / BusyBits.MINUTES_PER_BUSY_INTERVAL;
-
- // The bit mask for coalescing the raw busy bits from the database
- // (1 bit per hour) into the busy bits per slot (4-hour slots).
- private static final int BUSY_SLOT_MASK = (1 << INTERVALS_PER_BUSY_SLOT) - 1;
-
- // The number of slots in a day
- private static final int SLOTS_PER_DAY = 24 / HOURS_PER_BUSY_SLOT;
-
- // There is one "busy" bit for each slot of time.
- private byte[][] mBusyBits = new byte[31][SLOTS_PER_DAY];
-
- // Raw busy bits from database
- private int[] mRawBusyBits = new int[31];
- private int[] mAllDayCounts = new int[31];
-
- private PopupWindow mPopup;
- private View mPopupView;
- private static final int POPUP_HEIGHT = 100;
- private int mPreviousPopupHeight;
- private static final int POPUP_DISMISS_DELAY = 3000;
- private DismissPopup mDismissPopup = new DismissPopup();
-
- // For drawing to an off-screen Canvas
- private Bitmap mBitmap;
- private Canvas mCanvas;
- private boolean mRedrawScreen = true;
- private Rect mBitmapRect = new Rect();
- private boolean mAnimating;
-
- // These booleans disable features that were taken out of the spec.
- private boolean mShowWeekNumbers = false;
- private boolean mShowToast = false;
-
- // Bitmap caches.
- // These improve performance by minimizing calls to NinePatchDrawable.draw() for common
- // drawables for events and day backgrounds.
- // mEventBitmapCache is indexed by an integer constructed from the bits in the busyBits
- // field. It is not expected to be larger than 12 bits (if so, we should switch to using a Map).
- // mDayBitmapCache is indexed by a unique integer constructed from the width/height.
- private SparseArray<Bitmap> mEventBitmapCache = new SparseArray<Bitmap>(1<<SLOTS_PER_DAY);
- private SparseArray<Bitmap> mDayBitmapCache = new SparseArray<Bitmap>(4);
-
- private ContextMenuHandler mContextMenuHandler = new ContextMenuHandler();
-
- /**
- * The selection modes are HIDDEN, PRESSED, SELECTED, and LONGPRESS.
- */
- private static final int SELECTION_HIDDEN = 0;
- private static final int SELECTION_PRESSED = 1;
- private static final int SELECTION_SELECTED = 2;
- private static final int SELECTION_LONGPRESS = 3;
-
- // Modulo used to pack (width,height) into a unique integer
- private static final int MODULO_SHIFT = 16;
-
- private int mSelectionMode = SELECTION_HIDDEN;
-
- /**
- * The first Julian day of the current month.
- */
- private int mFirstJulianDay;
-
- private final EventLoader mEventLoader;
-
- private ArrayList<Event> mEvents = new ArrayList<Event>();
-
- private Drawable mTodayBackground;
- private Drawable mDayBackground;
-
- // Cached colors
- private int mMonthOtherMonthColor;
- private int mMonthWeekBannerColor;
- private int mMonthOtherMonthBannerColor;
- private int mMonthOtherMonthDayNumberColor;
- private int mMonthDayNumberColor;
- private int mMonthTodayNumberColor;
-
- public MonthView(MonthActivity activity, Navigator navigator) {
- super(activity);
- mEventLoader = activity.mEventLoader;
- mNavigator = navigator;
- mEventGeometry = new EventGeometry();
- mEventGeometry.setMinEventHeight(1.0f);
- mEventGeometry.setHourGap(HOUR_GAP);
- init(activity);
- }
-
- private void init(MonthActivity activity) {
- setFocusable(true);
- setClickable(true);
- setOnCreateContextMenuListener(this);
- mParentActivity = activity;
- mViewCalendar = new Time();
- long now = System.currentTimeMillis();
- mViewCalendar.set(now);
- mViewCalendar.monthDay = 1;
- long millis = mViewCalendar.normalize(true /* ignore DST */);
- mFirstJulianDay = Time.getJulianDay(millis, mViewCalendar.gmtoff);
- mViewCalendar.set(now);
-
- mCursor = new DayOfMonthCursor(mViewCalendar.year, mViewCalendar.month,
- mViewCalendar.monthDay, mParentActivity.getStartDay());
- mToday = new Time();
- mToday.set(System.currentTimeMillis());
-
- mResources = activity.getResources();
- mBoxSelected = mResources.getDrawable(R.drawable.month_view_selected);
- mBoxPressed = mResources.getDrawable(R.drawable.month_view_pressed);
- mBoxLongPressed = mResources.getDrawable(R.drawable.month_view_longpress);
-
- mDnaEmpty = mResources.getDrawable(R.drawable.dna_empty);
- mDnaTop = mResources.getDrawable(R.drawable.dna_1_of_6);
- mDnaMiddle = mResources.getDrawable(R.drawable.dna_2345_of_6);
- mDnaBottom = mResources.getDrawable(R.drawable.dna_6_of_6);
- mTodayBackground = mResources.getDrawable(R.drawable.month_view_today_background);
- mDayBackground = mResources.getDrawable(R.drawable.month_view_background);
-
- // Cache color lookups
- Resources res = getResources();
- mMonthOtherMonthColor = res.getColor(R.color.month_other_month);
- mMonthWeekBannerColor = res.getColor(R.color.month_week_banner);
- mMonthOtherMonthBannerColor = res.getColor(R.color.month_other_month_banner);
- mMonthOtherMonthDayNumberColor = res.getColor(R.color.month_other_month_day_number);
- mMonthDayNumberColor = res.getColor(R.color.month_day_number);
- mMonthTodayNumberColor = res.getColor(R.color.month_today_number);
-
- if (mShowToast) {
- LayoutInflater inflater;
- inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mPopupView = inflater.inflate(R.layout.month_bubble, null);
- mPopup = new PopupWindow(activity);
- mPopup.setContentView(mPopupView);
- Resources.Theme dialogTheme = getResources().newTheme();
- dialogTheme.applyStyle(android.R.style.Theme_Dialog, true);
- TypedArray ta = dialogTheme.obtainStyledAttributes(new int[] {
- android.R.attr.windowBackground });
- mPopup.setBackgroundDrawable(ta.getDrawable(0));
- ta.recycle();
- }
-
- mGestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
- float velocityY) {
- // The user might do a slow "fling" after touching the screen
- // and we don't want the long-press to pop up a context menu.
- // Setting mLaunchDayView to false prevents the long-press.
- mLaunchDayView = false;
- mSelectionMode = SELECTION_HIDDEN;
-
- int distanceX = Math.abs((int) e2.getX() - (int) e1.getX());
- int distanceY = Math.abs((int) e2.getY() - (int) e1.getY());
- if (distanceY < HORIZONTAL_FLING_THRESHOLD || distanceY < distanceX) {
- return false;
- }
-
- // Switch to a different month
- Time time = mOtherViewCalendar;
- time.set(mViewCalendar);
- if (velocityY < 0) {
- time.month += 1;
- } else {
- time.month -= 1;
- }
- time.normalize(true);
- mParentActivity.goTo(time);
-
- return true;
- }
-
- @Override
- public boolean onDown(MotionEvent e) {
- mLaunchDayView = false;
- return true;
- }
-
- @Override
- public void onShowPress(MotionEvent e) {
- int x = (int) e.getX();
- int y = (int) e.getY();
- int row = (y - WEEK_GAP) / (WEEK_GAP + mCellHeight);
- int col = (x - mBorder) / (MONTH_DAY_GAP + mCellWidth);
- if (row > 5) {
- row = 5;
- }
- if (col > 6) {
- col = 6;
- }
-
- // Launch the Day/Agenda view when the finger lifts up,
- // unless the finger moves before lifting up.
- mLaunchDayView = true;
-
- // Highlight the selected day.
- mCursor.setSelectedRowColumn(row, col);
- mSelectionMode = SELECTION_PRESSED;
- mRedrawScreen = true;
- invalidate();
- }
-
- @Override
- public void onLongPress(MotionEvent e) {
- // If mLaunchDayView is true, then we haven't done any scrolling
- // after touching the screen, so allow long-press to proceed
- // with popping up the context menu.
- if (mLaunchDayView) {
- mLaunchDayView = false;
- mSelectionMode = SELECTION_LONGPRESS;
- mRedrawScreen = true;
- invalidate();
- performLongClick();
- }
- }
-
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2,
- float distanceX, float distanceY) {
- // If the user moves his finger after touching, then do not
- // launch the Day view when he lifts his finger. Also, turn
- // off the selection.
- mLaunchDayView = false;
-
- if (mSelectionMode != SELECTION_HIDDEN) {
- mSelectionMode = SELECTION_HIDDEN;
- mRedrawScreen = true;
- invalidate();
- }
- return true;
- }
-
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- if (mLaunchDayView) {
- mSelectionMode = SELECTION_SELECTED;
- mRedrawScreen = true;
- invalidate();
- mLaunchDayView = false;
- int x = (int) e.getX();
- int y = (int) e.getY();
- long millis = getSelectedMillisFor(x, y);
- Utils.startActivity(getContext(), mDetailedView, millis);
- mParentActivity.finish();
- }
-
- return true;
- }
- });
- }
-
- public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
- MenuItem item;
-
- final long startMillis = getSelectedTimeInMillis();
- final int flags = DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE
- | DateUtils.FORMAT_ABBREV_MONTH;
-
- final String title = DateUtils.formatDateTime(mParentActivity, startMillis, flags);
- menu.setHeaderTitle(title);
-
- item = menu.add(0, MenuHelper.MENU_DAY, 0, R.string.show_day_view);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_day);
- item.setAlphabeticShortcut('d');
-
- item = menu.add(0, MenuHelper.MENU_AGENDA, 0, R.string.show_agenda_view);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_agenda);
- item.setAlphabeticShortcut('a');
-
- item = menu.add(0, MenuHelper.MENU_EVENT_CREATE, 0, R.string.event_create);
- item.setOnMenuItemClickListener(mContextMenuHandler);
- item.setIcon(android.R.drawable.ic_menu_add);
- item.setAlphabeticShortcut('n');
- }
-
- private class ContextMenuHandler implements MenuItem.OnMenuItemClickListener {
- public boolean onMenuItemClick(MenuItem item) {
- switch (item.getItemId()) {
- case MenuHelper.MENU_DAY: {
- long startMillis = getSelectedTimeInMillis();
- MenuHelper.switchTo(mParentActivity, DayActivity.class.getName(), startMillis);
- mParentActivity.finish();
- break;
- }
- case MenuHelper.MENU_AGENDA: {
- long startMillis = getSelectedTimeInMillis();
- MenuHelper.switchTo(mParentActivity, AgendaActivity.class.getName(), startMillis);
- mParentActivity.finish();
- break;
- }
- case MenuHelper.MENU_EVENT_CREATE: {
- long startMillis = getSelectedTimeInMillis();
- long endMillis = startMillis + DateUtils.HOUR_IN_MILLIS;
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setClassName(mContext, EditEvent.class.getName());
- intent.putExtra(EVENT_BEGIN_TIME, startMillis);
- intent.putExtra(EVENT_END_TIME, endMillis);
- mParentActivity.startActivity(intent);
- break;
- }
- default: {
- return false;
- }
- }
- return true;
- }
- }
-
- void reloadEvents() {
- // Get the date for the beginning of the month
- Time monthStart = mTempTime;
- monthStart.set(mViewCalendar);
- monthStart.monthDay = 1;
- monthStart.hour = 0;
- monthStart.minute = 0;
- monthStart.second = 0;
- long millis = monthStart.normalize(true /* ignore isDst */);
- int startDay = Time.getJulianDay(millis, monthStart.gmtoff);
-
- // Load the busy-bits in the background
- mParentActivity.startProgressSpinner();
- final long startMillis;
- if (PROFILE_LOAD_TIME) {
- startMillis = SystemClock.uptimeMillis();
- } else {
- // To avoid a compiler error that this variable might not be initialized.
- startMillis = 0;
- }
- mEventLoader.loadBusyBitsInBackground(startDay, 31, mRawBusyBits, mAllDayCounts,
- new Runnable() {
- public void run() {
- convertBusyBits();
- if (PROFILE_LOAD_TIME) {
- long endMillis = SystemClock.uptimeMillis();
- long elapsed = endMillis - startMillis;
- Log.i("Cal", (mViewCalendar.month+1) + "/" + mViewCalendar.year + " Month view load busybits: " + elapsed);
- }
- mRedrawScreen = true;
- mParentActivity.stopProgressSpinner();
- invalidate();
- }
- });
- }
-
- void animationStarted() {
- mAnimating = true;
- }
-
- void animationFinished() {
- mAnimating = false;
- mRedrawScreen = true;
- invalidate();
- }
-
- @Override
- protected void onSizeChanged(int width, int height, int oldw, int oldh) {
- drawingCalc(width, height);
- // If the size changed, then we should rebuild the bitmaps...
- clearBitmapCache();
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- // No need to hang onto the bitmaps...
- clearBitmapCache();
- if (mBitmap != null) {
- mBitmap.recycle();
- }
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- if (mRedrawScreen) {
- if (mCanvas == null) {
- drawingCalc(getWidth(), getHeight());
- }
-
- // If we are zero-sized, the canvas will remain null so check again
- if (mCanvas != null) {
- // Clear the background
- final Canvas bitmapCanvas = mCanvas;
- bitmapCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
- doDraw(bitmapCanvas);
- mRedrawScreen = false;
- }
- }
-
- // If we are zero-sized, the bitmap will be null so guard against this
- if (mBitmap != null) {
- canvas.drawBitmap(mBitmap, mBitmapRect, mBitmapRect, null);
- }
- }
-
- private void doDraw(Canvas canvas) {
- boolean isLandscape = getResources().getConfiguration().orientation
- == Configuration.ORIENTATION_LANDSCAPE;
-
- Paint p = new Paint();
- Rect r = mRect;
- int columnDay1 = mCursor.getColumnOf(1);
-
- // Get the Julian day for the date at row 0, column 0.
- int day = mFirstJulianDay - columnDay1;
-
- int weekNum = 0;
- Calendar calendar = null;
- if (mShowWeekNumbers) {
- calendar = Calendar.getInstance();
- boolean noPrevMonth = (columnDay1 == 0);
-
- // Compute the week number for the first row.
- weekNum = getWeekOfYear(0, 0, noPrevMonth, calendar);
- }
-
- for (int row = 0; row < 6; row++) {
- for (int column = 0; column < 7; column++) {
- drawBox(day, weekNum, row, column, canvas, p, r, isLandscape);
- day += 1;
- }
-
- if (mShowWeekNumbers) {
- weekNum += 1;
- if (weekNum >= 53) {
- boolean inCurrentMonth = (day - mFirstJulianDay < 31);
- weekNum = getWeekOfYear(row + 1, 0, inCurrentMonth, calendar);
- }
- }
- }
-
- drawGrid(canvas, p);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (mGestureDetector.onTouchEvent(event)) {
- return true;
- }
-
- return super.onTouchEvent(event);
- }
-
- private long getSelectedMillisFor(int x, int y) {
- int row = (y - WEEK_GAP) / (WEEK_GAP + mCellHeight);
- int column = (x - mBorder) / (MONTH_DAY_GAP + mCellWidth);
- if (column > 6) {
- column = 6;
- }
-
- DayOfMonthCursor c = mCursor;
- Time time = mTempTime;
- time.set(mViewCalendar);
-
- // Compute the day number from the row and column. If the row and
- // column are in a different month from the current one, then the
- // monthDay might be negative or it might be greater than the number
- // of days in this month, but that is okay because the normalize()
- // method will adjust the month (and year) if necessary.
- time.monthDay = 7 * row + column - c.getOffset() + 1;
- return time.normalize(true);
- }
-
- /**
- * Create a bitmap at the origin and draw the drawable to it using the bounds specified by rect.
- *
- * @param drawable the drawable we wish to render
- * @param width the width of the resulting bitmap
- * @param height the height of the resulting bitmap
- * @return a new bitmap
- */
- private Bitmap createBitmap(Drawable drawable, int width, int height) {
- // Create a bitmap with the same format as mBitmap (should be Bitmap.Config.ARGB_8888)
- Bitmap bitmap = Bitmap.createBitmap(width, height, mBitmap.getConfig());
-
- // Draw the drawable into the bitmap at the origin.
- Canvas canvas = new Canvas(bitmap);
- drawable.setBounds(0, 0, width, height);
- drawable.draw(canvas);
- return bitmap;
- }
-
- /**
- * Clears the bitmap cache. Generally only needed when the screen size changed.
- */
- private void clearBitmapCache() {
- recycleAndClearBitmapCache(mEventBitmapCache);
- recycleAndClearBitmapCache(mDayBitmapCache);
- }
-
- private void recycleAndClearBitmapCache(SparseArray<Bitmap> bitmapCache) {
- int size = bitmapCache.size();
- for(int i = 0; i < size; i++) {
- bitmapCache.valueAt(i).recycle();
- }
- bitmapCache.clear();
-
- }
-
- /**
- * Draw the grid lines for the calendar
- * @param canvas The canvas to draw on.
- * @param p The paint used for drawing.
- */
- private void drawGrid(Canvas canvas, Paint p) {
- p.setColor(mMonthOtherMonthColor);
- p.setAntiAlias(false);
-
- final int width = getMeasuredWidth();
- final int height = getMeasuredHeight();
-
- for (int row = 0; row < 6; row++) {
- int y = WEEK_GAP + row * (WEEK_GAP + mCellHeight) - 1;
- canvas.drawLine(0, y, width, y, p);
- }
- for (int column = 1; column < 7; column++) {
- int x = mBorder + column * (MONTH_DAY_GAP + mCellWidth) - 1;
- canvas.drawLine(x, WEEK_GAP, x, height, p);
- }
- }
-
- /**
- * Draw a single box onto the canvas.
- * @param day The Julian day.
- * @param weekNum The week number.
- * @param row The row of the box (0-5).
- * @param column The column of the box (0-6).
- * @param canvas The canvas to draw on.
- * @param p The paint used for drawing.
- * @param r The rectangle used for each box.
- * @param isLandscape Is the current orientation landscape.
- */
- private void drawBox(int day, int weekNum, int row, int column, Canvas canvas, Paint p,
- Rect r, boolean isLandscape) {
-
- // Only draw the selection if we are in the press state or if we have
- // moved the cursor with key input.
- boolean drawSelection = false;
- if (mSelectionMode != SELECTION_HIDDEN) {
- drawSelection = mCursor.isSelected(row, column);
- }
-
- boolean withinCurrentMonth = mCursor.isWithinCurrentMonth(row, column);
- boolean isToday = false;
- int dayOfBox = mCursor.getDayAt(row, column);
- if (dayOfBox == mToday.monthDay && mCursor.getYear() == mToday.year
- && mCursor.getMonth() == mToday.month) {
- isToday = true;
- }
-
- int y = WEEK_GAP + row*(WEEK_GAP + mCellHeight);
- int x = mBorder + column*(MONTH_DAY_GAP + mCellWidth);
-
- r.left = x;
- r.top = y;
- r.right = x + mCellWidth;
- r.bottom = y + mCellHeight;
-
-
- // Adjust the left column, right column, and bottom row to leave
- // no border.
- if (column == 0) {
- r.left = -1;
- } else if (column == 6) {
- r.right += mBorder + 2;
- }
-
- if (row == 5) {
- r.bottom = getMeasuredHeight();
- }
-
- // Draw the cell contents (excluding monthDay number)
- if (!withinCurrentMonth) {
- boolean firstDayOfNextmonth = isFirstDayOfNextMonth(row, column);
-
- // Adjust cell boundaries to compensate for the different border
- // style.
- r.top--;
- if (column != 0) {
- r.left--;
- }
- } else if (drawSelection) {
- if (mSelectionMode == SELECTION_SELECTED) {
- mBoxSelected.setBounds(r);
- mBoxSelected.draw(canvas);
- } else if (mSelectionMode == SELECTION_PRESSED) {
- mBoxPressed.setBounds(r);
- mBoxPressed.draw(canvas);
- } else {
- mBoxLongPressed.setBounds(r);
- mBoxLongPressed.draw(canvas);
- }
-
- drawEvents(day, canvas, r, p);
- if (!mAnimating) {
- updateEventDetails(day);
- }
- } else {
- // Today gets a different background
- if (isToday) {
- // We could cache this for a little bit more performance, but it's not on the
- // performance radar...
- Drawable background = mTodayBackground;
- background.setBounds(r);
- background.draw(canvas);
- } else {
- // Use the bitmap cache to draw the day background
- int width = r.right - r.left;
- int height = r.bottom - r.top;
- // Compute a unique id that depends on width and height.
- int id = (height << MODULO_SHIFT) | width;
- Bitmap bitmap = mDayBitmapCache.get(id);
- if (bitmap == null) {
- bitmap = createBitmap(mDayBackground, width, height);
- mDayBitmapCache.put(id, bitmap);
- }
- canvas.drawBitmap(bitmap, r.left, r.top, p);
- }
- drawEvents(day, canvas, r, p);
- }
-
- // Draw week number
- if (mShowWeekNumbers && column == 0) {
- // Draw the banner
- p.setStyle(Paint.Style.FILL);
- p.setColor(mMonthWeekBannerColor);
- int right = r.right;
- r.right = right - BUSYBIT_WIDTH - BUSYBIT_RIGHT_MARGIN;
- if (isLandscape) {
- int bottom = r.bottom;
- r.bottom = r.top + WEEK_BANNER_HEIGHT;
- r.left++;
- canvas.drawRect(r, p);
- r.bottom = bottom;
- r.left--;
- } else {
- int top = r.top;
- r.top = r.bottom - WEEK_BANNER_HEIGHT;
- r.left++;
- canvas.drawRect(r, p);
- r.top = top;
- r.left--;
- }
- r.right = right;
-
- // Draw the number
- p.setColor(mMonthOtherMonthBannerColor);
- p.setAntiAlias(true);
- p.setTypeface(null);
- p.setTextSize(WEEK_TEXT_SIZE);
- p.setTextAlign(Paint.Align.LEFT);
-
- int textX = r.left + WEEK_TEXT_PADDING;
- int textY;
- if (isLandscape) {
- textY = r.top + WEEK_BANNER_HEIGHT - WEEK_TEXT_PADDING;
- } else {
- textY = r.bottom - WEEK_TEXT_PADDING;
- }
-
- canvas.drawText(String.valueOf(weekNum), textX, textY, p);
- }
-
- // Draw the monthDay number
- p.setStyle(Paint.Style.FILL);
- p.setAntiAlias(true);
- p.setTypeface(null);
- p.setTextSize(MONTH_DAY_TEXT_SIZE);
-
- if (!withinCurrentMonth) {
- p.setColor(mMonthOtherMonthDayNumberColor);
- } else if (drawSelection || !isToday) {
- p.setColor(mMonthDayNumberColor);
- } else {
- p.setColor(mMonthTodayNumberColor);
- }
-
- p.setTextAlign(Paint.Align.CENTER);
- int right = r.right - BUSYBIT_WIDTH - BUSYBIT_RIGHT_MARGIN;
- int textX = r.left + (right - r.left) / 2; // center of text
- int textY = r.bottom - BUSYBIT_TOP_BOTTOM_MARGIN - 2; // bottom of text
- canvas.drawText(String.valueOf(mCursor.getDayAt(row, column)), textX, textY, p);
- }
-
- /**
- * Converts the busy bits from the database that use 1-hour intervals to
- * the 4-hour time slots needed in this view. Also, we map all-day
- * events to the first two 4-hour time slots (that is, an all-day event
- * will look like the first 8 hours from 12am to 8am are busy). This
- * looks better than setting just the first 4-hour time slot because that
- * is barely visible in landscape mode.
- */
- private void convertBusyBits() {
- if (DEBUG_BUSYBITS) {
- Log.i("Cal", "convertBusyBits() SLOTS_PER_DAY: " + SLOTS_PER_DAY
- + " BUSY_SLOT_MASK: " + BUSY_SLOT_MASK
- + " INTERVALS_PER_BUSY_SLOT: " + INTERVALS_PER_BUSY_SLOT);
- for (int day = 0; day < 31; day++) {
- int bits = mRawBusyBits[day];
- String bitString = String.format("0x%06x", bits);
- String valString = "";
- for (int slot = 0; slot < SLOTS_PER_DAY; slot++) {
- int val = bits & BUSY_SLOT_MASK;
- bits = bits >>> INTERVALS_PER_BUSY_SLOT;
- valString += " " + val;
- }
- Log.i("Cal", "[" + day + "] " + bitString + " " + valString
- + " allday: " + mAllDayCounts[day]);
- }
- }
- for (int day = 0; day < 31; day++) {
- int bits = mRawBusyBits[day];
- for (int slot = 0; slot < SLOTS_PER_DAY; slot++) {
- int val = bits & BUSY_SLOT_MASK;
- bits = bits >>> INTERVALS_PER_BUSY_SLOT;
- if (val == 0) {
- mBusyBits[day][slot] = 0;
- } else {
- mBusyBits[day][slot] = 1;
- }
- }
- if (mAllDayCounts[day] > 0) {
- mBusyBits[day][0] = 1;
- mBusyBits[day][1] = 1;
- }
- }
- }
-
- /**
- * Create a bitmap at the origin for the given set of busyBits.
- *
- * @param busyBits an array of bits with elements set to 1 if we have an event for that slot
- * @param rect the size of the resulting
- * @return a new bitmap
- */
- private Bitmap createEventBitmap(byte[] busyBits, Rect rect) {
- // Compute the size of the smallest bitmap, excluding margins.
- final int left = 0;
- final int right = BUSYBIT_WIDTH;
- final int top = 0;
- final int bottom = (rect.bottom - rect.top) - 2 * BUSYBIT_TOP_BOTTOM_MARGIN;
- final int height = bottom - top;
- final int width = right - left;
-
- final Drawable dnaEmpty = mDnaEmpty;
- final Drawable dnaTop = mDnaTop;
- final Drawable dnaMiddle = mDnaMiddle;
- final Drawable dnaBottom = mDnaBottom;
- final float slotHeight = (float) height / SLOTS_PER_DAY;
-
- // Create a bitmap with the same format as mBitmap (should be Bitmap.Config.ARGB_8888)
- Bitmap bitmap = Bitmap.createBitmap(width, height, mBitmap.getConfig());
-
- // Create a canvas for drawing and draw background (dnaEmpty)
- Canvas canvas = new Canvas(bitmap);
- dnaEmpty.setBounds(left, top, right, bottom);
- dnaEmpty.draw(canvas);
-
- // The first busy bit is a drawable that is round at the top
- if (busyBits[0] == 1) {
- float rectBottom = top + slotHeight;
- dnaTop.setBounds(left, top, right, (int) rectBottom);
- dnaTop.draw(canvas);
- }
-
- // The last busy bit is a drawable that is round on the bottom
- int lastIndex = busyBits.length - 1;
- if (busyBits[lastIndex] == 1) {
- float rectTop = bottom - slotHeight;
- dnaBottom.setBounds(left, (int) rectTop, right, bottom);
- dnaBottom.draw(canvas);
- }
-
- // Draw all intermediate pieces. We could further optimize this to
- // draw runs of bits, but it probably won't yield much more performance.
- float rectTop = top + slotHeight;
- for (int index = 1; index < lastIndex; index++) {
- float rectBottom = rectTop + slotHeight;
- if (busyBits[index] == 1) {
- dnaMiddle.setBounds(left, (int) rectTop, right, (int) rectBottom);
- dnaMiddle.draw(canvas);
- }
- rectTop = rectBottom;
- }
- return bitmap;
- }
-
- private void drawEvents(int date, Canvas canvas, Rect rect, Paint p) {
- // These are the coordinates of the upper left corner where we'll draw the event bitmap
- int top = rect.top + BUSYBIT_TOP_BOTTOM_MARGIN;
- int right = rect.right - BUSYBIT_RIGHT_MARGIN;
- int left = right - BUSYBIT_WIDTH;
-
- // Display the busy bits. Draw a rectangle for each run of 1-bits.
- int day = date - mFirstJulianDay;
- byte[] busyBits = mBusyBits[day];
- int lastIndex = busyBits.length - 1;
-
- // Cache index is simply all of the bits combined into an integer
- int cacheIndex = 0;
- for (int i = 0 ; i <= lastIndex; i++) cacheIndex |= busyBits[i] << i;
- Bitmap bitmap = mEventBitmapCache.get(cacheIndex);
- if (bitmap == null) {
- // Create a bitmap that we'll reuse for all events with the same
- // combination of busyBits.
- bitmap = createEventBitmap(busyBits, rect);
- mEventBitmapCache.put(cacheIndex, bitmap);
- }
- canvas.drawBitmap(bitmap, left, top, p);
- }
-
- private boolean isFirstDayOfNextMonth(int row, int column) {
- if (column == 0) {
- column = 6;
- row--;
- } else {
- column--;
- }
- return mCursor.isWithinCurrentMonth(row, column);
- }
-
- private int getWeekOfYear(int row, int column, boolean isWithinCurrentMonth,
- Calendar calendar) {
- calendar.set(Calendar.DAY_OF_MONTH, mCursor.getDayAt(row, column));
- if (isWithinCurrentMonth) {
- calendar.set(Calendar.MONTH, mCursor.getMonth());
- calendar.set(Calendar.YEAR, mCursor.getYear());
- } else {
- int month = mCursor.getMonth();
- int year = mCursor.getYear();
- if (row < 2) {
- // Previous month
- if (month == 0) {
- year--;
- month = 11;
- } else {
- month--;
- }
- } else {
- // Next month
- if (month == 11) {
- year++;
- month = 0;
- } else {
- month++;
- }
- }
- calendar.set(Calendar.MONTH, month);
- calendar.set(Calendar.YEAR, year);
- }
-
- return calendar.get(Calendar.WEEK_OF_YEAR);
- }
-
- void setDetailedView(String detailedView) {
- mDetailedView = detailedView;
- }
-
- void setSelectedTime(Time time) {
- // Save the selected time so that we can restore it later when we switch views.
- mSavedTime.set(time);
-
- mViewCalendar.set(time);
- mViewCalendar.monthDay = 1;
- long millis = mViewCalendar.normalize(true /* ignore DST */);
- mFirstJulianDay = Time.getJulianDay(millis, mViewCalendar.gmtoff);
- mViewCalendar.set(time);
-
- mCursor = new DayOfMonthCursor(time.year, time.month, time.monthDay,
- mCursor.getWeekStartDay());
-
- mRedrawScreen = true;
- invalidate();
- }
-
- public long getSelectedTimeInMillis() {
- Time time = mTempTime;
- time.set(mViewCalendar);
-
- time.month += mCursor.getSelectedMonthOffset();
- time.monthDay = mCursor.getSelectedDayOfMonth();
-
- // Restore the saved hour:minute:second offset from when we entered
- // this view.
- time.second = mSavedTime.second;
- time.minute = mSavedTime.minute;
- time.hour = mSavedTime.hour;
- return time.normalize(true);
- }
-
- Time getTime() {
- return mViewCalendar;
- }
-
- public int getSelectionMode() {
- return mSelectionMode;
- }
-
- public void setSelectionMode(int selectionMode) {
- mSelectionMode = selectionMode;
- }
-
- private void drawingCalc(int width, int height) {
- mCellHeight = (height - (6 * WEEK_GAP)) / 6;
- mEventGeometry.setHourHeight((mCellHeight - 25.0f * HOUR_GAP) / 24.0f);
- mCellWidth = (width - (6 * MONTH_DAY_GAP)) / 7;
- mBorder = (width - 6 * (mCellWidth + MONTH_DAY_GAP) - mCellWidth) / 2;
-
- if (mShowToast) {
- mPopup.dismiss();
- mPopup.setWidth(width - 20);
- mPopup.setHeight(POPUP_HEIGHT);
- }
-
- if (((mBitmap == null)
- || mBitmap.isRecycled()
- || (mBitmap.getHeight() != height)
- || (mBitmap.getWidth() != width))
- && (width > 0) && (height > 0)) {
- if (mBitmap != null) {
- mBitmap.recycle();
- }
- mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- mCanvas = new Canvas(mBitmap);
- }
-
- mBitmapRect.top = 0;
- mBitmapRect.bottom = height;
- mBitmapRect.left = 0;
- mBitmapRect.right = width;
- }
-
- private void updateEventDetails(int date) {
- if (!mShowToast) {
- return;
- }
-
- getHandler().removeCallbacks(mDismissPopup);
- ArrayList<Event> events = mEvents;
- int numEvents = events.size();
- if (numEvents == 0) {
- mPopup.dismiss();
- return;
- }
-
- int eventIndex = 0;
- for (int i = 0; i < numEvents; i++) {
- Event event = events.get(i);
-
- if (event.startDay > date || event.endDay < date) {
- continue;
- }
-
- // If we have all the event that we can display, then just count
- // the extra ones.
- if (eventIndex >= 4) {
- eventIndex += 1;
- continue;
- }
-
- int flags;
- boolean showEndTime = false;
- if (event.allDay) {
- int numDays = event.endDay - event.startDay;
- if (numDays == 0) {
- flags = DateUtils.FORMAT_UTC | DateUtils.FORMAT_SHOW_DATE
- | DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_ALL;
- } else {
- showEndTime = true;
- flags = DateUtils.FORMAT_UTC | DateUtils.FORMAT_SHOW_DATE
- | DateUtils.FORMAT_ABBREV_ALL;
- }
- } else {
- flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_CAP_NOON_MIDNIGHT;
- if (DateFormat.is24HourFormat(mContext)) {
- flags |= DateUtils.FORMAT_24HOUR;
- }
- }
-
- String timeRange;
- if (showEndTime) {
- timeRange = DateUtils.formatDateRange(mParentActivity,
- event.startMillis, event.endMillis, flags);
- } else {
- timeRange = DateUtils.formatDateRange(mParentActivity,
- event.startMillis, event.startMillis, flags);
- }
-
- TextView timeView = null;
- TextView titleView = null;
- switch (eventIndex) {
- case 0:
- timeView = (TextView) mPopupView.findViewById(R.id.time0);
- titleView = (TextView) mPopupView.findViewById(R.id.event_title0);
- break;
- case 1:
- timeView = (TextView) mPopupView.findViewById(R.id.time1);
- titleView = (TextView) mPopupView.findViewById(R.id.event_title1);
- break;
- case 2:
- timeView = (TextView) mPopupView.findViewById(R.id.time2);
- titleView = (TextView) mPopupView.findViewById(R.id.event_title2);
- break;
- case 3:
- timeView = (TextView) mPopupView.findViewById(R.id.time3);
- titleView = (TextView) mPopupView.findViewById(R.id.event_title3);
- break;
- }
-
- timeView.setText(timeRange);
- titleView.setText(event.title);
- eventIndex += 1;
- }
- if (eventIndex == 0) {
- // We didn't find any events for this day
- mPopup.dismiss();
- return;
- }
-
- // Hide the items that have no event information
- View view;
- switch (eventIndex) {
- case 1:
- view = mPopupView.findViewById(R.id.item_layout1);
- view.setVisibility(View.GONE);
- view = mPopupView.findViewById(R.id.item_layout2);
- view.setVisibility(View.GONE);
- view = mPopupView.findViewById(R.id.item_layout3);
- view.setVisibility(View.GONE);
- view = mPopupView.findViewById(R.id.plus_more);
- view.setVisibility(View.GONE);
- break;
- case 2:
- view = mPopupView.findViewById(R.id.item_layout1);
- view.setVisibility(View.VISIBLE);
- view = mPopupView.findViewById(R.id.item_layout2);
- view.setVisibility(View.GONE);
- view = mPopupView.findViewById(R.id.item_layout3);
- view.setVisibility(View.GONE);
- view = mPopupView.findViewById(R.id.plus_more);
- view.setVisibility(View.GONE);
- break;
- case 3:
- view = mPopupView.findViewById(R.id.item_layout1);
- view.setVisibility(View.VISIBLE);
- view = mPopupView.findViewById(R.id.item_layout2);
- view.setVisibility(View.VISIBLE);
- view = mPopupView.findViewById(R.id.item_layout3);
- view.setVisibility(View.GONE);
- view = mPopupView.findViewById(R.id.plus_more);
- view.setVisibility(View.GONE);
- break;
- case 4:
- view = mPopupView.findViewById(R.id.item_layout1);
- view.setVisibility(View.VISIBLE);
- view = mPopupView.findViewById(R.id.item_layout2);
- view.setVisibility(View.VISIBLE);
- view = mPopupView.findViewById(R.id.item_layout3);
- view.setVisibility(View.VISIBLE);
- view = mPopupView.findViewById(R.id.plus_more);
- view.setVisibility(View.GONE);
- break;
- default:
- view = mPopupView.findViewById(R.id.item_layout1);
- view.setVisibility(View.VISIBLE);
- view = mPopupView.findViewById(R.id.item_layout2);
- view.setVisibility(View.VISIBLE);
- view = mPopupView.findViewById(R.id.item_layout3);
- view.setVisibility(View.VISIBLE);
- TextView tv = (TextView) mPopupView.findViewById(R.id.plus_more);
- tv.setVisibility(View.VISIBLE);
- String format = mResources.getString(R.string.plus_N_more);
- String plusMore = String.format(format, eventIndex - 4);
- tv.setText(plusMore);
- break;
- }
-
- if (eventIndex > 5) {
- eventIndex = 5;
- }
- int popupHeight = 20 * eventIndex + 15;
- mPopup.setHeight(popupHeight);
-
- if (mPreviousPopupHeight != popupHeight) {
- mPreviousPopupHeight = popupHeight;
- mPopup.dismiss();
- }
- mPopup.showAtLocation(this, Gravity.BOTTOM | Gravity.LEFT, 0, 0);
- postDelayed(mDismissPopup, POPUP_DISMISS_DELAY);
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- long duration = event.getEventTime() - event.getDownTime();
-
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_CENTER:
- if (mSelectionMode == SELECTION_HIDDEN) {
- // Don't do anything unless the selection is visible.
- break;
- }
-
- if (mSelectionMode == SELECTION_PRESSED) {
- // This was the first press when there was nothing selected.
- // Change the selection from the "pressed" state to the
- // the "selected" state. We treat short-press and
- // long-press the same here because nothing was selected.
- mSelectionMode = SELECTION_SELECTED;
- mRedrawScreen = true;
- invalidate();
- break;
- }
-
- // Check the duration to determine if this was a short press
- if (duration < ViewConfiguration.getLongPressTimeout()) {
- long millis = getSelectedTimeInMillis();
- Utils.startActivity(getContext(), mDetailedView, millis);
- mParentActivity.finish();
- } else {
- mSelectionMode = SELECTION_LONGPRESS;
- mRedrawScreen = true;
- invalidate();
- performLongClick();
- }
- }
- return super.onKeyUp(keyCode, event);
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (mSelectionMode == SELECTION_HIDDEN) {
- if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT
- || keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_UP
- || keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
- // Display the selection box but don't move or select it
- // on this key press.
- mSelectionMode = SELECTION_SELECTED;
- mRedrawScreen = true;
- invalidate();
- return true;
- } else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
- // Display the selection box but don't select it
- // on this key press.
- mSelectionMode = SELECTION_PRESSED;
- mRedrawScreen = true;
- invalidate();
- return true;
- }
- }
-
- mSelectionMode = SELECTION_SELECTED;
- boolean redraw = false;
- Time other = null;
-
- switch (keyCode) {
- case KeyEvent.KEYCODE_ENTER:
- long millis = getSelectedTimeInMillis();
- Utils.startActivity(getContext(), mDetailedView, millis);
- mParentActivity.finish();
- return true;
- case KeyEvent.KEYCODE_DPAD_UP:
- if (mCursor.up()) {
- other = mOtherViewCalendar;
- other.set(mViewCalendar);
- other.month -= 1;
- other.monthDay = mCursor.getSelectedDayOfMonth();
-
- // restore the calendar cursor for the animation
- mCursor.down();
- }
- redraw = true;
- break;
-
- case KeyEvent.KEYCODE_DPAD_DOWN:
- if (mCursor.down()) {
- other = mOtherViewCalendar;
- other.set(mViewCalendar);
- other.month += 1;
- other.monthDay = mCursor.getSelectedDayOfMonth();
-
- // restore the calendar cursor for the animation
- mCursor.up();
- }
- redraw = true;
- break;
-
- case KeyEvent.KEYCODE_DPAD_LEFT:
- if (mCursor.left()) {
- other = mOtherViewCalendar;
- other.set(mViewCalendar);
- other.month -= 1;
- other.monthDay = mCursor.getSelectedDayOfMonth();
-
- // restore the calendar cursor for the animation
- mCursor.right();
- }
- redraw = true;
- break;
-
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- if (mCursor.right()) {
- other = mOtherViewCalendar;
- other.set(mViewCalendar);
- other.month += 1;
- other.monthDay = mCursor.getSelectedDayOfMonth();
-
- // restore the calendar cursor for the animation
- mCursor.left();
- }
- redraw = true;
- break;
- }
-
- if (other != null) {
- other.normalize(true /* ignore DST */);
- mNavigator.goTo(other);
- } else if (redraw) {
- mRedrawScreen = true;
- invalidate();
- }
-
- return redraw;
- }
-
- class DismissPopup implements Runnable {
- public void run() {
- mPopup.dismiss();
- }
- }
-
- // This is called when the activity is paused so that the popup can
- // be dismissed.
- void dismissPopup() {
- if (!mShowToast) {
- return;
- }
-
- // Protect against null-pointer exceptions
- if (mPopup != null) {
- mPopup.dismiss();
- }
-
- Handler handler = getHandler();
- if (handler != null) {
- handler.removeCallbacks(mDismissPopup);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2008 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.text.format.Time;
-
-public interface Navigator {
- /**
- * Returns the time in millis of the selected event in this view.
- * @return the selected time in UTC milliseconds.
- */
- long getSelectedTime();
-
- /**
- * Changes the view to include the given time.
- * @param time the desired time to view.
- */
- void goTo(Time time);
-
- /**
- * Changes the view to include today's date.
- */
- void goToToday();
-
- /**
- * This is called when the user wants to create a new event and returns
- * true if the new event should default to an all-day event.
- * @return true if the new event should be an all-day event.
- */
- boolean getAllDay();
-}
+++ /dev/null
-/*
- * Copyright (C) 2007 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.app.Activity;
-import android.app.AlertDialog;
-import android.content.AsyncQueryHandler;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.Calendar.Calendars;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.view.MenuItem.OnMenuItemClickListener;
-import android.widget.AdapterView;
-import android.widget.CheckBox;
-import android.widget.ListView;
-
-
-public class SelectCalendarsActivity extends Activity implements ListView.OnItemClickListener {
-
- private static final String TAG = "Calendar";
- private View mView = null;
- private Cursor mCursor = null;
- private QueryHandler mQueryHandler;
- private SelectCalendarsAdapter mAdapter;
- private static final String[] PROJECTION = new String[] {
- Calendars._ID,
- Calendars.DISPLAY_NAME,
- Calendars.COLOR,
- Calendars.SELECTED,
- Calendars.SYNC_EVENTS
- };
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
- setContentView(R.layout.calendars_activity);
- getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
- Window.PROGRESS_INDETERMINATE_ON);
- mQueryHandler = new QueryHandler(getContentResolver());
- mView = findViewById(R.id.calendars);
- ListView items = (ListView) mView.findViewById(R.id.items);
- Context context = mView.getContext();
- mCursor = managedQuery(Calendars.CONTENT_URI, PROJECTION,
- Calendars.SYNC_EVENTS + "=1",
- null /* selectionArgs */,
- Calendars.DEFAULT_SORT_ORDER);
-
- mAdapter = new SelectCalendarsAdapter(context, mCursor);
- items.setAdapter(mAdapter);
- items.setOnItemClickListener(this);
-
- // Start a background sync to get the list of calendars from the server.
- startCalendarSync();
- }
-
- @Override
- public void onPause() {
- super.onPause();
-
- // We might have changed selected calendars, so push gadget updates
-
- // TODO: remove this once we link up CalendarProvider and any gadgets to watch
- // for updates to the Calendar table.
- CalendarGadgetProvider.performUpdate(this, null);
- }
-
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- CheckBox box = (CheckBox) view.findViewById(R.id.checkbox);
- box.toggle();
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
- MenuItem item;
- item = menu.add(0, 0, 0, R.string.add_calendars)
- .setOnMenuItemClickListener(new ChangeCalendarAction(false /* not remove */));
- item.setIcon(android.R.drawable.ic_menu_add);
-
- item = menu.add(0, 0, 0, R.string.remove_calendars)
- .setOnMenuItemClickListener(new ChangeCalendarAction(true /* remove */));
- item.setIcon(android.R.drawable.ic_menu_delete);
- return true;
- }
-
- /**
- * ChangeCalendarAction is used both for adding and removing calendars.
- * The constructor takes a boolean argument that is false if adding
- * calendars and true if removing calendars. The user selects calendars
- * to be added or removed from a pop-up list.
- */
- public class ChangeCalendarAction implements OnMenuItemClickListener,
- DialogInterface.OnClickListener, DialogInterface.OnMultiChoiceClickListener {
-
- int mNumItems;
- long[] mCalendarIds;
- boolean[] mIsChecked;
- ContentResolver mContentResolver;
- boolean mRemove;
-
- public ChangeCalendarAction(boolean remove) {
- mContentResolver = SelectCalendarsActivity.this.getContentResolver();
- mRemove = remove;
- }
-
- /*
- * This is called when the user selects a calendar from either the
- * "Add calendars" or "Remove calendars" popup dialog.
- */
- public void onClick(DialogInterface dialog, int position, boolean isChecked) {
- mIsChecked[position] = isChecked;
- }
-
- /*
- * This is called when the user presses the OK or Cancel button on the
- * "Add calendars" or "Remove calendars" popup dialog.
- */
- public void onClick(DialogInterface dialog, int which) {
- // If the user cancelled the dialog, then do nothing.
- if (which == DialogInterface.BUTTON2) {
- return;
- }
-
- boolean changesFound = false;
- for (int position = 0; position < mNumItems; position++) {
- // If this calendar wasn't selected, then skip it.
- if (!mIsChecked[position]) {
- continue;
- }
- changesFound = true;
-
- long id = mCalendarIds[position];
- Uri uri = ContentUris.withAppendedId(Calendars.CONTENT_URI, id);
- ContentValues values = new ContentValues();
- int selected = 1;
- if (mRemove) {
- selected = 0;
- }
- values.put(Calendars.SELECTED, selected);
- values.put(Calendars.SYNC_EVENTS, selected);
- mContentResolver.update(uri, values, null, null);
- }
-
- // If there were any changes, then update the list of calendars
- // that are synced.
- if (changesFound) {
- mCursor.requery();
- }
- }
-
- public boolean onMenuItemClick(MenuItem item) {
- AlertDialog.Builder builder = new AlertDialog.Builder(SelectCalendarsActivity.this);
- String selection;
- if (mRemove) {
- builder.setTitle(R.string.remove_calendars)
- .setIcon(android.R.drawable.ic_dialog_alert);
- selection = Calendars.SYNC_EVENTS + "=1";
- } else {
- builder.setTitle(R.string.add_calendars);
- selection = Calendars.SYNC_EVENTS + "=0";
- }
- ContentResolver cr = getContentResolver();
- Cursor cursor = cr.query(Calendars.CONTENT_URI, PROJECTION,
- selection, null /* selectionArgs */,
- Calendars.DEFAULT_SORT_ORDER);
- if (cursor == null) {
- Log.w(TAG, "Cannot get cursor for calendars");
- return true;
- }
-
- int count = cursor.getCount();
- mNumItems = count;
- CharSequence[] calendarNames = new CharSequence[count];
- mCalendarIds = new long[count];
- mIsChecked = new boolean[count];
- try {
- int pos = 0;
- while (cursor.moveToNext()) {
- mCalendarIds[pos] = cursor.getLong(0);
- calendarNames[pos] = cursor.getString(1);
- pos += 1;
- }
- } finally {
- cursor.close();
- }
-
- builder.setMultiChoiceItems(calendarNames, null, this)
- .setPositiveButton(android.R.string.ok, this)
- .setNegativeButton(android.R.string.cancel, this)
- .show();
- return true;
- }
- }
-
- private class QueryHandler extends AsyncQueryHandler {
- public QueryHandler(ContentResolver cr) {
- super(cr);
- }
-
- @Override
- protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
- getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
- Window.PROGRESS_VISIBILITY_OFF);
-
- // If the Activity is finishing, then close the cursor.
- // Otherwise, use the new cursor in the adapter.
- if (isFinishing()) {
- stopManagingCursor(cursor);
- cursor.close();
- } else {
- if (cursor.getCount() == 0) {
- // There are no calendars. This might happen if we lost
- // the wireless connection (in airplane mode, for example).
- // Leave the current list of calendars alone and pop up
- // a dialog explaining that the connection is down.
- // But allow the user to add and remove calendars.
- return;
- }
- if (mCursor != null) {
- stopManagingCursor(mCursor);
- }
- mCursor = cursor;
- startManagingCursor(cursor);
- mAdapter.changeCursor(cursor);
- }
- }
- }
-
- // This class implements the menu option "Refresh list from server".
- // (No longer used.)
- public class RefreshAction implements Runnable {
- public void run() {
- startCalendarSync();
- }
- }
-
- // startCalendarSync() checks the server for an updated list of Calendars
- // (in the background) using an AsyncQueryHandler.
- //
- // Calendars are never removed from the phone due to a server sync.
- // But if a Calendar is added on the web (and it is selected and not
- // hidden) then it will be added to the list of calendars on the phone
- // (when this asynchronous query finishes). When a new calendar from the
- // web is added to the phone, then the events for that calendar are also
- // downloaded from the web.
- //
- // This sync is done automatically in the background when the
- // SelectCalendars activity is started.
- private void startCalendarSync() {
- getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
- Window.PROGRESS_VISIBILITY_ON);
-
- // TODO: make sure the user has login info.
-
- Uri uri = Calendars.LIVE_CONTENT_URI;
- mQueryHandler.startQuery(0, null, uri, PROJECTION,
- Calendars.SYNC_EVENTS + "=1",
- null, Calendars.DEFAULT_SORT_ORDER);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007 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.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable;
-import android.net.Uri;
-import android.provider.Calendar.Calendars;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CursorAdapter;
-import android.widget.TextView;
-
-public class SelectCalendarsAdapter extends CursorAdapter {
-
- private static final int CLEAR_ALPHA_MASK = 0x00FFFFFF;
- private static final int HIGH_ALPHA = 255 << 24;
- private static final int MED_ALPHA = 180 << 24;
- private static final int LOW_ALPHA = 150 << 24;
-
- /* The corner should be rounded on the top right and bottom right */
- private static final float[] CORNERS = new float[] {0, 0, 5, 5, 5, 5, 0, 0};
-
- private static final String TAG = "Calendar";
-
- private final LayoutInflater mInflater;
- private final ContentResolver mResolver;
- private final ContentValues mValues = new ContentValues();
-
- private class CheckBoxListener implements CheckBox.OnCheckedChangeListener {
- private final long mCalendarId;
-
- private CheckBoxListener(long calendarId) {
- mCalendarId = calendarId;
- }
-
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- Uri uri = ContentUris.withAppendedId(Calendars.CONTENT_URI, mCalendarId);
- mValues.clear();
- int checked = isChecked ? 1 : 0;
- mValues.put(Calendars.SELECTED, checked);
- mResolver.update(uri, mValues, null, null);
- }
- }
-
- public SelectCalendarsAdapter(Context context, Cursor cursor) {
- super(context, cursor);
- mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mResolver = context.getContentResolver();
- }
-
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.calendar_item, parent, false);
- }
-
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- int idColumn = cursor.getColumnIndexOrThrow(Calendars._ID);
- int nameColumn = cursor.getColumnIndexOrThrow(Calendars.DISPLAY_NAME);
- int selectedColumn = cursor.getColumnIndexOrThrow(Calendars.SELECTED);
- int colorColumn = cursor.getColumnIndexOrThrow(Calendars.COLOR);
- view.findViewById(R.id.color).setBackgroundDrawable(getColorChip(cursor.getInt(colorColumn)));
- setText(view, R.id.calendar, cursor.getString(nameColumn));
- CheckBox box = (CheckBox) view.findViewById(R.id.checkbox);
- long id = cursor.getLong(idColumn);
- boolean checked = cursor.getInt(selectedColumn) != 0;
- box.setOnCheckedChangeListener(null);
- box.setChecked(checked);
- box.setOnCheckedChangeListener(new CheckBoxListener(id));
- }
-
- private static void setText(View view, int id, String text) {
- if (TextUtils.isEmpty(text)) {
- return;
- }
- TextView textView = (TextView) view.findViewById(id);
- textView.setText(text);
- }
-
- private Drawable getColorChip(int color) {
-
- /*
- * We want the color chip to have a nice gradient using
- * the color of the calendar. To do this we use a GradientDrawable.
- * The color supplied has an alpha of FF so we first do:
- * color & 0x00FFFFFF
- * to clear the alpha. Then we add our alpha to it.
- * We use 3 colors to get a step effect where it starts off very
- * light and quickly becomes dark and then a slow transition to
- * be even darker.
- */
- color &= CLEAR_ALPHA_MASK;
- int startColor = color | HIGH_ALPHA;
- int middleColor = color | MED_ALPHA;
- int endColor = color | LOW_ALPHA;
- int[] colors = new int[] {startColor, middleColor, endColor};
- GradientDrawable d = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, colors);
- d.setCornerRadii(CORNERS);
- return d;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2006 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 static android.provider.Calendar.EVENT_BEGIN_TIME;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.text.format.Time;
-import android.view.animation.AlphaAnimation;
-import android.widget.ViewFlipper;
-
-public class Utils {
- public static void startActivity(Context context, String className, long time) {
- Intent intent = new Intent(Intent.ACTION_VIEW);
-
- intent.setClassName(context, className);
- intent.putExtra(EVENT_BEGIN_TIME, time);
-
- context.startActivity(intent);
- }
-
- public static final Time timeFromIntent(Intent intent) {
- Time time = new Time();
- time.set(timeFromIntentInMillis(intent));
- return time;
- }
-
- /**
- * If the given intent specifies a time (in milliseconds since the epoch),
- * then that time is returned. Otherwise, the current time is returned.
- */
- public static final long timeFromIntentInMillis(Intent intent) {
- // If the time was specified, then use that. Otherwise, use the current time.
- long millis = intent.getLongExtra(EVENT_BEGIN_TIME, -1);
- if (millis == -1) {
- millis = System.currentTimeMillis();
- }
- return millis;
- }
-
- public static final void applyAlphaAnimation(ViewFlipper v) {
- AlphaAnimation in = new AlphaAnimation(0.0f, 1.0f);
-
- in.setStartOffset(0);
- in.setDuration(500);
-
- AlphaAnimation out = new AlphaAnimation(1.0f, 0.0f);
-
- out.setStartOffset(0);
- out.setDuration(500);
-
- v.setInAnimation(in);
- v.setOutAnimation(out);
- }
-
- /**
- * Formats the given Time object so that it gives the month and year
- * (for example, "September 2007").
- *
- * @param time the time to format
- * @return the string containing the weekday and the date
- */
- public static String formatMonthYear(Time time) {
- Resources res = Resources.getSystem();
- return time.format(res.getString(com.android.internal.R.string.month_year));
- }
-
- // TODO: replace this with the correct i18n way to do this
- public static final String englishNthDay[] = {
- "", "1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th",
- "10th", "11th", "12th", "13th", "14th", "15th", "16th", "17th", "18th", "19th",
- "20th", "21st", "22nd", "23rd", "24th", "25th", "26th", "27th", "28th", "29th",
- "30th", "31st"
- };
-
- public static String formatNth(int nth) {
- return "the " + englishNthDay[nth];
- }
-
- /**
- * Sets the time to the beginning of the day (midnight) by clearing the
- * hour, minute, and second fields.
- */
- static void setTimeToStartOfDay(Time time) {
- time.second = 0;
- time.minute = 0;
- time.hour = 0;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2006 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.SharedPreferences;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.ProgressBar;
-import android.widget.ViewSwitcher;
-
-public class WeekActivity extends CalendarActivity implements ViewSwitcher.ViewFactory {
- /**
- * The view id used for all the views we create. It's OK to have all child
- * views have the same ID. This ID is used to pick which view receives
- * focus when a view hierarchy is saved / restore
- */
- private static final int VIEW_ID = 1;
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- setContentView(R.layout.week_activity);
-
- mSelectedDay = Utils.timeFromIntent(getIntent());
- mViewSwitcher = (ViewSwitcher) findViewById(R.id.switcher);
- mViewSwitcher.setFactory(this);
- mViewSwitcher.getCurrentView().requestFocus();
- mProgressBar = (ProgressBar) findViewById(R.id.progress_circular);
- }
-
- public View makeView() {
- WeekView wv = new WeekView(this);
- wv.setId(VIEW_ID);
- wv.setLayoutParams(new ViewSwitcher.LayoutParams(
- LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
- wv.setSelectedDay(mSelectedDay);
- return wv;
- }
-
- @Override
- protected void onResume() {
- super.onResume();
-
- CalendarView view1 = (CalendarView) mViewSwitcher.getCurrentView();
- CalendarView view2 = (CalendarView) mViewSwitcher.getNextView();
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
-
- String str = prefs.getString(CalendarPreferenceActivity.KEY_DETAILED_VIEW,
- CalendarPreferenceActivity.DEFAULT_DETAILED_VIEW);
- view1.setDetailedView(str);
- view2.setDetailedView(str);
-
- // Record Week View as the (new) start view
- String activityString = CalendarApplication.ACTIVITY_NAMES[CalendarApplication.WEEK_VIEW_ID];
- SharedPreferences.Editor editor = prefs.edit();
- editor.putString(CalendarPreferenceActivity.KEY_START_VIEW, activityString);
- editor.commit();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- CalendarView view = (CalendarView) mViewSwitcher.getCurrentView();
- mSelectedDay = view.getSelectedDay();
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2006 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;
-
-
-public class WeekView extends CalendarView {
- private static final int CELL_MARGIN = 0;
-
- public WeekView(CalendarActivity activity) {
- super(activity);
- init();
- }
-
- private void init() {
- mDrawTextInEventRect = false;
- mNumDays = 7;
- mEventGeometry.setCellMargin(CELL_MARGIN);
- }
-}
+++ /dev/null
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-# Include all test java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CalendarTests
-
-LOCAL_INSTRUMENTATION_FOR := Calendar
-
-include $(BUILD_PACKAGE)
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.calendar.tests">
-
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <!--
- The test delcared in this instrumentation will be run along with tests declared by
- all other applications via the command: "adb shell itr".
- The "itr" command will find all tests declared by all applications. If you want to run just these
- tests on their own then use the command:
- "adb shell am instrument -w com.android.calendar.tests/android.test.InstrumentationTestRunner"
- -->
- <instrumentation android:name="android.test.InstrumentationTestRunner"
- android:targetPackage="com.android.calendar"
- android:label="calendar tests"/>
-
- <instrumentation android:name="CalendarLaunchPerformance"
- android:targetPackage="com.android.calendar"
- android:label="Calendar Launch Performance">
- </instrumentation>
-
-</manifest>
+++ /dev/null
-/*
- * Copyright (C) 2007 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.tests;
-
-import android.app.Activity;
-import android.test.LaunchPerformanceBase;
-import android.os.Bundle;
-
-import java.util.Map;
-
-/**
- * Instrumentation class for Browser launch performance testing.
- */
-public class CalendarLaunchPerformance extends LaunchPerformanceBase {
-
- public static final String LOG_TAG = "CalendarLaunchPerformance";
-
- public CalendarLaunchPerformance() {
- super();
- }
-
- @Override
- public void onCreate(Bundle arguments) {
- super.onCreate(arguments);
-
- mIntent.setClassName(getTargetContext(), "com.android.calendar.LaunchActivity");
- start();
- }
-
- /**
- * Calls LaunchApp and finish.
- */
- @Override
- public void onStart() {
- super.onStart();
- LaunchApp();
- finish(Activity.RESULT_OK, mResults);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007 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.test.TestBrowserActivity;
-import junit.framework.TestSuite;
-
-
-/**
- * Unit tests for com.android.calendar.
- */
-public class CalendarTests extends TestBrowserActivity {
-
- @Override
- public final TestSuite getTopTestSuite() {
- return suite();
- }
-
- public static TestSuite suite() {
- TestSuite suite = new TestSuite(CalendarTests.class.getName());
- suite.addTestSuite(FormatDateRangeTest.class);
- suite.addTestSuite(WeekNumberTest.class);
- return suite;
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007 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.res.Resources;
-import android.text.format.DateUtils;
-import android.text.format.Time;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.util.Log;
-
-
-/**
- * Unit tests for {@link android.text.format.DateUtils#formatDateRange}.
- */
-public class FormatDateRangeTest extends AndroidTestCase {
-
- private class DateRange {
- public Time date1;
- public Time date2;
- public int flags;
- public String expectedOutput;
-
- public DateRange(int year1, int month1, int day1, int hour1, int minute1,
- int year2, int month2, int day2, int hour2, int minute2,
- int flags, String output) {
- if ((flags & DateUtils.FORMAT_UTC) != 0) {
- date1 = new Time(Time.TIMEZONE_UTC);
- date2 = new Time(Time.TIMEZONE_UTC);
- } else {
- date1 = new Time();
- date2 = new Time();
- }
-
- // If the year is zero, then set it to the current year.
- if (year1 == 0 && year2 == 0) {
- date1.set(System.currentTimeMillis());
- year1 = year2 = date1.year;
- }
-
- date1.set(0, minute1, hour1, day1, month1, year1);
- date1.normalize(true /* ignore isDst */);
-
- date2.set(0, minute2, hour2, day2, month2, year2);
- date2.normalize(true /* ignore isDst */);
-
- this.flags = flags;
- expectedOutput = output;
- }
- }
-
- private Resources mResources;
-
- DateRange[] tests = {
- new DateRange(0, 10, 9, 8, 0, 0, 10, 9, 11, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL, "8am \u2013 11am"),
- new DateRange(0, 10, 9, 8, 0, 0, 10, 9, 11, 0,
- DateUtils.FORMAT_SHOW_TIME, "8:00am \u2013 11:00am"),
- new DateRange(0, 10, 9, 8, 0, 0, 10, 9, 17, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_24HOUR, "08:00 \u2013 17:00"),
- new DateRange(0, 10, 9, 8, 0, 0, 10, 9, 12, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL, "8am \u2013 noon"),
- new DateRange(0, 10, 9, 8, 0, 0, 10, 9, 12, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_NO_NOON | DateUtils.FORMAT_ABBREV_ALL,
- "8am \u2013 12pm"),
- new DateRange(0, 10, 9, 8, 0, 0, 10, 9, 12, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_CAP_NOON | DateUtils.FORMAT_ABBREV_ALL,
- "8am \u2013 Noon"),
- new DateRange(0, 10, 9, 10, 30, 0, 10, 9, 13, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL, "10:30am \u2013 1pm"),
- new DateRange(0, 10, 9, 13, 0, 0, 10, 9, 14, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL, "1pm \u2013 2pm"),
- new DateRange(0, 10, 9, 0, 0, 0, 10, 9, 14, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL, "12am \u2013 2pm"),
- new DateRange(0, 10, 9, 20, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL, "8pm \u2013 midnight"),
- new DateRange(0, 10, 10, 0, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL, "12am"),
- new DateRange(0, 10, 9, 20, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_24HOUR | DateUtils.FORMAT_ABBREV_ALL,
- "20:00 \u2013 00:00"),
- new DateRange(0, 10, 10, 0, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_24HOUR | DateUtils.FORMAT_ABBREV_ALL,
- "00:00"),
- new DateRange(0, 10, 9, 20, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL, "Nov 9"),
- new DateRange(0, 10, 10, 0, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL, "Nov 10"),
- new DateRange(0, 10, 9, 20, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_24HOUR | DateUtils.FORMAT_ABBREV_ALL,
- "Nov 9"),
- new DateRange(0, 10, 10, 0, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_24HOUR | DateUtils.FORMAT_ABBREV_ALL,
- "Nov 10"),
- new DateRange(0, 10, 9, 20, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_NO_MIDNIGHT | DateUtils.FORMAT_ABBREV_ALL,
- "8pm \u2013 12am"),
- new DateRange(0, 10, 9, 20, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_CAP_MIDNIGHT | DateUtils.FORMAT_ABBREV_ALL,
- "8pm \u2013 Midnight"),
- new DateRange(0, 10, 9, 0, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL, "12am \u2013 midnight"),
- new DateRange(0, 10, 9, 0, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_24HOUR | DateUtils.FORMAT_ABBREV_ALL,
- "00:00 \u2013 00:00"),
- new DateRange(0, 10, 9, 0, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_UTC | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL, "Nov 9"),
- new DateRange(0, 10, 9, 0, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_UTC | DateUtils.FORMAT_ABBREV_ALL, "Nov 9"),
- new DateRange(0, 10, 9, 0, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_UTC, "November 9"),
- new DateRange(0, 10, 8, 0, 0, 0, 10, 10, 0, 0,
- DateUtils.FORMAT_UTC | DateUtils.FORMAT_ABBREV_ALL, "Nov 8 \u2013 9"),
- new DateRange(0, 10, 9, 0, 0, 0, 10, 11, 0, 0,
- DateUtils.FORMAT_UTC | DateUtils.FORMAT_ABBREV_ALL, "Nov 9 \u2013 10"),
- new DateRange(0, 10, 9, 8, 0, 0, 10, 11, 17, 0,
- DateUtils.FORMAT_UTC | DateUtils.FORMAT_ABBREV_ALL, "Nov 9 \u2013 11"),
- new DateRange(0, 9, 29, 8, 0, 0, 10, 3, 17, 0,
- DateUtils.FORMAT_UTC | DateUtils.FORMAT_ABBREV_ALL, "Oct 29 \u2013 Nov 3"),
- new DateRange(2007, 11, 29, 8, 0, 2008, 0, 2, 17, 0,
- DateUtils.FORMAT_UTC | DateUtils.FORMAT_ABBREV_ALL, "Dec 29, 2007 \u2013 Jan 2, 2008"),
- new DateRange(2007, 11, 29, 0, 0, 2008, 0, 2, 0, 0,
- DateUtils.FORMAT_UTC | DateUtils.FORMAT_ABBREV_ALL, "Dec 29, 2007 \u2013 Jan 1, 2008"),
- new DateRange(2007, 11, 29, 8, 0, 2008, 0, 2, 17, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL,
- "Dec 29, 2007, 8am \u2013 Jan 2, 2008, 5pm"),
- new DateRange(0, 10, 9, 8, 0, 0, 10, 11, 17, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL,
- "Nov 9, 8am \u2013 Nov 11, 5pm"),
- new DateRange(2007, 10, 9, 8, 0, 2007, 10, 11, 17, 0,
- DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_ALL,
- "Fri, Nov 9, 2007 \u2013 Sun, Nov 11, 2007"),
- new DateRange(2007, 10, 9, 8, 0, 2007, 10, 11, 17, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_ALL,
- "Fri, Nov 9, 2007, 8am \u2013 Sun, Nov 11, 2007, 5pm"),
- new DateRange(2007, 11, 3, 13, 0, 2007, 11, 3, 14, 0,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR,
- "1:00pm \u2013 2:00pm, December 3, 2007"),
- };
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- mResources = mContext.getResources();
- }
-
- @MediumTest
- public void testAll() throws Exception {
- int len = tests.length;
- for (int index = 0; index < len; index++) {
- DateRange dateRange = tests[index];
- long startMillis = dateRange.date1.toMillis(false /* use isDst */);
- long endMillis = dateRange.date2.toMillis(false /* use isDst */);
- int flags = dateRange.flags;
- String output = DateUtils.formatDateRange(mContext, startMillis, endMillis, flags);
- if (!dateRange.expectedOutput.equals(output)) {
- Log.i("FormatDateRangeTest", "index " + index
- + " expected: " + dateRange.expectedOutput
- + " actual: " + output);
- }
- assertEquals(dateRange.expectedOutput, output);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2007 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.res.Resources;
-import android.text.format.DateUtils;
-import android.text.format.Time;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-
-
-/**
- * Unit tests for {@link android.text.format.Time#getWeekNumber}.
- */
-public class WeekNumberTest extends AndroidTestCase {
-
- private class DateAndWeekNumber {
- public Time date;
- public Time allDayDate;
- public int expectedWeekNumber;
-
- public DateAndWeekNumber(int year, int month, int day, int expectedWeekNumber) {
- date = new Time();
- allDayDate = new Time(Time.TIMEZONE_UTC);
-
- date.set(0, 0, 0, day, month, year);
- date.normalize(true /* ignore isDst */);
-
- allDayDate.set(day, month, year);
- allDayDate.normalize(true /* ignore isDst */);
-
- this.expectedWeekNumber = expectedWeekNumber;
- }
- }
-
- DateAndWeekNumber[] tests = {
- new DateAndWeekNumber(1998, 11, 28, 53),
- new DateAndWeekNumber(1998, 11, 29, 53),
- new DateAndWeekNumber(1998, 11, 30, 53),
- new DateAndWeekNumber(1998, 11, 31, 53),
- new DateAndWeekNumber(1999, 0, 1, 53),
- new DateAndWeekNumber(1999, 0, 2, 53),
- new DateAndWeekNumber(1999, 0, 3, 53),
- new DateAndWeekNumber(1999, 0, 4, 1),
- new DateAndWeekNumber(1999, 0, 10, 1),
- new DateAndWeekNumber(1999, 0, 20, 3),
- new DateAndWeekNumber(1999, 0, 30, 4),
-
- new DateAndWeekNumber(1999, 11, 28, 52),
- new DateAndWeekNumber(1999, 11, 29, 52),
- new DateAndWeekNumber(1999, 11, 30, 52),
- new DateAndWeekNumber(1999, 11, 31, 52),
- new DateAndWeekNumber(2000, 0, 1, 52),
- new DateAndWeekNumber(2000, 0, 2, 52),
- new DateAndWeekNumber(2000, 0, 3, 1),
- new DateAndWeekNumber(2000, 0, 4, 1),
- new DateAndWeekNumber(2000, 0, 10, 2),
- new DateAndWeekNumber(2000, 0, 20, 3),
- new DateAndWeekNumber(2000, 0, 30, 4),
-
- new DateAndWeekNumber(2000, 11, 28, 52),
- new DateAndWeekNumber(2000, 11, 29, 52),
- new DateAndWeekNumber(2000, 11, 30, 52),
- new DateAndWeekNumber(2000, 11, 31, 52),
- new DateAndWeekNumber(2001, 0, 1, 1),
- new DateAndWeekNumber(2001, 0, 2, 1),
- new DateAndWeekNumber(2001, 0, 3, 1),
- new DateAndWeekNumber(2001, 0, 4, 1),
- new DateAndWeekNumber(2001, 0, 10, 2),
- new DateAndWeekNumber(2001, 0, 20, 3),
- new DateAndWeekNumber(2001, 0, 30, 5),
-
- new DateAndWeekNumber(2001, 11, 28, 52),
- new DateAndWeekNumber(2001, 11, 29, 52),
- new DateAndWeekNumber(2001, 11, 30, 52),
- new DateAndWeekNumber(2001, 11, 31, 1),
- new DateAndWeekNumber(2002, 0, 1, 1),
- new DateAndWeekNumber(2002, 0, 2, 1),
- new DateAndWeekNumber(2002, 0, 3, 1),
- new DateAndWeekNumber(2002, 0, 4, 1),
- new DateAndWeekNumber(2002, 0, 10, 2),
- new DateAndWeekNumber(2002, 0, 20, 3),
- new DateAndWeekNumber(2002, 0, 30, 5),
-
- new DateAndWeekNumber(2002, 11, 28, 52),
- new DateAndWeekNumber(2002, 11, 29, 52),
- new DateAndWeekNumber(2002, 11, 30, 1),
- new DateAndWeekNumber(2002, 11, 31, 1),
- new DateAndWeekNumber(2003, 0, 1, 1),
- new DateAndWeekNumber(2003, 0, 2, 1),
- new DateAndWeekNumber(2003, 0, 3, 1),
- new DateAndWeekNumber(2003, 0, 4, 1),
- new DateAndWeekNumber(2003, 0, 10, 2),
- new DateAndWeekNumber(2003, 0, 20, 4),
- new DateAndWeekNumber(2003, 0, 30, 5),
-
- new DateAndWeekNumber(2003, 11, 28, 52),
- new DateAndWeekNumber(2003, 11, 29, 1),
- new DateAndWeekNumber(2003, 11, 30, 1),
- new DateAndWeekNumber(2003, 11, 31, 1),
- new DateAndWeekNumber(2004, 0, 1, 1),
- new DateAndWeekNumber(2004, 0, 2, 1),
- new DateAndWeekNumber(2004, 0, 3, 1),
- new DateAndWeekNumber(2004, 0, 4, 1),
- new DateAndWeekNumber(2004, 0, 10, 2),
- new DateAndWeekNumber(2004, 0, 20, 4),
- new DateAndWeekNumber(2004, 0, 30, 5),
-
- new DateAndWeekNumber(2004, 0, 1, 1),
- new DateAndWeekNumber(2004, 1, 1, 5),
- new DateAndWeekNumber(2004, 2, 1, 10),
- new DateAndWeekNumber(2004, 3, 1, 14),
- new DateAndWeekNumber(2004, 4, 1, 18),
- new DateAndWeekNumber(2004, 5, 1, 23),
- new DateAndWeekNumber(2004, 6, 1, 27),
- new DateAndWeekNumber(2004, 7, 1, 31),
- new DateAndWeekNumber(2004, 8, 1, 36),
- new DateAndWeekNumber(2004, 9, 1, 40),
- new DateAndWeekNumber(2004, 10, 1, 45),
- new DateAndWeekNumber(2004, 11, 1, 49),
-
- new DateAndWeekNumber(2004, 11, 28, 53),
- new DateAndWeekNumber(2004, 11, 29, 53),
- new DateAndWeekNumber(2004, 11, 30, 53),
- new DateAndWeekNumber(2004, 11, 31, 53),
- new DateAndWeekNumber(2005, 0, 1, 53),
- new DateAndWeekNumber(2005, 0, 2, 53),
- new DateAndWeekNumber(2005, 0, 3, 1),
- new DateAndWeekNumber(2005, 0, 4, 1),
- new DateAndWeekNumber(2005, 0, 10, 2),
- new DateAndWeekNumber(2005, 0, 20, 3),
- new DateAndWeekNumber(2005, 0, 30, 4),
-
- new DateAndWeekNumber(2005, 11, 28, 52),
- new DateAndWeekNumber(2005, 11, 29, 52),
- new DateAndWeekNumber(2005, 11, 30, 52),
- new DateAndWeekNumber(2005, 11, 31, 52),
- new DateAndWeekNumber(2006, 0, 1, 52),
- new DateAndWeekNumber(2006, 0, 2, 1),
- new DateAndWeekNumber(2006, 0, 3, 1),
- new DateAndWeekNumber(2006, 0, 4, 1),
- new DateAndWeekNumber(2006, 0, 10, 2),
- new DateAndWeekNumber(2006, 0, 20, 3),
- new DateAndWeekNumber(2006, 0, 30, 5),
-
- new DateAndWeekNumber(2006, 11, 28, 52),
- new DateAndWeekNumber(2006, 11, 29, 52),
- new DateAndWeekNumber(2006, 11, 30, 52),
- new DateAndWeekNumber(2006, 11, 31, 52),
- new DateAndWeekNumber(2007, 0, 1, 1),
- new DateAndWeekNumber(2007, 0, 2, 1),
- new DateAndWeekNumber(2007, 0, 3, 1),
- new DateAndWeekNumber(2007, 0, 4, 1),
- new DateAndWeekNumber(2007, 0, 10, 2),
- new DateAndWeekNumber(2007, 0, 20, 3),
- new DateAndWeekNumber(2007, 0, 30, 5),
-
- new DateAndWeekNumber(2007, 11, 28, 52),
- new DateAndWeekNumber(2007, 11, 29, 52),
- new DateAndWeekNumber(2007, 11, 30, 52),
- new DateAndWeekNumber(2007, 11, 31, 1),
- new DateAndWeekNumber(2008, 0, 1, 1),
- new DateAndWeekNumber(2008, 0, 2, 1),
- new DateAndWeekNumber(2008, 0, 3, 1),
- new DateAndWeekNumber(2008, 0, 4, 1),
- new DateAndWeekNumber(2008, 0, 10, 2),
- new DateAndWeekNumber(2008, 0, 20, 3),
- new DateAndWeekNumber(2008, 0, 30, 5),
-
- new DateAndWeekNumber(2008, 11, 28, 52),
- new DateAndWeekNumber(2008, 11, 29, 1),
- new DateAndWeekNumber(2008, 11, 30, 1),
- new DateAndWeekNumber(2008, 11, 31, 1),
- new DateAndWeekNumber(2009, 0, 1, 1),
- new DateAndWeekNumber(2009, 0, 2, 1),
- new DateAndWeekNumber(2009, 0, 3, 1),
- new DateAndWeekNumber(2009, 0, 4, 1),
- new DateAndWeekNumber(2009, 0, 10, 2),
- new DateAndWeekNumber(2009, 0, 20, 4),
- new DateAndWeekNumber(2009, 0, 30, 5),
- };
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @SmallTest
- public void testAll() throws Exception {
- int len = tests.length;
- for (int index = 0; index < len; index++) {
- DateAndWeekNumber test = tests[index];
- int weekNumber = test.date.getWeekNumber();
- if (weekNumber != test.expectedWeekNumber) {
- long millis = test.date.toMillis(false /* use isDst */);
- int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NUMERIC_DATE;
- String output = DateUtils.formatDateTime(mContext, millis, flags);
- Log.i("WeekNumberTest", "index " + index
- + " date: " + output
- + " expected: " + test.expectedWeekNumber
- + " actual: " + weekNumber);
- }
- assertEquals(weekNumber, test.expectedWeekNumber);
-
- weekNumber = test.allDayDate.getWeekNumber();
- if (weekNumber != test.expectedWeekNumber) {
- long millis = test.date.toMillis(false /* use isDst */);
- int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NUMERIC_DATE;
- String output = DateUtils.formatDateTime(mContext, millis, flags);
- Log.i("WeekNumberTest", "(all-day) index " + index
- + " date: " + output
- + " expected: " + test.expectedWeekNumber
- + " actual: " + weekNumber);
- }
- assertEquals(weekNumber, test.expectedWeekNumber);
- }
- }
-}