/* * WPCleaner: A tool to help on Wikipedia maintenance tasks. * Copyright (C) 2013 Nicolas Vervelle * * See README.txt file for licensing information. */ package org.wikipediacleaner.gui.swing; import java.awt.Color; import java.awt.Dimension; import java.awt.Frame; import java.awt.GridBagConstraints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.beans.EventHandler; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.Callable; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JTextField; import javax.swing.JToggleButton; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import org.wikipediacleaner.api.APIFactory; import org.wikipediacleaner.api.MediaWikiController; import org.wikipediacleaner.api.check.CheckError; import org.wikipediacleaner.api.check.CheckErrorPage; import org.wikipediacleaner.api.check.CheckWiki; import org.wikipediacleaner.api.check.algorithm.CheckErrorAlgorithm; import org.wikipediacleaner.api.constants.EnumWikipedia; import org.wikipediacleaner.api.constants.WPCConfigurationString; import org.wikipediacleaner.api.constants.WPCConfigurationStringList; import org.wikipediacleaner.api.data.DataManager; import org.wikipediacleaner.api.data.Page; import org.wikipediacleaner.api.data.PageAnalysis; import org.wikipediacleaner.gui.swing.action.ActionFullAnalysis; import org.wikipediacleaner.gui.swing.action.ReplaceAllLinksAction; import org.wikipediacleaner.gui.swing.basic.BasicWindow; import org.wikipediacleaner.gui.swing.basic.BasicWorker; import org.wikipediacleaner.gui.swing.basic.DefaultBasicWorkerListener; import org.wikipediacleaner.gui.swing.basic.Utilities; import org.wikipediacleaner.gui.swing.component.MWPane; import org.wikipediacleaner.gui.swing.worker.SendWorker; import org.wikipediacleaner.i18n.GT; import org.wikipediacleaner.images.EnumImageSize; import org.wikipediacleaner.utils.Configuration; import org.wikipediacleaner.utils.ConfigurationValueBoolean; import org.wikipediacleaner.utils.ConfigurationValueInteger; import org.wikipediacleaner.utils.ConfigurationValueShortcut; /** * A base class for Wikipedia Cleaner windows with one page contents. */ public abstract class OnePageWindow extends PageWindow { private Page page; private String pageName; private boolean pageLoaded = false; /** * @return Page. */ @Override public Page getPage() { return page; } /** * @param page Page. */ protected void setPage(Page page) { this.page = page; } /** * @return Page name. */ protected String getPageName() { if ((pageName == null) && (page != null)) { return page.getTitle(); } return pageName; } /** * @param pageName Page name. */ protected void setPageName(String pageName) { EnumWikipedia wikipedia = getWikipedia(); if (wikipedia != null) { this.pageName = wikipedia.normalizeTitle(pageName); } else { this.pageName = pageName; } } /** * @return Page name in the text component. */ protected String getTextPageName() { if (textPagename != null) { return textPagename.getText(); } return pageName; } /** * @return Flag indicating if the page is loaded. */ protected boolean isPageLoaded() { return pageLoaded; } /** * Indicates that the page is loaded. */ protected void setPageLoaded() { pageLoaded = true; } /** * Indicates if the page is loaded. * * @param loaded Flag indicating if the page is loaded. */ protected void setPageLoaded(boolean loaded) { pageLoaded = loaded; } /** * @param pageAnalysis Page analysis. * @return Default comment. */ protected String getAutomaticComment(PageAnalysis pageAnalysis) { return getWikipedia().getConfiguration().getUpdatePageMessage(); } /** * @param comment Comment. */ protected void setComment(String comment) { if (textComment == null) { return; } if ((chkAutomaticComment != null) && (!chkAutomaticComment.isSelected())) { return; } textComment.setText(comment); } /** * @return Comment */ protected String getComment() { if (textComment == null) { return null; } return textComment.getText(); } /** * Clean page. */ protected void clean() { pageLoaded = false; if (getTextContents() != null) { getTextContents().setText(null); } page = DataManager.getPage(getWikipedia(), getTextPageName(), null, null, null); updateComponentState(); } /* ====================================================================== */ /* Workers */ /* ====================================================================== */ /** * Setup the Reloade Worker. * * @param reloadWorker Reload Worker. */ protected void setupReloadWorker(BasicWorker reloadWorker) { if (reloadWorker == null) { return; } reloadWorker.setListener(new DefaultBasicWorkerListener() { @Override public void beforeStart( @SuppressWarnings("unused") BasicWorker worker) { beforeStartReloadWorker(); } @Override public void beforeFinished( @SuppressWarnings("unused") BasicWorker worker) { beforeFinishedReloadWorker(); } @Override public void afterFinished( @SuppressWarnings("unused") BasicWorker worker, @SuppressWarnings("unused") boolean ok) { afterFinishedReloadWorker(); } }); } /** * Callback called at the end of the Reload Worker. */ protected void afterFinishedReloadWorker() { setContents(); updateComponentState(); } /** * Callback called before the end of the Reload Worker. */ protected void beforeFinishedReloadWorker() { setPageLoaded(); } /** * Callback called before the start of the Reload Worker. */ protected void beforeStartReloadWorker() { // } /* ====================================================================== */ /* Components */ /* ====================================================================== */ private JLabel textPagename; private JButton buttonDisambiguation; private JButton buttonAnalysisRedirect; private JButton buttonRedo; private JButton buttonUndo; private JButton buttonReload; private JButton buttonSend; private JButton buttonFullAnalysis; private JTextField textComment; private JCheckBox chkAutomaticComment; private JToggleButton chkSpelling; private JLabel lblLastModified; private JLabel lblEditProtectionLevel; private JButton buttonOptions; private JPopupMenu menuOptions; JMenuItem chkCloseAfterSend; private JMenuItem chkEditTalkPage; JMenuItem chkUpdateDabWarning; JMenuItem chkCreateDabWarning; private MWPane textContents; /** * Update component state. */ @Override protected void updateComponentState() { boolean redirect = (page != null) && (page.isRedirect()); boolean article = (page != null) && (page.isArticle()); boolean dabWarning = article && (getConfiguration().getString(WPCConfigurationString.DAB_WARNING_TEMPLATE) != null) && (getConfiguration().getStringList(WPCConfigurationStringList.TODO_TEMPLATES) != null); setEnabledStatus(textComment, (chkAutomaticComment == null) || (!chkAutomaticComment.isSelected())); setEnabledStatus(textContents, pageLoaded); setEnabledStatus(buttonDisambiguation, pageLoaded); setEnabledStatus(buttonFullAnalysis, pageLoaded); setEnabledStatus(buttonAnalysisRedirect, redirect); setVisibleStatus(buttonAnalysisRedirect, redirect); setEnabledStatus(buttonOptions, pageLoaded); setEnabledStatus(buttonSend, pageLoaded && (textContents != null) && textContents.isModified()); setEnabledStatus(chkCloseAfterSend, pageLoaded); setEnabledStatus(chkCreateDabWarning, pageLoaded && dabWarning && (chkUpdateDabWarning != null) && (chkUpdateDabWarning.isSelected())); setEnabledStatus(chkEditTalkPage, pageLoaded && article); setEnabledStatus(chkSpelling, pageLoaded); setEnabledStatus(chkUpdateDabWarning, pageLoaded && dabWarning); setEnabledStatus(menuFixRedirects, (menuFixRedirects != null) && (menuFixRedirects.getItemCount() > 0)); } /** * Add a component for the page name. * * @param panel Container. */ protected void addTextPageName(JPanel panel) { if (textPagename == null) { textPagename = new JLabel(getPageName()); JLabel labelPagename = Utilities.createJLabel(GT._("&Page :")); labelPagename.setLabelFor(textPagename); labelPagename.setHorizontalAlignment(SwingConstants.TRAILING); panel.add(labelPagename); panel.add(textPagename); } } /** * Add a component for the Disambiguation button. * * @param panel Container. * @param icon Flag indicating if an icon should be used. */ protected void addButtonDisambiguation(JComponent panel, boolean icon) { if (buttonDisambiguation == null) { if (icon) { buttonDisambiguation = Utilities.createJButton( "commons-disambig-colour.png", EnumImageSize.NORMAL, GT._("Disambiguation"), false, null); } else { buttonDisambiguation = Utilities.createJButton(GT._("Disambiguation"), null); } buttonDisambiguation.addActionListener(EventHandler.create( ActionListener.class, this, "actionDisambiguation")); panel.add(buttonDisambiguation); } } /** * Add a component for the Full Analysis button. * * @param panel Container. * @param icon Flag indicating if an icon should be used. */ protected void addButtonFullAnalysis(JComponent panel, boolean icon) { if (buttonFullAnalysis == null) { buttonFullAnalysis = ActionFullAnalysis.createButton( getWikipedia(), getPageName(), true, false, true); panel.add(buttonFullAnalysis); } } /** * Add a component for the Redirect buttons. * * @param panel Container. */ protected void addButtonRedirect(JComponent panel) { buttonAnalysisRedirect = Utilities.createJButton( "commons-redirect-arrow-without-text.png", EnumImageSize.NORMAL, GT._("Redirect"), false, null); buttonAnalysisRedirect.addActionListener(EventHandler.create( ActionListener.class, this, "actionAnalysisRedir")); panel.add(buttonAnalysisRedirect); } /** * Add a component for the Reload button. * * @param panel Container. * @param icon Flag indicating if an icon should be used. */ protected void addButtonReload(JComponent panel, boolean icon) { if (buttonReload == null) { buttonReload = createButtonReload(this, icon); panel.add(buttonReload); } } /** * Create a Reload button. * * @param listener Action listener. * @param icon Flag indicating if an icon should be used. * @return Reload button. */ public JButton createButtonReload(ActionListener listener, boolean icon) { JButton button = null; if (icon) { button = Utilities.createJButton( "gnome-view-refresh.png", EnumImageSize.NORMAL, GT._("Reload (Alt + &R)"), false, null); } else { button = Utilities.createJButton(GT._("&Reload"), null); } button.setActionCommand(ACTION_RELOAD); button.addActionListener(listener); return button; } /** * Add a component for the Send button. * * @param panel Container. * @param icon Flag indicating if an icon should be used. */ protected void addButtonSend(JComponent panel, boolean icon) { if (buttonSend == null) { buttonSend = createButtonSend(this, icon); panel.add(buttonSend); } } /** * Create a Send button. * * @param listener Action listener. * @param icon Flag indicating if an icon should be used. * @return Send button. */ public JButton createButtonSend(ActionListener listener, boolean icon) { JButton button = Utilities.createJButton( icon ? "gnome-document-send.png" : null, EnumImageSize.NORMAL, GT._("Send"), !icon, ConfigurationValueShortcut.SEND); button.setActionCommand(ACTION_SEND); button.addActionListener(listener); return button; } /** * Add a component for the Undo / Redo buttons. * * @param panel Container. * @param icon Flag indicating if an icon should be used. */ protected void addButtonUndoRedo(JComponent panel, boolean icon) { if (icon) { buttonUndo = Utilities.createJButton( "gnome-edit-undo.png", EnumImageSize.NORMAL, GT._("Undo"), false, null); } else { buttonUndo = Utilities.createJButton(GT._("Undo"), null); } panel.add(buttonUndo); if (icon) { buttonRedo = Utilities.createJButton( "gnome-edit-redo.png", EnumImageSize.NORMAL, GT._("Redo"), false, null); } else { buttonRedo = Utilities.createJButton(GT._("Redo"), null); } panel.add(buttonRedo); if (textContents != null) { textContents.getUndoManager().setUndoButton(buttonUndo); textContents.getUndoManager().setRedoButton(buttonRedo); } } /** * Create a TOC button. * * @param listener Action listener. * @param icon Flag indicating if an icon should be used. * @return TOC button. */ public JButton createButtonToc(ActionListener listener, boolean icon) { JButton button; if (icon) { button = Utilities.createJButton( "gnome-format-indent-more.png", EnumImageSize.NORMAL, GT._("Table of Contents"), false, null); } else { button = Utilities.createJButton(GT._("Table of Contents"), null); } button.setActionCommand(ACTION_TOC); button.addActionListener(listener); return button; } /** * Create a Validate button. * * @param listener Action listener. * @param icon Flag indicating if an icon should be used. * @return Validate button. */ public JButton createButtonValidate(ActionListener listener, boolean icon) { JButton button = Utilities.createJButton( icon ? "commons-approve-icon.png" : null, EnumImageSize.NORMAL, GT._("Validate"), !icon, ConfigurationValueShortcut.VALIDATE); button.setActionCommand(ACTION_VALIDATE); button.addActionListener(listener); return button; } /** * Add a component for the Automatic Comment checkbox. * * @param panel Container. * @param constraints Constraints. */ protected void addChkAutomaticComment(JPanel panel, GridBagConstraints constraints) { chkAutomaticComment = createChkAutomaticComment(true, this); panel.add(chkAutomaticComment, constraints); constraints.gridx++; textComment = new JTextField(getAutomaticComment(null)); constraints.weightx = 1; panel.add(textComment, constraints); } /** * Add a component for the Manual Comment. * * @param panel Container. * @param constraints constraints. */ protected void addComment(JPanel panel, GridBagConstraints constraints) { JLabel label = Utilities.createJLabel(GT._("Comment")); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.gridwidth = 1; constraints.weightx = 0; panel.add(label, constraints); constraints.gridx++; textComment = new JTextField(""); constraints.weightx = 1; panel.add(textComment, constraints); } /** * Create a Automatic Comment checkbox. * * @param listener Action listener. * @return Automatic Comment checkbox. */ public JCheckBox createChkAutomaticComment(boolean checked, ItemListener listener) { JCheckBox checkbox = Utilities.createJCheckBox(GT._("Automatic comment"), checked); checkbox.addItemListener(listener); return checkbox; } /** * Add a component for the Options button. * * @param panel Container. * @param icon Flag indicating if an icon should be used. */ protected void addButtonOptions(JComponent panel, boolean icon) { if (icon) { buttonOptions = Utilities.createJButton( "gnome-preferences-other.png", EnumImageSize.NORMAL, GT._("Options"), false, null); } else { buttonOptions = Utilities.createJButton(GT._("Options"), null); } buttonOptions.addActionListener(EventHandler.create( ActionListener.class, this, "actionOptions")); panel.add(buttonOptions); Configuration config = Configuration.getConfiguration(); menuOptions = new JPopupMenu(); chkCloseAfterSend = Utilities.createJCheckBoxMenuItm( GT._("&Close after sending"), config.getBoolean( null, ConfigurationValueBoolean.CLOSE_FULL)); menuOptions.add(chkCloseAfterSend); chkEditTalkPage = Utilities.createJCheckBoxMenuItm( GT._("&Add a note on talk page"), false); getTextContents().setCheckBoxAddNote(chkEditTalkPage); menuOptions.add(chkEditTalkPage); chkUpdateDabWarning = Utilities.createJCheckBoxMenuItm( GT._("Update disambiguation warning on talk page"), false); getTextContents().setCheckBoxUpdateDabWarning(chkUpdateDabWarning); menuOptions.add(chkUpdateDabWarning); chkCreateDabWarning = Utilities.createJCheckBoxMenuItm( GT._("Create disambiguation warning on talk page"), false); getTextContents().setCheckBoxCreateDabWarning(chkCreateDabWarning); menuOptions.add(chkCreateDabWarning); } /** * Action called when Check Spelling button is pressed. */ public void actionOptions() { menuOptions.show(buttonOptions, 0, buttonOptions.getHeight()); } /** * Add a button for checking spelling. * * @param panel Container. * @param icon Flag indicating if an icon should be used. */ public void addChkSpelling(JComponent panel, boolean icon) { boolean checked = shouldCheckSpelling(); if (icon) { chkSpelling = Utilities.createJToggleButton( "gnome-tools-check-spelling.png", EnumImageSize.NORMAL, GT._("Check spelling and typography"), false); } else { chkSpelling = Utilities.createJToggleButton(GT._("Spelling")); } chkSpelling.setSelected(checked); panel.add(chkSpelling); } /** * @return True if spelling should be checked. */ public boolean shouldCheckSpelling() { if (chkSpelling != null) { return chkSpelling.isSelected(); } Configuration config = Configuration.getConfiguration(); return config.getBoolean( null, ConfigurationValueBoolean.SPELLING); } /** * Add a component for the Last modified label. * * @param panel Container. */ protected void addLblLastModified(JComponent panel) { lblLastModified = Utilities.createJLabel(" "); panel.add(lblLastModified); } /** * Add a component for the Edit protection level. * * @param panel Container. */ protected void addLblEditProtectionLevel(JComponent panel) { lblEditProtectionLevel = Utilities.createJLabel(" "); lblEditProtectionLevel.setToolTipText(GT._("Protection level for editing the page")); panel.add(lblEditProtectionLevel); } /** * Add a component for the Text. * * @param panel Container. * @param constraints Constraints. */ protected void addTextContents(JPanel panel, GridBagConstraints constraints) { addTextContents(panel, constraints, textContents, buttonUndo); } /** * Add a component for the Text. * * @param panel Container. * @param constraints Constraints. * @param textPane Text pane. * @param undo Button undo. */ protected void addTextContents( JPanel panel, GridBagConstraints constraints, MWPane textPane, JButton undo) { if (textPane != null) { Configuration config = Configuration.getConfiguration(); textPane.setBackground(Color.WHITE); textPane.setEditable(true); if (undo != null) { textPane.getUndoManager().setUndoLevels(config.getInt( null, ConfigurationValueInteger.ANALYSIS_UNDO_LVL)); } textPane.addPropertyChangeListener( MWPane.PROPERTY_MODIFIED, new PropertyChangeListener() { /* (non-Javadoc) * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) */ @Override public void propertyChange(@SuppressWarnings("unused") PropertyChangeEvent evt) { updateComponentState(); } }); JComponent scrollContents = MWPane.createComplexPane(textPane); scrollContents.setMinimumSize(new Dimension(100, 100)); scrollContents.setPreferredSize(new Dimension(1000, 500)); panel.add(scrollContents, constraints); } } /** * Create the text contents component. * * @param window Window. */ protected void createTextContents(BasicWindow window) { if (textContents == null) { textContents = new MWPane(getWikipedia(), page, window); textContents.addPropertyChangeListener(MWPane.PROPERTY_MODIFIED, this); } } /** * @return Text contents component. */ protected MWPane getTextContents() { return textContents; } /** * Set the contents. */ void setContents() { if (SwingUtilities.isEventDispatchThread()) { if (getTextContents() != null) { getTextContents().setWikiPage(page); getTextContents().setText(page.getContents()); } if (lblLastModified != null) { if ((page.getContentsTimestamp() != null) && (!page.getContentsTimestamp().equals(""))) { Long duration = page.getContentsAge(); if (duration != null) { long minutes = duration.longValue() / 60 + 1; if (minutes > 60) { lblLastModified.setToolTipText(GT._( "Last modified at {0}", page.getContentsTimestamp())); } else { if (minutes <= 5) { lblLastModified.setForeground(Color.RED); } else { lblLastModified.setForeground(Color.ORANGE); } lblLastModified.setToolTipText(GT.__( "Last modified at {0}. It was modified less than {1} minute ago.", "Last modified at {0}. It was modified less than {1} minutes ago.", minutes, new Object[] { page.getContentsTimestamp(), Long.valueOf(minutes) } )); } } lblLastModified.setText(page.getContentsTimestamp()); lblLastModified.setVisible(true); } else { lblLastModified.setVisible(false); } } if (lblEditProtectionLevel != null) { if ((page.getEditProtectionLevel() != null) && (!page.getEditProtectionLevel().equals(""))) { if ("sysop".equals(page.getEditProtectionLevel())) { lblEditProtectionLevel.setForeground(Color.RED); } else { lblEditProtectionLevel.setForeground(Color.ORANGE); } lblEditProtectionLevel.setText(" (" + page.getEditProtectionLevel() + ")"); } else { lblEditProtectionLevel.setVisible(false); } } updateComponentState(); } else { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { setContents(); } }); } } /* ====================================================================== */ /* Menus */ /* ====================================================================== */ private JMenu menuFixRedirects; /** * @return Fix redirects menu. */ protected JMenu createFixRedirectsMenu() { if (menuFixRedirects == null) { menuFixRedirects = Utilities.createJMenu(GT._("Fix &redirects")); } else { menuFixRedirects.removeAll(); } if ((page != null) && (page.getLinks() != null)) { for (Page p : page.getLinks()) { if (p.isRedirect() && !Boolean.TRUE.equals(p.isDisambiguationPage())) { String newTitle = p.getRedirectDestination(); String text = GT._( "Link \"{0}\" to \"{1}\"", new Object[] { p.getTitle(), newTitle }); JMenuItem menuItem = new JMenuItem(text); String warning = getConfiguration().getString( WPCConfigurationString.REDIRECT_WARNING_BEFORE_REPLACEMENT); menuItem.addActionListener(new ReplaceAllLinksAction( getTextContents(), p, newTitle, warning)); menuFixRedirects.add(menuItem); } } } return menuFixRedirects; } /** * @return Tools menu. */ protected JMenu createToolsMenu() { JMenu menu = Utilities.createJMenu(GT._("&Tools")); JMenuItem menuItem = null; menu.add(createFixRedirectsMenu()); menuItem = Utilities.createJMenuItem(GT._("&Preview"), false); menuItem.addActionListener(EventHandler.create( ActionListener.class, this, "actionPreview")); menu.add(menuItem); menuItem = Utilities.createJMenuItem(GT._("&Expand templates"), false); menuItem.addActionListener(EventHandler.create( ActionListener.class, this, "actionExpandTemplates")); menu.add(menuItem); menuItem = Utilities.createJMenuItem(GT._("Expand templates &and Preview"), false); menuItem.addActionListener(EventHandler.create( ActionListener.class, this, "actionExpandTemplatesPreview")); menu.add(menuItem); return menu; } /* ====================================================================== */ /* ItemListener */ /* ====================================================================== */ /* (non-Javadoc) * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent) */ @Override public void itemStateChanged(ItemEvent e) { if ((e == null) || (e.getSource() == null)) { return; } Object source = e.getSource(); if ((chkAutomaticComment != null) && (textComment != null) && (source == chkAutomaticComment)) { textComment.setEnabled(!chkAutomaticComment.isSelected()); if (chkAutomaticComment.isSelected()) { textComment.setText(getAutomaticComment(null)); } } } /* ====================================================================== */ /* PropertyChange */ /* ====================================================================== */ /* (non-Javadoc) * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) */ @Override public void propertyChange(PropertyChangeEvent evt) { if (evt == null) { return; } if (MWPane.PROPERTY_MODIFIED.equals(evt.getPropertyName())) { updateComponentState(); } } /* ====================================================================== */ /* ActionListener */ /* ====================================================================== */ public final static String ACTION_FULL_ANALYSIS_PAGE = "FULL ANALYSIS PAGE"; public final static String ACTION_RELOAD = "RELOAD"; public final static String ACTION_SEND = "SEND"; public final static String ACTION_TOC = "TOC"; public final static String ACTION_VALIDATE = "VALIDATE"; /** * Invoked when an action occurs. * * @param e Event. */ @Override public void actionPerformed(ActionEvent e) { if (e == null) { return; } if (ACTION_FULL_ANALYSIS_PAGE.equals(e.getActionCommand())) { actionFullAnalysis(); } else if (ACTION_RELOAD.equals(e.getActionCommand())) { actionReload(); } else if (ACTION_SEND.equals(e.getActionCommand())) { actionSend(); } else if (ACTION_TOC.equals(e.getActionCommand())) { actionToc(); } else if (ACTION_VALIDATE.equals(e.getActionCommand())) { actionValidate(true); } } /** * Action called when Disambiguation button is pressed. */ public void actionDisambiguation() { Controller.runDisambiguationAnalysis(getPageName(), getWikipedia()); } /** * Action called when Analysis Redirect button is pressed. */ public void actionAnalysisRedir() { JPopupMenu menu = new JPopupMenu(); JMenuItem item = new JMenuItem( GT._("Full analysis"), Utilities.getImageIcon("gnome-system-run.png", EnumImageSize.NORMAL)); item.addActionListener(EventHandler.create( ActionListener.class, this, "actionFullAnalysisRedir")); menu.add(item); item = new JMenuItem( GT._("Disambiguation analysis"), Utilities.getImageIcon("commons-disambig-colour.png", EnumImageSize.NORMAL)); item.addActionListener(EventHandler.create( ActionListener.class, this, "actionDisambiguationRedir")); menu.add(item); menu.show( buttonAnalysisRedirect, 0, buttonAnalysisRedirect.getHeight()); } /** * Action called when Disambiguation Redirect button is pressed. */ public void actionDisambiguationRedir() { if (page != null) { Controller.runDisambiguationAnalysis( page.getRedirectTitle(), getWikipedia()); } } /** * Action called when Expand Templates menu is selected. */ public void actionExpandTemplates() { if (textContents != null) { Controller.runExpandTemplates( getPageName(), textContents.getText(), true, false, getWikipedia()); } } /** * Action called when Expand Templates / Preview menu is selected. */ public void actionExpandTemplatesPreview() { if (textContents != null) { Controller.runExpandTemplates( getPageName(), textContents.getText(), true, true, getWikipedia()); } } /** * Action called when Full analysis button is pressed. */ private void actionFullAnalysis() { Controller.runFullAnalysis(getPageName(), null, getWikipedia()); } /** * Action called when Full analysis Redirect button is pressed. */ public void actionFullAnalysisRedir() { if (page != null) { Controller.runFullAnalysis( page.getRedirectTitle(), null, getWikipedia()); } } /** * Action called when Preview menu is selected. */ public void actionPreview() { if (textContents != null) { Controller.runExpandTemplates( getPageName(), textContents.getText(), false, true, getWikipedia()); } } /** * Action called when Reload button is pressed. */ protected abstract void actionReload(); /** * Action called when Send button is pressed. */ private void actionSend() { actionValidate(false); // Check that a comment is available if ((textComment != null) && (textComment.getText().trim().length() == 0)) { Utilities.displayWarning(getParentComponent(), GT._( "A comment is required for sending the page.")); return; } if ((chkEditTalkPage != null) && chkEditTalkPage.isSelected() && (page != null) && (page.getTalkPage() != null)) { Controller.runNewSection( page.getTalkPage(), getTextContents().getText(), page.getTitle(), getWikipedia()); } Configuration config = Configuration.getConfiguration(); final boolean hideWindow = config.getBoolean( null, ConfigurationValueBoolean.ANALYSIS_HIDE_SENDING); final boolean forceWatch = config.getBoolean( null, ConfigurationValueBoolean.FORCE_WATCH); final int oldState = getParentComponent().getExtendedState(); final boolean updateDabWarning = (chkUpdateDabWarning != null) && (chkUpdateDabWarning.isSelected()); final boolean createDabWarning = (chkCreateDabWarning != null) && (chkCreateDabWarning.isSelected()); final boolean createISBNWarning = false; boolean updateISBNWarning = false; final boolean createISSNWarning = false; boolean updateISSNWarning = false; final boolean createDuplicateArgsWarning = false; boolean updateDuplicateArgsWarning = false; List<CheckError.Progress> errorsFixed = computeErrorsFixed(); if (errorsFixed != null) { for (CheckError.Progress errorFixed : errorsFixed) { CheckErrorAlgorithm algorithm = errorFixed.algorithm; int errorNumber = algorithm.getErrorNumber(); if ((errorNumber == 69) || (errorNumber == 70) || (errorNumber == 71) || (errorNumber == 72) || (errorNumber == 73)) { updateISBNWarning = true; } if ((errorNumber == 106) || (errorNumber == 107) || (errorNumber == 108)) { updateISSNWarning = true; } if (errorNumber == 524) { updateDuplicateArgsWarning = true; } } } if (hideWindow) { getParentComponent().setExtendedState(Frame.ICONIFIED); } getParentComponent().setTitle(GT._("Sending {0}", page.getTitle())); SendWorker sendWorker = new SendWorker.Builder(). allowDabWarning(updateDabWarning, createDabWarning). allowISBNWarning(updateISBNWarning, createISBNWarning). allowISSNWarning(updateISSNWarning, createISSNWarning). allowDuplicateArgsWarning(updateDuplicateArgsWarning, createDuplicateArgsWarning). createWorker( getWikipedia(), this, page, getTextContents().getText(), (textComment != null) ? textComment.getText() : getWikipedia().getConfiguration().getUpdatePageMessage(), forceWatch, getContributions(), errorsFixed); sendWorker.setListener(new DefaultBasicWorkerListener() { @Override public void afterFinished( BasicWorker worker, boolean ok) { if (!worker.shouldContinue()) { return; } if (ok) { if ((chkCloseAfterSend != null) && chkCloseAfterSend.isSelected()) { dispose(); } else { worker.getWindow().setWindowTitle(getTitle()); worker.getWindow().setExtendedState(oldState); actionReload(); } } else { worker.getWindow().setWindowTitle(getTitle()); worker.getWindow().setExtendedState(oldState); } } }); sendWorker.start(); } /** * Action called when TOC button is pressed. */ private void actionToc() { if (getTextContents() != null) { getTextContents().toggleToc(); } } /** * Action called when Validate button is pressed. * * @param fullValidate Full validation ? */ protected void actionValidate(boolean fullValidate) { // Implement in sub-classes } // ========================================================================= // Check Wiki // ========================================================================= private List<CheckErrorPage> initialErrors; /** * Initialize list of initial errors. * * @param algorithms Algorithms. */ protected void initializeInitialErrors( Collection<CheckErrorAlgorithm> algorithms) { if (page != null) { PageAnalysis pageAnalysis = page.getAnalysis(page.getContents(), false); pageAnalysis.shouldCheckSpelling(shouldCheckSpelling()); List<CheckErrorPage> errorsFound = CheckError.analyzeErrors( algorithms, pageAnalysis, false); initialErrors = new ArrayList<CheckErrorPage>(); if (errorsFound != null) { for (CheckErrorPage tmpError : errorsFound) { initialErrors.add(tmpError); } } } } /** * @return Initial errors. */ protected Collection<CheckErrorPage> getInitialErrors() { return initialErrors; } /** * @return Initial algorithms. */ protected Collection<CheckErrorAlgorithm> getInitialAlgorithms() { if (initialErrors == null) { return null; } Collection<CheckErrorAlgorithm> algorithms = new ArrayList<CheckErrorAlgorithm>(); for (CheckErrorPage error : initialErrors) { CheckErrorAlgorithm algorithm = error.getAlgorithm(); if (!algorithms.contains(algorithm)) { algorithms.add(algorithm); } } return algorithms; } /** * Mark a page as fixed for an error. * * @param errorNumber Error number. * @param pageFixed Page. */ static public void markPageAsFixed( final String errorNumber, final Page pageFixed) { if (pageFixed != null) { MediaWikiController.addSimpleTask(new Callable<Page>() { @Override public Page call() throws Exception { CheckWiki checkWiki = APIFactory.getCheckWiki(); if (checkWiki != null) { checkWiki.markAsFixed(pageFixed, errorNumber); } return pageFixed; }}); } } /** * @return Errors fixed. */ protected List<CheckError.Progress> computeErrorsFixed() { return CheckError.computeErrorsFixed(initialErrors, getTextContents().getText(), shouldCheckSpelling()); } }