auto import from //branches/cupcake/...@130745

This commit is contained in:
The Android Open Source Project 2009-02-10 15:44:05 -08:00
parent bb96f41aa9
commit 15a8880cb1
73 changed files with 1310 additions and 822 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 918 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 667 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 695 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 669 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -16,7 +16,6 @@
<com.android.launcher.DragLayer
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
android:id="@+id/drag_layer"
@ -37,15 +36,15 @@
</com.android.launcher.Workspace>
<com.android.internal.widget.SlidingDrawer
<SlidingDrawer
android:id="@+id/drawer"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
androidprv:bottomOffset="7px"
androidprv:handle="@+id/all_apps"
androidprv:content="@+id/content">
android:bottomOffset="7dip"
android:handle="@+id/all_apps"
android:content="@+id/content">
<com.android.launcher.HandleView
android:id="@id/all_apps"
@ -81,7 +80,7 @@
android:verticalSpacing="10dip"
android:numColumns="5" />
</com.android.internal.widget.SlidingDrawer>
</SlidingDrawer>
<com.android.launcher.DeleteZone
android:id="@+id/delete_zone"

View File

@ -16,7 +16,6 @@
<com.android.launcher.DragLayer
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
android:id="@+id/drag_layer"
@ -37,15 +36,15 @@
</com.android.launcher.Workspace>
<com.android.internal.widget.SlidingDrawer
<SlidingDrawer
android:id="@+id/drawer"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
androidprv:topOffset="5px"
androidprv:bottomOffset="7px"
androidprv:handle="@+id/all_apps"
androidprv:content="@+id/content">
android:topOffset="5dip"
android:bottomOffset="7dip"
android:handle="@+id/all_apps"
android:content="@+id/content">
<com.android.launcher.HandleView
android:id="@id/all_apps"
@ -81,7 +80,7 @@
android:verticalSpacing="10dip"
android:numColumns="4" />
</com.android.internal.widget.SlidingDrawer>
</SlidingDrawer>
<com.android.launcher.DeleteZone
android:id="@+id/delete_zone"

View File

@ -0,0 +1,25 @@
<?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.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:textAppearance="?android:attr/textAppearanceLargeInverse"
android:gravity="center_vertical"
android:drawablePadding="14dip"
android:paddingLeft="15dip"
android:paddingRight="15dip" />

View File

@ -17,11 +17,10 @@
** limitations under the License.
*/
-->
<ExpandableListView xmlns:android="http://schemas.android.com/apk/res/android"
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="5px"
android:layout_marginTop="5dip"
android:cacheColorHint="@null"
android:childDivider="@android:drawable/divider_horizontal_bright"
android:divider="@android:drawable/divider_horizontal_bright"
android:scrollbars="vertical" />

View File

@ -0,0 +1,29 @@
<?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.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="10dip"
android:paddingBottom="10dip"
android:paddingLeft="20dip"
android:paddingRight="20dip"
android:gravity="center"
android:background="@drawable/bg_gadget_error"
android:textAppearance="?android:attr/textAppearanceMediumInverse"
android:textColor="@color/gadget_error_color"
android:text="@string/gadget_error_text"
/>

View File

@ -36,7 +36,7 @@
android:singleLine="true"
android:selectAllOnFocus="true"
android:completionThreshold="1"
android:inputType="textAutoComplete|textSearchString"
android:inputType="textAutoComplete|textSearch"
/>
<ImageButton android:id="@+id/search_go_btn"
@ -46,4 +46,10 @@
android:src="@*android:drawable/ic_btn_search"
/>
<ImageButton android:id="@+id/search_voice_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_btn_speak_now"
/>
</com.android.launcher.Search>

View File

@ -28,14 +28,24 @@
<string name="menu_item_add_item">"Přidat na plochu"</string>
<string name="group_applications">"Aplikace"</string>
<string name="group_shortcuts">"Zástupce"</string>
<!-- no translation found for group_search (5905328940867162196) -->
<skip />
<!-- no translation found for group_folder (236213814675135523) -->
<skip />
<string name="group_live_folders">"Složka Live"</string>
<string name="group_widgets">"Miniaplikace"</string>
<!-- no translation found for group_gadgets (7795333306847768497) -->
<skip />
<string name="group_wallpapers">"Tapeta"</string>
<string name="add_folder">"Složka"</string>
<string name="add_clock">"Hodiny"</string>
<string name="add_photo_frame">"Rámeček fotografie"</string>
<string name="add_search">"Vyhledávání"</string>
<string name="out_of_space">"Na této ploše již není místo."</string>
<!-- no translation found for title_select_shortcut (2858897527672831763) -->
<skip />
<!-- no translation found for title_select_live_folder (441136484932944782) -->
<skip />
<string name="menu_add">"Přidat"</string>
<string name="menu_wallpaper">"Tapeta"</string>
<string name="menu_search">"Hledat"</string>
@ -50,4 +60,6 @@
<string name="permlab_write_settings">"zápis nastavení a odkazů plochy"</string>
<string name="permdesc_write_settings">"Povoluje aplikaci změnit nastavení a odkazy plochy."</string>
<string name="search_hint">"Vyhledávání Google"</string>
<!-- no translation found for gadget_error_text (7654995305187314446) -->
<skip />
</resources>

View File

@ -28,14 +28,24 @@
<string name="menu_item_add_item">"Zur Startseite hinzufügen"</string>
<string name="group_applications">"Anwendung"</string>
<string name="group_shortcuts">"Verknüpfung"</string>
<!-- no translation found for group_search (5905328940867162196) -->
<skip />
<!-- no translation found for group_folder (236213814675135523) -->
<skip />
<string name="group_live_folders">"Live-Ordner"</string>
<string name="group_widgets">"Widget"</string>
<!-- no translation found for group_gadgets (7795333306847768497) -->
<skip />
<string name="group_wallpapers">"Hintergrund"</string>
<string name="add_folder">"Ordner"</string>
<string name="add_clock">"Uhr"</string>
<string name="add_photo_frame">"Bildrahmen"</string>
<string name="add_search">"Suchen"</string>
<string name="out_of_space">"Auf der Startseite ist kein Platz mehr vorhanden."</string>
<!-- no translation found for title_select_shortcut (2858897527672831763) -->
<skip />
<!-- no translation found for title_select_live_folder (441136484932944782) -->
<skip />
<string name="menu_add">"Hinzufügen"</string>
<string name="menu_wallpaper">"Hintergrund"</string>
<string name="menu_search">"Suchen"</string>
@ -50,4 +60,6 @@
<string name="permlab_write_settings">"Einstellungen und Shortcuts für Startseite schreiben"</string>
<string name="permdesc_write_settings">"Ermöglicht einer Anwendung, die Einstellungen und Shortcuts auf der Startseite zu ändern."</string>
<string name="search_hint">"Google-Suche"</string>
<!-- no translation found for gadget_error_text (7654995305187314446) -->
<skip />
</resources>

View File

@ -28,14 +28,24 @@
<string name="menu_item_add_item">"Añadir a pantalla de página principal"</string>
<string name="group_applications">"Aplicación"</string>
<string name="group_shortcuts">"Acceso directo"</string>
<!-- no translation found for group_search (5905328940867162196) -->
<skip />
<!-- no translation found for group_folder (236213814675135523) -->
<skip />
<string name="group_live_folders">"Carpeta activa"</string>
<string name="group_widgets">"Widget"</string>
<!-- no translation found for group_gadgets (7795333306847768497) -->
<skip />
<string name="group_wallpapers">"Papel tapiz"</string>
<string name="add_folder">"Carpeta"</string>
<string name="add_clock">"Reloj"</string>
<string name="add_photo_frame">"Picture frame"</string>
<string name="add_search">"Búsqueda de Google"</string>
<string name="out_of_space">"No queda espacio en esta pantalla de página principal."</string>
<!-- no translation found for title_select_shortcut (2858897527672831763) -->
<skip />
<!-- no translation found for title_select_live_folder (441136484932944782) -->
<skip />
<string name="menu_add">"Añadir"</string>
<string name="menu_wallpaper">"Papel tapiz"</string>
<string name="menu_search">"Búsqueda de Google"</string>
@ -50,4 +60,6 @@
<string name="permlab_write_settings">"escribir información de accesos directos y de configuración de la página principal"</string>
<string name="permdesc_write_settings">"Permite que una aplicación modifique la configuración y los accesos directos de la página principal."</string>
<string name="search_hint">"Búsqueda de Google"</string>
<!-- no translation found for gadget_error_text (7654995305187314446) -->
<skip />
</resources>

View File

@ -28,14 +28,24 @@
<string name="menu_item_add_item">"Ajouter à l\'écran d\'accueil"</string>
<string name="group_applications">"Application"</string>
<string name="group_shortcuts">"Raccourci"</string>
<!-- no translation found for group_search (5905328940867162196) -->
<skip />
<!-- no translation found for group_folder (236213814675135523) -->
<skip />
<string name="group_live_folders">"Dossier live"</string>
<string name="group_widgets">"Widget"</string>
<!-- no translation found for group_gadgets (7795333306847768497) -->
<skip />
<string name="group_wallpapers">"Arrière-plan"</string>
<string name="add_folder">"Dossier"</string>
<string name="add_clock">"Horloge"</string>
<string name="add_photo_frame">"Cadre d\'image"</string>
<string name="add_search">"Rechercher"</string>
<string name="out_of_space">"Plus d\'espace libre sur l\'écran Accueil."</string>
<!-- no translation found for title_select_shortcut (2858897527672831763) -->
<skip />
<!-- no translation found for title_select_live_folder (441136484932944782) -->
<skip />
<string name="menu_add">"Ajouter"</string>
<string name="menu_wallpaper">"Arrière-plan"</string>
<string name="menu_search">"Rechercher"</string>
@ -50,4 +60,6 @@
<string name="permlab_write_settings">"écrire les paramètres de la page d\'accueil et des raccourcis"</string>
<string name="permdesc_write_settings">"Permet à une application de modifier les paramètres et les raccourcis de la page d\'accueil."</string>
<string name="search_hint">"Recherche Google"</string>
<!-- no translation found for gadget_error_text (7654995305187314446) -->
<skip />
</resources>

View File

@ -28,14 +28,24 @@
<string name="menu_item_add_item">"Aggiungi a schermata Home"</string>
<string name="group_applications">"Applicazione"</string>
<string name="group_shortcuts">"Collegamento"</string>
<!-- no translation found for group_search (5905328940867162196) -->
<skip />
<!-- no translation found for group_folder (236213814675135523) -->
<skip />
<string name="group_live_folders">"Cartella dinamica"</string>
<string name="group_widgets">"Widget"</string>
<!-- no translation found for group_gadgets (7795333306847768497) -->
<skip />
<string name="group_wallpapers">"Sfondo"</string>
<string name="add_folder">"Cartella"</string>
<string name="add_clock">"Orologio"</string>
<string name="add_photo_frame">"Cornice immagini"</string>
<string name="add_search">"Ricerca"</string>
<string name="out_of_space">"Spazio nella schermata Home esaurito."</string>
<!-- no translation found for title_select_shortcut (2858897527672831763) -->
<skip />
<!-- no translation found for title_select_live_folder (441136484932944782) -->
<skip />
<string name="menu_add">"Aggiungi"</string>
<string name="menu_wallpaper">"Sfondo"</string>
<string name="menu_search">"Cerca"</string>
@ -50,4 +60,6 @@
<string name="permlab_write_settings">"creare impostazioni e collegamenti in Home"</string>
<string name="permdesc_write_settings">"Consente a un\'applicazione di modificare le impostazioni e i collegamenti in Home."</string>
<string name="search_hint">"Ricerca Google"</string>
<!-- no translation found for gadget_error_text (7654995305187314446) -->
<skip />
</resources>

View File

@ -28,14 +28,24 @@
<string name="menu_item_add_item">"ホーム画面に追加"</string>
<string name="group_applications">"アプリケーション"</string>
<string name="group_shortcuts">"ショートカット"</string>
<!-- no translation found for group_search (5905328940867162196) -->
<skip />
<!-- no translation found for group_folder (236213814675135523) -->
<skip />
<string name="group_live_folders">"ライブフォルダ"</string>
<string name="group_widgets">"ウィジェット"</string>
<!-- no translation found for group_gadgets (7795333306847768497) -->
<skip />
<string name="group_wallpapers">"壁紙"</string>
<string name="add_folder">"フォルダ"</string>
<string name="add_clock">"時計"</string>
<string name="add_photo_frame">"写真フレーム"</string>
<string name="add_search">"検索"</string>
<string name="out_of_space">"このホーム画面には空きスペースがありません。"</string>
<!-- no translation found for title_select_shortcut (2858897527672831763) -->
<skip />
<!-- no translation found for title_select_live_folder (441136484932944782) -->
<skip />
<string name="menu_add">"追加"</string>
<string name="menu_wallpaper">"壁紙"</string>
<string name="menu_search">"検索"</string>
@ -50,4 +60,6 @@
<string name="permlab_write_settings">"ホームの設定とショートカットの書き込み"</string>
<string name="permdesc_write_settings">"ホームの設定とショートカットの変更をアプリケーションに許可します。"</string>
<string name="search_hint">"Google検索"</string>
<!-- no translation found for gadget_error_text (7654995305187314446) -->
<skip />
</resources>

65
res/values-ko/strings.xml Normal file
View File

@ -0,0 +1,65 @@
<?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="application_name">"홈"</string>
<string name="folder_name">"폴더"</string>
<string name="chooser_wallpaper">"배경화면 선택"</string>
<string name="wallpaper_instructions">"배경화면 설정"</string>
<string name="pick_wallpaper">"배경화면 갤러리"</string>
<string name="activity_not_found">"전화기에 설치되어 있지 않은 응용프로그램입니다."</string>
<string name="rename_folder_label">"폴더 이름"</string>
<string name="rename_folder_title">"폴더 이름 바꾸기"</string>
<string name="rename_action">"확인"</string>
<string name="cancel_action">"취소"</string>
<string name="menu_item_add_item">"홈 화면에 추가"</string>
<string name="group_applications">"응용프로그램"</string>
<string name="group_shortcuts">"바로가기"</string>
<!-- no translation found for group_search (5905328940867162196) -->
<skip />
<!-- no translation found for group_folder (236213814675135523) -->
<skip />
<string name="group_live_folders">"라이브 폴더"</string>
<string name="group_widgets">"위젯"</string>
<!-- no translation found for group_gadgets (7795333306847768497) -->
<skip />
<string name="group_wallpapers">"배경화면"</string>
<string name="add_folder">"폴더"</string>
<string name="add_clock">"시계"</string>
<string name="add_photo_frame">"사진 프레임"</string>
<string name="add_search">"검색"</string>
<string name="out_of_space">"홈 화면에 더 이상 공간이 없습니다."</string>
<!-- no translation found for title_select_shortcut (2858897527672831763) -->
<skip />
<!-- no translation found for title_select_live_folder (441136484932944782) -->
<skip />
<string name="menu_add">"추가"</string>
<string name="menu_wallpaper">"배경화면"</string>
<string name="menu_search">"검색"</string>
<string name="menu_notifications">"알림"</string>
<string name="menu_settings">"설정"</string>
<string name="permlab_install_shortcut">"바로가기 설치"</string>
<string name="permdesc_install_shortcut">"응용프로그램이 사용자의 작업 없이 바로가기를 추가할 수 있도록 합니다."</string>
<string name="permlab_uninstall_shortcut">"바로가기 제거"</string>
<string name="permdesc_uninstall_shortcut">"응용프로그램이 사용자의 작업 없이 바로가기를 제거할 수 있도록 합니다."</string>
<string name="permlab_read_settings">"홈 설정 및 바로가기 읽기"</string>
<string name="permdesc_read_settings">"응용프로그램이 홈에 있는 설정 및 바로가기를 읽을 수 있습니다."</string>
<string name="permlab_write_settings">"홈 설정 및 바로가기 쓰기"</string>
<string name="permdesc_write_settings">"응용프로그램이 홈에 있는 설정 및 바로가기를 변경할 수 있습니다."</string>
<string name="search_hint">"Google 검색"</string>
<!-- no translation found for gadget_error_text (7654995305187314446) -->
<skip />
</resources>

65
res/values-nb/strings.xml Normal file
View File

@ -0,0 +1,65 @@
<?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="application_name">"Hjem"</string>
<string name="folder_name">"Mappe"</string>
<string name="chooser_wallpaper">"Velg bakgrunnsbilde fra"</string>
<string name="wallpaper_instructions">"Velg bakgrunnsbilde"</string>
<string name="pick_wallpaper">"Bildegalleri"</string>
<string name="activity_not_found">"Applikasjonen er ikke installert."</string>
<string name="rename_folder_label">"Mappenavn"</string>
<string name="rename_folder_title">"Gi nytt navn til mappe"</string>
<string name="rename_action">"OK"</string>
<string name="cancel_action">"Avbryt"</string>
<string name="menu_item_add_item">"Legg til skrivebord"</string>
<string name="group_applications">"Applikasjon"</string>
<string name="group_shortcuts">"Snarvei"</string>
<!-- no translation found for group_search (5905328940867162196) -->
<skip />
<!-- no translation found for group_folder (236213814675135523) -->
<skip />
<string name="group_live_folders">"Aktiv mappe"</string>
<string name="group_widgets">"Skrivebordselement"</string>
<!-- no translation found for group_gadgets (7795333306847768497) -->
<skip />
<string name="group_wallpapers">"Bakgrunnsbilde"</string>
<string name="add_folder">"Mappe"</string>
<string name="add_clock">"Klokke"</string>
<string name="add_photo_frame">"Bilderamme"</string>
<string name="add_search">"Søk"</string>
<string name="out_of_space">"Ikke nok plass på skrivebordet."</string>
<!-- no translation found for title_select_shortcut (2858897527672831763) -->
<skip />
<!-- no translation found for title_select_live_folder (441136484932944782) -->
<skip />
<string name="menu_add">"Legg til"</string>
<string name="menu_wallpaper">"Bakgrunnsbilde"</string>
<string name="menu_search">"Søk"</string>
<string name="menu_notifications">"Varslinger"</string>
<string name="menu_settings">"Innstillinger"</string>
<string name="permlab_install_shortcut">"shortcuts"</string>
<string name="permdesc_install_shortcut">"Allows an application to add shortcuts without user intervention."</string>
<string name="permlab_uninstall_shortcut">"uninstall shortcuts"</string>
<string name="permdesc_uninstall_shortcut">"Allows an application to remove shortcuts without user intervention."</string>
<string name="permlab_read_settings">"read Home settings and shortcuts"</string>
<string name="permdesc_read_settings">"Allows an application to read the settings and shortcuts in Home."</string>
<string name="permlab_write_settings">"write Home settings and shortcuts"</string>
<string name="permdesc_write_settings">"Allows an application to change the settings and shortcuts in Home."</string>
<string name="search_hint">"Google-søk"</string>
<!-- no translation found for gadget_error_text (7654995305187314446) -->
<skip />
</resources>

View File

@ -28,14 +28,24 @@
<string name="menu_item_add_item">"Toevoegen aan startpagina"</string>
<string name="group_applications">"Toepassing"</string>
<string name="group_shortcuts">"Snelkoppeling"</string>
<!-- no translation found for group_search (5905328940867162196) -->
<skip />
<!-- no translation found for group_folder (236213814675135523) -->
<skip />
<string name="group_live_folders">"Live map"</string>
<string name="group_widgets">"Widget"</string>
<!-- no translation found for group_gadgets (7795333306847768497) -->
<skip />
<string name="group_wallpapers">"Achtergrond"</string>
<string name="add_folder">"Map"</string>
<string name="add_clock">"Klok"</string>
<string name="add_photo_frame">"Fotolijstje"</string>
<string name="add_search">"Zoeken"</string>
<string name="out_of_space">"Er is geen ruimte meer op dit startscherm."</string>
<!-- no translation found for title_select_shortcut (2858897527672831763) -->
<skip />
<!-- no translation found for title_select_live_folder (441136484932944782) -->
<skip />
<string name="menu_add">"Toevoegen"</string>
<string name="menu_wallpaper">"Achtergrond"</string>
<string name="menu_search">"Zoeken"</string>
@ -50,4 +60,6 @@
<string name="permlab_write_settings">"instellingen en snelkoppelingen voor de startpagina schrijven"</string>
<string name="permdesc_write_settings">"Hiermee kan een toepassing de instellingen en snelkoppelingen op de startpagina wijzigen."</string>
<string name="search_hint">"Zoeken met Google"</string>
<!-- no translation found for gadget_error_text (7654995305187314446) -->
<skip />
</resources>

View File

@ -15,7 +15,7 @@
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="application_name">"Strona główna"</string>
<string name="application_name">"Sieć"</string>
<string name="folder_name">"Folder"</string>
<string name="chooser_wallpaper">"Wybierz tapetę"</string>
<string name="wallpaper_instructions">"Ustaw tapetę"</string>
@ -28,14 +28,24 @@
<string name="menu_item_add_item">"Dodaj do strony głównej"</string>
<string name="group_applications">"Aplikacja"</string>
<string name="group_shortcuts">"Skrót"</string>
<!-- no translation found for group_search (5905328940867162196) -->
<skip />
<!-- no translation found for group_folder (236213814675135523) -->
<skip />
<string name="group_live_folders">"Folder Live"</string>
<string name="group_widgets">"Widget"</string>
<!-- no translation found for group_gadgets (7795333306847768497) -->
<skip />
<string name="group_wallpapers">"Tapeta"</string>
<string name="add_folder">"Folder"</string>
<string name="add_clock">"Zegar"</string>
<string name="add_photo_frame">"Ramka obrazu"</string>
<string name="add_search">"Szukaj"</string>
<string name="out_of_space">"Brak miejsca na tej stronie głównej"</string>
<!-- no translation found for title_select_shortcut (2858897527672831763) -->
<skip />
<!-- no translation found for title_select_live_folder (441136484932944782) -->
<skip />
<string name="menu_add">"Dodaj"</string>
<string name="menu_wallpaper">"Tapeta"</string>
<string name="menu_search">"Szukaj"</string>
@ -50,4 +60,6 @@
<string name="permlab_write_settings">"zapisywanie ustawień i skrótów strony głównej"</string>
<string name="permdesc_write_settings">"Umożliwia aplikacji zmianę ustawień i skrótów strony głównej."</string>
<string name="search_hint">"Szukaj w Google"</string>
<!-- no translation found for gadget_error_text (7654995305187314446) -->
<skip />
</resources>

View File

@ -28,14 +28,24 @@
<string name="menu_item_add_item">"Добавление на главный экран"</string>
<string name="group_applications">"Приложение"</string>
<string name="group_shortcuts">"Ярлык"</string>
<!-- no translation found for group_search (5905328940867162196) -->
<skip />
<!-- no translation found for group_folder (236213814675135523) -->
<skip />
<string name="group_live_folders">"Динамическая папка"</string>
<string name="group_widgets">"Виджет"</string>
<!-- no translation found for group_gadgets (7795333306847768497) -->
<skip />
<string name="group_wallpapers">"Фоновый рисунок"</string>
<string name="add_folder">"Папка"</string>
<string name="add_clock">"Часы"</string>
<string name="add_photo_frame">"Рамка для картинки"</string>
<string name="add_search">"Поиск"</string>
<string name="out_of_space">"На главном экране больше нет места."</string>
<!-- no translation found for title_select_shortcut (2858897527672831763) -->
<skip />
<!-- no translation found for title_select_live_folder (441136484932944782) -->
<skip />
<string name="menu_add">"Добавить"</string>
<string name="menu_wallpaper">"Фоновый рисунок"</string>
<string name="menu_search">"Искать"</string>
@ -50,4 +60,6 @@
<string name="permlab_write_settings">"записывать ярлыки и настройки главного экрана"</string>
<string name="permdesc_write_settings">"Позволяет приложению изменять настройки и ярлыки на главном экране."</string>
<string name="search_hint">"Поиск Google"</string>
<!-- no translation found for gadget_error_text (7654995305187314446) -->
<skip />
</resources>

View File

@ -28,14 +28,24 @@
<string name="menu_item_add_item">"添加到“主页”屏幕"</string>
<string name="group_applications">"应用程序"</string>
<string name="group_shortcuts">"快捷键"</string>
<!-- no translation found for group_search (5905328940867162196) -->
<skip />
<!-- no translation found for group_folder (236213814675135523) -->
<skip />
<string name="group_live_folders">"活动的文件夹"</string>
<string name="group_widgets">"小工具"</string>
<!-- no translation found for group_gadgets (7795333306847768497) -->
<skip />
<string name="group_wallpapers">"壁纸"</string>
<string name="add_folder">"文件夹"</string>
<string name="add_clock">"时钟"</string>
<string name="add_photo_frame">"相框"</string>
<string name="add_search">"搜索"</string>
<string name="out_of_space">"该“主页”屏幕上没有多余空间。"</string>
<!-- no translation found for title_select_shortcut (2858897527672831763) -->
<skip />
<!-- no translation found for title_select_live_folder (441136484932944782) -->
<skip />
<string name="menu_add">"添加"</string>
<string name="menu_wallpaper">"壁纸"</string>
<string name="menu_search">"搜索"</string>
@ -50,4 +60,6 @@
<string name="permlab_write_settings">"写入“主页”设置和快捷键"</string>
<string name="permdesc_write_settings">"允许应用程序更改“主页”中的设置和快捷键。"</string>
<string name="search_hint">"Google 搜索"</string>
<!-- no translation found for gadget_error_text (7654995305187314446) -->
<skip />
</resources>

View File

@ -28,14 +28,24 @@
<string name="menu_item_add_item">"新增至首頁畫面"</string>
<string name="group_applications">"應用程式"</string>
<string name="group_shortcuts">"捷徑"</string>
<!-- no translation found for group_search (5905328940867162196) -->
<skip />
<!-- no translation found for group_folder (236213814675135523) -->
<skip />
<string name="group_live_folders">"使用中的資料夾"</string>
<string name="group_widgets">"Widget"</string>
<!-- no translation found for group_gadgets (7795333306847768497) -->
<skip />
<string name="group_wallpapers">"桌布"</string>
<string name="add_folder">"資料夾"</string>
<string name="add_clock">"時鐘"</string>
<string name="add_photo_frame">"相框"</string>
<string name="add_search">"搜尋"</string>
<string name="out_of_space">"首頁已無空間"</string>
<!-- no translation found for title_select_shortcut (2858897527672831763) -->
<skip />
<!-- no translation found for title_select_live_folder (441136484932944782) -->
<skip />
<string name="menu_add">"新增"</string>
<string name="menu_wallpaper">"桌布"</string>
<string name="menu_search">"搜尋"</string>
@ -50,4 +60,6 @@
<string name="permlab_write_settings">"寫入首頁設定和捷徑"</string>
<string name="permdesc_write_settings">"允許應用程式變更首頁中的設定和捷徑。"</string>
<string name="search_hint">"Google 搜尋"</string>
<!-- no translation found for gadget_error_text (7654995305187314446) -->
<skip />
</resources>

View File

@ -22,4 +22,6 @@
<color name="grid_dark_background">#EB191919</color>
<color name="bubble_dark_background">#B2191919</color>
<color name="delete_color_filter">#A5FF0000</color>
<color name="gadget_error_color">#fccc</color>
</resources>

View File

@ -52,9 +52,16 @@
<string name="group_applications">Application</string>
<!-- Options in "Add to Home" dialog box; Title of the group containing the list of all shortcuts -->
<string name="group_shortcuts">Shortcut</string>
<!-- Options in "Add to Home" dialog box; Title of the search gadget -->
<string name="group_search">Search</string>
<!-- Options in "Add to Home" dialog box; Title of the folder gadget -->
<string name="group_folder">Folder</string>
<!-- Options in "Add to Home" dialog box; Title of the group containing the list of all live folders -->
<string name="group_live_folders">Live folder</string>
<!-- Options in "Add to Home" dialog box; Title of the group containing the list of all widgets -->
<string name="group_widgets">Widget</string>
<!-- Options in "Add to Home" dialog box; Title of the group containing the list of all gadgets -->
<string name="group_gadgets">Gadget</string>
<!-- Options in "Add to Home" dialog box; Title of the group containing the list of apps that can set the wallpaper-->
<string name="group_wallpapers">Wallpaper</string>
<!-- Options in "Add to Home" dialog box; Name of the Folder widget-->
@ -68,6 +75,11 @@
<!-- Error message when user has filled a home screen, possibly not used -->
<string name="out_of_space">No more room on this Home screen.</string>
<!-- Title of dialog when user is selecting shortcut to add to homescreen -->
<string name="title_select_shortcut">Select shortcut</string>
<!-- Title of dialog when user is selecting live folder to add to homescreen -->
<string name="title_select_live_folder">Select live folder</string>
<!-- Menus items: -->
<skip />
<!-- Verb, menu item used to add an item on the desktop -->
@ -101,5 +113,8 @@
This translation SHOULD MATCH the string "search_hint" which is found in
GoogleSearch/res/values/strings.xml -->
<string name="search_hint">Google Search</string>
<!-- Text to show user in place of a gadget when we can't display it properly -->
<string name="gadget_error_text">Problem loading gadget</string>
</resources>

View File

