factor out contact selector into its own MVC group

dbus-notify
Zlatin Balevsky 2022-05-04 12:38:22 +01:00
parent 9e5af81aba
commit fef73f14ab
No known key found for this signature in database
GPG Key ID: A72832072D525E41
7 changed files with 162 additions and 82 deletions

View File

@ -233,4 +233,9 @@ mvcGroups {
view = 'com.muwire.gui.chat.ChatFavoritesView'
controller = 'com.muwire.gui.chat.ChatFavoritesController'
}
'contact-selector' {
model = 'com.muwire.gui.ContactSelectorModel'
view = 'com.muwire.gui.ContactSelectorView'
controller = 'com.muwire.gui.ContactSelectorController'
}
}

View File

@ -0,0 +1,8 @@
package com.muwire.gui
import griffon.core.artifact.GriffonController
import griffon.metadata.ArtifactProviderFor
@ArtifactProviderFor(GriffonController)
class ContactSelectorController {
}

View File

@ -46,7 +46,7 @@ class NewMessageController {
}
Set<Persona> recipients = new HashSet<>()
recipients.addAll(model.recipients)
recipients.addAll(view.contactSelector.model.contacts)
if (recipients.isEmpty()) {
JOptionPane.showMessageDialog(null, trans("NO_RECIPIENTS_BODY"),

View File

@ -654,7 +654,7 @@ FOLDER_CONFIRM_DELETE=This folder is not empty. Are you sure you want to delete
## New message window
UNREAD=Unread
RECIPIENTS=Recipients
RECIPIENTS_TITLE=Drag and drop recipients from your contacts
RECIPIENTS_TITLE=Drag and drop contacts from your contact list
SEND=Send
MESSAGE_VERB=Message
MESSAGE_NOUN=Message

View File

@ -0,0 +1,13 @@
package com.muwire.gui
import com.muwire.core.Persona
import griffon.core.artifact.GriffonModel
import griffon.inject.MVCMember
import griffon.metadata.ArtifactProviderFor
import javax.annotation.Nonnull
@ArtifactProviderFor(GriffonModel)
class ContactSelectorModel {
Set<Persona> contacts
}

View File

@ -0,0 +1,122 @@
package com.muwire.gui
import com.muwire.core.Persona
import griffon.core.artifact.GriffonView
import griffon.inject.MVCMember
import griffon.metadata.ArtifactProviderFor
import javax.annotation.Nonnull
import javax.swing.DefaultListModel
import javax.swing.JComponent
import javax.swing.JList
import javax.swing.JMenuItem
import javax.swing.JPanel
import javax.swing.JPopupMenu
import javax.swing.ListSelectionModel
import javax.swing.TransferHandler
import javax.swing.border.TitledBorder
import java.awt.BorderLayout
import java.awt.datatransfer.DataFlavor
import java.awt.datatransfer.Transferable
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
import static com.muwire.gui.Translator.trans
@ArtifactProviderFor(GriffonView)
class ContactSelectorView {
@MVCMember @Nonnull
FactoryBuilderSupport builder
@MVCMember @Nonnull
ContactSelectorModel model
DefaultListModel contactsModel
JList contactsList
JPanel component
void initUI() {
contactsModel = new DefaultListModel()
model.contacts.each {
contactsModel.addElement(new Contact(it))
}
contactsList = new JList(contactsModel)
contactsList.setVisibleRowCount(2)
component = builder.panel(border : builder.titledBorder(title : trans("RECIPIENTS_TITLE"),
border : builder.etchedBorder(), titlePosition : TitledBorder.TOP)) {
borderLayout()
scrollPane(constraints : BorderLayout.CENTER) {
widget(contactsList)
}
}
}
void mvcGroupInit(Map<String, String> args) {
def transferHandler = new PersonaTransferHandler()
contactsList.setTransferHandler(transferHandler)
contactsList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
JPopupMenu contactsMenu = new JPopupMenu()
JMenuItem removeItem = new JMenuItem(trans("REMOVE"))
removeItem.addActionListener({removeSelectedContacts()})
contactsMenu.add(removeItem)
contactsList.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.isPopupTrigger() || e.getButton() == MouseEvent.BUTTON3)
contactsMenu.show(e.getComponent(), e.getX(), e.getY())
}
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger() || e.getButton() == MouseEvent.BUTTON3)
contactsMenu.show(e.getComponent(), e.getX(), e.getY())
}
})
}
void removeSelectedContacts() {
int [] selected = contactsList.getSelectedIndices()
if (selected.length == 0)
return
Arrays.sort(selected)
for (int i = selected.length - 1; i >= 0; i--) {
Contact removed = contactsModel.remove(selected[i])
model.contacts.remove(removed.persona)
}
}
class PersonaTransferHandler extends TransferHandler {
@Override
public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
for (DataFlavor df : transferFlavors) {
if (df == CopyPasteSupport.LIST_FLAVOR) {
return true
}
}
return false
}
public boolean importData(JComponent c, Transferable t) {
List<?> items = t.getTransferData(CopyPasteSupport.LIST_FLAVOR)
if (items == null || items.isEmpty()) {
return false
}
items.each {
if (model.contacts.add(it))
contactsModel.insertElementAt(new Contact(it),0)
}
return true
}
}
private static class Contact {
private final Persona persona
Contact(Persona persona) {
this.persona = persona
}
public String toString() {
"<html>" + PersonaCellRenderer.htmlize(persona) + "</html>"
}
}
}

