/* * Jajuk * Copyright (C) The Jajuk Team * http://jajuk.info * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ package org.jajuk.ui.views; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.FileNotFoundException; import java.net.URL; import java.util.HashSet; import java.util.Locale; import java.util.Set; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JToggleButton; import javax.swing.JToolBar; import net.miginfocom.swing.MigLayout; import org.jajuk.events.JajukEvent; import org.jajuk.events.JajukEvents; import org.jajuk.events.ObservationManager; import org.jajuk.services.players.QueueModel; import org.jajuk.ui.actions.ActionManager; import org.jajuk.ui.actions.JajukAction; import org.jajuk.ui.actions.JajukActions; import org.jajuk.ui.widgets.JajukHtmlPanel; import org.jajuk.ui.widgets.JajukJToolbar; import org.jajuk.util.Conf; import org.jajuk.util.Const; import org.jajuk.util.IconLoader; import org.jajuk.util.JajukIcons; import org.jajuk.util.LocaleManager; import org.jajuk.util.Messages; import org.jajuk.util.UtilFeatures; import org.jajuk.util.UtilSystem; import org.jajuk.util.log.Log; /** * Wikipedia view. */ public class WikipediaView extends ViewAdapter implements ActionListener { /** Generated serialVersionUID. */ private static final long serialVersionUID = 1L; JLabel jlLanguage; JComboBox jcbLanguage; /** Cobra web browser. */ JajukHtmlPanel browser; JButton jbCopy; JButton jbLaunchInExternalBrowser; JToggleButton jbArtistSearch; JToggleButton jbAlbumSearch; JToggleButton jbTrackSearch; /** Language index. */ int indexLang = 0; /** * . */ enum Type { ARTIST, ALBUM, TRACK } Type type = Type.ARTIST; /** Current search. */ String search = null; /* * (non-Javadoc) * * @see org.jajuk.ui.views.IView#getDesc() */ @Override public String getDesc() { return Messages.getString("WikipediaView.0"); } /* * (non-Javadoc) * * @see org.jajuk.ui.views.IView#populate() */ @Override public void initUI() { jlLanguage = new JLabel(Messages.getString("WikipediaView.1")); jcbLanguage = new JComboBox(); for (String sDesc : LocaleManager.getLocalesDescs()) { jcbLanguage.addItem(sDesc); } // get stored language jcbLanguage.setSelectedItem(LocaleManager.getDescForLocale(Conf .getString(Const.CONF_WIKIPEDIA_LANGUAGE))); jcbLanguage.addActionListener(this); // Buttons JajukAction aCopy = ActionManager.getAction(JajukActions.COPY_TO_CLIPBOARD); jbCopy = new JButton(aCopy); if (UtilSystem.isBrowserSupported()) { jbLaunchInExternalBrowser = new JButton( ActionManager.getAction(JajukActions.LAUNCH_IN_BROWSER)); // Remove text inside the buttons jbLaunchInExternalBrowser.setText(null); } jbCopy.setText(null); ButtonGroup bg = new ButtonGroup(); jbArtistSearch = new JToggleButton(IconLoader.getIcon(JajukIcons.ARTIST), false); jbArtistSearch.setToolTipText(Messages.getString("WikipediaView.5")); // Select artist search (default) jbArtistSearch.setSelected(true); jbArtistSearch.addActionListener(this); jbAlbumSearch = new JToggleButton(IconLoader.getIcon(JajukIcons.ALBUM), true); jbAlbumSearch.setToolTipText(Messages.getString("WikipediaView.6")); jbAlbumSearch.addActionListener(this); jbTrackSearch = new JToggleButton(IconLoader.getIcon(JajukIcons.TRACK), false); jbTrackSearch.setToolTipText(Messages.getString("WikipediaView.7")); jbTrackSearch.addActionListener(this); // Group this three mutual exclusive buttons bg.add(jbArtistSearch); bg.add(jbAlbumSearch); bg.add(jbTrackSearch); JToolBar jtb = new JajukJToolbar(); jtb.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); // Add items jtb.add(jbArtistSearch); jtb.add(jbAlbumSearch); jtb.add(jbTrackSearch); jtb.addSeparator(); jtb.add(jbCopy); if (UtilSystem.isBrowserSupported()) { jtb.add(jbLaunchInExternalBrowser); jtb.addSeparator(); } jtb.add(jcbLanguage); JPanel jpCommand = new JPanel(); jpCommand.setBorder(BorderFactory.createEtchedBorder()); jpCommand.setLayout(new FlowLayout(FlowLayout.LEFT)); jpCommand.add(jtb); // global layout setLayout(new MigLayout("ins 0", "[grow]", "[][grow]")); browser = new JajukHtmlPanel(); add(jpCommand, "growx,wrap"); add(browser, "grow"); // Display default page at startup is none track launch // avoid to launch this if a track is playing // to avoid thread concurrency if (QueueModel.getPlayingFile() == null) { reset(); } // subscriptions to events ObservationManager.register(WikipediaView.this); // Force initial message refresh UtilFeatures.updateStatus(this); } /* (non-Javadoc) * @see org.jajuk.events.Observer#getRegistrationKeys() */ @Override public Set<JajukEvents> getRegistrationKeys() { Set<JajukEvents> eventSubjectSet = new HashSet<JajukEvents>(); eventSubjectSet.add(JajukEvents.FILE_LAUNCHED); eventSubjectSet.add(JajukEvents.ZERO); eventSubjectSet.add(JajukEvents.WEBRADIO_LAUNCHED); eventSubjectSet.add(JajukEvents.ARTIST_CHANGED); eventSubjectSet.add(JajukEvents.ALBUM_CHANGED); eventSubjectSet.add(JajukEvents.TRACK_CHANGED); eventSubjectSet.add(JajukEvents.PERSPECTIVE_CHANGED); return eventSubjectSet; } /* * (non-Javadoc) * * @see org.jajuk.ui.Observer#update(java.lang.String) */ @Override public void update(JajukEvent event) { JajukEvents subject = event.getSubject(); // Make a search after a stop period if (subject.equals(JajukEvents.FILE_LAUNCHED) || subject.equals(JajukEvents.PERSPECTIVE_CHANGED) || subject.equals(JajukEvents.WEBRADIO_LAUNCHED)) { // If current state is stopped, reset page if (!QueueModel.isPlayingTrack()) { reset(); return; } // Launch search launchSearch(false); } // Reset the page when stopping else if (subject.equals(JajukEvents.ZERO)) { reset(); } // User changed current track tags, so we have to reload // new artist wikipedia page else if (subject.equals(JajukEvents.ARTIST_CHANGED) || subject.equals(JajukEvents.ALBUM_CHANGED) || subject.equals(JajukEvents.TRACK_CHANGED)) { update(new JajukEvent(JajukEvents.FILE_LAUNCHED)); } } /** * Perform wikipedia search. * * @param bForceReload force the page display */ private void launchSearch(final boolean bForceReload) { // do nothing without internet, // TODO: display useful text that states this... if (Conf.getBoolean(Const.CONF_NETWORK_NONE_INTERNET_ACCESS)) { try { browser.setUnknown(); } catch (Exception e) { Log.error(e); } return; } Thread t = new Thread("Wikipedia Search Thread") { @Override public void run() { try { String lSearch = null; if (QueueModel.getPlayingFile() != null) { if (type == Type.ARTIST) { lSearch = QueueModel.getPlayingFile().getTrack().getArtist().getName2(); // don't display page if item is unknown if (Messages.getString(UNKNOWN_ARTIST).equals(lSearch)) { lSearch = null; } } else if (type == Type.ALBUM) { lSearch = QueueModel.getPlayingFile().getTrack().getAlbum().getName2(); // don't display page if item is unknown if (Messages.getString(UNKNOWN_ALBUM).equals(lSearch)) { lSearch = null; } } else if (type == Type.TRACK) { lSearch = QueueModel.getPlayingFile().getTrack().getName(); } } // If search is still null, display an nothing found page if (lSearch == null) { browser.setUnknown(); return; } // Avoid reloading an existing page if (!bForceReload && lSearch.equals(WikipediaView.this.search)) { return; } // Store the search to avoid future identical searches WikipediaView.this.search = lSearch; // Wikipedia now redirect to HTTPS automatically so we need to use the // HTTPS URL URL url = new URL(("https://" + LocaleManager.getLocaleForDesc((String) jcbLanguage.getSelectedItem()) + ".wikipedia.org/wiki/" + lSearch).replaceAll(" ", "_")); Log.debug("Wikipedia search: {{" + url + "}}"); jbCopy.putClientProperty(Const.DETAIL_CONTENT, url.toExternalForm()); if (UtilSystem.isBrowserSupported()) { jbLaunchInExternalBrowser.putClientProperty(Const.DETAIL_CONTENT, url.toExternalForm()); } browser.setURL(url, LocaleManager .getLocaleForDesc((String) jcbLanguage.getSelectedItem()).toString()); } catch (FileNotFoundException e) { // only report a warning for FileNotFoundException and do not show a // stacktrace in the logfile as it is expected in many cases where the // name is not found on Wikipedia Log.warn("Could not load URL, no content found at specified address: {{" + e.getMessage() + "}}"); } catch (Exception e) { Log.error(e); } } }; t.setPriority(Thread.MIN_PRIORITY); t.start(); } /* * Reset view */ /** * Reset. * */ private void reset() { // Reset current search this.search = null; // Display jajuk page (in a thread to avoid freezing UI) new Thread("Wikipedia Reset Thread") { @Override public void run() { if (browser != null) { try { browser.clearDocument(); browser.setToolTipText(""); } catch (Exception e) { Log.error(e); } } } }.start(); } /* * (non-Javadoc) * * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent) */ @Override public void actionPerformed(ActionEvent arg0) { if (arg0.getSource() == jcbLanguage) { // update index Locale locale = LocaleManager.getLocaleForDesc((String) jcbLanguage.getSelectedItem()); Conf.setProperty(Const.CONF_WIKIPEDIA_LANGUAGE, locale.getLanguage()); // force launch wikipedia search for this language launchSearch(true); } else if (arg0.getSource() == jbAlbumSearch) { type = Type.ALBUM; // force event launchSearch(true); } else if (arg0.getSource() == jbArtistSearch) { type = Type.ARTIST; // force event launchSearch(true); } else if (arg0.getSource() == jbTrackSearch) { type = Type.TRACK; // force event launchSearch(true); } } }