/*
Copyright 2003-2012 Dmitry Barashev, GanttProject Team
This file is part of GanttProject, an opensource project management tool.
GanttProject 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 3 of the License, or
(at your option) any later version.
GanttProject 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 GanttProject. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sourceforge.ganttproject.search;
import java.awt.Color;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collections;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import net.sourceforge.ganttproject.IGanttProject;
import net.sourceforge.ganttproject.gui.UIFacade;
import net.sourceforge.ganttproject.language.GanttLanguage;
import net.sourceforge.ganttproject.language.GanttLanguage.Event;
import net.sourceforge.ganttproject.search.SearchDialog.SearchCallback;
public class SearchUiImpl implements SearchUi {
private final IGanttProject project;
private final UIFacade uiFacade;
private JTextField searchBox;
private Color myInitialForeground;
public SearchUiImpl(IGanttProject project, UIFacade uiFacade) {
this.project = project;
this.uiFacade = uiFacade;
PopupSearchCallback callback = new PopupSearchCallback();
searchBox = new JTextField(30);
myInitialForeground = searchBox.getForeground();
searchBox.setForeground(Color.GRAY);
final GanttLanguage i18n = GanttLanguage.getInstance();
i18n.addListener(new GanttLanguage.Listener() {
@Override
public void languageChanged(Event event) {
searchBox.setText(i18n.formatText("search.prompt.pattern", i18n.getText("search.dialog.search"),
i18n.getText("search.prompt.shortcut")));
}
});
callback.setSearchBox(searchBox);
}
@Override
public void requestFocus() {
searchBox.requestFocusInWindow();
}
public JTextField getSearchField() {
return searchBox;
}
class PopupSearchCallback implements SearchCallback {
private SearchDialog myDialog = new SearchDialog(project, uiFacade);
private JTextField searchBox;
private JList list = new JList();
private Runnable onSelect;
private Runnable onDismiss;
public PopupSearchCallback() {
list.setBorder(BorderFactory.createEmptyBorder());
list.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_ENTER:
e.consume();
e.setKeyCode(0);
onSelect.run();
break;
case KeyEvent.VK_ESCAPE:
onDismiss.run();
break;
}
}
});
list.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
onSelect.run();
}
});
}
@Override
public void accept(final List<SearchResult<?>> results) {
if (results.isEmpty()) {
return;
}
list.setListData(results.toArray(new SearchResult[0]));
JScrollPane scrollPane = new JScrollPane(list);
scrollPane.setBorder(BorderFactory.createEmptyBorder());
final JPopupMenu popup = new JPopupMenu();
popup.add(scrollPane);
popup.show(searchBox, 0, searchBox.getHeight());
list.requestFocusInWindow();
list.setSelectedIndex(0);
onSelect = new Runnable() {
@Override
public void run() {
onSelect(popup, results);
}
};
onDismiss = new Runnable() {
@Override
public void run() {
popup.setVisible(false);
searchBox.requestFocusInWindow();
}
};
}
private void onSelect(JPopupMenu popup, List<SearchResult<?>> results) {
popup.setVisible(false);
SearchResult selectedValue = results.get(list.getSelectedIndex());
selectedValue.getSearchService().select(Collections.singletonList(selectedValue));
}
void setSearchBox(JTextField searchBox) {
this.searchBox = searchBox;
searchBox.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER && PopupSearchCallback.this.searchBox.isFocusOwner()) {
runSearch();
}
}
});
this.searchBox.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
PopupSearchCallback.this.searchBox.selectAll();
PopupSearchCallback.this.searchBox.setForeground(myInitialForeground);
}
});
}
void dismissPopup() {
}
protected void runSearch() {
myDialog.runSearch(searchBox.getText(), this);
}
}
}