Newsfeed: use a Java header for RSS title 65/17765/1
Clément DAVID [Thu, 4 Feb 2016 14:31:16 +0000 (15:31 +0100)]
Due to the poor CSS support of the JRE HTMLEditorKit the use of Swing
components is preferred.

Change-Id: I024907944f9b6579bbe365c32f7b93bf8d90d376

scilab/modules/ui_data/src/java/org/scilab/modules/ui_data/newsfeed/NewsFeedController.java
scilab/modules/ui_data/src/java/org/scilab/modules/ui_data/newsfeed/NewsFeedWidget.java
scilab/modules/ui_data/src/java/org/scilab/modules/ui_data/newsfeed/NewsFetcher.java

index 9a0026e..fa5888e 100644 (file)
@@ -101,6 +101,10 @@ public class NewsFeedController implements ActionListener {
         }
     }
 
+    public NewsFetcher getNewsFetcher() {
+        return newsFetcher;
+    }
+
     public News getCurrentNews() {
         return currentNews;
     }
index 530bb74..c643267 100644 (file)
-/*
-* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-* Copyright (C) 2015 - Scilab Enterprises
-*
- * Copyright (C) 2012 - 2016 - Scilab Enterprises
- *
- * This file is hereby licensed under the terms of the GNU GPL v2.0,
- * pursuant to article 5.3.4 of the CeCILL v.2.1.
- * This file was originally licensed under the terms of the CeCILL v2.1,
- * and continues to be available under such terms.
- * For more information, see the COPYING file which you should have received
- * along with this program.
-*
-*/
-
-package org.scilab.modules.ui_data.newsfeed;
-
-import org.scilab.modules.commons.ScilabConstants;
-import org.scilab.modules.commons.gui.FindIconHelper;
-import org.scilab.modules.gui.utils.WebBrowser;
-
-import javax.swing.JPanel;
-import javax.swing.JEditorPane;
-import javax.swing.JScrollPane;
-import javax.swing.text.html.HTMLEditorKit;
-import javax.swing.text.Document;
-import javax.swing.event.HyperlinkEvent;
-import javax.swing.event.HyperlinkListener;
-import javax.swing.SwingUtilities;
-import javax.swing.UIManager;
-
-import javax.swing.text.Element;
-import javax.swing.text.AttributeSet;
-import javax.swing.text.html.HTML;
-
-import java.awt.BorderLayout;
-import java.awt.Font;
-import java.io.File;
-import java.text.SimpleDateFormat;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-/**
- * News feed widget Displays one news at a time.
- * Controlled by NewsFeedController
- * Displays news in HTML format (JEditorPane/HTMLEditorKit)
- * Loads styles from CSS newsfeed.css (in directory ui_data/etc or SCIHOME)
- */
-public class NewsFeedWidget extends JPanel implements NewsFeedEventListener, HyperlinkListener {
-    private static final String NAVIGATION_HTML_ID = "navigation";
-    private static final String PREVIOUS_HTML_ID = "previous";
-    private static final String NEXT_HTML_ID = "next";
-    private static final String NEWS_TITLE_HTML_ID = "news_title";
-    private static final String NEWS_DATE_HTML_ID = "news_date";
-    private static final String NEWS_CONTENT_HTML_ID = "news_content";
-    private static final String NEWS_LINK_HTML_ID = "news_link";
-    private static final String NEWS_DESCRIPTION_HTML_ID = "news_description";
-
-    private NewsFeedController newsFeedController;
-    private JEditorPane editorPane;
-    private JScrollPane scrollPane;
-
-    public NewsFeedWidget(NewsFeedController newsFeedController) {
-        this.newsFeedController = newsFeedController;
-
-        editorPane = new JEditorPane();
-        editorPane.setEditable(false);
-        editorPane.setContentType("text/html");
-
-        // use current look & feel font
-        editorPane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
-        Font font = UIManager.getFont("Label.font");
-        editorPane.setFont(font);
-
-        HTMLEditorKit htmlEditorKit = new HTMLEditorKit();
-        editorPane.setEditorKit(htmlEditorKit);
-        Document doc = htmlEditorKit.createDefaultDocument();
-        editorPane.setDocument(doc);
-
-        htmlEditorKit.getStyleSheet().importStyleSheet(getStyleSheetURL());
-
-        editorPane.addHyperlinkListener(this);
-
-        scrollPane = new JScrollPane(editorPane);
-        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
-        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
-
-        setLayout(new BorderLayout());
-        add(scrollPane, BorderLayout.CENTER);
-    }
-
-    public void newsFeedEventReceived(NewsFeedEvent evt) {
-        switch (evt.getEventType()) {
-            case NewsFeedEvent.NEWS_CHANGED: {
-                displayNews(newsFeedController.getCurrentNews());
-                break;
-            }
-            case NewsFeedEvent.NEWSFEED_ERROR: {
-                displayError(((NewsFeedErrorEvent) evt).getErrorMessage());
-                break;
-            }
-        }
-    }
-
-    public void hyperlinkUpdate(HyperlinkEvent event) {
-        if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
-            String name = null;
-            Element element = event.getSourceElement();
-            AttributeSet atts = element.getAttributes();
-            AttributeSet linkAtts = (AttributeSet)atts.getAttribute(HTML.Tag.A);
-            if (linkAtts != null) {
-                name = (String)linkAtts.getAttribute(HTML.Attribute.NAME);
-            }
-            if (name != null) {
-                if (name.equals("previous")) {
-                    newsFeedController.previousNews();
-                } else if (name.equals("next")) {
-                    newsFeedController.nextNews();
-                }
-            } else {
-                URL url = event.getURL();
-                if (url != null) {
-                    WebBrowser.openUrl(url, event.getDescription());
-                }
-            }
-        }
-    }
-
-    private void displayNews(News news) {
-        StringBuilder newsHtmlBuilder = new StringBuilder();
-
-        // Add navigation links
-        // Previous news icon link
-        String previousIconUrl = getIconURL("go-previous");
-        String previousIconHtml = getImageHtml("previous", previousIconUrl);
-        String previousLinkHtml = getSpanHtml(getLinkHtml("previous", "previous", previousIconHtml), PREVIOUS_HTML_ID);
-        // Next news icon link
-        String nextIconUrl = getIconURL("go-next");
-        String nextIconHtml = getImageHtml("next", nextIconUrl);
-        String nextLinkHtml = getSpanHtml(getLinkHtml("next", "next", nextIconHtml), NEXT_HTML_ID);
-        newsHtmlBuilder.append(getDivHtml(String.format("%s %s", previousLinkHtml, nextLinkHtml), NAVIGATION_HTML_ID));
-
-        if (news.getContent() != null) {
-            // if given, use RSS item content
-            newsHtmlBuilder.append(getDivHtml(news.getTitle(), NEWS_TITLE_HTML_ID));
-            newsHtmlBuilder.append(getDivHtml(news.getContent(), NEWS_CONTENT_HTML_ID));
-        } else {
-            // otherwise get content from title, date, description
-            String newsTitleHtml = getSpanHtml(news.getTitle(), NEWS_TITLE_HTML_ID);
-            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE dd MMM yyyy HH:mm");
-            String dateStr = simpleDateFormat.format(news.getDate());
-            String newsDateHtml = getSpanHtml(dateStr, NEWS_DATE_HTML_ID);
-            newsHtmlBuilder.append(getDivHtml(String.format("%s - %s", newsTitleHtml, newsDateHtml)));
-            newsHtmlBuilder.append(getDivHtml(news.getDescription(), NEWS_DESCRIPTION_HTML_ID));
-        }
-
-        // Add news link if exist
-        if (news.getLink() != null) {
-            newsHtmlBuilder.append(getDivHtml(getLinkHtml(news.getLink(), news.getLink()), NEWS_LINK_HTML_ID));
-        }
-
-        display(getHTML(newsHtmlBuilder));
-    }
-
-    private String getLinkHtml(String name, String url, String description) {
-        return String.format("<a name='%s' href='%s'>%s</a>", name, url, description);
-    }
-
-    private String getLinkHtml(String url, String description) {
-        return String.format("<a href='%s'>%s</a>", url, description);
-    }
-
-    private String getImageHtml(String name, String url) {
-        // Cannot setup margin and border with CSS, bugs of HTMLEditorKit ?
-        return String.format("<img name='%s' src='%s' hspace=2 border='0'/>", name, url);
-    }
-
-    private String getSpanHtml(String spanContent, String spanId) {
-        return String.format("<span id='%s'>%s</span>", spanId, spanContent);
-    }
-
-    private String getDivHtml(String divContent, String divId) {
-        return String.format("<div id='%s'>%s</div>", divId, divContent);
-    }
-
-    private String getDivHtml(String divContent) {
-        return String.format("<div>%s</div>", divContent);
-    }
-
-    private void displayError(String errorMessage) {
-        StringBuilder errMsgHtmlBuilder = new StringBuilder(errorMessage);
-        display(getHTML(errMsgHtmlBuilder));
-    }
-
-    private String getHTML(StringBuilder htmlBuilder) {
-        htmlBuilder.insert(0, "<html><body>");
-        htmlBuilder.append("</body></html>");
-        return htmlBuilder.toString();
-    }
-
-    private void display(String htmlContent) {
-        editorPane.setText(htmlContent);
-        try    {
-            SwingUtilities.invokeLater(new Runnable() {
-                public void run() {
-                    scrollPane.getHorizontalScrollBar().setValue(0);
-                    scrollPane.getVerticalScrollBar().setValue(0);
-                    repaint();
-                }
-            });
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    private URL getStyleSheetURL() {
-        File settingsFile = new File(ScilabConstants.SCIHOME + "/newsfeed.css");
-        if (!settingsFile.exists()) {
-            settingsFile = new File(ScilabConstants.SCI + "/modules/ui_data/etc/newsfeed.css");
-        }
-        if (settingsFile.exists()) {
-            try {
-                return settingsFile.toURI().toURL();
-            } catch (MalformedURLException e) {
-                e.printStackTrace();
-                return null;
-            }
-        } else {
-            return null;
-        }
-    }
-
-    private String getIconURL(String iconName) {
-        String iconFilePath = FindIconHelper.findIcon(iconName);
-        File iconFile = new File(iconFilePath);
-        if (iconFile.exists()) {
-            try {
-                return iconFile.toURI().toURL().toString();
-            } catch (MalformedURLException e) {
-                return null;
-            }
-        } else {
-            return null;
-        }
-    }
-}
+/*\r
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab\r
+ * Copyright (C) 2015-2016 - Scilab Enterprises - Simon Marchetto\r
+ * Copyright (C) 2016 - Scilab Enterprises - Clement David\r
+ *\r
+ * Copyright (C) 2012 - 2016 - Scilab Enterprises\r
+ *\r
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,\r
+ * pursuant to article 5.3.4 of the CeCILL v.2.1.\r
+ * This file was originally licensed under the terms of the CeCILL v2.1,\r
+ * and continues to be available under such terms.\r
+ * For more information, see the COPYING file which you should have received\r
+ * along with this program.\r
+ *\r
+ */\r
+\r
+package org.scilab.modules.ui_data.newsfeed;\r
+\r
+import org.scilab.modules.commons.ScilabConstants;\r
+import org.scilab.modules.commons.gui.FindIconHelper;\r
+import org.scilab.modules.gui.utils.WebBrowser;\r
+\r
+import javax.swing.JPanel;\r
+import javax.swing.JEditorPane;\r
+import javax.swing.JScrollPane;\r
+import javax.swing.text.html.HTMLEditorKit;\r
+import javax.swing.text.Document;\r
+import javax.swing.event.HyperlinkEvent;\r
+import javax.swing.event.HyperlinkListener;\r
+import javax.swing.SwingUtilities;\r
+import javax.swing.UIManager;\r
+\r
+import java.awt.BorderLayout;\r
+import java.awt.Font;\r
+import java.awt.event.ActionEvent;\r
+import java.io.File;\r
+import java.text.SimpleDateFormat;\r
+\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\r
+import java.util.logging.Level;\r
+import java.util.logging.Logger;\r
+import javax.swing.AbstractAction;\r
+import javax.swing.Action;\r
+import javax.swing.ImageIcon;\r
+import javax.swing.JButton;\r
+\r
+/**\r
+ * News feed widget Displays one news at a time.\r
+ * Controlled by NewsFeedController\r
+ * Displays news in HTML format (JEditorPane/HTMLEditorKit)\r
+ * Loads styles from CSS newsfeed.css (in directory ui_data/etc or SCIHOME)\r
+ */\r
+public class NewsFeedWidget extends JPanel implements NewsFeedEventListener, HyperlinkListener {\r
+    private static final String NEWS_DATE_HTML_ID = "news_date";\r
+    private static final String NEWS_CONTENT_HTML_ID = "news_content";\r
+    private static final String NEWS_LINK_HTML_ID = "news_link";\r
+    private static final String NEWS_DESCRIPTION_HTML_ID = "news_description";\r
+\r
+    private final NewsFeedController newsFeedController;\r
+    private final JEditorPane editorPane;\r
+    private final JScrollPane scrollPane;\r
+    private final JPanel headerPane;\r
+    private final JButton headerButton;\r
+\r
+    public NewsFeedWidget(NewsFeedController newsFeedController) {\r
+        this.newsFeedController = newsFeedController;\r
+\r
+        editorPane = new JEditorPane();\r
+        editorPane.setEditable(false);\r
+        editorPane.setContentType("text/html");\r
+\r
+        // use current look & feel font\r
+        editorPane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);\r
+        Font font = UIManager.getFont("Label.font");\r
+        editorPane.setFont(font);\r
+\r
+        HTMLEditorKit htmlEditorKit = new HTMLEditorKit();\r
+        editorPane.setEditorKit(htmlEditorKit);\r
+        Document doc = htmlEditorKit.createDefaultDocument();\r
+        editorPane.setDocument(doc);\r
+\r
+        htmlEditorKit.getStyleSheet().importStyleSheet(getStyleSheetURL());\r
+\r
+        editorPane.addHyperlinkListener(this);\r
+\r
+        headerButton = new JButton();\r
+        headerPane = new JPanel(new BorderLayout());\r
+        headerPane.add(new JButton(new AbstractAction(null, new ImageIcon(FindIconHelper.findIcon("go-previous"))) {\r
+            @Override\r
+            public void actionPerformed(ActionEvent e) {\r
+                newsFeedController.previousNews();\r
+            }\r
+        }), BorderLayout.WEST);\r
+        headerPane.add(headerButton, BorderLayout.CENTER);\r
+        headerPane.add(new JButton(new AbstractAction(null, new ImageIcon(FindIconHelper.findIcon("go-next"))) {\r
+            @Override\r
+            public void actionPerformed(ActionEvent e) {\r
+                newsFeedController.nextNews();\r
+            }\r
+        }), BorderLayout.EAST);\r
+\r
+        scrollPane = new JScrollPane(editorPane);\r
+        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);\r
+        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);\r
+\r
+        setLayout(new BorderLayout());\r
+        add(headerPane, BorderLayout.NORTH);\r
+        add(scrollPane, BorderLayout.CENTER);\r
+    }\r
+\r
+    public void newsFeedEventReceived(NewsFeedEvent evt) {\r
+        switch (evt.getEventType()) {\r
+            case NewsFeedEvent.NEWS_CHANGED: {\r
+                displayNews(newsFeedController.getCurrentNews());\r
+                break;\r
+            }\r
+            case NewsFeedEvent.NEWSFEED_ERROR: {\r
+                displayError(((NewsFeedErrorEvent) evt).getErrorMessage());\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+    public void hyperlinkUpdate(HyperlinkEvent event) {\r
+        if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {\r
+            URL url = event.getURL();\r
+            if (url != null) {\r
+                WebBrowser.openUrl(url, event.getDescription());\r
+            }\r
+        }\r
+    }\r
+\r
+    private void displayNews(News news) {\r
+        StringBuilder newsHtmlBuilder = new StringBuilder();\r
+\r
+        if (news.getContent() != null) {\r
+            // if given, use RSS item content\r
+            newsHtmlBuilder.append(getDivHtml(news.getContent(), NEWS_CONTENT_HTML_ID));\r
+        } else {\r
+            // otherwise get content : date, description\r
+            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE dd MMM yyyy HH:mm");\r
+            String dateStr = simpleDateFormat.format(news.getDate());\r
+            String newsDateHtml = getSpanHtml(dateStr, NEWS_DATE_HTML_ID);\r
+            newsHtmlBuilder.append(getDivHtml(newsDateHtml));\r
+            newsHtmlBuilder.append(getDivHtml(news.getDescription(), NEWS_DESCRIPTION_HTML_ID));\r
+        }\r
+\r
+        // Add news link if exist\r
+        if (news.getLink() != null) {\r
+            newsHtmlBuilder.append(getDivHtml(getLinkHtml(news.getLink(), news.getLink()), NEWS_LINK_HTML_ID));\r
+        }\r
+\r
+        display(new AbstractAction(news.getTitle()) {\r
+            @Override\r
+            public void actionPerformed(ActionEvent e) {\r
+                try {\r
+                    WebBrowser.openUrl(new URL(news.getLink()), news.getLink());\r
+                } catch (MalformedURLException ex) {\r
+                    Logger.getLogger(NewsFeedWidget.class.getName()).log(Level.SEVERE, null, ex);\r
+                }\r
+            }\r
+        }, getHTML(newsHtmlBuilder));\r
+    }\r
+\r
+    private String getLinkHtml(String url, String description) {\r
+        return String.format("<a href='%s'>%s</a>", url, description);\r
+    }\r
+\r
+    private String getSpanHtml(String spanContent, String spanId) {\r
+        return String.format("<span id='%s'>%s</span>", spanId, spanContent);\r
+    }\r
+\r
+    private String getDivHtml(String divContent, String divId) {\r
+        return String.format("<div id='%s'>%s</div>", divId, divContent);\r
+    }\r
+\r
+    private String getDivHtml(String divContent) {\r
+        return String.format("<div>%s</div>", divContent);\r
+    }\r
+\r
+    private void displayError(String errorMessage) {\r
+        StringBuilder errMsgHtmlBuilder = new StringBuilder(errorMessage);\r
+        display(new AbstractAction() {\r
+            @Override\r
+            public void actionPerformed(ActionEvent e) {\r
+                URL url = newsFeedController.getNewsFetcher().getURL();\r
+                WebBrowser.openUrl(url, url.toString());\r
+            }\r
+        }, getHTML(errMsgHtmlBuilder));\r
+    }\r
+\r
+    private String getHTML(StringBuilder htmlBuilder) {\r
+        htmlBuilder.insert(0, "<html><body>");\r
+        htmlBuilder.append("</body></html>");\r
+        return htmlBuilder.toString();\r
+    }\r
+\r
+    private void display(final Action titleAction, final String htmlContent) {\r
+        try    {\r
+            SwingUtilities.invokeLater(new Runnable() {\r
+                public void run() {\r
+                    scrollPane.getHorizontalScrollBar().setValue(0);\r
+                    scrollPane.getVerticalScrollBar().setValue(0);\r
+\r
+                    headerButton.setAction(titleAction);\r
+                    headerButton.setToolTipText(titleAction.getValue(Action.NAME).toString());\r
+\r
+                    editorPane.setText(htmlContent);\r
+                }\r
+            });\r
+        } catch (Exception e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    private URL getStyleSheetURL() {\r
+        File settingsFile = new File(ScilabConstants.SCIHOME + "/newsfeed.css");\r
+        if (!settingsFile.exists()) {\r
+            settingsFile = new File(ScilabConstants.SCI + "/modules/ui_data/etc/newsfeed.css");\r
+        }\r
+        if (settingsFile.exists()) {\r
+            try {\r
+                return settingsFile.toURI().toURL();\r
+            } catch (MalformedURLException e) {\r
+                e.printStackTrace();\r
+                return null;\r
+            }\r
+        } else {\r
+            return null;\r
+        }\r
+    }\r
+}\r
index e4ecd6c..9d09079 100644 (file)
@@ -47,6 +47,11 @@ public class NewsFetcher {
         rssURL = new URL(urlSetting);\r
     }\r
 \r
+    public URL getURL() {\r
+        return rssURL;\r
+    }\r
+\r
+\r
     public boolean isOK() {\r
         return rssURL != null;\r
     }\r