[Search] Refactor: implement asynchronous search

To prevent UI from blocking and to prevent excessive searches, the
custom model needs to be refactored to not do synchronous searches in
on_get_value().

This is achieved by
 * adding  SearchModel.set_request_range() so the view can inform the
   model of the required rows
 * Adding a dict-based cache for the search results
 * Adding row-inserted/changed/deleted signals to the model

Fixes #2

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
[player] Use buttons with stock media images

Also use a play/pause button instead of separate ones

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
[Player] Remove Stop-button

Remove "Stop" button: it does not give the user much added value
and the relation to pause is not clear to many people (this is
why most modern players do not use it).

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
[Player] Update UI based only on gstreamer state

This is simpler and less error-prone than doing it both from
gstreamer and UI event handlers.

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
[Player] Fix seeking

Do seeks so that the UI doesn't block. Enable seeking
while playing.

Fixes #3

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
[Player] Create the adjustment like other widgets

Create the adjustment on init(), only do set_upper()
when duration is available.

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
[Player] Move play-pause-button next to the progress scale

Change is a purely visual one.

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
[Search] Refactor: separate generic model code from search

Create a new GenericModel class and put most of SearchModel code
there. Subclass SearchModel from GenericModel. Later we can use
GenericModel for BrowseModel as well, removing duplicate code.

No functional changes.

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
[Model] Name column indexes

This makes it easier to change the model without breaking things outside
the model.

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
[Model] stop fetching if all results have been fetched already

This will skip one useless search/browse call in some cases.

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
[Model] Add "static rows" in the model

This allows inserting a static row into the model. It will be
inserted before the actual search/browse results. This is useful
for BrowseModel that wants to edd e.g. ".."-row for moving up a
directory

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
[Browse] Use the GenericModel for Browse

This removes a lot of duplicate code and makes Browse perform as well
as Search.

Note that BrowseModels are discarded as soon as the view changes to
another "directory" (BrowseModel). Caching could be added later on.

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
[Model] auto-load items also when max_items is not known

This mostly removes special casing for the servers that do not support
max_items: the code already works quite well for them.

Add GenericModel.length_is_known() so we can still do the most
efficient thing with better servers.

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
[UPnP] Handle GetServers() asynchronously

The call won't take long normally, and the app isn't really useful
until it returns. Nevertheless, D-Bus calls should still be
asynchronous.

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>