1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package ca.uhn.hl7v2.testpanel.ui.editor;
27
28 import java.awt.BorderLayout;
29 import java.awt.Color;
30 import java.awt.Component;
31 import java.awt.Dimension;
32 import java.awt.EventQueue;
33 import java.awt.Font;
34 import java.awt.Frame;
35 import java.awt.GridBagConstraints;
36 import java.awt.GridBagLayout;
37 import java.awt.Insets;
38 import java.awt.Point;
39 import java.awt.SystemColor;
40 import java.awt.Toolkit;
41 import java.awt.datatransfer.Clipboard;
42 import java.awt.datatransfer.StringSelection;
43 import java.awt.event.ActionEvent;
44 import java.awt.event.ActionListener;
45 import java.awt.event.MouseAdapter;
46 import java.awt.event.MouseEvent;
47 import java.beans.PropertyChangeEvent;
48 import java.beans.PropertyChangeListener;
49 import java.util.ArrayList;
50 import java.util.List;
51
52 import javax.swing.Box;
53 import javax.swing.ButtonGroup;
54 import javax.swing.DefaultComboBoxModel;
55 import javax.swing.ImageIcon;
56 import javax.swing.JButton;
57 import javax.swing.JComboBox;
58 import javax.swing.JEditorPane;
59 import javax.swing.JLabel;
60 import javax.swing.JMenuItem;
61 import javax.swing.JPanel;
62 import javax.swing.JPopupMenu;
63 import javax.swing.JRadioButton;
64 import javax.swing.JScrollBar;
65 import javax.swing.JScrollPane;
66 import javax.swing.JSplitPane;
67 import javax.swing.JTabbedPane;
68 import javax.swing.JToggleButton;
69 import javax.swing.JToolBar;
70 import javax.swing.SwingConstants;
71 import javax.swing.SwingUtilities;
72 import javax.swing.event.CaretEvent;
73 import javax.swing.event.CaretListener;
74 import javax.swing.event.DocumentEvent;
75 import javax.swing.event.DocumentListener;
76 import javax.swing.text.Highlighter;
77
78 import jsyntaxpane.DefaultSyntaxKit;
79
80 import org.apache.commons.lang.StringUtils;
81 import org.apache.commons.lang.Validate;
82 import org.slf4j.Logger;
83 import org.slf4j.LoggerFactory;
84
85 import ca.uhn.hl7v2.conf.ProfileException;
86 import ca.uhn.hl7v2.testpanel.controller.Controller;
87 import ca.uhn.hl7v2.testpanel.controller.Prefs;
88 import ca.uhn.hl7v2.testpanel.model.conf.ProfileFileList;
89 import ca.uhn.hl7v2.testpanel.model.conf.ProfileGroup;
90 import ca.uhn.hl7v2.testpanel.model.conn.OutboundConnection;
91 import ca.uhn.hl7v2.testpanel.model.conn.OutboundConnectionList;
92 import ca.uhn.hl7v2.testpanel.model.msg.Hl7V2MessageCollection;
93 import ca.uhn.hl7v2.testpanel.ui.ActivityTable;
94 import ca.uhn.hl7v2.testpanel.ui.BaseMainPanel;
95 import ca.uhn.hl7v2.testpanel.ui.Er7SyntaxKit;
96 import ca.uhn.hl7v2.testpanel.ui.HoverButtonMouseAdapter;
97 import ca.uhn.hl7v2.testpanel.ui.IDestroyable;
98 import ca.uhn.hl7v2.testpanel.ui.ShowEnum;
99 import ca.uhn.hl7v2.testpanel.ui.v2tree.Hl7V2MessageTree;
100 import ca.uhn.hl7v2.testpanel.ui.v2tree.Hl7V2MessageTree.IWorkingListener;
101 import ca.uhn.hl7v2.testpanel.util.IOkCancelCallback;
102 import ca.uhn.hl7v2.testpanel.util.Range;
103 import ca.uhn.hl7v2.testpanel.xsd.Hl7V2EncodingTypeEnum;
104 import ca.uhn.hl7v2.validation.impl.DefaultValidation;
105
106 public class Hl7V2MessageEditorPanel extends BaseMainPanel implements IDestroyable {
107 private static final String CREATE_NEW_CONNECTION = "Create New Connection...";
108 private static final String NO_CONNECTIONS = "No Connections";
109 private static final Logger ourLog = LoggerFactory.getLogger(Hl7V2MessageEditorPanel.class);
110 private SendOptionsPopupDialog mySendOptionsPopupDialog;
111
112 static {
113
114 System.setProperty("DefaultFont", "ARIAL-PLAIN-13");
115
116 try {
117 DefaultSyntaxKit.initKit();
118 DefaultSyntaxKit.registerContentType("text/er7", Er7SyntaxKit.class.getName());
119 ourLog.info("Registered syntaxKit");
120 } catch (Throwable e) {
121 e.printStackTrace();
122 }
123
124 }
125
126 private boolean myDontRespondToSourceMessageChanges;
127 private Component myhorizontalStrut_4;
128 private JPanel bottomPanel;
129 private JPanel messageEditorContainerPanel;
130 private JComboBox myShowCombo;
131 private Controller myController;
132 private boolean myDisableCaretUpdateHandling;
133 private DocumentListener myDocumentListener;
134 private JToggleButton myFollowToggle;
135 private JLabel mylabel;
136 private JLabel mylabel_1;
137 private JLabel mylabel_2;
138 private JLabel mylabel_3;
139 private Hl7V2MessageCollection myMessage;
140 private JEditorPane myMessageEditor;
141 private PropertyChangeListener myMessageListeneer;
142 private JScrollPane myMessageScrollPane;
143 private PropertyChangeListener myOutboundConnectionsListener;
144 private JComboBox myOutboundInterfaceCombo;
145 private DefaultComboBoxModel myOutboundInterfaceComboModel;
146 private JComboBox myProfileCombobox;
147 private ProfileComboModel myProfileComboboxModel;
148 private PropertyChangeListener myRangeListener;
149 private JRadioButton myRdbtnEr7;
150 private JRadioButton myRdbtnXml;
151 private PropertyChangeListener mySelectedPathListener;
152 private JButton mySendButton;
153 private JSplitPane mysplitPane;
154 private JLabel myTerserPathTextField;
155 private JToolBar mytoolBar;
156 private Hl7V2MessageTree myTreePanel;
157 private JScrollPane myTreeScrollPane;
158 private JPanel treeContainerPanel;
159 private JTabbedPane myTopTabBar;
160
161 private ActivityTable mySendingActivityTable;
162 private PropertyChangeListener myWindowTitleListener;
163 private Component myhorizontalStrut;
164 private Component myhorizontalStrut_1;
165 private boolean myOutboundInterfaceComboModelIsUpdating;
166 private ArrayList<OutboundConnection> myOutboundInterfaceComboModelShadow;
167 private final JPopupMenu myTerserPathPopupMenu = new JPopupMenu();
168 private boolean myHandlingProfileComboboxChange;
169 private JLabel mylabel_4;
170 private JToolBar mytoolBar_1;
171 private TablesComboModel myTablesComboModel;
172 private PropertyChangeListener myProfilesListener;
173 private PropertyChangeListener myProfilesNamesListener;
174 private JButton mySpinner;
175 private Component myhorizontalGlue;
176 private ImageIcon mySpinnerIconOn;
177 private ImageIcon mySpinnerIconOff;
178 private JButton collapseAllButton;
179 private JButton expandAllButton;
180 private Component myhorizontalStrut_2;
181 private JButton mySendOptionsButton;
182
183
184
185
186 public Hl7V2MessageEditorPanel(final Controller theController) {
187 setBorder(null);
188 myController = theController;
189
190 ButtonGroup encGrp = new ButtonGroup();
191 setLayout(new BorderLayout(0, 0));
192
193 mysplitPane = new JSplitPane();
194 mysplitPane.setResizeWeight(0.5);
195 mysplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
196 add(mysplitPane);
197
198 mysplitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
199 public void propertyChange(PropertyChangeEvent theEvt) {
200 double ratio = (double) mysplitPane.getDividerLocation() / mysplitPane.getHeight();
201 ourLog.debug("Resizing split to ratio: {}", ratio);
202 Prefs.getInstance().setHl7EditorSplit(ratio);
203 }
204 });
205
206 EventQueue.invokeLater(new Runnable() {
207 public void run() {
208 mysplitPane.setDividerLocation(Prefs.getInstance().getHl7EditorSplit());
209 }
210 });
211
212 messageEditorContainerPanel = new JPanel();
213 messageEditorContainerPanel.setBorder(null);
214 mysplitPane.setRightComponent(messageEditorContainerPanel);
215 messageEditorContainerPanel.setLayout(new BorderLayout(0, 0));
216
217 myMessageEditor = new JEditorPane();
218 Highlighter h = new UnderlineHighlighter();
219 myMessageEditor.setHighlighter(h);
220
221 myMessageEditor.setSelectedTextColor(Color.black);
222
223 myMessageEditor.setCaret(new EditorCaret());
224
225 myMessageScrollPane = new JScrollPane(myMessageEditor);
226 messageEditorContainerPanel.add(myMessageScrollPane);
227
228 JToolBar toolBar = new JToolBar();
229 messageEditorContainerPanel.add(toolBar, BorderLayout.NORTH);
230 toolBar.setFloatable(false);
231 toolBar.setRollover(true);
232
233 myFollowToggle = new JToggleButton("Follow");
234 myFollowToggle.setToolTipText("Keep the message tree (above) and the message editor (below) in sync");
235 myFollowToggle.addActionListener(new ActionListener() {
236 public void actionPerformed(ActionEvent e) {
237 theController.setMessageEditorInFollowMode(myFollowToggle.isSelected());
238 }
239 });
240 myFollowToggle.setIcon(new ImageIcon(Hl7V2MessageEditorPanel.class.getResource("/ca/uhn/hl7v2/testpanel/images/updown.png")));
241 myFollowToggle.setSelected(theController.isMessageEditorInFollowMode());
242 toolBar.add(myFollowToggle);
243
244 myhorizontalStrut = Box.createHorizontalStrut(20);
245 toolBar.add(myhorizontalStrut);
246
247 mylabel_4 = new JLabel("Encoding");
248 toolBar.add(mylabel_4);
249
250 myRdbtnEr7 = new JRadioButton("ER7");
251 myRdbtnEr7.setMargin(new Insets(1, 2, 0, 1));
252 toolBar.add(myRdbtnEr7);
253
254 myRdbtnXml = new JRadioButton("XML");
255 myRdbtnXml.setMargin(new Insets(1, 5, 0, 1));
256 toolBar.add(myRdbtnXml);
257 encGrp.add(myRdbtnEr7);
258 encGrp.add(myRdbtnXml);
259
260 treeContainerPanel = new JPanel();
261 mysplitPane.setLeftComponent(treeContainerPanel);
262 treeContainerPanel.setLayout(new BorderLayout(0, 0));
263
264 mySpinnerIconOn = new ImageIcon(Hl7V2MessageEditorPanel.class.getResource("/ca/uhn/hl7v2/testpanel/images/spinner.gif"));
265 mySpinnerIconOff = new ImageIcon();
266
267 myTreePanel = new Hl7V2MessageTree(theController);
268 myTreePanel.setWorkingListener(new IWorkingListener() {
269
270 public void startedWorking() {
271 mySpinner.setText("");
272 mySpinner.setIcon(mySpinnerIconOn);
273 mySpinnerIconOn.setImageObserver(mySpinner);
274 }
275
276
277 public void finishedWorking(String theStatus) {
278 mySpinner.setText(theStatus);
279
280 mySpinner.setIcon(mySpinnerIconOff);
281 mySpinnerIconOn.setImageObserver(null);
282 }
283 });
284 myTreeScrollPane = new JScrollPane(myTreePanel);
285
286 myTopTabBar = new JTabbedPane();
287 treeContainerPanel.add(myTopTabBar);
288 myTopTabBar.setBorder(null);
289
290 JPanel treeContainer = new JPanel();
291 treeContainer.setLayout(new BorderLayout(0, 0));
292 treeContainer.add(myTreeScrollPane);
293
294 myTopTabBar.add("Message Tree", treeContainer);
295
296 mytoolBar_1 = new JToolBar();
297 mytoolBar_1.setFloatable(false);
298 treeContainer.add(mytoolBar_1, BorderLayout.NORTH);
299
300 mylabel_3 = new JLabel("Show");
301 mytoolBar_1.add(mylabel_3);
302
303 myShowCombo = new JComboBox();
304 mytoolBar_1.add(myShowCombo);
305 myShowCombo.setPreferredSize(new Dimension(130, 27));
306 myShowCombo.setMinimumSize(new Dimension(130, 27));
307 myShowCombo.setMaximumSize(new Dimension(130, 32767));
308
309 collapseAllButton = new JButton();
310 collapseAllButton.setBorderPainted(false);
311 collapseAllButton.addMouseListener(new HoverButtonMouseAdapter(collapseAllButton));
312 collapseAllButton.addActionListener(new ActionListener() {
313 public void actionPerformed(ActionEvent e) {
314 myTreePanel.collapseAll();
315 }
316 });
317 collapseAllButton.setToolTipText("Collapse All");
318 collapseAllButton.setIcon(new ImageIcon(Hl7V2MessageEditorPanel.class.getResource("/ca/uhn/hl7v2/testpanel/images/collapse_all.png")));
319 mytoolBar_1.add(collapseAllButton);
320
321 expandAllButton = new JButton();
322 expandAllButton.setBorderPainted(false);
323 expandAllButton.addMouseListener(new HoverButtonMouseAdapter(expandAllButton));
324 expandAllButton.addActionListener(new ActionListener() {
325 public void actionPerformed(ActionEvent e) {
326 myTreePanel.expandAll();
327 }
328 });
329 expandAllButton.setToolTipText("Expand All");
330 expandAllButton.setIcon(new ImageIcon(Hl7V2MessageEditorPanel.class.getResource("/ca/uhn/hl7v2/testpanel/images/expand_all.png")));
331 mytoolBar_1.add(expandAllButton);
332
333 myhorizontalGlue = Box.createHorizontalGlue();
334 mytoolBar_1.add(myhorizontalGlue);
335
336 mySpinner = new JButton("");
337 mySpinner.setForeground(Color.DARK_GRAY);
338 mySpinner.setHorizontalAlignment(SwingConstants.RIGHT);
339 mySpinner.setMaximumSize(new Dimension(200, 15));
340 mySpinner.setPreferredSize(new Dimension(200, 15));
341 mySpinner.setMinimumSize(new Dimension(200, 15));
342 mySpinner.setBorderPainted(false);
343 mySpinner.setSize(new Dimension(16, 16));
344 mytoolBar_1.add(mySpinner);
345 myProfileComboboxModel = new ProfileComboModel();
346
347 myTablesComboModel = new TablesComboModel(myController);
348
349 mytoolBar = new JToolBar();
350 mytoolBar.setFloatable(false);
351 mytoolBar.setRollover(true);
352 treeContainerPanel.add(mytoolBar, BorderLayout.NORTH);
353
354 myOutboundInterfaceCombo = new JComboBox();
355 myOutboundInterfaceComboModel = new DefaultComboBoxModel();
356
357 mylabel_1 = new JLabel("Send");
358 mytoolBar.add(mylabel_1);
359 myOutboundInterfaceCombo.setModel(myOutboundInterfaceComboModel);
360 myOutboundInterfaceCombo.setMaximumSize(new Dimension(200, 32767));
361 mytoolBar.add(myOutboundInterfaceCombo);
362
363 mySendButton = new JButton("Send");
364 mySendButton.addMouseListener(new HoverButtonMouseAdapter(mySendButton));
365 mySendButton.setBorderPainted(false);
366 mySendButton.addActionListener(new ActionListener() {
367 public void actionPerformed(ActionEvent e) {
368
369
370 int selectedIndex = myOutboundInterfaceCombo.getSelectedIndex();
371 OutboundConnection connection = myController.getOutboundConnectionList().getConnections().get(selectedIndex);
372 activateSendingActivityTabForConnection(connection);
373 myController.sendMessages(connection, myMessage, mySendingActivityTable.provideTransmissionCallback());
374 }
375 });
376
377 myhorizontalStrut_2 = Box.createHorizontalStrut(20);
378 myhorizontalStrut_2.setPreferredSize(new Dimension(2, 0));
379 myhorizontalStrut_2.setMinimumSize(new Dimension(2, 0));
380 myhorizontalStrut_2.setMaximumSize(new Dimension(2, 32767));
381 mytoolBar.add(myhorizontalStrut_2);
382
383 mySendOptionsButton = new JButton("Options");
384 mySendOptionsButton.setBorderPainted(false);
385 final HoverButtonMouseAdapteroverButtonMouseAdapter">HoverButtonMouseAdapter sendOptionsHoverAdaptor = new HoverButtonMouseAdapter(mySendOptionsButton);
386 mySendOptionsButton.addMouseListener(sendOptionsHoverAdaptor);
387 mySendOptionsButton.setIcon(new ImageIcon(Hl7V2MessageEditorPanel.class.getResource("/ca/uhn/hl7v2/testpanel/images/sendoptions.png")));
388 mytoolBar.add(mySendOptionsButton);
389 mySendOptionsButton.addActionListener(new ActionListener() {
390
391 public void actionPerformed(ActionEvent theE) {
392 if (mySendOptionsPopupDialog != null) {
393 mySendOptionsPopupDialog.doHide();
394 mySendOptionsPopupDialog = null;
395 return;
396 }
397 mySendOptionsPopupDialog = new SendOptionsPopupDialog(Hl7V2MessageEditorPanel.this, myMessage, mySendOptionsButton, sendOptionsHoverAdaptor);
398 Point los = mySendOptionsButton.getLocationOnScreen();
399 mySendOptionsPopupDialog.setLocation(los.x, los.y + mySendOptionsButton.getHeight());
400 mySendOptionsPopupDialog.setVisible(true);
401 }
402 });
403
404 mySendButton.setIcon(new ImageIcon(Hl7V2MessageEditorPanel.class.getResource("/ca/uhn/hl7v2/testpanel/images/button_execute.png")));
405 mytoolBar.add(mySendButton);
406
407 myhorizontalStrut_1 = Box.createHorizontalStrut(20);
408 mytoolBar.add(myhorizontalStrut_1);
409
410 mylabel_2 = new JLabel("Validate");
411 mytoolBar.add(mylabel_2);
412
413 myProfileCombobox = new JComboBox();
414 mytoolBar.add(myProfileCombobox);
415 myProfileCombobox.setPreferredSize(new Dimension(200, 27));
416 myProfileCombobox.setMinimumSize(new Dimension(200, 27));
417 myProfileCombobox.addActionListener(new ActionListener() {
418
419 public void actionPerformed(ActionEvent e) {
420 if (myHandlingProfileComboboxChange) {
421 return;
422 }
423
424 myHandlingProfileComboboxChange = true;
425 try {
426 if (myProfileCombobox.getSelectedIndex() == 0) {
427 myMessage.setValidationContext(null);
428 } else if (myProfileCombobox.getSelectedIndex() == 1) {
429 myMessage.setValidationContext(new DefaultValidation());
430 } else if (myProfileCombobox.getSelectedIndex() > 0) {
431 ProfileGroup profile = myProfileComboboxModel.myProfileGroups.get(myProfileCombobox.getSelectedIndex());
432 myMessage.setRuntimeProfile(profile);
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448 }
449 } catch (ProfileException e2) {
450 ourLog.error("Failed to load profile", e2);
451 } finally {
452 myHandlingProfileComboboxChange = false;
453 }
454 }
455 });
456 myProfileCombobox.setMaximumSize(new Dimension(300, 32767));
457 myProfileCombobox.setModel(myProfileComboboxModel);
458
459 myhorizontalStrut_4 = Box.createHorizontalStrut(20);
460 myhorizontalStrut_4.setPreferredSize(new Dimension(2, 0));
461 myhorizontalStrut_4.setMinimumSize(new Dimension(2, 0));
462 myhorizontalStrut_4.setMaximumSize(new Dimension(2, 32767));
463 mytoolBar.add(myhorizontalStrut_4);
464
465
466
467
468
469
470 mySendingActivityTable = new ActivityTable();
471 mySendingActivityTable.setController(myController);
472 myTopTabBar.addTab("Sending", null, mySendingActivityTable, null);
473
474
475
476
477
478
479
480
481 bottomPanel = new JPanel();
482 bottomPanel.setPreferredSize(new Dimension(10, 20));
483 bottomPanel.setMinimumSize(new Dimension(10, 20));
484 add(bottomPanel, BorderLayout.SOUTH);
485 GridBagLayout gbl_bottomPanel = new GridBagLayout();
486 gbl_bottomPanel.columnWidths = new int[] { 98, 74, 0 };
487 gbl_bottomPanel.rowHeights = new int[] { 16, 0 };
488 gbl_bottomPanel.columnWeights = new double[] { 0.0, 1.0, Double.MIN_VALUE };
489 gbl_bottomPanel.rowWeights = new double[] { 0.0, Double.MIN_VALUE };
490 bottomPanel.setLayout(gbl_bottomPanel);
491
492 mylabel = new JLabel("Terser Path:");
493 mylabel.setHorizontalTextPosition(SwingConstants.LEFT);
494 mylabel.setHorizontalAlignment(SwingConstants.LEFT);
495 GridBagConstraints gbc_label = new GridBagConstraints();
496 gbc_label.fill = GridBagConstraints.VERTICAL;
497 gbc_label.weighty = 1.0;
498 gbc_label.anchor = GridBagConstraints.NORTHWEST;
499 gbc_label.gridx = 0;
500 gbc_label.gridy = 0;
501 bottomPanel.add(mylabel, gbc_label);
502
503 myTerserPathTextField = new JLabel();
504 myTerserPathTextField.setForeground(Color.BLUE);
505 myTerserPathTextField.setFont(new Font("Lucida Console", Font.PLAIN, 13));
506 myTerserPathTextField.setBorder(null);
507 myTerserPathTextField.setBackground(SystemColor.control);
508 myTerserPathTextField.addMouseListener(new MouseAdapter() {
509 @Override
510 public void mouseClicked(MouseEvent e) {
511 if (StringUtils.isNotEmpty(myTerserPathTextField.getText())) {
512 myTerserPathPopupMenu.show(myTerserPathTextField, 0, 0);
513 }
514 }
515 });
516
517 GridBagConstraints gbc_TerserPathTextField = new GridBagConstraints();
518 gbc_TerserPathTextField.weightx = 1.0;
519 gbc_TerserPathTextField.fill = GridBagConstraints.HORIZONTAL;
520 gbc_TerserPathTextField.gridx = 1;
521 gbc_TerserPathTextField.gridy = 0;
522 bottomPanel.add(myTerserPathTextField, gbc_TerserPathTextField);
523
524 initLocal();
525
526 }
527
528
529 public void destroy() {
530 myMessage.removePropertyChangeListener(Hl7V2MessageCollection.SOURCE_MESSAGE_PROPERTY, myMessageListeneer);
531 myMessage.removePropertyChangeListener(Hl7V2MessageCollection.PROP_HIGHLITED_RANGE, myRangeListener);
532 myMessage.removePropertyChangeListener(Hl7V2MessageCollection.SAVED_PROPERTY, myWindowTitleListener);
533 myMessage.removePropertyChangeListener(Hl7V2MessageCollection.PROP_SAVE_FILENAME, myWindowTitleListener);
534
535 myTreePanel.destroy();
536 myController.getOutboundConnectionList().addPropertyChangeListener(OutboundConnectionList.PROP_LIST, myOutboundConnectionsListener);
537
538 myTablesComboModel.destroy();
539 unregisterProfileNamesListeners();
540 }
541
542
543 private void initLocal() {
544
545 myDocumentListener = new DocumentListener() {
546
547 public void changedUpdate(DocumentEvent theE) {
548 ourLog.info("Document change: " + theE);
549 handleChange(theE);
550 }
551
552
553 private void handleChange(DocumentEvent theE) {
554 myDontRespondToSourceMessageChanges = true;
555 try {
556 long start = System.currentTimeMillis();
557
558 String newSource = myMessageEditor.getText();
559 int changeStart = theE.getOffset();
560 int changeEnd = changeStart + theE.getLength();
561 myMessage.updateSourceMessage(newSource, changeStart, changeEnd);
562
563 ourLog.info("Handled document update in {} ms", System.currentTimeMillis() - start);
564 } finally {
565 myDontRespondToSourceMessageChanges = false;
566 }
567 }
568
569
570 public void insertUpdate(DocumentEvent theE) {
571 ourLog.info("Document insert: " + theE);
572 handleChange(theE);
573 }
574
575
576 public void removeUpdate(DocumentEvent theE) {
577 ourLog.info("Document removed: " + theE);
578 handleChange(theE);
579 }
580 };
581 myMessageEditor.getDocument().addDocumentListener(myDocumentListener);
582
583 myMessageEditor.addCaretListener(new CaretListener() {
584
585 public void caretUpdate(final CaretEvent theE) {
586 removeMostHighlights();
587 if (!myDisableCaretUpdateHandling) {
588 myController.invokeInBackground(new Runnable() {
589 public void run() {
590 myMessage.setHighlitedPathBasedOnRange(new Range(theE.getDot(), theE.getMark()));
591 myTreePanel.repaint();
592 }});
593 }
594 }
595 });
596
597 updateOutboundConnectionsBox();
598 myOutboundConnectionsListener = new PropertyChangeListener() {
599
600 public void propertyChange(PropertyChangeEvent theEvt) {
601 updateOutboundConnectionsBox();
602 }
603 };
604 myController.getOutboundConnectionList().addPropertyChangeListener(OutboundConnectionList.PROP_LIST, myOutboundConnectionsListener);
605
606 myOutboundInterfaceCombo.addActionListener(new ActionListener() {
607 public void actionPerformed(ActionEvent theE) {
608 if (!myOutboundInterfaceComboModelIsUpdating) {
609 updateSendButton();
610 }
611 }
612
613 });
614
615 JMenuItem copyMenuItem = new JMenuItem("Copy to Clipboard");
616 copyMenuItem.addActionListener(new ActionListener() {
617 public void actionPerformed(ActionEvent theE) {
618 String selection = myTerserPathTextField.getText();
619 StringSelection data = new StringSelection(selection);
620 Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
621 clipboard.setContents(data, data);
622 }
623 });
624 myTerserPathPopupMenu.add(copyMenuItem);
625
626 myProfilesListener = new PropertyChangeListener() {
627 public void propertyChange(PropertyChangeEvent theEvt) {
628 myProfileComboboxModel.update();
629 registerProfileNamesListeners();
630 }
631 };
632 myController.getProfileFileList().addPropertyChangeListener(ProfileFileList.PROP_FILES, myProfilesListener);
633 registerProfileNamesListeners();
634
635 myProfilesNamesListener = new PropertyChangeListener() {
636 public void propertyChange(PropertyChangeEvent theEvt) {
637 myProfileComboboxModel.update();
638 }
639 };
640
641 }
642
643
644 private void registerProfileNamesListeners() {
645 unregisterProfileNamesListeners();
646 for (ProfileGroup next : myController.getProfileFileList().getProfiles()) {
647 next.addPropertyChangeListener(ProfileGroup.PROP_NAME, myProfilesNamesListener);
648 }
649 }
650
651
652 private void unregisterProfileNamesListeners() {
653 for (ProfileGroup next : myController.getProfileFileList().getProfiles()) {
654 next.removePropertyChangeListener(ProfileGroup.PROP_NAME, myProfilesNamesListener);
655 }
656 }
657
658
659 private void updateSendButton() {
660 String selected = (String) myOutboundInterfaceCombo.getSelectedItem();
661 if (selected == null || selected == NO_CONNECTIONS) {
662 mySendButton.setEnabled(false);
663 if (myMessage != null) {
664 myMessage.setLastSendToInterfaceId(null);
665 }
666 return;
667 }
668
669 if (selected == CREATE_NEW_CONNECTION) {
670 IOkCancelCallback<OutboundConnection> handler = new IOkCancelCallback<OutboundConnection>() {
671 public void ok(OutboundConnection theArg) {
672 myMessage.setLastSendToInterfaceId(theArg.getId());
673 myOutboundInterfaceCombo.setSelectedIndex(myOutboundInterfaceComboModel.getSize() - 2);
674 }
675
676
677 public void cancel(OutboundConnection theArg) {
678 myOutboundInterfaceCombo.setSelectedIndex(0);
679 }
680 };
681 myController.addOutboundConnectionToSendTo(handler);
682 return;
683 }
684
685 if (myMessage != null) {
686 int selectedIndex = myOutboundInterfaceCombo.getSelectedIndex();
687 OutboundConnection connection = myController.getOutboundConnectionList().getConnections().get(selectedIndex);
688 myMessage.setLastSendToInterfaceId(connection.getId());
689 }
690
691 mySendButton.setEnabled(true);
692 }
693
694
695
696
697
698
699 public void setMessage(Hl7V2MessageCollection theMessage) {
700 Validate.isTrue(myMessage == null);
701
702 myMessage = theMessage;
703
704 myShowCombo.setModel(new ShowComboModel());
705
706
707 if (StringUtils.isNotBlank(myMessage.getLastSendToInterfaceId())) {
708 for (int i = 0; i < myOutboundInterfaceComboModelShadow.size(); i++) {
709 if (myOutboundInterfaceComboModelShadow.get(i).getId().equals(myMessage.getLastSendToInterfaceId())) {
710 myOutboundInterfaceCombo.setSelectedIndex(i);
711 break;
712 }
713 }
714 }
715
716 updateEncodingButtons();
717 myRdbtnEr7.addActionListener(new ActionListener() {
718 public void actionPerformed(ActionEvent theE) {
719 removeHighlights();
720 myMessage.setEncoding(Hl7V2EncodingTypeEnum.ER_7);
721 }
722 });
723 myRdbtnXml.addActionListener(new ActionListener() {
724 public void actionPerformed(ActionEvent theE) {
725 removeHighlights();
726 myMessage.setEncoding(Hl7V2EncodingTypeEnum.XML);
727 }
728 });
729
730 try {
731 myDisableCaretUpdateHandling = true;
732 updateMessageEditor();
733 } finally {
734 myDisableCaretUpdateHandling = false;
735 }
736
737 myMessageListeneer = new PropertyChangeListener() {
738 public void propertyChange(PropertyChangeEvent theEvt) {
739 if (myDontRespondToSourceMessageChanges) {
740 return;
741 }
742 try {
743 myDisableCaretUpdateHandling = true;
744 updateMessageEditor();
745 } finally {
746 myDisableCaretUpdateHandling = false;
747 }
748 }
749 };
750 myMessage.addPropertyChangeListener(Hl7V2MessageCollection.SOURCE_MESSAGE_PROPERTY, myMessageListeneer);
751
752 mySelectedPathListener = new PropertyChangeListener() {
753
754 public void propertyChange(PropertyChangeEvent theEvt) {
755 String path = myMessage.getHighlitedPath();
756 if (path == null) {
757 path = "";
758 }
759
760 int index = path.indexOf('/');
761 if (index > -1) {
762 path = path.substring(index);
763 }
764
765 myTerserPathTextField.setText(path);
766 }
767 };
768 myMessage.addPropertyChangeListener(Hl7V2MessageCollection.PROP_HIGHLITED_PATH, mySelectedPathListener);
769
770 myTreePanel.setMessage(myMessage);
771
772 myRangeListener = new PropertyChangeListener() {
773
774 public void propertyChange(PropertyChangeEvent theEvt) {
775 if (theEvt.getNewValue() == null || !myFollowToggle.isSelected()) {
776 return;
777 }
778 Range range = (Range) theEvt.getNewValue();
779
780
781
782
783
784
785 myMessageEditor.setCaretPosition(range.getStart());
786 myMessageEditor.moveCaretPosition(range.getEnd());
787
788 myMessageEditor.setCaretPosition(range.getEnd());
789 myMessageEditor.moveCaretPosition(range.getStart());
790
791
792 myMessageEditor.repaint();
793
794 String substring = myMessage.getSourceMessage().substring(range.getStart(), range.getEnd());
795 ourLog.info("Selected range set to " + range + " which is " + substring);
796 }
797 };
798 myMessage.addPropertyChangeListener(Hl7V2MessageCollection.PROP_HIGHLITED_RANGE, myRangeListener);
799
800 myProfileComboboxModel.update();
801
802
803 myWindowTitleListener = new PropertyChangeListener() {
804 public void propertyChange(PropertyChangeEvent theEvt) {
805 updateWindowTitle();
806 }
807 };
808 myMessage.addPropertyChangeListener(Hl7V2MessageCollection.SAVED_PROPERTY, myWindowTitleListener);
809 myMessage.addPropertyChangeListener(Hl7V2MessageCollection.PROP_SAVE_FILENAME, myWindowTitleListener);
810 updateWindowTitle();
811
812 EventQueue.invokeLater(new Runnable() {
813
814 public void run() {
815 myMessageEditor.setCaretPosition(0);
816 myMessageEditor.grabFocus();
817 }
818 });
819
820 }
821
822
823 private void removeHighlights() {
824 Highlighter hilite = myMessageEditor.getHighlighter();
825 Highlighter.Highlight[] hilites = hilite.getHighlights();
826 for (int i = 0; i < hilites.length; i++) {
827 hilite.removeHighlight(hilites[i]);
828 }
829 }
830
831
832
833
834 private void removeMostHighlights() {
835 Highlighter hilite = myMessageEditor.getHighlighter();
836 Highlighter.Highlight[] hilites = hilite.getHighlights();
837 for (int i = 0; i < hilites.length - 2; i++) {
838 hilite.removeHighlight(hilites[i]);
839 }
840 }
841
842
843 private void updateWindowTitle() {
844 StringBuilder b = new StringBuilder();
845
846 if (myMessage.isSaved() == false) {
847 b.append("Unsaved");
848 }
849
850 if (b.length() > 0) {
851 b.append(" - ");
852 }
853 if (StringUtils.isNotBlank(myMessage.getSaveFileName())) {
854 b.append(myMessage.getSaveFileName());
855 } else {
856 b.append("New File");
857 }
858
859 setWindowTitle(b.toString());
860 }
861
862
863 private void updateEncodingButtons() {
864 switch (myMessage.getEncoding()) {
865 case XML:
866 myRdbtnXml.setSelected(true);
867 myRdbtnEr7.setSelected(false);
868 break;
869 case ER_7:
870 myRdbtnXml.setSelected(false);
871 myRdbtnEr7.setSelected(true);
872 }
873 }
874
875
876
877 private void updateMessageEditor() {
878
879 final JScrollBar vsb = myMessageScrollPane.getVerticalScrollBar();
880 int initialVerticalValue = vsb.getValue();
881
882 myMessageEditor.getDocument().removeDocumentListener(myDocumentListener);
883
884 String sourceMessage = myMessage.getSourceMessage();
885
886 if (myMessage.getEncoding() == Hl7V2EncodingTypeEnum.XML) {
887 myMessageEditor.setContentType("text/xml");
888 } else {
889 myMessageEditor.setContentType("text/er7");
890 sourceMessage = sourceMessage.replace('\r', '\n');
891 }
892
893 myMessageEditor.setText(sourceMessage);
894
895 myMessageEditor.getDocument().addDocumentListener(myDocumentListener);
896
897 final int verticalValue = Math.min(initialVerticalValue, vsb.getMaximum());
898
899 SwingUtilities.invokeLater(new Runnable() {
900 public void run() {
901
902 vsb.setValue(verticalValue);
903 }
904 });
905
906 }
907
908
909 private void updateOutboundConnectionsBox() {
910 int currentSelection = myOutboundInterfaceCombo.getSelectedIndex();
911
912 List<OutboundConnection> conn = myController.getOutboundConnectionList().getConnections();
913
914 myOutboundInterfaceComboModelIsUpdating = true;
915
916 myOutboundInterfaceComboModel.removeAllElements();
917 myOutboundInterfaceComboModelShadow = new ArrayList<OutboundConnection>();
918 if (conn.isEmpty()) {
919 myOutboundInterfaceComboModel.addElement(NO_CONNECTIONS);
920 myOutboundInterfaceComboModelShadow.add(null);
921 } else {
922 for (OutboundConnection next : conn) {
923 myOutboundInterfaceComboModel.addElement(next.getName());
924 myOutboundInterfaceComboModelShadow.add(next);
925 }
926 }
927
928 myOutboundInterfaceComboModel.addElement(CREATE_NEW_CONNECTION);
929 myOutboundInterfaceComboModelShadow.add(null);
930
931 if (currentSelection != -1 && currentSelection < myOutboundInterfaceComboModel.getSize()) {
932 myOutboundInterfaceCombo.setSelectedIndex(currentSelection);
933 } else {
934 myOutboundInterfaceCombo.setSelectedIndex(0);
935 }
936
937 myOutboundInterfaceComboModelIsUpdating = false;
938
939 updateSendButton();
940 }
941
942 private class ProfileComboModel extends DefaultComboBoxModel {
943
944
945
946 private ArrayList<ProfileGroup> myProfileGroups;
947
948
949 public void update() {
950 myHandlingProfileComboboxChange = true;
951 try {
952 super.removeAllElements();
953 myProfileGroups = new ArrayList<ProfileGroup>();
954
955 addElement("No Profile/Validation");
956 myProfileGroups.add(null);
957
958 addElement("Default Datatype Validation (HAPI)");
959 myProfileGroups.add(null);
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976 for (ProfileGroup nextProfile : myController.getProfileFileList().getProfiles()) {
977 String nextString = "Profile Group: " + nextProfile.getName();
978 addElement(nextString);
979 myProfileGroups.add(nextProfile);
980 if (myMessage.getRuntimeProfile() == nextProfile) {
981 setSelectedItem(nextString);
982 }
983 }
984
985 if (myMessage.getValidationContext() instanceof DefaultValidation) {
986 setSelectedItem(getElementAt(1));
987 } else if (getSelectedItem() == null) {
988 setSelectedItem(getElementAt(0));
989 }
990 } finally {
991 myHandlingProfileComboboxChange = false;
992 }
993 }
994 }
995
996 public class ShowComboModel extends DefaultComboBoxModel implements ActionListener {
997 private static final String ALL = "All";
998 private static final String ERRORS = "Errors";
999 private static final String POPULATED = "Populated";
1000 private static final String SUPPORTED = "Supported";
1001
1002
1003 public ShowComboModel() {
1004 addElement(POPULATED);
1005 addElement(ALL);
1006 addElement(ERRORS);
1007 addElement(SUPPORTED);
1008
1009 switch (myMessage.getEditorShowMode()) {
1010 case ALL:
1011 setSelectedItem(ALL);
1012 break;
1013 case ERROR:
1014 setSelectedItem(ERRORS);
1015 break;
1016 case POPULATED:
1017 setSelectedItem(POPULATED);
1018 break;
1019 case SUPPORTED:
1020 setSelectedItem(SUPPORTED);
1021 break;
1022 }
1023
1024 myShowCombo.addActionListener(this);
1025 }
1026
1027
1028 public void actionPerformed(ActionEvent theE) {
1029 String value = (String) myShowCombo.getSelectedItem();
1030
1031 if (value == ALL) {
1032 myTreePanel.setEditorShowModeAndUpdateAccordingly(ShowEnum.ALL);
1033 } else if (value == ERRORS) {
1034 myTreePanel.setEditorShowModeAndUpdateAccordingly(ShowEnum.ERROR);
1035 } else if (value == SUPPORTED) {
1036 myTreePanel.setEditorShowModeAndUpdateAccordingly(ShowEnum.SUPPORTED);
1037 } else {
1038 myTreePanel.setEditorShowModeAndUpdateAccordingly(ShowEnum.POPULATED);
1039 }
1040
1041 }
1042 }
1043
1044
1045 private void activateSendingActivityTabForConnection(OutboundConnection theConnection) {
1046 mySendingActivityTable.setConnection(theConnection, false);
1047 myTopTabBar.setSelectedComponent(mySendingActivityTable);
1048 }
1049
1050 public Frame getWindow() {
1051 return myController.getWindow();
1052 }
1053
1054 }