001: package tide.editor;
002:
003: import tide.project.*;
004: import snow.sortabletable.*;
005: import snow.utils.gui.*;
006: import javax.swing.*;
007: import javax.swing.event.*;
008: import java.awt.BorderLayout;
009: import java.awt.event.*;
010: import java.awt.Insets;
011: import javax.swing.border.*;
012: import java.util.*;
013: import java.io.*;
014: import java.util.concurrent.*;
015:
016: /** To see and edit the auto replacements.
017: */
018: public class AutoReplaceManagementDialog extends JDialog {
019: private final ReplacementsTM tm = new ReplacementsTM();
020: private final SortableTableModel stm = new SortableTableModel(tm);
021: private final JTable table = new JTable(stm);
022: private final JTextArea replArea = new JTextArea();
023:
024: public AutoReplaceManagementDialog() {
025: super (MainEditorFrame.instance, "AutoReplace management", true);
026: this .setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
027:
028: JSplitPane csp = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
029: new JScrollPane(table), new JScrollPane(replArea));
030: add(csp, BorderLayout.CENTER);
031: csp.setDividerLocation(200);
032:
033: stm.installGUI(table);
034: table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
035: table.addMouseListener(new MouseAdapter() {
036: @Override
037: public void mousePressed(MouseEvent me) {
038: if (me.isPopupTrigger())
039: showPopup(me);
040: }
041:
042: @Override
043: public void mouseReleased(MouseEvent me) {
044: if (me.isPopupTrigger())
045: showPopup(me);
046: }
047:
048: private void showPopup(MouseEvent me) {
049: JPopupMenu popup = new JPopupMenu();
050: JMenuItem remove = new JMenuItem("Remove",
051: Icons.sharedCross);
052: popup.add(remove);
053: remove.addActionListener(new ActionListener() {
054: public void actionPerformed(ActionEvent ae) {
055: List<Integer> rem = new ArrayList<Integer>();
056: for (int sel : table.getSelectedRows()) {
057: int ind = stm
058: .getIndexInUnsortedFromTablePos(sel);
059: if (ind >= 0) {
060: rem.add(ind);
061: }
062: }
063: tm.remove(rem);
064: }
065: });
066:
067: popup.show(table, me.getX(), me.getY());
068: }
069:
070: });
071:
072: table.getSelectionModel().addListSelectionListener(
073: new ListSelectionListener() {
074: public void valueChanged(ListSelectionEvent lse) {
075: if (actualDisplayed != null) {
076: actualDisplayed.setReplacement(replArea
077: .getText());
078: // TODO: caret pos
079: }
080:
081: int ind = stm
082: .getIndexInUnsortedFromTablePos(table
083: .getSelectedRow());
084: if (ind >= 0) {
085: actualDisplayed = tm.getReplAt(ind);
086: } else {
087: actualDisplayed = null;
088: }
089:
090: if (actualDisplayed != null) {
091: replArea.setText(actualDisplayed
092: .getReplacement());
093: replArea
094: .setCaretPosition(actualDisplayed
095: .getReplacement().length()
096: - actualDisplayed.rewindAfterReplace);
097: } else {
098: replArea.setText("");
099: }
100: }
101: });
102:
103: AdvancedSearchPanel asp = new AdvancedSearchPanel("", null,
104: stm, false);
105: add(asp, BorderLayout.NORTH);
106:
107: JButton newRepl = new JButton("New entry", Icons.sharedPlus);
108: newRepl.setMargin(new Insets(0, 2, 0, 2));
109: asp.add(Box.createHorizontalStrut(10));
110: asp.add(newRepl);
111: newRepl.addActionListener(new ActionListener() {
112: public void actionPerformed(ActionEvent ae) {
113: tm.createNew();
114: }
115: });
116:
117: JButton resetDef = new JButton("Reset to defaults",
118: Icons.sharedCross);
119: resetDef.setMargin(new Insets(0, 2, 0, 2));
120: asp.add(Box.createHorizontalStrut(10));
121: asp.add(resetDef);
122: resetDef.addActionListener(new ActionListener() {
123: public void actionPerformed(ActionEvent ae) {
124: UserAutoReplacements.getInstance().createDefaults();
125: tm.refresh();
126: }
127: });
128:
129: add(new CloseControlPanel(this , false, true, "close"),
130: BorderLayout.SOUTH);
131:
132: pack();
133: this .setLocationRelativeTo(MainEditorFrame.instance);
134: setVisible(true);
135:
136: // save actual edited
137: if (actualDisplayed != null) {
138: actualDisplayed.setReplacement(replArea.getText());
139: }
140: } // Constructor
141:
142: public static void main(String[] arguments) {
143: //System.out.println(detectCollisions(Arrays.asList("aa", "b", ")));
144: }
145:
146: /** @return null if none, human readable description otherwise.
147: */
148: public static String detectCollisions(List<String> shortcuts) {
149: for (int i = 0; i < shortcuts.size(); i++) {
150: String si = shortcuts.get(i);
151: for (int j = 0; j < i; j++) {
152:
153: String sj = shortcuts.get(j);
154:
155: if (si.contains(sj) || sj.contains(si))
156: return si + " collides with " + sj;
157:
158: }
159: }
160: return null;
161: }
162:
163: private static List<String> getKeys(
164: Collection<UserAutoReplacements.AutoReplacement> ure) {
165: List<String> ke = new ArrayList<String>();
166: for (UserAutoReplacements.AutoReplacement re : ure) {
167: ke.add(re.shortcut);
168: }
169: return ke;
170: }
171:
172: private UserAutoReplacements.AutoReplacement actualDisplayed = null;
173:
174: class ReplacementsTM extends FineGrainTableModel {
175: final List<UserAutoReplacements.AutoReplacement> replacements = new ArrayList<UserAutoReplacements.AutoReplacement>();
176:
177: public ReplacementsTM() {
178: refresh();
179: }
180:
181: private void refresh() {
182: replacements.clear();
183: replacements
184: .addAll(UserAutoReplacements.getInstance().replacements
185: .values());
186: this .fireTableDataChanged();
187: this .fireTableModelHasChanged();
188:
189: }
190:
191: @Override
192: public String getColumnName(int col) {
193: if (col == 0)
194: return "Shortcut";
195: if (col == 1)
196: return "Replacement";
197: if (col == 2)
198: return "Rewind";
199: return "?";
200: }
201:
202: public int getColumnCount() {
203: return 3;
204: }
205:
206: public int getRowCount() {
207: return replacements.size();
208: }
209:
210: public Object getValueAt(int row, int col) {
211: UserAutoReplacements.AutoReplacement bm = replacements
212: .get(row);
213: if (col == 0)
214: return bm.shortcut;
215: if (col == 1)
216: return bm.getReplacement();
217: if (col == 2)
218: return new Integer(bm.rewindAfterReplace);
219: return "?";
220: }
221:
222: @Override
223: public int getPreferredColumnWidth(int col) {
224: if (col == 0)
225: return 5;
226: if (col == 2)
227: return 5;
228: return -1;
229: }
230:
231: public UserAutoReplacements.AutoReplacement getReplAt(int row) {
232: UserAutoReplacements.AutoReplacement bm = replacements
233: .get(row);
234: return bm;
235: }
236:
237: @Override
238: public void setValueAt(Object o, int row, int col) {
239: UserAutoReplacements.AutoReplacement bm = replacements
240: .get(row);
241: if (col == 0) {
242: List<String> ke = getKeys(UserAutoReplacements
243: .getInstance().replacements.values());
244:
245: // remove the old (the first)
246: ke.remove("" + getValueAt(row, col));
247:
248: ke.add("" + o);
249: String co = detectCollisions(ke);
250: if (co != null) {
251: JOptionPane.showMessageDialog(null, "Bad key " + o
252: + ":\n\n" + co, "Error",
253: JOptionPane.ERROR_MESSAGE);
254: return;
255: }
256:
257: UserAutoReplacements.getInstance().replacements
258: .remove(bm.shortcut);
259: bm.shortcut = "" + o;
260: UserAutoReplacements.getInstance().replacements.put(
261: bm.shortcut, bm);
262: }
263:
264: if (col == 2) {
265: bm.rewindAfterReplace = Integer.parseInt("" + o);
266: }
267: }
268:
269: @Override
270: public boolean isCellEditable(int row, int col) {
271: return col != 1;
272: }
273:
274: public void remove(List<Integer> ind) {
275: this .fireTableModelWillChange();
276: Collections.sort(ind);
277: for (int i = ind.size() - 1; i >= 0; i--) // start with greatest index !!
278: {
279: UserAutoReplacements.getInstance().replacements
280: .remove(replacements.get(ind.get(i)).shortcut);
281: }
282: refresh();
283: this .fireTableDataChanged();
284: this .fireTableModelHasChanged();
285: }
286:
287: public void createNew() {
288: this.fireTableModelWillChange();
289:
290: replacements.add(UserAutoReplacements.getInstance()
291: .addNew());
292:
293: this.fireTableDataChanged();
294: this.fireTableModelHasChanged();
295: }
296: }
297: }
|