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

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