Skip to content

Commit

Permalink
Merge branch 'master' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
nvdaes committed Sep 18, 2018
2 parents dcd6c11 + 9cda0ce commit c6a146b
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 49 deletions.
158 changes: 112 additions & 46 deletions addon/globalPlugins/readFeeds/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: UTF-8 -*-

# Read feeds: A simple plugin for reading feeds with NVDA
#Copyright (C) 2012-2017 Noelia Ruiz Martínez, Mesar Hameed
#Copyright (C) 2012-2018 Noelia Ruiz Martínez, Mesar Hameed
# Released under GPL 2

import os
Expand All @@ -13,6 +13,7 @@
import config
import urllib
import scriptHandler
from scriptHandler import script
import api
import gui
from gui import guiHelper
Expand Down Expand Up @@ -148,7 +149,7 @@ def __init__(self, parent):
self.deleteButton = buttonHelper.addButton(self, label=_("&Delete..."))
self.deleteButton.Bind(wx.EVT_BUTTON, self.onDelete)

# Translators: The label of a button to set a feed as default.
# Translators: The label of a button to set a feed as default.
self.defaultButton = buttonHelper.addButton(self, label=_("S&et default"))
self.defaultButton.Bind(wx.EVT_BUTTON, self.onDefault)

Expand All @@ -168,7 +169,7 @@ def __init__(self, parent):
mainSizer.Fit(self)
self.Sizer = mainSizer
self.searchTextEdit.SetFocus()
self.Center(wx.BOTH | wx.CENTER_ON_SCREEN)
self.CentreOnScreen()

def __del__(self):
FeedsDialog._instance = None
Expand Down Expand Up @@ -214,16 +215,9 @@ def onArticles(self, evt):
with open(os.path.join(FEEDS_PATH, "%s.txt" % self.stringSel), "r") as f:
address = f.read()
f.close()
feed = Feed(address)
with wx.SingleChoiceDialog(self,
# Translators: the label of a single choice dialog.
_("Open web page of selected article."),
# Translators: Title of a dialog.
u"{feedTitle} ({feedNumber})".format(feedTitle=self.stringSel, feedNumber=feed.getNumberOfArticles()),
[feed.getArticleTitle(index) for index in xrange(feed.getNumberOfArticles())]) as d:
if d.ShowModal() == wx.ID_CANCEL:
return
os.startfile(feed.getArticleLink(d.Selection))
self.feed = Feed(address)
self.Disable()
ArticlesDialog(self).Show()

def onOpen(self, evt):
with open(os.path.join(FEEDS_PATH, "%s.txt" % self.stringSel), "r") as f:
Expand Down Expand Up @@ -264,7 +258,7 @@ def onRename(self, evt):
# Translators: The label of a field to enter a new name for a feed.
with wx.TextEntryDialog(self, _("New name:"),
# Translators: The title of a dialog to rename a feed.
_("Rename feed"), defaultValue=self.stringSel) as d:
_("Rename feed"), value=self.stringSel) as d:
if d.ShowModal() == wx.ID_CANCEL or not d.Value:
return
curName = "%s.txt" % self.stringSel
Expand All @@ -275,6 +269,63 @@ def onRename(self, evt):

def onClose(self, evt):
self.Destroy()
FeedsDialog._instance = None

class ArticlesDialog(wx.Dialog):

def __init__(self, parent):
# Translators: The title of the articles dialog.
super(ArticlesDialog, self).__init__(parent, title=u"{feedTitle} ({feedNumber})".format(feedTitle=parent.stringSel, feedNumber=parent.feed.getNumberOfArticles()))

mainSizer = wx.BoxSizer(wx.VERTICAL)
sHelper = guiHelper.BoxSizerHelper(self, orientation=wx.VERTICAL)