@ -16,456 +16,111 @@
package com.android.launcher;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.BaseExpandableListAdapter;
import android.graphics.drawable.Drawable;
import android.provider.LiveFolders;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Shows a list of all the items that can be added to the workspace.
* Adapter showing the types of items that can be added to a {@link Workspace}.
*/
public final class AddAdapter extends BaseExpandableListAdapter {
private static final int GROUP_APPLICATIONS = 0;
private static final int GROUP_SHORTCUTS = 1;
private static final int GROUP_WIDGETS = 2;
private static final int GROUP_LIVE_FOLDERS = 3;
private static final int GROUP_WALLPAPERS = 4;
private final Intent mCreateShortcutIntent;
private final Intent mCreateLiveFolderIntent;
private Intent mSetWallpaperIntent;
public class AddAdapter extends BaseAdapter {
private final Launcher mLauncher;
private final LayoutInflater mInflater;
private Launcher mLauncher;
private Group[] mGroups;
/**
* Abstract class representing one thing that can be added
*/
public abstract class AddAction implements Runnable {
protected final Context mContext;
AddAction(Context context) {
mContext = context;
}
Drawable getIcon(int resource) {
return mContext.getResources().getDrawable(resource);
}
public abstract void bindView(View v);
}
/**
* Class representing an action that will create set the wallpaper.
*/
public class SetWallpaperAction extends CreateShortcutAction {
SetWallpaperAction(Context context, ResolveInfo info) {
super(context, info);
}
public void run() {
Intent intent = new Intent(mSetWallpaperIntent);
ActivityInfo activityInfo = mInfo.activityInfo;
intent.setComponent(new ComponentName(activityInfo.applicationInfo.packageName,
activityInfo.name));
mLauncher.startActivity(intent);
}
}
private final ArrayList<ListItem> mItems = new ArrayList<ListItem>();
public static final int ITEM_APPLICATION = 0;
public static final int ITEM_SHORTCUT = 1;
public static final int ITEM_SEARCH = 2;
public static final int ITEM_GADGET = 3;
public static final int ITEM_LIVE_FOLDER = 4;
public static final int ITEM_FOLDER = 5;
public static final int ITEM_WALLPAPER = 6;
/**
* Class representing an action that will create a specific type
* of shortcut
* Specific item in our list.
*/
public class CreateShortcutAction extends AddAction {
public class ListItem {
public final CharSequence text;
public final Drawable image;
public final int actionTag;
ResolveInfo mInfo;
private CharSequence mLabel;
private Drawable mIcon;
CreateShortcutAction(Context context, ResolveInfo info) {
super(context);
mInfo = info;
}
@Override
public void bindView(View view) {
ResolveInfo info = mInfo;
TextView text = (TextView) view;
PackageManager pm = mLauncher.getPackageManager();
if (mLabel == null) {
mLabel = info.loadLabel(pm);
if (mLabel == null) {
mLabel = info.activityInfo.name;
}
public ListItem(Resources res, int textResourceId, int imageResourceId, int actionTag) {
text = res.getString(textResourceId);
if (imageResourceId != -1) {
image = res.getDrawable(imageResourceId);
} else {
image = null;
}
if (mIcon == null) {
mIcon = Utilities.createIconThumbnail(info.loadIcon(pm), mContext);
}
text.setText(mLabel);
text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
}
public void run() {
Intent intent = new Intent(mCreateShortcutIntent);
ActivityInfo activityInfo = mInfo.activityInfo;
intent.setComponent(new ComponentName(activityInfo.applicationInfo.packageName,
activityInfo.name));
mLauncher.addShortcut(intent);
}
}
/**
* Class representing an action that will create a specific type
* of live folder
*/
public class CreateLiveFolderAction extends CreateShortcutAction {
CreateLiveFolderAction(Context context, ResolveInfo info) {
super(context, info);
}
@Override
public void run() {
Intent intent = new Intent(mCreateLiveFolderIntent);
ActivityInfo activityInfo = mInfo.activityInfo;
intent.setComponent(new ComponentName(activityInfo.applicationInfo.packageName,
activityInfo.name));
mLauncher.addLiveFolder(intent);
}
}
/**
* Class representing an action that will add a folder
*/
public class CreateFolderAction extends AddAction {
private Drawable mIcon;
CreateFolderAction(Context context) {
super(context);
}
@Override
public void bindView(View view) {
TextView text = (TextView) view;
text.setText(R.string.add_folder);
if (mIcon == null) mIcon = getIcon(R.drawable.ic_launcher_folder);
text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
}
public void run() {
mLauncher.addFolder();
}
}
/**
* Class representing an action that will add a folder
*/
public class CreateClockAction extends AddAction {
CreateClockAction(Context context) {
super(context);
}
@Override
public void bindView(View view) {
TextView text = (TextView) view;
text.setText(R.string.add_clock);
Drawable icon = getIcon(R.drawable.ic_launcher_alarmclock);
text.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
}
public void run() {
mLauncher.addClock();
}
}
/**
* Class representing an action that will add a PhotoFrame
*/
public class CreatePhotoFrameAction extends AddAction {
private Drawable mIcon;
CreatePhotoFrameAction(Context context) {
super(context);
}
@Override
public void bindView(View view) {
TextView text = (TextView) view;
text.setText(R.string.add_photo_frame);
if (mIcon == null) mIcon = getIcon(R.drawable.ic_launcher_gallery);
text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
}
public void run() {
mLauncher.getPhotoForPhotoFrame();
}
}
/**
* Class representing an action that will add a Search widget
*/
public class CreateSearchAction extends AddAction {
private Drawable mIcon;
CreateSearchAction(Context context) {
super(context);
}
@Override
public void bindView(View view) {
TextView text = (TextView) view;
text.setText(R.string.add_search);
if (mIcon == null) mIcon = getIcon(R.drawable.ic_search_gadget);
text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
}
public void run() {
mLauncher.addSearch();
this.actionTag = actionTag;
}
}
private class Group {
private String mName;
private ArrayList<AddAction> mList;
Group(String name) {
mName = name;
mList = new ArrayList<AddAction>();
}
void add(AddAction action) {
mList.add(action);
}
int size() {
return mList.size();
}
String getName() {
return mName;
}
void run(int position) {
mList.get(position).run();
}
void bindView(int childPosition, View view) {
mList.get(childPosition).bindView(view);
}
public Object get(int childPosition) {
return mList.get(childPosition);
}
}
private class ApplicationsGroup extends Group {
private final Launcher mLauncher;
private final ArrayList<ApplicationInfo> mApplications;
ApplicationsGroup(Launcher launcher, String name) {
super(name);
mLauncher = launcher;
mApplications = Launcher.getModel().getApplications();
}
@Override
int size() {
return mApplications == null ? 0 : mApplications.size();
}
@Override
void add(AddAction action) {
}
@Override
void run(int position) {
final ApplicationInfo info = mApplications.get(position);
mLauncher.addApplicationShortcut(info);
}
@Override
void bindView(int childPosition, View view) {
TextView text = (TextView) view.findViewById(R.id.title);
final ApplicationInfo info = mApplications.get(childPosition);
text.setText(info.title);
if (!info.filtered) {
info.icon = Utilities.createIconThumbnail(info.icon, mLauncher);
info.filtered = true;
}
text.setCompoundDrawablesWithIntrinsicBounds(info.icon, null, null, null);
}
@Override
public Object get(int childPosition) {
return mApplications.get(childPosition);
}
}
public AddAdapter(Launcher launcher, boolean forFolder) {
mCreateShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
mCreateShortcutIntent.setComponent(null);
mCreateLiveFolderIntent = new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER);
mCreateLiveFolderIntent.setComponent(null);
mSetWallpaperIntent = new Intent(Intent.ACTION_SET_WALLPAPER);
mSetWallpaperIntent.setComponent(null);
public AddAdapter(Launcher launcher) {
super();
mLauncher = launcher;
mInflater = (LayoutInflater) launcher.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mInflater = (LayoutInflater) mLauncher.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Create default actions
Resources res = launcher.getResources();
mItems.add(new ListItem(res, R.string.group_applications,
R.drawable.ic_launcher_application, ITEM_APPLICATION));
mItems.add(new ListItem(res, R.string.group_shortcuts,
R.drawable.ic_launcher_empty, ITEM_SHORTCUT));
mItems.add(new ListItem(res, R.string.group_search,
R.drawable.ic_search_gadget, ITEM_SEARCH));
mItems.add(new ListItem(res, R.string.group_gadgets,
R.drawable.ic_launcher_gadget, ITEM_GADGET));
mItems.add(new ListItem(res, R.string.group_live_folders,
R.drawable.ic_launcher_empty, ITEM_LIVE_FOLDER));
mItems.add(new ListItem(res, R.string.group_folder,
R.drawable.ic_launcher_folder, ITEM_FOLDER));
mItems.add(new ListItem(res, R.string.group_wallpapers,
R.drawable.ic_launcher_gallery, ITEM_WALLPAPER));
mGroups = new Group[forFolder ? 2 : 5];
final Group[] groups = mGroups;
groups[GROUP_APPLICATIONS] = new ApplicationsGroup(mLauncher,
mLauncher.getString(R.string.group_applications));
groups[GROUP_SHORTCUTS] = new Group(mLauncher.getString(R.string.group_shortcuts));
groups[GROUP_LIVE_FOLDERS] = new Group(mLauncher.getString(R.string.group_live_folders));
}
if (!forFolder) {
groups[GROUP_WALLPAPERS] = new Group(mLauncher.getString(R.string.group_wallpapers));
groups[GROUP_SHORTCUTS].add(new CreateFolderAction(launcher));
groups[GROUP_WIDGETS] = new Group(mLauncher.getString(R.string.group_widgets));
final Group widgets = groups[GROUP_WIDGETS];
widgets.add(new CreateClockAction(launcher));
widgets.add(new CreatePhotoFrameAction(launcher));
widgets.add(new CreateSearchAction(launcher));
public View getView(int position, View convertView, ViewGroup parent) {
ListItem item = (ListItem) getItem(position);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.add_list_item, parent, false);
}
PackageManager packageManager = launcher.getPackageManager();
List<ResolveInfo> list = findTargetsForIntent(mCreateShortcutIntent, packageManager);
if (list != null && list.size() > 0) {
int count = list.size();
final Group shortcuts = groups[GROUP_SHORTCUTS];
for (int i = 0; i < count; i++) {
ResolveInfo resolveInfo = list.get(i);
shortcuts.add(new CreateShortcutAction(launcher, resolveInfo));
}
}
list = findTargetsForIntent(mCreateLiveFolderIntent, packageManager);
if (list != null && list.size() > 0) {
int count = list.size();
final Group shortcuts = groups[GROUP_LIVE_FOLDERS];
for (int i = 0; i < count; i++) {
ResolveInfo resolveInfo = list.get(i);
shortcuts.add(new CreateLiveFolderAction(launcher, resolveInfo));
}
}
list = findTargetsForIntent(mSetWallpaperIntent, packageManager);
if (list != null && list.size() > 0) {
int count = list.size();
final Group shortcuts = groups[GROUP_WALLPAPERS];
for (int i = 0; i < count; i++) {
ResolveInfo resolveInfo = list.get(i);
shortcuts.add(new SetWallpaperAction(launcher, resolveInfo));
}
}
TextView textView = (TextView) convertView;
textView.setTag(item);
textView.setText(item.text);
textView.setCompoundDrawablesWithIntrinsicBounds(item.image, null, null, null);
return convertView;
}
private List<ResolveInfo> findTargetsForIntent(Intent intent, PackageManager packageManager) {
List<ResolveInfo> list = packageManager.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
if (list != null) {
int count = list.size();
if (count > 1) {
// Only display the first matches that are either of equal
// priority or have asked to be default options.
ResolveInfo firstInfo = list.get(0);
for (int i=1; i<count; i++) {
ResolveInfo resolveInfo = list.get(i);
if (firstInfo.priority != resolveInfo.priority ||
firstInfo.isDefault != resolveInfo.isDefault) {
while (i < count) {
list.remove(i);
count--;
}
}
}
Collections.sort(list, new ResolveInfo.DisplayNameComparator(packageManager));
}
}
return list;
public int getCount() {
return mItems.size();
}
public int getGroupCount() {
return mGroups.length;
public Object getItem(int position) {
return mItems.get(position);
}
public int getChildrenCount(int groupPosition) {
return mGroups[groupPosition].size();
}
public Object getGroup(int groupPosition) {
return mGroups[groupPosition].getName();
}
public Object getChild(int groupPosition, int childPosition) {
return mGroups[groupPosition].get(childPosition);
}
public long getGroupId(int groupPosition) {
return groupPosition;
}
public long getChildId(int groupPosition, int childPosition) {
return (groupPosition << 16) | childPosition;
}
public boolean hasStableIds() {
return true;
}
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
View view;
if (convertView == null) {
view = mInflater.inflate(R.layout.create_shortcut_group_item, parent, false);
} else {
view = convertView;
}
((TextView) view).setText(mGroups[groupPosition].getName());
return view;
}
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
View convertView, ViewGroup parent) {
View view;
if (convertView == null) {
view = mInflater.inflate(R.layout.create_shortcut_list_item, parent, false);
} else {
view = convertView;
}
mGroups[groupPosition].bindView(childPosition, view);
return view;
}
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
void performAction(int groupPosition, int childPosition) {
mGroups[groupPosition].run(childPosition);
public long getItemId(int position) {
return position;
}
}

View File

@ -40,6 +40,9 @@ public class BubbleTextView extends TextView {
private boolean mBackgroundSizeChanged;
private Drawable mBackground;
private float mCornerRadius;
private float mPaddingH;
private float mPaddingV;
public BubbleTextView(Context context) {
super(context);
@ -64,6 +67,12 @@ public class BubbleTextView extends TextView {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(getContext().getResources().getColor(R.color.bubble_dark_background));
final float scale = getContext().getResources().getDisplayMetrics().density;
mCornerRadius = CORNER_RADIUS * scale;
mPaddingH = PADDING_H * scale;
//noinspection PointlessArithmeticExpression
mPaddingV = PADDING_V * scale;
}
@Override
@ -114,11 +123,11 @@ public class BubbleTextView extends TextView {
final int left = getCompoundPaddingLeft();
final int top = getExtendedPaddingTop();
rect.set(left + layout.getLineLeft(0) - PADDING_H,
top + layout.getLineTop(0) - PADDING_V,
Math.min(left + layout.getLineRight(0) + PADDING_H, mScrollX + mRight - mLeft),
top + layout.getLineBottom(0) + PADDING_V);
canvas.drawRoundRect(rect, CORNER_RADIUS, CORNER_RADIUS, mPaint);
rect.set(left + layout.getLineLeft(0) - mPaddingH,
top + layout.getLineTop(0) - mPaddingV,
Math.min(left + layout.getLineRight(0) + mPaddingH, mScrollX + mRight - mLeft),
top + layout.getLineBottom(0) + mPaddingV);
canvas.drawRoundRect(rect, mCornerRadius, mCornerRadius, mPaint);
super.draw(canvas);
}

View File

@ -56,6 +56,8 @@ public class CellLayout extends ViewGroup {
private RectF mDragRect = new RectF();
private boolean mDirtyTag;
public CellLayout(Context context) {
this(context, null);
}
@ -157,6 +159,7 @@ public class CellLayout extends ViewGroup {
cellInfo.spanY = lp.cellVSpan;
cellInfo.valid = true;
found = true;
mDirtyTag = false;
break;
}
}
@ -181,10 +184,12 @@ public class CellLayout extends ViewGroup {
cellInfo.valid = cellXY[0] >= 0 && cellXY[1] >= 0 && cellXY[0] < xCount &&
cellXY[1] < yCount && !occupied[cellXY[0]][cellXY[1]];
if (cellInfo.valid) {
findIntersectingVacantCells(cellInfo, cellXY[0], cellXY[1],
xCount, yCount, occupied);
}
// Instead of finding the interesting vacant cells here, wait until a
// caller invokes getTag() to retrieve the result. Finding the vacant
// cells is a bit expensive and can generate many new objects, it's
// therefore better to defer it until we know we actually need it.
mDirtyTag = true;
}
setTag(cellInfo);
} else if (action == MotionEvent.ACTION_UP) {
@ -194,12 +199,31 @@ public class CellLayout extends ViewGroup {
cellInfo.spanX = 0;
cellInfo.spanY = 0;
cellInfo.valid = false;
mDirtyTag = false;
setTag(cellInfo);
}
return false;
}
@Override
public CellInfo getTag() {
final CellInfo info = (CellInfo) super.getTag();
if (mDirtyTag && info.valid) {
final boolean portrait = mPortrait;
final int xCount = portrait ? mShortAxisCells : mLongAxisCells;
final int yCount = portrait ? mLongAxisCells : mShortAxisCells;
final boolean[][] occupied = mOccupied;
findOccupiedCells(xCount, yCount, occupied);
findIntersectingVacantCells(info, info.cellX, info.cellY, xCount, yCount, occupied);
mDirtyTag = false;
}
return info;
}
private static void findIntersectingVacantCells(CellInfo cellInfo, int x, int y,
int xCount, int yCount, boolean[][] occupied) {
@ -207,14 +231,15 @@ public class CellLayout extends ViewGroup {
cellInfo.maxVacantSpanXSpanY = Integer.MIN_VALUE;
cellInfo.maxVacantSpanY = Integer.MIN_VALUE;
cellInfo.maxVacantSpanYSpanX = Integer.MIN_VALUE;
cellInfo.vacantCells = new ArrayList<CellInfo.VacantCell>();
cellInfo.clearVacantCells();
if (occupied[x][y]) {
return;
}
Rect current = new Rect(x, y, x, y);
findVacantCell(current, xCount, yCount, occupied, cellInfo);
cellInfo.current.set(x, y, x, y);
findVacantCell(cellInfo.current, xCount, yCount, occupied, cellInfo);
}
private static void findVacantCell(Rect current, int xCount, int yCount, boolean[][] occupied,
@ -256,7 +281,7 @@ public class CellLayout extends ViewGroup {
}
private static void addVacantCell(Rect current, CellInfo cellInfo) {
CellInfo.VacantCell cell = new CellInfo.VacantCell();
CellInfo.VacantCell cell = CellInfo.VacantCell.acquire();
cell.cellX = current.left;
cell.cellY = current.top;
cell.spanX = current.right - current.left + 1;
@ -317,10 +342,9 @@ public class CellLayout extends ViewGroup {
cellInfo.maxVacantSpanXSpanY = Integer.MIN_VALUE;
cellInfo.maxVacantSpanY = Integer.MIN_VALUE;
cellInfo.maxVacantSpanYSpanX = Integer.MIN_VALUE;
cellInfo.vacantCells = new ArrayList<CellInfo.VacantCell>();
cellInfo.screen = mCellInfo.screen;
Rect current = new Rect();
Rect current = cellInfo.current;
for (int x = 0; x < xCount; x++) {
for (int y = 0; y < yCount; y++) {
@ -634,6 +658,26 @@ public class CellLayout extends ViewGroup {
dragRect.set(x, y, x + width, y + height);
}
/**
* Computes the required horizontal and vertical cell spans to always
* fit the given rectangle.
*
* @param width Width in pixels
* @param height Height in pixels
* @param cellInfo {@link CellInfo} to fill with calculated span parameters
*/
public void rectToCell(int width, int height, CellInfo cellInfo) {
// Always assume we're working with the smallest span to make sure we
// reserve enough space in both orientations.
int actualWidth = mCellWidth + mWidthGap;
int actualHeight = mCellHeight + mHeightGap;
int smallerSize = Math.min(actualWidth, actualHeight);
// Always round up to next largest cell
cellInfo.spanX = (width + smallerSize) / smallerSize;
cellInfo.spanY = (height + smallerSize) / smallerSize;
}
/**
* Find the first vacant cell, if there is one.
@ -811,12 +855,54 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
}
static final class CellInfo implements ContextMenu.ContextMenuInfo {
/**
* See View.AttachInfo.InvalidateInfo for futher explanations about
* the recycling mechanism. In this case, we recycle the vacant cells
* instances because up to several hundreds can be instanciated when
* the user long presses an empty cell.
*/
static final class VacantCell {
int cellX;
int cellY;
int spanX;
int spanY;
// We can create up to 523 vacant cells on a 4x4 grid, 100 seems
// like a reasonable compromise given the size of a VacantCell and
// the fact that the user is not likely to touch an empty 4x4 grid
// very often
private static final int POOL_LIMIT = 100;
private static final Object sLock = new Object();
private static int sAcquiredCount = 0;
private static VacantCell sRoot;
private VacantCell next;
static VacantCell acquire() {
synchronized (sLock) {
if (sRoot == null) {
return new VacantCell();
}
VacantCell info = sRoot;
sRoot = info.next;
sAcquiredCount--;
return info;
}
}
void release() {
synchronized (sLock) {
if (sAcquiredCount < POOL_LIMIT) {
sAcquiredCount++;
next = sRoot;
sRoot = this;
}
}
}
@Override
public String toString() {
return "VacantCell[x=" + cellX + ", y=" + cellY + ", spanX=" + spanX +
@ -832,17 +918,27 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
int screen;
boolean valid;
ArrayList<VacantCell> vacantCells;
final ArrayList<VacantCell> vacantCells = new ArrayList<VacantCell>(VacantCell.POOL_LIMIT);
int maxVacantSpanX;
int maxVacantSpanXSpanY;
int maxVacantSpanY;
int maxVacantSpanYSpanX;
final Rect current = new Rect();
private void clearVacantCells() {
final ArrayList<VacantCell> list = vacantCells;
final int count = list.size();
for (int i = 0; i < count; i++) list.get(i).release();
list.clear();
}
void findVacantCellsFromOccupied(boolean[] occupied, int xCount, int yCount) {
if (cellX < 0 || cellY < 0) {
maxVacantSpanX = maxVacantSpanXSpanY = Integer.MIN_VALUE;
maxVacantSpanY = maxVacantSpanYSpanX = Integer.MIN_VALUE;
vacantCells = new ArrayList<VacantCell>();
clearVacantCells();
return;
}
@ -855,26 +951,40 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
CellLayout.findIntersectingVacantCells(this, cellX, cellY, xCount, yCount, unflattened);
}
/**
* This method can be called only once! Calling #findVacantCellsFromOccupied will
* restore the ability to call this method.
*
* Finds the upper-left coordinate of the first rectangle in the grid that can
* hold a cell of the specified dimensions.
*
* @param cellXY The array that will contain the position of a vacant cell if such a cell
* can be found.
* @param spanX The horizontal span of the cell we want to find.
* @param spanY The vertical span of the cell we want to find.
*
* @return True if a vacant cell of the specified dimension was found, false otherwise.
*/
boolean findCellForSpan(int[] cellXY, int spanX, int spanY) {
if (vacantCells == null) {
return false;
}
final ArrayList<VacantCell> list = vacantCells;
final int count = list.size();
boolean found = false;
if (this.spanX >= spanX && this.spanY >= spanY) {
cellXY[0] = cellX;
cellXY[1] = cellY;
return true;
found = true;
}
final ArrayList<VacantCell> list = vacantCells;
final int count = list.size();
// Look for an exact match first
for (int i = 0; i < count; i++) {
VacantCell cell = list.get(i);
if (cell.spanX == spanX && cell.spanY == spanY) {
cellXY[0] = cell.cellX;
cellXY[1] = cell.cellY;
return true;
found = true;
break;
}
}
@ -884,11 +994,14 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
if (cell.spanX >= spanX && cell.spanY >= spanY) {
cellXY[0] = cell.cellX;
cellXY[1] = cell.cellY;
return true;
found = true;
break;
}
}
return false;
clearVacantCells();
return found;
}
@Override

View File

@ -97,6 +97,12 @@ public class DeleteZone extends ImageView implements DropTarget, DragController.
final UserFolderInfo userFolderInfo = (UserFolderInfo)item;
LauncherModel.deleteUserFolderContentsFromDatabase(mLauncher, userFolderInfo);
model.removeUserFolder(userFolderInfo);
} else if (item instanceof LauncherGadgetInfo) {
final LauncherGadgetInfo launcherGadgetInfo = (LauncherGadgetInfo)item;
final LauncherGadgetHost gadgetHost = mLauncher.getGadgetHost();
if (gadgetHost != null) {
gadgetHost.deleteGadgetId(launcherGadgetInfo.gadgetId);
}
}
LauncherModel.deleteItemFromDatabase(mLauncher, item);
}

View File

@ -320,40 +320,33 @@ public class DragLayer extends FrameLayout implements DragController {
break;
case MotionEvent.ACTION_MOVE:
if (Launcher.sOpenGlEnabled) {
mLastMotionX = x;
mLastMotionY = y;
final int scrollX = mScrollX;
final int scrollY = mScrollY;
invalidate();
} else {
final int scrollX = mScrollX;
final int scrollY = mScrollY;
final float touchX = mTouchOffsetX;
final float touchY = mTouchOffsetY;
final float touchX = mTouchOffsetX;
final float touchY = mTouchOffsetY;
final int offsetX = mBitmapOffsetX;
final int offsetY = mBitmapOffsetY;
final int offsetX = mBitmapOffsetX;
final int offsetY = mBitmapOffsetY;
int left = (int) (scrollX + mLastMotionX - touchX - offsetX);
int top = (int) (scrollY + mLastMotionY - touchY - offsetY);
int left = (int) (scrollX + mLastMotionX - touchX - offsetX);
int top = (int) (scrollY + mLastMotionY - touchY - offsetY);
final Bitmap dragBitmap = mDragBitmap;
final int width = dragBitmap.getWidth();
final int height = dragBitmap.getHeight();
final Bitmap dragBitmap = mDragBitmap;
final int width = dragBitmap.getWidth();
final int height = dragBitmap.getHeight();
final Rect rect = mRect;
rect.set(left - 1, top - 1, left + width + 1, top + height + 1);
final Rect rect = mRect;
rect.set(left - 1, top - 1, left + width + 1, top + height + 1);
mLastMotionX = x;
mLastMotionY = y;
mLastMotionX = x;
mLastMotionY = y;
left = (int) (scrollX + x - touchX - offsetX);
top = (int) (scrollY + y - touchY - offsetY);
left = (int) (scrollX + x - touchX - offsetX);
top = (int) (scrollY + y - touchY - offsetY);
rect.union(left - 1, top - 1, left + width + 1, top + height + 1);
invalidate(rect);
}
rect.union(left - 1, top - 1, left + width + 1, top + height + 1);
invalidate(rect);
final int[] coordinates = mDropCoordinates;
DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates);

View File

@ -38,10 +38,8 @@ class ItemInfo {
/**
* One of {@link LauncherSettings.Favorites#ITEM_TYPE_APPLICATION},
* {@link LauncherSettings.Favorites#ITEM_TYPE_SHORTCUT},
* {@link LauncherSettings.Favorites#ITEM_TYPE_USER_FOLDER},
* {@link LauncherSettings.Favorites#ITEM_TYPE_WIDGET_CLOCK},
* {@link LauncherSettings.Favorites#ITEM_TYPE_WIDGET_SEARCH} or
* {@link LauncherSettings.Favorites#ITEM_TYPE_WIDGET_PHOTO_FRAME},
* {@link LauncherSettings.Favorites#ITEM_TYPE_USER_FOLDER}, or
* {@link LauncherSettings.Favorites#ITEM_TYPE_GADGET}.
*/
int itemType;

View File

@ -24,16 +24,21 @@ import android.app.SearchManager;
import android.app.StatusBarManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.gadget.GadgetInfo;
import android.gadget.GadgetManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
@ -64,16 +69,15 @@ import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.View.OnLongClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.GridView;
import android.widget.SlidingDrawer;
import android.app.IWallpaperService;
import com.android.internal.widget.SlidingDrawer;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@ -86,8 +90,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private static final boolean PROFILE_STARTUP = false;
private static final boolean DEBUG_USER_INTERFACE = false;
private static final boolean REMOVE_SHORTCUT_ON_PACKAGE_REMOVE = false;
private static final int WALLPAPER_SCREENS_SPAN = 2;
private static final int MENU_GROUP_ADD = 1;
@ -98,9 +100,12 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private static final int MENU_SETTINGS = MENU_NOTIFICATIONS + 1;
private static final int REQUEST_CREATE_SHORTCUT = 1;
private static final int REQUEST_CHOOSE_PHOTO = 2;
private static final int REQUEST_UPDATE_PHOTO = 3;
private static final int REQUEST_CREATE_LIVE_FOLDER = 4;
private static final int REQUEST_CREATE_GADGET = 5;
private static final int REQUEST_PICK_APPLICATION = 6;
private static final int REQUEST_PICK_SHORTCUT = 7;
private static final int REQUEST_PICK_LIVE_FOLDER = 8;
private static final int REQUEST_PICK_GADGET = 9;
static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";
@ -148,10 +153,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private static Bitmap sWallpaper;
// Indicates whether the OpenGL pipeline was enabled, either through
// USE_OPENGL_BY_DEFAULT or the system property launcher.opengl
static boolean sOpenGlEnabled;
private static final Object sLock = new Object();
private static int sScreen = DEFAULT_SCREN;
@ -164,7 +165,12 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private DragLayer mDragLayer;
private Workspace mWorkspace;
private GadgetManager mGadgetManager;
private LauncherGadgetHost mGadgetHost;
private static final int GADGET_HOST_ID = 1024;
private CellLayout.CellInfo mAddItemCellInfo;
private CellLayout.CellInfo mMenuAddInfo;
private final int[] mCellCoordinates = new int[2];
@ -189,6 +195,11 @@ public final class Launcher extends Activity implements View.OnClickListener, On
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mInflater = getLayoutInflater();
mGadgetManager = GadgetManager.getInstance(this);
mGadgetHost = new LauncherGadgetHost(this, GADGET_HOST_ID);
// TODO: figure out if this is first launch and correctly clear GadgetHost database
if (PROFILE_STARTUP) {
android.os.Debug.startMethodTracing("/sdcard/launcher");
@ -223,6 +234,18 @@ public final class Launcher extends Activity implements View.OnClickListener, On
Selection.setSelection(mDefaultKeySsb, 0);
}
@Override
protected void onStart() {
super.onStart();
mGadgetHost.startListening();
}
@Override
protected void onStop() {
super.onStop();
mGadgetHost.stopListening();
}
private void checkForLocaleChange() {
final SharedPreferences preferences = getSharedPreferences(PREFERENCES, MODE_PRIVATE);
final Configuration configuration = getResources().getConfiguration();
@ -283,20 +306,42 @@ public final class Launcher extends Activity implements View.OnClickListener, On
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// The pattern used here is that a user PICKs a specific application,
// which, depending on the target, might need to CREATE the actual target.
// For example, the user would PICK_SHORTCUT for "Music playlist", and we
// launch over to the Music app to actually CREATE_SHORTCUT.
if (resultCode == RESULT_OK && mAddItemCellInfo != null) {
switch (requestCode) {
case REQUEST_PICK_APPLICATION:
completeAddApplication(this, data, mAddItemCellInfo);
break;
case REQUEST_PICK_SHORTCUT:
addShortcut(data);
break;
case REQUEST_CREATE_SHORTCUT:
completeAddShortcut(data, mAddItemCellInfo, !mDesktopLocked);
break;
case REQUEST_CHOOSE_PHOTO:
completeAddPhotoFrame(data, mAddItemCellInfo);
break;
case REQUEST_UPDATE_PHOTO:
completeUpdatePhotoFrame(data, mAddItemCellInfo);
case REQUEST_PICK_LIVE_FOLDER:
addLiveFolder(data);
break;
case REQUEST_CREATE_LIVE_FOLDER:
completeAddLiveFolder(data, mAddItemCellInfo, !mDesktopLocked);
break;
case REQUEST_PICK_GADGET:
addGadget(data);
break;
case REQUEST_CREATE_GADGET:
completeAddGadget(data, mAddItemCellInfo, !mDesktopLocked);
break;
}
} else if (requestCode == REQUEST_PICK_GADGET &&
resultCode == RESULT_CANCELED && data != null) {
// Clean up the gadgetId if we canceled
int gadgetId = data.getIntExtra(GadgetManager.EXTRA_GADGET_ID, -1);
if (gadgetId != -1) {
mGadgetHost.deleteGadgetId(gadgetId);
}
}
mWaitingForResult = false;
@ -398,7 +443,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On
mRestoring = true;
}
boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);
if (renameFolder) {
long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);
@ -439,10 +483,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On
grid.setTextFilterEnabled(true);
grid.setDragger(dragLayer);
grid.setLauncher(this);
if (sOpenGlEnabled) {
grid.setScrollingCacheEnabled(false);
grid.setFadingEdgeLength(0);
}
workspace.setOnLongClickListener(this);
workspace.setDragger(dragLayer);
@ -456,18 +496,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On
dragLayer.setIgnoredDropTarget(grid);
dragLayer.setDragScoller(workspace);
dragLayer.setDragListener(deleteZone);
if (DEBUG_USER_INTERFACE) {
android.widget.Button finishButton = new android.widget.Button(this);
finishButton.setText("Finish");
workspace.addInScreen(finishButton, 1, 0, 0, 1, 1);
finishButton.setOnClickListener(new android.widget.Button.OnClickListener() {
public void onClick(View v) {
finish();
}
});
}
}
/**
@ -507,11 +535,42 @@ public final class Launcher extends Activity implements View.OnClickListener, On
return favorite;
}
void addApplicationShortcut(ApplicationInfo info) {
mAddItemCellInfo.screen = mWorkspace.getCurrentScreen();
mWorkspace.addApplicationShortcut(info, mAddItemCellInfo);
}
/**
* Add an application shortcut to the workspace.
*
* @param data The intent describing the application.
* @param cellInfo The position on screen where to create the shortcut.
*/
void completeAddApplication(Context context, Intent data, CellLayout.CellInfo cellInfo) {
cellInfo.screen = mWorkspace.getCurrentScreen();
// Find details for this application
ComponentName component = data.getComponent();
PackageManager packageManager = context.getPackageManager();
ActivityInfo activityInfo = null;
try {
activityInfo = packageManager.getActivityInfo(component, 0 /* no flags */);
} catch (NameNotFoundException e) {
Log.e(LOG_TAG, "Couldn't find ActivityInfo for selected application", e);
}
if (activityInfo != null) {
ApplicationInfo itemInfo = new ApplicationInfo();
itemInfo.title = activityInfo.loadLabel(packageManager);
if (itemInfo.title == null) {
itemInfo.title = activityInfo.name;
}
itemInfo.setActivity(component, Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
itemInfo.icon = activityInfo.loadIcon(packageManager);
itemInfo.container = ItemInfo.NO_ID;
mWorkspace.addApplicationShortcut(itemInfo, mAddItemCellInfo);
}
}
/**
* Add a shortcut to the workspace.
*
@ -535,6 +594,74 @@ public final class Launcher extends Activity implements View.OnClickListener, On
}
}
/**
* Add a gadget to the workspace.
*
* @param data The intent describing the gadgetId.
* @param cellInfo The position on screen where to create the shortcut.
* @param insertAtFirst
*/
private void completeAddGadget(Intent data, CellLayout.CellInfo cellInfo,
boolean insertAtFirst) {
Bundle extras = data.getExtras();
int gadgetId = extras.getInt(GadgetManager.EXTRA_GADGET_ID, -1);
Log.d(LOG_TAG, "dumping extras content="+extras.toString());
GadgetInfo gadgetInfo = mGadgetManager.getGadgetInfo(gadgetId);
// Calculate the grid spans needed to fit this gadget
CellLayout layout = (CellLayout) mWorkspace.getChildAt(cellInfo.screen);
layout.rectToCell(gadgetInfo.minWidth, gadgetInfo.minHeight, cellInfo);
// Try finding open space on Launcher screen
final int[] xy = mCellCoordinates;
if (!findSlot(cellInfo, xy, cellInfo.spanX, cellInfo.spanY)) return;
// Build Launcher-specific Gadget info and save to database
LauncherGadgetInfo launcherInfo = new LauncherGadgetInfo(gadgetId);
launcherInfo.spanX = cellInfo.spanX;
launcherInfo.spanY = cellInfo.spanY;
LauncherModel.addItemToDatabase(this, launcherInfo,
LauncherSettings.Favorites.CONTAINER_DESKTOP,
mWorkspace.getCurrentScreen(), xy[0], xy[1], false);
if (!mRestoring) {
sModel.addDesktopItem(launcherInfo);
// Perform actual inflation because we're live
launcherInfo.hostView = mGadgetHost.createView(this, gadgetId, gadgetInfo);
launcherInfo.hostView.setGadget(gadgetId, gadgetInfo);
launcherInfo.hostView.setTag(launcherInfo);
mWorkspace.addInCurrentScreen(launcherInfo.hostView, xy[0], xy[1],
launcherInfo.spanX, launcherInfo.spanY, insertAtFirst);
} else if (sModel.isDesktopLoaded()) {
sModel.addDesktopItem(launcherInfo);
}
// Request fresh update if we needed to config this gadget to
// remove the stale UPDATE from the initial bind
if (!extras.containsKey(SKIP_CONFIG) || true) {
// TODO: move this down into GadgetManager to prevent abuse? (anyone
// could force a specific gadget into the ground through flooding)
Log.d(LOG_TAG, "requesting new gadget update because we had a config step");
Intent intent = new Intent(GadgetManager.GADGET_UPDATE_ACTION);
intent.putExtra(GadgetManager.EXTRA_GADGET_IDS, new int[] { gadgetId });
intent.setComponent(gadgetInfo.provider);
sendBroadcast(intent);
}
}
public LauncherGadgetHost getGadgetHost() {
return mGadgetHost;
}
static ApplicationInfo addShortcut(Context context, Intent data,
CellLayout.CellInfo cellInfo, boolean notify) {
@ -584,107 +711,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On
return info;
}
/**
* Add a PhotFrame to the workspace.
*
* @param data The intent describing the photo.
* @param cellInfo The position on screen where to create the shortcut.
*/
private void completeAddPhotoFrame(Intent data, CellLayout.CellInfo cellInfo) {
final Bundle extras = data.getExtras();
if (extras != null) {
Bitmap photo = extras.getParcelable("data");
Widget info = Widget.makePhotoFrame();
info.photo = photo;
final int[] xy = mCellCoordinates;
if (!findSlot(cellInfo, xy, info.spanX, info.spanY)) return;
LauncherModel.addItemToDatabase(this, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
mWorkspace.getCurrentScreen(), xy[0], xy[1], false);
if (!mRestoring) {
sModel.addDesktopItem(info);
final PhotoFrame view = (PhotoFrame) mInflater.inflate(info.layoutResource, null);
view.setImageBitmap(photo);
view.setTag(info);
mWorkspace.addInCurrentScreen(view, xy[0], xy[1], info.spanX, info.spanY);
} else if (sModel.isDesktopLoaded()) {
sModel.addDesktopItem(info);
}
}
}
/**
* Updates a workspace PhotoFrame.
*
* @param data The intent describing the photo.
* @param cellInfo The position on screen of the PhotoFrame to update.
*/
private void completeUpdatePhotoFrame(Intent data, CellLayout.CellInfo cellInfo) {
final Bundle extras = data.getExtras();
if (extras != null) {
Widget info;
Bitmap photo = extras.getParcelable("data");
if (!mRestoring) {
final CellLayout layout = (CellLayout) mWorkspace.getChildAt(cellInfo.screen);
final PhotoFrame view = (PhotoFrame) layout.findCell(cellInfo.cellX, cellInfo.cellY,
cellInfo.spanX, cellInfo.spanY, null);
view.setImageBitmap(photo);
info = (Widget) view.getTag();
} else {
info = LauncherModel.getPhotoFrameInfo(this, cellInfo.screen,
cellInfo.cellX, cellInfo.cellY);
}
info.photo = photo;
LauncherModel.updateItemInDatabase(this, info);
}
}
/**
* Starts a new Intent to let the user update the PhotoFrame defined by the
* specified Widget.
*
* @param widget The Widget info defining which PhotoFrame to update.
*/
void updatePhotoFrame(Widget widget) {
CellLayout.CellInfo info = new CellLayout.CellInfo();
info.screen = widget.screen;
info.cellX = widget.cellX;
info.cellY = widget.cellY;
info.spanX = widget.spanX;
info.spanY = widget.spanY;
mAddItemCellInfo = info;
startActivityForResult(createPhotoPickIntent(), Launcher.REQUEST_UPDATE_PHOTO);
}
/**
* Creates an Intent used to let the user pick a photo for a PhotoFrame.
*
* @return The Intent to pick a photo suited for a PhotoFrame.
*/
private static Intent createPhotoPickIntent() {
// TODO: Move this method to PhotoFrame?
// TODO: get these values from constants somewhere
// TODO: Adjust the PhotoFrame's image size to avoid on the fly scaling
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 192);
intent.putExtra("outputY", 192);
intent.putExtra("noFaceDetection", true);
intent.putExtra("return-data", true);
return intent;
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
@ -871,10 +897,51 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private void removeShortcutsForPackage(String packageName) {
if (packageName != null && packageName.length() > 0) {
android.util.Log.d(LOG_TAG, packageName);
mWorkspace.removeShortcutsForPackage(packageName);
}
}
static final String SKIP_CONFIG = "skip_config";
void addGadget(Intent data) {
int gadgetId = data.getIntExtra(GadgetManager.EXTRA_GADGET_ID, -1);
GadgetInfo gadget = mGadgetManager.getGadgetInfo(gadgetId);
if (gadget.configure != null) {
// Launch over to configure gadget, if needed
Intent intent = new Intent(GadgetManager.GADGET_CONFIGURE_ACTION);
intent.setComponent(gadget.configure);
intent.putExtra(GadgetManager.EXTRA_GADGET_ID, gadgetId);
startActivityForResult(intent, REQUEST_CREATE_GADGET);
} else {
// Otherwise just add it
Log.d(LOG_TAG, "dumping extras content="+data.getExtras().toString());
data.putExtra(SKIP_CONFIG, true);
Log.d(LOG_TAG, "dumping extras content="+data.getExtras().toString());
onActivityResult(REQUEST_CREATE_GADGET, Activity.RESULT_OK, data);
}
}
void addSearch() {
final Widget info = Widget.makeSearch();
final CellLayout.CellInfo cellInfo = mAddItemCellInfo;
final int[] xy = mCellCoordinates;
final int spanX = info.spanX;
final int spanY = info.spanY;
if (!findSlot(cellInfo, xy, spanX, spanY)) return;
sModel.addDesktopItem(info);
LauncherModel.addItemToDatabase(this, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
mWorkspace.getCurrentScreen(), xy[0], xy[1], false);
final View view = mInflater.inflate(info.layoutResource, null);
view.setTag(info);
mWorkspace.addInCurrentScreen(view, xy[0], xy[1], info.spanX, spanY);
}
void addShortcut(Intent intent) {
startActivityForResult(intent, REQUEST_CREATE_SHORTCUT);
@ -964,39 +1031,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On
return info;
}
void getPhotoForPhotoFrame() {
startActivityForResult(createPhotoPickIntent(), REQUEST_CHOOSE_PHOTO);
}
void addClock() {
final Widget info = Widget.makeClock();
addWidget(info);
}
void addSearch() {
final Widget info = Widget.makeSearch();
addWidget(info);
}
private void addWidget(final Widget info) {
final CellLayout.CellInfo cellInfo = mAddItemCellInfo;
final int[] xy = mCellCoordinates;
final int spanX = info.spanX;
final int spanY = info.spanY;
if (!findSlot(cellInfo, xy, spanX, spanY)) return;
sModel.addDesktopItem(info);
LauncherModel.addItemToDatabase(this, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
mWorkspace.getCurrentScreen(), xy[0], xy[1], false);
final View view = mInflater.inflate(info.layoutResource, null);
view.setTag(info);
mWorkspace.addInCurrentScreen(view, xy[0], xy[1], info.spanX, spanY);
}
private boolean findSlot(CellLayout.CellInfo cellInfo, int[] xy, int spanX, int spanY) {
if (!cellInfo.findCellForSpan(xy, spanX, spanY)) {
boolean[] occupied = mSavedState != null ?
@ -1136,6 +1170,18 @@ public final class Launcher extends Activity implements View.OnClickListener, On
for (int i = 0; i < count; i++) {
((ViewGroup) workspace.getChildAt(i)).removeAllViewsInLayout();
}
if (DEBUG_USER_INTERFACE) {
android.widget.Button finishButton = new android.widget.Button(this);
finishButton.setText("Finish");
workspace.addInScreen(finishButton, 1, 0, 0, 1, 1);
finishButton.setOnClickListener(new android.widget.Button.OnClickListener() {
public void onClick(View v) {
finish();
}
});
}
count = shortcuts.size();
@ -1176,11 +1222,41 @@ public final class Launcher extends Activity implements View.OnClickListener, On
workspace.addInScreen(newLiveFolder, item.screen, item.cellX, item.cellY, 1, 1,
!desktopLocked);
break;
default:
case LauncherSettings.Favorites.ITEM_TYPE_GADGET:
final LauncherGadgetInfo launcherInfo = (LauncherGadgetInfo) item;
final int gadgetId = launcherInfo.gadgetId;
GadgetInfo gadgetInfo = mGadgetManager.getGadgetInfo(gadgetId);
launcherInfo.hostView = mGadgetHost.createView(this, gadgetId, gadgetInfo);
Log.d(LOG_TAG, "about to setGadget during desktop bind");
launcherInfo.hostView.setGadget(gadgetId, gadgetInfo);
launcherInfo.hostView.setTag(launcherInfo);
workspace.addInScreen(launcherInfo.hostView, item.screen, item.cellX,
item.cellY, item.spanX, item.spanY, !desktopLocked);
// Now that we've bound the item, request an update for it
if (gadgetInfo != null) {
if (gadgetInfo.provider != null) {
Intent intent = new Intent(GadgetManager.GADGET_UPDATE_ACTION);
intent.putExtra(GadgetManager.EXTRA_GADGET_IDS, new int[] { gadgetId });
intent.setComponent(gadgetInfo.provider);
sendBroadcast(intent);
}
}
break;
case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
final int screen = workspace.getCurrentScreen();
final View view = mInflater.inflate(R.layout.widget_search,
(ViewGroup) workspace.getChildAt(screen), false);
final Widget widget = (Widget) item;
final View view = createWidget(mInflater, widget);
view.setTag(widget);
workspace.addWidget(view, widget, !desktopLocked);
break;
}
}
@ -1226,17 +1302,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On
mDrawer.unlock();
}
private View createWidget(LayoutInflater inflater, Widget widget) {
final Workspace workspace = mWorkspace;
final int screen = workspace.getCurrentScreen();
View v = inflater.inflate(widget.layoutResource,
(ViewGroup) workspace.getChildAt(screen), false);
if (widget.itemType == LauncherSettings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME) {
((ImageView)v).setImageBitmap(widget.photo);
}
return v;
}
DragController getDragController() {
return mDragLayer;
}
@ -1263,6 +1328,11 @@ public final class Launcher extends Activity implements View.OnClickListener, On
startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
} catch (SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(LOG_TAG, "Launcher does not have the permission to launch " + intent +
". Make sure to create a MAIN intent-filter for the corresponding activity " +
"or use the exported attribute for this activity.", e);
}
}
@ -1508,24 +1578,24 @@ public final class Launcher extends Activity implements View.OnClickListener, On
* Displays the shortcut creation dialog and launches, if necessary, the
* appropriate activity.
*/
private class CreateShortcut implements ExpandableListView.OnChildClickListener,
DialogInterface.OnCancelListener, ExpandableListView.OnGroupExpandListener {
private class CreateShortcut implements AdapterView.OnItemClickListener,
DialogInterface.OnCancelListener {
private AddAdapter mAdapter;
private ExpandableListView mList;
private ListView mList;
Dialog createDialog() {
mWaitingForResult = true;
mAdapter = new AddAdapter(Launcher.this, false);
mAdapter = new AddAdapter(Launcher.this);
final AlertDialog.Builder builder = new AlertDialog.Builder(Launcher.this);
builder.setTitle(getString(R.string.menu_item_add_item));
builder.setIcon(0);
mList = (ExpandableListView)
mList = (ListView)
View.inflate(Launcher.this, R.layout.create_shortcut_list, null);
mList.setAdapter(mAdapter);
mList.setOnChildClickListener(this);
mList.setOnGroupExpandListener(this);
mList.setOnItemClickListener(this);
builder.setView(mList);
builder.setInverseBackgroundForced(true);
@ -1539,13 +1609,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On
return dialog;
}
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
int childPosition, long id) {
mAdapter.performAction(groupPosition, childPosition);
cleanup();
return true;
}
public void onCancel(DialogInterface dialog) {
mWaitingForResult = false;
cleanup();
@ -1556,10 +1619,76 @@ public final class Launcher extends Activity implements View.OnClickListener, On
dismissDialog(DIALOG_CREATE_SHORTCUT);
}
public void onGroupExpand(int groupPosition) {
long packged = ExpandableListView.getPackedPositionForGroup(groupPosition);
int position = mList.getFlatListPosition(packged);
mList.setSelectionFromTop(position, 0);
public void onItemClick(AdapterView parent, View view, int position, long id) {
// handle which item was clicked based on position
// this will launch off pick intent
Object tag = view.getTag();
if (tag instanceof AddAdapter.ListItem) {
AddAdapter.ListItem item = (AddAdapter.ListItem) tag;
cleanup();
switch (item.actionTag) {
case AddAdapter.ITEM_APPLICATION: {
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);
startActivityForResult(pickIntent, REQUEST_PICK_APPLICATION);
break;
}
case AddAdapter.ITEM_SHORTCUT: {
Intent shortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
pickIntent.putExtra(Intent.EXTRA_INTENT, shortcutIntent);
pickIntent.putExtra(Intent.EXTRA_TITLE,
getText(R.string.title_select_shortcut));
startActivityForResult(pickIntent, REQUEST_PICK_SHORTCUT);
break;
}
case AddAdapter.ITEM_SEARCH: {
addSearch();
break;
}
case AddAdapter.ITEM_GADGET: {
int gadgetId = Launcher.this.mGadgetHost.allocateGadgetId();
Intent pickIntent = new Intent(GadgetManager.GADGET_PICK_ACTION);
pickIntent.putExtra(GadgetManager.EXTRA_HOST_ID, GADGET_HOST_ID);
pickIntent.putExtra(GadgetManager.EXTRA_GADGET_ID, gadgetId);
startActivityForResult(pickIntent, REQUEST_PICK_GADGET);
break;
}
case AddAdapter.ITEM_LIVE_FOLDER: {
Intent liveFolderIntent = new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER);
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
pickIntent.putExtra(Intent.EXTRA_INTENT, liveFolderIntent);
pickIntent.putExtra(Intent.EXTRA_TITLE,
getText(R.string.title_select_live_folder));
startActivityForResult(pickIntent, REQUEST_PICK_LIVE_FOLDER);
break;
}
case AddAdapter.ITEM_FOLDER: {
addFolder();
dismissDialog(DIALOG_CREATE_SHORTCUT);
break;
}
case AddAdapter.ITEM_WALLPAPER: {
startWallpaper();
break;
}
}
}
}
}
@ -1569,13 +1698,20 @@ public final class Launcher extends Activity implements View.OnClickListener, On
private class ApplicationsIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//noinspection ConstantConditions
if (REMOVE_SHORTCUT_ON_PACKAGE_REMOVE &&
Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
removeShortcutsForPackage(intent.getData().getSchemeSpecificPart());
boolean reloadWorkspace = false;
if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
removeShortcutsForPackage(intent.getData().getSchemeSpecificPart());
} else {
reloadWorkspace = true;
}
}
removeDialog(DIALOG_CREATE_SHORTCUT);
sModel.loadApplications(false, Launcher.this, false);
if (!reloadWorkspace) {
sModel.loadApplications(false, Launcher.this, false);
} else {
sModel.loadUserItems(false, Launcher.this, false, true);
}
}
}

View File

@ -0,0 +1,131 @@
/*
* 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.launcher;
import android.content.Context;
import android.gadget.GadgetHost;
import android.gadget.GadgetHostView;
import android.gadget.GadgetInfo;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.TextView;
/**
* Specific {@link GadgetHost} that creates our {@link LauncherGadgetHostView} which correctly
* captures all long-press events. This ensures that users can always pick up and move gadgets.
*/
public class LauncherGadgetHost extends GadgetHost {
public LauncherGadgetHost(Context context, int hostId) {
super(context, hostId);
}
protected GadgetHostView onCreateView(Context context, int gadgetId, GadgetInfo gadget) {
return new LauncherGadgetHostView(context);
}
/**
* {@inheritDoc}
*/
public class LauncherGadgetHostView extends GadgetHostView {
static final String TAG = "LauncherGadgetHostView";
private boolean mHasPerformedLongPress;
private CheckForLongPress mPendingCheckForLongPress;
private LayoutInflater mInflater;
public LauncherGadgetHostView(Context context) {
super(context);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Prepare our default transition animations
setAnimateFirstView(true);
setInAnimation(context, android.R.anim.fade_in);
setOutAnimation(context, android.R.anim.fade_out);
}
@Override
protected View getErrorView() {
return mInflater.inflate(R.layout.gadget_error, this, false);
}
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Consume any touch events for ourselves after longpress is triggered
if (mHasPerformedLongPress) {
mHasPerformedLongPress = false;
return true;
}
// Watch for longpress events at this level to make sure
// users can always pick up this Gadget
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
postCheckForLongClick();
break;
}
case MotionEvent.ACTION_UP: {
mHasPerformedLongPress = false;
if (mPendingCheckForLongPress != null) {
removeCallbacks(mPendingCheckForLongPress);
}
break;
}
}
// Otherwise continue letting touch events fall through to children
return false;
}
class CheckForLongPress implements Runnable {
private int mOriginalWindowAttachCount;
public void run() {
if ((mParent != null) && hasWindowFocus()
&& mOriginalWindowAttachCount == getWindowAttachCount()
&& !mHasPerformedLongPress) {
if (performLongClick()) {
mHasPerformedLongPress = true;
}
}
}
public void rememberWindowAttachCount() {
mOriginalWindowAttachCount = getWindowAttachCount();
}
}
private void postCheckForLongClick() {
mHasPerformedLongPress = false;
if (mPendingCheckForLongPress == null) {
mPendingCheckForLongPress = new CheckForLongPress();
}
mPendingCheckForLongPress.rememberWindowAttachCount();
postDelayed(mPendingCheckForLongPress, ViewConfiguration.getLongPressTimeout());
}
}
}

View File

@ -0,0 +1,53 @@
/*
* 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.launcher;
import android.content.ContentValues;
import android.gadget.GadgetHostView;
/**
* Represents a gadget, which just contains an identifier.
*/
class LauncherGadgetInfo extends ItemInfo {
/**
* Identifier for this gadget when talking with {@link GadgetManager} for updates.
*/
int gadgetId;
/**
* View that holds this gadget after it's been created. This view isn't created
* until Launcher knows it's needed.
*/
GadgetHostView hostView = null;
LauncherGadgetInfo(int gadgetId) {
itemType = LauncherSettings.Favorites.ITEM_TYPE_GADGET;
this.gadgetId = gadgetId;
}
@Override
void onAddToDatabase(ContentValues values) {
super.onAddToDatabase(values);
values.put(LauncherSettings.Favorites.GADGET_ID, gadgetId);
}
@Override
public String toString() {
return Integer.toString(gadgetId);
}
}

View File

@ -272,7 +272,8 @@ public class LauncherModel {
try {
while (c.moveToNext()) {
try {
if (c.getInt(itemTypeIndex) != LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
if (c.getInt(itemTypeIndex) !=
LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
continue;
}
@ -374,15 +375,19 @@ public class LauncherModel {
final int iconResourceIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_RESOURCE);
final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
final int gadgetIdIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.GADGET_ID);
final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX);
final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY);
final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
final int displayModeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.DISPLAY_MODE);
ApplicationInfo info;
String intentDescription;
Widget widgetInfo = null;
LauncherGadgetInfo gadgetInfo = null;
int container;
long id;
Intent intent;
@ -494,41 +499,44 @@ public class LauncherModel {
break;
}
break;
case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK:
case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME:
switch (itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK:
widgetInfo = Widget.makeClock();
break;
case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
widgetInfo = Widget.makeSearch();
break;
case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME:
widgetInfo = Widget.makePhotoFrame();
byte[] data = c.getBlob(iconIndex);
if (data != null) {
widgetInfo.photo =
BitmapFactory.decodeByteArray(data, 0, data.length);
}
break;
}
widgetInfo = Widget.makeSearch();
if (widgetInfo != null) {
container = c.getInt(containerIndex);
if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
Log.e(Launcher.LOG_TAG, "Widget found where container "
+ "!= CONTAINER_DESKTOP -- ignoring!");
continue;
}
widgetInfo.id = c.getLong(idIndex);
widgetInfo.screen = c.getInt(screenIndex);
widgetInfo.container = container;
widgetInfo.cellX = c.getInt(cellXIndex);
widgetInfo.cellY = c.getInt(cellYIndex);
desktopItems.add(widgetInfo);
container = c.getInt(containerIndex);
if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
Log.e(Launcher.LOG_TAG, "Widget found where container "
+ "!= CONTAINER_DESKTOP ignoring!");
continue;
}
widgetInfo.id = c.getLong(idIndex);
widgetInfo.screen = c.getInt(screenIndex);
widgetInfo.container = container;
widgetInfo.cellX = c.getInt(cellXIndex);
widgetInfo.cellY = c.getInt(cellYIndex);
desktopItems.add(widgetInfo);
break;
case LauncherSettings.Favorites.ITEM_TYPE_GADGET:
// Read all Launcher-specific gadget details
int gadgetId = c.getInt(gadgetIdIndex);
gadgetInfo = new LauncherGadgetInfo(gadgetId);
gadgetInfo.id = c.getLong(idIndex);
gadgetInfo.screen = c.getInt(screenIndex);
gadgetInfo.cellX = c.getInt(cellXIndex);
gadgetInfo.cellY = c.getInt(cellYIndex);
gadgetInfo.spanX = c.getInt(spanXIndex);
gadgetInfo.spanY = c.getInt(spanYIndex);
container = c.getInt(containerIndex);
if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
Log.e(Launcher.LOG_TAG, "Gadget found where container "
+ "!= CONTAINER_DESKTOP -- ignoring!");
continue;
}
gadgetInfo.container = c.getInt(containerIndex);
desktopItems.add(gadgetInfo);
break;
}
} catch (Exception e) {
@ -972,7 +980,7 @@ public class LauncherModel {
final ContentResolver cr = context.getContentResolver();
cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null);
cr.delete(LauncherSettings.Favorites.CONTENT_URI, LauncherSettings.Favorites.CONTAINER + "=" + info.id,
null);
cr.delete(LauncherSettings.Favorites.CONTENT_URI,
LauncherSettings.Favorites.CONTAINER + "=" + info.id, null);
}
}

