Package net.sf.jpluck.apps.jpluckx.ui

Source Code of net.sf.jpluck.apps.jpluckx.ui.DocumentDialog

package net.sf.jpluck.apps.jpluckx.ui;

import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.text.DateFormatSymbols;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.jsp.el.ExpressionEvaluator;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.SpinnerDateModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.LineBorder;
import javax.swing.colorchooser.AbstractColorChooserPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import net.sf.jpluck.ClientConfiguration;
import net.sf.jpluck.VersionInfo;
import net.sf.jpluck.jxl.Document;
import net.sf.jpluck.jxl.Feed;
import net.sf.jpluck.jxl.JXL;
import net.sf.jpluck.jxl.Template;
import net.sf.jpluck.swing.ComponentGroup;
import net.sf.jpluck.swing.EntryTextField;
import net.sf.jpluck.swing.FileBrowseButton;
import net.sf.jpluck.swing.GUIUtil;
import net.sf.jpluck.ui.Banner;
import net.sf.jpluck.ui.StandardDialog;
import net.sf.jpluck.ui.ValidationException;
import net.sf.jpluck.util.ColorUtil;
import net.sf.jpluck.util.el.DefaultVariables;
import net.sf.jpluck.util.el.StaticFunctionMapper;
import net.sf.jpluck.xml.ContextAdapter;

import org.apache.commons.el.ExpressionEvaluatorImpl;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.Pointer;
import org.quartz.CronTrigger;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import com.jgoodies.forms.builder.ButtonBarBuilder;
import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.factories.Borders;
import com.jgoodies.forms.layout.FormLayout;

import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.net.URI;


public class DocumentDialog extends StandardDialog {
    private AlternateListener alternateListener = new AlternateListener();
    private BPPListener embeddedBppListener;
    private BPPListener standaloneBppListener;
    private Banner banner;
    private CardLayout scheduleLayout;
    private ComponentGroup imageGroup = new ComponentGroup();
    private ComponentGroup scheduleGroup = new ComponentGroup();
    private EntryTextField categoryText = new EntryTextField(15, 15);
    private EntryTextField embeddedHeightText = new EntryTextField(4, 4);
    private EntryTextField embeddedWidthText = new EntryTextField(4, 4);
    private EntryTextField linkColorText = new EntryTextField(7, 7);
    private EntryTextField nameText = new EntryTextField(31);
    private EntryTextField standaloneHeightText = new EntryTextField(4, 4);
    private EntryTextField standaloneWidthText = new EntryTextField(4, 4);
    private EntryTextField unresolvedLinkColorText = new EntryTextField(7, 7);
    private EntryTextField uriText = new EntryTextField(35);
    private EntryTextField userAgentText = new EntryTextField(35);
    private FileBrowseButton uriBrowse;
    private ImageSizeListener embeddedHeightListener;
    private ImageSizeListener embeddedWidthListener;
    private ImageSizeListener standaloneHeightListener;
    private ImageSizeListener standaloneWidthListener;
    private JButton categoryButton = new JButton(new CategoryAction());
    private JButton linkColorButton;
    private JButton unresolvedLinkColorButton;
    private JButton userAgentButton = new JButton(new SelectUserAgentAction());
    private JCheckBox altTextCheck = new JCheckBox("Include image alt. text");
    private JCheckBox alternateCheck = new JCheckBox("Link to alternate copy");
    private JCheckBox backupCheck = new JCheckBox("Set backup bit");
    private JCheckBox cacheCheck = new JCheckBox("Use download cache");
    private JCheckBox convertCheck = new JCheckBox("Convert now");
    private JCheckBox embeddedHeightCheck = new JCheckBox("Max. height: ");
    private JCheckBox embeddedWidthCheck = new JCheckBox("Max. width: ");
    private JCheckBox hiresCheck = new JCheckBox("Use hires margins");
    private JCheckBox includeURIInfoCheck = new JCheckBox("Include URL info");
    private JCheckBox inheritImagesCheck = new JCheckBox("Inherit image settings from template");
    private JCheckBox maxAgeCheck = new JCheckBox("Leave out items older than ");
    private JCheckBox removeAccentsCheck = new JCheckBox("Remove accents in database name");
    private JCheckBox standaloneHeightCheck = new JCheckBox("Max. height: ");
    private JCheckBox standaloneWidthCheck = new JCheckBox("Max. width: ");
    private JComboBox dayCombo;
    private JComboBox dayOfMonthCombo;
    private EntryTextField filenameText = new EntryTextField(40);
    private EntryTextField referrerText = new EntryTextField(35);
    private JComboBox embeddedBppCombo = new JComboBox(new String[] {
                                                           "No embedded images", "1bpp embedded images",
                                                           "2bpp embedded images", "4bpp embedded images",
                                                           "8bpp embedded images", "16bpp embedded images"
                                                       });
    private JComboBox inputEncodingCombo;
    private JComboBox linksCombo = new JComboBox(new String[] { "Leave as is", "Use specific color" });
    private JComboBox outputEncodingCombo;
    private JComboBox restrictCombo = new JComboBox(new String[] { "none", "domain", "host", "directory" });
    private JComboBox scheduleCombo = new JComboBox(new String[] {
                                                        "none", "hourly", "daily", "weekly", "monthly", "cron"
                                                    });
    private JComboBox standaloneBppCombo = new JComboBox(new String[] {
                                                             "No standalone images", "1bpp standalone images",
                                                             "2bpp standalone images", "4bpp standalone images",
                                                             "8bpp standalone images", "16bpp standalone images"
                                                         });
    private JComboBox structureCombo = new JComboBox(new String[] {
                                                         "Put each feed item on a separate page",
                                                         "Put all feed items on a single page", "Show feed item links"
                                                     });
    private JComboBox templateCombo = new JComboBox();
    private JComboBox unresolvedLinksCombo = new JComboBox(new String[] { "Leave as is", "Remove", "Use specific color" });
    private JLabel embeddedSizeLabel;
    private JLabel maxAgeLabel = new JLabel(" days");
    private JLabel nameWarningLabel = new JLabel();
    private JLabel scheduleLabel;
    private JLabel standaloneSizeLabel;
    private JPanel schedulePanel = new JPanel();
    private JSpinner dailyTimeSpinner = new JSpinner(new SpinnerDateModel());
    private JSpinner maxAgeSpinner = new JSpinner(new SpinnerNumberModel(7, 1, 99, 1));
    private JSpinner maxDepthSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 99, 1));
    private JSpinner minuteSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 59, 1));
    private JSpinner monthlyTimeSpinner = new JSpinner(new SpinnerDateModel());
    private JSpinner weeklyTimeSpinner = new JSpinner(new SpinnerDateModel());
    private JTabbedPane tabPane = new JTabbedPane();
    private LinksListener linksListener = new LinksListener();
    private MaxAgeListener maxAgeListener = new MaxAgeListener();
    private PatternPanel exclusionPanel;
    private PatternPanel inclusionPanel;
    private ScheduleListener scheduleListener = new ScheduleListener();
    private SelectColorAction selectLinkColorAction = new SelectColorAction(linkColorText);
    private SelectColorAction selectUnresolvedLinkColorAction = new SelectColorAction(unresolvedLinkColorText);
    private UnresolvedLinksListener unresolvedLinksListener = new UnresolvedLinksListener();
    private String[] categories = new String[0];
    private boolean editingDefault;
    private EntryTextField cronText;

    private class MyDropTargetListener implements DropTargetListener
    {
        public void drop(DropTargetDropEvent dtde) {
            try {
                Transferable tr = dtde.getTransferable();
                if(dtde.isDataFlavorSupported(DataFlavor.stringFlavor)) {
                    dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
                    String filename = (String)tr.getTransferData(DataFlavor.stringFlavor);
                    uriText.setText(URI.create(filename).toString());
                    dtde.dropComplete(true);
                }
                else if(dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
                    dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
                    java.util.List files = (java.util.List)tr.getTransferData(DataFlavor.javaFileListFlavor);
                    for(Iterator iterator = (Iterator)files.iterator(); iterator.hasNext();) {
                        File file = (File)iterator.next();
                        uriText.setText(file.toURI().toString());
                        break; // only process first file in the list, for now
                    }
                    dtde.dropComplete(true);
                }
                else {
                    dtde.rejectDrop();
                }
            }
            catch(IOException ioe) {
                ioe.printStackTrace();
            }
            catch(UnsupportedFlavorException ufe) {
                ufe.printStackTrace();
            }
        }
        public void dragExit(DropTargetEvent dte) {}
        public void dragEnter(DropTargetDragEvent dtde) {}
        public void dragOver(DropTargetDragEvent dtde) {}
        public void dropActionChanged(DropTargetDragEvent dtde) {}
    }

    protected DocumentDialog(JFrame owner) {
        super(owner);
    }

    public static Result addFeed(JFrame owner, JXL jxl, String title, String url, boolean pluckthis) {
        return add(owner, jxl, true, title, null, pluckthis);
    }

    public static Result addSite(JFrame owner, JXL jxl, String name, String url, boolean pluckthis) {
        return add(owner, jxl, false, name, url, pluckthis);
    }

    public static Result edit(JFrame owner, Document document)
                       throws IOException, SAXException {
        owner.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        DocumentDialog dlg = new DocumentDialog(owner);
        boolean feed = (document instanceof Feed);
        dlg.initComponents(feed);
        dlg.initTemplates(document.getJXL());
        dlg.initValues(document);
        if (feed) {
            dlg.banner.showSheet("editFeed");
        } else {
            dlg.banner.showSheet("editSite");
        }
        owner.setCursor(Cursor.getDefaultCursor());
        dlg.setLocationRelativeTo(owner);
        dlg.show();
        if (!dlg.isCancelled()) {
            dlg.update(document);
            document.getJXL().edited(document);
            document.getJXL().save();
            return new Result(true, dlg.convertCheck.isSelected());
        } else {
            return new Result(false, false);
        }
    }

    public static void editDefault(JFrame owner) throws SAXException, IOException {
        owner.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        Document document = ClientConfiguration.getDefault().getDefaultDocument();
        DocumentDialog dlg = new DocumentDialog(owner);
        dlg.editingDefault = true;
        dlg.initComponents(false);
        dlg.banner.showSheet("editDefault");
        if (document == null) {
            JXL jxl = new JXL();
            Element site = jxl.createSiteElement();
            org.w3c.dom.Document dom = site.getOwnerDocument();
            Element name = dom.createElement("name");
            name.appendChild(dom.createTextNode("default"));
            site.appendChild(dom.createElement("uri"));
            document = jxl.add(site);
            jxl.save(new File(ClientConfiguration.getDefault().getDefaultJXLPath()));
        } else {
            dlg.initValues(document);
        }
        owner.setCursor(Cursor.getDefaultCursor());
        dlg.setLocationRelativeTo(owner);
        dlg.nameText.setText("");
        dlg.setTitle("Default Settings");
        dlg.show();
        if (!dlg.isCancelled()) {
            dlg.update(document);
            document.getJXL().save();
        }
    }

    public boolean ok() {
        try {
            if ((nameText.getText().length() == 0) && !editingDefault) {
                throw ValidationException.required(nameText, "Please enter a name.");
            }
            if ((uriText.getText().length() == 0) && !editingDefault) {
                throw ValidationException.required(uriText, "Please enter a URL.");
            }
            ExpressionEvaluator eval = new ExpressionEvaluatorImpl();
            try {
                eval.evaluate((String) nameText.getText(), String.class, new DefaultVariables(),
                              StaticFunctionMapper.getDefault());
            } catch (Exception e) {
                throw ValidationException.invalid(nameText, "Error evaluating EL expression:\n" + e.getMessage());
            }
            try {
                eval.evaluate((String) uriText.getText(), String.class, new DefaultVariables(),
                              StaticFunctionMapper.getDefault());
            } catch (Exception e) {
                throw ValidationException.invalid(uriText, "Error evaluating EL expression:\n" + e.getMessage());
            }

            if (scheduleCombo.getSelectedItem().equals("cron")) {
                try {
                    CronTrigger trigger = new CronTrigger();
                    trigger.setCronExpression(cronText.getText());
                } catch (Exception e) {
                    throw ValidationException.invalid(cronText, "Invalid cron expression.");
                }
            }

            if (embeddedBppCombo.getSelectedIndex() > 0) {
                if (!embeddedWidthCheck.isSelected()) {
                    int result = JOptionPane.showConfirmDialog(this,
                                                               "It is STRONGLY recommended that you specify\n" +
                                                               "a maximum width for embedded images.\n\n" +
                                                               "Do you want to specify a maximum width now?",
                                                               "Maximum Embedded Width", JOptionPane.YES_NO_OPTION,
                                                               JOptionPane.QUESTION_MESSAGE);
                    if (result == JOptionPane.YES_OPTION) {
                        tabPane.setSelectedIndex(1);
                        embeddedWidthCheck.setSelected(true);
                        embeddedWidthText.requestFocus();
                        return false;
                    }
                }
                if (embeddedWidthCheck.isSelected() && !embeddedWidthText.containsIntValue()) {
                    throw ValidationException.required(embeddedWidthText, "Please enter a maximum width.");
                }
                if (embeddedHeightCheck.isSelected() && !embeddedHeightText.containsIntValue()) {
                    throw ValidationException.required(embeddedHeightText, "Please enter a maximum height.");
                }
            }
            if (standaloneBppCombo.getSelectedIndex() > 0) {
                if (standaloneWidthCheck.isSelected() && !standaloneWidthText.containsIntValue()) {
                    throw ValidationException.required(standaloneWidthText, "Please enter a maximum width.");
                }
                if (standaloneHeightCheck.isSelected() && !standaloneHeightText.containsIntValue()) {
                    throw ValidationException.required(standaloneHeightText, "Please enter a maximum height.");
                }
            }
            if (linksCombo.getSelectedIndex() == 1) {
                String s = linkColorText.getText();
                if (s.length() == 0) {
                    throw ValidationException.required(linkColorText, "Please specify a link color.");
                } else if (ColorUtil.getColor(s) == null) {
                    throw ValidationException.invalid(linkColorText, "Invalid color.");
                }
            }
            if (unresolvedLinksCombo.getSelectedIndex() == 2) {
                String s = unresolvedLinkColorText.getText();
                if (s.length() == 0) {
                    throw ValidationException.required(unresolvedLinkColorText, "Please specify a link color.");
                } else if (ColorUtil.getColor(s) == null) {
                    throw ValidationException.invalid(unresolvedLinkColorText, "Invalid color.");
                }
            }

            if (categoryText.getText().length() > 0) {
                if (categories.length == 0) {
                    categories = new String[] { categoryText.getText() };
                } else {
                    categories[0] = categoryText.getText();
                }
            } else {
                if (categories.length > 0) {
                    String[] newCategories = new String[categories.length - 1];
                    System.arraycopy(categories, 1, newCategories, 0, categories.length - 1);
                    categories = newCategories;
                }
            }

            return true;
        } catch (ValidationException e) {
            e.showMessageDialog();
            return false;
        }
    }

    protected void initButtonBar(ButtonBarBuilder builder) {
        if (!editingDefault) {
            convertCheck.setMnemonic('w');
            convertCheck.setFocusable(false);
            builder.addGridded(convertCheck);
        }
    }

    private static Result add(JFrame owner, JXL jxl, boolean feed, String name, String url, boolean pluckthis) {
        owner.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

        DocumentDialog dlg = new DocumentDialog(owner);
        dlg.initComponents(feed);
        dlg.convertCheck.setSelected(pluckthis);
        dlg.initTemplates(jxl);
        try {
            Document defaultDocument = ClientConfiguration.getDefault().getDefaultDocument();
            if (defaultDocument != null) {
                dlg.initValues(defaultDocument);
                dlg.nameText.setText("");
                dlg.uriText.setText("");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (feed) {
            dlg.banner.showSheet("addFeed");
        } else {
            dlg.banner.showSheet("addSite");
        }
        if (name != null) {
            dlg.nameText.setText(name);
        }
        if (url != null) {
            dlg.uriText.setText(url);
        } else {
            // Try retrieving the URL from the clipboard
            try {
                Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
                Transferable transferable = clipboard.getContents(dlg);
                if ((transferable != null) && transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) {
                    String s = (String) transferable.getTransferData(DataFlavor.stringFlavor);
                    if (s.startsWith("http://") || s.startsWith("file:/")) {
                        dlg.uriText.setText(s);
                    } else {
                        File file = new File(s);
                        if (file.exists() && file.isFile()) {
                            dlg.uriText.setText(file.toURI().toString());
                        }
                    }
                }
            } catch (Exception e) {
            }
        }
        Template template = jxl.getDefaultTemplate();
        if (template != null) {
            dlg.templateCombo.setSelectedItem(template.getID());
        }

        if (pluckthis) {
            dlg.cacheCheck.setSelected(false);
            dlg.maxDepthSpinner.setValue(new Integer(0));
            dlg.banner.showSheet("pluckthis");
        }

        dlg.setLocationRelativeTo(owner);
        owner.setCursor(Cursor.getDefaultCursor());
        dlg.show();
        if (!dlg.isCancelled()) {
            Element element;
            if (feed) {
                element = jxl.createFeedElement();
            } else {
                element = jxl.createSiteElement();
            }
            dlg.populate(element);
            jxl.add(element);
            return new Result(true, dlg.convertCheck.isSelected());
        } else {
            return new Result(false, false);
        }
    }

    private void setBppCombo(JComboBox combo, int bpp) {
        if ((bpp == 1) || (bpp == 2)) {
            combo.setSelectedIndex(bpp);
        } else if (bpp == 4) {
            combo.setSelectedIndex(3);
        } else if (bpp == 8) {
            combo.setSelectedIndex(4);
        } else if (bpp == 16) {
            combo.setSelectedIndex(5);
        }
    }

    private void initComponents(boolean feed) {
        banner = new Banner();
        banner.addSheet("Add New Site", "addSite");
        banner.addSheet("Add New Feed", "addFeed");
        banner.addSheet("Edit Site", "editSite");
        banner.addSheet("Edit Feed", "editFeed");
        banner.addSheet("Default Settings", "editDefault");
        banner.addSheet("PluckThis", "pluckthis");

        Calendar cal = new GregorianCalendar();
        DateFormatSymbols symbols = new DateFormatSymbols(Locale.ENGLISH);
        String[] dayNames = symbols.getWeekdays();
        int day = cal.getFirstDayOfWeek();
        String[] days = new String[7];
        for (int i = 0; i < 7; i++) {
            days[i] = dayNames[day];
            day++;
            if (day > 7) {
                day = 1;
            }
        }
        dayCombo = new JComboBox(days);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        dailyTimeSpinner.setValue(cal.getTime());
        weeklyTimeSpinner.setValue(cal.getTime());
        monthlyTimeSpinner.setValue(cal.getTime());

        /*Language[] languages = Language.getAll();
        Object[] objects = new Object[languages.length + 1];
        objects[0] = "<Not selected>";
        System.arraycopy(languages, 0, objects, 1, languages.length);
        languageCombo = new JComboBox(objects);*/
        nameText.getDocument().addDocumentListener(new NameListener());
        nameWarningLabel.setForeground(Color.RED);
        nameWarningLabel.setVisible(false);
        nameWarningLabel.setToolTipText("Name is longer than 31 characters and will be truncated.");
        uriBrowse = new FileBrowseButton("...", uriText, "Select File", "Select", false, true,
                                         new SupportedFileTypesFilter());

        PanelBuilder nameBuilder = new PanelBuilder(new FormLayout("left:pref, 4dlu, pref:grow", "pref"));
        nameBuilder.add(nameText, "1,1");
        nameBuilder.add(nameWarningLabel, "3,1");

        PanelBuilder uriBuilder = new PanelBuilder(new FormLayout("left:pref, 4dlu, 20dlu", "pref"));
        uriBuilder.add(uriText, "1,1");
        uriBuilder.add(uriBrowse, "3,1");

        PanelBuilder maxDepthBuilder = new PanelBuilder(new FormLayout("left:pref, left:pref", "pref"));
        maxDepthBuilder.add(maxDepthSpinner, "1,1");
        maxDepthBuilder.addLabel(" links deep", "2,1");

        PanelBuilder categoryBuilder = new PanelBuilder(new FormLayout("pref, 4dlu, 20dlu", "pref"));
        categoryBuilder.add(categoryText, "1,1");
        categoryBuilder.add(categoryButton, "3,1");
        GUIUtil.makeEqualHeight(categoryText, categoryButton);

        JPanel maxAgePanel = new JPanel(new FormLayout("pref,pref,pref", "pref"));
        maxAgePanel.add(maxAgeCheck, "1,1");
        maxAgeCheck.addChangeListener(maxAgeListener);
        maxAgePanel.add(maxAgeSpinner, "2,1");
        maxAgeSpinner.setEnabled(false);
        maxAgePanel.add(maxAgeLabel, "3,1");

        scheduleLayout = new CardLayout();
        schedulePanel.setLayout(scheduleLayout);

        JPanel nonePanel = new JPanel();
        schedulePanel.add(nonePanel, "none");

        JPanel hourlyPanel = new JPanel(new FormLayout("pref,pref,pref", "pref"));
        hourlyPanel.add(new JLabel(" at "), "1,1");
        hourlyPanel.add(minuteSpinner, "2,1");
        hourlyPanel.add(new JLabel(" (minute of the hour)"), "3,1");
        schedulePanel.add(hourlyPanel, "hourly");

        JPanel dailyPanel = new JPanel(new FormLayout("pref,pref", "pref"));
        dailyTimeSpinner.setEditor(new JSpinner.DateEditor(dailyTimeSpinner,
                                                           ClientConfiguration.getDefault().getTimeFormat()));
        dailyPanel.add(new JLabel(" at "), "1,1");
        dailyPanel.add(dailyTimeSpinner, "2,1");
        schedulePanel.add(dailyPanel, "daily");

        JPanel weeklyPanel = new JPanel(new FormLayout("pref,pref,pref,pref", "pref"));
        weeklyTimeSpinner.setEditor(new JSpinner.DateEditor(weeklyTimeSpinner,
                                                            ClientConfiguration.getDefault().getTimeFormat()));
        weeklyPanel.add(new JLabel(" on "), "1,1");
        weeklyPanel.add(dayCombo, "2,1");
        weeklyPanel.add(new JLabel(" at "), "3,1");
        weeklyPanel.add(weeklyTimeSpinner, "4,1");
        schedulePanel.add(weeklyPanel, "weekly");

        String[] daysOfMonth = new String[32];
        for (int i = 1; i <= 31; i++) {
            String s = String.valueOf(i);
            int j = i;
            if (j > 30) {
                j -= 30;
            } else if (j > 20) {
                j -= 20;
            }
            if (j == 1) {
                s += "st";
            } else if (j == 2) {
                s += "nd";
            } else if (j == 3) {
                s += "rd";
            } else {
                s += "th";
            }
            daysOfMonth[i - 1] = s;
        }
        daysOfMonth[31] = "<last>";
        dayOfMonthCombo = new JComboBox(daysOfMonth);
        monthlyTimeSpinner.setEditor(new JSpinner.DateEditor(monthlyTimeSpinner,
                                                             ClientConfiguration.getDefault().getTimeFormat()));

        JPanel monthlyPanel = new JPanel(new FormLayout("pref,pref,pref,pref", "pref"));
        monthlyPanel.add(new JLabel(" on the "), "1,1");
        monthlyPanel.add(dayOfMonthCombo, "2,1");
        monthlyPanel.add(new JLabel(" at "), "3,1");
        monthlyPanel.add(monthlyTimeSpinner, "4,1");
        schedulePanel.add(monthlyPanel, "monthly");

        JPanel cronPanel = new JPanel(new FormLayout("4dlu, left:pref", "pref"));
        cronText = new EntryTextField(20);
        cronPanel.add(cronText, "2,1");
        schedulePanel.add(cronPanel, "cron");

        scheduleCombo.addItemListener(scheduleListener);

        altTextCheck.setSelected(true);

        linksCombo.addItemListener(linksListener);
        unresolvedLinksCombo.addItemListener(unresolvedLinksListener);

        List charsetList = new ArrayList();
        Map map = Charset.availableCharsets();
        for (Iterator it = map.values().iterator(); it.hasNext();) {
            Charset charset = (Charset) it.next();
            charsetList.add(charset.displayName().toLowerCase());
        }
        charsetList.add(0, "<Autodetect>");
        inputEncodingCombo = new JComboBox(charsetList.toArray());
        charsetList.remove(0);
        charsetList.add(0, "<Default>");
        outputEncodingCombo = new JComboBox(charsetList.toArray());

        includeURIInfoCheck.setSelected(true);
        cacheCheck.setSelected(true);

        PanelBuilder userAgentBuilder = new PanelBuilder(new FormLayout("pref, 4dlu, 20dlu", "pref"));
        userAgentBuilder.add(userAgentText, "1,1");
        userAgentBuilder.add(userAgentButton, "3,1");
        GUIUtil.makeEqualHeight(userAgentText, userAgentButton);

        String extraRows = (feed ? "4dlu, pref, 4dlu, pref, " : "4dlu, pref, ");

        FormLayout mainLayout = new FormLayout("left:pref, 6dlu, left:pref:grow",
                                               "pref, 4dlu, pref, 4dlu, pref, 4dlu, pref, 7dlu," +
                                               "pref, 4dlu, pref, 4dlu, pref, 4dlu, pref, 4dlu, pref, " + extraRows +
                                               "7dlu, " + "pref, 4dlu, pref");
        PanelBuilder mainBuilder = new PanelBuilder(mainLayout);
        mainBuilder.setBorder(Borders.TABBED_DIALOG_BORDER);
        mainBuilder.addSeparator("Document", "1,1,3,1");

        JLabel nameLabel = mainBuilder.addLabel("&Name", "1,3");
        nameLabel.setLabelFor(nameText);
        nameLabel.setEnabled(!editingDefault);
        mainBuilder.add(nameBuilder.getPanel(), "3,3");
        nameText.setEnabled(!editingDefault);

        mainBuilder.addLabel("&Category", "1,5").setLabelFor(categoryText);
        mainBuilder.add(categoryBuilder.getPanel(), "3,5");

        JLabel templateLabel = mainBuilder.addLabel("&Template", "1,7");
        templateLabel.setLabelFor(templateCombo);
        templateLabel.setEnabled(!editingDefault);
        mainBuilder.add(templateCombo, "3,7");
        templateCombo.setEnabled(!editingDefault);

        mainBuilder.addSeparator((feed ? "Feed" : "Site"), "1,9,3,1");

        JLabel uriLabel = mainBuilder.addLabel("&URL", "1,11");
        uriLabel.setLabelFor(uriText);
        uriLabel.setEnabled(!editingDefault);
        mainBuilder.add(uriBuilder.getPanel(), "3,11");
        GUIUtil.enablePanel(uriBuilder.getPanel(), !editingDefault);

        new DropTarget(uriText,DnDConstants.ACTION_COPY_OR_MOVE,new DocumentDialog.MyDropTargetListener());
       
        int row = 13;
        if (feed) {
            mainBuilder.addLabel("Structure", "1," + row);
            mainBuilder.add(structureCombo, "3," + row);
            row += 2;
            mainBuilder.addLabel("Filter", "1," + row);
            mainBuilder.add(maxAgePanel, "3," + row);
            row += 2;
        }

        mainBuilder.addLabel("Max. &Depth", "1," + row).setLabelFor(maxDepthSpinner);
        mainBuilder.add(maxDepthBuilder.getPanel(), "3," + row);
        row += 2;

        mainBuilder.addLabel("&Restrict to", "1," + row).setLabelFor(restrictCombo);
        mainBuilder.add(restrictCombo, "3," + row);
        row += 2;

        if (!feed) {
            mainBuilder.addLabel("Referrer", "1," + row).setLabelFor(referrerText);
            mainBuilder.add(referrerText, "3," + row);
            row += 2;
        }

        mainBuilder.addLabel("Cache", "1," + row);
        mainBuilder.add(cacheCheck, "3," + row);
        row += 2;

        mainBuilder.addSeparator("Schedule", "1," + row + ",3,1");
        row += 2;

        mainBuilder.addLabel("&Schedule", "1," + row).setLabelFor(scheduleCombo);

        PanelBuilder scheduleBuilder = new PanelBuilder(new FormLayout("pref,left:pref:grow", "pref"));
        scheduleBuilder.add(scheduleCombo, "1,1");
        scheduleBuilder.add(schedulePanel, "2,1");
        mainBuilder.add(scheduleBuilder.getPanel(), "3," + row);

        FormLayout imagesLayout = new FormLayout("pref, pref, pref, 18dlu, pref, pref, pref",
                                                 "pref, 4dlu, pref, 4dlu, pref, 2dlu, pref, 2dlu, pref");
        PanelBuilder imagesBuilder = new PanelBuilder(imagesLayout);

        imagesBuilder.add(altTextCheck, "1,1,7,1");
        imagesBuilder.add(embeddedBppCombo, "1,3,3,1");
        imagesBuilder.add(embeddedWidthCheck, "1,5");
        imagesBuilder.add(embeddedWidthText, "2,5");
        JLabel embeddedWidthLabel = imagesBuilder.addLabel(" pixels", "3,5");
        imagesBuilder.add(embeddedHeightCheck, "1,7");
        imagesBuilder.add(embeddedHeightText, "2,7");
        JLabel embeddedHeightLabel = imagesBuilder.addLabel(" pixels", "3,7");
        imagesBuilder.add(alternateCheck, "1,9,7,1");

        imagesBuilder.add(standaloneBppCombo, "5,3,3,1");
        imagesBuilder.add(standaloneWidthCheck, "5,5");
        imagesBuilder.add(standaloneWidthText, "6,5");
        JLabel standaloneWidthLabel = imagesBuilder.addLabel(" pixels", "7,5");
        imagesBuilder.add(standaloneHeightCheck, "5,7");
        imagesBuilder.add(standaloneHeightText, "6,7");
        JLabel standaloneHeightLabel = imagesBuilder.addLabel(" pixels", "7,7");

        embeddedWidthListener = new ImageSizeListener(embeddedWidthCheck, embeddedWidthText, embeddedWidthLabel);
        embeddedWidthCheck.addChangeListener(embeddedWidthListener);
        embeddedHeightListener = new ImageSizeListener(embeddedHeightCheck, embeddedHeightText, embeddedHeightLabel);
        embeddedHeightCheck.addChangeListener(embeddedHeightListener);
        embeddedBppListener = new BPPListener(embeddedBppCombo,
                                              new ImageSizeListener[] { embeddedWidthListener, embeddedHeightListener },
                                              alternateCheck);
        embeddedBppCombo.addItemListener(embeddedBppListener);
        embeddedBppCombo.addItemListener(alternateListener);
        standaloneWidthListener = new ImageSizeListener(standaloneWidthCheck, standaloneWidthText,
                                                        standaloneWidthLabel);
        standaloneWidthCheck.addChangeListener(standaloneWidthListener);
        standaloneHeightListener = new ImageSizeListener(standaloneHeightCheck, standaloneHeightText,
                                                         standaloneHeightLabel);
        standaloneHeightCheck.addChangeListener(standaloneHeightListener);
        standaloneBppListener = new BPPListener(standaloneBppCombo,
                                                new ImageSizeListener[] {
                                                    standaloneWidthListener, standaloneHeightListener
                                                });
        standaloneBppCombo.addItemListener(standaloneBppListener);
        standaloneBppCombo.addItemListener(alternateListener);

        PanelBuilder linksBuilder = new PanelBuilder(new FormLayout("pref, 6dlu, pref, 4dlu, pref, 4dlu, 20dlu",
                                                                    "pref, 4dlu, pref"));
        linksBuilder.addLabel("Normal Links", "1,1");
        linksBuilder.add(linksCombo, "3,1");
        linksBuilder.add(linkColorText, "5,1");
        linkColorButton = new JButton(selectLinkColorAction);
        GUIUtil.makeEqualHeight(linkColorText, linkColorButton);
        linksBuilder.add(linkColorButton, "7,1");
        linksBuilder.addLabel("Unresolved Links", "1,3");
        linksBuilder.add(unresolvedLinksCombo, "3,3");
        linksBuilder.add(unresolvedLinkColorText, "5,3");
        unresolvedLinkColorButton = new JButton(selectUnresolvedLinkColorAction);
        linksBuilder.add(unresolvedLinkColorButton, "7,3");
        GUIUtil.makeEqualHeight(unresolvedLinkColorText, unresolvedLinkColorButton);

        PanelBuilder encodingBuilder = new PanelBuilder(new FormLayout("pref, 6dlu, pref",
                                                                       "pref, 4dlu, pref, 4dlu, pref"));
        encodingBuilder.addLabel("Input encoding", "1,1");
        encodingBuilder.add(inputEncodingCombo, "3,1");
        encodingBuilder.addLabel("Output encoding", "1,3");
        encodingBuilder.add(outputEncodingCombo, "3,3");

        FormLayout formatLayout = new FormLayout("left:pref:grow",
                                                 "pref, 4dlu, pref, 7dlu, " + "pref, 4dlu, pref, 7dlu, " +
                                                 "pref, 4dlu, pref");
        PanelBuilder formatBuilder = new PanelBuilder(formatLayout);
        formatBuilder.setBorder(Borders.TABBED_DIALOG_BORDER);
        formatBuilder.addSeparator("Images", "1,1,fill,center");
        formatBuilder.add(imagesBuilder.getPanel(), "1,3");
        formatBuilder.addSeparator("Links", "1,5,fill,center");
        formatBuilder.add(linksBuilder.getPanel(), "1,7");
        formatBuilder.addSeparator("Character Encoding", "1,9,fill,center");
        formatBuilder.add(encodingBuilder.getPanel(), "1,11");

        FormLayout patternLayout = new FormLayout("pref:grow", "pref, 4dlu, pref, 7dlu, pref, 4dlu, pref");
        PanelBuilder patternBuilder = new PanelBuilder(patternLayout);
        patternBuilder.setBorder(Borders.TABBED_DIALOG_BORDER);
        patternBuilder.addSeparator("URL Inclusion Patterns", "1,1");
        inclusionPanel = new PatternPanel(this);
        patternBuilder.add(inclusionPanel, "1,3");
        patternBuilder.addSeparator("URL Exclusion Patterns", "1,5");
        exclusionPanel = new PatternPanel(this);
        patternBuilder.add(exclusionPanel, "1,7");

        FormLayout advancedLayout = new FormLayout("pref, 6dlu, left:pref:grow",
                                                   "pref, 4dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 7dlu, " +
                                                   "pref, 4dlu, pref, 4dlu, pref, 7dlu, " +
                                                   "pref, 4dlu, pref, 4dlu, pref");
        PanelBuilder advancedBuilder = new PanelBuilder(advancedLayout);
        advancedBuilder.setBorder(Borders.TABBED_DIALOG_BORDER);
        advancedBuilder.addSeparator("Miscellaneous", "1,1,3,1");
        advancedBuilder.add(includeURIInfoCheck, "1,3,3,1");
        advancedBuilder.add(backupCheck, "1,5,3,1");
        advancedBuilder.add(removeAccentsCheck, "1,7,3,1");
        advancedBuilder.add(hiresCheck, "1,9,3,1");
        advancedBuilder.addSeparator("Identification", "1,11,3,1");
        advancedBuilder.addLabel("User Agent", "1,13");
        advancedBuilder.add(userAgentBuilder.getPanel(), "3,13");
        advancedBuilder.addLabel("Default: \"" + VersionInfo.userAgent() + "\".", "3,15");
        advancedBuilder.addSeparator("Custom PDB filename", "1,17,3,1");
        advancedBuilder.addLabel("Filename", "1,19");
        advancedBuilder.add(filenameText, "3,19");
        advancedBuilder.addLabel("(The document name is used by default.)", "3,21");

        tabPane.setBorder(Borders.createEmptyBorder("4dlu, 7dlu, 0dlu, 7dlu"));
        tabPane.add("Main", mainBuilder.getPanel());
        tabPane.setMnemonicAt(0, 'M');
        tabPane.add("Formatting", formatBuilder.getPanel());
        tabPane.setMnemonicAt(1, 'F');
        tabPane.add("Patterns", patternBuilder.getPanel());
        tabPane.setMnemonicAt(2, 'P');
        tabPane.add("Advanced", advancedBuilder.getPanel());
        tabPane.setMnemonicAt(3, 'A');

        initDialog(banner, tabPane);

        if (editingDefault) {
            categoryText.requestFocus();
        } else {
            nameText.requestFocus();
        }

        nameChanged();
    }

    private void initTemplates(JXL jxl) {
        Template[] templates = jxl.getTemplates();
        List templateList = new ArrayList();
        templateList.add("_default");
        for (int i = 0; i < templates.length; i++) {
            String id = templates[i].getID();
            if (!id.equals("_default")) {
                templateList.add(id);
            }
        }
        templateCombo.setModel(new DefaultComboBoxModel(templateList.toArray()));
    }

    private void initValues(Document document) {
        nameText.setText(document.getRawName());
        uriText.setText(document.getRawUri());
        restrictCombo.setSelectedItem(document.getRestrict());
        maxDepthSpinner.setValue(new Integer(document.getLinkDepth()));
        if (document.getReferrer() != null) {
            referrerText.setText(document.getReferrer());
        }

        ContextAdapter ctx = new ContextAdapter(document.getElement());

        List categoryList = new ArrayList();
        for (Iterator it = ctx.iterate("category"); it.hasNext();) {
            categoryList.add((String) it.next());
        }
        categories = (String[]) categoryList.toArray(new String[categoryList.size()]);
        if (categories.length > 0) {
            categoryText.setText(categories[0]);
        }
        categoryButton.setToolTipText("" + Arrays.asList(categories));

        String template = document.getTemplateID();
        templateCombo.setSelectedItem(template);

        if (document instanceof Feed) {
            Feed feed = (Feed) document;
            if (feed.isUsePageStructure()) {
                structureCombo.setSelectedIndex(0);
            } else if (feed.isUseListStructure()) {
                structureCombo.setSelectedIndex(1);
            } else {
                structureCombo.setSelectedIndex(2);
            }
            if (feed.getMaxAge() != -1) {
                maxAgeCheck.setSelected(true);
                maxAgeSpinner.setValue(new Integer(feed.getMaxAge()));
            }
        }

        Pointer p = ctx.getPointer("schedule/*");
        if (p != null) {
            Element element = (Element) p.getNode();
            String s = element.getNodeName();
            if (s.equals("cron")) {
                scheduleCombo.setSelectedItem("cron");
            } else {
                scheduleCombo.setSelectedItem(s);
            }
            if (s.equals("hourly")) {
                minuteSpinner.setValue(new Integer(Integer.parseInt(element.getAttribute("minute"))));
            } else if (s.equals("daily")) {
                Calendar cal = Calendar.getInstance();
                cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(element.getAttribute("hour")));
                cal.set(Calendar.MINUTE, Integer.parseInt(element.getAttribute("minute")));
                dailyTimeSpinner.setValue(cal.getTime());
            } else if (s.equals("weekly")) {
                String day = element.getAttribute("day");
                day = day.substring(0, 1).toUpperCase() + day.substring(1);
                dayCombo.setSelectedItem(day);

                Calendar cal = Calendar.getInstance();
                cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(element.getAttribute("hour")));
                cal.set(Calendar.MINUTE, Integer.parseInt(element.getAttribute("minute")));
                weeklyTimeSpinner.setValue(cal.getTime());
            } else if (s.equals("monthly")) {
                Calendar cal = Calendar.getInstance();
                String day = element.getAttribute("day");
                if (day.equals("last")) {
                    dayOfMonthCombo.setSelectedIndex(31);
                } else {
                    dayOfMonthCombo.setSelectedIndex(Integer.parseInt(day) - 1);
                }
                cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(element.getAttribute("hour")));
                cal.set(Calendar.MINUTE, Integer.parseInt(element.getAttribute("minute")));
                monthlyTimeSpinner.setValue(cal.getTime());
            } else if (s.equals("cron")) {
                cronText.setText(element.getFirstChild().getNodeValue());
            }
        }

        altTextCheck.setSelected(document.isIncludeAltText());
        p = ctx.getPointer("images/embedded");
        if (p != null) {
            Element embedded = (Element) p.getNode();
            setBppCombo(embeddedBppCombo, Integer.parseInt(embedded.getAttribute("bpp")));
            String width = embedded.getAttribute("maxWidth");
            embeddedWidthCheck.setSelected(width.length() > 0);
            embeddedWidthText.setText(width);
            String height = embedded.getAttribute("maxHeight");
            embeddedHeightText.setText(height);
            embeddedHeightCheck.setSelected(height.length() > 0);
            alternateCheck.setSelected(embedded.getAttribute("alternate").equals("yes"));
        }
        embeddedBppListener.itemStateChanged(null);
        p = ctx.getPointer("images/standalone");
        if (p != null) {
            Element standalone = (Element) p.getNode();
            setBppCombo(standaloneBppCombo, Integer.parseInt(standalone.getAttribute("bpp")));
            String width = standalone.getAttribute("maxWidth");
            standaloneWidthCheck.setSelected(width.length() > 0);
            standaloneWidthText.setText(width);
            String height = standalone.getAttribute("maxHeight");
            standaloneHeightText.setText(height);
            standaloneHeightCheck.setSelected(height.length() > 0);
        }
        if (ctx.getValue("@linkColor") != null) {
            linksCombo.setSelectedIndex(1);
            linkColorText.setText(ctx.getValue("@linkColor").toString());
        }
        if (document.isRemoveUnresolvedLinks()) {
            unresolvedLinksCombo.setSelectedIndex(1);
        } else if (ctx.getValue("@unresolvedLinkColor") != null) {
            unresolvedLinksCombo.setSelectedIndex(2);
            unresolvedLinkColorText.setText(ctx.getValue("@unresolvedLinkColor").toString());
        }

        inputEncodingCombo.setSelectedItem(document.getInputEncoding());
        outputEncodingCombo.setSelectedItem(document.getOutputEncoding());

        Iterator it = ctx.iterate("uriPatterns/include");
        while (it.hasNext()) {
            inclusionPanel.addPattern((String) it.next());
        }
        it = ctx.iterate("uriPatterns/exclude");
        while (it.hasNext()) {
            exclusionPanel.addPattern((String) it.next());
        }

        includeURIInfoCheck.setSelected(document.isIncludeURIInfo());
        backupCheck.setSelected(document.isSetBackupBit());
        removeAccentsCheck.setSelected(document.isRemoveAccents());
        cacheCheck.setSelected(document.isUseHTTPCache());
        hiresCheck.setSelected(document.isUseHiresMargins());

        if (document.getUserAgent() != null) {
            userAgentText.setText(document.getUserAgent());
        }

        if (document.getRawFilename() != null) {
            filenameText.setText(document.getRawFilename());
        }

        standaloneBppListener.itemStateChanged(null);
        alternateListener.itemStateChanged(null);
        linksListener.itemStateChanged(null);
        unresolvedLinksListener.itemStateChanged(null);
        maxAgeListener.stateChanged(null);
    }

    private void nameChanged() {
        String s = nameText.getText().trim();
        if (s.length() == 0) {
            setTitle("<Untitled>");
        } else {
            setTitle(s);
        }
        if (s.length() > 31) {
            nameWarningLabel.setVisible(true);
            nameWarningLabel.setText("(" + s.length() + ")");
        } else {
            nameWarningLabel.setVisible(false);
        }
    }

    private void populate(Element element) {
        org.w3c.dom.Document dom = element.getOwnerDocument();
        Element name = dom.createElement("name");
        name.appendChild(dom.createTextNode(nameText.getText()));
        element.appendChild(name);

        if (filenameText.getText().length() > 0) {
            Element filename = dom.createElement("filename");
            filename.appendChild(dom.createTextNode(filenameText.getText()));
            element.appendChild(filename);
        }

        Element uri = dom.createElement("uri");
        element.appendChild(uri);
        uri.appendChild(dom.createTextNode(uriText.getText()));

        int depth = ((Integer) maxDepthSpinner.getValue()).intValue();
        if (depth > 0) {
            uri.setAttribute("maxDepth", String.valueOf(depth));
        }
    if (referrerText.getText().length() > 0) {
      element.setAttribute("referrer", referrerText.getText());
    }

        String restrict = (String) restrictCombo.getSelectedItem();
        if (!restrict.equals("none")) {
            uri.setAttribute("restrict", restrict);
        }

        if (element.getNodeName().equals("feed")) {
            populateFeedStructure(element);
        }

        String template = (String) templateCombo.getSelectedItem();
        if (!template.equals("_default")) {
            element.setAttribute("template", template);
        }

        String[] inclusionPatterns = inclusionPanel.getPatterns();
    String[] exclusionPatterns = exclusionPanel.getPatterns();
        if (inclusionPatterns.length > 0 || exclusionPatterns.length>0) {
            Element uriPatterns = dom.createElement("uriPatterns");
            element.appendChild(uriPatterns);
            for (int i = 0; i < inclusionPatterns.length; i++) {
                Element pattern = dom.createElement("include");
                pattern.appendChild(dom.createTextNode(inclusionPatterns[i]));
                uriPatterns.appendChild(pattern);
            }
      for (int i = 0; i < exclusionPatterns.length; i++) {
        Element pattern = dom.createElement("exclude");
        pattern.appendChild(dom.createTextNode(exclusionPatterns[i]));
        uriPatterns.appendChild(pattern);
      }
        }
        if (!altTextCheck.isSelected() || (embeddedBppCombo.getSelectedIndex() > 0) ||
                    (standaloneBppCombo.getSelectedIndex() > 0)) {
            Element images = dom.createElement("images");
            element.appendChild(images);
            if (!altTextCheck.isSelected()) {
                images.setAttribute("includeAltText", "no");
            }
            if (embeddedBppCombo.getSelectedIndex() > 0) {
                Element embedded = dom.createElement("embedded");
                populateEmbedded(embedded);
                images.appendChild(embedded);
            }
            if (standaloneBppCombo.getSelectedIndex() > 0) {
                Element standalone = dom.createElement("standalone");
                populateStandalone(standalone);
                images.appendChild(standalone);
            }
        }

        for (int i = 0; i < categories.length; i++) {
            Element category = dom.createElement("category");
            category.appendChild(dom.createTextNode(categories[i]));
            element.appendChild(category);
        }

        String s = (String) scheduleCombo.getSelectedItem();
        if (!s.equals("none")) {
            Element schedule = dom.createElement("schedule");
            element.appendChild(schedule);
            populateSchedule(dom, schedule);
        }

        populateAttributes(element);
    }

    private void populateAttributes(Element element) {
        if (linksCombo.getSelectedIndex() == 1) {
            element.setAttribute("linkColor", linkColorText.getText());
        } else {
            element.removeAttribute("linkColor");
        }
        if (unresolvedLinksCombo.getSelectedIndex() == 1) {
            element.setAttribute("removeUnresolvedLinks", "yes");
        } else {
            element.removeAttribute("removeUnresolvedLinks");
        }
        if (unresolvedLinksCombo.getSelectedIndex() == 2) {
            element.setAttribute("unresolvedLinkColor", unresolvedLinkColorText.getText());
        } else {
            element.removeAttribute("unresolvedLinkColor");
        }

        if (inputEncodingCombo.getSelectedIndex() > 0) {
            element.setAttribute("inputEncoding", (String) inputEncodingCombo.getSelectedItem());
        } else {
            element.removeAttribute("inputEncoding");
        }
        if (outputEncodingCombo.getSelectedIndex() > 0) {
            element.setAttribute("outputEncoding", (String) outputEncodingCombo.getSelectedItem());
        } else {
            element.removeAttribute("outputEncoding");
        }

        if (!includeURIInfoCheck.isSelected()) {
            element.setAttribute("includeUriInfo", "no");
        } else {
            element.removeAttribute("includeUriInfo");
        }

        if (!cacheCheck.isSelected()) {
            element.setAttribute("cache", "no");
        } else {
            element.removeAttribute("cache");
        }
        if (hiresCheck.isSelected()) {
            element.setAttribute("margins", "hires");
        } else {
            element.removeAttribute("margins");
        }

        if (backupCheck.isSelected()) {
            element.setAttribute("backup", "yes");
        } else {
            element.removeAttribute("backup");
        }

        if (removeAccentsCheck.isSelected()) {
            element.setAttribute("removeAccents", "yes");
        } else {
            element.removeAttribute("removeAccents");
        }

        if (userAgentText.getText().length() > 0) {
            element.setAttribute("userAgent", userAgentText.getText());
        } else {
            element.removeAttribute("userAgent");
        }
    }

    private void populateEmbedded(Element embedded) {
        int idx = embeddedBppCombo.getSelectedIndex();
        int bpp = 0;
        if ((idx == 1) || (idx == 2)) {
            bpp = idx;
        } else if (idx == 3) {
            bpp = 4;
        } else if (idx == 4) {
            bpp = 8;
        } else if (idx == 5) {
            bpp = 16;
        }
        embedded.setAttribute("bpp", String.valueOf(bpp));

        if (embeddedWidthCheck.isSelected()) {
            embedded.setAttribute("maxWidth", embeddedWidthText.getText());
        } else {
            embedded.removeAttribute("maxWidth");
        }
        if (embeddedHeightCheck.isSelected()) {
            embedded.setAttribute("maxHeight", embeddedHeightText.getText());
        } else {
            embedded.removeAttribute("maxHeight");
        }
        if ((standaloneBppCombo.getSelectedIndex() > 0) && alternateCheck.isSelected()) {
            embedded.setAttribute("alternate", "yes");
        } else {
            embedded.removeAttribute("alternate");
        }
    }

    private void populateFeedStructure(Element element) {
        String structure = null;
        switch (structureCombo.getSelectedIndex()) {
        case 0:
            structure = "pages";
            break;
        case 1:
            structure = "list";
            break;
        case 2:
            structure = "links";
            break;
        }
        element.setAttribute("structure", structure);
        if (maxAgeCheck.isSelected()) {
            element.setAttribute("maxAge", maxAgeSpinner.getValue().toString());
        } else {
            element.removeAttribute("maxAge");
        }
    }

    private void populateSchedule(org.w3c.dom.Document doc, Element schedule) {
        String s = (String) scheduleCombo.getSelectedItem();
        if (s.equals("hourly")) {
            Element hourly = doc.createElement("hourly");
            hourly.setAttribute("minute", String.valueOf(minuteSpinner.getValue()));
            schedule.appendChild(hourly);
        } else if (s.equals("daily")) {
            Element daily = doc.createElement("daily");
            Calendar cal = Calendar.getInstance();
            cal.setTime((Date) dailyTimeSpinner.getValue());
            daily.setAttribute("hour", String.valueOf(cal.get(Calendar.HOUR_OF_DAY)));
            daily.setAttribute("minute", String.valueOf(cal.get(Calendar.MINUTE)));
            schedule.appendChild(daily);
        } else if (s.equals("weekly")) {
            Element weekly = doc.createElement("weekly");
            String day = (String) dayCombo.getSelectedItem();
            Calendar cal = Calendar.getInstance();
            cal.setTime((Date) weeklyTimeSpinner.getValue());
            weekly.setAttribute("day", day.toLowerCase());
            weekly.setAttribute("hour", String.valueOf(cal.get(Calendar.HOUR_OF_DAY)));
            weekly.setAttribute("minute", String.valueOf(cal.get(Calendar.MINUTE)));
            schedule.appendChild(weekly);
        } else if (s.equals("monthly")) {
            Element monthly = doc.createElement("monthly");
            int i = dayOfMonthCombo.getSelectedIndex() + 1;
            String day = ((i == 32) ? "last" : String.valueOf(i));
            Calendar cal = Calendar.getInstance();
            cal.setTime((Date) monthlyTimeSpinner.getValue());
            monthly.setAttribute("day", day);
            monthly.setAttribute("hour", String.valueOf(cal.get(Calendar.HOUR_OF_DAY)));
            monthly.setAttribute("minute", String.valueOf(cal.get(Calendar.MINUTE)));
            schedule.appendChild(monthly);
        } else if (s.equals("cron")) {
            Element cron = doc.createElement("cron");
            cron.appendChild(doc.createTextNode(cronText.getText()));
            schedule.appendChild(cron);
        }
    }

    private void populateStandalone(Element standalone) {
        int idx = standaloneBppCombo.getSelectedIndex();
        int bpp = 0;
        if ((idx == 1) || (idx == 2)) {
            bpp = idx;
        } else if (idx == 3) {
            bpp = 4;
        } else if (idx == 4) {
            bpp = 8;
        } else if (idx == 5) {
            bpp = 16;
        }
        standalone.setAttribute("bpp", String.valueOf(bpp));

        if (standaloneWidthCheck.isSelected()) {
            standalone.setAttribute("maxWidth", standaloneWidthText.getText());
        } else {
            standalone.removeAttribute("maxWidth");
        }
        if (standaloneHeightCheck.isSelected()) {
            standalone.setAttribute("maxHeight", standaloneHeightText.getText());
        } else {
            standalone.removeAttribute("maxHeight");
        }
    }

    private void update(Document document) {
        Element element = document.getElement();
        org.w3c.dom.Document dom = element.getOwnerDocument();
        ContextAdapter ctx = new ContextAdapter(JXPathContext.newContext(element));
        if (!editingDefault) {
            ctx.setValue("name", nameText.getText());
        }
        ctx.removeAll("category");

        Pointer p = ctx.getPointer("description|schedule|transform|autoBookmark");
        for (int i = 0; i < categories.length; i++) {
            Element category = (Element) dom.createElement("category");
            category.appendChild(dom.createTextNode(categories[i]));
            if (p != null) {
                element.insertBefore(category, (Element) p.getNode());
            } else {
                element.appendChild(category);
            }
        }

        if (!editingDefault) {
            String template = (String) templateCombo.getSelectedItem();
            if (template.equals("_default")) {
                ctx.remove("@template");
            } else {
                ctx.setValue("@template", template);
            }
        }

        if (!editingDefault) {
            ctx.setValue("uri", uriText.getText());
        }

        int depth = ((Integer) maxDepthSpinner.getValue()).intValue();
        if (depth > 0) {
            ctx.setValue("uri/@maxDepth", String.valueOf(depth));
        } else {
            ctx.remove("uri/@maxDepth");
        }
        document.resetStartingURI();

        String restrict = (String) restrictCombo.getSelectedItem();
        if (restrict.equals("none")) {
            ctx.remove("uri/@restrict");
        } else {
            ctx.setValue("uri/@restrict", restrict);
        }
    if (referrerText.getText().length() > 0) {
      ctx.setValue("uri/@referrer", referrerText.getText());
    } else {
      ctx.remove("uri/@referrer");
    }

        if (element.getNodeName().equals("feed")) {
            populateFeedStructure(element);
        }

        String s = (String) scheduleCombo.getSelectedItem();
        if (s.equals("none")) {
            ctx.removeAll("schedule");
        } else {
            p = ctx.getPointer("schedule");

            Element schedule;
            if (p != null) {
                schedule = (Element) p.getNode();
                ctx.removeAll("schedule/*");
            } else {
                schedule = dom.createElement("schedule");
                p = ctx.getPointer("transform|autoBookmark");
                if (p != null) {
                    element.insertBefore(schedule, (Element) p.getNode());
                } else {
                    element.appendChild(schedule);
                }
            }

            populateSchedule(dom, schedule);
        }

        if (altTextCheck.isSelected() && (embeddedBppCombo.getSelectedIndex() == 0) &&
                    (standaloneBppCombo.getSelectedIndex() == 0)) {
            ctx.removeAll("images");
        }

        if (altTextCheck.isSelected()) {
            ctx.removeAll("images/@includeAltText");
        } else {
            p = ctx.getPointer("images");
            if (p != null) {
                Element images = (Element) p.getNode();
                images.setAttribute("includeAltText", "no");
            } else {
                Element images = dom.createElement("images");
                images.setAttribute("includeAltText", "no");
                p = ctx.getPointer("category|description|schedule|transform|autoBookmark");
                if (p != null) {
                    element.insertBefore(images, (Element) p.getNode());
                } else {
                    element.appendChild(images);
                }
            }
        }

        if (embeddedBppCombo.getSelectedIndex() == 0) {
            ctx.removeAll("images/embedded");
        } else {
            p = ctx.getPointer("images/embedded");
            Element embedded;
            if (p != null) {
                embedded = (Element) p.getNode();
            } else {
                embedded = dom.createElement("embedded");
                p = ctx.getPointer("images");
                if (p != null) {
                    Element images = (Element) p.getNode();
                    p = ctx.getPointer("images/standalone");
                    if (p != null) {
                        Element standalone = (Element) p.getNode();
                        images.insertBefore(embedded, standalone);
                    } else {
                        images.appendChild(embedded);
                    }
                } else {
                    Element images = dom.createElement("images");
                    p = ctx.getPointer("category|description|schedule|transform|autoBookmark");
                    if (p != null) {
                        element.insertBefore(images, (Element) p.getNode());
                    } else {
                        element.appendChild(images);
                    }
                    images.appendChild(embedded);
                }
            }
            populateEmbedded(embedded);
        }
        if (standaloneBppCombo.getSelectedIndex() == 0) {
            ctx.removeAll("images/standalone");
        } else {
            p = ctx.getPointer("images/standalone");
            Element standalone;
            if (p != null) {
                standalone = (Element) p.getNode();
            } else {
                standalone = dom.createElement("standalone");
                p = ctx.getPointer("images");
                if (p != null) {
                    Element images = (Element) p.getNode();
                    images.appendChild(standalone);
                } else {
                    Element images = dom.createElement("images");
                    p = ctx.getPointer("category|description|schedule|transform|autoBookmark");
                    if (p != null) {
                        element.insertBefore(images, (Element) p.getNode());
                    } else {
                        element.appendChild(images);
                    }
                    images.appendChild(standalone);
                }
            }
            populateStandalone(standalone);
        }

        String[] inclusionPatterns = inclusionPanel.getPatterns();
    String[] exclusionPatterns = exclusionPanel.getPatterns();
        if (inclusionPatterns.length > 0 || exclusionPatterns.length > 0) {
            Element uriPatterns;
            p = ctx.getPointer("uriPatterns");
            if (p != null) {
                uriPatterns = (Element) p.getNode();
            } else {
                p = ctx.getPointer("images|category|description|schedule|transform|autoBookmark");
                uriPatterns = dom.createElement("uriPatterns");
                if (p != null) {
                    element.insertBefore(uriPatterns, (Element) p.getNode());
                } else {
                    element.appendChild(uriPatterns);
                }
            }
            ctx.removeAll("uriPatterns/*");
            for (int i = 0; i < inclusionPatterns.length; i++) {
                Element include = dom.createElement("include");
                include.appendChild(dom.createTextNode(inclusionPatterns[i]));
                uriPatterns.appendChild(include);
            }
      for (int i = 0; i < exclusionPatterns.length; i++) {
        Element exclude = dom.createElement("exclude");
        exclude.appendChild(dom.createTextNode(exclusionPatterns[i]));
        uriPatterns.appendChild(exclude);
      }
        } else {
            ctx.remove("uriPatterns");
        }
        ctx.remove("filename");
        if (filenameText.getText().length() > 0) {
            Element filename = dom.createElement("filename");
            filename.appendChild(dom.createTextNode(filenameText.getText()));
            element.insertBefore(filename, (Element) ctx.getPointer("uri").getNode());
        }

        populateAttributes(element);

        document.configureParentTemplate();
    }

    public static class Result {
        private boolean convert;
        private boolean ok;

        Result(boolean ok, boolean convert) {
            this.ok = ok;
            this.convert = convert;
        }

        public boolean isConvert() {
            return convert;
        }

        public boolean isOk() {
            return ok;
        }
    }

    private class AlternateListener implements ItemListener {
        public void itemStateChanged(ItemEvent e) {
            alternateCheck.setEnabled((embeddedBppCombo.getSelectedIndex() > 0) &&
                                      (standaloneBppCombo.getSelectedIndex() > 0));
        }
    }

    private class BPPListener implements ItemListener {
        private JCheckBox checkBox;
        private JComboBox comboBox;
        private ImageSizeListener[] listeners;

        BPPListener(JComboBox comboBox, ImageSizeListener[] listeners, JCheckBox checkBox) {
            this.comboBox = comboBox;
            this.listeners = listeners;
        }

        BPPListener(JComboBox comboBox, ImageSizeListener[] listeners) {
            this(comboBox, listeners, null);
        }

        public void itemStateChanged(ItemEvent e) {
            boolean b = comboBox.getSelectedIndex() > 0;
            for (int i = 0; i < listeners.length; i++) {
                listeners[i].checkBox.setEnabled(b);
                listeners[i].textField.setEnabled(b);
                listeners[i].label.setEnabled(b);
                if (b) {
                    listeners[i].stateChanged(null);
                }
            }
        }
    }

    private class CategoryAction extends AbstractAction {
        CategoryAction() {
            super("...");
            putValue(Action.SHORT_DESCRIPTION, "Edit Categories");
        }

        public void actionPerformed(ActionEvent e) {
            String s = categoryText.getText();
            if (s.length() > 0) {
                if (categories.length > 0) {
                    categories[0] = s;
                } else {
                    categories = new String[] { s };
                }
            }

            CategoryDialog dlg = new CategoryDialog(DocumentDialog.this, categories);
            dlg.setLocationRelativeTo(categoryButton);
            dlg.show();
            if (!dlg.isCancelled()) {
                categories = dlg.getCategories();
                if (categories.length > 0) {
                    categoryText.setText(categories[0]);
                } else {
                    categoryText.setText("");
                }
                categoryButton.setToolTipText("" + Arrays.asList(categories));
            }
        }
    }

    private class ImageSizeListener implements ChangeListener {
        JCheckBox checkBox;
        JLabel label;
        JTextField textField;

        ImageSizeListener(JCheckBox checkBox, JTextField textField, JLabel label) {
            this.checkBox = checkBox;
            this.textField = textField;
            this.label = label;
        }

        public void stateChanged(ChangeEvent e) {
            textField.setEnabled(checkBox.isSelected());
            label.setEnabled(checkBox.isSelected());
        }
    }

    private static class LinkColorPreview extends JLabel implements ChangeListener {
        private JColorChooser colorChooser;

        public LinkColorPreview(JColorChooser colorChooser) {
            this.colorChooser = colorChooser;
            setText(" The quick brown fox jumps over the lazy dog ");
            setFont(getFont().deriveFont(Font.BOLD));
            setOpaque(true);
            setBackground(Color.WHITE);
            setForeground(colorChooser.getColor());
            setBorder(new LineBorder(Color.BLACK, 1));
            colorChooser.getSelectionModel().addChangeListener(this);
        }

        public Dimension getPreferredSize() {
            Dimension d = super.getPreferredSize();
            d.height += 10;
            return d;
        }

        public void stateChanged(ChangeEvent e) {
            setForeground(colorChooser.getColor());
            repaint();
        }
    }

    private class LinksListener implements ItemListener {
        public void itemStateChanged(ItemEvent e) {
            boolean b = linksCombo.getSelectedIndex() == 1;
            linkColorText.setEnabled(b);
            linkColorButton.setEnabled(b);
        }
    }

    private class MaxAgeListener implements ChangeListener {
        public void stateChanged(ChangeEvent e) {
            boolean b = maxAgeCheck.isSelected();
            maxAgeSpinner.setEnabled(b);
            maxAgeLabel.setEnabled(b);
        }
    }

    private class NameListener implements DocumentListener {
        public void changedUpdate(DocumentEvent e) {
            nameChanged();
        }

        public void insertUpdate(DocumentEvent e) {
            nameChanged();
        }

        public void removeUpdate(DocumentEvent e) {
            nameChanged();
        }
    }

    private class ScheduleListener implements ItemListener {
        public void itemStateChanged(ItemEvent e) {
            scheduleLayout.show(schedulePanel, (String) scheduleCombo.getSelectedItem());
        }
    }

    private class SelectColorAction extends AbstractAction {
        private JTextField textField;

        SelectColorAction(JTextField textField) {
            super("...");
            this.textField = textField;
        }

        public void actionPerformed(ActionEvent e) {
            Color color = ColorUtil.getColor(textField.getText());
            if (color == null) {
                color = Color.BLUE;
            }
            final JColorChooser colorChooser = new JColorChooser(color);
            AbstractColorChooserPanel[] panels = colorChooser.getChooserPanels();
            colorChooser.setChooserPanels(new AbstractColorChooserPanel[] { panels[2], panels[1] });
            colorChooser.setPreviewPanel(new LinkColorPreview(colorChooser));
            colorChooser.setBorder(Borders.DIALOG_BORDER);
            ActionListener okListener = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    textField.setText(ColorUtil.toHex(colorChooser.getColor()));
                }
            };
            JDialog dialog = JColorChooser.createDialog(DocumentDialog.this, "Select Link Color", true, colorChooser,
                                                        okListener, null);
            dialog.setResizable(false);
            dialog.show();
        }
    }

    private class SelectUserAgentAction extends AbstractAction {
        SelectUserAgentAction() {
            super("...");
        }

        public void actionPerformed(ActionEvent e) {
            UserAgentDialog dlg = new UserAgentDialog(DocumentDialog.this, userAgentText.getText());
            dlg.setLocationRelativeTo(DocumentDialog.this);
            dlg.show();
            if (!dlg.isCancelled()) {
                userAgentText.setText(dlg.getUserAgent());
            }
        }
    }

    private class UnresolvedLinksListener implements ItemListener {
        public void itemStateChanged(ItemEvent e) {
            boolean b = unresolvedLinksCombo.getSelectedIndex() == 2;
            unresolvedLinkColorText.setEnabled(b);
            unresolvedLinkColorButton.setEnabled(b);
        }
    }
}
TOP

Related Classes of net.sf.jpluck.apps.jpluckx.ui.DocumentDialog

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.