diff options
author | lado <herrlado@gmail.com> | 2012-03-23 09:18:44 +0100 |
---|---|---|
committer | lado <herrlado@gmail.com> | 2012-03-23 09:18:44 +0100 |
commit | 421a5adede3d223019d27bd20460a7e9eca296fb (patch) | |
tree | 73ef203ab9b790b2cda67ded479c13008ff2d074 | |
parent | 39825c9ecd86f779ef068065c3d13d77a80ac834 (diff) | |
download | vdr-manager-421a5adede3d223019d27bd20460a7e9eca296fb.tar.gz vdr-manager-421a5adede3d223019d27bd20460a7e9eca296fb.tar.bz2 |
http://projects.vdr-developer.org/issues/913
http://projects.vdr-developer.org/issues/873
http://projects.vdr-developer.org/issues/866
13 files changed, 740 insertions, 63 deletions
diff --git a/vdrmanager/AndroidManifest.xml b/vdrmanager/AndroidManifest.xml index 12e6b37..9930ad8 100644 --- a/vdrmanager/AndroidManifest.xml +++ b/vdrmanager/AndroidManifest.xml @@ -1,9 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="de.bjusystems.vdrmanager" android:versionName="0.4.7" - android:versionCode="407"> + package="de.bjusystems.vdrmanager" android:versionName="0.4.9" + android:versionCode="409"> + + + + <uses-permission android:name="android.permission.INTERNET"/> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + + + <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="14" /> + <application android:icon="@drawable/app_logo" - android:hardwareAccelerated="true" android:label="@string/app_name" android:debuggable="false" android:name=".app.VdrManagerApp"> <activity android:label="@string/app_name" android:name=".gui.VdrManagerActivity" android:configChanges="locale"> @@ -90,10 +98,4 @@ </application> - <uses-permission android:name="android.permission.INTERNET"/> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - - - <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="11" /> - </manifest>
\ No newline at end of file diff --git a/vdrmanager/res/layout/timer_detail.xml b/vdrmanager/res/layout/timer_detail.xml index 21432eb..d86d9ef 100644 --- a/vdrmanager/res/layout/timer_detail.xml +++ b/vdrmanager/res/layout/timer_detail.xml @@ -33,34 +33,69 @@ android:paddingLeft="4.0dip" android:paddingBottom="2.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="2.0dip" android:text="@string/timer_detail_title_title"/> + <EditText android:id="@+id/timer_detail_title" android:layout_width="fill_parent" android:layout_height="wrap_content"/> + + + <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> + + <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> + <TextView android:paddingLeft="4.0dip" android:paddingBottom="2.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="2.0dip" + android:text="@string/timer_detail_day_title"/> + + + <Button + android:id="@+id/timer_detail_day" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:editable="false"/> + + </LinearLayout> + + <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> + <TextView + android:paddingLeft="4.0dip" android:paddingBottom="2.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="2.0dip" + android:text="@string/timer_detail_repeat_title"/> + + + <Button + android:id="@+id/timer_detail_repeat" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/never" + android:editable="false"/> + + </LinearLayout> + + + </LinearLayout> + + + <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> + + <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> + + + <TextView + android:paddingLeft="4.0dip" android:paddingBottom="2.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="2.0dip" android:text="@string/timer_detail_start_title"/> - - <LinearLayout - android:id="@+id/timer_detail_start_daytime" - android:layout_width="fill_parent" - android:layout_height="wrap_content"> - + <Button android:id="@+id/timer_detail_start" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:text="20:34" android:editable="false"/> - - <Button - android:id="@+id/timer_detail_day" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:editable="false"/> - - </LinearLayout> - + + </LinearLayout> + + <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:paddingLeft="4.0dip" android:paddingBottom="2.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="2.0dip" android:text="@string/timer_detail_end_title"/> @@ -71,13 +106,37 @@ android:layout_height="wrap_content" android:editable="false"/> - <TextView - android:id="@+id/timer_detail_fill" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:layout_weight="0.5"/> - - </LinearLayout> + + </LinearLayout> + </LinearLayout> + + <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> + <TextView android:width="80dp" android:text="@string/timer_detail_use_vps" android:layout_width="wrap_content" android:layout_height="wrap_content" /> + <CheckBox android:id="@+id/timer_detail_vps" android:layout_height="wrap_content" android:layout_width="wrap_content"/> + </LinearLayout> + + + + + <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> + + <TextView android:width="80dp" android:text="@string/timer_detail_priority" android:layout_width="wrap_content" android:layout_height="wrap_content" /> + + <EditText android:layout_height="wrap_content" android:numeric="integer" android:id="@+id/timer_detail_priority" android:layout_width="wrap_content" android:hint="@string/timer_detail_priority"/> + + + </LinearLayout> + + <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> + + <TextView android:width="80dp" android:text="@string/timer_detail_lifetime" android:layout_width="wrap_content" android:layout_height="wrap_content" /> + + <EditText android:layout_height="wrap_content" android:numeric="integer" android:id="@+id/timer_detail_lifetime" android:layout_width="wrap_content" android:hint="@string/timer_detail_lifetime_hint"/> + + + </LinearLayout> + + </LinearLayout> </ScrollView> diff --git a/vdrmanager/res/values-uk/strings.xml b/vdrmanager/res/values-uk/strings.xml new file mode 100644 index 0000000..9511c3d --- /dev/null +++ b/vdrmanager/res/values-uk/strings.xml @@ -0,0 +1,273 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="action_menu_channels">Канали</string> + <string name="action_menu_timers">Таймери</string> + <string name="action_menu_recordings">Записи</string> + <string name="action_menu_epg">Список EPG</string> + <string name="action_menu_search">Пошук EPG</string> + <string name="action_menu_wakeup">Пробудження</string> + <string name="app_name">VDR-менеджер</string> + <string name="channel_item_menu_epg">Показати EPG</string> + <string name="channel_item_menu_stream">Показати живий ефір</string> + <string name="channel_item_menu_hide">Сховати</string> + <string name="channel_item_menu_hide_permanent">Ховати постійно</string> + <string name="channel_group_menu_hide">Сховати</string> + <string name="channel_group_menu_hide_permanent">Ховати постійно</string> + <string name="menu_groupby">Групувати за</string> + <string name="groupby_group">Група</string> + <string name="groupby_provider">Постачальник</string> + <string name="groupby_name">Назва</string> + <string name="groupby_name_all_channels_group">Всі канали</string> + <string name="groupby_window_title_templte">Групувати за %1$s</string> + <string name="common_delete">Вилучити</string> + <string name="prefs_current_value">Поточний:</string> + <string name="prefs_current_value_template">\nПоточний: %1$s</string> + <string name="prefs_current_value_not_set"><не встановлено></string> + <string name="no_connection">Немає підключення</string> + <string name="aborted">Підключення перервано.</string> + <string name="no_connection_retry">Повторити</string> + <string name="refresh">Оновити</string> + <string name="done">Виконано</string> + <string name="share">Поділитися</string> + <string name="search_reapt">Перезапустити</string> + <string name="share_chooser">Поділитися текстом EPG</string> + <string name="about_text">Про програму \"VDR-менеджер\" для Android\n +Це версія %1$s\n +Якщо Ви маєте пристрій VDR, до якого є доступ +через інтернет і є мобільний телефон з ОС Android, тоді Ви оцінити можливості цієї прогорами. +Для більше інформації відвідайте сторінку http://projects.vdr-developer.org/projects/vdr-manager/wiki. +Автор:\n +bju<herrlado@gmail.com> +herrlado<herrlado@gmail.com> + </string> + <string name="about_title">Про програму</string> + <string name="no_internet_connection">Немає даних з’єднання</string> + <string name="update_will_start_in">Оновлення розпочнеться протягом однієї секунди</string> + <string name="epg_menu_search">Пошук EPG</string> + <string name="epg_menu_times">Пошук часів</string> + <string name="epg_item_menu_timer_add">Створити таймер</string> + <string name="epg_item_menu_timer_delete">Вилучити таймер</string> + <string name="epg_item_menu_timer_modify">Змінити таймер</string> + <string name="epg_item_menu_timer_enable">Увімкнути таймер</string> + <string name="epg_item_menu_timer_disable">Вимкнути таймер</string> + <string name="epg_no_items">Нічого не знайдено…</string> + <string name="epg_client_errors">Сталася помилка, перевірте журнали…</string> + <string name="navigae_at_the_end">Кінець</string> + <string name="navigae_at_the_start">Початок</string> + <string name="epg_search_times_add">Додати час</string> + <string name="epg_search_times_window">Час користувача</string> + <string name="epg_list_time_label">А що зараз на</string> + <string name="epg_list_time_now">Зараз</string> + <string name="epg_list_time_next">Наступний</string> + <string name="epg_list_time_adhoc">Без точки доступу</string> + <string name="epg_list_channel_spinner">Канал</string> + <string name="epg_list_search_label">Результати пошуку</string> + <string name="epg_event_share_text">Поділитися</string> + <string name="epg_event_imdb_text">Пошук IMDb</string> + <string name="epg_event_omdb_text">Пошук OMDB</string> + <string name="epg_event_tmdb_text">TMDb пошук</string> + <string name="epg_eent_livetv_text">Потік</string> + <string name="epg_event_create_timer_text">Додати таймер</string> + <string name="epg_event_modify_timer_text">Змінити таймер</string> + <string name="epg_search_button">Пошук</string> + <string name="epg_duration_template">%1$s хв</string> + <string name="epg_duration_template_live">%1$s/%2$s хв</string> + <string name="epg_of_a_channel">EPG -> %1$s, %2$s/%3$s</string> + <string name="epg_by_channel">EPG по каналу</string> + <string name="epg_by_search">Пошук EPG</string> + <string name="epg_by_search_param">Пошук EPG: \'%1$s\'</string> + <string name="epg_by_time">EPG по часу</string> + <string name="epg_by_time_args">EPG по часу: \'%1$s\'</string> + <string name="search_epg_hint">Пошук EPG</string> + <string name="epg_search_settings_description">Пошук VDR EPG</string> + <string name="epg_window_title_count">%1$s, %2$s елементів</string> + <string name="channels_window_title_count">%1$s, %2$s/%3$s</string> + <string name="new_timer">Новий таймер</string> + <string name="vdr_error_text">Зв\'язок з VDR викликав помилку: %1$s</string> + <string name="livetv">Прямий ефір</string> + <string name="settings_livetv_summary">Потрібен streamdev сервер на VDR і зовнішній програвач, наприклад VPlayer</string> + <string name="settings_livetv_streamformat">Формат потоку</string> + <string name="settings_livetv_port">Порт трансляції потоку</string> + <string name="settings_livetv_port_summary">Типово 3000. Доступ повинен бути включений в streamdevhosts.conf.</string> + <string name="key_remux_enable">remux_enable</string> + <string name="key_remux_command">remux_command</string> + <string name="key_remux_parameter">remux_parameter</string> + <string name="stream_via_as">Потік</string> + <string name="stream_via">через %s</string> + <string name="stream_as">як %s</string> + <string name="remux_title">Remux</string> + <string name="remux_enable_title">Увімкнути Remux</string> + <string name="remux_enable_summary">Активувати потік через remux (тобто externremux.sh)</string> + <string name="remux_command_title">Команда</string> + <string name="remux_command_summary">Зазвичай EXT або Extern, наприклад http://vdr:3000/EXT/1</string> + <string name="remux_parameter_title">Параметр</string> + <string name="remux_parameter_summary">Контроль якості потокової трансляції. Наприклад http://vdr:3000/EXT;DSL1000/1</string> + <string name="main_menu_preferences">Уподобання</string> + <string name="main_menu_info">Інформація</string> + <string name="main_menu_exit">Вийти</string> + <string name="main_menu_goto">Перемикач пристроїв</string> + <string name="main_menu_goto_title">Перемкнутися до...</string> + <string name="main_menu_goto_no_vdr">Не вдається завантажити вибраний пристрій :(</string> + <string name="main_menu_switched_to">Перейшли до %1$s</string> + <string name="vdr_devices_summary">Визначити один або кілька пристроїв VDR.</string> + <string name="vdr_devices">Пристрої VDR</string> + <string name="vdr_preferences">Параметри мережі</string> + <string name="vdr_host_title">Вузол VDR</string> + <string name="vdr_host_summary">Вузол з запущеним VDR</string> + <string name="vdr_port_title">Порт додатку VDR </string> + <string name="vdr_port_summary">Порт для підключення до додатку VDR</string> + <string name="vdr_port_default">6420</string> + <string name="vdr_password_title">Пароль додатку VDR</string> + <string name="vdr_password_summary">Пароль для додатка VDR</string> + <string name="vdr_ssl_title">Безпечне підключення</string> + <string name="vdr_ssl_summary">Використовувати SSL для підключень (в даний час не підтримується)</string> + <string name="channel_filter_preferences">Налаштування каналу</string> + <string name="channel_filter_filter_title">Обмеження на канали</string> + <string name="channel_filter_filter_summary">Вокористовувати тільки дані канали</string> + <string name="channel_filter_last_title">Фільтр каналів</string> + <string name="channel_filter_last_summary">Розділені комами номери каналів або діапазони (роздільник \"-\"). Наприклад 1,2,4-10</string> + <string name="wakeup_preferences">Пробудження віддаленого VDR</string> + <string name="wakeup_enabled_title">Може пробудити віддалений вузол VDR</string> + <string name="wakeup_enabled_summary">Дозволяє пробудити віддалений вузол VDR</string> + <string name="wakeup_url_title">URL-адреса для віддаленого пробудження</string> + <string name="wakeup_url_summary">URL-адреса для запиту пробудження</string> + <string name="wakeup_user_title">Користувач пробудження</string> + <string name="wakeup_user_summary">Користувач віддаленого пробудження</string> + <string name="wakeup_password_title">Пароль пробудження</string> + <string name="wakeup_password_summary">Пароль для віддаленого пробудження</string> + <string name="wakeup_method_title">Метод пробудження</string> + <string name="wakeup_method_summary">Виберіть метод пробудження вузла VDR</string> + <string name="default_wakeup_method">wol</string> + <string name="wakeup_wol_custom_boradcast_title">IP-адреса призначення</string> + <string name="wakeup_wol_custom_boradcast_summary">Якщо у Вас немає статичних таблиці ARP, Вам потрібно використовувати якусь широкомовну адресу.</string> + <string name="wakeup_wol_mac_title">MAC-адреса</string> + <string name="wakeup_wol_mac_summary">MAC-адреса вузла VDR. Використайте \':\' або \'-\' або пропуск як роздільник.</string> + <string name="timer_preferences">Типовий таймер</string> + <string name="timer_pre_start_buffer_title">Зміщення при початку</string> + <string name="timer_pre_start_buffer_summary">Хвилини запису перед початком трансляції</string> + <string name="timer_post_end_buffer_title">Зміщення при зупинці</string> + <string name="timer_post_end_buffer_summary">Хвилини запису після закінчення трансляції</string> + <string name="timer_default_priority_title">Типовий пріоритет</string> + <string name="timer_default_priority_summary">Типовий пріоритет</string> + <string name="timer_default_primary_limit_title">Типове основне обмеження</string> + <string name="timer_default_primary_limit_summary">Типове основне обмеження</string> + <string name="timer_default_lifetime_title">Типова тривалість</string> + <string name="timer_default_lifetime_summary">Типова тривалість</string> + <string name="gui_preferences">Налаштування графічного інтерфейсу</string> + <string name="gui_enable_24h_format_title">Використання 24-годинного формату</string> + <string name="gui_enable_24h_format_summary_on">13:00</string> + <string name="gui_enable_24h_format_summary_off">1:00 вечора</string> + <string name="gui_channels_show_channel_numbers_title">Показати номери каналів</string> + <string name="gui_channels_show_channel_numbers_summary">Показати номери каналів у списку каналів.</string> + <string name="gui_quit_on_back_title">Вийти на кнопку \"Назад\"</string> + <string name="gui_quit_on_back_summary_on">Кнопки \"Назад\" завершує роботу VDR-менеджера</string> + <string name="gui_quit_on_back_summary_off">Кнопка \"Назад\" не завершує роботу VDR-менеджера</string> + <string name="qui_show_imdb_button_title">Показати кнопку IMDb</string> + <string name="qui_show_imdb_button_summary_on">Кнопка IMDb відображається</string> + <string name="qui_show_imdb_button_summary_off">Кнопка IMDb не відображається</string> + <string name="qui_imdb_url_title">Сторінка IMDb</string> + <string name="qui_imdb_url_summary">На якій сторінці IMDb шукати.</string> + <string name="qui_show_omdb_button_title">Показати кнопку OMDB</string> + <string name="qui_show_omdb_button_summary_on">Кнопка OMDB відображається</string> + <string name="qui_show_omdb_button_summary_off">Кнопка OMDB не відображається</string> + <string name="qui_show_tmdb_button_title">Показати кнопку TMDb</string> + <string name="qui_show_tmdb_button_summary_on">Кнопка TMDb відображається</string> + <string name="qui_show_tmdb_button_summary_off">Кнопка TMDb не відображається</string> + <string name="gui_custom_locale_title">Мова</string> + <string name="gui_custom_locale_sum">Встановити мову.</string> + <string name="vdr_advanced_preferences">Додатково</string> + <string name="vdr_advanced_preferences_summary">Додаткові параметри</string> + <string name="vdr_conntimeout_title">Затримка з\'єднання</string> + <string name="vdr_conntimeout_sum">Як довго (в секундах) почекати, перш ніж встановиться підключення?</string> + <string name="vdr_readtimeout_title">Час очікування читання</string> + <string name="vdr_readtimeout_sum">Як довго (в секундах) очікувати для кожної операції читання рядка?</string> + <string name="vdr_timeout_title">Загальний час очікування</string> + <string name="vdr_timeout_sum">Як довго (в секундах) очікавати на операцію вводу/виводу, перш ніж вона перерветься?</string> + <string name="streaming_password_title">Пароль Streamdev</string> + <string name="streaming_password_sum">Встановити пароль користувача сервера потокового відео (наприклад: -a \'користувач:пароль\')</string> + <string name="streaming_username_title">Ім\'я користувача Streamdev</string> + <string name="streaming_username_sum">Встановити ім\'я користувача сервера потокового відео (наприклад: -a \'користувач:пароль\')</string> + <string name="vdr_encoding_title">Кодування символів</string> + <string name="vdr_encoding_summary">Кодування символів Вашого VDR пристрою. За замовчуванням UTF-8.</string> + <string name="new_vdr">Новий VDR</string> + <string name="no_vdr">Немає VDR пристроїв</string> + <string name="vdr_devices_category">Пристрої VDR</string> + <string name="vdr_prefs_category">Пристрій</string> + <string name="vdr_name_title">Назва</string> + <string name="vdr_name_summary">Назва для цього пристрою</string> + <string name="vdr_device_delete_qeustion">Вилучити цей пристрій?</string> + <string name="recstream">Потокове передавання записів</string> + <string name="recstream_enable_title">Потокове передавання записів</string> + <string name="recstream_enable_summary">Увімкнення потокового передавання записів</string> + <string name="recstream_method_title">Метод передачі потоку</string> + <string name="recstream_method_summary">На даний час потоковий ефір через додаток VDR live підтримується</string> + <string name="settings_live_port">Порт додатка VDR live</string> + <string name="settings_live_port_summary">Додаток VDR live має стандартний порт 8008.</string> + <string name="progress_connect">Підключення...</string> + <string name="progress_connect_error">Невдале з’єднання!</string> + <string name="progress_connect_timeout">Затримка з\'єднання!</string> + <string name="progress_login">Логін.</string> + <string name="progress_login_error">Увійти не вдалося.</string> + <string name="progress_whatson_loading">Завантаження EPG…</string> + <string name="progress_timers_loading">Завантаження таймерів…</string> + <string name="progress_recordings_loading">Завантаження записів…</string> + <string name="progress_channels_loading">Завантаження каналів…</string> + <string name="progress_disconnect">Відключення…</string> + <string name="progress_wakeup_sending">Ініціювання запиту пробудження…</string> + <string name="progress_wakeup_sent">Запит пробудження надісланий</string> + <string name="progress_wakeup_error">Помилка при відправці запиту пробудження: %1$s</string> + <string name="progress_timer_save">Збереження таймера...</string> + <string name="progress_timer_delete">Вилучення таймера...</string> + <string name="progress_recording_delete">Вилучення запису...</string> + <string name="progress_timer_enable">Включення таймера...</string> + <string name="progress_timer_modify">Оновлення таймера...</string> + <string name="progress_timer_disable">Відключення таймера...</string> + <string name="progress_connect_finished_abnormal">Зв’язок несподівано завершено</string> + <string name="progress_connect_finished_abnormal_arg">Зв’язок несподівано завершено: %1$s</string> + <string name="progress_cache_hit">Завантажено з кешу</string> + <string name="recording_item_menu_delete">Вилучити</string> + <string name="recording_item_menu_stream">Потік</string> + <string name="recent_channels">Недавні канали</string> + <string name="recent_channels_no_history">Немає історії...</string> + <string name="gui_max_recent_channels_title">Макс. к-сть недавніх каналів</string> + <string name="gui_max_recent_channels_summary">Скільки каналів повинно зберігатися в недавніх каналах?</string> + <string-array name="livetv_streamformat"> + <item>TS</item> + <item>PES</item> + <item>ES</item> + <item>PS</item> + </string-array> + <string-array name="livetv_streamformat_values"> + <item>TS</item> + <item>PES</item> + <item>ES</item> + <item>PS</item> + </string-array> + <string-array name="wakeup_methods"> + <item>Виклик URL</item> + <item>WOL (пробудження через інтернет)</item> + </string-array> + <string-array name="imdb_urls"> + <item>Міжнародний</item> + <item>imdb.com</item> + <item>uk.imdb.com</item> + <item>imdb.de</item> + <item>imdb.es</item> + <item>imdb.fr</item> + <item>imdb.it</item> + <item>imdb.pt</item> + </string-array> + <string-array name="lang"> + <item>Англійська</item> + <item>Німецька</item> + <item>Італійська</item> + </string-array> + <string-array name="remux_entries"> + <item>EXT</item> + <item>EXTERN (не рекомендується)</item> + </string-array> + <string-array name="recstream_entries"> + <item>Додаток VDR live</item> + </string-array> +</resources> diff --git a/vdrmanager/res/values/strings.xml b/vdrmanager/res/values/strings.xml index f85fe60..8b537bb 100644 --- a/vdrmanager/res/values/strings.xml +++ b/vdrmanager/res/values/strings.xml @@ -309,4 +309,29 @@ <string name="recent_channels_no_history">No history…</string> <string name="gui_max_recent_channels_title">Max. recent channels</string> <string name="gui_max_recent_channels_summary">How many channels should be kept in the recent channels?</string> + <string name="timer_detail_day_title">Day</string> + + <!-- Repeat options that appear under an alarm on main Alarm Clock + screen to identify repetition schedule: special case for when + the alarm is set to repeat every day --> + <string name="every_day">Every day</string> + + <!-- Repeat options that appear under an alarm on main Alarm Clock + screen to identify repetition schedule: special case for when + the alarm is set to never repeat --> + <string name="never">Never</string> + + <!-- Repeat options that appear under an alarm on main Alarm Clock + screen to identify repetition schedule: concatenate days with + this character, i.e. "Mon, Tue, Wed" --> + <string name="day_concat">", "</string> + <string name="timer_detail_repeat_title">Repeat</string> + <string name="timer_detail_use_vps">Use VPS:</string> + <string name="timer_detail_priority">Priority:</string> + <string name="timer_detail_lifetime">Lifetime:</string> + <string name="timer_detail_lifetime_hint">e.g. 99</string> + <string name="timer_detail_priority_hint">e.g. 50</string> + + + <string name="timer_detail_title_vps">%1$s (VPS)</string> </resources>
\ No newline at end of file diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/Preferences.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/Preferences.java index 88156cd..a846596 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/data/Preferences.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/Preferences.java @@ -4,16 +4,12 @@ import java.util.List; import java.util.Locale; import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; import android.text.TextUtils; -import android.widget.Toast; import de.bjusystems.vdrmanager.R; import de.bjusystems.vdrmanager.StringUtils; -import de.bjusystems.vdrmanager.app.Intents; import de.bjusystems.vdrmanager.data.db.OrmDatabaseHelper; -import de.bjusystems.vdrmanager.gui.VdrListActivity; /** * Class for all preferences diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/data/Timer.java b/vdrmanager/src/de/bjusystems/vdrmanager/data/Timer.java index 0c8ce4e..929165c 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/data/Timer.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/data/Timer.java @@ -15,8 +15,14 @@ import de.bjusystems.vdrmanager.gui.Utils; * @author bju */ public class Timer extends Event implements Timerable{ - - private static final int ENABLED = 1; + + +// tfActive = 0x0001, +// tfInstant = 0x0002, +// tfVps = 0x0004, +// tfRecording = 0x0008, +// tfAll = 0xFFFF, + private static final int ACTIVE = 1; private static final int INSTANT = 2; private static final int VPS = 4; private static final int RECORDING = 8; @@ -25,6 +31,27 @@ public class Timer extends Event implements Timerable{ private int flags; private int priority; private int lifetime; + private String weekdays = "-------"; + + public void setPriority(int priority) { + this.priority = priority; + } + + + public void setLifetime(int lifetime) { + this.lifetime = lifetime; + } + + + public String getWeekdays() { + return weekdays; + } + + + public void setWeekdays(String weekdays) { + this.weekdays = weekdays; + } + /** * Constructs a timer from SvdrpHelper result line @@ -72,6 +99,10 @@ public class Timer extends Event implements Timerable{ this.channelId = values[12]; } + if(values.length > 13) { + this.weekdays = values[13]; + } + description = Utils.mapSpecialChars(description); } @@ -86,6 +117,7 @@ public class Timer extends Event implements Timerable{ t.start = new Date(start.getTime()); t.stop = new Date(stop.getTime()); t.title = title; + t.weekdays = weekdays; return t; } @@ -93,7 +125,7 @@ public class Timer extends Event implements Timerable{ final Preferences prefs = Preferences.getPreferences(); this.number = 0; - this.flags = ENABLED; + this.flags = ACTIVE; this.channelNumber = event.getChannelNumber(); this.channelName = event.getChannelName(); this.channelId = event.getChannelId(); @@ -119,7 +151,7 @@ public class Timer extends Event implements Timerable{ final Calendar cal = new GregorianCalendar(); cal.setTime(start); - line.append(String.format("%04d-%02d-%02d:", cal.get(Calendar.YEAR), + line.append((weekdays.equals("-------") == false ? weekdays + "@" : "") + String.format("%04d-%02d-%02d:", cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH))); line.append(String.format("%02d%02d:", cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE))); @@ -157,7 +189,7 @@ public class Timer extends Event implements Timerable{ } public boolean isEnabled() { - return (flags & ENABLED) == ENABLED; + return (flags & ACTIVE) == ACTIVE; } public boolean isInstant() { @@ -180,11 +212,19 @@ public class Timer extends Event implements Timerable{ this.stop = stop; } + public void setVps(boolean useVps){ + if(useVps){ + flags = flags | VPS; + } else { + flags = flags & ~VPS; + } + } + public void setEnabled(final boolean enabled) { if (enabled) { - flags = flags | ENABLED; + flags = flags | ACTIVE; } else { - flags = flags & ~ENABLED; + flags = flags & ~ACTIVE; } } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseActivity.java index 39f03b3..2da2a67 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/BaseActivity.java @@ -227,6 +227,9 @@ public abstract class BaseActivity<Result, T extends ListView> extends ICSBaseAc } protected void alert(String msg) { + if(isFinishing()){ + return; + } new AlertDialog.Builder(this)// .setMessage(msg)// .setPositiveButton(android.R.string.ok, null)// diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelListActivity.java index ee67b90..08a1956 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelListActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/ChannelListActivity.java @@ -35,6 +35,7 @@ import de.bjusystems.vdrmanager.tasks.VoidAsyncTask; import de.bjusystems.vdrmanager.utils.svdrp.ChannelClient; import de.bjusystems.vdrmanager.utils.svdrp.SvdrpAsyncTask; import de.bjusystems.vdrmanager.utils.svdrp.SvdrpClient; +import de.bjusystems.vdrmanager.utils.svdrp.SvdrpEvent; /** * This class is used for showing what's current running on all channels @@ -60,6 +61,8 @@ public class ChannelListActivity extends public static final int MENU_NAME = 2; private int groupBy = MENU_GROUP; + + private int groupByInverse = 0; final static ArrayList<String> ALL_CHANNELS_GROUP = new ArrayList<String>(1); @@ -106,8 +109,16 @@ public class ChannelListActivity extends return; } - // get channel task - channelClient = new ChannelClient(useCache); + if(channelClient == null){ + // get channel task + channelClient = new ChannelClient(); + } else { + channelClient.removeSvdrpListener(this); + } + + if(useCache == false){ + ChannelClient.clearCache(); + } // create background task final SvdrpAsyncTask<Channel, SvdrpClient<Channel>> task = new SvdrpAsyncTask<Channel, SvdrpClient<Channel>>( @@ -504,5 +515,9 @@ public class ChannelListActivity extends protected SvdrpClient<Channel> getClient() { return channelClient; } + + public void svdrpEvent(SvdrpEvent event, Channel result){ + super.svdrpEvent(event, result); + } }
\ No newline at end of file diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventEpgListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventEpgListActivity.java index 14273c2..eedcc76 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventEpgListActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/EventEpgListActivity.java @@ -107,7 +107,7 @@ public class EventEpgListActivity extends BaseTimerEditActivity<Epg> implements } private void startQuery() { - new ChannelsTask(this, new ChannelClient(true)) { + new ChannelsTask(this, new ChannelClient()) { public void finished(SvdrpEvent event) { if (event == SvdrpEvent.CACHE_HIT || event == SvdrpEvent.FINISHED_SUCCESS) { diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/RecordingListActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/RecordingListActivity.java index 64faf73..0b1cda7 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/RecordingListActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/RecordingListActivity.java @@ -1,12 +1,16 @@ package de.bjusystems.vdrmanager.gui; +import java.util.ArrayList; import java.util.Calendar; -import android.content.ClipData.Item; +import android.app.AlertDialog; +import android.content.DialogInterface; + import android.os.Bundle; -import android.util.Log; + import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; +import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; @@ -37,6 +41,18 @@ public class RecordingListActivity extends BaseEventListActivity<Recording> RecordingClient recordingClient; + public static final int MENU_DATE = 0; + public static final int MENU_NAME = 1; + public static final int MENU_CHANNEL = 2; + + public static final int ASC = 0; + + public static final int DESC = 1; + + private int groupBy = MENU_DATE; + + private int ASC_DESC = ASC; + @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -61,6 +77,64 @@ public class RecordingListActivity extends BaseEventListActivity<Recording> } + private String[] getAvailableGroupByEntries() { + ArrayList<String> entries = new ArrayList<String>(2); + entries.add(getString(R.string.groupby_date)); + entries.add(getString(R.string.groupby_name)); + entries.add(getString(R.string.groupby_channel)); + return entries.toArray(Utils.EMPTY); + } + + AlertDialog groupByDialog = null; + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + switch (item.getItemId()) { + case R.id.menu_groupby: + // case MENU_PROVIDER: + // case MENU_NAME: + if (groupByDialog == null) { + groupByDialog = new AlertDialog.Builder(this) + .setTitle(R.string.menu_groupby) + .setIcon(android.R.drawable.ic_menu_sort_alphabetically) + .setSingleChoiceItems(getAvailableGroupByEntries(), + groupBy, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int which) { + if(groupBy == which){ + ASC_DESC = ASC_DESC == ASC ? DESC : ASC; + } else { + groupBy = which; + ASC_DESC = ASC; + } + //fillAdapter(); + groupByDialog.dismiss(); + } + }).create(); + } + + groupByDialog.show(); + + return true; + default: + return super.onOptionsItemSelected(item); + } + } + /* + * (non-Javadoc) + * + * @see + * de.bjusystems.vdrmanager.gui.BaseActivity#onCreateOptionsMenu(android + * .view.Menu) + */ + @Override + public boolean onCreateOptionsMenu(final Menu menu) { + final MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.recording_list_menu, menu); + return super.onCreateOptionsMenu(menu); + } + @Override protected SvdrpClient<Recording> getClient() { diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerDetailsActivity.java b/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerDetailsActivity.java index 599d18d..14ca7a1 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerDetailsActivity.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/gui/TimerDetailsActivity.java @@ -1,19 +1,26 @@ package de.bjusystems.vdrmanager.gui; +import java.text.DateFormatSymbols; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import android.app.Activity; +import android.app.AlertDialog; import android.app.DatePickerDialog; import android.app.DatePickerDialog.OnDateSetListener; import android.app.TimePickerDialog; import android.app.TimePickerDialog.OnTimeSetListener; +import android.content.Context; +import android.content.DialogInterface; import android.os.Bundle; +import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; +import android.widget.CheckBox; import android.widget.DatePicker; +import android.widget.EditText; import android.widget.TextView; import android.widget.TimePicker; import android.widget.Toast; @@ -30,36 +37,44 @@ import de.bjusystems.vdrmanager.utils.svdrp.SvdrpEvent; public class TimerDetailsActivity extends Activity implements OnClickListener, OnDateSetListener, OnTimeSetListener { - public static final int REQUEST_CODE_TIMER_MODIFIED = 34; public static final int REQUEST_CODE_TIMER_EDIT = 35; - + public static final int REQUEST_CODE_TIMER_ADD = 36; - + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - View view = getLayoutInflater().inflate(R.layout.timer_detail, null); tView = new EditTimerViewHolder(); tView.view = view; tView.title = (TextView) view.findViewById(R.id.timer_detail_title); tView.channel = (TextView) view.findViewById(R.id.timer_detail_channel); tView.dateField = (Button) view.findViewById(R.id.timer_detail_day); - tView.startField = (Button) view - .findViewById(R.id.timer_detail_start); + tView.startField = (Button) view.findViewById(R.id.timer_detail_start); tView.endField = (Button) view.findViewById(R.id.timer_detail_end); tView.saveButton = (Button) view.findViewById(R.id.timer_details_save); tView.modifyButton = (Button) view .findViewById(R.id.timer_details_modify); + tView.repeat = (Button) view.findViewById(R.id.timer_detail_repeat); + + tView.vps = (CheckBox) view.findViewById(R.id.timer_detail_vps); + + tView.priority = (EditText) view + .findViewById(R.id.timer_detail_priority); + + tView.lifecycle = (EditText) view + .findViewById(R.id.timer_detail_lifetime); + view.findViewById(R.id.timer_details_cancel).setOnClickListener(this); tView.dateField.setOnClickListener(this); tView.startField.setOnClickListener(this); tView.endField.setOnClickListener(this); tView.saveButton.setOnClickListener(this); tView.modifyButton.setOnClickListener(this); + tView.repeat.setOnClickListener(this); setContentView(view); timer = getApp().getCurrentTimer(); original = timer.copy(); @@ -89,6 +104,10 @@ public class TimerDetailsActivity extends Activity implements OnClickListener, Button endField; Button saveButton; Button modifyButton; + CheckBox vps; + Button repeat; + EditText priority; + EditText lifecycle; } EditTimerViewHolder tView = null; @@ -98,7 +117,7 @@ public class TimerDetailsActivity extends Activity implements OnClickListener, // SetTimerClient setTimerClient; Timer timer; - + Timer original; private void updateDisplay(TimerOperation op) { @@ -122,10 +141,17 @@ public class TimerDetailsActivity extends Activity implements OnClickListener, EventFormatter f = new EventFormatter(timer, true); tView.channel.setText(timer.getChannelNumber() + " " + timer.getChannelName()); + // tView.title.setText(timer.isVps() ? + // getString(R.string.timer_detail_title_vps, f.getTitle()) : + // f.getTitle()); tView.title.setText(f.getTitle()); tView.dateField.setText(f.getDate()); tView.startField.setText(f.getTime()); tView.endField.setText(f.getStop()); + tView.vps.setChecked(timer.isVps()); + tView.priority.setText(String.valueOf(timer.getPriority())); + tView.lifecycle.setText(String.valueOf(timer.getLifetime())); + tView.repeat.setText(getSelectedItems().toString(this, true)); } protected VdrManagerApp getApp() { @@ -173,26 +199,96 @@ public class TimerDetailsActivity extends Activity implements OnClickListener, break; } case R.id.timer_details_cancel: { -// finishActivity(REQUEST_CODE_TIMER_EDIT); + // finishActivity(REQUEST_CODE_TIMER_EDIT); finish(); break; } case R.id.timer_details_modify: timer.setTitle(tView.title.getText().toString()); + timer.setVps(tView.vps.isChecked()); + timer.setPriority(getIntOr0(tView.priority)); + timer.setLifetime(getIntOr0(tView.lifecycle)); + modifyTimer(timer); - //say(R.string.done); + // say(R.string.done); break; case R.id.timer_details_save: { timer.setTitle(tView.title.getText().toString()); + createTimer(timer); - //say(R.string.done); + // say(R.string.done); break; } - + + case R.id.timer_detail_repeat: { + + String[] weekdays = new DateFormatSymbols().getWeekdays(); + String[] values = new String[] { weekdays[Calendar.MONDAY], + weekdays[Calendar.TUESDAY], weekdays[Calendar.WEDNESDAY], + weekdays[Calendar.THURSDAY], weekdays[Calendar.FRIDAY], + weekdays[Calendar.SATURDAY], weekdays[Calendar.SUNDAY], }; + + final DaysOfWeek mNewDaysOfWeek = new DaysOfWeek(0); + + final AlertDialog b = new AlertDialog.Builder(this) + .setMultiChoiceItems(values, getSelectedItems().getBooleanArray(), + new DialogInterface.OnMultiChoiceClickListener() { + public void onClick(DialogInterface dialog, + int which, boolean isChecked) { + mNewDaysOfWeek.set(which, isChecked); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int which) { + StringBuilder sb = new StringBuilder(7); + sb.append(mNewDaysOfWeek.isSet(0) ? 'M' : '-'); + sb.append(mNewDaysOfWeek.isSet(1) ? 'T' : '-'); + sb.append(mNewDaysOfWeek.isSet(2) ? 'W' : '-'); + sb.append(mNewDaysOfWeek.isSet(3) ? 'T' : '-'); + sb.append(mNewDaysOfWeek.isSet(4) ? 'F' : '-'); + sb.append(mNewDaysOfWeek.isSet(5) ? 'S' : '-'); + sb.append(mNewDaysOfWeek.isSet(6) ? 'S' : '-'); + timer.setWeekdays(sb.toString()); + tView.repeat.setText(mNewDaysOfWeek.toString(TimerDetailsActivity.this, true)); + } + }).create(); + + b.show(); + } } } + DaysOfWeek getSelectedItems() { + String str = timer.getWeekdays(); + + DaysOfWeek dow = new DaysOfWeek(0); + if (str.length() != 7) { + return dow; + } + + + dow.set(0, str.charAt(0) == 'M'); + dow.set(1, str.charAt(1) == 'T'); + dow.set(2, str.charAt(2) == 'W'); + dow.set(3, str.charAt(3) == 'T'); + dow.set(4, str.charAt(4) == 'F'); + dow.set(5, str.charAt(5) == 'S'); + dow.set(6, str.charAt(6) == 'S'); + + return dow; + } + + private int getIntOr0(EditText text) { + if (TextUtils.isEmpty(text.getText().toString())) { + return 0; + } + return Integer.valueOf(text.getText().toString()); + } + protected void say(int res) { Toast.makeText(this, res, Toast.LENGTH_SHORT).show(); } @@ -273,4 +369,95 @@ public class TimerDetailsActivity extends Activity implements OnClickListener, task.start(); } + /* + * Days of week code as a single int. 0x00: no day 0x01: Monday 0x02: + * Tuesday 0x04: Wednesday 0x08: Thursday 0x10: Friday 0x20: Saturday 0x40: + * Sunday + */ + static final class DaysOfWeek { + + private static int[] DAY_MAP = new int[] { Calendar.MONDAY, + Calendar.TUESDAY, Calendar.WEDNESDAY, Calendar.THURSDAY, + Calendar.FRIDAY, Calendar.SATURDAY, Calendar.SUNDAY, }; + + // Bitmask of all repeating days + private int mDays; + + DaysOfWeek(int days) { + mDays = days; + } + + public String toString(Context context, boolean showNever) { + StringBuilder ret = new StringBuilder(); + + // no days + if (mDays == 0) { + return showNever ? context.getText(R.string.never).toString() + : ""; + } + + // every day + if (mDays == 0x7f) { + return context.getText(R.string.every_day).toString(); + } + + // count selected days + int dayCount = 0, days = mDays; + while (days > 0) { + if ((days & 1) == 1) + dayCount++; + days >>= 1; + } + + // short or long form? + DateFormatSymbols dfs = new DateFormatSymbols(); + String[] dayList = (dayCount > 1) ? dfs.getShortWeekdays() : dfs + .getWeekdays(); + + // selected days + for (int i = 0; i < 7; i++) { + if ((mDays & (1 << i)) != 0) { + ret.append(dayList[DAY_MAP[i]]); + dayCount -= 1; + if (dayCount > 0) + ret.append(context.getText(R.string.day_concat)); + } + } + return ret.toString(); + } + + private boolean isSet(int day) { + return ((mDays & (1 << day)) > 0); + } + + public void set(int day, boolean set) { + if (set) { + mDays |= (1 << day); + } else { + mDays &= ~(1 << day); + } + } + + public void set(DaysOfWeek dow) { + mDays = dow.mDays; + } + + public int getCoded() { + return mDays; + } + + // Returns days of week encoded in an array of booleans. + public boolean[] getBooleanArray() { + boolean[] ret = new boolean[7]; + for (int i = 0; i < 7; i++) { + ret[i] = isSet(i); + } + return ret; + } + + public boolean isRepeatSet() { + return mDays != 0; + } + + } } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/ChannelClient.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/ChannelClient.java index 8f60124..ecbed98 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/ChannelClient.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/ChannelClient.java @@ -28,11 +28,11 @@ public class ChannelClient extends SvdrpClient<Channel> implements private static boolean inited = false; - public ChannelClient(boolean useCache) { + public ChannelClient() { super(); - if (useCache == false) { - clearCache(); - } +// if (useCache == false) { +// clearCache(); +// } addSvdrpListener(this); } @@ -86,7 +86,7 @@ public class ChannelClient extends SvdrpClient<Channel> implements if (inited == true) { informListener(SvdrpEvent.CACHE_HIT, null); } else { - runCommand("channels " + Preferences.getPreferences().getChannels()); + runCommand("channels " + Preferences.get().getChannels()); } } diff --git a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpAsyncTask.java b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpAsyncTask.java index fd4c63b..743fca6 100644 --- a/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpAsyncTask.java +++ b/vdrmanager/src/de/bjusystems/vdrmanager/utils/svdrp/SvdrpAsyncTask.java @@ -42,6 +42,9 @@ public class SvdrpAsyncTask<Result, Client extends SvdrpClient<Result>> public void svdrpEvent(final SvdrpEvent event, final Result result) { publishProgress(event, result); + if(event == SvdrpEvent.FINISHED_SUCCESS || event == SvdrpEvent.FINISHED_ABNORMALY || event == SvdrpEvent.ABORTED || event == SvdrpEvent.ERROR || event == SvdrpEvent.CACHE_HIT){ + client.removeSvdrpListener(this); + } } @SuppressWarnings("unchecked") |