View File

@ -1,7 +1,7 @@
package com.muwire.gui
import griffon.core.artifact.GriffonView
import griffon.core.mvc.MVCGroup
import griffon.inject.MVCMember
import griffon.metadata.ArtifactProviderFor
@ -48,24 +48,21 @@ class NewMessageView {
NewMessageModel model
JFrame window
DefaultListModel recipientsModel
JList recipientsList
JTextField subjectField
JTextArea bodyArea
JTable attachmentsTable
def lastAttachmentsTableSortEvent
def mainFrame
MVCGroup contactSelector
void initUI() {
mainFrame = application.windowManager.findWindow("main-frame")
int rowHeight = application.context.get("row-height")
recipientsModel = new DefaultListModel()
model.recipients.each {
recipientsModel.addElement(new Recipient(it))
}
recipientsList = new JList(recipientsModel)
recipientsList.setVisibleRowCount(2)
def params = [:]
params.contacts = model.recipients
contactSelector = mvcGroup.createMVCGroup("contact-selector", UUID.randomUUID().toString(), params)
window = builder.frame(visible : false, locationRelativeTo : mainFrame,
defaultCloseOperation : JFrame.DISPOSE_ON_CLOSE,
@ -74,12 +71,9 @@ class NewMessageView {
borderLayout()
panel(constraints : BorderLayout.NORTH) {
borderLayout()
panel(constraints : BorderLayout.NORTH, border : titledBorder(title : trans("RECIPIENTS_TITLE"),
border : etchedBorder(), titlePosition : TitledBorder.TOP)) {
borderLayout()
scrollPane(constraints : BorderLayout.CENTER) {
widget(recipientsList)
}
panel(constraints : BorderLayout.NORTH) {
gridLayout(rows: 1, cols: 1)
widget(contactSelector.view.component)
}
panel(constraints : BorderLayout.SOUTH, border : titledBorder(title : trans("SUBJECT"),
border : etchedBorder(), titlePosition : TitledBorder.TOP)) {
@ -147,28 +141,6 @@ class NewMessageView {
}
})
// recipients list
transferHandler = new PersonaTransferHandler()
recipientsList.setTransferHandler(transferHandler)
recipientsList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
JPopupMenu recipientsMenu = new JPopupMenu()
JMenuItem removeItem = new JMenuItem(trans("REMOVE"))
removeItem.addActionListener({removeSelectedRecipients()})
recipientsMenu.add(removeItem)
recipientsList.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.isPopupTrigger() || e.getButton() == MouseEvent.BUTTON3)
recipientsMenu.show(e.getComponent(), e.getX(), e.getY())
}
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger() || e.getButton() == MouseEvent.BUTTON3)
recipientsMenu.show(e.getComponent(), e.getX(), e.getY())
}
})
// general window
window.addWindowListener(new WindowAdapter() {
@ -181,15 +153,8 @@ class NewMessageView {
window.setVisible(true)
}
void removeSelectedRecipients() {
int [] selected = recipientsList.getSelectedIndices()
if (selected.length == 0)
return
Arrays.sort(selected)
for (int i = selected.length - 1; i >= 0; i--) {
Recipient removed = recipientsModel.remove(selected[i])
model.recipients.remove(removed.persona)
}
void mvcGroupDestroy() {
contactSelector?.destroy()
}
void removeSelectedAttachments() {
@ -239,38 +204,5 @@ class NewMessageView {
}
}
class PersonaTransferHandler extends TransferHandler {
@Override
public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
for (DataFlavor df : transferFlavors) {
if (df == CopyPasteSupport.LIST_FLAVOR) {
return true
}
}
return false
}
public boolean importData(JComponent c, Transferable t) {
List<?> items = t.getTransferData(CopyPasteSupport.LIST_FLAVOR)
if (items == null || items.isEmpty()) {
return false
}
items.each {
if (model.recipients.add(it))
recipientsModel.insertElementAt(new Recipient(it),0)
}
return true
}
}
private static class Recipient {
private final Persona persona
Recipient(Persona persona) {
this.persona = persona
}
public String toString() {
"<html>" + PersonaCellRenderer.htmlize(persona) + "</html>"
}
}
}