QUrl interprets a single number as an ip address, so the track URL cdda://1
would become cdda://0.0.0.1. A previous fix addresses this issue by adding an
extra character "a" to the affected URLs then removing the last instance of the
character upon usage. However, this didn't apply when a path was present
(cdda:///dev/sr0/1), but would still attempt to reverse the change later
(cdd:///dev/sr0/1).
This change applies the fix-up to all cdda urls and moves the conversion
utilities to a single location.
See: 335bc89c9 ("Workaround for broken CD playback in Qt5 (#6021)")
In Application::MoveToNewThread, name the new thread after the object being
moved. Give those objects names as well.
The thread names display in gdb with "info threads".
Add a tab for Qt debug features. Initially provides access to dumpObjectTree() on
Application and MainWindow objects. This dumps the object's child objects to the
log.
The NetworkRemote is moved to a new thread after creation. On that thread, its
child classes create timers. When the network remote class is deleted on the
main thread, we see "Timers cannot be stopped from another thread".
To avoid this error, use deleteLater to delete NetworkRemote and its composition
classes on its own thread.
According to the gst_element_request_pad documentation, request pads must be
released after usage. They aren't automatically released and dereferenced when
the element is destroyed.
Add Accept, Apply, Reject methods to settings pages to mirror dialog. This will
allow settings pages to handle these events at a more granular level and will
allow common behavor in the base class.
Pressing the close button on the window sends a close event, where other methods
of exiting visualization just hide the window. If shown again after close, the
window will be empty. To fix this, handle and reject the close event. Call hide
instead.
The rowsAboutToBeRemoved signal from the model provides a parent index, but with
QStandardItemModel, top level items are added to an invisible root item that
doesn't have a valid index. This causes the range check to miss top level items
due to a perceived parent mismatch. When the load completes, it attempts to
access an object that has been deleted.
RedirectPolicyAttribute was introduced in Qt 5.9, but Debian Stretch is at 5.7.
This change can be reverted when the base support version moves to 5.9.
Add a class to wrap the URL in the playback engines. In the future, this will
contain authentication information for the specified URL. It can also include
the start and end time as well as other data that is currently specified along
with the URL.
While iterating over expandList in refreshExpanded, calls to setExpanded cause
the list to be appended. Since QList uses an array implementation that must
reallocate when reserved space is exhausted, iterators are unsafe for this case.
Use indexes, which are O(1) in QLists, instead of iterators.
- Group list and settings so they can be enabled/disabled together.
- Make default selection shortcut list. Previous behavior set options
for the first item, but didn't highlight selection.
- Rename ItemClicked to CurrentItemChanged to reflect correct signal.
Nvidia force close from 2011. Last driver version affected was 304.37, 304.83 is the last in the series and is from 2013.
macOS Soundcloud certificate - CA exists in the system bundle.
macOS font issue from 2013
Gnome volume control with Glib older than 2.36 - Debian Jessie, oldoldstable repo has 2.42
Clementine detects a data directory in the same directory as the executable to
determine portable configuration. But there are some packages that create
/usr/bin/data, causing Clementine to run in portable mode.
Use a more unique data directory name, clementine-data, as the portable data
directory. For backwards compatibility, use the legacy data directory if the
already exists there.
Removal of items from a playlist is done with a single transaction. When
Queue::SourceLayoutChanged is called after this, the items in the queue are
checked one at a time. When an item is removed, it triggers dataChanged signal
from the model, connected to the SourceDataChanged slot. There, ItemCountChanged
is emitted which calls UpdateTotalLength. This method will assert when it finds
an item that is in the queue, but not in the playlist.
To solve this, disconnect the ItemCountChanged signal at the beginning of
SourceLayoutChanged and re-enable it after cleaning the queue. The method emits
the signal before returning.
The Google Drive Client::GetFile currently fails due to an extra / in the
request. Use QString::remove to strip all "/" characters from the id.
Note: While this fixes the ability to get the media URL, a change to the
Google Drive API breaks the playback. This will be addressed in a future
commit.
In some cases, URL queries contain auth information. For cases where error
strings are passed from other libraries, such as from gstreamer, add a utility
function, ScrubUrlQueries, to strip queries from URLs in strings.
Incorrect QJsonDocument::fromBinaryData was used several places in
DropboxService. Add a single ParseJsonReply method to the base class that
properly checks and parses network replies and reports errors.
- When parsing a response, use fromJson instead of fromBinaryData.
fromBinaryData expects a serialized binary format.
- Calling toString on a non-string JSON value will return an empty
string. Call toVariant().toString() to do the conversion.
- Add checks for network reply errors.
Noted previously, using the [] operator on a non-const QJsonObject causes the
creation of the key and does not work for checking existence. Convert the
remaining isUndefined call sites to use QJsonObect::contains.
There are several instances of the LibraryModel class used in the system. Each
of these creates a LibraryDirectoryModel instance, but only the instance held
by the main library is every used. Move this out of the LibraryModel class and
into the Library class.
At the time of this commit, the channel list from intergalactic.fm is
unavailable. To the user, this is failing silently. Add an error message for
this failure. If this issue persists, then the service should be removed or a
hardcoded station list should be used.
Use qLogCat to put verbose GStreamer callback messages into a new
GstEnginePipelineCallbacks category. Filter that category instead of
the entire class by default.
The fix-up for URLs for files that that begin with // no longer works since the
QUrl class determines that these modifications are invalid, resulting in an
empty string when converted. Instead of attempting to modify the QUrl, add a
utility function that makes the correction on the encoded byte array at time of
usage.
When a directory is removed from the library during a scan, the scan continues
until complete. This change cancels the scan immediately, unblocking the watcher
thread, then signals the watcher to remove the directory.
A second issue occurs when a previously scanned device is removed during a
scan. All remaining files will be marked as deleted. This change mitigates
this issue, but a timing hole still remains here.
This is can be done without protecting the directory reference since the method
that removes directories from the watch list is only called on the same thread
as the scan, and never during the life of the ScanTransaction object.
When scanning a device such as a mobile phone, it's likely that a directory
containing both image and audio files will be found. Besides the appearance of a
hung scan, it's unlikely that a relevant image will be found.
In the case where filters for relevant filenames don't yield results, set a
sanity limit on the number of images. If the list size is beyond than that
threshold, return an empty path.
On Linux systems, failure to watch a path may be caused by the limit set in
/proc/sys/fs/inotify/max_user_watches. This can be demonstrated by creating
a directory with a large number of empty subdirectories and adding that test
directory as a library.
Check that a file is readable before adding a watch. If adding the watch fails,
report the error to the user only once. Only add the path to subdir_mapping_
if watch succeeds.
QFileSystemWatcher::addPath returns a boolean to indicate success. Modify
QtFSListener::AddPath to reflect that. For now, the MacFSListener version will
always return true.
Using libmtp or libgphoto2 to access a device that gvfs has mounted causes the
connection to fail. libmtp is calling libusb_claim_interface which, according to
libusb documentation, will return LIBUSB_ERROR_BUSY if claimed by a different
program. For mtp and gphoto2 devices discovered by the GioLister, use the file
scheme and access the device through the gvfs mount.
The uri returned from g_file_get_uri is percent encoded. This causes the regex
in GioLister::MakeDeviceUrls to fail and causes the URL to be invalid. In this
case, it falls back to the file scheme. Newer versions of gvfs obtain the serial
id from udev instead of using the bus and device IDs.
Note that this bug covers a different issue where mtp is failing to connect. The
result is actually desired behavior. The follow-up change will address this.
A LibraryBackend may be deleted while an associated LibraryModel object is using
it. An example is an async query running while a connected device is removed.
To prevent this, use a share pointer for the LibraryBackend.
This fixes one case where LibraryBackend is used after deletion. However, the
raw pointer is still passed around in several other places. These should be
evaluated on a case-by-case basis to insure that circular depencencies aren't
introduced.
Create a thread pool for each LibraryModel object and block destruction until
all threads that are operating on this object are complete.
Note that this is not a complete solution. The async query also uses the library
backend which may still be deleted before the thread exits. This will be
addressed in a future change.
A commit in qt 5.7 changes a qWarning to a qFatal if a QThread is still running
when it's deleted. When we get the LoadFinished signal in MtpDevice, stop
the loader thread's event loop to avoid this situation.
See qtbase commit c8277b6e532