Service value ranges and router adjustments

Allows services to register a value as being a range so that the UI can
properly use a SpinBox instead of a regular dropdown.
Separated Router _validate() method from play()

This moves the logic out that is responsible for dealing with validating
and normalizing the service ID, text, and options such that it will be
reusable between all three future methods (play(), record(), and
record_multi()).
Basic service-based dialog setup

This is realized first with the single media file insert dialog.
Threading support for service calls

Introduces two router-internal classes that handle the pooling and
worker threads.