2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6 * The contents of this file are subject to the terms of either the GNU
7 * General Public License Version 2 only ("GPL") or the Common
8 * Development and Distribution License("CDDL") (collectively, the
9 * "License"). You may not use this file except in compliance with the
10 * License. You can obtain a copy of the License at
11 * http://www.netbeans.org/cddl-gplv2.html
12 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13 * specific language governing permissions and limitations under the
14 * License. When distributing the software, include this License Header
15 * Notice in each file and include the License file at
16 * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17 * particular file as subject to the "Classpath" exception as provided
18 * by Sun in the GPL Version 2 section of the License file that
19 * accompanied this code. If applicable, add the following below the
20 * License Header, with the fields enclosed by brackets [] replaced by
21 * your own identifying information:
22 * "Portions Copyrighted [year] [name of copyright owner]"
26 * The Original Software is NetBeans. The Initial Developer of the Original
27 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28 * Microsystems, Inc. All Rights Reserved.
29 * Portions Copyright 2008 Alexander Coles (Ikonoklastik Productions).
31 * If you wish your version of this file to be governed by only the CDDL
32 * or only the GPL Version 2, indicate your decision by adding
33 * "[Contributor] elects to include this software in this distribution
34 * under the [CDDL or GPL Version 2] license." If you do not indicate a
35 * single choice of license, a recipient has the option to distribute
36 * your version of this file under either the CDDL, the GPL Version 2 or
37 * to extend the choice of license to its licensees as provided above.
38 * However, if you add GPL Version 2 code and therefore, elected the GPL
39 * Version 2 license, then the option applies only if the new code is
40 * made subject to such option by the copyright holder.
42 package org
.netbeans
.modules
.git
.ui
.log
;
44 import java
.awt
.Dimension
;
45 import java
.awt
.event
.ActionEvent
;
46 import java
.awt
.event
.ActionListener
;
47 import java
.awt
.event
.KeyEvent
;
48 import java
.beans
.PropertyChangeEvent
;
49 import java
.beans
.PropertyChangeListener
;
51 import java
.util
.ArrayList
;
52 import java
.util
.Collection
;
53 import java
.util
.Collections
;
54 import java
.util
.HashSet
;
55 import java
.util
.List
;
57 import java
.util
.StringTokenizer
;
58 import javax
.swing
.AbstractAction
;
59 import javax
.swing
.Action
;
60 import javax
.swing
.KeyStroke
;
61 import javax
.swing
.SwingUtilities
;
62 import javax
.swing
.event
.DocumentEvent
;
63 import javax
.swing
.event
.DocumentListener
;
64 import org
.netbeans
.modules
.git
.Git
;
65 import org
.netbeans
.modules
.git
.GitException
;
66 import org
.netbeans
.modules
.git
.GitModuleConfig
;
67 import org
.netbeans
.modules
.git
.ui
.diff
.DiffSetupSource
;
68 import org
.netbeans
.modules
.git
.ui
.diff
.Setup
;
69 import org
.netbeans
.modules
.versioning
.util
.NoContentPanel
;
70 import org
.openide
.awt
.Mnemonics
;
71 import org
.openide
.explorer
.ExplorerManager
;
72 import org
.openide
.nodes
.Node
;
73 import org
.openide
.util
.NbBundle
;
74 import org
.openide
.util
.RequestProcessor
;
75 import org
.openide
.windows
.TopComponent
;
78 * Contains all components of the Search History panel.
80 * @author Maros Sandor
82 class SearchHistoryPanel
extends javax
.swing
.JPanel
implements ExplorerManager
.Provider
, PropertyChangeListener
, ActionListener
, DiffSetupSource
, DocumentListener
{
84 private final File
[] roots
;
85 private final String repositoryUrl
;
86 private final SearchCriteriaPanel criteria
;
88 private Divider divider
;
89 private Action searchAction
;
90 private SearchExecutor currentSearch
;
91 private RequestProcessor
.Task currentSearchTask
;
93 private boolean criteriaVisible
;
94 private boolean searchInProgress
;
95 private List
<RepositoryRevision
> results
;
96 private SummaryView summaryView
;
97 private DiffResultsView diffView
;
98 private boolean bOutSearch
;
99 private boolean bIncomingSearch
;
100 private AbstractAction nextAction
;
101 private AbstractAction prevAction
;
103 /** Creates new form SearchHistoryPanel */
104 public SearchHistoryPanel(File
[] roots
, SearchCriteriaPanel criteria
) {
105 this.bOutSearch
= false;
106 this.bIncomingSearch
= false;
108 this.repositoryUrl
= null;
109 this.criteria
= criteria
;
110 criteriaVisible
= true;
111 explorerManager
= new ExplorerManager ();
114 refreshComponents(true);
117 public SearchHistoryPanel(String repositoryUrl
, File localRoot
, SearchCriteriaPanel criteria
) {
118 this.bOutSearch
= false;
119 this.bIncomingSearch
= false;
120 this.repositoryUrl
= repositoryUrl
;
121 this.roots
= new File
[] { localRoot
};
122 this.criteria
= criteria
;
123 criteriaVisible
= true;
124 explorerManager
= new ExplorerManager ();
127 refreshComponents(true);
130 void setOutSearch() {
131 criteria
.setForOut();
133 divider
.setVisible(false);
134 tbSummary
.setToolTipText(NbBundle
.getMessage(SearchHistoryPanel
.class, "TT_OutSummary"));
135 showMergesChkBox
.setToolTipText(NbBundle
.getMessage(SearchHistoryPanel
.class, "TT_OutShowMerges"));
136 tbDiff
.setToolTipText(NbBundle
.getMessage(SearchHistoryPanel
.class, "TT_OutShowDiff"));
139 boolean isOutSearch() {
143 boolean isShowMerges() {
144 return showMergesChkBox
.isSelected();
148 void setIncomingSearch() {
149 criteria
.setForIncoming();
150 bIncomingSearch
= true;
151 tbDiff
.setVisible(false);
152 bNext
.setVisible(false);
153 bPrev
.setVisible(false);
154 showMergesChkBox
.setToolTipText(NbBundle
.getMessage(SearchHistoryPanel
.class, "TT_IncomingShowMerges"));
155 tbSummary
.setToolTipText(NbBundle
.getMessage(SearchHistoryPanel
.class, "TT_IncomingSummary"));
158 boolean isIncomingSearch() {
159 return bIncomingSearch
;
162 void setSearchCriteria(boolean b
) {
164 refreshComponents(false);
167 private void setupComponents() {
170 divider
= new Divider(this);
171 java
.awt
.GridBagConstraints gridBagConstraints
;
172 gridBagConstraints
= new java
.awt
.GridBagConstraints();
173 gridBagConstraints
.gridy
= 2;
174 gridBagConstraints
.gridwidth
= java
.awt
.GridBagConstraints
.REMAINDER
;
175 gridBagConstraints
.fill
= java
.awt
.GridBagConstraints
.HORIZONTAL
;
176 gridBagConstraints
.weightx
= 1.0;
177 gridBagConstraints
.insets
= new java
.awt
.Insets(2, 0, 2, 0);
178 add(divider
, gridBagConstraints
);
180 searchCriteriaPanel
.add(criteria
);
181 searchAction
= new AbstractAction(NbBundle
.getMessage(SearchHistoryPanel
.class, "CTL_Search")) { // NOI18N
183 putValue(Action
.SHORT_DESCRIPTION
, NbBundle
.getMessage(SearchHistoryPanel
.class, "TT_Search")); // NOI18N
185 public void actionPerformed(ActionEvent e
) {
189 getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
).put(KeyStroke
.getKeyStroke(KeyEvent
.VK_ENTER
, 0), "search"); // NOI18N
190 getActionMap().put("search", searchAction
); // NOI18N
191 bSearch
.setAction(searchAction
);
192 Mnemonics
.setLocalizedText(bSearch
, NbBundle
.getMessage(SearchHistoryPanel
.class, "CTL_Search")); // NOI18N
194 Dimension d1
= tbSummary
.getPreferredSize();
195 Dimension d2
= tbDiff
.getPreferredSize();
196 if (d1
.width
> d2
.width
) {
197 tbDiff
.setPreferredSize(d1
);
200 nextAction
= new AbstractAction(null, new javax
.swing
.ImageIcon(getClass().getResource("/org/netbeans/modules/mercurial/resources/icons/diff-next.png"))) { // NOI18N
202 putValue(Action
.SHORT_DESCRIPTION
, java
.util
.ResourceBundle
.getBundle("org/netbeans/modules/mercurial/ui/diff/Bundle"). // NOI18N
203 getString("CTL_DiffPanel_Next_Tooltip")); // NOI18N
205 public void actionPerformed(ActionEvent e
) {
206 diffView
.onNextButton();
209 prevAction
= new AbstractAction(null, new javax
.swing
.ImageIcon(getClass().getResource("/org/netbeans/modules/mercurial/resources/icons/diff-prev.png"))) { // NOI18N
211 putValue(Action
.SHORT_DESCRIPTION
, java
.util
.ResourceBundle
.getBundle("org/netbeans/modules/mercurial/ui/diff/Bundle"). // NOI18N
212 getString("CTL_DiffPanel_Prev_Tooltip")); // NOI18N
214 public void actionPerformed(ActionEvent e
) {
215 diffView
.onPrevButton();
218 bNext
.setAction(nextAction
);
219 bPrev
.setAction(prevAction
);
221 criteria
.tfFrom
.getDocument().addDocumentListener(this);
222 criteria
.tfTo
.getDocument().addDocumentListener(this);
224 getActionMap().put("jumpNext", nextAction
); // NOI18N
225 getActionMap().put("jumpPrev", prevAction
); // NOI18N
227 showMergesChkBox
.setSelected(GitModuleConfig
.getDefault().getShowHistoryMerges());
228 showMergesChkBox
.setOpaque(false);
231 public void actionPerformed(ActionEvent e
) {
232 if (e
.getID() == Divider
.DIVIDER_CLICKED
) {
233 criteriaVisible
= !criteriaVisible
;
234 refreshComponents(false);
238 private ExplorerManager explorerManager
;
240 public void propertyChange(PropertyChangeEvent evt
) {
241 if (ExplorerManager
.PROP_SELECTED_NODES
.equals(evt
.getPropertyName())) {
242 TopComponent tc
= (TopComponent
) SwingUtilities
.getAncestorOfClass(TopComponent
.class, this);
243 if (tc
== null) return;
244 tc
.setActivatedNodes((Node
[]) evt
.getNewValue());
248 public void addNotify() {
250 explorerManager
.addPropertyChangeListener(this);
253 public void removeNotify() {
254 explorerManager
.removePropertyChangeListener(this);
255 super.removeNotify();
258 public ExplorerManager
getExplorerManager () {
259 return explorerManager
;
262 final void refreshComponents(boolean refreshResults
) {
263 if (refreshResults
) {
264 resultsPanel
.removeAll();
265 if (results
== null) {
266 if (searchInProgress
) {
267 resultsPanel
.add(new NoContentPanel(NbBundle
.getMessage(SearchHistoryPanel
.class, "LBL_SearchHistory_Searching"))); // NOI18N
269 resultsPanel
.add(new NoContentPanel(NbBundle
.getMessage(SearchHistoryPanel
.class, "LBL_SearchHistory_NoResults"))); // NOI18N
272 if (tbSummary
.isSelected()) {
273 if (summaryView
== null) {
274 summaryView
= new SummaryView(this, results
);
276 resultsPanel
.add(summaryView
.getComponent());
278 if (diffView
== null) {
279 diffView
= new DiffResultsView(this, results
);
281 resultsPanel
.add(diffView
.getComponent());
284 resultsPanel
.revalidate();
285 resultsPanel
.repaint();
287 nextAction
.setEnabled(!tbSummary
.isSelected() && diffView
!= null && diffView
.isNextEnabled());
288 prevAction
.setEnabled(!tbSummary
.isSelected() && diffView
!= null && diffView
.isPrevEnabled());
290 divider
.setArrowDirection(criteriaVisible ? Divider
.UP
: Divider
.DOWN
);
291 searchCriteriaPanel
.setVisible(criteriaVisible
);
292 bSearch
.setVisible(criteriaVisible
);
297 public void setResults(List
<RepositoryRevision
> newResults
) {
298 setResults(newResults
, false);
301 private void setResults(List
<RepositoryRevision
> newResults
, boolean searching
) {
302 this.results
= newResults
;
303 this.searchInProgress
= searching
;
306 refreshComponents(true);
309 public String
getRepositoryUrl() {
310 return repositoryUrl
;
313 public String
getSearchRepositoryRootUrl() throws GitException
{
314 if (repositoryUrl
!= null) return repositoryUrl
;
316 File root
= Git
.getInstance().getTopmostManagedParent(roots
[0]);
317 return root
.toString();
320 public File
[] getRoots() {
324 public SearchCriteriaPanel
getCriteria() {
328 private synchronized void search() {
329 if (currentSearchTask
!= null) {
330 currentSearchTask
.cancel();
332 setResults(null, true);
333 currentSearch
= new SearchExecutor(this);
334 currentSearchTask
= RequestProcessor
.getDefault().create(currentSearch
);
335 currentSearchTask
.schedule(0);
338 void executeSearch() {
342 void showDiff(RepositoryRevision
.Event revision
) {
343 tbDiff
.setSelected(true);
344 refreshComponents(true);
345 diffView
.select(revision
);
348 public void showDiff(RepositoryRevision container
) {
349 tbDiff
.setSelected(true);
350 refreshComponents(true);
351 diffView
.select(container
);
355 * Return diff setup describing shown history.
356 * It return empty collection on non-atomic
357 * revision ranges. XXX move this logic to clients?
359 public Collection
getSetups() {
360 if (results
== null) {
361 return Collections
.EMPTY_SET
;
363 if (tbDiff
.isSelected()) {
364 return diffView
.getSetups();
366 return summaryView
.getSetups();
370 Collection
getSetups(RepositoryRevision
[] revisions
, RepositoryRevision
.Event
[] events
) {
371 long fromRevision
= Long
.MAX_VALUE
;
372 long toRevision
= Long
.MIN_VALUE
;
373 Set
<File
> filesToDiff
= new HashSet
<File
>();
375 for (RepositoryRevision revision
: revisions
) {
376 long rev
= Long
.parseLong(revision
.getLog().getRevision());
377 if (rev
> toRevision
) toRevision
= rev
;
378 if (rev
< fromRevision
) fromRevision
= rev
;
379 List
<RepositoryRevision
.Event
> evs
= revision
.getEvents();
380 for (RepositoryRevision
.Event event
: evs
) {
381 File file
= event
.getFile();
383 filesToDiff
.add(file
);
388 for (RepositoryRevision
.Event event
: events
) {
389 long rev
= Long
.parseLong(event
.getLogInfoHeader().getLog().getRevision());
390 if (rev
> toRevision
) toRevision
= rev
;
391 if (rev
< fromRevision
) fromRevision
= rev
;
392 if (event
.getFile() != null) {
393 filesToDiff
.add(event
.getFile());
397 List
<Setup
> setups
= new ArrayList
<Setup
>();
398 for (File file
: filesToDiff
) {
399 Setup setup
= new Setup(file
, Long
.toString(fromRevision
- 1), Long
.toString(toRevision
));
405 public String
getSetupDisplayName() {
409 public static int compareRevisions(String r1
, String r2
) {
410 StringTokenizer st1
= new StringTokenizer(r1
, "."); // NOI18N
411 StringTokenizer st2
= new StringTokenizer(r2
, "."); // NOI18N
413 if (!st1
.hasMoreTokens()) {
414 return st2
.hasMoreTokens() ?
-1 : 0;
416 if (!st2
.hasMoreTokens()) {
417 return st1
.hasMoreTokens() ?
1 : 0;
419 int n1
= Integer
.parseInt(st1
.nextToken());
420 int n2
= Integer
.parseInt(st2
.nextToken());
421 if (n1
!= n2
) return n2
- n1
;
425 /** This method is called from within the constructor to
426 * initialize the form.
427 * WARNING: Do NOT modify this code. The content of this method is
428 * always regenerated by the Form Editor.
430 // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
431 private void initComponents() {
432 java
.awt
.GridBagConstraints gridBagConstraints
;
434 buttonGroup1
= new javax
.swing
.ButtonGroup();
435 searchCriteriaPanel
= new javax
.swing
.JPanel();
436 bSearch
= new javax
.swing
.JButton();
437 jPanel1
= new javax
.swing
.JPanel();
438 jToolBar1
= new javax
.swing
.JToolBar();
439 tbSummary
= new javax
.swing
.JToggleButton();
440 tbDiff
= new javax
.swing
.JToggleButton();
441 jSeparator2
= new javax
.swing
.JSeparator();
442 bNext
= new javax
.swing
.JButton();
443 bPrev
= new javax
.swing
.JButton();
444 jSeparator3
= new javax
.swing
.JToolBar
.Separator();
445 showMergesChkBox
= new javax
.swing
.JCheckBox();
446 resultsPanel
= new javax
.swing
.JPanel();
448 setBorder(javax
.swing
.BorderFactory
.createEmptyBorder(8, 8, 0, 8));
449 setLayout(new java
.awt
.GridBagLayout());
451 searchCriteriaPanel
.setLayout(new java
.awt
.BorderLayout());
452 gridBagConstraints
= new java
.awt
.GridBagConstraints();
453 gridBagConstraints
.gridx
= 0;
454 gridBagConstraints
.gridy
= 0;
455 gridBagConstraints
.gridwidth
= java
.awt
.GridBagConstraints
.REMAINDER
;
456 gridBagConstraints
.fill
= java
.awt
.GridBagConstraints
.BOTH
;
457 gridBagConstraints
.anchor
= java
.awt
.GridBagConstraints
.FIRST_LINE_START
;
458 gridBagConstraints
.weightx
= 1.0;
459 add(searchCriteriaPanel
, gridBagConstraints
);
461 java
.util
.ResourceBundle bundle
= java
.util
.ResourceBundle
.getBundle("org/netbeans/modules/mercurial/ui/log/Bundle"); // NOI18N
462 bSearch
.setToolTipText(bundle
.getString("TT_Search")); // NOI18N
463 gridBagConstraints
= new java
.awt
.GridBagConstraints();
464 gridBagConstraints
.gridx
= 0;
465 gridBagConstraints
.gridy
= 1;
466 gridBagConstraints
.anchor
= java
.awt
.GridBagConstraints
.LINE_START
;
467 add(bSearch
, gridBagConstraints
);
469 jPanel1
.setPreferredSize(new java
.awt
.Dimension(10, 6));
470 gridBagConstraints
= new java
.awt
.GridBagConstraints();
471 gridBagConstraints
.gridy
= 2;
472 gridBagConstraints
.gridwidth
= java
.awt
.GridBagConstraints
.REMAINDER
;
473 gridBagConstraints
.fill
= java
.awt
.GridBagConstraints
.HORIZONTAL
;
474 gridBagConstraints
.weightx
= 1.0;
475 gridBagConstraints
.insets
= new java
.awt
.Insets(0, 0, 2, 0);
476 add(jPanel1
, gridBagConstraints
);
478 jToolBar1
.setFloatable(false);
479 jToolBar1
.setRollover(true);
481 buttonGroup1
.add(tbSummary
);
482 tbSummary
.setSelected(true);
483 org
.openide
.awt
.Mnemonics
.setLocalizedText(tbSummary
, bundle
.getString("CTL_ShowSummary")); // NOI18N
484 tbSummary
.setToolTipText(bundle
.getString("TT_Summary")); // NOI18N
485 tbSummary
.addActionListener(new java
.awt
.event
.ActionListener() {
486 public void actionPerformed(java
.awt
.event
.ActionEvent evt
) {
490 jToolBar1
.add(tbSummary
);
491 tbSummary
.getAccessibleContext().setAccessibleName(org
.openide
.util
.NbBundle
.getMessage(SearchHistoryPanel
.class, "CTL_ShowSummary")); // NOI18N
493 buttonGroup1
.add(tbDiff
);
494 org
.openide
.awt
.Mnemonics
.setLocalizedText(tbDiff
, bundle
.getString("CTL_ShowDiff")); // NOI18N
495 tbDiff
.setToolTipText(bundle
.getString("TT_ShowDiff")); // NOI18N
496 tbDiff
.addActionListener(new java
.awt
.event
.ActionListener() {
497 public void actionPerformed(java
.awt
.event
.ActionEvent evt
) {
501 jToolBar1
.add(tbDiff
);
503 jSeparator2
.setOrientation(javax
.swing
.SwingConstants
.VERTICAL
);
504 jSeparator2
.setMaximumSize(new java
.awt
.Dimension(2, 32767));
505 jToolBar1
.add(jSeparator2
);
506 jToolBar1
.add(bNext
);
507 bNext
.getAccessibleContext().setAccessibleName("null");
508 bNext
.getAccessibleContext().setAccessibleDescription("null");
510 jToolBar1
.add(bPrev
);
511 bPrev
.getAccessibleContext().setAccessibleName("null");
512 bPrev
.getAccessibleContext().setAccessibleDescription("null");
514 jToolBar1
.add(jSeparator3
);
516 showMergesChkBox
.setSelected(true);
517 org
.openide
.awt
.Mnemonics
.setLocalizedText(showMergesChkBox
, org
.openide
.util
.NbBundle
.getMessage(SearchHistoryPanel
.class, "CTL_ShowMerge")); // NOI18N
518 showMergesChkBox
.setToolTipText(org
.openide
.util
.NbBundle
.getMessage(SearchHistoryPanel
.class, "TT_ShowMerges")); // NOI18N
519 showMergesChkBox
.setFocusable(false);
520 showMergesChkBox
.setHorizontalTextPosition(javax
.swing
.SwingConstants
.RIGHT
);
521 showMergesChkBox
.setVerticalTextPosition(javax
.swing
.SwingConstants
.BOTTOM
);
522 showMergesChkBox
.addChangeListener(new javax
.swing
.event
.ChangeListener() {
523 public void stateChanged(javax
.swing
.event
.ChangeEvent evt
) {
524 showMergesChkBoxStateChanged(evt
);
527 jToolBar1
.add(showMergesChkBox
);
529 gridBagConstraints
= new java
.awt
.GridBagConstraints();
530 gridBagConstraints
.gridy
= 3;
531 gridBagConstraints
.gridwidth
= java
.awt
.GridBagConstraints
.REMAINDER
;
532 gridBagConstraints
.fill
= java
.awt
.GridBagConstraints
.HORIZONTAL
;
533 add(jToolBar1
, gridBagConstraints
);
535 resultsPanel
.setLayout(new java
.awt
.BorderLayout());
536 gridBagConstraints
= new java
.awt
.GridBagConstraints();
537 gridBagConstraints
.gridx
= 0;
538 gridBagConstraints
.gridy
= 4;
539 gridBagConstraints
.gridwidth
= java
.awt
.GridBagConstraints
.REMAINDER
;
540 gridBagConstraints
.gridheight
= java
.awt
.GridBagConstraints
.REMAINDER
;
541 gridBagConstraints
.fill
= java
.awt
.GridBagConstraints
.BOTH
;
542 gridBagConstraints
.weightx
= 1.0;
543 gridBagConstraints
.weighty
= 1.0;
544 gridBagConstraints
.insets
= new java
.awt
.Insets(8, 0, 8, 0);
545 add(resultsPanel
, gridBagConstraints
);
546 }// </editor-fold>//GEN-END:initComponents
548 private void onViewToggle(java
.awt
.event
.ActionEvent evt
) {//GEN-FIRST:event_onViewToggle
549 refreshComponents(true);
550 }//GEN-LAST:event_onViewToggle
552 private void showMergesChkBoxStateChanged(javax
.swing
.event
.ChangeEvent evt
) {//GEN-FIRST:event_showMergesChkBoxStateChanged
553 GitModuleConfig
.getDefault().setShowHistoryMerges( showMergesChkBox
.isSelected());
554 }//GEN-LAST:event_showMergesChkBoxStateChanged
556 public void insertUpdate(DocumentEvent e
) {
560 public void removeUpdate(DocumentEvent e
) {
564 public void changedUpdate(DocumentEvent e
) {
568 private void validateUserInput() {
569 String from
= criteria
.getFrom();
570 if(from
== null && criteria
.tfFrom
.getText().trim().length() > 0) {
571 bSearch
.setEnabled(false);
574 String to
= criteria
.getTo();
575 if(to
== null && criteria
.tfTo
.getText().trim().length() > 0) {
576 bSearch
.setEnabled(false);
579 bSearch
.setEnabled(true);
582 // Variables declaration - do not modify//GEN-BEGIN:variables
583 private javax
.swing
.JButton bNext
;
584 private javax
.swing
.JButton bPrev
;
585 private javax
.swing
.JButton bSearch
;
586 private javax
.swing
.ButtonGroup buttonGroup1
;
587 private javax
.swing
.JPanel jPanel1
;
588 private javax
.swing
.JSeparator jSeparator2
;
589 private javax
.swing
.JToolBar
.Separator jSeparator3
;
590 private javax
.swing
.JToolBar jToolBar1
;
591 private javax
.swing
.JPanel resultsPanel
;
592 private javax
.swing
.JPanel searchCriteriaPanel
;
593 private javax
.swing
.JCheckBox showMergesChkBox
;
594 private javax
.swing
.JToggleButton tbDiff
;
595 private javax
.swing
.JToggleButton tbSummary
;
596 // End of variables declaration//GEN-END:variables