view MainWindow.py @ 119:04a730f9d07d backend

move all sqlalchemy related classes to the respective sub-package. use a backend to abstract from access to the data
author Dirk Olmes <dirk@xanthippe.ping.de>
date Sun, 21 Aug 2011 03:55:16 +0200
parents e9145e8dd698
children e830fa1cc7a2
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.selectedFeed.entriesSortedByUpdateDate(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.selectedEntry.toggleRead()
        self.session.commit()
        self.ui.feedEntryList.doItemsLayout()

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

    def markSelectedEntriesRead(self):
        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()
                # use selectedEntry here to ensure it has a valid state after all
                # selected entries are marked read
                self.selectedEntry = self.feedEntries[row]
                self.selectedEntry.markRead()
        self.session.commit()
        self.ui.feedEntryList.doItemsLayout()

    def addFeed(self):
        pass
#        addFeed = AddFeed(self.session)
#        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.session.commit()
#            self.updateFeedList()

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

    def showPreferences(self):
        pass
#        preferences = PreferencesDialog(self.session)
#        preferences.exec_()

    def showFeedSettings(self):
        feedSettings = FeedSettings(self.session, self.selectedFeed)
        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)