summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/drawable-hdpi/ic_colorpicker_swatch_selected.pngbin0 -> 2414 bytes
-rw-r--r--res/drawable-hdpi/ic_menu_colorpicker_holo_dark.pngbin0 -> 1419 bytes
-rw-r--r--res/drawable-hdpi/ic_menu_colorpicker_holo_light.pngbin0 -> 1556 bytes
-rw-r--r--res/drawable-mdpi/ic_colorpicker_swatch_selected.pngbin0 -> 1662 bytes
-rw-r--r--res/drawable-mdpi/ic_menu_colorpicker_holo_dark.pngbin0 -> 994 bytes
-rw-r--r--res/drawable-mdpi/ic_menu_colorpicker_holo_light.pngbin0 -> 1063 bytes
-rw-r--r--res/drawable-xhdpi/ic_colorpicker_swatch_selected.pngbin0 -> 3241 bytes
-rw-r--r--res/drawable-xhdpi/ic_menu_colorpicker_holo_dark.pngbin0 -> 1898 bytes
-rw-r--r--res/drawable-xhdpi/ic_menu_colorpicker_holo_light.pngbin0 -> 2078 bytes
-rw-r--r--res/drawable/color_picker_swatch.xml16
-rw-r--r--res/layout-sw600dp/edit_event_1.xml67
-rw-r--r--res/layout/color_picker_dialog.xml45
-rw-r--r--res/layout/edit_event_1.xml51
-rw-r--r--res/layout/event_info.xml92
-rw-r--r--res/layout/event_info_dialog.xml4
-rw-r--r--res/layout/event_info_headline.xml123
-rw-r--r--res/menu/event_info_title_bar.xml7
-rw-r--r--res/values/dimens.xml5
-rw-r--r--res/values/strings.xml7
-rw-r--r--res/values/styles.xml15
-rw-r--r--src/com/android/calendar/CalendarEventModel.java33
-rw-r--r--src/com/android/calendar/EventInfoActivity.java70
-rw-r--r--src/com/android/calendar/EventInfoFragment.java236
-rw-r--r--src/com/android/calendar/SearchActivity.java2
-rw-r--r--src/com/android/calendar/agenda/AgendaFragment.java3
-rw-r--r--src/com/android/calendar/color/ColorComparator.java61
-rw-r--r--src/com/android/calendar/color/ColorPickerDialog.java173
-rw-r--r--src/com/android/calendar/color/ColorPickerPalette.java144
-rw-r--r--src/com/android/calendar/color/ColorPickerSwatch.java91
-rw-r--r--src/com/android/calendar/event/EditEventFragment.java69
-rw-r--r--src/com/android/calendar/event/EditEventHelper.java44
-rw-r--r--src/com/android/calendar/event/EditEventView.java72
-rw-r--r--src/com/android/calendar/event/EventColorCache.java106
-rw-r--r--src/com/android/calendar/event/EventColorPickerDialog.java67
34 files changed, 1356 insertions, 247 deletions
diff --git a/res/drawable-hdpi/ic_colorpicker_swatch_selected.png b/res/drawable-hdpi/ic_colorpicker_swatch_selected.png
new file mode 100644
index 00000000..3cbfe1a8
--- /dev/null
+++ b/res/drawable-hdpi/ic_colorpicker_swatch_selected.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_colorpicker_holo_dark.png b/res/drawable-hdpi/ic_menu_colorpicker_holo_dark.png
new file mode 100644
index 00000000..df143ede
--- /dev/null
+++ b/res/drawable-hdpi/ic_menu_colorpicker_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_colorpicker_holo_light.png b/res/drawable-hdpi/ic_menu_colorpicker_holo_light.png
new file mode 100644
index 00000000..fc7a1a19
--- /dev/null
+++ b/res/drawable-hdpi/ic_menu_colorpicker_holo_light.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_colorpicker_swatch_selected.png b/res/drawable-mdpi/ic_colorpicker_swatch_selected.png
new file mode 100644
index 00000000..acbdecac
--- /dev/null
+++ b/res/drawable-mdpi/ic_colorpicker_swatch_selected.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_colorpicker_holo_dark.png b/res/drawable-mdpi/ic_menu_colorpicker_holo_dark.png
new file mode 100644
index 00000000..246488a4
--- /dev/null
+++ b/res/drawable-mdpi/ic_menu_colorpicker_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_colorpicker_holo_light.png b/res/drawable-mdpi/ic_menu_colorpicker_holo_light.png
new file mode 100644
index 00000000..6ad4fede
--- /dev/null
+++ b/res/drawable-mdpi/ic_menu_colorpicker_holo_light.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_colorpicker_swatch_selected.png b/res/drawable-xhdpi/ic_colorpicker_swatch_selected.png
new file mode 100644
index 00000000..812ff2c3
--- /dev/null
+++ b/res/drawable-xhdpi/ic_colorpicker_swatch_selected.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_colorpicker_holo_dark.png b/res/drawable-xhdpi/ic_menu_colorpicker_holo_dark.png
new file mode 100644
index 00000000..03a84a8c
--- /dev/null
+++ b/res/drawable-xhdpi/ic_menu_colorpicker_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_colorpicker_holo_light.png b/res/drawable-xhdpi/ic_menu_colorpicker_holo_light.png
new file mode 100644
index 00000000..1a0b2cd9
--- /dev/null
+++ b/res/drawable-xhdpi/ic_menu_colorpicker_holo_light.png
Binary files differ
diff --git a/res/drawable/color_picker_swatch.xml b/res/drawable/color_picker_swatch.xml
new file mode 100644
index 00000000..db71091a
--- /dev/null
+++ b/res/drawable/color_picker_swatch.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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="oval" /> \ No newline at end of file
diff --git a/res/layout-sw600dp/edit_event_1.xml b/res/layout-sw600dp/edit_event_1.xml
index f5935cc5..0c18282d 100644
--- a/res/layout-sw600dp/edit_event_1.xml
+++ b/res/layout-sw600dp/edit_event_1.xml
@@ -28,24 +28,28 @@
android:text="@string/edit_event_calendar_label"
style="@style/TextAppearance.EditEvent_Label"
android:gravity="center_vertical" />
- <FrameLayout
- android:id="@+id/calendar_selector_wrapper"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_marginRight="12dip"
- android:layout_marginLeft="12dip"
- android:focusable="true" >
- <Spinner
- android:id="@+id/calendars_spinner"
- android:prompt="@string/edit_event_calendar_label"
- android:layout_gravity="center_vertical"
- android:gravity="center_vertical"
- android:layout_height="wrap_content"
+ <LinearLayout
+ android:id="@+id/calendar_selector_wrapper"
android:layout_width="match_parent"
- android:layout_marginRight="0dip"
- android:layout_marginLeft="0dip"
- style="@style/TextAppearance.EditEvent_Spinner"/>
- </FrameLayout>
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="12dip"
+ android:layout_marginRight="12dip"
+ android:focusable="true" >
+ <Spinner
+ android:id="@+id/calendars_spinner"
+ style="@style/TextAppearance.EditEvent_Spinner"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_marginLeft="0dip"
+ android:layout_marginRight="0dip"
+ android:gravity="center_vertical"
+ android:prompt="@string/edit_event_calendar_label" />
+ <ImageButton
+ android:id="@+id/change_color_new_event"
+ style="@style/EditEventColorImageButton" />
+ </LinearLayout>
</TableRow>
<!-- CALENDAR DISPLAY for existing events -->
@@ -57,13 +61,28 @@
<TextView
android:text="@string/edit_event_calendar_label"
style="@style/TextAppearance.EditEvent_Label" />
- <TextView
- android:id="@+id/calendar_textview"
- android:textColor="#FFFFFFFF"
- android:minHeight="48dip"
- android:paddingLeft="12dip"
- android:paddingRight="12dip"
- style="@style/TextAppearance.EditEvent_Value" />
+ <LinearLayout
+ android:id="@+id/calendar_textview_with_colorpicker"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="12dip"
+ android:layout_marginRight="12dip" >
+ <TextView
+ android:id="@+id/calendar_textview"
+ style="@style/TextAppearance.EditEvent_Value"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:paddingLeft="12dip"
+ android:paddingRight="12dip"
+ android:layout_marginLeft="0dip"
+ android:layout_marginRight="0dip"
+ android:layout_height="wrap_content"
+ android:minHeight="48dip"
+ android:textColor="#FFFFFFFF" />
+ <ImageButton
+ android:id="@+id/change_color_existing_event"
+ style="@style/EditEventColorImageButton" />
+ </LinearLayout>
</TableRow>
<!-- WHAT -->
diff --git a/res/layout/color_picker_dialog.xml b/res/layout/color_picker_dialog.xml
new file mode 100644
index 00000000..44518c0f
--- /dev/null
+++ b/res/layout/color_picker_dialog.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:gravity="center" >
+
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:gravity="center"
+ android:padding="28dp" >
+
+ <ProgressBar
+ android:id="@android:id/progress"
+ style="?android:attr/progressBarStyleLarge"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:gravity="center" />
+
+ <com.android.calendar.color.ColorPickerPalette
+ android:id="@+id/color_picker"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:gravity="center"
+ android:visibility="gone" />
+ </FrameLayout>
+</ScrollView> \ No newline at end of file
diff --git a/res/layout/edit_event_1.xml b/res/layout/edit_event_1.xml
index 7242a384..46aaf525 100644
--- a/res/layout/edit_event_1.xml
+++ b/res/layout/edit_event_1.xml
@@ -22,7 +22,7 @@
<!-- CALENDARS SELECTOR for new events -->
<LinearLayout
android:id="@+id/calendar_selector_group"
- android:orientation="vertical"
+ android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true" >
@@ -30,41 +30,54 @@
android:id="@+id/calendars_spinner"
android:prompt="@string/edit_event_calendar_label"
android:layout_height="wrap_content"
- android:layout_width="match_parent"
+ android:layout_width="0dip"
+ android:layout_weight="1"
android:layout_gravity="center_vertical"
android:paddingBottom="10dip"
android:paddingTop="10dip"
android:layout_marginLeft="12dip"
android:layout_marginRight="12dip"
android:gravity="center_vertical" />
+ <ImageButton
+ android:id="@+id/change_color_new_event"
+ style="@style/EditEventColorImageButton" />
</LinearLayout>
<!-- CALENDAR DISPLAY for existing events -->
<LinearLayout
android:id="@+id/calendar_group"
- android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="5dip"
android:paddingTop="5dip"
android:focusable="true">
- <TextView
- android:id="@+id/calendar_textview"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:textColor="#FFFFFFFF"
- android:layout_marginLeft="24dip"
- android:layout_marginRight="24dip"
- style="@style/TextAppearance.EditEvent_Value" />
- <TextView
- android:id="@+id/calendar_textview_secondary"
+ <LinearLayout
+ android:layout_width="0dip"
+ android:layout_weight="1"
android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:textColor="#FFFFFFFF"
- android:layout_marginLeft="24dip"
- android:layout_marginRight="24dip"
- android:textSize="14sp"
- style="@style/TextAppearance.EditEvent_Value" />
+ android:focusable="true"
+ android:orientation="vertical" >
+ <TextView
+ android:id="@+id/calendar_textview"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:textColor="#FFFFFFFF"
+ android:layout_marginLeft="24dip"
+ android:layout_marginRight="24dip"
+ style="@style/TextAppearance.EditEvent_Value" />
+ <TextView
+ android:id="@+id/calendar_textview_secondary"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:textColor="#FFFFFFFF"
+ android:layout_marginLeft="24dip"
+ android:layout_marginRight="24dip"
+ android:textSize="14sp"
+ style="@style/TextAppearance.EditEvent_Value" />
+ </LinearLayout>
+ <ImageButton
+ android:id="@+id/change_color_existing_event"
+ style="@style/EditEventColorImageButton" />
</LinearLayout>
<!-- WHAT -->
diff --git a/res/layout/event_info.xml b/res/layout/event_info.xml
index eb297fbf..8b8b5539 100644
--- a/res/layout/event_info.xml
+++ b/res/layout/event_info.xml
@@ -46,7 +46,7 @@
android:animateLayoutChanges="true"
android:layout_height="match_parent">
- <LinearLayout
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
@@ -54,95 +54,7 @@
<!-- Container for the event's headline
Name, Date, Time & Location
-->
- <LinearLayout
- android:id="@+id/event_info_headline"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="16dip"
- android:paddingRight="16dip"
- android:paddingTop="8dip"
- android:paddingBottom="16dip"
- android:layout_weight="1"
- android:orientation="vertical">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <!-- WHAT -->
- <TextView
- android:id="@+id/title"
- android:layout_weight=".8"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:autoLink="all"
- android:textIsSelectable="true"
- android:textStyle="bold"
- android:textColor="@color/event_info_headline_color"
- android:textColorLink="@color/event_info_headline_color"
- style="?android:attr/textAppearanceLarge"
- android:textSize="24sp" />
- <!-- BUTTONS -->
- <LinearLayout
- android:id="@+id/event_info_buttons_container"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="right">
- <Button
- android:id="@+id/edit"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:enabled="false"
- style="?android:attr/buttonBarButtonStyle"
- android:textColor="@color/event_info_headline_color"
- android:text="@string/edit_event_label" />
- <Button
- android:id="@+id/delete"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- style="?android:attr/buttonBarButtonStyle"
- android:textColor="@color/event_info_headline_color"
- android:text="@string/delete_label" />
- </LinearLayout>
- </LinearLayout>
-
- <!-- WHEN -->
- <TextView
- android:id="@+id/when_datetime"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="4dip"
- android:textIsSelectable="true"
- android:textSize="14sp"
- android:textColor="@color/event_info_headline_color"
- style="?android:attr/textAppearanceLarge" />
-
- <TextView
- android:id="@+id/when_repeat"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="-3dip"
- android:textSize="14sp"
- android:textColor="@color/event_info_headline_transparent_color"
- style="?android:attr/textAppearanceLarge" />
-
- <!-- WHERE -->
- <TextView
- android:id="@+id/where"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:ellipsize="end"
- android:singleLine="false"
- android:layout_marginTop="4dip"
- android:textIsSelectable="true"
- android:textSize="14sp"
- android:textColor="@color/event_info_headline_color"
- android:textColorLink="@color/event_info_headline_link_color"
- style="?android:attr/textAppearanceLarge" />
- </LinearLayout>
+ <include layout="@layout/event_info_headline" />
<LinearLayout
android:layout_width="match_parent"
diff --git a/res/layout/event_info_dialog.xml b/res/layout/event_info_dialog.xml
index e51b7f24..ff4d1c57 100644
--- a/res/layout/event_info_dialog.xml
+++ b/res/layout/event_info_dialog.xml
@@ -94,6 +94,10 @@
android:layout_marginRight="16dip"
android:layout_gravity="right">
<ImageButton
+ android:id="@+id/change_color"
+ style="@style/EditEventColorImageButton"
+ android:visibility="gone" />
+ <ImageButton
android:id="@+id/edit"
android:contentDescription="@string/edit_label"
android:layout_width="48dip"
diff --git a/res/layout/event_info_headline.xml b/res/layout/event_info_headline.xml
new file mode 100644
index 00000000..26f97b6f
--- /dev/null
+++ b/res/layout/event_info_headline.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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/event_info_headline"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:paddingBottom="16dip"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:paddingTop="8dip" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal" >
+
+ <!-- WHAT -->
+ <TextView
+ android:id="@+id/title"
+ style="?android:attr/textAppearanceLarge"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight=".8"
+ android:autoLink="all"
+ android:textColor="@color/event_info_headline_color"
+ android:textColorLink="@color/event_info_headline_color"
+ android:textIsSelectable="true"
+ android:textSize="24sp"
+ android:textStyle="bold" />
+ <!-- BUTTONS -->
+
+ <LinearLayout
+ android:id="@+id/event_info_buttons_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="right"
+ android:orientation="horizontal" >
+
+ <Button
+ android:id="@+id/change_color"
+ style="?android:attr/buttonBarButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:enabled="false"
+ android:text="@string/choose_event_color_label"
+ android:textColor="@color/event_info_headline_color" />
+
+ <Button
+ android:id="@+id/edit"
+ style="?android:attr/buttonBarButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:enabled="false"
+ android:text="@string/edit_event_label"
+ android:textColor="@color/event_info_headline_color" />
+
+ <Button
+ android:id="@+id/delete"
+ style="?android:attr/buttonBarButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/delete_label"
+ android:textColor="@color/event_info_headline_color" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <!-- WHEN -->
+
+ <TextView
+ android:id="@+id/when_datetime"
+ style="?android:attr/textAppearanceLarge"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="4dip"
+ android:textColor="@color/event_info_headline_color"
+ android:textIsSelectable="true"
+ android:textSize="14sp" />
+
+ <TextView
+ android:id="@+id/when_repeat"
+ style="?android:attr/textAppearanceLarge"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="-3dip"
+ android:textColor="@color/event_info_headline_transparent_color"
+ android:textSize="14sp" />
+
+ <!-- WHERE -->
+
+ <TextView
+ android:id="@+id/where"
+ style="?android:attr/textAppearanceLarge"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="4dip"
+ android:ellipsize="end"
+ android:singleLine="false"
+ android:textColor="@color/event_info_headline_color"
+ android:textColorLink="@color/event_info_headline_link_color"
+ android:textIsSelectable="true"
+ android:textSize="14sp" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/menu/event_info_title_bar.xml b/res/menu/event_info_title_bar.xml
index d2a3eec8..b3a6d074 100644
--- a/res/menu/event_info_title_bar.xml
+++ b/res/menu/event_info_title_bar.xml
@@ -16,6 +16,13 @@
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id='@+id/info_action_change_color'
+ android:alphabeticShortcut="c"
+ android:title="@string/choose_event_color_label"
+ android:icon="@drawable/ic_menu_colorpicker_holo_light"
+ android:showAsAction="withText|always"
+ android:enabled="false"
+ android:visible="false" />
<item android:id="@+id/info_action_edit"
android:alphabeticShortcut="e"
android:title="@string/edit_label"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index d2caea0f..f0b57ee0 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -52,4 +52,9 @@
<dimen name="calendar_controls_height">300dip</dimen>
<dimen name="agenda_item_right_margin">4dip</dimen>
<dimen name="today_icon_text_size">14sp</dimen>
+
+ <dimen name="color_swatch_large">64dip</dimen>
+ <dimen name="color_swatch_small">48dip</dimen>
+ <dimen name="color_swatch_margins_large">8dip</dimen>
+ <dimen name="color_swatch_margins_small">4dip</dimen>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index aee89b91..a4ead66a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -278,6 +278,13 @@
<string name="view_event_organizer_label">Organizer:</string>
<!-- Label for the local timezone -->
+ <!-- Label for showing event color picker -->
+ <string name="choose_event_color_label">Choose event color</string>
+ <!-- Title for event color picker dialog -->
+ <string name="event_color_picker_dialog_title">Event Color</string>
+ <!-- Label for button which sets event color to default calendar color -->
+ <string name="event_color_set_to_default">Set to default calendar color</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'). -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 4545a15f..0a3fd966 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -17,7 +17,7 @@
** limitations under the License.
*/
-->
-<resources>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
@@ -224,6 +224,19 @@
<item name="android:ellipsize">none</item>
<item name="android:padding">4dp</item>
</style>
+
+ <style name="EditEventColorImageButton" parent="android:attr/buttonBarButtonStyle">
+ <item name="android:enabled">false</item>
+ <item name="android:layout_width">48dip</item>
+ <item name="android:layout_height">48dip</item>
+ <item name="android:layout_marginRight">8dip</item>
+ <item name="android:layout_gravity">center_vertical</item>
+ <item name="android:contentDescription">@string/choose_event_color_label</item>
+ <item name="android:padding">8dip</item>
+ <item name="android:scaleType">centerInside</item>
+ <item name="android:background">@android:color/transparent</item>
+ <item name="android:src">@drawable/ic_menu_colorpicker_holo_dark</item>
+ </style>
<style name="WidgetDayOfWeekStyle">
<item name="android:layout_width">wrap_content</item>
diff --git a/src/com/android/calendar/CalendarEventModel.java b/src/com/android/calendar/CalendarEventModel.java
index 6da72806..44c66bf0 100644
--- a/src/com/android/calendar/CalendarEventModel.java
+++ b/src/com/android/calendar/CalendarEventModel.java
@@ -16,9 +16,6 @@
package com.android.calendar;
-import com.android.calendar.event.EditEventHelper;
-import com.android.common.Rfc822Validator;
-
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -29,6 +26,10 @@ import android.provider.CalendarContract.Reminders;
import android.text.TextUtils;
import android.text.util.Rfc822Token;
+import com.android.calendar.event.EditEventHelper;
+import com.android.calendar.event.EventColorCache;
+import com.android.common.Rfc822Validator;
+
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
@@ -201,6 +202,8 @@ public class CalendarEventModel implements Serializable {
public long mCalendarId = -1;
public String mCalendarDisplayName = ""; // Make sure this is in sync with the mCalendarId
public int mCalendarColor = 0;
+ public String mCalendarAccountName;
+ public String mCalendarAccountType;
public int mCalendarMaxReminders;
public String mCalendarAllowedReminders;
public String mCalendarAllowedAttendeeTypes;
@@ -210,6 +213,9 @@ public class CalendarEventModel implements Serializable {
public String mSyncAccount = null;
public String mSyncAccountType = null;
+ public EventColorCache mEventColorCache;
+ public int mEventColor = -1;
+
// PROVIDER_NOTES owner account comes from the calendars table
public String mOwnerAccount = null;
public String mTitle = null;
@@ -843,6 +849,11 @@ public class CalendarEventModel implements Serializable {
if (mEventStatus != originalModel.mEventStatus) {
return false;
}
+
+ if (mEventColor != originalModel.mEventColor) {
+ return false;
+ }
+
return true;
}
@@ -872,4 +883,20 @@ public class CalendarEventModel implements Serializable {
return true;
}
+
+ public int[] getCalendarEventColors() {
+ if (mEventColorCache != null) {
+ return mEventColorCache.getColorArray(mCalendarAccountName, mCalendarAccountType);
+ }
+ return null;
+ }
+
+ public int getEventColorKey() {
+ if (mEventColorCache != null) {
+ return mEventColorCache.getColorKey(mCalendarAccountName, mCalendarAccountType,
+ mEventColor);
+ }
+ return -1;
+ }
+
}
diff --git a/src/com/android/calendar/EventInfoActivity.java b/src/com/android/calendar/EventInfoActivity.java
index 2b4c8a13..a0a126f6 100644
--- a/src/com/android/calendar/EventInfoActivity.java
+++ b/src/com/android/calendar/EventInfoActivity.java
@@ -25,8 +25,11 @@ import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
+import android.provider.CalendarContract;
import android.provider.CalendarContract.Attendees;
import android.util.Log;
import android.widget.Toast;
@@ -42,6 +45,23 @@ public class EventInfoActivity extends Activity {
private long mStartMillis, mEndMillis;
private long mEventId;
+ // Create an observer so that we can update the views whenever a
+ // Calendar event changes.
+ private final ContentObserver mObserver = new ContentObserver(new Handler()) {
+ @Override
+ public boolean deliverSelfNotifications() {
+ return false;
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ if (selfChange) return;
+ if (mInfoFragment != null) {
+ mInfoFragment.reloadEvents();
+ }
+ }
+ };
+
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -135,53 +155,6 @@ public class EventInfoActivity extends Activity {
}
}
-// @Override
-// public boolean onOptionsItemSelected(MenuItem item) {
-//
-// // Handles option menu selections:
-// // Home button - close event info activity and start the main calendar one
-// // Edit button - start the event edit activity and close the info activity
-// // Delete button - start a delete query that calls a runnable that close the info activity
-//
-// switch (item.getItemId()) {
-// case android.R.id.home:
-// Intent launchIntent = new Intent();
-// launchIntent.setAction(Intent.ACTION_VIEW);
-// launchIntent.setData(Uri.parse(CalendarContract.CONTENT_URI + "/time"));
-// launchIntent.setFlags(
-// Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-// startActivity(launchIntent);
-// finish();
-// return true;
-// case R.id.info_action_edit:
-// Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventId);
-// Intent intent = new Intent(Intent.ACTION_EDIT, uri);
-// intent.putExtra(EXTRA_EVENT_BEGIN_TIME, mStartMillis);
-// intent.putExtra(EXTRA_EVENT_END_TIME, mEndMillis);
-// intent.setClass(this, EditEventActivity.class);
-// intent.putExtra(EVENT_EDIT_ON_LAUNCH, true);
-// startActivity(intent);
-// finish ();
-// break;
-// case R.id.info_action_delete:
-// DeleteEventHelper deleteHelper = new DeleteEventHelper(
-// this, this, true /* exitWhenDone */);
-// deleteHelper.delete(mStartMillis, mEndMillis, mEventId, -1, onDeleteRunnable);
-// break;
-// default:
-// break;
-// }
-// return super.onOptionsItemSelected(item);
-// }
-
- // runs at the end of a delete action and closes the activity
-// private Runnable onDeleteRunnable = new Runnable() {
-// @Override
-// public void run() {
-// finish ();
-// }
-// };
-
@Override
protected void onNewIntent(Intent intent) {
// From the Android Dev Guide: "It's important to note that when
@@ -202,11 +175,14 @@ public class EventInfoActivity extends Activity {
@Override
protected void onResume() {
super.onResume();
+ getContentResolver().registerContentObserver(CalendarContract.Events.CONTENT_URI,
+ true, mObserver);
}
@Override
protected void onPause() {
super.onPause();
+ getContentResolver().unregisterContentObserver(mObserver);
}
@Override
diff --git a/src/com/android/calendar/EventInfoFragment.java b/src/com/android/calendar/EventInfoFragment.java
index 05ef6e0d..a8d27f81 100644
--- a/src/com/android/calendar/EventInfoFragment.java
+++ b/src/com/android/calendar/EventInfoFragment.java
@@ -42,6 +42,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.database.Cursor;
+import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
@@ -49,6 +50,7 @@ import android.os.Bundle;
import android.provider.CalendarContract;
import android.provider.CalendarContract.Attendees;
import android.provider.CalendarContract.Calendars;
+import android.provider.CalendarContract.Colors;
import android.provider.CalendarContract.Events;
import android.provider.CalendarContract.Reminders;
import android.provider.ContactsContract;
@@ -64,6 +66,7 @@ import android.text.method.MovementMethod;
import android.text.style.ForegroundColorSpan;
import android.text.util.Rfc822Token;
import android.util.Log;
+import android.util.SparseIntArray;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -94,9 +97,12 @@ import com.android.calendar.CalendarController.EventType;
import com.android.calendar.CalendarEventModel.Attendee;
import com.android.calendar.CalendarEventModel.ReminderEntry;
import com.android.calendar.alerts.QuickResponseActivity;
+import com.android.calendar.color.ColorComparator;
+import com.android.calendar.color.ColorPickerSwatch.OnColorSelectedListener;
import com.android.calendar.event.AttendeesView;
import com.android.calendar.event.EditEventActivity;
import com.android.calendar.event.EditEventHelper;
+import com.android.calendar.event.EventColorPickerDialog;
import com.android.calendar.event.EventViewUtils;
import com.android.calendarcommon2.DateException;
import com.android.calendarcommon2.Duration;
@@ -110,7 +116,7 @@ import java.util.List;
public class EventInfoFragment extends DialogFragment implements OnCheckedChangeListener,
CalendarController.EventHandler, OnClickListener, DeleteEventHelper.DeleteNotifyListener {
- public static final boolean DEBUG = false;
+ public static final boolean DEBUG = true;
public static final String TAG = "EventInfoFragment";
@@ -122,8 +128,14 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
protected static final String BUNDLE_KEY_WINDOW_STYLE = "key_window_style";
protected static final String BUNDLE_KEY_ATTENDEE_RESPONSE = "key_attendee_response";
+ protected static final String BUNDLE_KEY_CALENDAR_COLOR = "key_calendar_color";
+ protected static final String BUNDLE_KEY_CURRENT_COLOR = "key_current_color";
+ protected static final String BUNDLE_KEY_ORIGINAL_COLOR = "key_original_color";
+
private static final String PERIOD_SPACE = ". ";
+ private static final String NO_EVENT_COLOR = "";
+
/**
* These are the corresponding indices into the array of strings
* "R.array.change_response_labels" in the resource file.
@@ -144,9 +156,11 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
private static final int TOKEN_QUERY_DUPLICATE_CALENDARS = 1 << 3;
private static final int TOKEN_QUERY_REMINDERS = 1 << 4;
private static final int TOKEN_QUERY_VISIBLE_CALENDARS = 1 << 5;
+ private static final int TOKEN_QUERY_COLORS = 1 << 6;
+
private static final int TOKEN_QUERY_ALL = TOKEN_QUERY_DUPLICATE_CALENDARS
| TOKEN_QUERY_ATTENDEES | TOKEN_QUERY_CALENDARS | TOKEN_QUERY_EVENT
- | TOKEN_QUERY_REMINDERS | TOKEN_QUERY_VISIBLE_CALENDARS;
+ | TOKEN_QUERY_REMINDERS | TOKEN_QUERY_VISIBLE_CALENDARS | TOKEN_QUERY_COLORS;
private int mCurrentQuery = 0;
@@ -162,17 +176,18 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
Events.DESCRIPTION, // 8
Events.EVENT_LOCATION, // 9
Calendars.CALENDAR_ACCESS_LEVEL, // 10
- Events.DISPLAY_COLOR, // 11 If SDK < 16, set to Calendars.CALENDAR_COLOR.
- Events.HAS_ATTENDEE_DATA, // 12
- Events.ORGANIZER, // 13
- Events.HAS_ALARM, // 14
- Calendars.MAX_REMINDERS, //15
- Calendars.ALLOWED_REMINDERS, // 16
- Events.CUSTOM_APP_PACKAGE, // 17
- Events.CUSTOM_APP_URI, // 18
- Events.ORIGINAL_SYNC_ID, // 19 do not remove; used in DeleteEventHelper
+ Events.CALENDAR_COLOR, // 11
+ Events.EVENT_COLOR, // 12
+ Events.HAS_ATTENDEE_DATA, // 13
+ Events.ORGANIZER, // 14
+ Events.HAS_ALARM, // 15
+ Calendars.MAX_REMINDERS, // 16
+ Calendars.ALLOWED_REMINDERS, // 17
+ Events.CUSTOM_APP_PACKAGE, // 18
+ Events.CUSTOM_APP_URI, // 19
Events.DTEND, // 20
Events.DURATION, // 21
+ Events.ORIGINAL_SYNC_ID // 22 do not remove; used in DeleteEventHelper
};
private static final int EVENT_INDEX_ID = 0;
private static final int EVENT_INDEX_TITLE = 1;
@@ -185,14 +200,15 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
private static final int EVENT_INDEX_DESCRIPTION = 8;
private static final int EVENT_INDEX_EVENT_LOCATION = 9;
private static final int EVENT_INDEX_ACCESS_LEVEL = 10;
- private static final int EVENT_INDEX_COLOR = 11;
- private static final int EVENT_INDEX_HAS_ATTENDEE_DATA = 12;
- private static final int EVENT_INDEX_ORGANIZER = 13;
- private static final int EVENT_INDEX_HAS_ALARM = 14;
- private static final int EVENT_INDEX_MAX_REMINDERS = 15;
- private static final int EVENT_INDEX_ALLOWED_REMINDERS = 16;
- private static final int EVENT_INDEX_CUSTOM_APP_PACKAGE = 17;
- private static final int EVENT_INDEX_CUSTOM_APP_URI = 18;
+ private static final int EVENT_INDEX_CALENDAR_COLOR = 11;
+ private static final int EVENT_INDEX_EVENT_COLOR = 12;
+ private static final int EVENT_INDEX_HAS_ATTENDEE_DATA = 13;
+ private static final int EVENT_INDEX_ORGANIZER = 14;
+ private static final int EVENT_INDEX_HAS_ALARM = 15;
+ private static final int EVENT_INDEX_MAX_REMINDERS = 16;
+ private static final int EVENT_INDEX_ALLOWED_REMINDERS = 17;
+ private static final int EVENT_INDEX_CUSTOM_APP_PACKAGE = 18;
+ private static final int EVENT_INDEX_CUSTOM_APP_URI = 19;
private static final int EVENT_INDEX_DTEND = 20;
private static final int EVENT_INDEX_DURATION = 21;
@@ -215,7 +231,6 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
static {
if (!Utils.isJellybeanOrLater()) {
- EVENT_PROJECTION[EVENT_INDEX_COLOR] = Calendars.CALENDAR_COLOR;
EVENT_PROJECTION[EVENT_INDEX_CUSTOM_APP_PACKAGE] = Events._ID; // dummy value
EVENT_PROJECTION[EVENT_INDEX_CUSTOM_APP_URI] = Events._ID; // dummy value
@@ -245,17 +260,30 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
Calendars.CALENDAR_DISPLAY_NAME, // 1
Calendars.OWNER_ACCOUNT, // 2
Calendars.CAN_ORGANIZER_RESPOND, // 3
- Calendars.ACCOUNT_NAME // 4
+ Calendars.ACCOUNT_NAME, // 4
+ Calendars.ACCOUNT_TYPE // 5
};
static final int CALENDARS_INDEX_DISPLAY_NAME = 1;
static final int CALENDARS_INDEX_OWNER_ACCOUNT = 2;
static final int CALENDARS_INDEX_OWNER_CAN_RESPOND = 3;
static final int CALENDARS_INDEX_ACCOUNT_NAME = 4;
+ static final int CALENDARS_INDEX_ACCOUNT_TYPE = 5;
static final String CALENDARS_WHERE = Calendars._ID + "=?";
static final String CALENDARS_DUPLICATE_NAME_WHERE = Calendars.CALENDAR_DISPLAY_NAME + "=?";
static final String CALENDARS_VISIBLE_WHERE = Calendars.VISIBLE + "=?";
+ static final String[] COLORS_PROJECTION = new String[] {
+ Colors._ID, // 0
+ Colors.COLOR, // 1
+ Colors.COLOR_KEY // 2
+ };
+
+ static final String COLORS_WHERE = Colors.ACCOUNT_NAME + "=? AND " + Colors.ACCOUNT_TYPE +
+ "=? AND " + Colors.COLOR_TYPE + "=" + Colors.TYPE_EVENT;
+
+ public static final int COLORS_INDEX_COLOR = 1;
+ public static final int COLORS_INDEX_COLOR_KEY = 2;
private View mView;
@@ -312,20 +340,25 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
private View mLoadingMsgView;
private ObjectAnimator mAnimateAlpha;
private long mLoadingMsgStartTime;
+
+ private EventColorPickerDialog mDialog;
+ private SparseIntArray mColorKeyMap = new SparseIntArray();
+ private int[] mColors;
+ private int mOriginalColor = -1;
+ private int mCalendarColor = -1;
+ private int mCurrentColor = -1;
+
private static final int FADE_IN_TIME = 300; // in milliseconds
private static final int LOADING_MSG_DELAY = 600; // in milliseconds
private static final int LOADING_MSG_MIN_DISPLAY_TIME = 600;
private boolean mNoCrossFade = false; // Used to prevent repeated cross-fade
-
ArrayList<Attendee> mAcceptedAttendees = new ArrayList<Attendee>();
ArrayList<Attendee> mDeclinedAttendees = new ArrayList<Attendee>();
ArrayList<Attendee> mTentativeAttendees = new ArrayList<Attendee>();
ArrayList<Attendee> mNoResponseAttendees = new ArrayList<Attendee>();
ArrayList<String> mToEmails = new ArrayList<String>();
ArrayList<String> mCcEmails = new ArrayList<String>();
- private int mColor;
-
private int mDefaultReminderMinutes;
private final ArrayList<LinearLayout> mReminderViews = new ArrayList<LinearLayout>(0);
@@ -386,6 +419,8 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
private Activity mActivity;
private Context mContext;
+ private CalendarController mController;
+
private class QueryHandler extends AsyncQueryService {
public QueryHandler(Context context) {
super(context);
@@ -412,6 +447,22 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
activity.finish();
return;
}
+ if (mCalendarColor == -1) {
+ mCalendarColor = Utils.getDisplayColorFromColor(
+ mEventCursor.getInt(EVENT_INDEX_CALENDAR_COLOR));
+ }
+
+ if (mOriginalColor == -1) {
+ mOriginalColor = mEventCursor.isNull(EVENT_INDEX_EVENT_COLOR)
+ ? mCalendarColor : Utils.getDisplayColorFromColor(
+ mEventCursor.getInt(EVENT_INDEX_EVENT_COLOR));
+ }
+
+ Log.d(TAG, "Current event color: " + mCurrentColor);
+ if (mCurrentColor == -1) {
+ mCurrentColor = mOriginalColor;
+ }
+
updateEvent(mView);
prepareReminders();
@@ -428,6 +479,13 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
// FRAG_TODO fragments shouldn't set the title anymore
updateTitle();
+ args = new String[] {
+ mCalendarsCursor.getString(CALENDARS_INDEX_ACCOUNT_NAME),
+ mCalendarsCursor.getString(CALENDARS_INDEX_ACCOUNT_TYPE) };
+ uri = Colors.CONTENT_URI;
+ startQuery(TOKEN_QUERY_COLORS, null, uri, COLORS_PROJECTION, COLORS_WHERE, args,
+ null);
+
if (!mIsBusyFreeCalendar) {
args = new String[] { Long.toString(mEventId) };
@@ -448,6 +506,37 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
sendAccessibilityEventIfQueryDone(TOKEN_QUERY_REMINDERS);
}
break;
+ case TOKEN_QUERY_COLORS:
+ ArrayList<Integer> colors = new ArrayList<Integer>();
+ if (cursor.moveToFirst()) {
+ do
+ {
+ int colorKey = cursor.getInt(COLORS_INDEX_COLOR_KEY);
+ int rawColor = cursor.getInt(COLORS_INDEX_COLOR);
+ int displayColor = Utils.getDisplayColorFromColor(rawColor);
+ mColorKeyMap.put(displayColor, colorKey);
+ colors.add(displayColor);
+ } while (cursor.moveToNext());
+ }
+ cursor.close();
+ Integer[] sortedColors = new Integer[colors.size()];
+ Arrays.sort(colors.toArray(sortedColors), new ColorComparator());
+ mColors = new int[sortedColors.length];
+ for (int i = 0; i < sortedColors.length; i++) {
+ mColors[i] = sortedColors[i].intValue();
+
+ float[] hsv = new float[3];
+ Color.colorToHSV(mColors[i], hsv);
+ Log.d("Color", "H:" + hsv[0] + ",S:" + hsv[1] + ",V:" + hsv[2]);
+ }
+ View button = mView.findViewById(R.id.change_color);
+ if (button != null && mColors.length > 0) {
+ button.setEnabled(true);
+ button.setVisibility(View.VISIBLE);
+ }
+ updateMenu();
+ cursor.close();
+ break;
case TOKEN_QUERY_ATTENDEES:
mAttendeesCursor = Utils.matrixCursorFromCursor(cursor);
initAttendeesCursor(mView);
@@ -552,8 +641,6 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
public EventInfoFragment() {
}
-
-
public EventInfoFragment(Context context, long eventId, long startMillis, long endMillis,
int attendeeResponse, boolean isDialog, int windowStyle) {
this(context, ContentUris.withAppendedId(Events.CONTENT_URI, eventId), startMillis,
@@ -653,9 +740,17 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
}
@Override
+ public void onDetach() {
+ super.onDetach();
+ mController.deregisterEventHandler(R.layout.event_info);
+ }
+
+ @Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = activity;
+ mController = CalendarController.getInstance(mActivity);
+ mController.registerEventHandler(R.layout.event_info, this);
mEditResponseHelper = new EditResponseHelper(activity);
if (mAttendeeResponseFromIntent != Attendees.ATTENDEE_STATUS_NONE) {
@@ -678,6 +773,9 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
mDeleteDialogVisible =
savedInstanceState.getBoolean(BUNDLE_KEY_DELETE_DIALOG_VISIBLE,false);
+ mCalendarColor = savedInstanceState.getInt(BUNDLE_KEY_CALENDAR_COLOR);
+ mOriginalColor = savedInstanceState.getInt(BUNDLE_KEY_ORIGINAL_COLOR);
+ mCurrentColor = savedInstanceState.getInt(BUNDLE_KEY_CURRENT_COLOR);
}
if (mWindowStyle == DIALOG_WINDOW_STYLE) {
@@ -692,7 +790,8 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
mWhere = (TextView) mView.findViewById(R.id.where);
mDesc = (ExpandableTextView) mView.findViewById(R.id.description);
mHeadlines = mView.findViewById(R.id.event_info_headline);
- mLongAttendees = (AttendeesView)mView.findViewById(R.id.long_attendee_list);
+ mLongAttendees = (AttendeesView) mView.findViewById(R.id.long_attendee_list);
+
mIsTabletConfig = Utils.getConfigBool(mActivity, R.bool.tablet_config);
if (mUri == null) {
@@ -757,6 +856,18 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
}
});
+ b = mView.findViewById(R.id.change_color);
+ b.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!mCanModifyCalendar) {
+ return;
+ }
+
+ showEventColorPickerDialog();
+ }
+ });
+
// Hide Edit/Delete buttons if in full screen mode on a phone
if (!mIsDialog && !mIsTabletConfig || mWindowStyle == EventInfoFragment.FULL_WINDOW_STYLE) {
mView.findViewById(R.id.event_info_buttons_container).setVisibility(View.GONE);
@@ -923,9 +1034,11 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
outState.putInt(BUNDLE_KEY_WINDOW_STYLE, mWindowStyle);
outState.putBoolean(BUNDLE_KEY_DELETE_DIALOG_VISIBLE, mDeleteDialogVisible);
outState.putInt(BUNDLE_KEY_ATTENDEE_RESPONSE, mAttendeeResponseFromIntent);
+ outState.putInt(BUNDLE_KEY_CALENDAR_COLOR, mCalendarColor);
+ outState.putInt(BUNDLE_KEY_ORIGINAL_COLOR, mOriginalColor);
+ outState.putInt(BUNDLE_KEY_CURRENT_COLOR, mCurrentColor);
}
-
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
@@ -974,16 +1087,53 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
mDeleteHelper.setOnDismissListener(createDeleteOnDismissListener());
mDeleteDialogVisible = true;
mDeleteHelper.delete(mStartMillis, mEndMillis, mEventId, -1, onDeleteRunnable);
+ } else if (itemId == R.id.info_action_change_color) {
+ showEventColorPickerDialog();
}
return super.onOptionsItemSelected(item);
}
+ private void showEventColorPickerDialog() {
+ if (mDialog == null) {
+ mDialog = new EventColorPickerDialog(mColors, mCurrentColor, mCalendarColor,
+ mIsTabletConfig);
+ mDialog.setOnColorSelectedListener(new OnColorSelectedListener() {
+
+ @Override
+ public void onColorSelected(int color) {
+ updateCurrentEventColor(color);
+ }
+ });
+ }
+ if (!mDialog.isAdded()) {
+ mDialog.show(getFragmentManager(), TAG);
+ }
+ }
+
+ private boolean saveEventColor() {
+ if (mCurrentColor == mOriginalColor) {
+ return false;
+ }
+
+ ContentValues values = new ContentValues();
+ if (mCurrentColor != mCalendarColor) {
+ values.put(Events.EVENT_COLOR_KEY, mColorKeyMap.get(mCurrentColor));
+ } else {
+ values.put(Events.EVENT_COLOR_KEY, NO_EVENT_COLOR);
+ }
+ Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventId);
+ mHandler.startUpdate(mHandler.getNextToken(), null, uri, values,
+ null, null, Utils.UNDO_DELAY);
+ return true;
+ }
+
@Override
public void onStop() {
Activity act = getActivity();
if (!mEventDeletionStarted && act != null && !act.isChangingConfigurations()) {
boolean responseSaved = saveResponse();
- if (saveReminders() || responseSaved) {
+ boolean eventColorSaved = saveEventColor();
+ if (saveReminders() || responseSaved || eventColorSaved) {
Toast.makeText(getActivity(), R.string.saving_event, Toast.LENGTH_SHORT).show();
}
}
@@ -1141,6 +1291,11 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
}
}
+ private void updateCurrentEventColor(int color) {
+ mCurrentColor = color;
+ mHeadlines.setBackgroundColor(color);
+ }
+
private void updateEvent(View view) {
if (mEventCursor == null || view == null) {
return;
@@ -1189,8 +1344,7 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
String rRule = mEventCursor.getString(EVENT_INDEX_RRULE);
String eventTimezone = mEventCursor.getString(EVENT_INDEX_EVENT_TIMEZONE);
- mColor = Utils.getDisplayColorFromColor(mEventCursor.getInt(EVENT_INDEX_COLOR));
- mHeadlines.setBackgroundColor(mColor);
+ updateCurrentEventColor(mCurrentColor);
// What
if (eventName != null) {
@@ -1419,6 +1573,7 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
}
private void updateCalendar(View view) {
+
mCalendarOwnerAccount = "";
if (mCalendarsCursor != null && mEventCursor != null) {
mCalendarsCursor.moveToFirst();
@@ -1487,7 +1642,6 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
button.setVisibility(View.VISIBLE);
}
}
-
if ((!mIsDialog && !mIsTabletConfig ||
mWindowStyle == EventInfoFragment.FULL_WINDOW_STYLE) && mMenu != null) {
mActivity.invalidateOptionsMenu();
@@ -1507,6 +1661,7 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
}
MenuItem delete = mMenu.findItem(R.id.info_action_delete);
MenuItem edit = mMenu.findItem(R.id.info_action_edit);
+ MenuItem changeColor = mMenu.findItem(R.id.info_action_change_color);
if (delete != null) {
delete.setVisible(mCanModifyCalendar);
delete.setEnabled(mCanModifyCalendar);
@@ -1515,6 +1670,10 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
edit.setVisible(mCanModifyEvent);
edit.setEnabled(mCanModifyEvent);
}
+ if (changeColor != null && mColors != null && mColors.length > 0) {
+ changeColor.setVisible(mCanModifyCalendar);
+ changeColor.setEnabled(mCanModifyCalendar);
+ }
}
private void updateAttendees(View view) {
@@ -1767,15 +1926,14 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
@Override
public void handleEvent(EventInfo event) {
- if (event.eventType == EventType.EVENTS_CHANGED && mHandler != null) {
- // reload the data
- reloadEvents();
- }
+ reloadEvents();
}
public void reloadEvents() {
- mHandler.startQuery(TOKEN_QUERY_EVENT, null, mUri, EVENT_PROJECTION,
- null, null, null);
+ if (mHandler != null) {
+ mHandler.startQuery(TOKEN_QUERY_EVENT, null, mUri, EVENT_PROJECTION,
+ null, null, null);
+ }
}
@Override
@@ -1946,6 +2104,4 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange
mDialogWidth = (int)r.getDimension(R.dimen.event_info_dialog_width);
mDialogHeight = (int)r.getDimension(R.dimen.event_info_dialog_height);
}
-
-
}
diff --git a/src/com/android/calendar/SearchActivity.java b/src/com/android/calendar/SearchActivity.java
index 4775b8d7..1c257599 100644
--- a/src/com/android/calendar/SearchActivity.java
+++ b/src/com/android/calendar/SearchActivity.java
@@ -191,7 +191,6 @@ public class SearchActivity extends Activity implements CalendarController.Event
event.getResponse(), false, EventInfoFragment.DIALOG_WINDOW_STYLE);
ft.replace(R.id.agenda_event_info, mEventInfoFragment);
ft.commit();
- mController.registerEventHandler(R.id.agenda_event_info, mEventInfoFragment);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri eventUri = ContentUris.withAppendedId(Events.CONTENT_URI, event.id);
@@ -238,7 +237,6 @@ public class SearchActivity extends Activity implements CalendarController.Event
ft.remove(mEventInfoFragment);
ft.commit();
mEventInfoFragment = null;
- mController.deregisterEventHandler(R.id.agenda_event_info);
mCurrentEventId = -1;
}
}
diff --git a/src/com/android/calendar/agenda/AgendaFragment.java b/src/com/android/calendar/agenda/AgendaFragment.java
index 898fdb3a..ac8e4dad 100644
--- a/src/com/android/calendar/agenda/AgendaFragment.java
+++ b/src/com/android/calendar/agenda/AgendaFragment.java
@@ -290,7 +290,6 @@ public class AgendaFragment extends Fragment implements CalendarController.Event
* @param fragmentManager
*/
public void removeFragments(FragmentManager fragmentManager) {
- mController.deregisterEventHandler(R.id.agenda_event_info);
if (getActivity().isFinishing()) {
return;
}
@@ -430,8 +429,6 @@ public class AgendaFragment extends Fragment implements CalendarController.Event
Attendees.ATTENDEE_STATUS_NONE, false,
EventInfoFragment.DIALOG_WINDOW_STYLE);
ft.replace(R.id.agenda_event_info, mEventFragment);
- mController.registerEventHandler(R.id.agenda_event_info,
- mEventFragment);
ft.commit();
} else {
fOld.reloadEvents();
diff --git a/src/com/android/calendar/color/ColorComparator.java b/src/com/android/calendar/color/ColorComparator.java
new file mode 100644
index 00000000..f0e5764c
--- /dev/null
+++ b/src/com/android/calendar/color/ColorComparator.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013 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.color;
+
+import android.graphics.Color;
+
+import java.util.Comparator;
+
+/**
+ * A color comparator which compares based on hue, saturation, and value.
+ */
+public class ColorComparator implements Comparator<Integer> {
+
+ @Override
+ public int compare(Integer lhs, Integer rhs) {
+ float[] hsv = new float[3];
+ Color.colorToHSV(lhs, hsv);
+ float hue1 = hsv[0];
+ float sat1 = hsv[1];
+ float val1 = hsv[2];
+
+ float[] hsv2 = new float[3];
+ Color.colorToHSV(rhs, hsv2);
+ float hue2 = hsv2[0];
+ float sat2 = hsv2[1];
+ float val2 = hsv2[2];
+
+ if (hue1 < hue2) {
+ return 1;
+ } else if (hue1 > hue2) {
+ return -1;
+ } else {
+ if (sat1 < sat2) {
+ return 1;
+ } else if (sat1 > sat2) {
+ return -1;
+ } else {
+ if (val1 < val2) {
+ return 1;
+ } else if (val1 > val2) {
+ return -1;
+ }
+ }
+ }
+ return 0;
+ }
+}
diff --git a/src/com/android/calendar/color/ColorPickerDialog.java b/src/com/android/calendar/color/ColorPickerDialog.java
new file mode 100644
index 00000000..3b3d7f4c
--- /dev/null
+++ b/src/com/android/calendar/color/ColorPickerDialog.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2013 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.color;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.Context;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ProgressBar;
+
+import com.android.calendar.R;
+import com.android.calendar.color.ColorPickerSwatch.OnColorSelectedListener;
+
+/**
+ * A dialog which takes in as input an array of colors and creates a palette allowing the user to
+ * select a specific color swatch, which invokes a listener.
+ */
+public class ColorPickerDialog extends DialogFragment implements OnColorSelectedListener {
+
+ public static final int SIZE_LARGE = 1;
+ public static final int SIZE_SMALL = 2;
+
+ protected AlertDialog mAlertDialog;
+
+ private static final String KEY_COLORS = "colors";
+ private static final String KEY_CURRENT_COLOR = "current_color";
+ private static final String KEY_COLUMNS = "columns";
+ private static final String KEY_SIZE = "size";
+
+ protected String mTitle;
+ protected int mTitleResId;
+ protected int[] mColors;
+ protected int mSelectedColor;
+ protected int mColumns;
+ protected int mSize;
+ private ColorPickerPalette mPalette;
+ private ProgressBar mProgress;
+
+ protected OnColorSelectedListener mListener;
+
+ public ColorPickerDialog() {
+ // Empty constructor required for dialog fragments.
+ }
+
+ public ColorPickerDialog(int titleResId, int[] colors, int selectedColor,
+ int columns, int size) {
+ mTitleResId = titleResId;
+ mColors = colors;
+ mSelectedColor = selectedColor;
+ mColumns = columns;
+ mSize = size;
+ }
+
+ public void setOnColorSelectedListener(OnColorSelectedListener listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setRetainInstance(true);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final Activity activity = getActivity();
+
+ final LayoutInflater layoutInflater = (LayoutInflater) activity
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ if (savedInstanceState != null) {
+ mColors = (int[]) savedInstanceState.getSerializable(KEY_COLORS);
+ mSelectedColor = savedInstanceState.getInt(KEY_CURRENT_COLOR);
+ mColumns = savedInstanceState.getInt(KEY_COLUMNS);
+ mSize = savedInstanceState.getInt(KEY_SIZE);
+ }
+
+ View view = LayoutInflater.from(getActivity()).inflate(R.layout.color_picker_dialog, null);
+ mProgress = (ProgressBar) view.findViewById(android.R.id.progress);
+ mPalette = (ColorPickerPalette) view.findViewById(R.id.color_picker);
+ mPalette.init(mSize, mColumns, this);
+
+ if (mColors != null) {
+ showPalette();
+ }
+
+ if (mTitle == null) {
+ mTitle = activity.getString(mTitleResId);
+ }
+
+ mAlertDialog = new AlertDialog.Builder(activity)
+ .setTitle(mTitle)
+ .setView(view)
+ .create();
+
+ return mAlertDialog;
+ }
+
+ @Override
+ public void onColorSelected(int color) {
+ if (mListener != null) {
+ mListener.onColorSelected(color);
+ }
+ mSelectedColor = color;
+ dismiss();
+ }
+
+ public void showPalette() {
+ mProgress.setVisibility(View.GONE);
+ mPalette.setVisibility(View.VISIBLE);
+ mPalette.drawPalette(mColors, mSelectedColor);
+ }
+
+ public void showProgress() {
+ mProgress.setVisibility(View.VISIBLE);
+ mPalette.setVisibility(View.GONE);
+ }
+
+ public void setColors(int[] colors) {
+ if (colors == null) {
+ return;
+ }
+ mColors = colors;
+ showPalette();
+ }
+
+ public void setColors(int[] colors, int selectedColor) {
+ mSelectedColor = selectedColor;
+ setColors(colors);
+ }
+
+ public void setSelectedColor(int color) {
+ if (mSelectedColor != color) {
+ setColors(mColors, color);
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putSerializable(KEY_COLORS, mColors);
+ outState.putInt(KEY_CURRENT_COLOR, mSelectedColor);
+ outState.putInt(KEY_COLUMNS, mColumns);
+ outState.putInt(KEY_SIZE, mSize);
+ }
+
+ @Override
+ public void onDestroyView() {
+ if (getDialog() != null && getRetainInstance()) {
+ getDialog().setDismissMessage(null);
+ }
+ super.onDestroyView();
+ }
+}
diff --git a/src/com/android/calendar/color/ColorPickerPalette.java b/src/com/android/calendar/color/ColorPickerPalette.java
new file mode 100644
index 00000000..dba1eda6
--- /dev/null
+++ b/src/com/android/calendar/color/ColorPickerPalette.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2013 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.color;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TableLayout;
+import android.widget.TableRow;
+
+import com.android.calendar.R;
+import com.android.calendar.color.ColorPickerSwatch.OnColorSelectedListener;
+
+/**
+ * A color picker custom view which creates an grid of color squares. The number of squares per
+ * row (and the padding between the squares) is determined by the user.
+ */
+public class ColorPickerPalette extends TableLayout {
+
+ public OnColorSelectedListener mOnColorSelectedListener;
+
+ private int mSwatchLength;
+ private int mMarginSize;
+ private int mNumColumns;
+
+ public ColorPickerPalette(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public ColorPickerPalette(Context context) {
+ super(context);
+ }
+
+ /**
+ * Initialize the size, columns, and listener. Size should be a pre-defined size (SIZE_LARGE
+ * or SIZE_SMALL) from ColorPickerDialogFragment.
+ */
+ public void init(int size, int columns, OnColorSelectedListener listener) {
+ mNumColumns = columns;
+ if (size == ColorPickerDialog.SIZE_LARGE) {
+ mSwatchLength = getResources().getDimensionPixelSize(R.dimen.color_swatch_large);
+ mMarginSize = getResources().getDimensionPixelSize(R.dimen.color_swatch_margins_large);
+ } else {
+ mSwatchLength = getResources().getDimensionPixelSize(R.dimen.color_swatch_small);
+ mMarginSize = getResources().getDimensionPixelSize(R.dimen.color_swatch_margins_small);
+ }
+ mOnColorSelectedListener = listener;
+ }
+
+ private TableRow createTableRow() {
+ TableRow row = new TableRow(getContext());
+ ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT);
+ row.setLayoutParams(params);
+ return row;
+ }
+
+ /**
+ * Adds swatches to table in a serpentine format.
+ */
+ public void drawPalette(int[] colors, int selectedColor) {
+
+ if (colors == null) {
+ return;
+ }
+
+ this.removeAllViews();
+ int rowElements = 0;
+ int rowNumber = 0;
+
+ // Fills the table with swatches based on the array of colors.
+ TableRow row = createTableRow();
+ for (int color : colors) {
+ addSwatchToRow(row, createColorSwatch(color, selectedColor), rowNumber);
+ rowElements++;
+ if (rowElements == mNumColumns) {
+ addView(row);
+ row = createTableRow();
+ rowElements = 0;
+ rowNumber++;
+ }
+ }
+
+ // Create blank views to fill the row if the last row has not been filled.
+ if (rowElements > 0) {
+ while (rowElements != mNumColumns) {
+ addSwatchToRow(row, createBlankSpace(), rowNumber);
+ rowElements++;
+ }
+ addView(row);
+ }
+ }
+
+ /**
+ * Appends a swatch to the end of the row for even-numbered rows (starting with row 0),
+ * to the beginning of a row for odd-numbered rows.
+ */
+ private void addSwatchToRow(TableRow row, View swatch, int rowNumber) {
+ if (rowNumber % 2 == 0) {
+ row.addView(swatch);
+ } else {
+ row.addView(swatch, 0);
+ }
+ }
+
+ /**
+ * Creates a blank space to fill the row.
+ */
+ private ImageView createBlankSpace() {
+ ImageView view = new ImageView(getContext());
+ TableRow.LayoutParams params = new TableRow.LayoutParams(mSwatchLength, mSwatchLength);
+ params.setMargins(mMarginSize, mMarginSize, mMarginSize, mMarginSize);
+ view.setLayoutParams(params);
+ return view;
+ }
+
+ /**
+ * Creates a color swatch.
+ */
+ private ColorPickerSwatch createColorSwatch(int color, int selectedColor) {
+ ColorPickerSwatch view = new ColorPickerSwatch(getContext(), color,
+ color == selectedColor, mOnColorSelectedListener);
+ TableRow.LayoutParams params = new TableRow.LayoutParams(mSwatchLength, mSwatchLength);
+ params.setMargins(mMarginSize, mMarginSize, mMarginSize, mMarginSize);
+ view.setLayoutParams(params);
+ return view;
+ }
+}
diff --git a/src/com/android/calendar/color/ColorPickerSwatch.java b/src/com/android/calendar/color/ColorPickerSwatch.java
new file mode 100644
index 00000000..c670116d
--- /dev/null
+++ b/src/com/android/calendar/color/ColorPickerSwatch.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2013 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.color;
+
+import android.content.Context;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.widget.ImageView;
+
+import com.android.calendar.R;
+
+import java.io.Serializable;
+
+/**
+ * Creates a circular swatch of a specified color. Adds a checkmark if marked as checked.
+ */
+public class ColorPickerSwatch extends ImageView implements View.OnClickListener {
+
+ private int mColor;
+ private Drawable mColorDrawable;
+ private Drawable mCheckmark;
+ private OnColorSelectedListener mOnColorSelectedListener;
+
+ /**
+ * Interface for a callback when a color square is selected.
+ */
+ public interface OnColorSelectedListener {
+
+ /**
+ * Called when a specific color square has been selected.
+ */
+ public void onColorSelected(int color);
+ }
+
+ /**
+ * @param context
+ */
+ public ColorPickerSwatch(Context context) {
+ super(context);
+ }
+
+ public ColorPickerSwatch(Context context, int color, boolean checked,
+ OnColorSelectedListener listener) {
+ super(context);
+ setScaleType(ScaleType.FIT_XY);
+ mColorDrawable = getContext().getResources()
+ .getDrawable(R.drawable.color_picker_swatch);
+ mCheckmark = getContext().getResources().getDrawable(
+ R.drawable.ic_colorpicker_swatch_selected);
+ mOnColorSelectedListener = listener;
+ setColor(color);
+ setChecked(checked);
+ setOnClickListener(this);
+ }
+
+ protected void setColor(int color) {
+ mColor = color;
+ mColorDrawable.setColorFilter(color, Mode.SRC_ATOP);
+ setBackgroundDrawable(mColorDrawable);
+ }
+
+ private void setChecked(boolean checked) {
+ if (checked) {
+ setImageDrawable(mCheckmark);
+ } else {
+ setImageDrawable(null);
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (mOnColorSelectedListener != null) {
+ mOnColorSelectedListener.onColorSelected(mColor);
+ }
+ }
+}
diff --git a/src/com/android/calendar/event/EditEventFragment.java b/src/com/android/calendar/event/EditEventFragment.java
index a7aa2b43..a81672a6 100644
--- a/src/com/android/calendar/event/EditEventFragment.java
+++ b/src/com/android/calendar/event/EditEventFragment.java
@@ -35,6 +35,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.provider.CalendarContract.Attendees;
import android.provider.CalendarContract.Calendars;
+import android.provider.CalendarContract.Colors;
import android.provider.CalendarContract.Events;
import android.provider.CalendarContract.Reminders;
import android.text.TextUtils;
@@ -61,6 +62,8 @@ import com.android.calendar.CalendarEventModel.ReminderEntry;
import com.android.calendar.DeleteEventHelper;
import com.android.calendar.R;
import com.android.calendar.Utils;
+import com.android.calendar.color.ColorComparator;
+import com.android.calendar.color.ColorPickerSwatch.OnColorSelectedListener;
import java.io.Serializable;
import java.util.ArrayList;
@@ -81,8 +84,10 @@ public class EditEventFragment extends Fragment implements EventHandler {
private static final int TOKEN_ATTENDEES = 1 << 1;
private static final int TOKEN_REMINDERS = 1 << 2;
private static final int TOKEN_CALENDARS = 1 << 3;
+ private static final int TOKEN_COLORS = 1 << 4;
+
private static final int TOKEN_ALL = TOKEN_EVENT | TOKEN_ATTENDEES | TOKEN_REMINDERS
- | TOKEN_CALENDARS;
+ | TOKEN_CALENDARS | TOKEN_COLORS;
private static final int TOKEN_UNITIALIZED = 1 << 31;
/**
@@ -109,6 +114,8 @@ public class EditEventFragment extends Fragment implements EventHandler {
private long mEnd;
private long mCalendarId = -1;
+ private EventColorPickerDialog mDialog;
+
private Activity mContext;
private final Done mOnDone = new Done();
@@ -303,12 +310,41 @@ public class EditEventFragment extends Fragment implements EventHandler {
EditEventHelper.setModelFromCalendarCursor(mModel, cursor);
EditEventHelper.setModelFromCalendarCursor(mOriginalModel, cursor);
}
+ startQuery(TOKEN_COLORS, null, Colors.CONTENT_URI,
+ EditEventHelper.COLORS_PROJECTION,
+ Colors.COLOR_TYPE + "=" + Colors.TYPE_EVENT, null, null);
} finally {
cursor.close();
}
-
setModelIfDone(TOKEN_CALENDARS);
break;
+ case TOKEN_COLORS:
+ if (cursor.moveToFirst()) {
+ EventColorCache cache = new EventColorCache();
+ do
+ {
+ int colorKey = cursor.getInt(EditEventHelper.COLORS_INDEX_COLOR_KEY);
+ int rawColor = cursor.getInt(EditEventHelper.COLORS_INDEX_COLOR);
+ int displayColor = Utils.getDisplayColorFromColor(rawColor);
+ String accountName = cursor
+ .getString(EditEventHelper.COLORS_INDEX_ACCOUNT_NAME);
+ String accountType = cursor
+ .getString(EditEventHelper.COLORS_INDEX_ACCOUNT_TYPE);
+ cache.insertColor(accountName, accountType,
+ displayColor, colorKey);
+ } while (cursor.moveToNext());
+ cache.sortPalettes(new ColorComparator());
+
+ mModel.mEventColorCache = cache;
+ mView.mColorPickerNewEvent.setOnClickListener(mOnColorPickerClicked);
+ mView.mColorPickerExistingEvent.setOnClickListener(mOnColorPickerClicked);
+ mView.setColorPickerButtonStates(mModel.getCalendarEventColors());
+ }
+ if (cursor != null) {
+ cursor.close();
+ }
+ setModelIfDone(TOKEN_COLORS);
+ break;
default:
cursor.close();
break;
@@ -316,6 +352,35 @@ public class EditEventFragment extends Fragment implements EventHandler {
}
}
+ private View.OnClickListener mOnColorPickerClicked = new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ int[] colors = mModel.getCalendarEventColors();
+ if (mDialog == null) {
+ mDialog = new EventColorPickerDialog(colors, mModel.mEventColor,
+ mModel.mCalendarColor, mView.mIsMultipane);
+ mDialog.setOnColorSelectedListener(new OnColorSelectedListener() {
+
+ @Override
+ public void onColorSelected(int color) {
+ // TODO(kingkung): Auto-generated method stub
+ if (mModel.mEventColor != color) {
+ mModel.mEventColor = color;
+ mView.updateHeadlineColor(mModel, color);
+ }
+ }
+ });
+ } else {
+ mDialog.setCalendarColor(mModel.mCalendarColor);
+ mDialog.setColors(colors, mModel.mEventColor);
+ }
+ if (!mDialog.isAdded()) {
+ mDialog.show(getFragmentManager(), TAG);
+ }
+ }
+ };
+
private void setModelIfDone(int queryType) {
synchronized (this) {
mOutstandingQueries &= ~queryType;
diff --git a/src/com/android/calendar/event/EditEventHelper.java b/src/com/android/calendar/event/EditEventHelper.java
index 49bd744d..32663e01 100644
--- a/src/com/android/calendar/event/EditEventHelper.java
+++ b/src/com/android/calendar/event/EditEventHelper.java
@@ -25,6 +25,7 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.provider.CalendarContract.Attendees;
import android.provider.CalendarContract.Calendars;
+import android.provider.CalendarContract.Colors;
import android.provider.CalendarContract.Events;
import android.provider.CalendarContract.Reminders;
import android.text.TextUtils;
@@ -59,6 +60,8 @@ public class EditEventHelper {
private static final boolean DEBUG = false;
+ private static final String NO_EVENT_COLOR = "";
+
public static final String[] EVENT_PROJECTION = new String[] {
Events._ID, // 0
Events.TITLE, // 1
@@ -82,6 +85,9 @@ public class EditEventHelper {
Events.GUESTS_CAN_MODIFY, // 19
Events.ORIGINAL_ID, // 20
Events.STATUS, // 21
+ Events.CALENDAR_COLOR, // 22
+ Events.EVENT_COLOR, // 23
+ Events.EVENT_COLOR_KEY // 24
};
protected static final int EVENT_INDEX_ID = 0;
protected static final int EVENT_INDEX_TITLE = 1;
@@ -105,6 +111,9 @@ public class EditEventHelper {
protected static final int EVENT_INDEX_GUESTS_CAN_MODIFY = 19;
protected static final int EVENT_INDEX_ORIGINAL_ID = 20;
protected static final int EVENT_INDEX_EVENT_STATUS = 21;
+ protected static final int EVENT_INDEX_CALENDAR_COLOR = 22;
+ protected static final int EVENT_INDEX_EVENT_COLOR = 23;
+ protected static final int EVENT_INDEX_EVENT_COLOR_KEY = 24;
public static final String[] REMINDERS_PROJECTION = new String[] {
Reminders._ID, // 0
@@ -191,6 +200,22 @@ public class EditEventHelper {
static final String CALENDARS_WHERE = Calendars._ID + "=?";
+ static final String[] COLORS_PROJECTION = new String[] {
+ Colors._ID, // 0
+ Colors.ACCOUNT_NAME,
+ Colors.ACCOUNT_TYPE,
+ Colors.COLOR, // 1
+ Colors.COLOR_KEY // 2
+ };
+
+ static final String COLORS_WHERE = Colors.ACCOUNT_NAME + "=? AND " + Colors.ACCOUNT_TYPE +
+ "=? AND " + Colors.COLOR_TYPE + "=" + Colors.TYPE_EVENT;
+
+ static final int COLORS_INDEX_ACCOUNT_NAME = 1;
+ static final int COLORS_INDEX_ACCOUNT_TYPE = 2;
+ static final int COLORS_INDEX_COLOR = 3;
+ static final int COLORS_INDEX_COLOR_KEY = 4;
+
static final String[] ATTENDEES_PROJECTION = new String[] {
Attendees._ID, // 0
Attendees.ATTENDEE_NAME, // 1
@@ -1044,6 +1069,14 @@ public class EditEventHelper {
model.mIsOrganizer = model.mOwnerAccount.equalsIgnoreCase(model.mOrganizer);
model.mGuestsCanModify = cursor.getInt(EVENT_INDEX_GUESTS_CAN_MODIFY) != 0;
+ int rawEventColor;
+ if (cursor.isNull(EVENT_INDEX_EVENT_COLOR)) {
+ rawEventColor = cursor.getInt(EVENT_INDEX_CALENDAR_COLOR);
+ } else {
+ rawEventColor = cursor.getInt(EVENT_INDEX_EVENT_COLOR);
+ }
+ model.mEventColor = Utils.getDisplayColorFromColor(rawEventColor);
+
if (accessLevel > 0) {
// For now the array contains the values 0, 2, and 3. We subtract
// one to make it easier to handle in code as 0,1,2.
@@ -1100,7 +1133,11 @@ public class EditEventHelper {
model.mCalendarAccessLevel = cursor.getInt(CALENDARS_INDEX_ACCESS_LEVEL);
model.mCalendarDisplayName = cursor.getString(CALENDARS_INDEX_DISPLAY_NAME);
- model.mCalendarColor = cursor.getInt(CALENDARS_INDEX_COLOR);
+ model.mCalendarColor = Utils.getDisplayColorFromColor(
+ cursor.getInt(CALENDARS_INDEX_COLOR));
+
+ model.mCalendarAccountName = cursor.getString(CALENDARS_INDEX_ACCOUNT_NAME);
+ model.mCalendarAccountType = cursor.getString(CALENDARS_INDEX_ACCOUNT_TYPE);
model.mCalendarMaxReminders = cursor.getInt(CALENDARS_INDEX_MAX_REMINDERS);
model.mCalendarAllowedReminders = cursor.getString(CALENDARS_INDEX_ALLOWED_REMINDERS);
@@ -1248,6 +1285,11 @@ public class EditEventHelper {
}
values.put(Events.ACCESS_LEVEL, accessLevel);
values.put(Events.STATUS, model.mEventStatus);
+ if (model.mEventColor == -1 || model.mEventColor == model.mCalendarColor) {
+ values.put(Events.EVENT_COLOR_KEY, NO_EVENT_COLOR);
+ } else {
+ values.put(Events.EVENT_COLOR_KEY, model.getEventColorKey());
+ }
return values;
}
diff --git a/src/com/android/calendar/event/EditEventView.java b/src/com/android/calendar/event/EditEventView.java
index 1c7b910e..1f9ba9fe 100644
--- a/src/com/android/calendar/event/EditEventView.java
+++ b/src/com/android/calendar/event/EditEventView.java
@@ -20,6 +20,7 @@ import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
+import android.app.FragmentManager;
import android.app.ProgressDialog;
import android.app.Service;
import android.app.TimePickerDialog;
@@ -31,11 +32,11 @@ import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
+import android.provider.CalendarContract;
import android.provider.CalendarContract.Attendees;
import android.provider.CalendarContract.Calendars;
import android.provider.CalendarContract.Events;
import android.provider.CalendarContract.Reminders;
-import android.provider.CalendarContract;
import android.provider.Settings;
import android.text.InputFilter;
import android.text.TextUtils;
@@ -47,6 +48,7 @@ import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -60,6 +62,7 @@ import android.widget.CalendarView;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.DatePicker;
+import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.MultiAutoCompleteTextView;
import android.widget.RadioButton;
@@ -82,6 +85,7 @@ import com.android.calendar.RecipientAdapter;
import com.android.calendar.TimezoneAdapter;
import com.android.calendar.TimezoneAdapter.TimezoneRow;
import com.android.calendar.Utils;
+import com.android.calendar.color.ColorPickerSwatch.OnColorSelectedListener;
import com.android.calendar.event.EditEventHelper.EditDoneRunnable;
import com.android.calendarcommon2.EventRecurrence;
import com.android.common.Rfc822InputFilter;
@@ -115,6 +119,9 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
Button mStartTimeButton;
Button mEndTimeButton;
Button mTimezoneButton;
+ View mColorPickerNewEvent;
+ View mColorPickerExistingEvent;
+ OnClickListener mChangeColorOnClickListener;
View mTimezoneRow;
TextView mStartTimeHome;
TextView mStartDateHome;
@@ -150,7 +157,7 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
private int[] mOriginalPadding = new int[4];
private int[] mOriginalSpinnerPadding = new int[4];
- private boolean mIsMultipane;
+ public boolean mIsMultipane;
private ProgressDialog mLoadingCalendarsDialog;
private AlertDialog mNoCalendarsDialog;
private AlertDialog mTimezoneDialog;
@@ -868,6 +875,9 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
mEndHomeGroup = view.findViewById(R.id.to_row_home_tz);
mAttendeesList = (MultiAutoCompleteTextView) view.findViewById(R.id.attendees);
+ mColorPickerNewEvent = view.findViewById(R.id.change_color_new_event);
+ mColorPickerExistingEvent = view.findViewById(R.id.change_color_existing_event);
+
mTitleTextView.setTag(mTitleTextView.getBackground());
mLocationTextView.setTag(mLocationTextView.getBackground());
mLocationAdapter = new EventLocationAdapter(activity);
@@ -1056,6 +1066,9 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
boolean canRespond = EditEventHelper.canRespond(model);
+ final long eventId = model.mId;
+ final long calendarId = model.mCalendarId;
+
long begin = model.mStart;
long end = model.mEnd;
mTimezone = model.mTimezone; // this will be UTC for all day events
@@ -1176,7 +1189,6 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
mResponseGroup.setVisibility(View.GONE);
}
- int displayColor = Utils.getDisplayColorFromColor(model.mCalendarColor);
if (model.mUri != null) {
// This is an existing event so hide the calendar spinner
// since we can't change the calendar.
@@ -1188,15 +1200,11 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
if (tv != null) {
tv.setText(model.mOwnerAccount);
}
- if (mIsMultipane) {
- mView.findViewById(R.id.calendar_textview).setBackgroundColor(displayColor);
- } else {
- mView.findViewById(R.id.calendar_group).setBackgroundColor(displayColor);
- }
} else {
View calendarGroup = mView.findViewById(R.id.calendar_group);
calendarGroup.setVisibility(View.GONE);
}
+ updateHeadlineColor(model, model.mEventColor);
populateWhen();
populateRepeats();
@@ -1208,6 +1216,23 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
sendAccessibilityEvent();
}
+ public void updateHeadlineColor(CalendarEventModel model, int displayColor) {
+ if (model.mUri != null) {
+ if (mIsMultipane) {
+ mView.findViewById(R.id.calendar_textview_with_colorpicker)
+ .setBackgroundColor(displayColor);
+ } else {
+ mView.findViewById(R.id.calendar_group).setBackgroundColor(displayColor);
+ }
+ } else {
+ if (mIsMultipane) {
+ mCalendarSelectorWrapper.setBackgroundColor(displayColor);
+ } else {
+ mCalendarSelectorGroup.setBackgroundColor(displayColor);
+ }
+ }
+ }
+
private void sendAccessibilityEvent() {
AccessibilityManager am =
(AccessibilityManager) mActivity.getSystemService(Service.ACCESSIBILITY_SERVICE);
@@ -1655,6 +1680,16 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
updateHomeTime();
}
+ public void setColorPickerButtonStates(int[] eventColors) {
+ if (eventColors == null || eventColors.length == 0) {
+ mColorPickerNewEvent.setEnabled(false);
+ mColorPickerExistingEvent.setEnabled(false);
+ } else {
+ mColorPickerNewEvent.setEnabled(true);
+ mColorPickerExistingEvent.setEnabled(true);
+ }
+ }
+
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// This is only used for the Calendar spinner in new events, and only fires when the
@@ -1666,6 +1701,13 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
return;
}
+ // Do nothing if the selection didn't change so that reminders will not get lost
+ int idColumn = c.getColumnIndexOrThrow(Calendars._ID);
+ long calendarId = c.getLong(idColumn);
+ if (calendarId == mModel.mCalendarId) {
+ return;
+ }
+
int colorColumn = c.getColumnIndexOrThrow(Calendars.CALENDAR_COLOR);
int color = c.getInt(colorColumn);
int displayColor = Utils.getDisplayColorFromColor(color);
@@ -1676,14 +1718,14 @@ public class EditEventView implements View.OnClickListener, DialogInterface.OnCa
mCalendarSelectorGroup.setBackgroundColor(displayColor);
}
- // Do nothing if the selection didn't change so that reminders will not get lost
- int idColumn = c.getColumnIndexOrThrow(Calendars._ID);
- long calendarId = c.getLong(idColumn);
- if (calendarId == mModel.mCalendarId) {
- return;
- }
mModel.mCalendarId = calendarId;
- mModel.mCalendarColor = color;
+ mModel.mCalendarColor = displayColor;
+ mModel.mCalendarAccountName = c.getString(EditEventHelper.CALENDARS_INDEX_ACCOUNT_NAME);
+ mModel.mCalendarAccountType = c.getString(EditEventHelper.CALENDARS_INDEX_ACCOUNT_TYPE);
+ mModel.mEventColor = mModel.mCalendarColor;
+
+ setColorPickerButtonStates(mModel.getCalendarEventColors());
+
// Update the max/allowed reminders with the new calendar properties.
int maxRemindersColumn = c.getColumnIndexOrThrow(Calendars.MAX_REMINDERS);
mModel.mCalendarMaxReminders = c.getInt(maxRemindersColumn);
diff --git a/src/com/android/calendar/event/EventColorCache.java b/src/com/android/calendar/event/EventColorCache.java
new file mode 100644
index 00000000..e7ed6687
--- /dev/null
+++ b/src/com/android/calendar/event/EventColorCache.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.calendar.event;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A cache for event colors and event color keys stored based upon calendar account name and type.
+ */
+public class EventColorCache {
+
+ private static final String SEPARATOR = "::";
+
+ private Map<String, ArrayList<Integer>> mColorPaletteMap;
+ private Map<String, Integer> mColorKeyMap;
+
+ public EventColorCache() {
+ mColorPaletteMap = new HashMap<String, ArrayList<Integer>>();
+ mColorKeyMap = new HashMap<String, Integer>();
+ }
+
+ /**
+ * Inserts a color into the cache.
+ */
+ public void insertColor(String accountName, String accountType, int displayColor,
+ int colorKey) {
+ mColorKeyMap.put(createKey(accountName, accountType, displayColor), colorKey);
+ String key = createKey(accountName, accountType);
+ ArrayList<Integer> colorPalette;
+ if ((colorPalette = mColorPaletteMap.get(key)) == null) {
+ colorPalette = new ArrayList<Integer>();
+ }
+ colorPalette.add(displayColor);
+ mColorPaletteMap.put(key, colorPalette);
+ }
+
+ /**
+ * Retrieve an array of colors for a specific account name and type.
+ */
+ public int[] getColorArray(String accountName, String accountType) {
+ ArrayList<Integer> colors = mColorPaletteMap.get(createKey(accountName, accountType));
+ if (colors == null) {
+ return null;
+ }
+ int[] ret = new int[colors.size()];
+ for (int i = 0; i < ret.length; i++) {
+ ret[i] = colors.get(i);
+ }
+ return ret;
+ }
+
+ /**
+ * Retrieve an event color's unique key based on account name, type, and color.
+ */
+ public int getColorKey(String accountName, String accountType, int displayColor) {
+ return mColorKeyMap.get(createKey(accountName, accountType, displayColor));
+ }
+
+ /**
+ * Sorts the arrays of colors based on a comparator.
+ */
+ public void sortPalettes(Comparator<Integer> comparator) {
+ for (String key : mColorPaletteMap.keySet()) {
+ ArrayList<Integer> palette = mColorPaletteMap.get(key);
+ Integer[] sortedColors = new Integer[palette.size()];
+ Arrays.sort(palette.toArray(sortedColors), comparator);
+ palette.clear();
+ for (Integer color : sortedColors) {
+ palette.add(color);
+ }
+ mColorPaletteMap.put(key, palette);
+ }
+ }
+
+ private String createKey(String accountName, String accountType) {
+ return new StringBuilder().append(accountName)
+ .append(SEPARATOR)
+ .append(accountType)
+ .toString();
+ }
+
+ private String createKey(String accountName, String accountType, int displayColor) {
+ return new StringBuilder(createKey(accountName, accountType))
+ .append(SEPARATOR)
+ .append(displayColor)
+ .toString();
+ }
+}
diff --git a/src/com/android/calendar/event/EventColorPickerDialog.java b/src/com/android/calendar/event/EventColorPickerDialog.java
new file mode 100644
index 00000000..23c2d78e
--- /dev/null
+++ b/src/com/android/calendar/event/EventColorPickerDialog.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.calendar.event;
+
+import android.app.Activity;
+import android.content.DialogInterface;
+import android.os.Bundle;
+
+import com.android.calendar.R;
+import com.android.calendar.color.ColorPickerDialog;
+
+/**
+ * A dialog which displays event colors, with an additional button for the calendar color.
+ */
+public class EventColorPickerDialog extends ColorPickerDialog {
+
+ private static final int NUM_COLUMNS = 4;
+
+ private int mCalendarColor;
+
+ public EventColorPickerDialog() {
+ // Empty constructor required for dialog fragment.
+ }
+
+ public EventColorPickerDialog(int[] colors, int selectedColor, int calendarColor,
+ boolean isTablet) {
+ super(R.string.event_color_picker_dialog_title, colors, selectedColor, NUM_COLUMNS,
+ isTablet ? SIZE_LARGE : SIZE_SMALL);
+ mCalendarColor = calendarColor;
+ }
+
+ public void setCalendarColor(int color) {
+ mCalendarColor = color;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ final Activity activity = getActivity();
+ mAlertDialog.setButton(DialogInterface.BUTTON_NEUTRAL,
+ activity.getString(R.string.event_color_set_to_default),
+ new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (mListener != null) {
+ mListener.onColorSelected(mCalendarColor);
+ }
+ }
+ }
+ );
+ }
+}