All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.modules.properties.FindPerformer Maven / Gradle / Ivy

There is a newer version: RELEASE230
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */


package org.netbeans.modules.properties;


import java.awt.event.*;
import java.awt.Rectangle;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.ref.SoftReference;
import java.util.HashSet;
import java.util.Set;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.util.NbBundle;
import org.openide.util.WeakListeners;


/**
 * FindPerformer is a performer of the FindAction which is invoked on Resource Bundles table view component.
 * Does actual dirty job, search on the actual activated table and sets the results as highlighted text on particular cell.
 *
 * @author  Peter Zavadsky
 * @author  Marian Petras
 */
public class FindPerformer extends javax.swing.AbstractAction
                           implements PropertyChangeListener {

    /** Table on which perform the search. */
    private JTable table;
    
    /** String to find. */
    private String findString;
    
    /** Stores values which are used to start search from and store the results for next search. 
     * 1st item - row index of cell with found string,
     * 2nd item - column index of cell with found string,
     * 3rd item - start offset of found string.
     * 4th item - end offset of found string.
     */
    private int[] searchValues;

    /** Flag if it is set highliht search. */
    private boolean highlightSearch = true;
    
    /** Flag if it is set match case search. */
    private boolean matchCaseSearch = false;
    
    /** Flag if it is set forward search. */
    private boolean backwardSearch = false;
    
    /** Flag if it is set wrap search. */
    private boolean wrapSearch = true;
    
    /** Flag if it is set search by rows. */
    private boolean rowSearch = true;
    
    /** Listener for registering keystrokes to find next action. */
    private final ActionListener findNextActionListener;
    
    /** Listener for registering keystrokes to find previous action. */
    private final ActionListener findPreviousActionListener;
    
    /** Listener for registering keystrokes to toggle highlight action. */
    private final ActionListener toggleHighlightListener;
    
    /** Keeps history of found strings. */
    private Set history = new HashSet();

    /** Helper variable keeping settings. */
    private TableViewSettings settings;

    // Initializes action listener use to register for key strokes to table.
    {
        findNextActionListener = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                // Find next action invoked (default F3) -> search next occurence.
                if(searchValues != null) {
                    synchronized(this) {
                        backwardSearch = false;
                        performSearch();
                    }
                }
            }
        };
        findPreviousActionListener = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                // Find previous action invoked (default Shift-F3)-> search previous occurence.
                if(searchValues != null) {
                    synchronized(this) {
                        backwardSearch = true;
                        performSearch();
                    }
                }
            }
        };

        toggleHighlightListener = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                // Toggle highlight action invoked (defauilt Shift-Alt-H) -> toggle highlight.
                highlightSearch = !highlightSearch;
                table.repaint();
            }
        };
    } // end of initializer
    
    /** Soft reference for caching singleton find performer on last table view. */
    private static SoftReference softRef;
    
    /** Dialog for perform search. */
    private static JDialog findDialog;
    
    /** Name of client property used to store search result values. */
    public static final String TABLE_SEARCH_RESULT = "table.search.result"; // NOI18N
    
    
    /** Creates new FindPerformer. Used internally only, for getting the singleton use #getFindPerformer method. */
    private  FindPerformer(JTable table) {
        this.table = table;
        
        settings = TableViewSettings.getDefault();
        settings.addPropertyChangeListener(
            WeakListeners.propertyChange(this, settings)
        );
        
                    registerKeyStrokes();
                }
            
        
    /**
     * Listen on setting changes.
     */
    public void propertyChange(PropertyChangeEvent evt) {
        // Settings were changed reset registered key strokes.
        registerKeyStrokes();
    }
    
    /** Gets find performer. */
    public static FindPerformer getFindPerformer(JTable table) {
        if(softRef != null) {
            FindPerformer fp = softRef.get();
            if(fp != null) {
                if(!fp.validateTable(table)) {
                    fp.resetTable(table);
                    fp.registerKeyStrokes();
                }
                return fp;
            }
        }
        
        FindPerformer fp = new FindPerformer(table);
        softRef = new SoftReference(fp);
        
        return fp;
    }
    
    /** Resets the table if necessary. */
    private void resetTable(JTable table) {
        this.table = table;
    }
    
    /** Validates if the table is the same one as last opened find panel. */
    private boolean validateTable(JTable table) {
        if(this.table != null && this.table.equals(table))
            return true;
        
        return false;
    }
    
    /** Register key strokes F3 and Shift-F3 (next & previous search) to table. */
    private synchronized void registerKeyStrokes() {
        // Register key strokes to table.
        KeyStroke[] keyStrokes = settings.getKeyStrokesFindNext();
        for(int i=0; irow loop else->column loop.
        for(int i= rowSearch ? startRow : startColumn; 
                backwardSearch ?  i>=0 : i<(rowSearch ? table.getRowCount() : table.getColumnCount()); 
                i = backwardSearch ? i-1 : i+1 ) {
            // If rowSearch->column loop else->row loop.
            for(int j= rowSearch ? startColumn : startRow; 
                    backwardSearch ?  j>=0 : j<(rowSearch ? table.getColumnCount() : table.getRowCount()); 
                    j = backwardSearch ? j-1 : j+1) {
                // Set row and column indexes for this iteration.        
                int row = rowSearch ? i : j;
                int column = rowSearch ? j : i;
                
                String str = ((PropertiesTableModel.StringPair)table.getValueAt(row, column)).toString();
                // Skip to next iteration if value is null or is the string in cell is shorter than string to find.
                if(str == null || str.length() < findString.length())
                    continue;
                
                if(!firstIteration)
                    startOffset = backwardSearch ? str.length()-findString.length() : 0;
                
                int offset = containsFindString(str, startOffset);
                
                if(offset>=0) {
                    // puts client property which is then used by cell editor
                    // for setting and highlighting the find string
                    table.putClientProperty(TABLE_SEARCH_RESULT, new int[] {row, column, offset, offset+findString.length()});
                    return new int[] {row, column, offset, offset+findString.length()};
                }
                
                if(firstIteration) firstIteration = false;
            }
            
            // Next inner loop from beginning(end) for forward (backward) search.
            if(rowSearch)
                startColumn = backwardSearch ? table.getColumnCount()-1 : 0;
            else 
                startRow = backwardSearch ? table.getRowCount()-1 : 0;
        }
        
        return null;
    }
    
    /** The function search if findString occures whitin specified string.
     * @param str String which is looked if contains find string.
     * @param startOffset Offset from starts the search.
     * @return Offset on which starts find string whitin str or -1. */
    private int containsFindString(String str, int startOffset) {
        if(startOffset < 0 || startOffset >= str.length())
            return -1;
        
        for(int i=startOffset;
                backwardSearch ?  i>=0 : i<(str.length()-findString.length()+1);
                i = backwardSearch ? i-1 : i+1) {
                    
            if(findString.regionMatches(!matchCaseSearch, 0, str, i, findString.length()))
                return i;
        }
        
        return -1;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy