From: jsurfer Date: Sat, 9 Oct 2004 14:03:31 +0000 (+0000) Subject: RSS news reader; initially copied from "all the news" X-Git-Url: http://secure.phpeclipse.com RSS news reader; initially copied from "all the news" --- diff --git a/archive/net.sourceforge.phpeclipse.news/.classpath b/archive/net.sourceforge.phpeclipse.news/.classpath new file mode 100644 index 0000000..0845836 --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/archive/net.sourceforge.phpeclipse.news/.cvsignore b/archive/net.sourceforge.phpeclipse.news/.cvsignore new file mode 100644 index 0000000..c865ab9 --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/.cvsignore @@ -0,0 +1,7 @@ +build.xml +org.jnegre.allthenews_*.*.*.jar +bin +allthenews.jar +allthenewssrc.zip +patch_*.txt +todo.txt diff --git a/archive/net.sourceforge.phpeclipse.news/.project b/archive/net.sourceforge.phpeclipse.news/.project new file mode 100644 index 0000000..aecfda3 --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/.project @@ -0,0 +1,29 @@ + + + net.sourceforge.phpeclipse.news + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.team.cvs.core.cvsnature + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/archive/net.sourceforge.phpeclipse.news/.settings/org.eclipse.core.resources.prefs b/archive/net.sourceforge.phpeclipse.news/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..4e795ad --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,3 @@ +#Tue Oct 05 18:40:07 CEST 2004 +eclipse.preferences.version=1 +encoding//src/net/sourceforge/phpeclipse/news/messages.properties=8859_1 diff --git a/archive/net.sourceforge.phpeclipse.news/about.html b/archive/net.sourceforge.phpeclipse.news/about.html new file mode 100644 index 0000000..d16f631 --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/about.html @@ -0,0 +1,238 @@ + + + + Common Public License - v 1.0 + + + +

Common Public License - v 1.0 +

+

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER +THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR +DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS +AGREEMENT. +

+

1. DEFINITIONS +

"Contribution" means: + +

+ + + +

+

"Contributor" means any person or entity that distributes the +Program. +

+

"Licensed Patents " mean patent claims licensable by a +Contributor which are necessarily infringed by the use or sale of its +Contribution alone or when combined with the Program. + +

+

"Program" means the Contributions +distributed in accordance with this Agreement. +

+

"Recipient" means anyone who receives the Program under this +Agreement, including all Contributors. +

+

2. GRANT OF RIGHTS +

+ + + + + + + + +

3. REQUIREMENTS +

A Contributor may choose to distribute the Program in +object code form under its own license agreement, provided that: +

+ + + + + + + +

When the Program is made available in source code form: + +

+ +

+

Contributors +may not remove or alter any copyright notices contained within the Program. + +

+

Each Contributor must identify itself as the originator of its +Contribution, if any, in a manner that reasonably allows subsequent Recipients +to identify the originator of the Contribution. +

+

4. COMMERCIAL DISTRIBUTION +

Commercial distributors of software may accept certain +responsibilities with respect to end users, business partners and the like. +While this license is intended to facilitate the commercial use of the Program, +the Contributor who includes the Program in a commercial product offering should +do so in a manner which does not create potential liability for other +Contributors. Therefore, if a Contributor includes the Program in a commercial +product offering, such Contributor ("Commercial Contributor") hereby agrees to +defend and indemnify every other Contributor ("Indemnified Contributor") against +any losses, damages and costs (collectively "Losses") arising from claims, +lawsuits and other legal actions brought by a third party against the +Indemnified Contributor to the extent caused by the acts or omissions of such +Commercial Contributor in connection with its distribution of the Program in a +commercial product offering. The obligations in this section do not apply to any +claims or Losses relating to any actual or alleged intellectual property +infringement. In order to qualify, an Indemnified Contributor must: a) promptly +notify the Commercial Contributor in writing of such claim, and b) allow the +Commercial Contributor to control, and cooperate with the Commercial Contributor +in, the defense and any related settlement negotiations. The Indemnified +Contributor may participate in any such claim at its own expense. +

+

For example, a Contributor might include the Program in a +commercial product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance claims, or +offers warranties related to Product X, those performance claims and warranties +are such Commercial Contributor's responsibility alone. Under this section, the +Commercial Contributor would have to defend claims against the other +Contributors related to those performance claims and warranties, and if a court +requires any other Contributor to pay any damages as a result, the Commercial +Contributor must pay those damages. + +

+

5. NO WARRANTY +

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS +PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR +CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A +PARTICULAR PURPOSE. Each Recipient is solely responsible for +determining the appropriateness of using and distributing the Program and assumes all risks associated with its +exercise of rights under this Agreement, including but not +limited to the risks and costs of program errors, compliance with applicable +laws, damage to or loss of data, programs or equipment, and +unavailability or interruption of operations. +

+

6. DISCLAIMER OF LIABILITY +

