view MainWindow.py @ 146:8ec20377bcb0

move getting the entries for a feed to the backend so that the couchdb backend can use a custom view for feed entries
author Dirk Olmes <dirk@xanthippe.ping.de>
date Thu, 25 Aug 2011 07:01:45 +0200
parents 089ee60b28fb
children babe14449162
line wrap: on
line source


from AddFeed import AddFeed
from DisplayModel import DisplayModel
from FeedEntryItemDelegate import FeedEntryItemDelegate
from FeedEntryTableModel import FeedEntryTableModel
from FeedSettings import FeedSettings
from PreferencesDialog import PreferencesDialog
from PyQt4.QtCore import QUrl
from PyQt4.QtGui import QApplication
from PyQt4.QtGui import QMainWindow
from PyQt4.QtGui import QWidget
from Ui_MainWindow import Ui_MainWindow
import subprocess

STATUS_MESSAGE_DISPLAY_MILLIS = 20000

class MainWindow(QMainWindow):
    def __init__(self, backend=None):
        QWidget.__init__(self, None)
        self.backend = backend
        self.preferences = backend.preferences()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.updateFeedList()
        self.initFeedEntryList()

    def updateFeedList(self):
        self.allFeeds = self.backend.getFeeds()
        feedModel = DisplayModel(self, self.allFeeds, "title")
        self.ui.feedList.setModel(feedModel)
        self.ui.feedList.update()

    def initFeedEntryList(self):
        # setup the default row height. This must be called before a table model is set
        self.ui.feedEntryList.verticalHeader().setDefaultSectionSize(20)

        self.ui.feedEntryList.setItemDelegate(FeedEntryItemDelegate())
        self.ui.feedEntryList.setModel(FeedEntryTableModel([]))
        self.ui.feedEntryList.horizontalHeader().setStretchLastSection(True)

    def feedSelected(self, index):
        self.selectedFeed = self.allFeeds[index.row()]
        self.enableFeedRelatedWidgets()
        self.setupFeedEntries()

    def enableFeedRelatedWidgets(self):
        self.ui.actionFeedSettings.setEnabled(True)
        self.ui.actionMarkFeedRead.setEnabled(True)
        self.ui.actionDeleteFeed.setEnabled(True)

    def setupFeedEntries(self):
        hideReadEntries = self.preferences.hideReadFeedEntries()
        self.feedEntries = self.backend.entriesForFeed(self.selectedFeed, hideReadEntries)
        self.initFeedDisplayModel()

    def initFeedDisplayModel(self):
        self.setupFeedTableModel()
        self.ui.feedEntryList.update()
        self.setupFeedTableHeaderWidths()
        self.scrollFirstRowInFeedTableToVisible()

    def setupFeedTableModel(self):
        model = FeedEntryTableModel(self.feedEntries)
        self.ui.feedEntryList.setModel(model)
        self.ui.feedEntryList.itemDelegate().entries = self.feedEntries

    def setupFeedTableHeaderWidths(self):
        width = self.ui.feedEntryList.width()
        firstColumnWidth = int(width * 0.8)
        self.ui.feedEntryList.setColumnWidth(0, firstColumnWidth)

    def scrollFirstRowInFeedTableToVisible(self):
        model = self.ui.feedEntryList.model()
        visibleIndex = model.createIndex(0, 0)
        self.ui.feedEntryList.scrollTo(visibleIndex)

    def feedEntrySelected(self, index):
        self.ui.menuArticle.setEnabled(True)
        self.ui.actionOpenLink.setEnabled(True)

        row = index.row()
        self.selectedEntry = self.feedEntries[row]
        self.selectedEntry.markRead()

        if self.selectedEntry.feed.auto_load_entry_link:
            self.openLinkFromSelectedEntry()
        else:
            self.openSummaryFromSelectedEntry()

    def feedEntryDoubleClicked(self, index):
        self.ui.menuArticle.setEnabled(True)
        self.openSelectedEntryInBrowser()

    def openSummaryFromSelectedEntry(self):
        # TODO this is the wrong base url, figure out the correct one
        baseUrl = QUrl(self.selectedEntry.link)
        self.ui.webView.setHtml(self.selectedEntry.summary, baseUrl)

    def openLinkFromSelectedEntry(self):
        if self.selectedEntry.feed.always_open_in_browser:
            self.openSelectedEntryInBrowser()
        else:
            self.openSelectedEntryInWebView()

    def openSelectedEntryInWebView(self):
        message = "Open %s ..." % (self.selectedEntry.title)
        self._updateStatusBar(message)
        url = QUrl(self.selectedEntry.link)
        self.ui.webView.load(url)
        self.ui.webView.show()

    def openSelectedEntryInBrowser(self):
        message = "Open %s in external browser" % (self.selectedEntry.title)
        self._updateStatusBar(message)
        # TODO make browser configurable
        browser = "/usr/local/bin/opera"
        subprocess.Popen([browser, self.selectedEntry.link])

    def toggleReadOnSelectedEntry(self):
        self.backend.toggleRead(self.selectedEntry)
        self.ui.feedEntryList.doItemsLayout()

    def markSelectedFeedRead(self):
        self.backend.markAllEntriesRead(self.selectedFeed)
        self.ui.feedEntryList.doItemsLayout()

    def markSelectedEntriesRead(self):
        entriesToBeMarked = []
        selectedIndexes = self.ui.feedEntryList.selectedIndexes()
        for index in selectedIndexes:
            # selectedIndexes returns one QModelIndex instance per row/column combo.
            # We are only interested in the rows here so just operate on the first
            # column
            if index.column() == 0:
                row = index.row()
                entriesToBeMarked.append(self.feedEntries[row])
        self.backend.markFeedEntriesAsRead(entriesToBeMarked)
        self.selectedEntry = None
        self.ui.feedEntryList.doItemsLayout()

    def addFeed(self):
        addFeed = AddFeed(self.backend)
        success = addFeed.exec_()
        if not success:
            return

        if addFeed.exception is not None:
            message = "Error while adding feed: " + str(addFeed.exception)
            self._updateStatusBar(message)
        else:
            self.updateFeedList()

    def deleteFeed(self):
        try:
            self.backend.deleteFeed(self.selectedFeed)
            self.updateFeedList()
        except Exception as exception:
            message = "Error while deleting feed: " + str(exception)
            self._updateStatusBar(message)

    def showPreferences(self):
        preferences = PreferencesDialog(self.backend)
        preferences.exec_()

    def showFeedSettings(self):
        feedSettings = FeedSettings(self.selectedFeed, self.backend)
        feedSettings.exec_()

    def _updateStatusBar(self, message):
        self.ui.statusbar.showMessage(message, STATUS_MESSAGE_DISPLAY_MILLIS)

    def close(self):
        self.backend.dispose()
        QMainWindow.close(self)

    def copyArticleURLToClipboard(self):
        clipboard = QApplication.clipboard()
        clipboard.setText(self.selectedEntry.link)