View File

@ -29,6 +29,7 @@ import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.database.Cursor;
import android.database.SQLException;
import android.util.Log;
import android.util.Xml;
import android.net.Uri;
@ -49,7 +50,8 @@ public class LauncherProvider extends ContentProvider {
private static final String LOG_TAG = "LauncherSettingsProvider";
private static final String DATABASE_NAME = "launcher.db";
private static final int DATABASE_VERSION = 1;
private static final int DATABASE_VERSION = 2;
static final String AUTHORITY = "com.android.launcher.settings";
@ -187,6 +189,7 @@ public class LauncherProvider extends ContentProvider {
"spanX INTEGER," +
"spanY INTEGER," +
"itemType INTEGER," +
"gadgetId INTEGER NOT NULL DEFAULT -1," +
"isShortcut INTEGER," +
"iconType INTEGER," +
"iconPackage TEXT," +
@ -196,6 +199,11 @@ public class LauncherProvider extends ContentProvider {
"displayMode INTEGER" +
");");
// TODO: During first database creation, trigger wipe of any gadgets that
// might have been left around during a wipe-data.
// GadgetManager gadgetManager = GadgetManager.getInstance(mContext);
if (!convertDatabase(db)) {
// Populate favorites table with initial favorites
loadFavorites(db, DEFAULT_FAVORITES_PATH);
@ -206,7 +214,7 @@ public class LauncherProvider extends ContentProvider {
boolean converted = false;
final Uri uri = Uri.parse("content://" + Settings.AUTHORITY +
"/favorites?notify=true");
"/old_favorites?notify=true");
final ContentResolver resolver = mContext.getContentResolver();
Cursor cursor = null;
@ -261,6 +269,7 @@ public class LauncherProvider extends ContentProvider {
values.put(LauncherSettings.Favorites.ICON_RESOURCE, c.getString(iconResourceIndex));
values.put(LauncherSettings.Favorites.CONTAINER, c.getInt(containerIndex));
values.put(LauncherSettings.Favorites.ITEM_TYPE, c.getInt(itemTypeIndex));
values.put(LauncherSettings.Favorites.GADGET_ID, -1);
values.put(LauncherSettings.Favorites.SCREEN, c.getInt(screenIndex));
values.put(LauncherSettings.Favorites.CELLX, c.getInt(cellXIndex));
values.put(LauncherSettings.Favorites.CELLY, c.getInt(cellYIndex));
@ -290,11 +299,31 @@ public class LauncherProvider extends ContentProvider {
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(LOG_TAG, "Upgrading database from version " + oldVersion + " to " +
newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_FAVORITES);
onCreate(db);
int version = oldVersion;
if (version == 1) {
// upgrade 1 -> 2 added gadgetId column
db.beginTransaction();
try {
// TODO: convert any existing widgets for search and clock
// this might involve a FORCE_ADD_GADGET permission in GadgetManager that
// Launcher could then use to add these gadgets without user interaction
db.execSQL("ALTER TABLE favorites " +
"ADD COLUMN gadgetId INTEGER NOT NULL DEFAULT -1;");
db.setTransactionSuccessful();
version = 2;
} catch (SQLException ex) {
// Old version remains, which means we wipe old data
Log.e(LOG_TAG, ex.getMessage(), ex);
} finally {
db.endTransaction();
}
}
if (version != DATABASE_VERSION) {
Log.w(LOG_TAG, "Destroying all old data.");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_FAVORITES);
onCreate(db);
}
}
@ -370,20 +399,7 @@ public class LauncherProvider extends ContentProvider {
} catch (IOException e) {
Log.w(LOG_TAG, "Got exception parsing favorites.", e);
}
// Add a clock
values.clear();
values.put(LauncherSettings.Favorites.CONTAINER,
LauncherSettings.Favorites.CONTAINER_DESKTOP);
values.put(LauncherSettings.Favorites.ITEM_TYPE,
LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK);
values.put(LauncherSettings.Favorites.SCREEN, 1);
values.put(LauncherSettings.Favorites.CELLX, 1);
values.put(LauncherSettings.Favorites.CELLY, 0);
values.put(LauncherSettings.Favorites.SPANX, 2);
values.put(LauncherSettings.Favorites.SPANY, 2);
db.insert(TABLE_FAVORITES, null, values);
// Add a search box
values.clear();
values.put(LauncherSettings.Favorites.CONTAINER,
@ -396,6 +412,9 @@ public class LauncherProvider extends ContentProvider {
values.put(LauncherSettings.Favorites.SPANX, 4);
values.put(LauncherSettings.Favorites.SPANY, 1);
db.insert(TABLE_FAVORITES, null, values);
// TODO: automatically add clock and search gadget to
// default locations. this might need the FORCE permission mentioned above
return i;
}

View File

@ -146,6 +146,11 @@ class LauncherSettings {
*/
static final int ITEM_TYPE_LIVE_FOLDER = 3;
/**
* The favorite is a gadget
*/
static final int ITEM_TYPE_GADGET = 4;
/**
* The favorite is a clock
*/
@ -161,6 +166,13 @@ class LauncherSettings {
*/
static final int ITEM_TYPE_WIDGET_PHOTO_FRAME = 1002;
/**
* The gadgetId of the gadget
*
* <P>Type: INTEGER</P>
*/
static final String GADGET_ID = "gadgetId";
/**
* Indicates whether this favorite is an application-created shortcut or not.
* If the value is 0, the favorite is not an application-created shortcut, if the

View File

@ -1,42 +0,0 @@
/*
* 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.launcher;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
/**
* Desktop widget that holds a user folder
*
*/
public class PhotoFrame extends ImageView implements OnClickListener {
public PhotoFrame(Context context, AttributeSet attrs) {
super(context, attrs);
setClickable(true);
setOnClickListener(this);
setWillNotCacheDrawing(true);
}
public void onClick(View v) {
((Launcher) mContext).updatePhotoFrame((Widget) getTag());
}
}

View File

@ -16,8 +16,6 @@
package com.android.launcher;
import java.util.List;
import android.app.ISearchManager;
import android.app.SearchManager;
import android.content.ActivityNotFoundException;
@ -59,6 +57,8 @@ import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import java.util.List;
public class Search extends LinearLayout implements OnClickListener, OnKeyListener,
OnLongClickListener, TextWatcher, OnItemClickListener, OnItemSelectedListener {
@ -66,6 +66,7 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
private AutoCompleteTextView mSearchText;
private ImageButton mGoButton;
private ImageButton mVoiceButton;
private OnLongClickListener mLongClickListener;
// Support for suggestions
@ -76,6 +77,9 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
private String mSuggestionQuery = null;
private int mItemSelected = -1;
// For voice searching
private Intent mVoiceSearchIntent;
private Rect mTempRect = new Rect();
/**
@ -86,6 +90,10 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
*/
public Search(Context context, AttributeSet attrs) {
super(context, attrs);
mVoiceSearchIntent = new Intent(android.speech.RecognizerIntent.ACTION_WEB_SEARCH);
mVoiceSearchIntent.putExtra(android.speech.RecognizerIntent.EXTRA_LANGUAGE_MODEL,
android.speech.RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
}
/**
@ -94,6 +102,14 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
public void onClick(View v) {
if (v == mGoButton) {
query();
} else if (v == mVoiceButton) {
try {
getContext().startActivity(mVoiceSearchIntent);
} catch (ActivityNotFoundException ex) {
// Should not happen, since we check the availability of
// voice search before showing the button. But just in case...
Log.w(TAG, "Could not find voice search activity");
}
}
}
@ -206,7 +222,7 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
return true;
}
}
} else if (v == mGoButton) {
} else if (v == mGoButton || v == mVoiceButton) {
boolean handled = false;
if (!event.isSystem() &&
(keyCode != KeyEvent.KEYCODE_DPAD_UP) &&
@ -243,7 +259,14 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
requestFocusFromTouch();
// Request focus unless the user tapped on the voice search button
final int x = (int) ev.getX();
final int y = (int) ev.getY();
final Rect frame = mTempRect;
mVoiceButton.getHitRect(frame);
if (!frame.contains(x, y)) {
requestFocusFromTouch();
}
return super.onInterceptTouchEvent(ev);
}
@ -268,26 +291,29 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
mSearchText.addTextChangedListener(this);
mGoButton = (ImageButton) findViewById(R.id.search_go_btn);
mVoiceButton = (ImageButton) findViewById(R.id.search_voice_btn);
mGoButton.setOnClickListener(this);
mVoiceButton.setOnClickListener(this);
mGoButton.setOnKeyListener(this);
mVoiceButton.setOnKeyListener(this);
mSearchText.setOnLongClickListener(this);
mGoButton.setOnLongClickListener(this);
mVoiceButton.setOnLongClickListener(this);
// disable the button since we start out w/empty input
mGoButton.setEnabled(false);
mGoButton.setFocusable(false);
configureSearchableInfo();
configureSuggestions();
configureVoiceSearchButton();
}
/** The rest of the class deals with providing search suggestions */
/**
* Set up the suggestions provider mechanism
* Read the searchable info from the search manager
*/
private void configureSuggestions() {
// get SearchableInfo
private void configureSearchableInfo() {
ISearchManager sms;
SearchableInfo searchable;
sms = ISearchManager.Stub.asInterface(ServiceManager.getService(Context.SEARCH_SERVICE));
@ -303,6 +329,36 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen
return;
}
mSearchable = searchable;
}
/**
* If appropriate & available, configure voice search
*
* Note: Because the home screen search widget is always web search, we only check for
* getVoiceSearchLaunchWebSearch() modes. We don't support the alternate form of app-specific
* voice search.
*/
private void configureVoiceSearchButton() {
boolean voiceSearchVisible = false;
if (mSearchable.getVoiceSearchEnabled() && mSearchable.getVoiceSearchLaunchWebSearch()) {
// Enable the voice search button if there is an activity that can handle it
PackageManager pm = getContext().getPackageManager();
List<ResolveInfo> list = pm.queryIntentActivities(mVoiceSearchIntent,
PackageManager.MATCH_DEFAULT_ONLY);
voiceSearchVisible = list.size() > 0;
}
// finally, set visible state of voice search button, as appropriate
mVoiceButton.setVisibility(voiceSearchVisible ? View.VISIBLE : View.GONE);
}
/** The rest of the class deals with providing search suggestions */
/**
* Set up the suggestions provider mechanism
*/
private void configureSuggestions() {
// get SearchableInfo
mSearchText.setOnItemClickListener(this);
mSearchText.setOnItemSelectedListener(this);

View File

@ -123,9 +123,6 @@ public class WallpaperChooser extends Activity implements AdapterView.OnItemSele
final String[] extras = resources.getStringArray(R.array.extra_wallpapers);
final String packageName = getApplication().getPackageName();
final ArrayList<Integer> images = mImages;
final ArrayList<Integer> thumbs = mThumbs;
for (String extra : extras) {
int res = resources.getIdentifier(extra, "drawable", packageName);
if (res != 0) {
@ -133,8 +130,8 @@ public class WallpaperChooser extends Activity implements AdapterView.OnItemSele
"drawable", packageName);
if (thumbRes != 0) {
images.add(res);
thumbs.add(res);
mThumbs.add(res);
mImages.add(res);
}
}
}
@ -148,7 +145,7 @@ public class WallpaperChooser extends Activity implements AdapterView.OnItemSele
public void onItemSelected(AdapterView parent, View v, int position, long id) {
final ImageView view = mImageView;
Bitmap b = BitmapFactory.decodeResource(getResources(), IMAGE_IDS[position], mOptions);
Bitmap b = BitmapFactory.decodeResource(getResources(), mImages.get(position), mOptions);
view.setImageBitmap(b);
// Help the GC

View File

@ -89,6 +89,8 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
private boolean mAllowLongPress;
private boolean mLocked;
private int mTouchSlop;
/**
* Used to inflate the Workspace from XML.
*
@ -126,6 +128,8 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
mPaint = new Paint();
mPaint.setDither(false);
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
/**
@ -626,8 +630,8 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
*/
final int xDiff = (int) Math.abs(x - mLastMotionX);
final int yDiff = (int) Math.abs(y - mLastMotionY);
final int touchSlop = ViewConfiguration.getTouchSlop();
final int touchSlop = mTouchSlop;
boolean xMoved = xDiff > touchSlop;
boolean yMoved = yDiff > touchSlop;
@ -1155,6 +1159,10 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
}
}
}
// TODO: remove gadgets when gadgetmanager tells us they're gone
// void removeGadgetsForProvider() {
// }
void moveToDefaultScreen() {
snapToScreen(mDefaultScreen);