diff options
author | steckbrief <steckbrief@chefmail.de> | 2015-10-04 14:55:15 +0200 |
---|---|---|
committer | steckbrief <steckbrief@chefmail.de> | 2015-10-04 15:24:44 +0200 |
commit | 52aa81e82e57a2c1d0074d482e8e706960492b8a (patch) | |
tree | 26c21b35f4b70f840693877a782514498ce94db0 | |
parent | a3d62e6a10df307786079a2cc1f93eee591f96c5 (diff) |
Implements FS#72, FS#72, FS#73, FS#65, FS#66 - Resource List Dialog added, Open resource
list on long click in conversations overview, open resource list on click
on bare jid in contact details view, Message details dialog added
13 files changed, 473 insertions, 4 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ContactDetailsActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/ContactDetailsActivity.java index c84f9b89..bf0c126e 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/ContactDetailsActivity.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/ContactDetailsActivity.java @@ -39,6 +39,7 @@ import de.thedevstack.conversationsplus.entities.Contact; import de.thedevstack.conversationsplus.entities.ListItem; import de.thedevstack.conversationsplus.services.XmppConnectionService.OnAccountUpdate; import de.thedevstack.conversationsplus.services.XmppConnectionService.OnRosterUpdate; +import de.thedevstack.conversationsplus.ui.listeners.ShowResourcesListDialogListener; import de.thedevstack.conversationsplus.utils.CryptoHelper; import de.thedevstack.conversationsplus.utils.UIHelper; import de.thedevstack.conversationsplus.xmpp.OnUpdateBlocklist; @@ -350,6 +351,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd } else { contactJidTv.setText(contact.getJid().toString()); } + contactJidTv.setOnClickListener(new ShowResourcesListDialogListener(ContactDetailsActivity.this, contact)); accountJidTv.setText(getString(R.string.using_account, contact.getAccount().getJid().toBareJid())); badge.setImageBitmap(avatarService().get(contact, getPixel(72))); badge.setOnClickListener(this.onBadgeClick); diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java index 8bd7e81e..d715aee2 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java @@ -42,8 +42,8 @@ import java.util.List; import java.util.NoSuchElementException; import java.util.concurrent.ConcurrentLinkedQueue; +import de.thedevstack.conversationsplus.ui.dialogs.MessageDetailsDialog; import de.thedevstack.conversationsplus.ui.listeners.ConversationSwipeRefreshListener; -import de.tzur.conversations.Settings; import de.thedevstack.conversationsplus.Config; import de.thedevstack.conversationsplus.R; import de.thedevstack.conversationsplus.crypto.PgpEngine; @@ -66,7 +66,6 @@ import de.thedevstack.conversationsplus.utils.GeoHelper; import de.thedevstack.conversationsplus.utils.UIHelper; import de.thedevstack.conversationsplus.xmpp.chatstate.ChatState; import de.thedevstack.conversationsplus.xmpp.jid.Jid; -import github.ankushsachdeva.emojicon.EmojiconEditText; import github.ankushsachdeva.emojicon.EmojiconGridView; import github.ankushsachdeva.emojicon.EmojiconsPopup; import github.ankushsachdeva.emojicon.emoji.Emojicon; @@ -502,6 +501,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { + case R.id.msg_ctx_mnu_details: + new MessageDetailsDialog(getActivity(), selectedMessage).show(); + return true; case R.id.share_with: shareWith(selectedMessage); return true; diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java index d6b944d0..dab291cc 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java @@ -21,6 +21,7 @@ import java.lang.ref.WeakReference; import java.util.List; import java.util.concurrent.RejectedExecutionException; +import de.thedevstack.conversationsplus.ui.listeners.ShowResourcesListDialogListener; import de.tzur.conversations.Settings; import de.thedevstack.conversationsplus.R; import de.thedevstack.conversationsplus.entities.Account; @@ -128,7 +129,8 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> { mTimestamp.setText(UIHelper.readableTimeDifference(activity,conversation.getLatestMessage().getTimeSent())); ImageView profilePicture = (ImageView) view.findViewById(R.id.conversation_image); - loadAvatar(conversation,profilePicture); + profilePicture.setOnLongClickListener(new ShowResourcesListDialogListener(activity, conversation.getContact())); + loadAvatar(conversation, profilePicture); return view; } diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/PresencesArrayAdapter.java b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/PresencesArrayAdapter.java new file mode 100644 index 00000000..0b5cb897 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/PresencesArrayAdapter.java @@ -0,0 +1,63 @@ +package de.thedevstack.conversationsplus.ui.adapter; + +import android.content.Context; +import android.graphics.Color; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.Map; + +import de.thedevstack.conversationsplus.R; +import de.thedevstack.conversationsplus.entities.Presences; +import de.thedevstack.conversationsplus.utils.UIHelper; + +/** + * Created by tzur on 27.09.2015. + */ +public class PresencesArrayAdapter extends ArrayAdapter<Presence> { + private final Context context; + private final Presence[] values; + + public PresencesArrayAdapter(Context context, Presences presences) { + super(context, R.layout.dialog_resources_status); + this.context = context; + this.values = getPresenceArray(presences); + addAll(this.values); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + LayoutInflater inflater = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View rowView = inflater.inflate(R.layout.dialog_resources_status, parent, false); + TextView textView = (TextView) rowView.findViewById(R.id.dlg_res_stat_resource_name); + textView.setText(this.values[position].resource); + textView.setTextColor(Color.parseColor(UIHelper.getStatusColor(this.values[position].status))); + + return rowView; + } + + private static Presence[] getPresenceArray(Presences presences) { + ArrayList<Presence> presenceArrayList = new ArrayList<>(); + if (null != presences && null != presences.getPresences() && !presences.getPresences().isEmpty()) { + for (Map.Entry<String, Integer> entry : presences.getPresences().entrySet()) { + Presence p = new Presence(); + p.resource = entry.getKey(); + p.status = entry.getValue(); + presenceArrayList.add(p); + } + presenceArrayList.trimToSize(); + } + return presenceArrayList.toArray(new Presence[0]); + } +} + +class Presence { + String resource; + int status; +} diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/AbstractAlertDialog.java b/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/AbstractAlertDialog.java new file mode 100644 index 00000000..10764798 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/AbstractAlertDialog.java @@ -0,0 +1,125 @@ +package de.thedevstack.conversationsplus.ui.dialogs; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.database.Cursor; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListAdapter; + +import de.thedevstack.conversationsplus.R; + +/** + * Created by tzur on 29.09.2015. + */ +public class AbstractAlertDialog { + protected AlertDialog.Builder builder; + + public AbstractAlertDialog(Context context, String title) { + this.builder = new AlertDialog.Builder(context); + this.builder.setTitle(title); + this.builder.setPositiveButton(R.string.cplus_ok, null); + } + + public AbstractAlertDialog(Context context, int titleTextId) { + this(context, context.getString(titleTextId)); + } + + public void show() { + this.builder.show(); + } + + public Context getContext() { + return builder.getContext(); + } + + public AlertDialog.Builder setTitle(int titleId) { + return builder.setTitle(titleId); + } + + public AlertDialog.Builder setTitle(CharSequence title) { + return builder.setTitle(title); + } + + public AlertDialog.Builder setIcon(int iconId) { + return builder.setIcon(iconId); + } + + public AlertDialog.Builder setIcon(Drawable icon) { + return builder.setIcon(icon); + } + + public AlertDialog.Builder setMessage(CharSequence message) { + return builder.setMessage(message); + } + + public AlertDialog.Builder setMessage(int messageId) { + return builder.setMessage(messageId); + } + + public AlertDialog.Builder setIconAttribute(int attrId) { + return builder.setIconAttribute(attrId); + } + + public AlertDialog.Builder setPositiveButton(int textId, DialogInterface.OnClickListener listener) { + return builder.setPositiveButton(textId, listener); + } + + public AlertDialog.Builder setPositiveButton(CharSequence text, DialogInterface.OnClickListener listener) { + return builder.setPositiveButton(text, listener); + } + + public AlertDialog.Builder setNegativeButton(int textId, DialogInterface.OnClickListener listener) { + return builder.setNegativeButton(textId, listener); + } + + public AlertDialog.Builder setNegativeButton(CharSequence text, DialogInterface.OnClickListener listener) { + return builder.setNegativeButton(text, listener); + } + + public AlertDialog.Builder setNeutralButton(int textId, DialogInterface.OnClickListener listener) { + return builder.setNeutralButton(textId, listener); + } + + public AlertDialog.Builder setNeutralButton(CharSequence text, DialogInterface.OnClickListener listener) { + return builder.setNeutralButton(text, listener); + } + + public AlertDialog.Builder setCancelable(boolean cancelable) { + return builder.setCancelable(cancelable); + } + + public AlertDialog.Builder setOnCancelListener(DialogInterface.OnCancelListener onCancelListener) { + return builder.setOnCancelListener(onCancelListener); + } + + public AlertDialog.Builder setOnDismissListener(DialogInterface.OnDismissListener onDismissListener) { + return builder.setOnDismissListener(onDismissListener); + } + + public AlertDialog.Builder setOnKeyListener(DialogInterface.OnKeyListener onKeyListener) { + return builder.setOnKeyListener(onKeyListener); + } + + public AlertDialog.Builder setAdapter(ListAdapter adapter, DialogInterface.OnClickListener listener) { + return builder.setAdapter(adapter, listener); + } + + public AlertDialog.Builder setCursor(Cursor cursor, DialogInterface.OnClickListener listener, String labelColumn) { + return builder.setCursor(cursor, listener, labelColumn); + } + + public AlertDialog.Builder setView(View view) { + return builder.setView(view); + } + + public AlertDialog.Builder setView(int layoutResId) { + return builder.setView(layoutResId); + } + + public AlertDialog.Builder setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener) { + return builder.setOnItemSelectedListener(listener); + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java b/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java new file mode 100644 index 00000000..05830c75 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java @@ -0,0 +1,59 @@ +package de.thedevstack.conversationsplus.ui.dialogs; + +import android.app.Activity; +import android.app.AlertDialog; +import android.text.format.DateFormat; +import android.view.View; +import android.widget.TextView; + +import java.util.Date; + +import de.thedevstack.conversationsplus.R; +import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.utils.UIHelper; + +/** + * Created by tzur on 29.09.2015. + */ +public class MessageDetailsDialog extends AbstractAlertDialog { + private AlertDialog.Builder builder; + + public MessageDetailsDialog(Activity context, Message message) { + super(context, R.string.dlg_msg_details_title); + this.createView(context, message); + } + + protected void createView(Activity context, Message message) { + int viewId = R.layout.dialog_message_details; + View view = context.getLayoutInflater().inflate(viewId, null); + TextView timeSent = (TextView) view.findViewById(R.id.dlgMsgDetTimeSent); + timeSent.setText(DateFormat.format("dd.MM.yyyy kk:mm:ss", new Date(message.getMergedTimeSent()))); + TextView sender = (TextView) view.findViewById(R.id.dlgMsgDetSender); + TextView receipient = (TextView) view.findViewById(R.id.dlgMsgDetReceipient); + String me = message.getConversation().getAccount().getJid().getResourcepart(); + String other = message.getCounterpart().getResourcepart(); + if (Message.STATUS_RECEIVED == message.getStatus()) { + sender.setText(other); + receipient.setText(me); + } else { + sender.setText(me); + receipient.setText(other); + } + + if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE || message.getTransferable() != null) { + view.findViewById(R.id.dlgMsgDetFileTable).setVisibility(View.VISIBLE); + if (null != message.getFileParams()) { + Message.FileParams params = message.getFileParams(); + TextView tvFilesize = (TextView) view.findViewById(R.id.dlgMsgDetFileSize); + tvFilesize.setText(UIHelper.getHumanReadableFileSize(params.size)); + } + TextView mimetype = (TextView) view.findViewById(R.id.dlgMsgDetFileMimeType); + mimetype.setText(message.getMimeType()); + } + this.setView(view); + } + + public void show() { + this.builder.show(); + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ShowResourcesListDialogListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ShowResourcesListDialogListener.java new file mode 100644 index 00000000..070ea58c --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ShowResourcesListDialogListener.java @@ -0,0 +1,47 @@ +package de.thedevstack.conversationsplus.ui.listeners; + +import android.content.Context; +import android.view.View; + +import de.thedevstack.conversationsplus.R; +import de.thedevstack.conversationsplus.entities.Contact; +import de.thedevstack.conversationsplus.ui.adapter.PresencesArrayAdapter; +import de.thedevstack.conversationsplus.ui.dialogs.AbstractAlertDialog; + +/** + * This listener shows the dialog with the resources of a contact. + * The resources are shown with the color of their current online mode. + * This listener implements OnClickListener and OnLongClickListener. + */ +public class ShowResourcesListDialogListener extends AbstractAlertDialog implements View.OnClickListener, View.OnLongClickListener { + private Contact contact; + + public ShowResourcesListDialogListener(Context context, Contact contact) { + super(context, getTitle(context, contact)); + this.contact = contact; + this.init(); + } + + private static final String getTitle(Context context, Contact contact) { + if (null != contact && null != contact.getJid() && null != contact.getJid().toBareJid()) { + int presenceCount = null != contact.getPresences() ? contact.getPresences().size() : 0; + return context.getString(R.string.dlg_resources_title, contact.getJid().toBareJid().toString(), presenceCount); + } + return null != contact ? contact.toString() : ""; + } + + protected void init() { + this.builder.setAdapter(new PresencesArrayAdapter(getContext(), this.contact.getPresences()), null); + } + + @Override + public void onClick(View v) { + this.show(); + } + + @Override + public boolean onLongClick(View view) { + this.show(); + return true; + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/UIHelper.java b/src/main/java/de/thedevstack/conversationsplus/utils/UIHelper.java index 0ef07808..532ff1cb 100644 --- a/src/main/java/de/thedevstack/conversationsplus/utils/UIHelper.java +++ b/src/main/java/de/thedevstack/conversationsplus/utils/UIHelper.java @@ -1,5 +1,7 @@ package de.thedevstack.conversationsplus.utils; +import java.math.BigDecimal; +import java.text.NumberFormat; import java.util.ArrayList; import java.util.Arrays; import java.net.URLConnection; @@ -286,4 +288,20 @@ public class UIHelper { body = body.replace("?","").replace("¿",""); return LOCATION_QUESTIONS.contains(body); } + + public static String getHumanReadableFileSize(long filesize) { + if (0 > filesize) { + return "?"; + } + double size = Double.valueOf(filesize); + String[] sizes = {" bytes", " Kb", " Mb", " Gb", " Tb"}; + int i = 0; + while (1023 < size) { + size /= 1024d; + ++i; + } + BigDecimal readableSize = new BigDecimal(size); + readableSize = readableSize.setScale(2, BigDecimal.ROUND_HALF_UP); + return readableSize.doubleValue() + sizes[i]; + } } diff --git a/src/main/res/layout/dialog_message_details.xml b/src/main/res/layout/dialog_message_details.xml new file mode 100644 index 00000000..67561ae7 --- /dev/null +++ b/src/main/res/layout/dialog_message_details.xml @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:padding="8dp"> + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Time Sent:" + android:id="@+id/dlgMsgDetLblTimeSent" /> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/dlgMsgDetTimeSent" + android:width="200dp" + android:layout_alignParentTop="true" + android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Sender Resource:" + android:id="@+id/dlgMsgDetLblSender" + android:layout_below="@+id/dlgMsgDetLblTimeSent" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/dlgMsgDetSender" + android:layout_below="@+id/dlgMsgDetTimeSent" + android:layout_alignRight="@+id/dlgMsgDetTimeSent" + android:layout_alignEnd="@+id/dlgMsgDetTimeSent" + android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Receipient Resource:" + android:id="@+id/dlgMsgDetLblReceipient" + android:layout_below="@+id/dlgMsgDetLblSender" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/dlgMsgDetReceipient" + android:layout_below="@+id/dlgMsgDetSender" + android:layout_alignRight="@+id/dlgMsgDetSender" + android:layout_alignEnd="@+id/dlgMsgDetSender" /> + + <TableLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@+id/dlgMsgDetLblReceipient" + android:layout_marginTop="11dp" + android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" + android:stretchColumns="1" + android:background="@color/black87" + android:id="@+id/dlgMsgDetFileTable"> + + <TableRow + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/white" + android:layout_marginTop="0.3dp" + android:layout_marginLeft="0.3dp" + android:layout_marginRight="0.3dp"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="File Details" + android:layout_column="0"/> + </TableRow> + + <TableRow + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/white" + android:layout_marginTop="0.3dp" + android:layout_marginLeft="0.3dp" + android:layout_marginRight="0.3dp"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Mime Type" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="" + android:id="@+id/dlgMsgDetFileMimeType" /> + </TableRow> + + <TableRow + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/white" + android:layout_marginLeft="0.3dp" + android:layout_marginTop="0.3dp" + android:layout_marginRight="0.3dp"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Size" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="" + android:id="@+id/dlgMsgDetFileSize"/> + </TableRow> + </TableLayout> + </RelativeLayout> + + + +</LinearLayout>
\ No newline at end of file diff --git a/src/main/res/layout/dialog_resources_status.xml b/src/main/res/layout/dialog_resources_status.xml new file mode 100644 index 00000000..4dd511f5 --- /dev/null +++ b/src/main/res/layout/dialog_resources_status.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" android:layout_width="match_parent" + android:layout_height="match_parent"> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="?android:attr/textAppearanceMedium" + android:text="Medium Text" + android:id="@+id/dlg_res_stat_resource_name" + android:layout_marginLeft="10dp" /> +</LinearLayout>
\ No newline at end of file diff --git a/src/main/res/menu/message_context.xml b/src/main/res/menu/message_context.xml index 4e1316d3..2fe1ca22 100644 --- a/src/main/res/menu/message_context.xml +++ b/src/main/res/menu/message_context.xml @@ -1,6 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > - + <item + android:id="@+id/msg_ctx_mnu_details" + android:title="@string/msg_ctx_mnu_details" + android:visible="true"/> <item android:id="@+id/copy_text" android:title="@string/copy_text" diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index 2d5337be..c9724e5a 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -466,4 +466,8 @@ <string name="search_for_contacts_or_groups">Nach Kontakten oder Konferenzen suchen</string> <string name="pref_led_notification_color">LED-Benachrichtigung Farbe</string> <string name="pref_led_notification_color_summary">Setze die Farbe der LED-Benachrichtigung</string> + <string name="msg_ctx_mnu_details">Nachrichtendetails</string> + <string name="dlg_msg_details_title">Nachrichtendetails</string> + <string name="cplus_ok">Ok</string> + <string name="dlg_resources_title">%1$s (%2$d)</string><!-- %s = bare jid, %d = count of online resources --> </resources> diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 77e7d23e..0bcbb9c4 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -495,4 +495,8 @@ <string name="search_for_contacts_or_groups">Search for contacts or groups</string> <string name="pref_led_notification_color">LED notification color</string> <string name="pref_led_notification_color_summary">Change the color of the LED notification</string> + <string name="msg_ctx_mnu_details">Message Details</string> + <string name="dlg_msg_details_title">Message Details</string> + <string name="cplus_ok">Ok</string> + <string name="dlg_resources_title">%1$s (%2$d)</string><!-- %s = bare jid, %d = count of online resources --> </resources> |