# Translators: The label of the articles list in the articles dialog.
articlesText = _("List of articles")
articlesChoices = [parent.feed.getArticleTitle(index) for index in xrange(parent.feed.getNumberOfArticles())]
self.articlesList = sHelper.addLabeledControl(articlesText, wx.ListBox, choices=articlesChoices)
self.articlesList.Selection = 0
self.articlesList.Bind(wx.EVT_CHOICE, self.onArticlesListChoice)

buttonHelper = guiHelper.ButtonHelper(wx.VERTICAL)
# Translators: The label of a button to open the selected article of a feed.
self.articleButton = wx.Button(self, label=_("Open &web page of selected article."))
self.articleButton.Bind(wx.EVT_BUTTON, self.onArticlesListChoice)
self.AffirmativeId = self.articleButton.Id
self.articleButton.SetDefault()
buttonHelper.addButton(self.articleButton)

# Translators: The label of a button to show information of a feed article.
self.infoButton = wx.Button(self, label=_("&About article..."))
self.infoButton.Bind(wx.EVT_BUTTON, self.onArticlesListInfo)
buttonHelper.addButton(self.infoButton)

closeButton = sHelper.addDialogDismissButtons(wx.Button(self, wx.ID_CLOSE, label=translate("&Close")))
closeButton.Bind(wx.EVT_BUTTON, lambda evt: self.Close())
self.Bind(wx.EVT_CLOSE, self.onClose)
self.EscapeId = wx.ID_CLOSE
mainSizer.Add(buttonHelper.sizer)
mainSizer.Add(sHelper.sizer, border = guiHelper.BORDER_FOR_DIALOGS, flag=wx.ALL)
mainSizer.Fit(self)
self.Sizer = mainSizer
self.CentreOnScreen()

def onArticlesListChoice(self, evt):
os.startfile(self.Parent.feed.getArticleLink(self.articlesList.Selection))

def onArticlesListInfo(self, evt):
articleInfo = u"{title}\r\n\r\n{address}".format(title=self.Parent.feed.getArticleTitle(self.articlesList.Selection), address=self.Parent.feed.getArticleLink(self.articlesList.Selection))
if gui.messageBox(
# Translators: the label of a message box dialog.
_("%s\r\n\r\nDo you want to copy article title and link to the clipboard?" % articleInfo),
# Translators: the title of a message box dialog.
_("Article information"),
wx.YES|wx.NO|wx.CANCEL|wx.ICON_QUESTION) == wx.YES:
api.copyToClip(articleInfo)

def onClose(self, evt):
self.Parent.Enable()
self.Destroy()

class CopyDialog(wx.Dialog):

Expand Down Expand Up @@ -308,7 +359,7 @@ def __init__(self, parent):
mainSizer.Add(sHelper.sizer, border=gui.guiHelper.BORDER_FOR_DIALOGS, flag=wx.ALL)
self.Sizer = mainSizer
mainSizer.Fit(self)
self.Center(wx.BOTH | wx.CENTER_ON_SCREEN)
self.CentreOnScreen()

def onCopy(self, evt):
if not self.copyDirectoryEdit.Value:
Expand Down Expand Up @@ -378,7 +429,7 @@ def __init__(self, parent):
mainSizer.Add(sHelper.sizer, border=gui.guiHelper.BORDER_FOR_DIALOGS, flag=wx.ALL)
self.Sizer = mainSizer
mainSizer.Fit(self)
self.Center(wx.BOTH | wx.CENTER_ON_SCREEN)
self.CentreOnScreen()

def onRestore(self, evt):
if not self.restoreDirectoryEdit.Value:
Expand Down Expand Up @@ -485,7 +536,7 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
scriptCategory = unicode(ADDON_SUMMARY)

def __init__(self):
super(globalPluginHandler.GlobalPlugin, self).__init__()
super(GlobalPlugin, self).__init__()
self.menu = gui.mainFrame.sysTrayIcon.toolsMenu
self.readFeedsMenu = wx.Menu()
# Translators: the name of a submenu.
Expand All @@ -504,8 +555,8 @@ def __init__(self):

def terminate(self):
try:
self.menu.RemoveItem(self.mainItem)
except wx.PyDeadObjectError:
self.menu.Remove(self.mainItem)
except:
pass

def onFeeds(self, evt):
Expand All @@ -514,32 +565,39 @@ def onFeeds(self, evt):
d.Show()
gui.mainFrame.postPopup()

@script(
# Translators: message presented in input mode.
description=_("Activates the Feeds dialog of %s." % ADDON_SUMMARY)
)
def script_activateFeedsDialog(self, gesture):
wx.CallAfter(self.onFeeds, None)
# Translators: message presented in input mode.
script_activateFeedsDialog.__doc__ = _("Activates the Feeds dialog of %s." % ADDON_SUMMARY)

def onCopy(self, evt):
gui.mainFrame.prePopup()
d = CopyDialog(gui.mainFrame)
d.Show()
gui.mainFrame.postPopup()

@script(
# Translators: message presented in input mode.
description=_("Activates the Copy dialog of %s." % ADDON_SUMMARY)
)
def script_activateCopyDialog(self, gesture):
wx.CallAfter(self.onCopy, None)
# Translators: message presented in input mode.
script_activateCopyDialog.__doc__ = _("Activates the Copy dialog of %s." % ADDON_SUMMARY)


def onRestore(self, evt):
gui.mainFrame.prePopup()
d = RestoreDialog(gui.mainFrame)
d.Show()
gui.mainFrame.postPopup()

@script(
# Translators: message presented in input mode.
description=_("Activates the Restore dialog of %s." % ADDON_SUMMARY)
)
def script_activateRestoreDialog(self, gesture):
wx.CallAfter(self.onRestore, None)
# Translators: message presented in input mode.
script_activateRestoreDialog.__doc__ = _("Activates the Restore dialog of %s." % ADDON_SUMMARY)

def getFirstArticle(self):
try:
Expand All @@ -552,13 +610,21 @@ def getFirstArticle(self):
ui.message(CAN_NOT_REPORT)
raise e

@script(
# Translators: message presented in input mode.
description=_("Refreshes the current feed and announces the most recent article title."),
gesture="kb:control+shift+NVDA+8"
)
def script_readFirstArticle(self, gesture):
self.getFirstArticle()
if self.feed:
ui.message(self.feed.getArticleTitle())
# Translators: message presented in input mode.
script_readFirstArticle.__doc__ = _("Refreshes the current feed and announces the most recent article title.")

@script(
# Translators: message presented in input mode.
description=_("Announces the title of the current article. Pressed two times, copies title and related link to the clipboard."),
gesture="kb:control+shift+NVDA+i"
)
def script_readCurrentArticle(self, gesture):
if not self.feed:
self.getFirstArticle()
Expand All @@ -568,25 +634,34 @@ def script_readCurrentArticle(self, gesture):
ui.message(_("Copied to clipboard %s") % articleInfo)
else:
ui.message(articleInfo)
# Translators: message presented in input mode.
script_readCurrentArticle.__doc__ = _("Announces the title of the current article. Pressed two times, copies title and related link to the clipboard.")

@script(
# Translators: message presented in input mode.
description=_("Announces the title of the next article."),
gesture="kb:control+shift+NVDA+o"
)
def script_readNextArticle(self, gesture):
if not self.feed:
self.getFirstArticle()
self.feed.next()
ui.message(self.feed.getArticleTitle())
# Translators: message presented in input mode.
script_readNextArticle.__doc__ = _("Announces the title of the next article.")

@script(
# Translators: message presented in input mode.
description=_("Announces the title of the previous article."),
gesture="kb:control+shift+NVDA+u"
)
def script_readPriorArticle(self, gesture):
if not self.feed:
self.getFirstArticle()
self.feed.previous()
ui.message(self.feed.getArticleTitle())
# Translators: message presented in input mode.
script_readPriorArticle.__doc__ = _("Announces the title of the previous article.")

