Skip to content

Commit

Permalink
QML UI: Basic episode list filters (bug 1527)
Browse files Browse the repository at this point in the history
This still needs some work (i.e. the list might
need refreshing after a download has finished
or an episode has been played/marked as old).
  • Loading branch information
thp committed Jan 14, 2012
1 parent 17bd235 commit 83a5418
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 4 deletions.
48 changes: 48 additions & 0 deletions data/ui/qml/EpisodeList.qml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -7,20 +7,41 @@ import 'config.js' as Config


Item { Item {
id: episodeList id: episodeList
property string currentFilterText


property alias model: listView.model property alias model: listView.model
property alias moving: listView.moving property alias moving: listView.moving
property alias count: listView.count


signal episodeContextMenu(variant episode) signal episodeContextMenu(variant episode)


function showFilterDialog() {
filterDialog.open();
}

function resetSelection() { function resetSelection() {
listView.openedIndex = -1 listView.openedIndex = -1
} }


Text {
anchors.centerIn: parent
color: 'white'
font.pixelSize: 30
horizontalAlignment: Text.AlignHCenter
text: '<big>' + _('No episodes') + '</big>' + '<br><small>' + _('Touch to change filter') + '</small>'
visible: !listView.visible

MouseArea {
anchors.fill: parent
onClicked: episodeList.showFilterDialog()
}
}

ListView { ListView {
id: listView id: listView
anchors.fill: parent anchors.fill: parent
property int openedIndex: -1 property int openedIndex: -1
visible: count > 0


delegate: Item { delegate: Item {
id: listItem id: listItem
Expand Down Expand Up @@ -91,5 +112,32 @@ Item {
ScrollDecorator { ScrollDecorator {
flickableItem: listView flickableItem: listView
} }

SelectionDialog {
id: filterDialog
titleText: _('Show episodes')

function resetSelection() {
selectedIndex = 0;
accepted();
}

onAccepted: {
episodeList.currentFilterText = model.get(selectedIndex).name;
episodeList.model.setFilter(selectedIndex);
}

model: ListModel {}

Component.onCompleted: {
var filters = controller.getEpisodeListFilterNames();

for (var index in filters) {
model.append({name: filters[index]});
}

resetSelection();
}
}
} }


8 changes: 7 additions & 1 deletion data/ui/qml/Main.qml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ Image {
property alias currentEpisode: mediaPlayer.episode property alias currentEpisode: mediaPlayer.episode
property variant currentPodcast: undefined property variant currentPodcast: undefined
property bool hasPodcasts: podcastList.hasItems property bool hasPodcasts: podcastList.hasItems
property alias currentFilterText: episodeList.currentFilterText


property bool playing: mediaPlayer.playing property bool playing: mediaPlayer.playing
property bool canGoBack: (closeButton.isRequired || mediaPlayer.visible) && !progressIndicator.opacity && !myGpoSheetVisible property bool canGoBack: (closeButton.isRequired || mediaPlayer.visible) && !progressIndicator.opacity && !myGpoSheetVisible
property bool hasPlayButton: nowPlayingThrobber.shouldAppear && !progressIndicator.opacity && !myGpoSheetVisible property bool hasPlayButton: nowPlayingThrobber.shouldAppear && !progressIndicator.opacity && !myGpoSheetVisible
property bool hasSearchButton: searchButton.visible && !mediaPlayer.visible && !progressIndicator.opacity && !myGpoSheetVisible property bool hasSearchButton: searchButton.visible && !mediaPlayer.visible && !progressIndicator.opacity && !myGpoSheetVisible
property bool myGpoSheetVisible: false property bool myGpoSheetVisible: false
property bool hasFilterButton: state == 'episodes' && !mediaPlayer.visible


function openMyGpo() { function openMyGpo() {
myGpoEnableSwitch.checked = controller.myGpoEnabled myGpoEnableSwitch.checked = controller.myGpoEnabled
Expand All @@ -45,6 +47,10 @@ Image {
} }
} }


function showFilterDialog() {
episodeList.showFilterDialog()
}

function clickPlayButton() { function clickPlayButton() {
nowPlayingThrobber.clicked() nowPlayingThrobber.clicked()
} }
Expand Down Expand Up @@ -407,7 +413,7 @@ Image {
anchors.right: searchButton.visible?searchButton.left:searchButton.right anchors.right: searchButton.visible?searchButton.left:searchButton.right
wrapMode: Text.NoWrap wrapMode: Text.NoWrap
clip: true clip: true
text: (contextMenu.state == 'opened')?(contextMenu.subscribeMode?_('Add a new podcast'):_('Context menu')):((main.state == 'episodes' || main.state == 'shownotes')?controller.episodeListTitle:"gPodder") text: (contextMenu.state == 'opened')?(contextMenu.subscribeMode?_('Add a new podcast'):_('Context menu')):((main.state == 'episodes' || main.state == 'shownotes')?(controller.episodeListTitle + ' (' + episodeList.count + ')'):"gPodder")
color: 'white' color: 'white'
font.pixelSize: parent.height * .5 font.pixelSize: parent.height * .5
font.bold: false font.bold: false
Expand Down
13 changes: 13 additions & 0 deletions data/ui/qml/main_harmattan.qml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -66,6 +66,19 @@ PageStackWindow {
//anchors.right: toolPlay.visible?toolPlay.left:toolPlay.right //anchors.right: toolPlay.visible?toolPlay.left:toolPlay.right
} }


ToolButton {
id: toolFilter
visible: mainObject.hasFilterButton
onClicked: mainObject.showFilterDialog()
anchors.centerIn: parent

Label {
color: 'white'
text: mainObject.currentFilterText
anchors.centerIn: parent
}
}

ToolIcon { ToolIcon {
id: toolPlay id: toolPlay
iconId: "icon-m-toolbar-content-audio-white" iconId: "icon-m-toolbar-content-audio-white"
Expand Down
2 changes: 1 addition & 1 deletion src/gpodder/model.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ def is_finished(self):
current position is greater than 99 percent of the current position is greater than 99 percent of the
total time or inside the last 10 seconds of a track. total time or inside the last 10 seconds of a track.
""" """
return self.current_position > 0 and \ return self.current_position > 0 and self.total_time > 0 and \
(self.current_position + 10 >= self.total_time or \ (self.current_position + 10 >= self.total_time or \
self.current_position >= self.total_time*.99) self.current_position >= self.total_time*.99)


Expand Down
52 changes: 50 additions & 2 deletions src/gpodder/qmlui/__init__.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from gpodder import core from gpodder import core
from gpodder import util from gpodder import util
from gpodder import my from gpodder import my
from gpodder import query


from gpodder.model import Model from gpodder.model import Model


Expand All @@ -49,6 +50,19 @@
import logging import logging
logger = logging.getLogger("qmlui") logger = logging.getLogger("qmlui")



EPISODE_LIST_FILTERS = [
# (UI label, EQL expression)
(_('All'), None),
(_('Hide deleted'), 'not deleted'),
(_('New'), 'new or downloading'),
(_('Downloaded'), 'downloaded or downloading'),
(_('Deleted'), 'deleted'),
(_('Finished'), 'finished'),
(_('Archived'), 'downloaded and archive'),
(_('Videos'), 'video'),
]

class Controller(QObject): class Controller(QObject):
def __init__(self, root): def __init__(self, root):
QObject.__init__(self) QObject.__init__(self)
Expand Down Expand Up @@ -83,6 +97,10 @@ def getEpisodeListTitle(self):
episodeListTitle = Property(unicode, getEpisodeListTitle, \ episodeListTitle = Property(unicode, getEpisodeListTitle, \
setEpisodeListTitle, notify=episodeListTitleChanged) setEpisodeListTitle, notify=episodeListTitleChanged)


@Slot(result='QStringList')
def getEpisodeListFilterNames(self):
return [caption for caption, eql in EPISODE_LIST_FILTERS]

@Slot(str, result=str) @Slot(str, result=str)
def translate(self, x): def translate(self, x):
return _(x) return _(x)
Expand Down Expand Up @@ -528,7 +546,7 @@ def get_object(self, index):
return self._objects[index.row()] return self._objects[index.row()]


def rowCount(self, parent=QModelIndex()): def rowCount(self, parent=QModelIndex()):
return len(self._objects) return len(self.get_objects())


def data(self, index, role): def data(self, index, role):
if index.isValid(): if index.isValid():
Expand All @@ -553,6 +571,36 @@ def sort(self):
self._objects = sorted(self._objects, key=model.QPodcast.sort_key) self._objects = sorted(self._objects, key=model.QPodcast.sort_key)
self.reset() self.reset()


class gPodderEpisodeListModel(gPodderListModel):
def __init__(self):
gPodderListModel.__init__(self)
self._filter = 0
self._filtered = []

def sort(self):
caption, eql = EPISODE_LIST_FILTERS[self._filter]

if eql is None:
self._filtered = self._objects
else:
eql = query.EQL(eql)
match = lambda episode: eql.match(episode._episode)
self._filtered = filter(match, self._objects)

self.reset()

def get_objects(self):
return self._filtered

def get_object(self, index):
return self._filtered[index.row()]

@Slot(int)
def setFilter(self, filter_index):
self._filter = filter_index
self.sort()


def QML(filename): def QML(filename):
for folder in gpodder.ui_folders: for folder in gpodder.ui_folders:
filename = os.path.join(folder, filename) filename = os.path.join(folder, filename)
Expand Down Expand Up @@ -605,7 +653,7 @@ def __init__(self, args, gpodder_core):
self.controller = Controller(self) self.controller = Controller(self)
self.media_buttons_handler = helper.MediaButtonsHandler() self.media_buttons_handler = helper.MediaButtonsHandler()
self.podcast_model = gPodderPodcastListModel() self.podcast_model = gPodderPodcastListModel()
self.episode_model = gPodderListModel() self.episode_model = gPodderEpisodeListModel()
self.last_episode = None self.last_episode = None


# A dictionary of episodes that are currently active # A dictionary of episodes that are currently active
Expand Down
2 changes: 2 additions & 0 deletions src/gpodder/query.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ def __getitem__(self, k):
return episode.state == gpodder.STATE_DELETED return episode.state == gpodder.STATE_DELETED
elif k == 'played': elif k == 'played':
return not episode.is_new return not episode.is_new
elif k == 'downloading':
return episode.downloading
elif k == 'archive': elif k == 'archive':
return episode.archive return episode.archive
elif k in ('finished', 'fin'): elif k in ('finished', 'fin'):
Expand Down

0 comments on commit 83a5418

Please sign in to comment.