/*
* 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.component;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.swing.JMenu;
import javax.swing.JPopupMenu;
import javax.swing.text.BadLocationException;
import org.wikipediacleaner.api.constants.EnumWikipedia;
import org.wikipediacleaner.api.data.DataManager;
import org.wikipediacleaner.api.data.ISBNRange;
import org.wikipediacleaner.api.data.Namespace;
import org.wikipediacleaner.api.data.Page;
import org.wikipediacleaner.api.data.PageAnalysis;
import org.wikipediacleaner.api.data.PageElement;
import org.wikipediacleaner.api.data.PageElementCategory;
import org.wikipediacleaner.api.data.PageElementComment;
import org.wikipediacleaner.api.data.PageElementExternalLink;
import org.wikipediacleaner.api.data.PageElementFunction;
import org.wikipediacleaner.api.data.PageElementISBN;
import org.wikipediacleaner.api.data.PageElementISSN;
import org.wikipediacleaner.api.data.PageElementImage;
import org.wikipediacleaner.api.data.PageElementInternalLink;
import org.wikipediacleaner.api.data.PageElementInterwikiLink;
import org.wikipediacleaner.api.data.PageElementLanguageLink;
import org.wikipediacleaner.api.data.PageElementParameter;
import org.wikipediacleaner.api.data.PageElementTemplate;
import org.wikipediacleaner.api.data.ISBNRange.ISBNInformation;
import org.wikipediacleaner.api.data.SearchEngine;
import org.wikipediacleaner.gui.swing.basic.BasicWindow;
import org.wikipediacleaner.gui.swing.menu.BasicMenuCreator;
import org.wikipediacleaner.i18n.GT;
/**
* A popup menu listener for MediaWikiPane.
*/
public abstract class MWPanePopupListener extends AbstractPopupListener {
private final EnumWikipedia wikipedia;
private BasicWindow window;
public MWPanePopupListener(EnumWikipedia wikipedia, BasicWindow window) {
this.wikipedia = wikipedia;
this.window = window;
}
/**
* @return Wikipedia.
*/
public EnumWikipedia getWikipedia() {
return wikipedia;
}
/**
* @return Window.
*/
public BasicWindow getWindow() {
return window;
}
/**
* Show popup menu in response to a mouse event.
*
* @param e Event.
*/
@Override
protected void showPopup(MouseEvent e) {
// Retrieve information
if (!(e.getComponent() instanceof MWPane)) {
return;
}
MWPane textPane = (MWPane) e.getComponent();
showPopup(textPane, textPane.viewToModel(e.getPoint()), e.getX(), e.getY());
}
/**
* Show popup menu in response to a key event.
*
* @param e Event.
*/
@Override
protected void showPopup(KeyEvent e) {
// Retrieve information
if (!(e.getComponent() instanceof MWPane)) {
return;
}
MWPane textPane = (MWPane) e.getComponent();
try {
Rectangle rect = textPane.modelToView(textPane.getCaretPosition());
showPopup(textPane, textPane.getSelectionStart(), rect.x, rect.y);
} catch (BadLocationException e1) {
//
}
}
/**
* Construct and show popup menu.
*
* @param textPane Text pane.
* @param position Position in text.
* @param x Position.
* @param y Position.
*/
private void showPopup(MWPane textPane, int position, int x, int y) {
// Basic checks
if (textPane == null) {
return;
}
// Create popup menu
Page originalPage = textPane.getWikiPage();
PageAnalysis pageAnalysis = originalPage.getAnalysis(textPane.getText(), true);
JPopupMenu popup = createPopup(textPane, position, pageAnalysis);
if (popup == null) {
popup = createDefaultPopup(textPane, position, pageAnalysis);
}
// Display popup menu
if (popup != null) {
popup.show(textPane, x, y);
}
}
/**
* Construct popup menu.
*
* @param textPane Text pane.
* @param position Position in text.
* @param pageAnalysis Page analysis.
*/
protected abstract JPopupMenu createPopup(
MWPane textPane, int position,
PageAnalysis pageAnalysis);
/* ===================================================================== */
/* Default implementation */
/* ===================================================================== */
/**
* Create a default popup menu.
*
* @param textPane Text pane.
* @param position Position in the text.
* @param pageAnalysis Page analysis.
* @return Popup menu.
*/
protected JPopupMenu createDefaultPopup(
MWPane textPane, int position,
PageAnalysis pageAnalysis) {
// Basic checks
if (pageAnalysis == null) {
return null;
}
// Find where the user has clicked
PageElement element = pageAnalysis.isInElement(position);
// Comment
if (element instanceof PageElementComment) {
return null;
}
// Menu for internal link
if (element instanceof PageElementInternalLink) {
PageElementInternalLink internalLink = (PageElementInternalLink) element;
return createDefaultPopupInternalLink(textPane, position, pageAnalysis, internalLink);
}
// Menu for image
if (element instanceof PageElementImage) {
PageElementImage image = (PageElementImage) element;
return createDefaultPopupImage(textPane, position, pageAnalysis, image);
}
// Menu for external link
if (element instanceof PageElementExternalLink) {
PageElementExternalLink externalLink = (PageElementExternalLink) element;
return createDefaultPopupExternalLink(pageAnalysis, position, externalLink);
}
// Menu for template
if (element instanceof PageElementTemplate) {
PageElementTemplate template = (PageElementTemplate) element;
return createDefaultPopupTemplate(pageAnalysis, position, template);
}
// Menu for category
if (element instanceof PageElementCategory) {
PageElementCategory category = (PageElementCategory) element;
return createDefaultPopupCategory(textPane, position, pageAnalysis, category);
}
// Menu for interwiki
if (element instanceof PageElementInterwikiLink) {
PageElementInterwikiLink interwiki = (PageElementInterwikiLink) element;
return createDefaultPopupInterwikiLink(textPane, position, pageAnalysis, interwiki);
}
// Menu for language
if (element instanceof PageElementLanguageLink) {
PageElementLanguageLink language = (PageElementLanguageLink) element;
return createDefaultPopupLanguageLink(textPane, position, pageAnalysis, language);
}
// Menu for parameter
if (element instanceof PageElementParameter) {
PageElementParameter parameter = (PageElementParameter) element;
return createDefaultPopupParameter(pageAnalysis, position, parameter);
}
// Menu for function
if (element instanceof PageElementFunction) {
PageElementFunction function = (PageElementFunction) element;
return createDefaultPopupFunction(pageAnalysis, position, function);
}
// Menu for ISBN
if (element instanceof PageElementISBN) {
PageElementISBN isbn = (PageElementISBN) element;
return createDefaultPopupISBN(pageAnalysis, position, isbn);
}
// Menu for ISSN
if (element instanceof PageElementISSN) {
PageElementISSN issn = (PageElementISSN) element;
return createDefaultPopupISSN(pageAnalysis, position, issn);
}
// Default menu
BasicMenuCreator menu = new BasicMenuCreator();
JPopupMenu popup = menu.createPopupMenu(GT._(
"Page: {0}",
limitTextLength(pageAnalysis.getPage().getTitle(), 50)));
menu.addCurrentChapter(popup, position, pageAnalysis);
menu.addSeparator(popup);
menu.addView(wikipedia, popup, pageAnalysis.getPage(), false);
return popup;
}
/**
* Create a default popup menu for an internal link.
*
* @param textPane Text pane.
* @param position Position in the text.
* @param pageAnalysis Page analysis.
* @param link Internal link.
* @return Popup menu.
*/
protected JPopupMenu createDefaultPopupInternalLink(
MWPane textPane, int position,
PageAnalysis pageAnalysis,
PageElementInternalLink link) {
if (link == null) {
return null;
}
// Initialization
Page page = DataManager.getPage(wikipedia, link.getLink(), null, null, null);
// Menu creation
BasicMenuCreator menu = new BasicMenuCreator();
JPopupMenu popup = menu.createPopupMenu(GT._(
"Page: {0}",
limitTextLength(page.getTitle(), 50)));
menu.addCurrentChapter(popup, position, pageAnalysis);
menu.addSeparator(popup);
menu.addView(wikipedia, popup, page, false);
menu.addAnalyze(wikipedia, popup, page);
menu.addDisambiguation(wikipedia, popup, page);
menu.addSeparator(popup);
menu.addItemRemoveLink(
popup, link.getDisplayedText(),
textPane, link.getBeginIndex(), link.getEndIndex());
return popup;
}
/**
* Create a default popup menu for an interwiki link.
*
* @param textPane Text pane.
* @param position Position in the text.
* @param pageAnalysis Page analysis.
* @param link Interwiki link.
* @return Popup menu.
*/
protected JPopupMenu createDefaultPopupInterwikiLink(
MWPane textPane, int position,
PageAnalysis pageAnalysis,
PageElementInterwikiLink link) {
if (link == null) {
return null;
}
// Menu creation
BasicMenuCreator menu = new BasicMenuCreator();
JPopupMenu popup = menu.createPopupMenu(GT._(
"Interwiki: {0}",
limitTextLength(link.getInterwikiText() + ":" + link.getLink(), 50)));
menu.addCurrentChapter(popup, position, pageAnalysis);
return popup;
}
/**
* Create a default popup menu for a language link.
*
* @param textPane Text pane.
* @param position Position in the text.
* @param pageAnalysis Page analysis.
* @param link Language link.
* @return Popup menu.
*/
protected JPopupMenu createDefaultPopupLanguageLink(
MWPane textPane, int position,
PageAnalysis pageAnalysis,
PageElementLanguageLink link) {
if (link == null) {
return null;
}
// Initialization
EnumWikipedia otherWikipedia = EnumWikipedia.getWikipedia(link.getLanguage());
Page otherPage = null;
if (otherWikipedia != null) {
otherPage = DataManager.getPage(otherWikipedia, link.getLink(), null, null, null);
}
// Menu creation
BasicMenuCreator menu = new BasicMenuCreator();
JPopupMenu popup = menu.createPopupMenu(
link.getLanguage() + ":" +
limitTextLength(link.getLink(), 50));
menu.addCurrentChapter(popup, position, pageAnalysis);
if (otherWikipedia != null) {
menu.addSeparator(popup);
menu.addView(otherWikipedia, popup, otherPage, false);
}
return popup;
}
/**
* Create a default popup menu for an image.
*
* @param textPane Text pane.
* @param position Position in the text.
* @param pageAnalysis Page analysis.
* @param image Image.
* @return Popup menu.
*/
protected JPopupMenu createDefaultPopupImage(
MWPane textPane, int position,
PageAnalysis pageAnalysis,
PageElementImage image) {
if (image == null) {
return null;
}
// Initialization
String fullName = wikipedia.getWikiConfiguration().getPageTitle(
Namespace.IMAGE,
image.getImage());
Page page = DataManager.getPage(wikipedia, fullName, null, null, null);
// Menu creation
BasicMenuCreator menu = new BasicMenuCreator();
JPopupMenu popup = menu.createPopupMenu(GT._(
"Image: {0}",
limitTextLength(image.getImage(), 50)));
menu.addCurrentChapter(popup, position, pageAnalysis);
menu.addSeparator(popup);
menu.addView(wikipedia, popup, page, false);
menu.addAnalyze(wikipedia, popup, page);
return popup;
}
/**
* Create a default popup menu for a category.
*
* @param textPane Text pane.
* @param position Position in the text.
* @param pageAnalysis Page analysis.
* @param category Category.
* @return Popup menu.
*/
protected JPopupMenu createDefaultPopupCategory(
MWPane textPane, int position,
PageAnalysis pageAnalysis,
PageElementCategory category) {
if (category == null) {
return null;
}
// Initialization
String fullName = wikipedia.getWikiConfiguration().getPageTitle(
Namespace.CATEGORY,
category.getName());
Page page = DataManager.getPage(wikipedia, fullName, null, null, null);
// Menu creation
BasicMenuCreator menu = new BasicMenuCreator();
JPopupMenu popup = menu.createPopupMenu(GT._(
"Category: {0}",
limitTextLength(category.getName(), 50)));
menu.addCurrentChapter(popup, position, pageAnalysis);
menu.addSeparator(popup);
menu.addView(wikipedia, popup, page, false);
menu.addAnalyze(wikipedia, popup, page);
return popup;
}
/**
* Create a default popup menu for an external link.
*
* @param pageAnalysis Page analysis.
* @param position Position in the text.
* @param link External link.
* @return Popup menu.
*/
protected JPopupMenu createDefaultPopupExternalLink(
PageAnalysis pageAnalysis, int position,
PageElementExternalLink link) {
if (link == null) {
return null;
}
// Menu creation
BasicMenuCreator menu = new BasicMenuCreator();
JPopupMenu popup = menu.createPopupMenu(GT._(
"External link: {0}",
limitTextLength(link.getLink(), 50)));
menu.addCurrentChapter(popup, position, pageAnalysis);
menu.addSeparator(popup);
menu.addItemView(null, popup, link.getLink());
return popup;
}
/**
* Create a default popup menu for a template.
*
* @param pageAnalysis Page analysis.
* @param position Position in the text.
* @param template Template.
* @return Popup menu.
*/
protected JPopupMenu createDefaultPopupTemplate(
PageAnalysis pageAnalysis, int position,
PageElementTemplate template) {
if (template == null) {
return null;
}
// Initialization
String fullName = wikipedia.getWikiConfiguration().getPageTitle(
Namespace.TEMPLATE,
template.getTemplateName());
Page page = DataManager.getPage(wikipedia, fullName, null, null, null);
// Menu creation
BasicMenuCreator menu = new BasicMenuCreator();
JPopupMenu popup = menu.createPopupMenu(GT._(
"Template: {0}",
limitTextLength(template.getTemplateName(), 50)));
menu.addCurrentChapter(popup, position, pageAnalysis);
// Search engines
Map<String, List<SearchEngine>> searchEngines = SearchEngine.getSearchEngines(
wikipedia, template, null);
if ((searchEngines != null) && !searchEngines.isEmpty()) {
menu.addSeparator(popup);
List<String> parameterNames = new ArrayList<>(searchEngines.keySet());
Collections.sort(parameterNames);
for (String parameterName : parameterNames) {
JMenu submenu = new JMenu(GT._("Search using {0}", parameterName));
for (SearchEngine searchEngine : searchEngines.get(parameterName)) {
menu.addItemView(null, submenu, searchEngine.getUrl(), searchEngine.getName());
}
menu.addSubmenu(popup, submenu, 0, 0);
}
}
// General items
menu.addSeparator(popup);
menu.addCheckTemplate(wikipedia, window.getParentComponent(), popup, template);
menu.addView(wikipedia, popup, page, false);
menu.addAnalyze(wikipedia, popup, page);
return popup;
}
/**
* Create a default popup menu for a parameter.
*
* @param pageAnalysis Page analysis.
* @param position Position in the text.
* @param parameter Parameter.
* @return Popup menu.
*/
protected JPopupMenu createDefaultPopupParameter(
PageAnalysis pageAnalysis, int position,
PageElementParameter parameter) {
if (parameter == null) {
return null;
}
// Menu creation
BasicMenuCreator menu = new BasicMenuCreator();
JPopupMenu popup = menu.createPopupMenu(GT._(
"Parameter: {0}",
limitTextLength(parameter.getParameterName(), 50)));
menu.addCurrentChapter(popup, position, pageAnalysis);
return popup;
}
/**
* Create a default popup menu for a function.
*
* @param pageAnalysis Page analysis.
* @param position Position in the text.
* @param function Function.
* @return Popup menu.
*/
protected JPopupMenu createDefaultPopupFunction(
PageAnalysis pageAnalysis, int position,
PageElementFunction function) {
if (function == null) {
return null;
}
// Menu creation
BasicMenuCreator menu = new BasicMenuCreator();
JPopupMenu popup = menu.createPopupMenu(GT._(
"Function: {0}",
limitTextLength(function.getFunctionName(), 50)));
menu.addCurrentChapter(popup, position, pageAnalysis);
return popup;
}
/**
* Create a default popup menu for an ISBN.
*
* @param pageAnalysis Page analysis.
* @param position Position in the text.
* @param isbn ISBN.
* @return Popup menu.
*/
protected JPopupMenu createDefaultPopupISBN(
PageAnalysis pageAnalysis, int position,
PageElementISBN isbn) {
if (isbn == null) {
return null;
}
// Menu creation
BasicMenuCreator menu = new BasicMenuCreator();
JPopupMenu popup = menu.createPopupMenu(GT._(
"ISBN: {0}",
limitTextLength(isbn.getISBN(), 50)));
ISBNInformation infos = ISBNRange.getInformation(isbn.getISBN());
if ((infos != null) && (infos.getTexts() != null)) {
for (String info : infos.getTexts()) {
menu.addDisabledText(popup, info);
}
}
menu.addCurrentChapter(popup, position, pageAnalysis);
return popup;
}
/**
* Create a default popup menu for an ISSN.
*
* @param pageAnalysis Page analysis.
* @param position Position in the text.
* @param issn ISSN.
* @return Popup menu.
*/
protected JPopupMenu createDefaultPopupISSN(
PageAnalysis pageAnalysis, int position,
PageElementISSN issn) {
if (issn == null) {
return null;
}
// Menu creation
BasicMenuCreator menu = new BasicMenuCreator();
JPopupMenu popup = menu.createPopupMenu(GT._(
"ISSN: {0}",
limitTextLength(issn.getISSN(), 50)));
menu.addCurrentChapter(popup, position, pageAnalysis);
return popup;
}
/**
* Limit text length to be used in menus.
*
* @param text Original text.
* @param maxLength Maximum length.
* @return Text with length restricted to maximum length.
*/
protected String limitTextLength(String text, int maxLength) {
if (text == null) {
return null;
}
if (maxLength < 10) {
maxLength = 10;
}
if (text.length() <= maxLength) {
return text;
}
int middle = (maxLength - 3) / 2;
text = text.substring(0, maxLength - middle) +
"..." +
text.substring(text.length() - middle);
return text;
}
}