Added copy-paste menu to text widgets.
Added base for media uploading.
0
BasicHTMLParser.java
Normal file → Executable file
0
ClipboardApi.java
Normal file → Executable file
219
ComposeWindow.java
Normal file → Executable file
@ -16,6 +16,12 @@ import javax.swing.UIManager;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import java.nio.file.Files;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
@ -23,6 +29,8 @@ import java.awt.event.ActionListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
@ -30,6 +38,8 @@ import java.awt.Insets;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Image;
|
||||
import java.io.File;
|
||||
import javax.swing.event.CaretListener;
|
||||
import javax.swing.event.CaretEvent;
|
||||
import java.util.List;
|
||||
@ -92,6 +102,15 @@ ComposeWindow extends JFrame {
|
||||
if (composition.contentWarning != null)
|
||||
assert !composition.contentWarning.trim().isEmpty();
|
||||
|
||||
// Oh, this is gonna be hell.
|
||||
/*
|
||||
* (未) For every attachment in composition,
|
||||
* attempt to upload it, then fill the media ID.
|
||||
* Then change MastodonApi#submit to accept an
|
||||
* array of media IDs. If any upload fails,
|
||||
* show an error message then return.
|
||||
*/
|
||||
|
||||
contentsDisplay.setSubmitting(true);
|
||||
api.submit(
|
||||
composition.text, composition.visibility,
|
||||
@ -135,22 +154,29 @@ ComposeWindow extends JFrame {
|
||||
private synchronized void
|
||||
syncDisplayToComposition()
|
||||
{
|
||||
ComposeComponent d = contentsDisplay;
|
||||
d.setText(composition.text);
|
||||
d.setReplyToPostId(composition.replyToPostId);
|
||||
d.setVisibility(stringFor(composition.visibility));
|
||||
d.setContentWarning(composition.contentWarning);
|
||||
ComposeComponent d1 = contentsDisplay;
|
||||
d1.setText(composition.text);
|
||||
d1.setReplyToPostId(composition.replyToPostId);
|
||||
d1.setVisibility(stringFor(composition.visibility));
|
||||
d1.setContentWarning(composition.contentWarning);
|
||||
|
||||
AttachmentsComponent d2 = attachmentsDisplay;
|
||||
d2.setAttachments(composition.attachments);
|
||||
}
|
||||
|
||||
private synchronized void
|
||||
syncCompositionToDisplay()
|
||||
{
|
||||
ComposeComponent d = contentsDisplay;
|
||||
Composition c = composition;
|
||||
c.text = d.getText();
|
||||
c.visibility = visibilityFrom(d.getVisibility());
|
||||
c.replyToPostId = nonEmpty(d.getReplyToPostId());
|
||||
c.contentWarning = nonEmpty(d.getContentWarning());
|
||||
Composition c = composition;
|
||||
|
||||
ComposeComponent d1 = contentsDisplay;
|
||||
c.text = d1.getText();
|
||||
c.visibility = visibilityFrom(d1.getVisibility());
|
||||
c.replyToPostId = nonEmpty(d1.getReplyToPostId());
|
||||
c.contentWarning = nonEmpty(d1.getContentWarning());
|
||||
|
||||
AttachmentsComponent d2 = attachmentsDisplay;
|
||||
c.attachments = d2.getAttachments();
|
||||
}
|
||||
|
||||
// - -%- -
|
||||
@ -248,9 +274,6 @@ implements ActionListener, CaretListener, KeyListener {
|
||||
private JButton
|
||||
submit;
|
||||
|
||||
private JButton
|
||||
showAttachmentsPage;
|
||||
|
||||
// ---%-@-%---
|
||||
|
||||
public void
|
||||
@ -332,10 +355,6 @@ implements ActionListener, CaretListener, KeyListener {
|
||||
public void
|
||||
actionPerformed(ActionEvent eA)
|
||||
{
|
||||
if (eA.getSource() == showAttachmentsPage)
|
||||
//primaire.showAttachmentsPage();
|
||||
;
|
||||
|
||||
if (eA.getSource() == submit)
|
||||
primaire.submit();
|
||||
}
|
||||
@ -398,13 +417,18 @@ implements ActionListener, CaretListener, KeyListener {
|
||||
Border b3 = BorderFactory.createLineBorder(Color.GRAY);
|
||||
Border bc = BorderFactory.createCompoundBorder(b3, b2);
|
||||
|
||||
TextActionPopupMenu textActionPopup;
|
||||
textActionPopup = new TextActionPopupMenu();
|
||||
|
||||
reply = new JTextField();
|
||||
JLabel replyLabel = new JLabel("In reply to: ");
|
||||
replyLabel.setLabelFor(reply);
|
||||
reply.addMouseListener(textActionPopup);
|
||||
|
||||
contentWarning = new JTextField();
|
||||
JLabel cwLabel = new JLabel("Content warning: ");
|
||||
cwLabel.setLabelFor(contentWarning);
|
||||
contentWarning.addMouseListener(textActionPopup);
|
||||
|
||||
JPanel top = new JPanel();
|
||||
top.setOpaque(false);
|
||||
@ -429,11 +453,7 @@ implements ActionListener, CaretListener, KeyListener {
|
||||
submit = new JButton("Submit");
|
||||
submit.addActionListener(this);
|
||||
|
||||
showAttachmentsPage = new JButton("Media");
|
||||
showAttachmentsPage.addActionListener(this);
|
||||
|
||||
Box bottom = Box.createHorizontalBox();
|
||||
//bottom.add(showAttachmentsPage);
|
||||
bottom.add(Box.createGlue());
|
||||
bottom.add(textLength);
|
||||
bottom.add(Box.createHorizontalStrut(12));
|
||||
@ -448,6 +468,7 @@ implements ActionListener, CaretListener, KeyListener {
|
||||
text.setBorder(bc);
|
||||
text.addCaretListener(this);
|
||||
text.addKeyListener(this);
|
||||
text.addMouseListener(textActionPopup);
|
||||
|
||||
setLayout(new BorderLayout(0, 8));
|
||||
add(top, BorderLayout.NORTH);
|
||||
@ -496,8 +517,30 @@ implements ActionListener {
|
||||
private JTextArea
|
||||
description;
|
||||
|
||||
private JFileChooser
|
||||
chooser;
|
||||
|
||||
// ---%-@-%---
|
||||
|
||||
public void
|
||||
setAttachments(Attachment[] n)
|
||||
{
|
||||
working.clear();
|
||||
if (n != null) for (Attachment attachment: n)
|
||||
{
|
||||
working.add(attachment);
|
||||
}
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
public Attachment[]
|
||||
getAttachments()
|
||||
{
|
||||
return working.toArray(new Attachment[0]);
|
||||
}
|
||||
|
||||
// - -%- -
|
||||
|
||||
private void
|
||||
updateButtons()
|
||||
{
|
||||
@ -510,10 +553,30 @@ implements ActionListener {
|
||||
if (working.size() > 3) selections.add(attachment4);
|
||||
if (working.size() < 4) selections.add(add);
|
||||
|
||||
if (working.size() > 3) attachment4.doClick();
|
||||
else if (working.size() > 2) attachment3.doClick();
|
||||
else if (working.size() > 1) attachment2.doClick();
|
||||
else if (working.size() > 0) attachment1.doClick();
|
||||
if (working.size() > 3)
|
||||
{
|
||||
attachment4.doClick();
|
||||
Image i = working.get(3).image;
|
||||
attachment4.setIcon(new ImageIcon(i));
|
||||
}
|
||||
else if (working.size() > 2)
|
||||
{
|
||||
attachment3.doClick();
|
||||
Image i = working.get(2).image;
|
||||
attachment3.setIcon(new ImageIcon(i));
|
||||
}
|
||||
else if (working.size() > 1)
|
||||
{
|
||||
attachment2.doClick();
|
||||
Image i = working.get(1).image;
|
||||
attachment2.setIcon(new ImageIcon(i));
|
||||
}
|
||||
else if (working.size() > 0)
|
||||
{
|
||||
attachment1.doClick();
|
||||
Image i = working.get(0).image;
|
||||
attachment1.setIcon(new ImageIcon(i));
|
||||
}
|
||||
else selectionsGroup.clearSelection();
|
||||
|
||||
int bw = sz.width;
|
||||
@ -539,10 +602,30 @@ implements ActionListener {
|
||||
|
||||
if (src == add)
|
||||
{
|
||||
// Invoke file picker. Try to get file.
|
||||
// Try to upload file. So on.
|
||||
// Then add to working.
|
||||
working.add(new Attachment());
|
||||
int r = chooser.showOpenDialog(this);
|
||||
if (r != JFileChooser.APPROVE_OPTION) return;
|
||||
|
||||
File f = chooser.getSelectedFile();
|
||||
|
||||
Attachment a = new Attachment();
|
||||
a.uploadee = f;
|
||||
|
||||
String mime = "", primary = "";
|
||||
try
|
||||
{
|
||||
mime = Files.probeContentType(f.toPath());
|
||||
primary = mime.split("/")[0];
|
||||
// Too lazy to instantiate a
|
||||
// javax.activation.MimeType.
|
||||
}
|
||||
catch (IOException eIo) { }
|
||||
if (primary.equals("image"))
|
||||
{
|
||||
String urlr = f.toURI().toString();
|
||||
a.image = ImageApi.remote(urlr);
|
||||
}
|
||||
|
||||
working.add(a);
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
@ -596,10 +679,15 @@ implements ActionListener {
|
||||
Border bc1 = BorderFactory.createCompoundBorder(b3, b2);
|
||||
Border bc2 = BorderFactory.createCompoundBorder(b4, b2);
|
||||
|
||||
TextActionPopupMenu textActionPopup;
|
||||
textActionPopup = new TextActionPopupMenu();
|
||||
|
||||
chooser = new JFileChooser();
|
||||
|
||||
add = new JButton("+");
|
||||
add.setPreferredSize(new Dimension(32, 32));
|
||||
add.setMargin(new Insets(0, 0, 0, 0));
|
||||
add.addActionListener(this);
|
||||
add.addActionListener(this);
|
||||
attachment1 = new JToggleButton("1");
|
||||
attachment2 = new JToggleButton("2");
|
||||
attachment3 = new JToggleButton("3");
|
||||
@ -663,6 +751,7 @@ implements ActionListener {
|
||||
java.awt.Font f = description.getFont();
|
||||
description.setFont(f.deriveFont(16f));
|
||||
description.setBorder(bc1);
|
||||
description.addMouseListener(textActionPopup);
|
||||
descriptionLabel = new JLabel("Description");
|
||||
descriptionLabel.setLabelFor(description);
|
||||
|
||||
@ -693,3 +782,71 @@ implements ActionListener {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class
|
||||
TextActionPopupMenu extends JPopupMenu
|
||||
implements MouseListener, ActionListener {
|
||||
|
||||
private JMenuItem
|
||||
copy,
|
||||
cut,
|
||||
paste;
|
||||
|
||||
private long
|
||||
pressed;
|
||||
|
||||
// ---%-@-%---
|
||||
|
||||
public void
|
||||
mousePressed(MouseEvent eM)
|
||||
{
|
||||
assert eM.getSource() instanceof JTextComponent;
|
||||
if (!eM.isPopupTrigger()) return;
|
||||
show((Component)eM.getSource(), eM.getX(), eM.getY());
|
||||
}
|
||||
|
||||
public void
|
||||
mouseReleased(MouseEvent eM)
|
||||
{
|
||||
if (eM.getClickCount() == 0) setVisible(false);
|
||||
}
|
||||
|
||||
public void
|
||||
mouseClicked(MouseEvent eM) { }
|
||||
|
||||
public void
|
||||
mouseEntered(MouseEvent eM) { }
|
||||
|
||||
public void
|
||||
mouseExited(MouseEvent eM) { }
|
||||
|
||||
public void
|
||||
actionPerformed(ActionEvent eA)
|
||||
{
|
||||
assert getInvoker() instanceof JTextComponent;
|
||||
JTextComponent inv = (JTextComponent)getInvoker();
|
||||
|
||||
if (eA.getSource() == copy) inv.copy();
|
||||
if (eA.getSource() == cut) inv.cut();
|
||||
if (eA.getSource() == paste) inv.paste();
|
||||
}
|
||||
|
||||
// ---%-@-%---
|
||||
|
||||
public
|
||||
TextActionPopupMenu()
|
||||
{
|
||||
copy = new JMenuItem("Copy");
|
||||
cut = new JMenuItem("Cut");
|
||||
paste = new JMenuItem("Paste");
|
||||
copy.addActionListener(this);
|
||||
cut.addActionListener(this);
|
||||
paste.addActionListener(this);
|
||||
|
||||
add(cut);
|
||||
add(copy);
|
||||
add(paste);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
0
ImageApi.java
Normal file → Executable file
0
ImageWindow.java
Normal file → Executable file
7
JKomasto.java
Normal file → Executable file
@ -22,6 +22,7 @@ import javax.swing.plaf.metal.DefaultMetalTheme;
|
||||
import javax.swing.plaf.metal.OceanTheme;
|
||||
import javax.swing.plaf.ColorUIResource;
|
||||
import javax.swing.UIDefaults;
|
||||
import java.io.File;
|
||||
import cafe.biskuteri.hinoki.Tree;
|
||||
|
||||
|
||||
@ -569,6 +570,9 @@ Attachment {
|
||||
public Image
|
||||
image;
|
||||
|
||||
public File
|
||||
uploadee;
|
||||
|
||||
// ---%-@-%---
|
||||
|
||||
public void
|
||||
@ -616,6 +620,9 @@ Composition {
|
||||
public Attachment[]
|
||||
attachments;
|
||||
|
||||
private File
|
||||
uploadee;
|
||||
|
||||
// ---%-@-%---
|
||||
|
||||
public
|
||||
|
0
KDE_Dialog_Appear.wav
Normal file → Executable file
0
LoginWindow.java
Normal file → Executable file
0
MastodonApi.java
Normal file → Executable file
0
NotificationsWindow.java
Normal file → Executable file
0
PostWindow.java
Normal file → Executable file
0
ProfileWindow.java
Normal file → Executable file
0
RepliesWindow.java
Normal file → Executable file
0
RequestListener.java
Normal file → Executable file
0
RichTextPane.java
Normal file → Executable file
0
RichTextPane2.java
Normal file → Executable file
1
RichTextPane3.java
Normal file → Executable file
@ -366,6 +366,7 @@ implements
|
||||
public void
|
||||
mousePressed(MouseEvent eM)
|
||||
{
|
||||
if (eM.getButton() != MouseEvent.BUTTON1) return;
|
||||
selStart = identifyNodeAt(eM.getX(), eM.getY());
|
||||
selEnd = null;
|
||||
repaint();
|
||||
|
0
RudimentaryHTMLParser.java
Normal file → Executable file
0
TimelineWindow.java
Normal file → Executable file
0
TwoToggleButton.java
Normal file → Executable file
0
WindowUpdater.java
Normal file → Executable file
0
graphics/Federated.xcf
Normal file → Executable file
0
graphics/Flags.xcf
Normal file → Executable file
0
graphics/Home.xcf
Normal file → Executable file
0
graphics/Hourglass.xcf
Normal file → Executable file
0
graphics/Kettle.xcf
Normal file → Executable file
0
graphics/boostToggled.png
Normal file → Executable file
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
0
graphics/boostUntoggled.png
Normal file → Executable file
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
0
graphics/button.png
Normal file → Executable file
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
0
graphics/disabledOverlay.png
Normal file → Executable file
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
0
graphics/favouriteToggled.png
Normal file → Executable file
Before Width: | Height: | Size: 353 B After Width: | Height: | Size: 353 B |
0
graphics/favouriteUntoggled.png
Normal file → Executable file
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
0
graphics/federated.png
Normal file → Executable file
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
0
graphics/home.png
Normal file → Executable file
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
0
graphics/kettle.png
Normal file → Executable file
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
0
graphics/miscToggled.png
Normal file → Executable file
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
0
graphics/miscUntoggled.png
Normal file → Executable file
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
0
graphics/nextToggled.png
Normal file → Executable file
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
0
graphics/nextUntoggled.png
Normal file → Executable file
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
0
graphics/postWindow.png
Normal file → Executable file
Before Width: | Height: | Size: 978 B After Width: | Height: | Size: 978 B |
0
graphics/prevToggled.png
Normal file → Executable file
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
0
graphics/prevUntoggled.png
Normal file → Executable file
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
0
graphics/ref1.png
Normal file → Executable file
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
0
graphics/replyToggled.png
Normal file → Executable file
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
0
graphics/replyUntoggled.png
Normal file → Executable file
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
0
graphics/selectedOverlay.png
Normal file → Executable file
Before Width: | Height: | Size: 313 B After Width: | Height: | Size: 313 B |
0
graphics/test1.png
Normal file → Executable file
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
0
graphics/test2.png
Normal file → Executable file
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
0
graphics/test3.png
Normal file → Executable file
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
0
graphics/test4.png
Normal file → Executable file
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |