You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PasteDialog.java 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /*
  2. * Copyright (c) 2006-2017 DMDirc Developers
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
  5. * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
  6. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
  7. * permit persons to whom the Software is furnished to do so, subject to the following conditions:
  8. *
  9. * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
  10. * Software.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  13. * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
  14. * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  15. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  16. */
  17. package com.dmdirc.addons.ui_swing.dialogs.paste;
  18. import com.dmdirc.addons.ui_swing.UIUtilities;
  19. import com.dmdirc.addons.ui_swing.components.frames.InputTextFrame;
  20. import com.dmdirc.addons.ui_swing.components.inputfields.SwingInputHandler;
  21. import com.dmdirc.addons.ui_swing.components.inputfields.TextAreaInputField;
  22. import com.dmdirc.addons.ui_swing.components.text.TextLabel;
  23. import com.dmdirc.addons.ui_swing.dialogs.StandardDialog;
  24. import com.dmdirc.interfaces.CommandController;
  25. import com.dmdirc.events.eventbus.EventBus;
  26. import com.dmdirc.interfaces.config.AggregateConfigProvider;
  27. import com.dmdirc.plugins.ServiceManager;
  28. import com.dmdirc.addons.ui_swing.components.IconManager;
  29. import com.dmdirc.ui.input.TabCompleterUtils;
  30. import com.dmdirc.ui.messages.ColourManagerFactory;
  31. import java.awt.Window;
  32. import java.awt.event.ActionEvent;
  33. import java.awt.event.ActionListener;
  34. import java.awt.event.KeyEvent;
  35. import java.awt.event.KeyListener;
  36. import javax.swing.AbstractAction;
  37. import javax.swing.JButton;
  38. import javax.swing.JComponent;
  39. import javax.swing.JScrollPane;
  40. import javax.swing.KeyStroke;
  41. import javax.swing.SwingUtilities;
  42. import javax.swing.WindowConstants;
  43. import net.miginfocom.swing.MigLayout;
  44. /**
  45. * Allows the user to confirm and modify a multi-line paste.
  46. */
  47. public final class PasteDialog extends StandardDialog implements ActionListener,
  48. KeyListener {
  49. /** Serial version UID. */
  50. private static final long serialVersionUID = 4;
  51. /** Number of lines Label. */
  52. private TextLabel infoLabel;
  53. /** Text area scrollpane. */
  54. private JScrollPane scrollPane;
  55. /** Text area. */
  56. private TextAreaInputField textField;
  57. /** Parent frame. */
  58. private final InputTextFrame parent;
  59. /** Edit button. */
  60. private JButton editButton;
  61. /** Parent window. */
  62. private final Window parentWindow;
  63. /** Icon manager to retrieve icons with. */
  64. private final IconManager iconManager;
  65. /** Service Manager to retrieve tab completers with. */
  66. private final ServiceManager serviceManager;
  67. /** Config to read settings from. */
  68. private final AggregateConfigProvider config;
  69. /** The controller to use to retrieve command information. */
  70. private final CommandController commandController;
  71. /**
  72. * Creates a new instance of PreferencesDialog.
  73. *
  74. * @param iconManager Icon manager to retrieve icons with
  75. * @param config Config to read settings from
  76. * @param serviceManager to retrieve tab completers with
  77. * @param commandController The controller to use to retrieve command information.
  78. * @param eventBus The bus to dispatch events on.
  79. * @param newParent The frame that owns this dialog
  80. * @param text text to show in the paste dialog
  81. * @param parentWindow Parent window
  82. */
  83. public PasteDialog(
  84. final IconManager iconManager,
  85. final AggregateConfigProvider config,
  86. final ServiceManager serviceManager,
  87. final CommandController commandController,
  88. final EventBus eventBus,
  89. final InputTextFrame newParent,
  90. final String text,
  91. final Window parentWindow,
  92. final ColourManagerFactory colourManagerFactory,
  93. final TabCompleterUtils tabCompleterUtils) {
  94. super(parentWindow, ModalityType.MODELESS);
  95. parent = newParent;
  96. this.parentWindow = parentWindow;
  97. this.iconManager = iconManager;
  98. this.config = config;
  99. this.serviceManager = serviceManager;
  100. this.commandController = commandController;
  101. initComponents(eventBus, text, colourManagerFactory, tabCompleterUtils);
  102. initListeners();
  103. setFocusTraversalPolicy(new PasteDialogFocusTraversalPolicy(
  104. getCancelButton(), editButton, getOkButton()));
  105. setFocusable(true);
  106. getOkButton().requestFocusInWindow();
  107. getOkButton().setSelected(true);
  108. }
  109. /**
  110. * Initialises GUI components.
  111. *
  112. * @param text text to show in the dialog
  113. */
  114. private void initComponents(final EventBus eventBus, final String text,
  115. final ColourManagerFactory colourManagerFactory,
  116. final TabCompleterUtils tabCompleterUtils) {
  117. scrollPane = new JScrollPane();
  118. textField = new TextAreaInputField(iconManager, colourManagerFactory, config, text);
  119. editButton = new JButton("Edit");
  120. infoLabel = new TextLabel();
  121. UIUtilities.addUndoManager(textField);
  122. orderButtons(new JButton(), new JButton());
  123. getOkButton().setText("Send");
  124. setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
  125. setTitle("Multi-line paste");
  126. setResizable(false);
  127. infoLabel.setText("This will be sent as "
  128. + parent.getContainer().getInputModel().get().getNumLines(textField.getText())
  129. + " lines. Are you sure you want to continue?");
  130. textField.setColumns(50);
  131. textField.setRows(10);
  132. new SwingInputHandler(serviceManager, textField, commandController,
  133. parent.getContainer().getInputModel().get().getCommandParser(),
  134. parent.getContainer(), tabCompleterUtils, eventBus)
  135. .setTypes(false, false, true,false);
  136. scrollPane.setViewportView(textField);
  137. scrollPane.setVisible(false);
  138. getContentPane().setLayout(new MigLayout("fill, hidemode 3"));
  139. getContentPane().add(infoLabel, "wrap, growx, pushx, span 3");
  140. getContentPane().add(scrollPane, "wrap, grow, push, span 3");
  141. getContentPane().add(getLeftButton(), "right, sg button");
  142. getContentPane().add(editButton, "right, sg button");
  143. getContentPane().add(getRightButton(), "right, sg button");
  144. }
  145. /**
  146. * Initialises listeners for this dialog.
  147. */
  148. private void initListeners() {
  149. getOkButton().addActionListener(this);
  150. getCancelButton().addActionListener(this);
  151. editButton.addActionListener(this);
  152. textField.addKeyListener(this);
  153. getRootPane().getActionMap().put("rightArrowAction",
  154. new AbstractAction("rightArrowAction") {
  155. private static final long serialVersionUID = 1;
  156. @Override
  157. public void actionPerformed(final ActionEvent evt) {
  158. final JButton button = (JButton) getFocusTraversalPolicy().
  159. getComponentAfter(PasteDialog.this, getFocusOwner());
  160. button.requestFocusInWindow();
  161. button.setSelected(true);
  162. }
  163. });
  164. getRootPane().getActionMap().put("leftArrowAction",
  165. new AbstractAction("leftArrowAction") {
  166. private static final long serialVersionUID = 1;
  167. @Override
  168. public void actionPerformed(final ActionEvent evt) {
  169. final JButton button = (JButton) getFocusTraversalPolicy().
  170. getComponentBefore(PasteDialog.this, getFocusOwner());
  171. button.requestFocusInWindow();
  172. button.setSelected(true);
  173. }
  174. });
  175. getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
  176. KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "rightArrowAction");
  177. getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
  178. KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "leftArrowAction");
  179. }
  180. @Override
  181. public void actionPerformed(final ActionEvent actionEvent) {
  182. if (getOkButton().equals(actionEvent.getSource())) {
  183. if (!textField.getText().isEmpty()) {
  184. final String[] lines = textField.getText().split("(\n|\r\n|\r)",
  185. Integer.MAX_VALUE);
  186. for (final String line : lines) {
  187. if (!line.isEmpty()) {
  188. parent.getContainer().getInputModel().ifPresent(im -> im.sendLine(line));
  189. parent.getInputHandler().addToBuffer(line);
  190. }
  191. }
  192. }
  193. dispose();
  194. } else if (editButton.equals(actionEvent.getSource())) {
  195. editButton.setEnabled(false);
  196. setResizable(true);
  197. scrollPane.setVisible(true);
  198. infoLabel.setText("This will be sent as "
  199. + parent.getContainer().getInputModel().get().getNumLines(textField.getText())
  200. + " lines.");
  201. setResizable(true);
  202. pack();
  203. SwingUtilities.invokeLater(() -> setLocationRelativeTo(parentWindow));
  204. } else if (getCancelButton().equals(actionEvent.getSource())) {
  205. dispose();
  206. }
  207. }
  208. @Override
  209. public void keyTyped(final KeyEvent e) {
  210. infoLabel.setText("This will be sent as "
  211. + parent.getContainer().getInputModel().get().getNumLines(textField.getText())
  212. + " lines.");
  213. }
  214. @Override
  215. public void keyPressed(final KeyEvent e) {
  216. // Do nothing
  217. }
  218. @Override
  219. public void keyReleased(final KeyEvent e) {
  220. // Do nothing
  221. }
  222. }