Skip to content

Commit 83970d3

Browse files
committed
Add recent filters list to channel browser
Signed-off-by: Mitch Gaffigan <mitch.gaffigan@comcast.net>
1 parent c648448 commit 83970d3

4 files changed

Lines changed: 312 additions & 4 deletions

File tree

client/src/com/mirth/connect/client/ui/browsers/message/MessageBrowser.java

Lines changed: 118 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ public void actionPerformed(ActionEvent e) {
236236

237237
advancedSearchPopup = createMessageBrowserAdvancedFilter();
238238
advancedSearchPopup.setVisible(false);
239+
recentFiltersButton.setEnabled(false);
239240

240241
LineBorder lineBorder = new LineBorder(new Color(0, 0, 0));
241242
TitledBorder titledBorder = new TitledBorder("Current Search");
@@ -331,6 +332,7 @@ public void loadChannel(MessageBrowserChannelModel channelModel) {
331332

332333
this.channelId = channelId;
333334
this.channelName = channelName;
335+
updateRecentFiltersButton();
334336
this.connectors = connectors;
335337
this.connectors.put(null, "Deleted Connectors");
336338
initMetaDataColumns(channelModel);
@@ -452,6 +454,101 @@ public void updateAdvancedSearchButtonFont() {
452454
}
453455
}
454456

457+
private void updateRecentFiltersButton() {
458+
recentFiltersButton.setEnabled(getRecentFilterStore().hasRecentFilters());
459+
}
460+
461+
private MessageBrowserRecentFilterStore getRecentFilterStore() {
462+
return new MessageBrowserRecentFilterStore(channelId);
463+
}
464+
465+
private void saveCurrentFilterToMru() {
466+
if (StringUtils.isBlank(channelId) || messageFilter == null || messageFilter.isEmpty()) {
467+
return;
468+
}
469+
470+
getRecentFilterStore().addRecentFilter(messageFilter);
471+
updateRecentFiltersButton();
472+
}
473+
474+
private void restoreRecentFilter() {
475+
List<MessageFilter> filters = getRecentFilterStore().loadRecentFilters();
476+
477+
if (filters.isEmpty()) {
478+
parent.alertInformation(this, "No recent message browser filters were found for this channel.");
479+
return;
480+
}
481+
482+
String[] options = new String[filters.size()];
483+
for (int i = 0; i < filters.size(); i++) {
484+
options[i] = (i + 1) + ". " + filters.get(i).toString(connectors, "\n", false);
485+
}
486+
487+
Object selection = JOptionPane.showInputDialog(this, "Select a recent filter to restore:", "Recent Filters", JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
488+
if (selection instanceof String) {
489+
int selectedIndex = Arrays.asList(options).indexOf(selection);
490+
if (selectedIndex >= 0) {
491+
applyMessageFilter(filters.get(selectedIndex));
492+
}
493+
}
494+
}
495+
496+
private void applyMessageFilter(MessageFilter filter) {
497+
resetSearchCriteria();
498+
499+
boolean allDay = inferAllDay(filter);
500+
501+
mirthDatePicker1.setDate((filter.getStartDate() == null) ? null : filter.getStartDate().getTime());
502+
mirthDatePicker2.setDate((filter.getEndDate() == null) ? null : filter.getEndDate().getTime());
503+
allDayCheckBox.setSelected(allDay);
504+
mirthTimePicker1.setEnabled(mirthDatePicker1.getDate() != null && !allDay);
505+
mirthTimePicker2.setEnabled(mirthDatePicker2.getDate() != null && !allDay);
506+
507+
if (filter.getStartDate() != null) {
508+
mirthTimePicker1.setDate(new SimpleDateFormat("HH:mm").format(filter.getStartDate().getTime()));
509+
}
510+
if (filter.getEndDate() != null && !allDay) {
511+
mirthTimePicker2.setDate(new SimpleDateFormat("HH:mm").format(filter.getEndDate().getTime()));
512+
}
513+
514+
textSearchField.setText(StringUtils.defaultString(filter.getTextSearch()));
515+
regexTextSearchCheckBox.setSelected(Boolean.TRUE.equals(filter.getTextSearchRegex()));
516+
517+
Set<Status> statuses = filter.getStatuses();
518+
statusBoxReceived.setSelected(statuses != null && statuses.contains(Status.RECEIVED));
519+
statusBoxTransformed.setSelected(statuses != null && statuses.contains(Status.TRANSFORMED));
520+
statusBoxFiltered.setSelected(statuses != null && statuses.contains(Status.FILTERED));
521+
statusBoxQueued.setSelected(statuses != null && statuses.contains(Status.QUEUED));
522+
statusBoxPending.setSelected(statuses != null && statuses.contains(Status.PENDING));
523+
statusBoxSent.setSelected(statuses != null && statuses.contains(Status.SENT));
524+
statusBoxError.setSelected(statuses != null && statuses.contains(Status.ERROR));
525+
526+
advancedSearchPopup.applyFilter(filter);
527+
updateAdvancedSearchButtonFont();
528+
updateFilterButtonFont(Font.BOLD);
529+
}
530+
531+
private boolean inferAllDay(MessageFilter filter) {
532+
if (filter == null) {
533+
return false;
534+
}
535+
536+
Calendar endDate = filter.getEndDate();
537+
if (endDate != null) {
538+
return endDate.get(Calendar.HOUR_OF_DAY) == 23
539+
&& endDate.get(Calendar.MINUTE) == 59
540+
&& endDate.get(Calendar.SECOND) == 59
541+
&& endDate.get(Calendar.MILLISECOND) == 999;
542+
}
543+
544+
Calendar startDate = filter.getStartDate();
545+
return startDate != null
546+
&& startDate.get(Calendar.HOUR_OF_DAY) == 0
547+
&& startDate.get(Calendar.MINUTE) == 0
548+
&& startDate.get(Calendar.SECOND) == 0
549+
&& startDate.get(Calendar.MILLISECOND) == 0;
550+
}
551+
455552
public String getChannelId() {
456553
return channelId;
457554
}
@@ -654,6 +751,8 @@ protected boolean generateMessageFilter() {
654751
advancedSearchPopup.applySelectionsToFilter(messageFilter);
655752
selectedMetaDataIds = messageFilter.getIncludedMetaDataIds();
656753

754+
saveCurrentFilterToMru();
755+
657756
if (messageFilter.getMaxMessageId() == null) {
658757
try {
659758
Long maxMessageId = parent.mirthClient.getMaxMessageId(channelId);
@@ -2648,6 +2747,14 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
26482747
}
26492748
});
26502749

2750+
recentFiltersButton = new javax.swing.JButton();
2751+
recentFiltersButton.setText("Recent...");
2752+
recentFiltersButton.addActionListener(new java.awt.event.ActionListener() {
2753+
public void actionPerformed(java.awt.event.ActionEvent evt) {
2754+
recentFiltersButtonActionPerformed(evt);
2755+
}
2756+
});
2757+
26512758
statusBoxFiltered.setBackground(new java.awt.Color(255, 255, 255));
26522759
statusBoxFiltered.setText("FILTERED");
26532760
statusBoxFiltered.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N
@@ -2761,7 +2868,7 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
27612868
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
27622869
.addComponent(advSearchButton, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE)
27632870
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
2764-
.addComponent(resetButton, javax.swing.GroupLayout.PREFERRED_SIZE, 56, javax.swing.GroupLayout.PREFERRED_SIZE))
2871+
.addComponent(resetButton, javax.swing.GroupLayout.PREFERRED_SIZE, 56, javax.swing.GroupLayout.PREFERRED_SIZE))
27652872
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
27662873
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
27672874
.addComponent(mirthDatePicker1, javax.swing.GroupLayout.PREFERRED_SIZE, 1, Short.MAX_VALUE)
@@ -2775,8 +2882,9 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
27752882
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
27762883
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
27772884
.addComponent(allDayCheckBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
2778-
.addComponent(filterButton, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE)
2779-
.addComponent(regexTextSearchCheckBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
2885+
.addComponent(recentFiltersButton, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE)
2886+
.addComponent(regexTextSearchCheckBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
2887+
.addComponent(filterButton, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE))
27802888
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
27812889
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
27822890
.addComponent(statusBoxQueued, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
@@ -2830,7 +2938,8 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
28302938
.addComponent(mirthTimePicker2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
28312939
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
28322940
.addComponent(mirthDatePicker2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
2833-
.addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
2941+
.addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
2942+
.addComponent(recentFiltersButton))
28342943
.addGap(7, 7, 7)
28352944
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
28362945
.addComponent(textSearchField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
@@ -2922,6 +3031,10 @@ private void filterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
29223031
runSearch();
29233032
}//GEN-LAST:event_filterButtonActionPerformed
29243033

3034+
private void recentFiltersButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_recentFiltersButtonActionPerformed
3035+
restoreRecentFilter();
3036+
}//GEN-LAST:event_recentFiltersButtonActionPerformed
3037+
29253038
private void countButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_countButtonActionPerformed
29263039
final String workingId = parent.startWorking("Counting search result size...");
29273040
filterButton.setEnabled(false);
@@ -3110,6 +3223,7 @@ private void textSearchFieldActionPerformed(java.awt.event.ActionEvent evt) {//G
31103223
private javax.swing.JLabel processedResponseLabel;
31113224
private javax.swing.JLabel processedResponseStatusLabel;
31123225
private com.mirth.connect.client.ui.components.MirthSyntaxTextArea processedResponseStatusTextArea;
3226+
private javax.swing.JButton recentFiltersButton;
31133227
private com.mirth.connect.client.ui.components.MirthCheckBox regexTextSearchCheckBox;
31143228
private javax.swing.JButton resetButton;
31153229
private javax.swing.JLabel responseLabel;

client/src/com/mirth/connect/client/ui/browsers/message/MessageBrowserAdvancedFilter.java

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,81 @@ public Boolean hasAdvancedCriteria() {
510510
return hasAdvancedCriteria;
511511
}
512512

513+
public void applyFilter(MessageFilter messageFilter) {
514+
stopEditing();
515+
resetSelections();
516+
517+
if (messageFilter == null) {
518+
return;
519+
}
520+
521+
ItemSelectionTableModel<Integer, String> connectorModel = ((ItemSelectionTableModel<Integer, String>) connectorTable.getModel());
522+
DefaultTableModel contentSearchModel = ((DefaultTableModel) contentSearchTable.getModel());
523+
DefaultTableModel metaDataSearchModel = ((DefaultTableModel) metaDataSearchTable.getModel());
524+
525+
List<Integer> includedMetaDataIds = messageFilter.getIncludedMetaDataIds();
526+
List<Integer> excludedMetaDataIds = messageFilter.getExcludedMetaDataIds();
527+
528+
if (includedMetaDataIds != null) {
529+
connectorModel.unselectAllKeys();
530+
for (Integer metaDataId : includedMetaDataIds) {
531+
connectorModel.selectKey(metaDataId);
532+
}
533+
} else if (excludedMetaDataIds != null) {
534+
connectorModel.selectAllKeys();
535+
for (int row = 0; row < connectorModel.getRowCount(); row++) {
536+
Integer metaDataId = (Integer) connectorModel.getValueAt(row, ItemSelectionTableModel.KEY_COLUMN);
537+
if (excludedMetaDataIds.contains(metaDataId)) {
538+
connectorModel.setValueAt(Boolean.FALSE, row, ItemSelectionTableModel.CHECKBOX_COLUMN);
539+
}
540+
}
541+
}
542+
543+
messageIdLowerField.setText((messageFilter.getMinMessageId() == null) ? "" : String.valueOf(messageFilter.getMinMessageId()));
544+
messageIdUpperField.setText((messageFilter.getMaxMessageId() == null) ? "" : String.valueOf(messageFilter.getMaxMessageId()));
545+
originalIdLowerField.setText((messageFilter.getOriginalIdLower() == null) ? "" : String.valueOf(messageFilter.getOriginalIdLower()));
546+
originalIdUpperField.setText((messageFilter.getOriginalIdUpper() == null) ? "" : String.valueOf(messageFilter.getOriginalIdUpper()));
547+
importIdLowerField.setText((messageFilter.getImportIdLower() == null) ? "" : String.valueOf(messageFilter.getImportIdLower()));
548+
importIdUpperField.setText((messageFilter.getImportIdUpper() == null) ? "" : String.valueOf(messageFilter.getImportIdUpper()));
549+
serverIdField.setText(StringUtils.defaultString(messageFilter.getServerId()));
550+
sendAttemptsLower.setValue((messageFilter.getSendAttemptsLower() == null) ? 0 : messageFilter.getSendAttemptsLower());
551+
sendAttemptsUpper.setValue((messageFilter.getSendAttemptsUpper() == null) ? "" : String.valueOf(messageFilter.getSendAttemptsUpper()));
552+
attachmentCheckBox.setSelected(Boolean.TRUE.equals(messageFilter.getAttachment()));
553+
errorCheckBox.setSelected(Boolean.TRUE.equals(messageFilter.getError()));
554+
555+
if (messageFilter.getContentSearch() != null) {
556+
for (ContentSearchElement contentSearchElement : messageFilter.getContentSearch()) {
557+
for (String search : contentSearchElement.getSearches()) {
558+
contentSearchModel.addRow(new Object[] { ContentType.fromCode(contentSearchElement.getContentCode()), search });
559+
}
560+
}
561+
}
562+
563+
if (messageFilter.getMetaDataSearch() != null) {
564+
for (MetaDataSearchElement metaDataSearchElement : messageFilter.getMetaDataSearch()) {
565+
if (cachedMetaDataColumns.containsKey(metaDataSearchElement.getColumnName())) {
566+
metaDataSearchModel.addRow(new Object[] {
567+
metaDataSearchElement.getColumnName(),
568+
MetaDataSearchOperator.fromString(metaDataSearchElement.getOperator()),
569+
formatMetaDataValue(metaDataSearchElement.getValue()),
570+
Boolean.TRUE.equals(metaDataSearchElement.getIgnoreCase()) });
571+
}
572+
}
573+
}
574+
}
575+
576+
private String formatMetaDataValue(Object value) {
577+
if (value == null) {
578+
return "";
579+
}
580+
581+
if (value instanceof java.util.Calendar) {
582+
return new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(((java.util.Calendar) value).getTime());
583+
}
584+
585+
return String.valueOf(value);
586+
}
587+
513588
private void stopEditing() {
514589
// if the user had typed in a value in the content search table, close the cell editor so that any value that was entered will be included in the search
515590
TableCellEditor cellEditor = contentSearchTable.getCellEditor();
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright (c) Mirth Corporation. All rights reserved.
3+
*
4+
* http://www.mirthcorp.com
5+
*
6+
* The software in this package is published under the terms of the MPL license a copy of which has
7+
* been included with this distribution in the LICENSE.txt file.
8+
*/
9+
10+
package com.mirth.connect.client.ui.browsers.message;
11+
12+
import java.util.ArrayList;
13+
import java.util.List;
14+
import java.util.prefs.Preferences;
15+
16+
import org.apache.commons.lang3.StringUtils;
17+
18+
import com.mirth.connect.client.ui.Mirth;
19+
import com.mirth.connect.model.converters.ObjectXMLSerializer;
20+
import com.mirth.connect.model.filters.MessageFilter;
21+
22+
class MessageBrowserRecentFilterStore {
23+
private static final int MAX_RECENT_FILTERS = 10;
24+
private static final String RECENT_FILTERS_PREFERENCE_PREFIX = "messageBrowserRecentFilters.";
25+
26+
private final String channelId;
27+
28+
public MessageBrowserRecentFilterStore(String channelId) {
29+
this.channelId = channelId;
30+
}
31+
32+
public boolean hasRecentFilters() {
33+
return !loadRecentFilters().isEmpty();
34+
}
35+
36+
public List<MessageFilter> loadRecentFilters() {
37+
List<MessageFilter> filters = new ArrayList<MessageFilter>();
38+
39+
if (StringUtils.isBlank(channelId)) {
40+
return filters;
41+
}
42+
43+
try {
44+
String serialized = Preferences.userNodeForPackage(Mirth.class).get(getRecentFiltersPreferenceKey(), "");
45+
if (StringUtils.isNotBlank(serialized)) {
46+
List<?> deserializedFilters = (List<?>) ObjectXMLSerializer.getInstance().deserialize(serialized, List.class);
47+
48+
for (Object deserializedFilter : deserializedFilters) {
49+
if (deserializedFilter instanceof MessageFilter) {
50+
filters.add((MessageFilter) deserializedFilter);
51+
}
52+
}
53+
}
54+
} catch (Exception e) {
55+
e.printStackTrace();
56+
Preferences.userNodeForPackage(Mirth.class).remove(getRecentFiltersPreferenceKey());
57+
}
58+
59+
return filters;
60+
}
61+
62+
public void saveRecentFilters(List<MessageFilter> filters) {
63+
if (StringUtils.isBlank(channelId)) {
64+
return;
65+
}
66+
67+
Preferences preferences = Preferences.userNodeForPackage(Mirth.class);
68+
69+
try {
70+
if (filters.isEmpty()) {
71+
preferences.remove(getRecentFiltersPreferenceKey());
72+
} else {
73+
preferences.put(getRecentFiltersPreferenceKey(), ObjectXMLSerializer.getInstance().serialize(filters));
74+
}
75+
} catch (Exception e) {
76+
e.printStackTrace();
77+
}
78+
}
79+
80+
public void addRecentFilter(MessageFilter filter) {
81+
if (StringUtils.isBlank(channelId) || filter == null) {
82+
return;
83+
}
84+
85+
List<MessageFilter> filters = loadRecentFilters();
86+
filters.add(0, filter);
87+
88+
if (filters.size() > MAX_RECENT_FILTERS) {
89+
filters = new ArrayList<MessageFilter>(filters.subList(0, MAX_RECENT_FILTERS));
90+
}
91+
92+
saveRecentFilters(filters);
93+
}
94+
95+
private String getRecentFiltersPreferenceKey() {
96+
return RECENT_FILTERS_PREFERENCE_PREFIX + channelId;
97+
}
98+
}

0 commit comments

Comments
 (0)