Subversion Repositories public

Rev

Rev 85 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
85 luk 1
/*
2
 * ICPropDialog.java - incron table rule properties dialog
3
 *
4
 * Copyright (c) 2006 Lukas Jelinek, http://www.aiken.cz
5
 *
6
 * ==========================================================================
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License Version 2 as
10
 * published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 *
21
 * ==========================================================================
22
 */
23
 
24
package cz.aiken.util.jincron;
25
 
26
import java.awt.*;
27
import java.awt.event.*;
28
import javax.swing.*;
29
import javax.swing.event.*;
30
import javax.swing.text.*;
31
import java.io.*;
32
import java.util.*;
33
 
34
/**
35
 *
36
 * @author luk
37
 */
38
public class ICPropDialog extends JDialog implements ActionListener, UndoableEditListener {
39
 
40
    private static final String title = "Rule properties";
41
 
42
    private boolean changed = false;
43
    private boolean commit = false;
44
 
45
    private JTextField path = new JTextField();
46
    private JButton pathBut = new JButton("Browse...");
47
    private JPanel events = new JPanel();
48
    private JPanel cmd = new JPanel();
49
    private JTextField cmdText = new JTextField();
50
 
51
    private InotifyEvent evt = null;
52
    private HashMap<Integer, JCheckBox> mask = new HashMap<Integer, JCheckBox>();
53
    private HashMap<Integer, JCheckBox> flags = new HashMap<Integer, JCheckBox>();
54
 
55
    /** Creates a new instance of ICPropDialog */
56
    public ICPropDialog(ICRow row) {
57
        super();
58
        init(row);
59
    }
60
 
61
    protected void init(ICRow row) {
62
        Container c = getContentPane();
63
        c.setLayout(null);
64
        setSize(480, 470);
65
        setLocation(200, 200);
66
        setModal(true);
67
        setResizable(false);
68
        updateTitle();
69
 
70
        JLabel lab = new JLabel("Path");
71
        lab.setSize(55, 20);
72
        lab.setLocation(20, 20);
73
        c.add(lab);
74
 
75
        path.setSize(280, 20);
76
        path.setLocation(60, 20);
77
        path.setText(row.getPath());
78
        path.getDocument().addUndoableEditListener(this);
79
        path.setToolTipText("Specify the path to be watched");
80
        c.add(path);
81
 
82
        pathBut.setSize(100, 20);
83
        pathBut.setLocation(350, 20);
84
        pathBut.setActionCommand("path");
85
        pathBut.addActionListener(this);
86
        pathBut.setToolTipText("Browse the filesystem for a watch path");
87
        c.add(pathBut);
88
 
89
 
90
        evt = new InotifyEvent(row.getEvent());
91
 
92
        events.setSize(435, 200);
93
        events.setLocation(20, 50);
94
        events.setLayout(null);
95
        events.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Events"));
96
        c.add(events);
97
 
98
        createCheckbox("all events", 130, 20, 20, 20, "IN_ALL_EVENTS", "Watch all events", events, mask, InotifyEvent.IN_ALL_EVENTS);
99
 
100
        createCheckbox("access", 130, 20, 20, 45, "IN_ACCESS", "Watch accesses to file(s)", events, mask, InotifyEvent.IN_ACCESS);
101
        createCheckbox("modify", 130, 20, 20, 70, "IN_MODIFY", "Watch file(s) modifications", events, mask, InotifyEvent.IN_MODIFY);
102
        createCheckbox("attr. change", 130, 20, 20, 95, "IN_ATTRIB", "Watch attribute (metadata) changes", events, mask, InotifyEvent.IN_ATTRIB);
103
        createCheckbox("close", 130, 20, 20, 120, "IN_CLOSE", "Watch close events", events, mask, InotifyEvent.IN_CLOSE);
104
        createCheckbox("close (write)", 130, 20, 20, 145, "IN_CLOSE_WRITE", "Watch close events with writing", events, mask, InotifyEvent.IN_CLOSE_WRITE);
105
        createCheckbox("close (no write)", 130, 20, 20, 170, "IN_CLOSE_NOWRITE", "Watch close events without writing", events, mask, InotifyEvent.IN_CLOSE_NOWRITE);
106
 
107
        createCheckbox("open", 130, 20, 160, 45, "IN_OPEN", "Watch open events", events, mask, InotifyEvent.IN_OPEN);
108
        createCheckbox("move", 130, 20, 160, 70, "IN_MOVE", "Watch file moves", events, mask, InotifyEvent.IN_MOVE);
109
        createCheckbox("moved from", 130, 20, 160, 95, "IN_MOVED_FROM", "Watch events on file(s) moved out", events, mask, InotifyEvent.IN_MOVED_FROM);
110
        createCheckbox("moved to", 130, 20, 160, 120, "IN_MOVED_TO", "Watch events on file(s) moved in", events, mask, InotifyEvent.IN_MOVED_TO);
111
        createCheckbox("create", 130, 20, 160, 145, "IN_CREATE", "Watch creations", events, mask, InotifyEvent.IN_CREATE);
112
        createCheckbox("delete", 130, 20, 160, 170, "IN_DELETE", "Watch deletions (unlinks)", events, mask, InotifyEvent.IN_DELETE);
113
 
114
        createCheckbox("delete self", 130, 20, 300, 45, "IN_DELETE_SELF", "Watch the watched path is destroyed", events, mask, InotifyEvent.IN_DELETE_SELF);
115
        createCheckbox("dir only", 130, 20, 300, 70, "IN_ONLYDIR", "Watch only directory events", events, mask, InotifyEvent.IN_ONLYDIR);
116
        createCheckbox("don't follow", 130, 20, 300, 95, "IN_DONT_FOLLOW", "Don't follow symbolic links", events, mask, InotifyEvent.IN_DONT_FOLLOW);
117
        createCheckbox("oneshot", 130, 20, 300, 120, "IN_ONESHOT", "Watch exactly one event", events, mask, InotifyEvent.IN_ONESHOT);
118
        createCheckbox("no loop", 130, 20, 300, 170, "IN_NO_LOOP", "Avoid looping", events, flags, InotifyEvent.IN_NO_LOOP);
119
 
120
        updateCheckboxes();
121
 
122
        cmd.setSize(435, 130);
123
        cmd.setLocation(20, 260);
124
        cmd.setLayout(null);
125
        cmd.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Command"));
126
        c.add(cmd);
127
 
128
        cmdText.setSize(390, 20);
129
        cmdText.setLocation(20, 30);
130
        cmdText.setText(row.getCommand());
131
        cmdText.getDocument().addUndoableEditListener(this);
132
        cmdText.setToolTipText("Specify a command here");
133
        cmd.add(cmdText);
134
 
135
        JButton but = new JButton("Watch path");
136
        but.setSize(190, 20);
137
        but.setLocation(20, 60);
138
        but.setActionCommand("watch_path");
139
        but.addActionListener(this);
140
        but.setToolTipText("Insert a symbol for watch path");
141
        cmd.add(but);
142
 
143
        but = new JButton("Event name");
144
        but.setSize(190, 20);
145
        but.setLocation(220, 60);
146
        but.setActionCommand("event_name");
147
        but.addActionListener(this);
148
        but.setToolTipText("Insert a symbol for watch name");
149
        cmd.add(but);
150
 
151
        but = new JButton("Mask (symbolic)");
152
        but.setSize(190, 20);
153
        but.setLocation(20, 90);
154
        but.setActionCommand("symbolic_mask");
155
        but.addActionListener(this);
156
        but.setToolTipText("Insert a symbol for symbolic event mask");
157
        cmd.add(but);
158
 
159
        but = new JButton("Mask (numeric)");
160
        but.setSize(190, 20);
161
        but.setLocation(220, 90);
162
        but.setActionCommand("numeric_mask");
163
        but.addActionListener(this);
164
        but.setToolTipText("Insert a symbol for numeric event mask");
165
        cmd.add(but);
166
 
167
 
168
        but = new JButton("OK");
169
        but.setSize(80, 20);
170
        but.setLocation(150, 400);
171
        but.setActionCommand("ok");
172
        but.addActionListener(this);
173
        but.setToolTipText("Apply changes if any");
174
        c.add(but);
175
 
176
        but = new JButton("Cancel");
177
        but.setSize(80, 20);
178
        but.setLocation(240, 400);
179
        but.setActionCommand("cancel");
180
        but.addActionListener(this);
181
        but.setToolTipText("Leave the dialog without applying changes");
182
        c.add(but);
183
    }
184
 
185
    protected void createCheckbox(String text, int width, int height, int x, int y, String cmd, String tooltip, Container c, HashMap<Integer, JCheckBox> map, int mapVal) {
186
        JCheckBox cb = new JCheckBox(text);
187
        cb.setLocation(x, y);
188
        cb.setSize(width, height);
189
        cb.addActionListener(this);
190
        cb.setActionCommand(cmd);
191
        cb.setToolTipText(tooltip);
192
        c.add(cb);
193
        map.put(new Integer(mapVal), cb);
194
    }
195
 
196
    protected void browsePath() {
197
        JFileChooser fc = new JFileChooser();
198
        fc.setDialogTitle("Watch path");
199
        fc.setDialogType(JFileChooser.OPEN_DIALOG);
200
        fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
201
        fc.setMultiSelectionEnabled(false);
202
        fc.setSelectedFile(new File(path.getText()));
203
 
204
        int res = fc.showDialog(this, "Select");
205
        if (res == JFileChooser.APPROVE_OPTION) {
206
            path.setText(fc.getSelectedFile().getAbsolutePath());
207
        }
208
    }
209
 
210
    protected void addCmdText(String txt) {
211
        String s = cmdText.getText();
212
 
213
        int start = cmdText.getSelectionStart();
214
        int end = cmdText.getSelectionEnd();
215
        if (start != -1 || end != -1) {
216
            cmdText.setText(s.substring(0, start) + txt + s.substring(end));
217
            cmdText.setCaretPosition(start + txt.length());
218
        }
219
        else {
220
            int pos = cmdText.getCaretPosition();
221
            if (pos != -1) {
222
                cmdText.setText(s.substring(0, pos) + txt + s.substring(pos));
223
                cmdText.setCaretPosition(pos + txt.length());
224
            }
225
            else {
226
                cmdText.setText(s + txt);
227
                cmdText.setCaretPosition(s.length() + txt.length());
228
            }
229
        }
230
 
231
        cmdText.requestFocusInWindow();
232
    }
233
 
234
    protected void updateTitle() {
235
        if (changed)
236
            setTitle(title + " (modified)");
237
        else
238
            setTitle(title);
239
    }
240
 
241
    protected void updateCheckboxes() {
242
        Iterator<Integer> it = mask.keySet().iterator();
243
        while (it.hasNext()) {
244
            Integer i = it.next();
245
            JCheckBox cb = mask.get(i);
246
            if (cb != null) {
247
                cb.getModel().setSelected(evt.hasMask(i.intValue()));
248
            }
249
        }
250
 
251
        it = flags.keySet().iterator();
252
        while (it.hasNext()) {
253
            Integer i = it.next();
254
            JCheckBox cb = flags.get(i);
255
            if (cb != null) {
256
                cb.getModel().setSelected(evt.hasFlags(i.intValue()));
257
            }
258
        }
259
    }
260
 
261
    protected void modifyEvent(int val, boolean fl) {
262
        if (fl) {
263
            JCheckBox cb = flags.get(val);
264
            if (cb != null) {
265
                evt.changeFlags(val, cb.getModel().isSelected());
266
            }
267
        }
268
        else {
269
            JCheckBox cb = mask.get(val);
270
            if (cb != null) {
271
                evt.changeMask(val, cb.getModel().isSelected());
272
            }
273
        }
274
 
275
        updateCheckboxes();
276
 
277
        changed = true;
278
        updateTitle();
279
    }
280
 
281
    public ICRow getData() {
282
        return new ICRow(path.getText(), evt, cmdText.getText());
283
    }
284
 
285
    public boolean isModified() {
286
        return changed;
287
    }
288
 
289
    public boolean isCommitted() {
290
        return commit;
291
    }
292
 
293
    protected boolean validateData() {
294
        if (path.getText().length() == 0) {
295
            JOptionPane.showMessageDialog(this, "The watch path must not be empty.", "Error", JOptionPane.ERROR_MESSAGE);
296
            return false;
297
        }
298
 
299
        if (!(new File(path.getText())).exists()) {
300
            JOptionPane.showMessageDialog(this, "The watch path does not exist.\nThis is not an error but incrond will ignore such rules.", "Warning", JOptionPane.WARNING_MESSAGE);
301
        }
302
 
303
        if (evt.getMask() == 0) {
304
            JOptionPane.showMessageDialog(this, "At least one event type must be watched.", "Error", JOptionPane.ERROR_MESSAGE);
305
            return false;
306
        }
307
 
308
        if (cmdText.getText().length() == 0) {
309
            JOptionPane.showMessageDialog(this, "The command must not be empty.", "Error", JOptionPane.ERROR_MESSAGE);
310
            return false;
311
        }
312
 
313
        return true;
314
    }
315
 
316
    public void actionPerformed(ActionEvent e) {
317
        String s = e.getActionCommand();
318
 
319
        if (s.equals("path")) {
320
            browsePath();
321
        }
322
        else if (s.equals("watch_path")) {
323
            addCmdText("$@");
324
        }
325
        else if (s.equals("event_name")) {
326
            addCmdText("$#");
327
        }
328
        else if (s.equals("symbolic_mask")) {
329
            addCmdText("$%");
330
        }
331
        else if (s.equals("numeric_mask")) {
332
            addCmdText("$&");
333
        }
334
        else if (s.equals("ok")) {
335
            if (validateData()) {
336
                commit = true;
337
                setVisible(false);
338
            }
339
        }
340
        else if (s.equals("cancel")) {
341
            setVisible(false);
342
        }
343
        else {
344
            int i = InotifyEvent.getMaskByName(s);
345
            if (i != 0) {
346
                modifyEvent(i, false);
347
                return;
348
            }
349
 
350
            i = InotifyEvent.getFlagsByName(s);
351
            if (i != 0) {
352
                modifyEvent(i, true);
353
            }
354
        }
355
    }
356
 
357
    public void undoableEditHappened(UndoableEditEvent e) {
358
        changed = true;
359
        updateTitle();
360
    }      
361
}