001: /*
002: * Copyright (C) 2003 Gerd Wagner
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU General Public License
006: * as published by the Free Software Foundation; either version 2
007: * of the License, or any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: */
018: package net.sourceforge.squirrel_sql.plugins.codecompletion;
019:
020: import java.awt.event.ActionEvent;
021: import java.awt.event.KeyEvent;
022:
023: import javax.swing.SwingUtilities;
024:
025: import net.sourceforge.squirrel_sql.client.IApplication;
026: import net.sourceforge.squirrel_sql.client.action.SquirrelAction;
027: import net.sourceforge.squirrel_sql.client.session.ISQLEntryPanel;
028: import net.sourceforge.squirrel_sql.client.session.ISession;
029: import net.sourceforge.squirrel_sql.fw.completion.CompletionCandidates;
030: import net.sourceforge.squirrel_sql.fw.completion.CompletionInfo;
031: import net.sourceforge.squirrel_sql.fw.completion.Completor;
032: import net.sourceforge.squirrel_sql.fw.completion.CompletorListener;
033:
034: public class CompleteCodeAction extends SquirrelAction {
035: private static final long serialVersionUID = 1L;
036: private ISQLEntryPanel _sqlEntryPanel;
037: transient private Completor _cc;
038: transient private CodeCompletorModel _model;
039:
040: public CompleteCodeAction(IApplication app,
041: CodeCompletionPlugin plugin, ISQLEntryPanel sqlEntryPanel,
042: ISession session,
043: CodeCompletionInfoCollection codeCompletionInfos) {
044: super (app, plugin.getResources());
045: _sqlEntryPanel = sqlEntryPanel;
046:
047: _model = new CodeCompletorModel(session, plugin,
048: codeCompletionInfos, sqlEntryPanel.getIdentifier());
049: _cc = new Completor(_sqlEntryPanel.getTextComponent(), _model);
050: _sqlEntryPanel
051: .addSQLTokenListener(_model.getSQLTokenListener());
052:
053: _cc.addCodeCompletorListener(new CompletorListener() {
054: public void completionSelected(CompletionInfo completion,
055: int replaceBegin, int keyCode, int modifiers) {
056: performCompletionSelected(
057: (CodeCompletionInfo) completion, replaceBegin,
058: keyCode, modifiers);
059: }
060: });
061: }
062:
063: public void actionPerformed(ActionEvent evt) {
064: _cc.show();
065: }
066:
067: private void performCompletionSelected(
068: CodeCompletionInfo completion, int replaceBegin,
069: int keyCode, int modifiers) {
070:
071: if (KeyEvent.VK_SPACE == keyCode
072: && modifiers == KeyEvent.CTRL_MASK) {
073: // Code Completion has been done within Code Completion.
074: // and relaunch completion popup.
075:
076: CompletionCandidates completionCandidates = _model
077: .getCompletionCandidates(_cc.getTextTillCarret());
078:
079: _sqlEntryPanel.setSelectionStart(replaceBegin);
080: _sqlEntryPanel.setSelectionEnd(_sqlEntryPanel
081: .getCaretPosition());
082: _sqlEntryPanel.replaceSelection(completionCandidates
083: .getAllCandidatesPrefix(false));
084:
085: SwingUtilities.invokeLater(new Runnable() {
086: public void run() {
087: _cc.show();
088: }
089: });
090: } else if (KeyEvent.VK_TAB == keyCode) {
091: _sqlEntryPanel.setSelectionStart(replaceBegin);
092: _sqlEntryPanel
093: .setSelectionEnd(getNextWhiteSpacePos(_sqlEntryPanel
094: .getCaretPosition()));
095: _sqlEntryPanel.replaceSelection(completion
096: .getCompletionString());
097: adoptCaret(completion);
098: } else {
099: _sqlEntryPanel.setSelectionStart(replaceBegin);
100: _sqlEntryPanel.setSelectionEnd(_sqlEntryPanel
101: .getCaretPosition());
102: _sqlEntryPanel.replaceSelection(completion
103: .getCompletionString());
104: adoptCaret(completion);
105: }
106:
107: }
108:
109: private void adoptCaret(CodeCompletionInfo completion) {
110: if (0 < completion.getMoveCarretBackCount()) {
111: _sqlEntryPanel.setCaretPosition(_sqlEntryPanel
112: .getCaretPosition()
113: - completion.getMoveCarretBackCount());
114: }
115: }
116:
117: private int getNextWhiteSpacePos(int startPos) {
118: String text = _sqlEntryPanel.getText();
119:
120: int retPos = startPos;
121:
122: for (; retPos < text.length(); ++retPos) {
123: if (Character.isWhitespace(text.charAt(retPos))) {
124: return retPos;
125: }
126: }
127:
128: return retPos;
129: }
130: }
|