EXCEPT AS EXPRESSLY SET FORTH IN THIS +AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + +(INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR +THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGES. +

+

7. GENERAL +

If any provision of this Agreement is +invalid or unenforceable under applicable law, it shall not affect the validity +or enforceability of the remainder of the terms of this Agreement, and without +further action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable. +

+

If Recipient institutes patent litigation against a Contributor +with respect to a patent applicable to software (including a cross-claim or +counterclaim in a lawsuit), then any patent licenses granted by that Contributor +to such Recipient under this Agreement shall terminate as of the date such +litigation is filed. In addition, if Recipient institutes patent litigation +against any entity (including a cross-claim or counterclaim in a lawsuit) +alleging that the Program itself (excluding combinations of the Program with +other software or hardware) infringes such Recipient's patent(s), then such +Recipient's rights granted under Section 2(b) shall terminate as of the date +such litigation is filed. +

+

All Recipient's rights under this Agreement shall terminate if +it fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of time after +becoming aware of such noncompliance. If all Recipient's rights under this +Agreement terminate, Recipient agrees to cease use and distribution of the +Program as soon as reasonably practicable. However, Recipient's obligations +under this Agreement and any licenses granted by Recipient relating to the +Program shall continue and survive. +

+

Everyone is permitted +to copy and distribute copies of this Agreement, but in order to avoid +inconsistency the Agreement is copyrighted and may only be modified in the +following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to + +time. No one other than the Agreement +Steward has the right to modify this Agreement. IBM is the initial Agreement +Steward. IBM may assign the responsibility to serve as the Agreement Steward to +a suitable separate entity. Each new version of the +Agreement will be given a distinguishing version number. The Program (including +Contributions) may always be distributed subject to the version of the Agreement +under which it was received. In addition, after a new version of the Agreement +is published, Contributor may elect to distribute the Program (including its +Contributions) under the new version. +Except as expressly stated in Sections 2(a) and 2(b) above, +Recipient receives no rights or licenses to the intellectual property of any +Contributor under this Agreement, whether expressly, by +implication, estoppel or otherwise. All +rights in the Program not expressly granted under this Agreement are +reserved. +

+

This Agreement is governed by the laws of the State of New York +and the intellectual property laws of the United States of America. No party to +this Agreement will bring a legal action under this Agreement more than one year +after the cause of action arose. Each party waives its rights to a jury trial in +any resulting litigation. +

+

\ No newline at end of file diff --git a/archive/net.sourceforge.phpeclipse.news/build.properties b/archive/net.sourceforge.phpeclipse.news/build.properties new file mode 100644 index 0000000..6262ab8 --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/build.properties @@ -0,0 +1,11 @@ +bin.includes = icons/,\ + plugin.xml,\ + allthenewssrc.zip,\ + about.html,\ + lib/,\ + allthenews.jar,\ + default_feeds.properties,\ + changes.txt +src.includes = src/ +source.allthenews.jar = src/ +bin.excludes = icons/*.xcf diff --git a/archive/net.sourceforge.phpeclipse.news/default_feeds.properties b/archive/net.sourceforge.phpeclipse.news/default_feeds.properties new file mode 100644 index 0000000..474b96a --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/default_feeds.properties @@ -0,0 +1,16 @@ +#This is the list of default feeds. +#The format is url=title +#Beware that characters such as : or = must be escaped in urls + +http\://www.phpeclipse.de/tiki-forums_rss.php=PHPeclipse - User Forums +http\://www.phpeclipse.de/tiki-forum_rss_de.php=PHPeclipse - deutsches Benutzer Forum +http\://www.phpeclipse.de/tiki-wiki_rss.php=PHPeclipse - Wiki +http\://www.eclipseproject.de/backend.php=EclipseProject.de - News +http\://www.eclipseproject.de/backendforum1.php=EclipseProject.de - Eclipse als IDE nutzen +http\://www.eclipseproject.de/backendforum4.php=EclipseProject.de - Eclipse Plugins benutzen +http\://www.eclipseproject.de/backendforum2.php=EclipseProject.de - Eclipse Plugins entwickeln +http\://www.eclipseproject.de/backendforum8.php=EclipseProject.de - SWT/JFace/RCP +http\://www.php.net/news.rss=php.net News +http\://www.jsurfer.org/backend.php=JSurfer.org +http\://today.java.net/pub/q/java_today_rss?x-ver\=1.0=Java.net +http\://eclipse-plugins.2y.net/eclipse/plugins_backend.jsp?what\=newandupdated=EclipsePlugins \ No newline at end of file diff --git a/archive/net.sourceforge.phpeclipse.news/icons/clear.gif b/archive/net.sourceforge.phpeclipse.news/icons/clear.gif new file mode 100644 index 0000000..2558326 Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.news/icons/clear.gif differ diff --git a/archive/net.sourceforge.phpeclipse.news/icons/external_browser.gif b/archive/net.sourceforge.phpeclipse.news/icons/external_browser.gif new file mode 100644 index 0000000..220c134 Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.news/icons/external_browser.gif differ diff --git a/archive/net.sourceforge.phpeclipse.news/icons/headlines.png b/archive/net.sourceforge.phpeclipse.news/icons/headlines.png new file mode 100644 index 0000000..9b38600 Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.news/icons/headlines.png differ diff --git a/archive/net.sourceforge.phpeclipse.news/icons/led_dark_green.gif b/archive/net.sourceforge.phpeclipse.news/icons/led_dark_green.gif new file mode 100644 index 0000000..5f0ca90 Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.news/icons/led_dark_green.gif differ diff --git a/archive/net.sourceforge.phpeclipse.news/icons/led_light_green.gif b/archive/net.sourceforge.phpeclipse.news/icons/led_light_green.gif new file mode 100644 index 0000000..a755dfd Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.news/icons/led_light_green.gif differ diff --git a/archive/net.sourceforge.phpeclipse.news/icons/led_red.gif b/archive/net.sourceforge.phpeclipse.news/icons/led_red.gif new file mode 100644 index 0000000..7941b10 Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.news/icons/led_red.gif differ diff --git a/archive/net.sourceforge.phpeclipse.news/icons/led_yellow.gif b/archive/net.sourceforge.phpeclipse.news/icons/led_yellow.gif new file mode 100644 index 0000000..eafb8d9 Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.news/icons/led_yellow.gif differ diff --git a/archive/net.sourceforge.phpeclipse.news/icons/leds.xcf b/archive/net.sourceforge.phpeclipse.news/icons/leds.xcf new file mode 100644 index 0000000..8aaa3ee Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.news/icons/leds.xcf differ diff --git a/archive/net.sourceforge.phpeclipse.news/icons/link.gif b/archive/net.sourceforge.phpeclipse.news/icons/link.gif new file mode 100644 index 0000000..2b78f04 Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.news/icons/link.gif differ diff --git a/archive/net.sourceforge.phpeclipse.news/icons/news.gif b/archive/net.sourceforge.phpeclipse.news/icons/news.gif new file mode 100644 index 0000000..3d2b8e5 Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.news/icons/news.gif differ diff --git a/archive/net.sourceforge.phpeclipse.news/icons/refresh.gif b/archive/net.sourceforge.phpeclipse.news/icons/refresh.gif new file mode 100644 index 0000000..9f6c9b1 Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.news/icons/refresh.gif differ diff --git a/archive/net.sourceforge.phpeclipse.news/lib/xmlrpc-1.2-b1.jar b/archive/net.sourceforge.phpeclipse.news/lib/xmlrpc-1.2-b1.jar new file mode 100644 index 0000000..cc67714 Binary files /dev/null and b/archive/net.sourceforge.phpeclipse.news/lib/xmlrpc-1.2-b1.jar differ diff --git a/archive/net.sourceforge.phpeclipse.news/plugin.xml b/archive/net.sourceforge.phpeclipse.news/plugin.xml new file mode 100644 index 0000000..b503f7f --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/plugin.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/Channel.java b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/Channel.java new file mode 100644 index 0000000..8b22c55 --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/Channel.java @@ -0,0 +1,194 @@ +package net.sourceforge.phpeclipse.news; + +import java.io.InputStream; +import java.io.PushbackInputStream; +import java.net.URL; +import java.net.URLConnection; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.HashSet; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.eclipse.core.runtime.Preferences; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +/** + * @author jnegre - http://www.jnegre.org/ + * + * (c)Copyright 2002 Jérôme Nègre + * + */ +public class Channel { + + private final String url; + private final String title; + + private boolean refreshing = false; + private String errorMessage = null; + private boolean unread = false; + + private ArrayList items = new ArrayList(); + private HashSet readUids = null; + + /** + * Constructor for Channel. + */ + public Channel(String title, String url) { + this(title, url, null); + } + + public Channel(String title, String url, HashSet readUids) { + this.title = title; + this.url = url; + this.readUids = readUids; + } + + + public void update() { + update(Plugin.getDefault().getPluginPreferences()); + } + + + public void update(Preferences prefs) { + ArrayList newItems = new ArrayList(); + String newErrorMessage = null; + try { + + URLConnection conn = new URL(url).openConnection(); + conn.setRequestProperty("User-Agent", Plugin.userAgent); + if(prefs.getBoolean(Plugin.FORCE_CACHE_PREFERENCE)) { + conn.setRequestProperty("Pragma", "no-cache"); + conn.setRequestProperty("Cache-Control", "no-cache"); + } + InputStream stream = conn.getInputStream(); + + /* workaround a bug of crimson (it seems to ignore the encoding + * if it does not get it the first time it reads bytes from + * the stream. We use a PushbackInputStream to be sure that the + * encoding declaration is in the buffer) + */ + PushbackInputStream pbStream = new PushbackInputStream(stream,64); + byte[] buffer = new byte[64]; + int pos = 0; + while(pos != 64) { + pos += pbStream.read(buffer, pos, 64-pos); + } + pbStream.unread(buffer); + //end workaround + + DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + InputSource inputSource = new InputSource(pbStream); + Document doc = parser.parse(inputSource); + pbStream.close(); + NodeList itemNodes = doc.getElementsByTagName("item"); + for (int i = 0; i < itemNodes.getLength(); i++) { + Item aNewItem = new Item(this, (Element) itemNodes.item(i)); + if(aNewItem.isBanned()) continue; + if(readUids!=null && readUids.remove(aNewItem.getUID())) { + aNewItem.setReadFlag(true); + } + int indexOld = items.indexOf(aNewItem); + if(indexOld != -1) { + newItems.add(items.get(indexOld)); + } else { + newItems.add(aNewItem); + } + + } + this.readUids = null; + } catch(UnknownHostException e) { + // no connection to internet + } catch(Exception e) { + newErrorMessage = e.toString(); + Plugin.logInfo("Error in channel update",e); + } + + synchronized(this) { + this.errorMessage = newErrorMessage; + if(newErrorMessage == null) { + this.items = newItems; + computeUnRead(); + } + } + } + + /** + * Returns the url. + * @return String + */ + public String getUrl() { + return url; + } + + /** + * Returns the errorMessage. + * @return String + */ + public synchronized String getErrorMessage() { + return errorMessage; + } + + /** + * Returns the items. + * @return ArrayList + */ + public synchronized ArrayList getItems() { + return new ArrayList(items); + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + return "Channel at "+url; + } + + /** + * Returns the title. + * @return String + */ + public String getTitle() { + return title; + } + + /** + * Returns the refreshing. + * @return boolean + */ + public boolean isRefreshing() { + return refreshing; + } + + /** + * Sets the refreshing. + * @param refreshing The refreshing to set + */ + public void setRefreshing(boolean refreshing) { + this.refreshing = refreshing; + } + + /** + * Returns the unread. + * @return boolean + */ + public boolean isUnread() { + return unread; + } + + public synchronized void computeUnRead() { + this.unread = false; + for (int i = 0; i < items.size(); i++) { + this.unread = this.unread || !((Item)items.get(i)).isReadFlag(); + } + } + + public String getUID() { + return "CHA" + url; + } + +} diff --git a/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/IconManager.java b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/IconManager.java new file mode 100644 index 0000000..2294108 --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/IconManager.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2004 Jérôme Nègre. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.jnegre.org/cpl1_0.html + * + * Contributors: + * Jérôme Nègre - initial API and implementation + *******************************************************************************/ + +/* + * Created on 12 juin 2004 + */ +package net.sourceforge.phpeclipse.news; + +import java.net.URL; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Image; + +/** + * @author Jérôme Nègre + */ +public class IconManager { + //the root folder containing the icons + private static final String ICON_FOLDER = "icons/"; + + //real file locations + private static final String LOC_LED_DARK_GREEN = "led_dark_green.gif"; + private static final String LOC_LED_LIGHT_GREEN = "led_light_green.gif"; + private static final String LOC_LED_RED = "led_red.gif"; + private static final String LOC_LED_YELLOW = "led_yellow.gif"; + private static final String LOC_LINK = "link.gif"; + private static final String LOC_REFRESH = "refresh.gif"; + private static final String LOC_EXTERNAL_BROWSER = "external_browser.gif"; + + //list of all icon files to put in the ImageRegistry + private static final String[] LOCATIONS = new String[]{ + LOC_LED_DARK_GREEN, + LOC_LED_LIGHT_GREEN, + LOC_LED_RED, + LOC_LED_YELLOW, + LOC_LINK, + LOC_REFRESH, + LOC_EXTERNAL_BROWSER + }; + + //public names + public static final String ICON_STATUS_ERROR = LOC_LED_RED; + public static final String ICON_STATUS_UNREAD = LOC_LED_LIGHT_GREEN; + public static final String ICON_STATUS_READ = LOC_LED_DARK_GREEN; + public static final String ICON_STATUS_REFRESH = LOC_LED_YELLOW; + + public static final String ICON_ACTION_REFRESH = LOC_REFRESH; + public static final String ICON_ACTION_LINK = LOC_LINK; + public static final String ICON_ACTION_EXTERNAL_BROWSER = LOC_EXTERNAL_BROWSER; + + /** + * Populates an image registry with all the locations + * @param registry + */ + protected static void populateImageRegistry(ImageRegistry registry) { + for(int i=0; i position && buffer.charAt(position) == expectedChar) { + return true; + } else { + return false; + } + } + + /** + * @return the description of this item + */ + public String getDescription() { + return description; + } + /** + * @return the author of this item + */ + public String getAuthor() { + return author; + } + + /** + * Returns the date. + * @return String + */ + public String getDate() { + return date; + } + + /** + * Returns the readFlag. + * @return boolean + */ + public boolean isReadFlag() { + return readFlag; + } + + /** + * Returns the channel. + * @return Channel + */ + public Channel getChannel() { + return channel; + } + + /** + * Returns a unique ID used to remember which + * items were read in the ChannelStore + * @return + */ + public String getUID() { + return getUsableLink() + ") ~ (" + getUsableTitle(); + } + +} diff --git a/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/Messages.java b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/Messages.java new file mode 100644 index 0000000..023315b --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/Messages.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2004 Jérôme Nègre. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.jnegre.org/cpl1_0.html + * + * Contributors: + * Jérôme Nègre - initial API and implementation + *******************************************************************************/ + +/* + * Created on 27 juil. 2004 + */ +package net.sourceforge.phpeclipse.news; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * @author Jérôme Nègre + */ +public class Messages { + private static final String BUNDLE_NAME = "net.sourceforge.phpeclipse.news.messages";//$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle + .getBundle(BUNDLE_NAME); + + private Messages() { + } + + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } +} \ No newline at end of file diff --git a/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/Perspective.java b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/Perspective.java new file mode 100644 index 0000000..a037d19 --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/Perspective.java @@ -0,0 +1,31 @@ +package net.sourceforge.phpeclipse.news; + +import net.sourceforge.phpeclipse.webbrowser.views.BrowserView; + +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +//import org.eclipse.update.internal.ui.UpdatePerspective; +/** + * @author Laurent Fourrier, Jérôme Nègre + * + */ +public class Perspective implements IPerspectiveFactory { + /** + * @see org.eclipse.ui.IPerspectiveFactory#createInitialLayout(IPageLayout) + */ + public void createInitialLayout(IPageLayout layout) { + String editorArea = layout.getEditorArea(); + layout.setEditorAreaVisible(false); + // IFolderLayout bottom = layout.createFolder("bottom", + // IPageLayout.BOTTOM, 0.70f, editorArea); + // bottom.addView("net.sourceforge.phpeclipse.news.view.headline"); + IFolderLayout bottom = layout.createFolder("bottom", IPageLayout.BOTTOM, 0.50f, editorArea); + bottom.addView(BrowserView.ID_BROWSER); + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, 0.30f, editorArea); + left.addView("net.sourceforge.phpeclipse.news.view.explorer"); + IFolderLayout right = layout.createFolder("right", IPageLayout.RIGHT, 0.70f, editorArea); + right.addView("net.sourceforge.phpeclipse.news.view.headline"); + } +} \ No newline at end of file diff --git a/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/Plugin.java b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/Plugin.java new file mode 100644 index 0000000..424e081 --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/Plugin.java @@ -0,0 +1,248 @@ +package net.sourceforge.phpeclipse.news; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Timer; +import java.util.TimerTask; + +import net.sourceforge.phpeclipse.news.pref.ChannelStore; +import net.sourceforge.phpeclipse.news.pref.ListEncoder; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPluginDescriptor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +public class Plugin extends AbstractUIPlugin { + + public static final String BACKENDS_SECTION = "backends"; + + public static final String REFRESH_INTERVAL_PREFERENCE = "net.sourceforge.phpeclipse.news.refreshinterval"; + + /** @deprecated */ + public static final String BACKENDS_PREFERENCE = "net.sourceforge.phpeclipse.news.backends"; + + public static final String BROWSER_PREFERENCE = "net.sourceforge.phpeclipse.news.browser"; + + public static final String BANNED_ITEMS_PREFERENCE = "net.sourceforge.phpeclipse.news.banneditems"; + + public static final String FORCE_CACHE_PREFERENCE = "net.sourceforge.phpeclipse.news.forcecache"; + + //Default values + public static final int DEFAULT_REFRESH_INTERVAL = 60; + + public static final String DEFAULT_BROWSER = "C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE"; + + public static final String DEFAULT_BANNED_ITEMS = ""; + + public static final boolean DEFAULT_FORCE_CACHE = false; + + //User-Agent + public static String userAgent; + + protected UpdateThread updateThread; + + protected ArrayList views = new ArrayList(); + + protected Timer timer; + + protected ArrayList channelList; + + protected Object channelLock = new Object(); + + protected ArrayList banList = new ArrayList(); + + /** + * List of RssListeners to notify + */ + private ArrayList rssListeners = new ArrayList(); + + /** + * Constructor for Plugin + */ + public Plugin(IPluginDescriptor descriptor) { + super(descriptor); + + //set the user-agent ID + StringBuffer buffer = new StringBuffer(); + buffer.append("AllTheNews/").append(descriptor.getVersionIdentifier()).append(" (").append(System.getProperty("os.name")) + .append("; ").append(System.getProperty("os.arch")).append("; http://www.jnegre.org/)"); + userAgent = buffer.toString(); + + singleton = this; + + //init the channel store + ChannelStore.init(this); + + updateBanList(); + updateChannelList(); + setTimer(); + } + + protected static Plugin singleton; + + public static Plugin getDefault() { + return singleton; + } + + public static void logError(String message, Throwable t) { + getDefault().getLog() + .log(new Status(IStatus.ERROR, getDefault().getDescriptor().getUniqueIdentifier(), IStatus.OK, message, t)); + } + + public static void logInfo(String message, Throwable t) { + getDefault().getLog().log(new Status(IStatus.INFO, getDefault().getDescriptor().getUniqueIdentifier(), IStatus.OK, message, t)); + } + + /* + * @see AbstractUIPlugin#initializeDefaultPreferences(IPreferenceStore) + */ + protected void initializeDefaultPreferences(IPreferenceStore store) { + store.setDefault(REFRESH_INTERVAL_PREFERENCE, DEFAULT_REFRESH_INTERVAL); + store.setDefault(BROWSER_PREFERENCE, DEFAULT_BROWSER); + store.setDefault(BANNED_ITEMS_PREFERENCE, DEFAULT_BANNED_ITEMS); + store.setDefault(FORCE_CACHE_PREFERENCE, DEFAULT_FORCE_CACHE); + } + + protected ImageRegistry createImageRegistry() { + ImageRegistry registry = super.createImageRegistry(); + IconManager.populateImageRegistry(registry); + return registry; + } + + public void addRssListener(RssListener listener) { + synchronized (rssListeners) { + rssListeners.add(listener); + } + } + + public void removeRssListener(RssListener listener) { + synchronized (rssListeners) { + rssListeners.remove(listener); + } + } + + public void notifyChannelListChanged(RssListener source) { + Iterator iterator = rssListeners.iterator(); + ArrayList channels = getChannelList(); + while (iterator.hasNext()) { + RssListener listener = (RssListener) iterator.next(); + if (listener != source) { + listener.onChannelListChanged(channels); + } + } + } + + public void notifyChannelStatusChanged(Channel channel, RssListener source) { + Iterator iterator = rssListeners.iterator(); + while (iterator.hasNext()) { + RssListener listener = (RssListener) iterator.next(); + if (listener != source) { + listener.onChannelStatusChanged(channel); + } + } + } + + public void notifyChannelSelected(Channel channel, RssListener source) { + Iterator iterator = rssListeners.iterator(); + while (iterator.hasNext()) { + RssListener listener = (RssListener) iterator.next(); + if (listener != source) { + listener.onChannelSelected(channel); + } + } + } + + public void notifyItemSelected(Item item, RssListener source) { + Iterator iterator = rssListeners.iterator(); + while (iterator.hasNext()) { + RssListener listener = (RssListener) iterator.next(); + if (listener != source) { + listener.onItemSelected(item); + } + } + } + + public void notifyItemStatusChanged(Item item, RssListener source) { + Iterator iterator = rssListeners.iterator(); + while (iterator.hasNext()) { + RssListener listener = (RssListener) iterator.next(); + if (listener != source) { + listener.onItemStatusChanged(item); + } + } + } + + public void setTimer() { + if (timer != null) { + timer.cancel(); + } + long period = getPreferenceStore().getInt(Plugin.REFRESH_INTERVAL_PREFERENCE) * 60000l; + if (period != 0) { + timer = new Timer(true); + timer.schedule(new UpdateTimer(), 0, period); + } + } + + public void updateBanList() { + synchronized (banList) { + banList.clear(); + + String banned = this.getPreferenceStore().getString(Plugin.BANNED_ITEMS_PREFERENCE); + String[] bannedTitles = ListEncoder.decode(banned); + for (int i = 0; i < bannedTitles.length; i++) { + banList.add(bannedTitles[i]); + } + } + } + + public boolean isBannedTitle(String title) { + synchronized (banList) { + return banList.contains(title); + } + } + + public void updateChannelList() { + synchronized (channelLock) { + channelList = ChannelStore.getChannels(); + } + notifyChannelListChanged(null); + } + + public ArrayList getChannelList() { + synchronized (channelLock) { + return new ArrayList(channelList); + } + } + + public void update() { + if (updateThread == null) { + updateThread = new UpdateThread(); + updateThread.start(); + } + } + + protected class UpdateTimer extends TimerTask { + public void run() { + update(); + } + } + + public void shutdown() throws CoreException { + ChannelStore.saveReadStatus(getChannelList()); + super.shutdown(); + } + + public IWorkbenchPage getActivePage() { + IWorkbenchWindow window = getWorkbench().getActiveWorkbenchWindow(); + if (window != null) + return window.getActivePage(); + return null; + } +} + diff --git a/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/RssListener.java b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/RssListener.java new file mode 100644 index 0000000..5e36f4b --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/RssListener.java @@ -0,0 +1,23 @@ +/* + * Created on 15 mai 2004 + * Copyright 2004 Jérôme Nègre + */ +package net.sourceforge.phpeclipse.news; + +import java.util.ArrayList; + +/** + * @author Jérôme Nègre + */ +public interface RssListener { + + public void onChannelListChanged(ArrayList channels); + + public void onChannelStatusChanged(Channel channel); + + public void onChannelSelected(Channel channel); + + public void onItemStatusChanged(Item tiem); + + public void onItemSelected(Item tiem); +} diff --git a/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/UpdateThread.java b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/UpdateThread.java new file mode 100644 index 0000000..8ab8e09 --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/UpdateThread.java @@ -0,0 +1,36 @@ +package net.sourceforge.phpeclipse.news; + +import java.util.Iterator; + +public class UpdateThread extends Thread { + + + /** + * Constructor for UpdateThread + */ + public UpdateThread() { + super(); + this.setDaemon(true); + } + + /** + * @see Runnable#run() + */ + public void run() { + try { + Plugin plugin = Plugin.getDefault(); + Iterator iterator = Plugin.getDefault().getChannelList().iterator(); + while(iterator.hasNext()) { + Channel channel = (Channel)iterator.next(); + channel.setRefreshing(true); + plugin.notifyChannelStatusChanged(channel, null); + channel.update(); + channel.setRefreshing(false); + plugin.notifyChannelStatusChanged(channel, null); + } + } finally { + Plugin.getDefault().updateThread = null; + } + } + +} \ No newline at end of file diff --git a/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/messages.properties b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/messages.properties new file mode 100644 index 0000000..9aa9b8f --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/messages.properties @@ -0,0 +1,3 @@ +#0 = description; 1=description with BR instead of \n; 2=url; 3=title +BrowserView.DescriptionTemplate={3}

{3}

{1}

Read more...

+BrowserView.NoDescription=No description diff --git a/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/pref/BanListEditor.java b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/pref/BanListEditor.java new file mode 100644 index 0000000..c685c1f --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/pref/BanListEditor.java @@ -0,0 +1,63 @@ +package net.sourceforge.phpeclipse.news.pref; + +import net.sourceforge.phpeclipse.news.Plugin; + +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.preference.ListEditor; +import org.eclipse.swt.widgets.Composite; + +public class BanListEditor extends ListEditor { + + /** + * Constructor for SiteListEditor + */ + protected BanListEditor(String name, String labelText, Composite parent) { + super(name, labelText, parent); + } + + /** + * @see ListEditor#parseString(String) + */ + protected String[] parseString(String stringList) { + return ListEncoder.decode(stringList); + } + + /** + * @see ListEditor#getNewInputObject() + */ + protected String getNewInputObject() { + InputDialog dialog; + dialog = new InputDialog(this.getShell(),"All The News","Enter item title to ban","",null); + dialog.open(); + if("".equals(dialog.getValue()) || dialog.getValue()==null) { + return null; + } else { + return dialog.getValue(); + } + } + + /** + * @see ListEditor#createList(String[]) + */ + protected String createList(String[] items) { + return ListEncoder.encode(items); + } + + /** + * @see org.eclipse.jface.preference.FieldEditor#doStore() + */ + protected void doStore() { + super.doStore(); + Plugin.getDefault().updateBanList(); + } + + + /** + * @see org.eclipse.jface.preference.FieldEditor#doLoadDefault() + */ + protected void doLoadDefault() { + super.doLoadDefault(); + Plugin.getDefault().updateBanList(); + } +} + diff --git a/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/pref/ChannelStore.java b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/pref/ChannelStore.java new file mode 100644 index 0000000..f48c494 --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/pref/ChannelStore.java @@ -0,0 +1,173 @@ +/* + * Created on 9 juin 2004 + * Copyright 2004 Jérôme Nègre + */ +package net.sourceforge.phpeclipse.news.pref; + +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Properties; + +import net.sourceforge.phpeclipse.news.Channel; +import net.sourceforge.phpeclipse.news.Item; +import net.sourceforge.phpeclipse.news.Plugin; + +import org.eclipse.jface.dialogs.IDialogSettings; + +/** + * @author Jérôme Nègre + */ +public class ChannelStore { + + private final static String DEFAULT_CHANNELS_FILE = "default_feeds.properties"; + + private final static String BACKENDS_SECTION = "backends"; + + private final static String CHANNELS_ORDER_KEY = "order"; + private final static String TITLE_KEY = "title"; + private final static String URL_KEY = "url"; + private final static String TYPE_KEY = "type"; + private final static String READ_KEY = "read"; + + private final static int TYPE_CHANNEL = 1; + + private static Plugin plugin = null; + + public static void init(Plugin plugin) { + ChannelStore.plugin = plugin; + } + + public static synchronized ArrayList getChannels() { + IDialogSettings section = getChannelsSection(); + String[] uids = section.getArray(CHANNELS_ORDER_KEY); + ArrayList result = new ArrayList(); + for(int i=0; inull if none + * (before creation or after disposal). + */ + private List list; + private ArrayList channels; + /** + * The button box containing the Add, Remove, Up, and Down buttons; + * null if none (before creation or after disposal). + */ + private Composite buttonBox; + /** + * The Add button. + */ + private Button addButton; + /** + * The Search button. + */ + private Button searchButton; + /** + * The Remove button. + */ + private Button removeButton; + /** + * The Up button. + */ + private Button upButton; + /** + * The Down button. + */ + private Button downButton; + /** + * The selection listener. + */ + private SelectionListener selectionListener; + /** + * Notifies that the Add button has been pressed. + */ + private void addPressed() { + setPresentsDefaultValue(false); + Channel input = getNewInputChannel(); + if (input != null) { + int index = list.getSelectionIndex(); + if (index >= 0) { + list.add(input.getTitle(), index + 1); + channels.add(index + 1, input); + } else { + list.add(input.getTitle(), 0); + channels.add(0, input); + } + selectionChanged(); + } + } + + /** + * Notifies that the Search button has been pressed. + */ + private void searchPressed() { + setPresentsDefaultValue(false); + SearchDialog sd = new SearchDialog(SiteListEditor.this + .getShell()); + sd.open(); + Channel[] inputs = sd.getChannels(); + for(int i=0; i= 0) { + list.add(inputs[i].getTitle(), index + 1); + channels.add(index + 1, inputs[i]); + } else { + list.add(inputs[i].getTitle(), 0); + channels.add(0, inputs[i]); + } + } + selectionChanged(); + } + + + /* (non-Javadoc) + * Method declared on FieldEditor. + */ + protected void adjustForNumColumns(int numColumns) { + Control control = getLabelControl(); + ((GridData) control.getLayoutData()).horizontalSpan = numColumns; + ((GridData) list.getLayoutData()).horizontalSpan = numColumns - 1; + } + /** + * Creates the Add, Remove, Up, and Down button in the given button box. + * + * @param buttonBox the box for the buttons + */ + private void createButtons(Composite buttonBox) { + addButton = createPushButton(buttonBox, "ListEditor.add");//$NON-NLS-1$ + //TODO use my bundle ? + searchButton = createPushButton(buttonBox, "Search (experimental)"); + removeButton = createPushButton(buttonBox, "ListEditor.remove");//$NON-NLS-1$ + upButton = createPushButton(buttonBox, "ListEditor.up");//$NON-NLS-1$ + downButton = createPushButton(buttonBox, "ListEditor.down");//$NON-NLS-1$ + } + /** + * Helper method to create a push button. + * + * @param parent the parent control + * @param key the resource name used to supply the button's label text + */ + private Button createPushButton(Composite parent, String key) { + Button button = new Button(parent, SWT.PUSH); + button.setText(JFaceResources.getString(key)); + button.setFont(parent.getFont()); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.heightHint = convertVerticalDLUsToPixels(button, + IDialogConstants.BUTTON_HEIGHT); + int widthHint = convertHorizontalDLUsToPixels(button, + IDialogConstants.BUTTON_WIDTH); + data.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT, + SWT.DEFAULT, true).x); + button.setLayoutData(data); + button.addSelectionListener(getSelectionListener()); + return button; + } + /** + * Creates a selection listener. + */ + public void createSelectionListener() { + selectionListener = new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + Widget widget = event.widget; + if (widget == addButton) { + addPressed(); + } else if (widget == searchButton) { + searchPressed(); + } else if (widget == removeButton) { + removePressed(); + } else if (widget == upButton) { + upPressed(); + } else if (widget == downButton) { + downPressed(); + } else if (widget == list) { + selectionChanged(); + } + } + }; + } + /* (non-Javadoc) + * Method declared on FieldEditor. + */ + protected void doFillIntoGrid(Composite parent, int numColumns) { + Control control = getLabelControl(parent); + GridData gd = new GridData(); + gd.horizontalSpan = numColumns; + control.setLayoutData(gd); + list = getListControl(parent); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.verticalAlignment = GridData.FILL; + gd.horizontalSpan = numColumns - 1; + gd.grabExcessHorizontalSpace = true; + list.setLayoutData(gd); + buttonBox = getButtonBoxControl(parent); + gd = new GridData(); + gd.verticalAlignment = GridData.BEGINNING; + buttonBox.setLayoutData(gd); + } + /* (non-Javadoc) + * Method declared on FieldEditor. + */ + protected void doLoad() { + if (list != null) { + channels = ChannelStore.getChannels(); + for (int i = 0; i < channels.size(); i++) { + list.add(((Channel)channels.get(i)).getTitle()); + } + } + } + /* (non-Javadoc) + * Method declared on FieldEditor. + */ + protected void doLoadDefault() { + if (list != null) { + list.removeAll(); + channels = ChannelStore.getDefaultChannels(); + for (int i = 0; i < channels.size(); i++) { + list.add(((Channel)channels.get(i)).getTitle()); + } + setPresentsDefaultValue(false); + } + } + /* (non-Javadoc) + * Method declared on FieldEditor. + */ + protected void doStore() { + ChannelStore.saveReadStatus(Plugin.getDefault().getChannelList()); + ChannelStore.setChannels(channels); + Plugin.getDefault().updateChannelList(); + } + /** + * Notifies that the Down button has been pressed. + */ + private void downPressed() { + swap(false); + } + /** + * Returns this field editor's button box containing the Add, Remove, + * Up, and Down button. + * + * @param parent the parent control + * @return the button box + */ + public Composite getButtonBoxControl(Composite parent) { + if (buttonBox == null) { + buttonBox = new Composite(parent, SWT.NULL); + GridLayout layout = new GridLayout(); + layout.marginWidth = 0; + buttonBox.setLayout(layout); + createButtons(buttonBox); + buttonBox.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent event) { + addButton = null; + searchButton = null; + removeButton = null; + upButton = null; + downButton = null; + buttonBox = null; + } + }); + } else { + checkParent(buttonBox, parent); + } + selectionChanged(); + return buttonBox; + } + /** + * Returns this field editor's list control. + * + * @param parent the parent control + * @return the list control + */ + public List getListControl(Composite parent) { + if (list == null) { + list = new List(parent, SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL + | SWT.H_SCROLL); + list.setFont(parent.getFont()); + list.addSelectionListener(getSelectionListener()); + list.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent event) { + list = null; + } + }); + } else { + checkParent(list, parent); + } + return list; + } + /* (non-Javadoc) + * Method declared on FieldEditor. + */ + public int getNumberOfControls() { + return 2; + } + /** + * Returns this field editor's selection listener. + * The listener is created if nessessary. + * + * @return the selection listener + */ + private SelectionListener getSelectionListener() { + if (selectionListener == null) + createSelectionListener(); + return selectionListener; + } + /** + * Returns this field editor's shell. + *

+ * This method is internal to the framework; subclassers should not call + * this method. + *

+ * + * @return the shell + */ + protected Shell getShell() { + if (addButton == null) + return null; + return addButton.getShell(); + } + /** + * Notifies that the Remove button has been pressed. + */ + private void removePressed() { + setPresentsDefaultValue(false); + int index = list.getSelectionIndex(); + if (index >= 0) { + list.remove(index); + channels.remove(index); + selectionChanged(); + } + } + /** + * Notifies that the list selection has changed. + */ + private void selectionChanged() { + int index = list.getSelectionIndex(); + int size = list.getItemCount(); + removeButton.setEnabled(index >= 0); + upButton.setEnabled(size > 1 && index > 0); + downButton.setEnabled(size > 1 && index >= 0 && index < size - 1); + } + /* (non-Javadoc) + * Method declared on FieldEditor. + */ + public void setFocus() { + if (list != null) { + list.setFocus(); + } + } + /** + * Moves the currently selected item up or down. + * + * @param up true if the item should move up, + * and false if it should move down + */ + private void swap(boolean up) { + setPresentsDefaultValue(false); + int index = list.getSelectionIndex(); + int target = up ? index - 1 : index + 1; + if (index >= 0) { + //list widget + String[] selection = list.getSelection(); + Assert.isTrue(selection.length == 1); + list.remove(index); + list.add(selection[0], target); + list.setSelection(target); + //channels arrayList + Object obj = channels.remove(index); + channels.add(target, obj); + } + selectionChanged(); + } + /** + * Notifies that the Up button has been pressed. + */ + private void upPressed() { + swap(true); + } + /* + * @see FieldEditor.setEnabled(boolean,Composite). + */ + public void setEnabled(boolean enabled, Composite parent) { + super.setEnabled(enabled, parent); + getListControl(parent).setEnabled(enabled); + addButton.setEnabled(enabled); + removeButton.setEnabled(enabled); + upButton.setEnabled(enabled); + downButton.setEnabled(enabled); + } + + /* + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + + /** + * Creates a site list field editor. + * + * @param name the name of the preference this field editor works on + * @param labelText the label text of the field editor + * @param parent the parent of the field editor's control + */ + protected SiteListEditor(String name, String labelText, Composite parent) { + init(name, labelText); + createControl(parent); + } + /** + * Creates and returns a new item for the list. + * + * @return a new item + */ + protected Channel getNewInputChannel() { + InputDialog dialog; + dialog = new InputDialog(this.getShell(), "All The News", + "Enter new site name", "", null); + dialog.open(); + if ("".equals(dialog.getValue()) || dialog.getValue() == null) + return null; + String title = dialog.getValue(); + dialog = new InputDialog(this.getShell(), "All The News", + "Enter new site URL", "", null); + dialog.open(); + if ("".equals(dialog.getValue()) || dialog.getValue() == null) + return null; + String url = dialog.getValue(); + return new Channel(title, url); + } +} \ No newline at end of file diff --git a/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/search/SearchDialog.java b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/search/SearchDialog.java new file mode 100644 index 0000000..7e63e5a --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/search/SearchDialog.java @@ -0,0 +1,238 @@ +/* + * Created on 25 janv. 2004 + * + * (c)2004 Jérôme Nègre - http://www.jnegre.org/ + */ + +package net.sourceforge.phpeclipse.news.search; + +import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Vector; + +import net.sourceforge.phpeclipse.news.Channel; + +import org.apache.xmlrpc.XmlRpcClient; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * @author Jérôme Nègre + * + */ +public class SearchDialog extends Dialog { + + private Label statusBar; + private Text searchText; + private List list; + private Text name; + private Text siteUrl; + private Text feedUrl; + private Text version; + private Text description; + + private ArrayList resultChannels = new ArrayList(); + + private XmlRpcClient xmlRpcClient; + + /** + * @param parentShell + */ + public SearchDialog(Shell parentShell) { + super(parentShell); + this.setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MODELESS); + } + + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText("Search using http://www.syndic8.com/"); + } + + /** + * Adds the controls to the dialog + * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) + */ + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite)super.createDialogArea(parent); + GridLayout gl = (GridLayout)composite.getLayout(); + gl.numColumns = 4; + + //Text to enter the searched words + searchText = new Text(composite,SWT.BORDER); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 3; + searchText.setLayoutData(gd); + //Button "search!" + Button searchButton = new Button(composite,0); + searchButton.setText("Search!"); + searchButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + //TODO use a worker + Cursor waitCursor = new Cursor(SearchDialog.this.getContents().getDisplay(), SWT.CURSOR_WAIT); + try { + SearchDialog.this.getContents().setCursor(waitCursor); + SearchDialog.this.searchNow(); + } catch (Exception x) { + setStatusMessage("Error: "+x.getMessage()); + } finally { + SearchDialog.this.getContents().setCursor(null); + waitCursor.dispose(); + } + } + }); + //List for the titles of the feeds + list = new List(composite,SWT.BORDER|SWT.H_SCROLL|SWT.V_SCROLL|SWT.SINGLE); + gd = new GridData(GridData.FILL_BOTH); + list.setLayoutData(gd); + list.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + SearchDialog.this.showFieldDetails((Hashtable)((ArrayList)list.getData()).get(list.getSelectionIndex())); + } + }); + + //Description of the selected feed + Group group = new Group(composite,0); + group.setText("Selected Feed"); + gd = new GridData(GridData.FILL_BOTH); + gd.horizontalSpan = 3; + group.setLayoutData(gd); + group.setLayout(new GridLayout(2,false)); + //name + new Label(group,0).setText("Name:"); + name = new Text(group,SWT.BORDER|SWT.READ_ONLY); + name.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + //site url + new Label(group,0).setText("Site URL:"); + siteUrl = new Text(group,SWT.BORDER|SWT.READ_ONLY); + siteUrl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + //feed url + new Label(group,0).setText("Feed URL:"); + feedUrl = new Text(group,SWT.BORDER|SWT.READ_ONLY); + feedUrl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + //RSS version + new Label(group,0).setText("RSS version:"); + version = new Text(group,SWT.BORDER|SWT.READ_ONLY); + version.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + //description + new Label(group,0).setText("Description:"); + description = new Text(group,SWT.BORDER|SWT.READ_ONLY|SWT.MULTI|SWT.H_SCROLL|SWT.V_SCROLL|SWT.WRAP); + description.setLayoutData(new GridData(GridData.FILL_BOTH)); + + //status bar + statusBar = new Label(composite,SWT.NONE); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 4; + statusBar.setLayoutData(gd); + setStatusMessage("Ready."); + return composite; + } + + private XmlRpcClient getXmlRpcClient() throws MalformedURLException { + if(this.xmlRpcClient == null) { + this.xmlRpcClient = new XmlRpcClient("http://www.syndic8.com/xmlrpc.php"); + } + return this.xmlRpcClient; + } + + /** + * + */ + protected void searchNow() throws Exception { + clearFeedList(); + setStatusMessage("Connecting..."); + XmlRpcClient client = getXmlRpcClient(); + //Get the list of ids + Vector args = new Vector(); + args.add(searchText.getText()); + args.add("sitename"); + //args.add(new Integer(30)); + Vector ids = (Vector)client.execute("syndic8.FindFeeds",args); + setStatusMessage("Found "+ids.size()+" result(s), asking for details..."); + //Get the descriptions of the feeds + Vector fields = new Vector(); + fields.add("sitename"); + fields.add("siteurl"); + fields.add("dataurl"); + fields.add("rss_version"); + fields.add("description"); + args.clear(); + args.add(ids); + args.add(fields); + Vector infos = (Vector)client.execute("syndic8.GetFeedInfo",args); + setStatusMessage("Showing details..."); + Iterator iterator = infos.iterator(); + while(iterator.hasNext()) { + Hashtable info = (Hashtable)iterator.next(); + addFeedInList(info); + } + setStatusMessage("Ready."); + } + + protected void clearFeedList() { + list.removeAll(); + showFieldDetails(null); + list.setData(new ArrayList()); + } + + protected void showFieldDetails(Hashtable info) { + name.setText(info==null?"":(String)info.get("sitename")); + siteUrl.setText(info==null?"":(String)info.get("siteurl")); + feedUrl.setText(info==null?"":(String)info.get("dataurl")); + version.setText(info==null?"":(String)info.get("rss_version")); + description.setText(info==null?"":(String)info.get("description")); + } + + protected void addFeedInList(Hashtable info) { + String name = (String)info.get("sitename"); + String dataurl = (String)info.get("dataurl"); + if("".equals(name) || "".equals(dataurl)) { + //skip it + return; + } + ArrayList al = (ArrayList)list.getData(); + al.add(info); + list.add(name); + } + + protected void setStatusMessage(String message) { + statusBar.setText(message); + //TODO remove next line + System.out.println(message); + } + + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent,IDialogConstants.OPEN_ID,"Add Selected",false); + createButton(parent,IDialogConstants.OK_ID,IDialogConstants.OK_LABEL,false); + } + + protected void buttonPressed(int buttonId) { + super.buttonPressed(buttonId); + if(buttonId == IDialogConstants.OPEN_ID) { + String name = this.name.getText(); + String url = this.feedUrl.getText(); + if(!"".equals(name) && !"".equals(url)) { + resultChannels.add(new Channel(name, url)); + } + } + } + + public Channel[] getChannels() { + return (Channel[])resultChannels.toArray(new Channel[]{}); + } +} diff --git a/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/view/ExplorerView.java b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/view/ExplorerView.java new file mode 100644 index 0000000..e1faf8d --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/view/ExplorerView.java @@ -0,0 +1,159 @@ +/* + * Created on 15 mai 2004 + * Copyright 2004 Jérôme Nègre + */ +package net.sourceforge.phpeclipse.news.view; + +import java.util.ArrayList; + +import net.sourceforge.phpeclipse.news.Channel; +import net.sourceforge.phpeclipse.news.IconManager; +import net.sourceforge.phpeclipse.news.Item; +import net.sourceforge.phpeclipse.news.Plugin; +import net.sourceforge.phpeclipse.news.RssListener; +import net.sourceforge.phpeclipse.webbrowser.views.BrowserView; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.part.ViewPart; + +/** + * @author Jérôme Nègre + */ +public class ExplorerView extends ViewPart implements RssListener { + + private TreeViewer treeViewer; + + private NewsTreeViewerProvider provider; + + private Action refreshAction; + + public ExplorerView() { + super(); + } + + public void dispose() { + Plugin.getDefault().removeRssListener(this); + super.dispose(); + } + + public void createPartControl(Composite parent) { + treeViewer = new TreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); + provider = new NewsTreeViewerProvider(); + treeViewer.setContentProvider(provider); + treeViewer.setLabelProvider(provider); + treeViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + Object selected = ((StructuredSelection) event.getSelection()).getFirstElement(); + if (selected != null) { + if (selected instanceof Channel) { + Plugin.getDefault().notifyChannelSelected((Channel) selected, ExplorerView.this); + } else if (selected instanceof Item) { + Plugin.getDefault().notifyItemSelected((Item) selected, ExplorerView.this); + } + } + } + }); + + createActions(); + createMenu(); + createToolBar(); + + Plugin.getDefault().addRssListener(this); + treeViewer.setInput(Plugin.getDefault()); + } + + public void setFocus() { + treeViewer.getControl().setFocus(); + } + + public void onChannelListChanged(ArrayList channels) { + treeViewer.setInput(Plugin.getDefault()); + } + + public void onChannelStatusChanged(final Channel channel) { + treeViewer.getControl().getDisplay().asyncExec(new Runnable() { + public void run() { + treeViewer.refresh(channel); + } + }); + } + + public void onChannelSelected(Channel channel) { + System.out.println("Explorer.onChannelSelected -> " + channel); + } + + public void onItemStatusChanged(final Item item) { + treeViewer.getControl().getDisplay().asyncExec(new Runnable() { + public void run() { + treeViewer.refresh(item); + } + }); + } + + private void createActions() { + //refresh + refreshAction = new Action("Refresh", IconManager.getImageDescriptor(IconManager.ICON_ACTION_REFRESH)) { + public void run() { + Plugin.getDefault().update(); + } + }; + refreshAction.setToolTipText("Refresh"); + } + + private void createMenu() { + //IMenuManager mgr = getViewSite().getActionBars().getMenuManager(); + //mgr.add(clearAction); + } + + private void createToolBar() { + IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager(); + mgr.add(refreshAction); + } + + private void setUrl(String url) { + IWorkbenchPage page = Plugin.getDefault().getActivePage(); + try { + IViewPart part = page.findView(BrowserView.ID_BROWSER); + if (part == null) { + part = page.showView(BrowserView.ID_BROWSER); + } else { + page.bringToTop(part); + } + ((BrowserView) part).setUrl(url); + } catch (Exception e) { + } + } + + // public void onItemSelected(Item tiem) { + // // NOP + // } + public void onItemSelected(Item item) { + if (item != null) { // && uiReady && linkAction.isChecked()) { + // if(showDescritionAction.isChecked()) { + // String desc = item.getDescription(); + // if(desc == null) + // desc = HTML_NO_DESCRIPTION; + // browser.setText(MessageFormat.format(HTML,new String[]{desc, encodeNewLine(desc), item.getUsableLink(), + // item.getUsableTitle()})); + // } else { + setUrl(item.getUsableLink()); + // } + //XXX this is a hack, should be done otherwise + boolean channelStatus = item.getChannel().isUnread(); + item.setReadFlag(true); + Plugin.getDefault().notifyItemStatusChanged(item, this); + if (channelStatus != item.getChannel().isUnread()) { + Plugin.getDefault().notifyChannelStatusChanged(item.getChannel(), this); + } + } + } +} \ No newline at end of file diff --git a/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/view/HeadlineView.java b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/view/HeadlineView.java new file mode 100644 index 0000000..e87ef3e --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/view/HeadlineView.java @@ -0,0 +1,105 @@ +/* + * Created on 15 mai 2004 + * Copyright 2004 Jérôme Nègre + */ +package net.sourceforge.phpeclipse.news.view; + +import java.util.ArrayList; +import java.util.Iterator; + +import net.sourceforge.phpeclipse.news.Channel; +import net.sourceforge.phpeclipse.news.IconManager; +import net.sourceforge.phpeclipse.news.Item; +import net.sourceforge.phpeclipse.news.Plugin; +import net.sourceforge.phpeclipse.news.RssListener; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.ui.part.ViewPart; + +/** + * @author Jérôme Nègre + */ +public class HeadlineView extends ViewPart implements RssListener { + + Table table; + + public HeadlineView() { + super(); + } + + public void dispose() { + Plugin.getDefault().removeRssListener(this); + super.dispose(); + } + + private TableColumn createColumn(int style, int width, String text) { + TableColumn col = new TableColumn(table, style); + col.setWidth(width); + col.setText(text); + return col; + } + + public void createPartControl(Composite parent) { + table = new Table(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION); + //TODO remember the width of the columns + createColumn(SWT.LEFT, 120, "Publication Date"); + createColumn(SWT.CENTER, 20, ""); + createColumn(SWT.LEFT, 600, "Title"); + table.setHeaderVisible(true); + table.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + Item item = (Item) e.item.getData(); + Plugin.getDefault().notifyItemSelected(item,HeadlineView.this); + } + }); + Plugin.getDefault().addRssListener(this); + } + + public void setFocus() { + table.setFocus(); + } + + public void onChannelListChanged(ArrayList channels) { + // NOP + } + + public void onChannelStatusChanged(Channel channel) { + // NOP + } + + public void onChannelSelected(Channel channel) { + fillTable(channel); + } + + public void onItemSelected(Item item) { + fillTable(item.getChannel()); + int index = item.getChannel().getItems().indexOf(item); + table.setSelection(index); + } + + public void onItemStatusChanged(Item item) { + fillTable(item.getChannel()); + int index = item.getChannel().getItems().indexOf(item); + table.setSelection(index); + } + + private void fillTable(Channel channel) { + Iterator items = channel.getItems().iterator(); + table.removeAll(); + while(items.hasNext()) { + Item item = (Item)items.next(); + TableItem tableItem = new TableItem(table,SWT.NONE); + tableItem.setText(0,item.getDate()); + String image = item.isReadFlag()? IconManager.ICON_STATUS_READ : IconManager.ICON_STATUS_UNREAD; + tableItem.setImage(1,IconManager.getImage(image)); + tableItem.setText(2,item.getUsableTitle()); + tableItem.setData(item); + } + } +} diff --git a/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/view/NewsTreeViewerProvider.java b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/view/NewsTreeViewerProvider.java new file mode 100644 index 0000000..8b225b3 --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.news/src/net/sourceforge/phpeclipse/news/view/NewsTreeViewerProvider.java @@ -0,0 +1,130 @@ +/* + * Created on 16 mai 2004 + * Copyright 2004 Jérôme Nègre + */ +package net.sourceforge.phpeclipse.news.view; + +import net.sourceforge.phpeclipse.news.Channel; +import net.sourceforge.phpeclipse.news.IconManager; +import net.sourceforge.phpeclipse.news.Item; +import net.sourceforge.phpeclipse.news.Plugin; + +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.graphics.Image; + +/** + * @author Jérôme Nègre + */ +public class NewsTreeViewerProvider + implements + ITreeContentProvider, + ILabelProvider { + + public Object[] getChildren(Object parentElement) { + if(parentElement instanceof Channel) { + return ((Channel)parentElement).getItems().toArray(); + } else { + return null; + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) + */ + public Object getParent(Object element) { + // TODO Auto-generated method stub + return null; + } + + public boolean hasChildren(Object element) { + if(element instanceof Channel) { + return !((Channel)element).getItems().isEmpty(); + } else { + return false; + } + } + + public Object[] getElements(Object inputElement) { + return ((Plugin)inputElement).getChannelList().toArray(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // TODO Auto-generated method stub + } + + public Image getImage(Object element) { + + String iconId; + + if(element instanceof Channel) { + Channel channel = (Channel)element; + if(channel.isRefreshing()) { + iconId = IconManager.ICON_STATUS_REFRESH; + } else if(channel.getErrorMessage()!=null) { + iconId = IconManager.ICON_STATUS_ERROR; + } else if(channel.isUnread()) { + iconId = IconManager.ICON_STATUS_UNREAD; + } else { + iconId = IconManager.ICON_STATUS_READ; + } + } else if(element instanceof Item) { + Item item = (Item)element; + if(item.isReadFlag()) { + iconId = IconManager.ICON_STATUS_READ; + } else { + iconId = IconManager.ICON_STATUS_UNREAD; + } + } else { + return null; + } + return Plugin.getDefault().getImageRegistry().getDescriptor(iconId).createImage(); + } + + public String getText(Object element) { + if(element instanceof Channel) { + return ((Channel)element).getTitle(); + } else if(element instanceof Item) { + return ((Item)element).getUsableTitle(); + } else { + return "Unexpected object: "+element; + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener) + */ + public void addListener(ILabelProviderListener listener) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String) + */ + public boolean isLabelProperty(Object element, String property) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener) + */ + public void removeListener(ILabelProviderListener listener) { + // TODO Auto-generated method stub + + } +}