mirror of https://github.com/zlatinb/muwire
new contact selector
parent
56f83c8078
commit
53206b3b84
|
@ -669,7 +669,7 @@ FOLDER_CONFIRM_DELETE=This folder is not empty. Are you sure you want to delete
|
||||||
## New message window
|
## New message window
|
||||||
UNREAD=Unread
|
UNREAD=Unread
|
||||||
RECIPIENTS=Recipients
|
RECIPIENTS=Recipients
|
||||||
RECIPIENTS_TITLE=Drag and drop contacts from your contact list
|
RECIPIENTS_TITLE=You can drag and drop contacts from your contact list here
|
||||||
SEND=Send
|
SEND=Send
|
||||||
MESSAGE_VERB=Message
|
MESSAGE_VERB=Message
|
||||||
MESSAGE_NOUN=Message
|
MESSAGE_NOUN=Message
|
||||||
|
@ -681,6 +681,9 @@ SUBJECT_TOO_LONG_BODY=Your subject is {0} characters. The maximum length is {1}
|
||||||
NO_RECIPIENTS=No Recipients
|
NO_RECIPIENTS=No Recipients
|
||||||
NO_RECIPIENTS_BODY=Please add at least one recipient.
|
NO_RECIPIENTS_BODY=Please add at least one recipient.
|
||||||
|
|
||||||
|
## Contact chooser
|
||||||
|
CONTACT_CHOOSER_SELECT_CONTACT=Select Contact
|
||||||
|
|
||||||
## Add Contact dialog
|
## Add Contact dialog
|
||||||
ADD_CONTACT_SPECIFIC=Add Contact
|
ADD_CONTACT_SPECIFIC=Add Contact
|
||||||
ADD_CONTACT_TITLE=Add a new contact
|
ADD_CONTACT_TITLE=Add a new contact
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.muwire.gui.contacts
|
package com.muwire.gui.contacts
|
||||||
|
|
||||||
|
import com.muwire.core.Core
|
||||||
import com.muwire.core.Persona
|
import com.muwire.core.Persona
|
||||||
import griffon.core.artifact.GriffonModel
|
import griffon.core.artifact.GriffonModel
|
||||||
import griffon.inject.MVCMember
|
import griffon.inject.MVCMember
|
||||||
|
@ -9,5 +10,6 @@ import javax.annotation.Nonnull
|
||||||
|
|
||||||
@ArtifactProviderFor(GriffonModel)
|
@ArtifactProviderFor(GriffonModel)
|
||||||
class ContactSelectorModel {
|
class ContactSelectorModel {
|
||||||
|
Core core
|
||||||
Set<Persona> contacts
|
Set<Persona> contacts
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@ class NewMessageView {
|
||||||
|
|
||||||
def params = [:]
|
def params = [:]
|
||||||
params.contacts = model.recipients
|
params.contacts = model.recipients
|
||||||
|
params.core = model.core
|
||||||
contactSelector = mvcGroup.createMVCGroup("contact-selector", UUID.randomUUID().toString(), params)
|
contactSelector = mvcGroup.createMVCGroup("contact-selector", UUID.randomUUID().toString(), params)
|
||||||
|
|
||||||
window = builder.frame(visible : false, locationRelativeTo : mainFrame,
|
window = builder.frame(visible : false, locationRelativeTo : mainFrame,
|
||||||
|
|
|
@ -43,6 +43,7 @@ class WatchedDirectoryView {
|
||||||
mainFrame = application.windowManager.findWindow("main-frame")
|
mainFrame = application.windowManager.findWindow("main-frame")
|
||||||
|
|
||||||
def params = [:]
|
def params = [:]
|
||||||
|
params.core = model.core
|
||||||
params.contacts = model.allowedContacts
|
params.contacts = model.allowedContacts
|
||||||
contactSelector = mvcGroup.createMVCGroup("contact-selector", UUID.randomUUID().toString(), params)
|
contactSelector = mvcGroup.createMVCGroup("contact-selector", UUID.randomUUID().toString(), params)
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,10 @@ import javax.swing.border.TitledBorder
|
||||||
import java.awt.BorderLayout
|
import java.awt.BorderLayout
|
||||||
import java.awt.datatransfer.DataFlavor
|
import java.awt.datatransfer.DataFlavor
|
||||||
import java.awt.datatransfer.Transferable
|
import java.awt.datatransfer.Transferable
|
||||||
|
import java.awt.event.ItemEvent
|
||||||
|
import java.awt.event.ItemListener
|
||||||
|
import java.awt.event.KeyAdapter
|
||||||
|
import java.awt.event.KeyEvent
|
||||||
import java.awt.event.MouseAdapter
|
import java.awt.event.MouseAdapter
|
||||||
import java.awt.event.MouseEvent
|
import java.awt.event.MouseEvent
|
||||||
|
|
||||||
|
@ -39,23 +43,37 @@ class ContactSelectorView {
|
||||||
|
|
||||||
DefaultListModel contactsModel
|
DefaultListModel contactsModel
|
||||||
JList contactsList
|
JList contactsList
|
||||||
|
ContactChooser contactChooser
|
||||||
|
ContactChooserModel contactChooserModel
|
||||||
|
|
||||||
JPanel component
|
JPanel component
|
||||||
|
|
||||||
|
private UISettings settings
|
||||||
|
|
||||||
|
private Contact lastSelectedContact
|
||||||
|
|
||||||
void initUI() {
|
void initUI() {
|
||||||
|
settings = application.context.get("ui-settings")
|
||||||
|
|
||||||
contactsModel = new DefaultListModel()
|
contactsModel = new DefaultListModel()
|
||||||
model.contacts.each {
|
model.contacts.each {
|
||||||
contactsModel.addElement(new Contact(it))
|
contactsModel.addElement(new Contact(it, settings))
|
||||||
}
|
}
|
||||||
contactsList = new JList(contactsModel)
|
contactsList = new JList(contactsModel)
|
||||||
contactsList.setVisibleRowCount(2)
|
contactsList.setVisibleRowCount(2)
|
||||||
|
|
||||||
component = builder.panel(border : builder.titledBorder(title : trans("RECIPIENTS_TITLE"),
|
contactChooserModel= new ContactChooserModel(model.core.trustService.getGood().values())
|
||||||
border : builder.etchedBorder(), titlePosition : TitledBorder.TOP)) {
|
contactChooser = new ContactChooser(settings, contactChooserModel)
|
||||||
|
|
||||||
|
component = builder.panel {
|
||||||
borderLayout()
|
borderLayout()
|
||||||
scrollPane(constraints : BorderLayout.CENTER) {
|
scrollPane(constraints : BorderLayout.CENTER, border : builder.titledBorder(title : trans("RECIPIENTS_TITLE"),
|
||||||
|
border : builder.etchedBorder(), titlePosition : TitledBorder.TOP)) {
|
||||||
widget(contactsList)
|
widget(contactsList)
|
||||||
}
|
}
|
||||||
|
widget(contactChooser, constraints: BorderLayout.SOUTH,
|
||||||
|
border : builder.titledBorder(title : trans("CONTACT_CHOOSER_SELECT_CONTACT"),
|
||||||
|
border : builder.etchedBorder(), titlePosition : TitledBorder.TOP))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +97,34 @@ class ContactSelectorView {
|
||||||
contactsMenu.show(e.getComponent(), e.getX(), e.getY())
|
contactsMenu.show(e.getComponent(), e.getX(), e.getY())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
contactChooser.addItemListener(new ItemListener() {
|
||||||
|
@Override
|
||||||
|
void itemStateChanged(ItemEvent e) {
|
||||||
|
if (e.getStateChange() != ItemEvent.SELECTED)
|
||||||
|
return
|
||||||
|
Object item = e.getItem()
|
||||||
|
if (item == null || item instanceof String)
|
||||||
|
return
|
||||||
|
ContactChooserPOP ccp = (ContactChooserPOP) item
|
||||||
|
if (ccp.getPersona() == null)
|
||||||
|
return
|
||||||
|
|
||||||
|
lastSelectedContact = new Contact(ccp.getPersona(), settings)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
contactChooser.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
void keyReleased(KeyEvent e) {
|
||||||
|
if (e.getKeyCode() != KeyEvent.VK_ENTER)
|
||||||
|
return
|
||||||
|
if (lastSelectedContact != null) {
|
||||||
|
if (model.contacts.add(lastSelectedContact.persona))
|
||||||
|
contactsModel << lastSelectedContact
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeSelectedContacts() {
|
void removeSelectedContacts() {
|
||||||
|
@ -110,7 +156,7 @@ class ContactSelectorView {
|
||||||
|
|
||||||
items.each {
|
items.each {
|
||||||
if (model.contacts.add(it))
|
if (model.contacts.add(it))
|
||||||
contactsModel.insertElementAt(new Contact(it),0)
|
contactsModel.insertElementAt(new Contact(it, settings),0)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -119,8 +165,9 @@ class ContactSelectorView {
|
||||||
private static class Contact {
|
private static class Contact {
|
||||||
private final UISettings settings
|
private final UISettings settings
|
||||||
private final Persona persona
|
private final Persona persona
|
||||||
Contact(Persona persona) {
|
Contact(Persona persona, UISettings settings) {
|
||||||
this.persona = persona
|
this.persona = persona
|
||||||
|
this.settings = settings
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.muwire.gui.contacts
|
||||||
|
|
||||||
|
import com.muwire.gui.UISettings
|
||||||
|
import com.muwire.gui.profile.PersonaOrProfileCellRenderer
|
||||||
|
|
||||||
|
import javax.swing.JComboBox
|
||||||
|
import javax.swing.JTextField
|
||||||
|
|
||||||
|
class ContactChooser extends JComboBox{
|
||||||
|
ContactChooser(UISettings settings, ContactChooserModel model) {
|
||||||
|
super()
|
||||||
|
setEditable(true)
|
||||||
|
setModel(model)
|
||||||
|
setEditor(new ContactChooserEditor(model, this))
|
||||||
|
setRenderer(new PersonaOrProfileListCellRenderer(settings))
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.muwire.gui.contacts
|
||||||
|
|
||||||
|
import javax.swing.SwingUtilities
|
||||||
|
import javax.swing.event.DocumentEvent
|
||||||
|
import javax.swing.event.DocumentListener
|
||||||
|
import javax.swing.plaf.basic.BasicComboBoxEditor
|
||||||
|
import java.awt.event.ActionEvent
|
||||||
|
import java.awt.event.ActionListener
|
||||||
|
import java.awt.event.KeyAdapter
|
||||||
|
import java.awt.event.KeyEvent
|
||||||
|
|
||||||
|
class ContactChooserEditor extends BasicComboBoxEditor{
|
||||||
|
|
||||||
|
private final ContactChooserModel model
|
||||||
|
private final ContactChooser field
|
||||||
|
|
||||||
|
ContactChooserEditor(ContactChooserModel model, ContactChooser field) {
|
||||||
|
super()
|
||||||
|
this.model = model
|
||||||
|
this.field = field
|
||||||
|
|
||||||
|
editor.addKeyListener(new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
void keyPressed(KeyEvent e) {
|
||||||
|
int keyCode = e.getKeyCode()
|
||||||
|
if (keyCode == KeyEvent.VK_ENTER)
|
||||||
|
editor.setText("")
|
||||||
|
else if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_DOWN) {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
SwingUtilities.invokeLater {
|
||||||
|
field.hidePopup()
|
||||||
|
if (model.onKeyStroke(editor.text))
|
||||||
|
field.showPopup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItem(Object o) {
|
||||||
|
if (o == null || o instanceof ContactChooserPOP)
|
||||||
|
super.setItem(o)
|
||||||
|
else
|
||||||
|
editor.setText("")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.muwire.gui.contacts
|
||||||
|
|
||||||
|
import com.muwire.core.trust.TrustService
|
||||||
|
import com.muwire.core.trust.TrustService.TrustEntry
|
||||||
|
import com.muwire.gui.profile.PersonaOrProfile
|
||||||
|
import com.muwire.gui.profile.PersonaOrProfileComparator
|
||||||
|
import com.muwire.gui.profile.TrustPOP
|
||||||
|
|
||||||
|
import javax.swing.ComboBoxModel
|
||||||
|
import javax.swing.DefaultComboBoxModel
|
||||||
|
import javax.swing.DefaultListModel
|
||||||
|
import javax.swing.MutableComboBoxModel
|
||||||
|
|
||||||
|
class ContactChooserModel extends DefaultComboBoxModel implements MutableComboBoxModel {
|
||||||
|
private final List<PersonaOrProfile> allObjects
|
||||||
|
private final Comparator<PersonaOrProfile> popComparator = new PersonaOrProfileComparator()
|
||||||
|
PersonaOrProfile selectedPOP
|
||||||
|
|
||||||
|
ContactChooserModel(Collection<TrustEntry> entries) {
|
||||||
|
allObjects = entries.collect {new ContactChooserPOP(it)}
|
||||||
|
addAll(allObjects)
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean onKeyStroke(String selected) {
|
||||||
|
|
||||||
|
if (selected == null || selected.length() == 0) {
|
||||||
|
removeAllElements()
|
||||||
|
addAll(allObjects)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
removeAllElements()
|
||||||
|
setSelectedItem(new ContactChooserPOP(selected))
|
||||||
|
|
||||||
|
List<PersonaOrProfile> matches = []
|
||||||
|
for(PersonaOrProfile pop : allObjects) {
|
||||||
|
if (justName(pop).containsIgnoreCase(selected))
|
||||||
|
matches << pop
|
||||||
|
}
|
||||||
|
if (matches.isEmpty())
|
||||||
|
return false
|
||||||
|
|
||||||
|
Collections.sort(matches, popComparator)
|
||||||
|
addAll(matches)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String justName(PersonaOrProfile pop) {
|
||||||
|
String name = pop.getPersona().getHumanReadableName()
|
||||||
|
name.substring(0, name.indexOf("@")).toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSelectedItem(Object anObject) {
|
||||||
|
if (anObject instanceof String) {
|
||||||
|
if (anObject == selectedPOP?.getPersona()?.getHumanReadableName())
|
||||||
|
super.setSelectedItem(selectedPOP)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (anObject == null)
|
||||||
|
selectedPOP = null
|
||||||
|
else {
|
||||||
|
if (!(anObject instanceof ContactChooserPOP))
|
||||||
|
throw new Exception("invalid type $anObject")
|
||||||
|
|
||||||
|
ContactChooserPOP ccp = (ContactChooserPOP) anObject
|
||||||
|
if (ccp.getPersona() != null)
|
||||||
|
selectedPOP = ccp
|
||||||
|
}
|
||||||
|
super.setSelectedItem(anObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package com.muwire.gui.contacts
|
||||||
|
|
||||||
|
import com.muwire.core.Persona
|
||||||
|
import com.muwire.core.profile.MWProfile
|
||||||
|
import com.muwire.core.profile.MWProfileHeader
|
||||||
|
import com.muwire.core.trust.TrustService.TrustEntry
|
||||||
|
import com.muwire.gui.profile.PersonaOrProfile
|
||||||
|
import com.muwire.gui.profile.ThumbnailIcon
|
||||||
|
|
||||||
|
import javax.swing.Icon
|
||||||
|
|
||||||
|
class ContactChooserPOP implements PersonaOrProfile {
|
||||||
|
private final TrustEntry trustEntry
|
||||||
|
private final String text
|
||||||
|
private Icon icon
|
||||||
|
|
||||||
|
ContactChooserPOP(TrustEntry trustEntry) {
|
||||||
|
this.trustEntry = trustEntry
|
||||||
|
this.text = null
|
||||||
|
}
|
||||||
|
|
||||||
|
ContactChooserPOP(String text) {
|
||||||
|
this.text = text
|
||||||
|
this.trustEntry = null
|
||||||
|
}
|
||||||
|
|
||||||
|
Persona getPersona() {
|
||||||
|
trustEntry?.getPersona()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Icon getThumbnail() {
|
||||||
|
MWProfileHeader header = getHeader()
|
||||||
|
if (header == null)
|
||||||
|
return null
|
||||||
|
if (icon == null)
|
||||||
|
icon = new ThumbnailIcon(header.getThumbNail())
|
||||||
|
return icon
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
MWProfileHeader getHeader() {
|
||||||
|
trustEntry.getProfileHeader()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
MWProfile getProfile() {
|
||||||
|
trustEntry.getProfile()
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof ContactChooserPOP))
|
||||||
|
return false
|
||||||
|
ContactChooserPOP other = (ContactChooserPOP)o
|
||||||
|
Objects.equals(text, other.text) &&
|
||||||
|
Objects.equals(trustEntry, other.trustEntry)
|
||||||
|
}
|
||||||
|
|
||||||
|
String toString() {
|
||||||
|
if (text != null)
|
||||||
|
return text
|
||||||
|
else
|
||||||
|
return getPersona().getHumanReadableName()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.muwire.gui.contacts
|
||||||
|
|
||||||
|
import com.muwire.gui.PersonaCellRenderer
|
||||||
|
import com.muwire.gui.UISettings
|
||||||
|
import com.muwire.gui.profile.PersonaOrProfile
|
||||||
|
|
||||||
|
import javax.swing.JLabel
|
||||||
|
import javax.swing.JList
|
||||||
|
import javax.swing.ListCellRenderer
|
||||||
|
import java.awt.Component
|
||||||
|
|
||||||
|
import static com.muwire.gui.Translator.trans
|
||||||
|
|
||||||
|
class PersonaOrProfileListCellRenderer implements ListCellRenderer<PersonaOrProfile>{
|
||||||
|
|
||||||
|
private final UISettings settings
|
||||||
|
|
||||||
|
PersonaOrProfileListCellRenderer(UISettings settings) {
|
||||||
|
this.settings = settings
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Component getListCellRendererComponent(JList<? extends PersonaOrProfile> list, PersonaOrProfile value,
|
||||||
|
int index, boolean isSelected, boolean cellHasFocus) {
|
||||||
|
|
||||||
|
JLabel rv = new JLabel()
|
||||||
|
String text
|
||||||
|
if (settings.personaRendererIds)
|
||||||
|
text = "<html>" + PersonaCellRenderer.htmlize(value.getPersona()) + "</html>"
|
||||||
|
else
|
||||||
|
text = PersonaCellRenderer.justName(value.getPersona())
|
||||||
|
|
||||||
|
rv.setText(text)
|
||||||
|
|
||||||
|
if (value.getThumbnail() != null)
|
||||||
|
rv.setIcon(value.getThumbnail())
|
||||||
|
else
|
||||||
|
rv.setIcon(null)
|
||||||
|
|
||||||
|
if (value.getTitle() != null)
|
||||||
|
rv.setToolTipText(value.getTitle())
|
||||||
|
else
|
||||||
|
rv.setToolTipText(trans("NO_PROFILE"))
|
||||||
|
|
||||||
|
if (!isSelected) {
|
||||||
|
rv.setForeground(list.getForeground())
|
||||||
|
rv.setBackground(list.getBackground())
|
||||||
|
} else {
|
||||||
|
rv.setForeground(list.getSelectionForeground())
|
||||||
|
rv.setBackground(list.getSelectionBackground())
|
||||||
|
}
|
||||||
|
rv
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue