com.application.areca.launcher.gui.composites.SearchComposite.java Source code

Java tutorial

Introduction

Here is the source code for com.application.areca.launcher.gui.composites.SearchComposite.java

Source

package com.application.areca.launcher.gui.composites;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

import com.application.areca.AbstractTarget;
import com.application.areca.ResourceManager;
import com.application.areca.TargetGroup;
import com.application.areca.WorkspaceItem;
import com.application.areca.launcher.gui.Application;
import com.application.areca.launcher.gui.common.AbstractWindow;
import com.application.areca.launcher.gui.common.ArecaImages;
import com.application.areca.launcher.gui.common.Refreshable;
import com.application.areca.launcher.gui.common.SecuredRunner;
import com.application.areca.search.DefaultSearchCriteria;
import com.application.areca.search.SearchResult;
import com.application.areca.search.SearchResultItem;
import com.application.areca.search.TargetSearchResult;
import com.myJava.util.log.Logger;
import com.myJava.util.taskmonitor.TaskCancelledException;
import com.myJava.util.taskmonitor.TaskMonitor;

/**
 * <BR>
 * @author Olivier PETRUCCI
 * <BR>
 *
 */

/*
Copyright 2005-2011, Olivier PETRUCCI.
    
This file is part of Areca.
    
Areca is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
    
Areca is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with Areca; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    
*/
public class SearchComposite extends AbstractTabComposite implements MouseListener, Listener, Refreshable {

    protected final ResourceManager RM = ResourceManager.instance();
    private final Application application = Application.getInstance();

    private Composite pnlTargets;
    private Composite pnlButtons;
    private Tree tree;

    protected Text txtPattern;
    protected Button chkLatest;
    protected Button chkCase;
    protected Button chkRegex;
    protected Button btnSearch;
    protected Button btnCancel;
    protected Button btnSelectAll;
    protected Button btnClear;
    protected Label lblLog;

    protected boolean select = true;

    protected ArrayList targets = new ArrayList();
    protected ArrayList checkBoxes = new ArrayList();

    protected TaskMonitor mon;

    public SearchComposite(Composite parent) {
        super(parent, SWT.NONE);
        GridLayout layout = new GridLayout(1, false);
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        setLayout(layout);

        Composite top = buildTopComposite(this);
        top.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

        Composite bottom = buildBottomComposite(this);
        bottom.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    }

