/*
* 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.pagelist;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.beans.EventHandler;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
import org.wikipediacleaner.api.constants.EnumWikipedia;
import org.wikipediacleaner.api.data.DataManager;
import org.wikipediacleaner.api.data.Page;
import org.wikipediacleaner.api.data.PageComment;
import org.wikipediacleaner.gui.swing.Controller;
import org.wikipediacleaner.gui.swing.action.ActionCheckArticle;
import org.wikipediacleaner.gui.swing.action.ActionUpdateWarning;
import org.wikipediacleaner.gui.swing.basic.BasicWindow;
import org.wikipediacleaner.gui.swing.basic.BasicWorker;
import org.wikipediacleaner.gui.swing.basic.DefaultBasicWindowListener;
import org.wikipediacleaner.gui.swing.basic.DefaultBasicWorkerListener;
import org.wikipediacleaner.gui.swing.basic.Utilities;
import org.wikipediacleaner.gui.swing.worker.CheckArticleWorker;
import org.wikipediacleaner.gui.swing.worker.UpdateInfoWorker;
import org.wikipediacleaner.i18n.GT;
import org.wikipediacleaner.images.EnumImageSize;
import org.wikipediacleaner.utils.Configuration;
import org.wikipediacleaner.utils.ConfigurationValueShortcut;
/**
* Window displaying a List of pages.
*/
public class PageListWindow extends BasicWindow {
public final static Integer WINDOW_VERSION = Integer.valueOf(2);
String title;
Page referencePage;
List<Page> pages;
boolean watchList;
PageListTable tablePages;
JLabel labelLinksCount;
private JButton buttonAdd;
private JButton buttonAutomaticFixing;
private JButton buttonCheckArticle;
private JButton buttonComments;
private JButton buttonDisambiguation;
private JButton buttonDisambiguationWatch;
private JButton buttonFullAnalysis;
private JButton buttonRemove;
private JButton buttonSave;
private JButton buttonSelectDab;
private JButton buttonUpdateInfo;
private JButton buttonView;
private JButton buttonViewHistory;
/**
* Create and display a PageListWindow.
*
* @param title Window title.
* @param pages Pages.
* @param wikipedia Wikipedia.
* @param watchList Flag indicating if pages can be removed.
*/
public static void createPageListWindow(
final String title,
final Page referencePage,
final List<Page> pages,
final EnumWikipedia wikipedia,
final boolean watchList) {
createWindow(
"PageListWindow", wikipedia,
WindowConstants.DISPOSE_ON_CLOSE,
PageListWindow.class,
new DefaultBasicWindowListener() {
@Override
public void initializeWindow(BasicWindow window) {
if (window instanceof PageListWindow) {
PageListWindow pageList = (PageListWindow) window;
pageList.title = title;
pageList.referencePage = referencePage;
pageList.pages = pages;
pageList.watchList = watchList;
}
}
});
}
/* (non-Javadoc)
* @see org.wikipediacleaner.gui.swing.basic.BasicWindow#getTitle()
*/
@Override
public String getTitle() {
return title;
}
/**
* Update component state.
*/
@Override
protected void updateComponentState() {
if (tablePages != null) {
tablePages.invalidate();
}
}
/**
* @return Window components.
*/
@Override
protected Component createComponents() {
JPanel panel = new JPanel(new GridBagLayout());
// Initialize constraints
GridBagConstraints constraints = new GridBagConstraints();
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.gridheight = 1;
constraints.gridwidth = 2;
constraints.gridx = 0;
constraints.gridy = 0;
constraints.insets = new Insets(0, 0, 0, 0);
constraints.ipadx = 0;
constraints.ipady = 0;
constraints.weightx = 1;
constraints.weighty = 0;
// Table
constraints.fill = GridBagConstraints.BOTH;
constraints.weighty = 1;
tablePages = PageListTable.createTable(getWikipedia(), pages);
JScrollPane scrollPages = new JScrollPane(tablePages);
scrollPages.setMinimumSize(new Dimension(300, 200));
scrollPages.setPreferredSize(new Dimension(450, 500));
scrollPages.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
panel.add(scrollPages, constraints);
constraints.gridy++;
// Links count
labelLinksCount = Utilities.createJLabel(GT._("Backlinks"));
updateBacklinksCount();
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.weightx = 1;
constraints.weighty = 0;
panel.add(labelLinksCount, constraints);
constraints.gridy++;
// Tool bar
JToolBar toolbar = new JToolBar(SwingConstants.HORIZONTAL);
toolbar.setFloatable(false);
toolbar.setBorderPainted(false);
buttonFullAnalysis = Utilities.createJButton(
"gnome-system-run.png", EnumImageSize.NORMAL,
GT._("Full analysis"), false,
ConfigurationValueShortcut.FULL_ANALYSIS);
buttonFullAnalysis.addActionListener(EventHandler.create(
ActionListener.class, this, "actionFullAnalysis"));
toolbar.add(buttonFullAnalysis);
buttonDisambiguation = Utilities.createJButton(
"commons-disambig-colour.png", EnumImageSize.NORMAL,
GT._("Disambiguation"), false,
ConfigurationValueShortcut.DAB_ANALYSIS);
buttonDisambiguation.addActionListener(EventHandler.create(
ActionListener.class, this, "actionDisambiguation"));
toolbar.add(buttonDisambiguation);
buttonCheckArticle = ActionCheckArticle.createInternalButton(
true, false, true);
buttonCheckArticle.addActionListener(EventHandler.create(
ActionListener.class, this, "actionCheckArticle"));
toolbar.add(buttonCheckArticle);
buttonSelectDab = Utilities.createJButton(
"wpc-select-disambig.png", EnumImageSize.NORMAL,
GT._("Select disambiguation pages with too many backlinks"),
false, null);
buttonSelectDab.addActionListener(EventHandler.create(
ActionListener.class, this, "actionSelectDisambiguation"));
toolbar.add(buttonSelectDab);
buttonDisambiguationWatch = Utilities.createJButton(
"commons-disambig-colour-plus.png", EnumImageSize.NORMAL,
GT._("Analyze pages with links to disambiguation pages"),
false, null);
buttonDisambiguationWatch.addActionListener(EventHandler.create(
ActionListener.class, this, "actionDisambiguationWatch"));
toolbar.add(buttonDisambiguationWatch);
ActionUpdateWarning.addButton(
getParentComponent(), this, toolbar, tablePages, true, false);
buttonUpdateInfo = Utilities.createJButton(
"gnome-view-refresh.png", EnumImageSize.NORMAL,
GT._("Update page information (Alt + &U)"), false, null);
buttonUpdateInfo.addActionListener(EventHandler.create(
ActionListener.class, this, "actionUpdateInfo"));
toolbar.add(buttonUpdateInfo);
buttonComments = Utilities.createJButton(
"tango-internet-group-chat.png", EnumImageSize.NORMAL,
GT._("Set page comments (Alt + &C)"), false, null);
buttonComments.addActionListener(EventHandler.create(
ActionListener.class, this, "actionSetComments"));
toolbar.add(buttonComments);
buttonView = Utilities.createJButton(
"gnome-emblem-web.png", EnumImageSize.NORMAL,
GT._("External Viewer"), false,
ConfigurationValueShortcut.EXTERNAL_VIEWER);
buttonView.addActionListener(EventHandler.create(
ActionListener.class, this, "actionView"));
toolbar.add(buttonView);
buttonViewHistory = Utilities.createJButton(
"gnome-emblem-documents.png", EnumImageSize.NORMAL,
GT._("History"), false,
ConfigurationValueShortcut.HISTORY);
buttonViewHistory.addActionListener(EventHandler.create(
ActionListener.class, this, "actionViewHistory"));
toolbar.add(buttonViewHistory);
buttonSave = Utilities.createJButton(
"gnome-document-save.png", EnumImageSize.NORMAL,
GT._("Save list"), false, null);
buttonSave.addActionListener(EventHandler.create(
ActionListener.class, this, "actionSave"));
toolbar.add(buttonSave);
buttonAutomaticFixing = Utilities.createJButton(GT._("Automatic fixing"), null);
buttonAutomaticFixing.addActionListener(EventHandler.create(
ActionListener.class, this, "actionRunAutomaticFixing"));
toolbar.add(buttonAutomaticFixing);
if (watchList) {
buttonRemove = Utilities.createJButton(
"gnome-list-remove.png", EnumImageSize.NORMAL,
GT._("Remove page"), false,
ConfigurationValueShortcut.LIST_REMOVE);
buttonRemove.addActionListener(EventHandler.create(
ActionListener.class, this, "actionRemove"));
toolbar.add(buttonRemove);
buttonAdd = Utilities.createJButton(
"gnome-list-add.png", EnumImageSize.NORMAL,
GT._("Add page"), false,
ConfigurationValueShortcut.LIST_ADD);
buttonAdd.addActionListener(EventHandler.create(
ActionListener.class, this, "actionAdd"));
toolbar.add(buttonAdd);
}
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.weightx = 1;
constraints.weighty = 0;
panel.add(toolbar, constraints);
constraints.gridy++;
return panel;
}
/**
* Action called when Full analysis button is pressed.
*/
public void actionFullAnalysis() {
List<Page> selectedPages = tablePages.getSelectedPages();
Controller.runFullAnalysis(
getParentComponent(),
selectedPages, null,
getWikipedia());
}
/**
* Action called when Disambiguation button is pressed.
*/
public void actionDisambiguation() {
List<Page> selectedPages = tablePages.getSelectedPages();
Controller.runDisambiguationAnalysis(
getParentComponent(),
selectedPages,
getWikipedia());
}
/**
* Action called when Select Disambiguation button is pressed.
*/
public void actionSelectDisambiguation() {
tablePages.clearSelection();
int index = 0;
for (Page page : pages) {
if (page.isDisambiguationPage()) {
if ((page.getComment() != null) &&
(page.getComment().getMaxMainArticles() != null)) {
int maxArticles = page.getComment().getMaxMainArticles().intValue();
Integer articles = page.getBacklinksCountInMainNamespace();
if ((articles != null) && (maxArticles < articles.intValue())) {
int tmpIndex = tablePages.convertRowIndexToView(index);
tablePages.addRowSelectionInterval(tmpIndex, tmpIndex);
}
}
}
index++;
}
}
/**
* Action called when Disambiguation Watch button is pressed.
*/
public void actionDisambiguationWatch() {
List<Page> selectedPages = tablePages.getSelectedPages();
if ((selectedPages == null) ||
(selectedPages.size() == 0)) {
return;
}
List<String> pageNames = new ArrayList<String>(selectedPages.size());
for (Page page : selectedPages) {
pageNames.add(page.getTitle());
}
new PageListWorker(
getWikipedia(), this, null,
pageNames,
PageListWorker.Mode.DAB_WATCH, false,
GT._("Articles with links to disambiguation pages")).start();
}
/**
* Action called when Remove button is pressed.
*/
public void actionRemove() {
if (displayYesNoWarning(GT._(
"You are about to remove the pages from your local watchlist.\n" +
"Are you sure?")) != JOptionPane.YES_OPTION) {
return;
}
List<Page> selectedPages = tablePages.getSelectedPages();
if ((selectedPages == null) || (selectedPages.isEmpty())) {
return;
}
Configuration config = Configuration.getConfiguration();
List<String> watchedPages = config.getStringList(
getWikipedia(), Configuration.ARRAY_WATCH_PAGES);
for (Page page : selectedPages) {
watchedPages.remove(page.getTitle());
}
config.setStringList(
getWikipedia(), Configuration.ARRAY_WATCH_PAGES, watchedPages);
tablePages.removePages(selectedPages);
}
/**
* Action called when Add button is pressed.
*/
public void actionAdd() {
String value = askForValue(
GT._("Enter the page title you want to add to your local watchlist"),
"", null);
if (value != null) {
Page page = DataManager.getPage(getWikipedia(), value, null, null, null);
Configuration config = Configuration.getConfiguration();
List<String> watchedPages = config.getStringList(
getWikipedia(), Configuration.ARRAY_WATCH_PAGES);
if (!watchedPages.contains(page.getTitle())) {
watchedPages.add(page.getTitle());
Collections.sort(watchedPages);
config.setStringList(getWikipedia(), Configuration.ARRAY_WATCH_PAGES, watchedPages);
tablePages.addPage(page);
}
}
}
/**
* Action called when Set comments button is pressed.
*/
public void actionSetComments() {
List<Page> selectedPages = tablePages.getSelectedPages();
Controller.runPageComments(selectedPages, getWikipedia());
}
/**
* Action called when Check article button is pressed.
*/
public void actionCheckArticle() {
List<Page> selectedPages = tablePages.getSelectedPages();
if ((selectedPages == null) || (selectedPages.size() == 0)) {
return;
}
final CheckArticleWorker checkWorker = new CheckArticleWorker(
getWikipedia(), this, selectedPages);
checkWorker.start();
}
/**
* Action called when Update information button is pressed.
*/
public void actionUpdateInfo() {
List<Page> selectedPages = tablePages.getSelectedPages();
if ((selectedPages == null) || (selectedPages.size() == 0)) {
return;
}
final UpdateInfoWorker updateWorker = new UpdateInfoWorker(
getWikipedia(), this, selectedPages);
updateWorker.setListener(new DefaultBasicWorkerListener() {
/* (non-Javadoc)
* @see org.wikipediacleaner.gui.swing.basic.DefaultBasicWorkerListener#afterFinished(org.wikipediacleaner.gui.swing.basic.BasicWorker, boolean)
*/
@Override
public void afterFinished(BasicWorker worker, boolean ok) {
tablePages.updateWatchedPages();
super.afterFinished(worker, ok);
updateBacklinksCount();
}
});
updateWorker.start();
}
/**
* Action called when View button is pressed.
*/
public void actionView() {
List<Page> selectedPages = tablePages.getSelectedPages();
if (selectedPages != null) {
for (Page page : selectedPages) {
Utilities.browseURL(getWikipedia(), page.getTitle(), false);
}
}
}
/**
* Action called when View History button is pressed.
*/
public void actionViewHistory() {
List<Page> selectedPages = tablePages.getSelectedPages();
if (selectedPages != null) {
for (Page page : selectedPages) {
Utilities.browseURL(getWikipedia(), page.getTitle(), "history");
}
}
}
/**
* Action called when Save button is pressed.
*/
public void actionSave() {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File("."));
fileChooser.setDialogTitle(GT._("Save list"));
int answer = fileChooser.showSaveDialog(this.getParentComponent());
if (answer != JFileChooser.APPROVE_OPTION) {
return;
}
File file = fileChooser.getSelectedFile();
if (file == null) {
return;
}
BufferedWriter buffer = null;
try {
buffer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"));
for (Page page : pages) {
buffer.append("* [[:" + page.getTitle() + "]]\n");
}
} catch (IOException e) {
// Nothing to do
} finally {
if (buffer != null) {
try {
buffer.close();
} catch (IOException e) {
// Nothing to do
}
}
}
}
/**
* Action called when Run Automatic Fixing button is pressed.
*/
public void actionRunAutomaticFixing() {
List<Page> selectedPages = tablePages.getSelectedPages();
if ((selectedPages == null) || (selectedPages.size() == 0)) {
Utilities.displayWarning(
getParentComponent(),
GT._("You must select pages on which running automatic fixing."));
return;
}
Controller.runAutomaticFixing(selectedPages, referencePage, getWikipedia());
}
/**
* Update the total count of backlinks.
*/
void updateBacklinksCount() {
int backlinksMain = 0;
int backlinks = 0;
int maxMain = 0;
int actualMain = 0;
for (Page page : pages) {
if (page != null) {
PageComment comment = page.getComment();
Integer tmpLinks = page.getBacklinksCountInMainNamespace();
if (tmpLinks != null) {
backlinksMain += tmpLinks.intValue();
if ((comment != null) && (comment.getMaxMainArticles() != null)) {
maxMain += comment.getMaxMainArticles().intValue();
actualMain += tmpLinks.intValue();
}
}
tmpLinks = page.getBacklinksCount();
if (tmpLinks != null) {
backlinks += tmpLinks.intValue();
}
}
}
String txtMain = null;
if ((actualMain > 0) || (maxMain > 0)) {
if (backlinksMain != actualMain) {
if (actualMain != maxMain) {
txtMain = "" + backlinksMain + " (" + actualMain + "/" + maxMain + ")";
} else {
txtMain = "" + backlinksMain + " (" + actualMain + ")";
}
} else if (actualMain != maxMain) {
txtMain = "" + actualMain + "/" + maxMain;
} else {
txtMain = "" + actualMain;
}
} else {
txtMain = "" + backlinksMain;
}
String txtAll = null;
txtAll = "" + backlinks;
labelLinksCount.setText(
GT.__("{0} page", "{0} pages", pages.size(), Integer.toString(pages.size())) +
", " +
GT._(
"Backlinks - Main namespace: {0}, All namespaces: {1}",
new Object[] { txtMain, txtAll }));
}
}