@script(
# Translators: message presented in input mode.
description=_("Announces article link, when pressed two times, opens related web page."),
gesture="kb:control+shift+NVDA+space"
)
def script_reportLink(self, gesture):
if not self.feed:
self.getFirstArticle()
Expand All @@ -595,24 +670,15 @@ def script_reportLink(self, gesture):
os.startfile(articleLink)
else:
ui.message(articleLink)
# Translators: message presented in input mode.
script_reportLink.__doc__ = _("Announces article link, when pressed two times, opens related web page.")

@script(
# Translators: message presented in input mode.
description=_("Copies title and related link of the current article to the clipboard.")
)
def script_copyArticleInfo(self, gesture):
if not self.feed:
self.getFirstArticle()
articleInfo = u"{title}\r\n\r\n{address}".format(title=self.feed.getArticleTitle(), address=self.feed.getArticleLink())
if api.copyToClip(articleInfo):
# Translators: message presented when the information about an article of a feed is copied to the clipboard.
ui.message(_("Copied to clipboard %s") % articleInfo)
# Translators: message presented in input mode.
script_copyArticleInfo.__doc__ = _("Copies title and related link of the current article to the clipboard.")

__gestures = {
"kb:control+shift+NVDA+8": "readFirstArticle",
"kb:control+shift+NVDA+i": "readCurrentArticle",
"kb:control+shift+NVDA+o": "readNextArticle",
"kb:control+shift+NVDA+u": "readPriorArticle",
"kb:control+shift+NVDA+space": "reportLink",
}

2 changes: 1 addition & 1 deletion buildVars.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# Translators: Long description to be shown for this add-on on add-on information from add-ons manager
"addon_description" : _("""Add-on for using NVDA as a feed reader."""),
# version
"addon_version" : "4.5",
"addon_version" : "5.0",
# Author(s)
"addon_author" : u"Noelia Ruiz Martínez <[email protected]>, Mesar Hameed <[email protected]>",
# URL for the add-on documentation support
Expand Down
9 changes: 7 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Opens a dialog with the following controls:

* Filter by: An edit box to search previously saved feeds.
* A list of the saved feeds.
* List of articles: Opens a dialog which presents the articles list from your current feed. Select the article you want to read and press OK button to open the corresponding page in your browser.
* List of articles: Opens a dialog which presents the articles list from your current feed. Select the article you want to read and press Enter or Open web page of selected article button to open the corresponding page in your browser. Press About article button to open a dialog showing title and link of the selected article; from this dialog, you'll be able to copy this info to the clipboard.
* Open feed: Opens the selected feed in the default application.
* New: Opens a dialog with an edit box to enter the address of a new feed. If the address is valid and the feed can be saved, its name, based on the feed title, will appear at the bottom of the feeds list.
* Rename: Opens a dialog with an edit box to rename the selected feed.
Expand Down Expand Up @@ -62,7 +62,11 @@ Opens a dialog to select a folder which replaces your feeds in the personalFeeds
* NVDA will display an error message if it was not possible to backup or restore the personalFeeds folder.
* The title of the articles list dialog displays the selected feed name and number of items available.

## Changes for 5.0 ##

* The articles list dialog has been enhanced.
* Compatible with NVDA 2018.3 or later (required).
* If needed, you can download the [last version compatible with NVDA 2017.3][3].

## Changes for 4.0 ##

Expand All @@ -86,4 +90,5 @@ Opens a dialog to select a folder which replaces your feeds in the personalFeeds

[1]: http://addons.nvda-project.org/files/get.php?file=rf

[2]: http://addons.nvda-project.org/files/get.php?file=rf-dev
[2]: http://addons.nvda-project.org/files/get.php?file=rf-dev
[3]: https://github.com/nvdaes/readFeeds/releases/download/4.5/readFeeds-4.5.nvda-addon

0 comments on commit c6a146b

Please sign in to comment.