    private Composite buildTopComposite(Composite parent) {
        Composite panel = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 3;
        layout.horizontalSpacing = 30;
        panel.setLayout(layout);

        Label lblPattern = new Label(panel, SWT.NONE);
        lblPattern.setText(RM.getLabel("search.criteria.pattern"));

        GridData dtPattern = new GridData();
        dtPattern.grabExcessHorizontalSpace = true;
        dtPattern.horizontalAlignment = SWT.FILL;
        txtPattern = new Text(panel, SWT.BORDER);
        txtPattern.setLayoutData(dtPattern);

        chkLatest = new Button(panel, SWT.CHECK);
        chkLatest.setSelection(true);
        chkLatest.setText(RM.getLabel("search.criteria.latest"));

        GridData dtTargets = new GridData();
        dtTargets.verticalSpan = 3;
        dtTargets.verticalAlignment = SWT.TOP;
        Label lblTargets = new Label(panel, SWT.NONE);
        lblTargets.setText(RM.getLabel("search.targets.label"));
        lblTargets.setLayoutData(dtTargets);

        GridData dtTargetsContent = new GridData(SWT.FILL, SWT.TOP, true, false);
        dtTargetsContent.verticalSpan = 3;
        dtTargetsContent.heightHint = 100;

        ScrolledComposite scr = new ScrolledComposite(panel, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
        scr.setLayout(new FillLayout());
        scr.setLayoutData(dtTargetsContent);

        pnlTargets = new Composite(scr, SWT.NONE);
        GridLayout tgLayout = new GridLayout(1, false);
        tgLayout.verticalSpacing = 0;
        pnlTargets.setLayout(tgLayout);
        scr.setContent(pnlTargets);

        chkCase = new Button(panel, SWT.CHECK);
        chkCase.setText(RM.getLabel("search.criteria.case"));

        chkRegex = new Button(panel, SWT.CHECK);
        chkRegex.setText(RM.getLabel("search.criteria.regex"));

        pnlButtons = new Composite(panel, SWT.NONE);
        GridLayout ly = new GridLayout(3, false);
        ly.marginHeight = 0;
        ly.marginWidth = 0;
        pnlButtons.setLayout(ly);
        pnlButtons.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

        btnSelectAll = new Button(pnlButtons, SWT.PUSH);
        btnSelectAll.setLayoutData(new GridData(SWT.RIGHT, SWT.BOTTOM, true, true));
        btnSelectAll.setText(RM.getLabel("search.selectall.label"));
        btnSelectAll.addListener(SWT.Selection, this);

        btnSearch = new Button(pnlButtons, SWT.PUSH);
        btnSearch.setLayoutData(new GridData(SWT.RIGHT, SWT.BOTTOM, false, true));
        btnSearch.setText(RM.getLabel("search.search.label"));
        btnSearch.addListener(SWT.Selection, this);

        btnCancel = new Button(pnlButtons, SWT.PUSH);
        btnCancel.setLayoutData(new GridData(SWT.RIGHT, SWT.BOTTOM, false, true));
        btnCancel.setText(RM.getLabel("search.cancel.label"));
        btnCancel.addListener(SWT.Selection, this);
        btnCancel.setEnabled(false);

        return panel;
    }

    private Composite buildBottomComposite(Composite parent) {
        Composite panel = new Composite(parent, SWT.NONE);
        panel.setLayout(new GridLayout(2, false));

        TreeViewer tv = new TreeViewer(panel, SWT.BORDER);
        tree = tv.getTree();
        tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
        tree.setLinesVisible(AbstractWindow.getTableLinesVisible());
        tree.addMouseListener(this);

        lblLog = new Label(panel, SWT.NONE);
        lblLog.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

        btnClear = new Button(panel, SWT.PUSH);
        btnClear.setLayoutData(new GridData(SWT.RIGHT, SWT.BOTTOM, false, false));
        btnClear.setText(RM.getLabel("search.clearall.label"));
        btnClear.addListener(SWT.Selection, this);

        return panel;
    }

    private void log(final String s) {
        Logger.defaultLogger().info(s);
        SecuredRunner.execute(new Runnable() {
            public void run() {
                lblLog.setText(s);
            }
        });
    }

    private String format(String s, int nb) {
        String ret = "" + nb + s;
        if (nb != 1) {
            ret += "s";
        }
        return ret;
    }

    private boolean haveTargetsChanged() {
        Iterator existingTgs = this.targets.iterator();
        Map map = new HashMap(this.targets.size());
        while (existingTgs.hasNext()) {
            AbstractTarget target = (AbstractTarget) existingTgs.next();
            map.put(target.getUid(), target);
        }

        if (checkChanged(application.getWorkspace().getContent(), map)) {
            return true;
        }
        return (map.size() != 0);
    }

    private boolean checkChanged(TargetGroup group, Map ref) {
        Iterator iter = group.getIterator();
        while (iter.hasNext()) {
            WorkspaceItem item = (WorkspaceItem) iter.next();
            if (item instanceof AbstractTarget) {
                AbstractTarget target = (AbstractTarget) item;
                AbstractTarget exist = (AbstractTarget) ref.remove(target.getUid());
                if (exist == null || !(exist.getName().equals(target.getName()))) {
                    return true;
                }
            } else {
                if (checkChanged((TargetGroup) item, ref)) {
                    return true;
                }
            }
        }
        return false;
    }

    private void selectAll() {
        if (select) {
            btnSelectAll.setText(RM.getLabel("search.deselectall.label"));
        } else {
            btnSelectAll.setText(RM.getLabel("search.selectall.label"));
        }

        Iterator iter = this.checkBoxes.iterator();
        while (iter.hasNext()) {
            Button btn = (Button) iter.next();
            btn.setSelection(select);
        }

        select = !select;
        pnlButtons.layout();
    }

    private void clearAll() {
        refreshContent(null);
    }

    private void buildTargetList() {
        // REMOVE EXISTING
        Iterator chkIter = this.checkBoxes.iterator();
        while (chkIter.hasNext()) {
            Button btn = (Button) chkIter.next();
            btn.dispose();
        }
        this.checkBoxes.clear();
        this.targets.clear();
        pnlTargets.pack();

        // ADD TGS
        addItems(application.getWorkspace().getContent());
        pnlTargets.setSize(pnlTargets.computeSize(SWT.DEFAULT, SWT.DEFAULT));
    }

    private void addItems(TargetGroup group) {
        Iterator iter = group.getSortedIterator();
        while (iter.hasNext()) {
            WorkspaceItem item = (WorkspaceItem) iter.next();
            if (item instanceof AbstractTarget) {
                AbstractTarget target = (AbstractTarget) item;
                this.targets.add(target);
                Button chk = new Button(pnlTargets, SWT.CHECK);
                chk.setText(target.getParent().getFullPath(" / ") + " / " + target.getName());
                this.checkBoxes.add(chk);
            } else {
                addItems((TargetGroup) item);
            }
        }
    }

    public void refresh() {
        // Refresh targets if needed
        if (haveTargetsChanged()) {
            buildTargetList();
        }

        // pre-check checkBoxes
        Iterator chkIter = this.checkBoxes.iterator();
        Iterator tgIter = this.targets.iterator();
        while (chkIter.hasNext()) {
            Button chk = (Button) chkIter.next();
            AbstractTarget target = (AbstractTarget) tgIter.next();
            chk.setSelection((this.application.isCurrentObjectTarget()
                    && this.application.getCurrentTarget().getUid().equals(target.getUid()))
                    || (this.application.isCurrentObjectTargetGroup()
                            && target.isChildOf(this.application.getCurrentTargetGroup())));
        }
    }

    public Object getRefreshableKey() {
        return this.getClass().getName();
    }

    public void handleEvent(Event event) {

        if (event.widget.equals(this.btnSearch)) {
            if (this.txtPattern.getText().trim().length() != 0) {
                clearAll();

                final SearchResult result = new SearchResult();
                mon = new TaskMonitor("Search");

                final DefaultSearchCriteria criteria = new DefaultSearchCriteria();
                criteria.setPattern(txtPattern.getText());
                criteria.setRestrictLatestArchive(this.chkLatest.getSelection());
                criteria.setMatchCase(chkCase.getSelection());
                criteria.setRegularExpression(chkRegex.getSelection());
                criteria.setMonitor(mon);

                final ArrayList selected = new ArrayList();
                for (int i = 0; i < targets.size(); i++) {
                    Button chk = (Button) checkBoxes.get(i);
                    if (chk.getSelection()) {
                        selected.add(targets.get(i));
                    }
                }

                Runnable rn = new Runnable() {
                    public void run() {
                        SecuredRunner.execute(new Runnable() {
                            public void run() {
                                application.enableWaitCursor();
                                btnClear.setEnabled(false);
                                btnSearch.setEnabled(false);
                                btnSelectAll.setEnabled(false);
                                btnCancel.setEnabled(true);
                            }
                        });

                        try {
                            for (int i = 0; i < selected.size(); i++) {
                                mon.checkTaskState();
                                AbstractTarget target = (AbstractTarget) selected.get(i);
                                log("Searching \"" + criteria.getPattern() + "\" in \"" + target.getName()
                                        + "\" ...");
                                TargetSearchResult targetResult = target.search(criteria);
                                if (!targetResult.isEmpty()) {
                                    result.setTargetSearchResult(target, targetResult);
                                }
                            }

                            log("Search completed - Initializing view ...");

                            SecuredRunner.execute(new Runnable() {
                                public void run() {
                                    refreshContent(result);
                                }
                            });

                            int nb = result.resultCount();
                            if (nb == 0) {
                                log("Search completed - No result found");
                            } else {
                                log("Search completed - " + format(" result", nb) + " found in "
                                        + format(" target", result.size()) + ".");
                            }
                        } catch (final TaskCancelledException e) {
                            log("Search cancelled.");
                        } catch (final Throwable e) {
                            SecuredRunner.execute(new Runnable() {
                                public void run() {
                                    application.handleException(e);
                                }
                            });
                        } finally {
                            SecuredRunner.execute(new Runnable() {
                                public void run() {
                                    application.disableWaitCursor();
                                    btnClear.setEnabled(true);
                                    btnSearch.setEnabled(true);
                                    btnSelectAll.setEnabled(true);
                                    btnCancel.setEnabled(false);
                                }
                            });
                        }
                    }
                };

                Thread searchThread = new Thread(rn);
                searchThread.setName("Search \"" + criteria.getPattern() + "\"");
                searchThread.start();
            }
        } else if (event.widget.equals(this.btnClear)) {
            log("");
            clearAll();
        } else if (event.widget.equals(this.btnCancel)) {
            if (mon != null) {
                mon.setCancelRequested();
            }
        } else {
            selectAll();
        }
    }

    private void refreshContent(SearchResult result) {
        tree.removeAll();

        if (result != null) {
            Iterator iter = result.targetIterator();
            while (iter.hasNext()) {
                AbstractTarget target = (AbstractTarget) iter.next();
                TargetSearchResult tResult = result.getTargetSearchResult(target);

                TreeItem targetNode = new TreeItem(tree, SWT.NONE);
                targetNode.setText(target.getName() + " (" + tResult.getItems().size() + ")");
                targetNode.setData(target);
                targetNode.setImage(ArecaImages.ICO_REF_TARGET);

                Iterator items = tResult.getItems().iterator();
                while (items.hasNext()) {
                    SearchResultItem searchItem = (SearchResultItem) items.next();
                    TreeItem item = new TreeItem(targetNode, SWT.NONE);
                    item.setData(searchItem);
                    item.setText(searchItem.getEntry().getKey());
                    item.setImage(ArecaImages.ICO_FS_FILE);
                }
            }

            if (result.size() == 0) {
                TreeItem noresult = new TreeItem(tree, SWT.NONE);
                noresult.setText(RM.getLabel("search.noresult.label"));
            }

            if (result.size() == 1) {
                tree.getItem(0).setExpanded(true);
            }
        }
    }

    public void mouseDoubleClick(MouseEvent e) {
    }

    public void mouseUp(MouseEvent e) {
    }

    public void mouseDown(MouseEvent e) {
        TreeItem item = this.tree.getItem(new Point(e.x, e.y));
        if (item != null && item.getParentItem() != null) {
            showMenu(e, Application.getInstance().getSearchContextMenu());
        }
    }

    private void showMenu(MouseEvent e, Menu m) {
        if (e.button == 3) {
            m.setVisible(true);
        }
    }

    public SearchResultItem getSelectedItem() {
        TreeItem[] selection = tree.getSelection();
        if (selection != null && selection.length != 0 && selection[0].getData() instanceof SearchResultItem) {
            return (SearchResultItem) selection[0].getData();
        } else {
            return null;
        }
    }
}