001: /*
002: * Copyright (c) 2001, Jacob Smullyan.
003: *
004: * This is part of SkunkDAV, a WebDAV client. See http://skunkdav.sourceforge.net/
005: * for the latest version.
006: *
007: * SkunkDAV is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License as published
009: * by the Free Software Foundation; either version 2, or (at your option)
010: * any later version.
011: *
012: * SkunkDAV is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with SkunkDAV; see the file COPYING. If not, write to the Free
019: * Software Foundation, 59 Temple Place - Suite 330, Boston, MA
020: * 02111-1307, USA.
021: */
022:
023: package org.skunk.dav.client.gui;
024:
025: import java.awt.GridBagConstraints;
026: import java.awt.GridBagLayout;
027: import java.awt.Insets;
028: import java.awt.event.ActionEvent;
029: import java.awt.event.ActionListener;
030: import java.awt.event.ItemEvent;
031: import java.awt.event.ItemListener;
032: import java.util.ArrayList;
033: import java.util.Enumeration;
034: import java.util.Iterator;
035: import java.util.Vector;
036: import javax.swing.BorderFactory;
037: import javax.swing.Box;
038: import javax.swing.DefaultListModel;
039: import javax.swing.JButton;
040: import javax.swing.JCheckBox;
041: import javax.swing.JComboBox;
042: import javax.swing.JComponent;
043: import javax.swing.JLabel;
044: import javax.swing.JList;
045: import javax.swing.JOptionPane;
046: import javax.swing.JPanel;
047: import javax.swing.JPasswordField;
048: import javax.swing.JScrollPane;
049: import javax.swing.JTextField;
050: import javax.swing.ListSelectionModel;
051: import javax.swing.SwingConstants;
052: import javax.swing.border.TitledBorder;
053: import javax.swing.event.ChangeEvent;
054: import javax.swing.event.ChangeListener;
055: import javax.swing.event.DocumentEvent;
056: import javax.swing.event.DocumentListener;
057: import javax.swing.event.ListSelectionEvent;
058: import javax.swing.event.ListSelectionListener;
059: import javax.swing.text.BadLocationException;
060: import javax.swing.text.Document;
061: import org.skunk.config.Configurator;
062: import org.skunk.dav.client.DAVConnection;
063: import org.skunk.dav.client.DAVConnectionPool;
064: import org.skunk.dav.client.DAVConstants;
065: import org.skunk.swing.text.EntryDocument;
066: import org.skunk.swing.text.PositiveIntegerEntryFilter;
067: import org.skunk.trace.Debug;
068:
069: /**
070: * a customizer for network properties. Was previously called GeneralCustomizer.
071: * now also includes server customization: host, port, etc.
072: * @author $Author: smulloni $
073: * @version $Revision: 1.5 $
074: */
075: public class NetworkCustomizer extends PreferencesCustomizer {
076: private JCheckBox rememberPassBox;
077: private JPanel customizer;
078: private Object socketTimeoutVal;
079: private Object reversionVal;
080: private JButton delButton, addButton;
081: private JTextField timeoutField;
082: private JTextField hostField, portField, pathField, nameField,
083: passField, ownerField;
084: private JList serverList;
085: private DefaultListModel serverListModel;
086: private JComboBox protoBox;
087:
088: private boolean timeoutFieldIsSensitive = true;
089: private boolean serverFieldsAreSensitive = true;
090:
091: public NetworkCustomizer(String title, Configurator configurator) {
092: super (title, configurator);
093: initConfig();
094: initComponents();
095: }
096:
097: private void initConfig()
098: {
099: for (Enumeration enum=DAVConnectionPool.getDAVConnections();enum.hasMoreElements();)
100: {
101: Object target=enum.nextElement();
102: if (Debug.DEBUG) Debug.trace(this , Debug.DP5, "next DAVConnection: "+ target);
103: addConfigTarget(target);
104: }
105: socketTimeoutVal=getConfigurator()
106: .getStore()
107: .getConfigValue(DAVConnection.class,
108: DAVConnection.SOCKET_TIMEOUT_PROPERTY);
109: if (socketTimeoutVal==null)
110: socketTimeoutVal=new Integer(DAVConnection.DEFAULT_SOCKET_TIMEOUT);
111: reversionVal=socketTimeoutVal;
112:
113: addConfigTarget(ServerData.container);
114: }
115:
116: private void initComponents() {
117: customizer = new JPanel(new GridBagLayout());
118: GridBagConstraints gbc = new GridBagConstraints();
119: gbc.anchor = GridBagConstraints.NORTHWEST;
120: gbc.gridx = 0;
121: gbc.gridy = 0;
122: gbc.gridwidth = 1;
123: gbc.gridheight = 1;
124: gbc.insets = new Insets(2, 2, 2, 2);
125: gbc.fill = GridBagConstraints.HORIZONTAL;
126: gbc.ipadx = 1;
127: gbc.ipady = 1;
128: gbc.weightx = 1.0;
129: gbc.weighty = 0.20;
130: gbc.anchor = GridBagConstraints.WEST;
131: customizer.add(initTimeout(), gbc);
132: gbc.gridy++;
133: gbc.weightx = 0.0;
134: gbc.weighty = 0.80;
135: customizer.add(initServers(), gbc);
136: //some empty space
137: gbc.weightx = 0.0;
138: gbc.gridy++;
139: gbc.weighty = 1.0;
140: customizer.add(new JLabel(), gbc);
141: }
142:
143: public void ok() {
144: Debug.trace(this , Debug.DP4, "in ok()");
145: if (updateServerConfigValues()) {
146: super .ok();
147: ExplorerMenuBar.refreshMenus();
148: }
149: }
150:
151: public void tryOn() {
152: Debug.trace(this , Debug.DP4, "in tryOn()");
153: if (updateServerConfigValues()) {
154: super .tryOn();
155: ExplorerMenuBar.refreshMenus();
156: }
157:
158: }
159:
160: private void cleanUp() {
161: //use this flag to suppress processing of document events
162: timeoutFieldIsSensitive = false;
163: timeoutField.setText(reversionVal.toString());
164: timeoutFieldIsSensitive = true;
165: refreshServerForm();
166: refreshServerList();
167: ExplorerMenuBar.refreshMenus();
168: }
169:
170: public void revert() {
171: super .revert();
172: cleanUp();
173: }
174:
175: public void revertToDefault() {
176: super .revertToDefault();
177: timeoutFieldIsSensitive = false;
178: socketTimeoutVal = new Integer(
179: DAVConnection.DEFAULT_SOCKET_TIMEOUT);
180: timeoutField.setText(socketTimeoutVal.toString());
181: timeoutFieldIsSensitive = true;
182: //refreshServerForm();
183: //refreshServerList();
184: //ExplorerMenuBar.refreshMenus();
185: }
186:
187: public void cancel() {
188: super .cancel();
189: cleanUp();
190: }
191:
192: private JPanel initTimeout() {
193: JPanel daPanel = new JPanel(new GridBagLayout());
194:
195: String timeoutTitle = ResourceManager
196: .getMessage(ResourceManager.NETWORK_CUSTOMIZER_TIMEOUT_TITLE);
197: JLabel timeoutLabel = new JLabel(timeoutTitle);
198: timeoutField = new JTextField(7);
199: timeoutField.setDocument(new EntryDocument(
200: new PositiveIntegerEntryFilter(0, 99999)));
201: timeoutField.setText(socketTimeoutVal.toString());
202: timeoutField.getDocument().addDocumentListener(
203: new TimeoutDocumentListener());
204:
205: GridBagConstraints gbc = new GridBagConstraints();
206: gbc.gridx = 0;
207: gbc.gridy = 0;
208: gbc.gridwidth = 1;
209: gbc.gridheight = 1;
210: gbc.insets = new Insets(2, 2, 2, 2);
211: gbc.fill = GridBagConstraints.NONE;
212: gbc.ipadx = 1;
213: gbc.ipady = 1;
214: gbc.weightx = 0.0;
215: gbc.weighty = 0.0;
216: gbc.anchor = GridBagConstraints.NORTHWEST;
217:
218: daPanel.add(timeoutLabel, gbc);
219: gbc.gridx++;
220: gbc.weightx = 1.0;
221: daPanel.add(timeoutField, gbc);
222:
223: String borderTitle = ResourceManager
224: .getMessage(ResourceManager.TIMEOUT_BORDER_TITLE);
225: daPanel.setBorder(BorderFactory.createTitledBorder(
226: BorderFactory.createEtchedBorder(), borderTitle,
227: TitledBorder.LEFT, TitledBorder.TOP));
228: return daPanel;
229: }
230:
231: public JPanel initServers() {
232: JPanel daPanel = new JPanel(new GridBagLayout());
233:
234: addButton = new JButton(ResourceManager
235: .getMessage(ResourceManager.ADD_SERVER_LABEL));
236: addButton.setActionCommand("add");
237: delButton = new JButton(ResourceManager
238: .getMessage(ResourceManager.DEL_SERVER_LABEL));
239: delButton.setActionCommand("delete");
240: delButton.setEnabled(false);
241:
242: protoBox = new JComboBox(getAvailableProtocols());
243: protoBox.setActionCommand("protocol");
244: serverListModel = new DefaultListModel();
245: refreshServerList();
246: serverList = new JList(serverListModel);
247: serverList
248: .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
249:
250: ServerFormListener formListener = new ServerFormListener();
251: serverList.addListSelectionListener(formListener);
252: addButton.addActionListener(formListener);
253: delButton.addActionListener(formListener);
254: protoBox.addActionListener(formListener);
255: hostField = new JTextField(22);
256: hostField.getDocument().addDocumentListener(formListener);
257: portField = new JTextField(5);
258: portField.setDocument(new EntryDocument(
259: new PositiveIntegerEntryFilter(0, ((int) Math
260: .pow(2, 16)) - 1)));
261: portField.getDocument().addDocumentListener(formListener);
262: pathField = new JTextField(22);
263: pathField.getDocument().addDocumentListener(formListener);
264: nameField = new JTextField(22);
265: nameField.getDocument().addDocumentListener(formListener);
266: passField = new JPasswordField(22);
267: passField.getDocument().addDocumentListener(formListener);
268: rememberPassBox = new JCheckBox(ResourceManager
269: .getMessage(ResourceManager.REMEMBER_PASSWORD_LABEL));
270: rememberPassBox.addItemListener(formListener);
271: ownerField = new JTextField(22);
272: ownerField.getDocument().addDocumentListener(formListener);
273:
274: GridBagConstraints gbc = new GridBagConstraints();
275: gbc.gridx = 0;
276: gbc.gridy = 0;
277: gbc.fill = GridBagConstraints.NONE;
278: gbc.insets = new Insets(2, 2, 2, 2);
279: gbc.ipadx = 1;
280: gbc.ipady = 1;
281: gbc.anchor = GridBagConstraints.WEST;
282: gbc.gridwidth = 1;
283: gbc.gridheight = GridBagConstraints.REMAINDER;
284:
285: Box serverBox = Box.createVerticalBox();
286: serverBox.add(Box.createVerticalGlue());
287: serverBox.add(new JScrollPane(serverList));
288: serverBox.add(Box.createVerticalGlue());
289: serverBox.add(addButton);
290: serverBox.add(Box.createVerticalGlue());
291: serverBox.add(delButton);
292: serverBox.add(Box.createVerticalGlue());
293:
294: daPanel.add(serverBox, gbc);
295:
296: gbc.gridheight = 1;
297: gbc.gridx = 1;
298:
299: JLabel tmpLabel;
300: gbc.anchor = GridBagConstraints.EAST;
301: tmpLabel = new JLabel(ResourceManager
302: .getMessage(ResourceManager.PROTOCOL_PROMPT),
303: SwingConstants.RIGHT);
304: daPanel.add(tmpLabel, gbc);
305:
306: gbc.gridx++;
307: gbc.anchor = GridBagConstraints.WEST;
308: daPanel.add(protoBox, gbc);
309:
310: gbc.gridx = 1;
311: gbc.gridy++;
312: gbc.anchor = GridBagConstraints.EAST;
313: tmpLabel = new JLabel(ResourceManager
314: .getMessage(ResourceManager.HOST_PROMPT),
315: SwingConstants.RIGHT);
316: daPanel.add(tmpLabel, gbc);
317:
318: gbc.gridx++;
319: gbc.anchor = GridBagConstraints.WEST;
320: daPanel.add(hostField, gbc);
321:
322: gbc.gridx = 1;
323: gbc.gridy++;
324: gbc.anchor = GridBagConstraints.EAST;
325: tmpLabel = new JLabel(ResourceManager
326: .getMessage(ResourceManager.PORT_PROMPT),
327: SwingConstants.RIGHT);
328: daPanel.add(tmpLabel, gbc);
329:
330: gbc.gridx++;
331: gbc.anchor = GridBagConstraints.WEST;
332: daPanel.add(portField, gbc);
333:
334: gbc.gridx = 1;
335: gbc.gridy++;
336: gbc.anchor = GridBagConstraints.EAST;
337: tmpLabel = new JLabel(ResourceManager
338: .getMessage(ResourceManager.PATH_PROMPT),
339: SwingConstants.RIGHT);
340: daPanel.add(tmpLabel, gbc);
341:
342: gbc.gridx++;
343: gbc.anchor = GridBagConstraints.WEST;
344: daPanel.add(pathField, gbc);
345:
346: gbc.gridx = 1;
347: gbc.gridy++;
348: gbc.anchor = GridBagConstraints.EAST;
349: tmpLabel = new JLabel(ResourceManager
350: .getMessage(ResourceManager.USERNAME_PROMPT),
351: SwingConstants.RIGHT);
352: daPanel.add(tmpLabel, gbc);
353:
354: gbc.gridx++;
355: gbc.anchor = GridBagConstraints.WEST;
356: daPanel.add(nameField, gbc);
357:
358: gbc.gridx = 1;
359: gbc.gridy++;
360: gbc.anchor = GridBagConstraints.CENTER;
361: gbc.gridwidth = 2;
362: daPanel.add(rememberPassBox, gbc);
363:
364: gbc.gridwidth = 1;
365: gbc.gridx = 1;
366: gbc.gridy++;
367: gbc.anchor = GridBagConstraints.EAST;
368: tmpLabel = new JLabel(ResourceManager
369: .getMessage(ResourceManager.PASSWORD_PROMPT),
370: SwingConstants.RIGHT);
371: daPanel.add(tmpLabel, gbc);
372:
373: gbc.gridx++;
374: gbc.anchor = GridBagConstraints.WEST;
375: daPanel.add(passField, gbc);
376:
377: gbc.gridx = 1;
378: gbc.gridy++;
379: gbc.anchor = GridBagConstraints.EAST;
380: tmpLabel = new JLabel(ResourceManager
381: .getMessage(ResourceManager.OWNER_PROMPT),
382: SwingConstants.RIGHT);
383: daPanel.add(tmpLabel, gbc);
384:
385: gbc.gridx++;
386: gbc.anchor = GridBagConstraints.WEST;
387: daPanel.add(ownerField, gbc);
388: String borderTitle = ResourceManager
389: .getMessage(ResourceManager.SERVER_BORDER_TITLE);
390: daPanel.setBorder(BorderFactory.createTitledBorder(
391: BorderFactory.createEtchedBorder(), borderTitle,
392: TitledBorder.LEFT, TitledBorder.TOP));
393: if (serverListModel.size() > 0)
394: serverList.setSelectedIndex(0);
395:
396: return daPanel;
397: }
398:
399: private void refreshServerList()
400: {
401: serverListModel.clear();
402: for (Enumeration enum=ServerData.getServers().elements();enum.hasMoreElements();)
403: {
404: serverListModel.addElement(enum.nextElement());
405: }
406: }
407:
408: private void populateForm(ServerData sd) {
409: //if the server data has https for the protocol, and
410: //SSL is not enabled, we've got a problem.
411: if (sd == null) {
412:
413: protoBox.setSelectedItem(DAVConstants.HTTP);
414: hostField.setText("");
415: portField.setText("80");
416: pathField.setText("/");
417: nameField.setText("");
418: rememberPassBox.setSelected(false);
419: passField.setText("");
420: ownerField.setText("");
421: } else {
422: boolean usesSSL = sd.usesSSL();
423: if (usesSSL && !DAVConnectionPool.canSupportSSL()) {
424: //issue warning
425: String message = ResourceManager
426: .getMessage(ResourceManager.HTTPS_NOT_SUPPORTED_MESSAGE);
427: String title = ResourceManager
428: .getMessage(ResourceManager.HTTPS_NOT_SUPPORTED_DIALOG_TITLE);
429: JOptionPane.showMessageDialog(this .customizer, message,
430: title, JOptionPane.WARNING_MESSAGE);
431: }
432: protoBox.setSelectedItem(usesSSL ? DAVConstants.HTTPS
433: : DAVConstants.HTTP);
434: hostField.setText(sd.getHost());
435: portField.setText(Integer.toString(sd.getPort()));
436: pathField.setText(sd.getInitialPath());
437: nameField.setText(sd.getUsername());
438: rememberPassBox.setSelected(sd.getRememberPassword());
439: passField.setText(sd.getPassword());
440: ownerField.setText(sd.getOwner());
441: }
442: }
443:
444: private class ServerFormListener implements ActionListener,
445: DocumentListener, ListSelectionListener, ItemListener {
446: public void itemStateChanged(ItemEvent ie) {
447: int stateChange = ie.getStateChange();
448: if (stateChange == ItemEvent.DESELECTED) {
449: boolean sensitivity = serverFieldsAreSensitive;
450: serverFieldsAreSensitive = false;
451: passField.setText("");
452: serverFieldsAreSensitive = sensitivity;
453: passField.setEnabled(false);
454: if (serverFieldsAreSensitive)
455: setDirty(true);
456: } else if (stateChange == ItemEvent.SELECTED) {
457: passField.setEnabled(true);
458: if (serverFieldsAreSensitive)
459: setDirty(true);
460: }
461:
462: }
463:
464: public void valueChanged(ListSelectionEvent lassie) {
465: Object val = serverList.getSelectedValue();
466: serverFieldsAreSensitive = false;
467: if (val != null) {
468: populateForm((ServerData) val);
469: delButton.setEnabled(true);
470: } else {
471: populateForm(null);
472: delButton.setEnabled(false);
473: }
474: serverFieldsAreSensitive = true;
475: }
476:
477: public void actionPerformed(ActionEvent ae) {
478: // for add and delete buttons
479: String command = ae.getActionCommand();
480: if ("add".equals(command)) {
481: ServerData sd = new ServerData(false, "", 80, "/", "",
482: "", false, false);
483: serverListModel.addElement(sd);
484: serverList.setSelectedValue(sd, true);
485: setDirty(true);
486: } else if ("delete".equals(command)) {
487: Object o = serverList.getSelectedValue();
488: int index = serverList.getSelectedIndex();
489: if (o != null) {
490: serverListModel.removeElement(o);
491: updateServerData();
492: int size = serverListModel.size();
493: if (size > index)
494: serverList.setSelectedIndex(index);
495: else if (size == index)
496: serverList.setSelectedIndex(size - 1);
497: else if (index == 0)
498: populateForm(null);
499: setDirty(true);
500: }
501: } else if ("protocol".equals(command)) {
502: formChanged();
503: }
504: }
505:
506: private void formChanged() {
507: if (serverFieldsAreSensitive) {
508: updateServerData();
509: }
510: }
511:
512: public void changedUpdate(DocumentEvent donkey) {
513: }
514:
515: public void insertUpdate(DocumentEvent donkey) {
516: formChanged();
517: }
518:
519: public void removeUpdate(DocumentEvent donkey) {
520: formChanged();
521: }
522: }
523:
524: private boolean portIsValid() {
525: try {
526: Integer.parseInt(portField.getText().trim());
527: return true;
528: } catch (NumberFormatException nafta) {
529: return false;
530: }
531: }
532:
533: private Object[] getAvailableProtocols() {
534: //if (DAVConnectionPool.canSupportSSL())
535: return new Object[] { DAVConstants.HTTP, DAVConstants.HTTPS };
536: //else return new Object[] { DAVConstants.HTTP };
537: }
538:
539: private Vector getServers()
540: {
541: Vector v=new Vector();
542: for (Enumeration enum=serverListModel.elements();enum.hasMoreElements();)
543: {
544: v.add(enum.nextElement());
545: }
546: return v;
547: }
548:
549: private boolean updateServerConfigValues() {
550: if (portIsValid()) {
551: Vector servers = getServers();
552: Debug.trace(this , Debug.DP2, "servers: {0}", servers);
553: setConfigValue(ServerDataContainer.class,
554: ServerDataContainer.SERVER_DATA_VECTOR_PROPERTY,
555: servers);
556: } else {
557: String message = ResourceManager
558: .getMessage(ResourceManager.PORT_INVALID_MESSAGE);
559: String title = ResourceManager
560: .getMessage(ResourceManager.PORT_INVALID_TITLE);
561: JOptionPane.showMessageDialog(this .customizer, message,
562: title, JOptionPane.ERROR_MESSAGE);
563: return false;
564: }
565: return true;
566: }
567:
568: private void refreshServerForm()
569: {
570: serverFieldsAreSensitive=false;
571: Object selected=serverList.getSelectedValue();
572: Vector servers=ServerData.getServers();
573: serverListModel.clear();
574: for (Enumeration enum=servers.elements();enum.hasMoreElements();)
575: {
576: Object o=enum.nextElement();
577: if (selected!=null)
578: {
579: if (((ServerData)selected).getHost().equals(((ServerData)o).getHost()))
580: selected=o;
581: }
582: serverListModel.addElement(o);
583: }
584: if (selected!=null)
585: {
586: serverList.setSelectedValue(selected, true);
587: }
588: serverFieldsAreSensitive=true;
589: }
590:
591: private void updateServerData() {
592: //modify the active ServerData according to the contents of the form
593: Object o = serverList.getSelectedValue();
594: if (o != null) {
595: ServerData sd = (ServerData) o;
596: sd.setHost(hostField.getText().trim());
597: sd.setInitialPath(pathField.getText().trim());
598: sd.setUsername(nameField.getText().trim());
599: sd.setRememberPassword(rememberPassBox.isSelected());
600: sd.setPassword(passField.getText());
601: sd.setUsesSSL(protoBox.getSelectedItem().equals(
602: DAVConstants.HTTPS));
603: sd.setOwner(ownerField.getText());
604: String portText = portField.getText().trim();
605: if (portText.length() > 0)
606: sd.setPort(Integer.parseInt(portText));
607: setDirty(true);
608: }
609: }
610:
611: public JComponent getCustomizer() {
612: return customizer;
613: }
614:
615: private class TimeoutDocumentListener implements DocumentListener {
616: public void changedUpdate(DocumentEvent donkey) {
617: //do nothing
618: }
619:
620: public void insertUpdate(DocumentEvent donkey) {
621: if (timeoutFieldIsSensitive)
622: _process(donkey.getDocument());
623: }
624:
625: public void removeUpdate(DocumentEvent donkey) {
626: if (timeoutFieldIsSensitive)
627: _process(donkey.getDocument());
628: }
629:
630: private void _process(Document doc) {
631: try {
632: Integer aye = new Integer(doc.getText(0, doc
633: .getLength()));
634: if (aye.equals(socketTimeoutVal))
635: return;
636: socketTimeoutVal = aye;
637: setConfigValue(DAVConnection.class,
638: DAVConnection.SOCKET_TIMEOUT_PROPERTY, aye);
639: setDirty(true);
640: } catch (BadLocationException ballocks) {
641: if (Debug.DEBUG)
642: Debug.trace(this , Debug.DP2, ballocks);
643: } catch (NumberFormatException e) {
644: if (Debug.DEBUG)
645: Debug.trace(this , Debug.DP2, e);
646: }
647: }
648: }
649:
650: }
651:
652: /* $Log: NetworkCustomizer.java,v $
653: /* Revision 1.5 2001/07/29 22:37:36 smulloni
654: /* fix to NetworkCustomizer; workaround to bad design of ServerData
655: /*
656: /* Revision 1.4 2001/07/26 18:35:33 smulloni
657: /* patched HTTPClient so jikes doesn't issue warnings about catching Exception;
658: /* replaced PropertyChangeEvents with ChangeEvents in PreferencesCustomizer and
659: /* related classes; incremented app version to 1.0.2.3.
660: /*
661: /* Revision 1.3 2001/06/13 01:09:03 smulloni
662: /* Some improvements to the network customizer (which is still buggy).
663: /* Also improvements for using the doAllprop switch, and for the layout of
664: /* the PropertiesDialog.
665: /*
666: /* Revision 1.2 2001/06/09 03:09:09 smulloni
667: /* added server customization to the NetworkCustomizer. Buggy.
668: /*
669: /* Revision 1.1 2001/02/06 22:15:04 smulloni
670: /* add two example files and moved GeneralCustomizer to NetworkCustomizer
671: /* */
|