Merge branch 'master' of https://github.com/clementine-player/Clementine
This commit is contained in:
commit
565c2cc921
|
@ -8,6 +8,7 @@
|
|||
*.dll
|
||||
*.exe
|
||||
*.pyd
|
||||
build/
|
||||
3rdparty/libprojectm/config.inp
|
||||
3rdparty/libprojectm/libprojectM.pc
|
||||
CMakeLists.txt.user
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/python
|
||||
# Emulates the behaviour of codesign --deep which is missing on OS X < 10.9
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
def SignPath(path, developer_id):
|
||||
args = [
|
||||
'codesign',
|
||||
'--preserve-metadata=identifier,entitlements,resource-rules,requirements',
|
||||
'-s', developer_id,
|
||||
'-fv', path
|
||||
]
|
||||
subprocess.check_call(args)
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 3:
|
||||
print 'Usage: %s <developer id> <app bundle>' % sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
developer_id = sys.argv[1]
|
||||
app_bundle = sys.argv[2]
|
||||
|
||||
for root, dirs, files in os.walk(app_bundle):
|
||||
for dir in dirs:
|
||||
if re.search(r'\.framework$', dir):
|
||||
SignPath(os.path.join(root, dir), developer_id)
|
||||
|
||||
for file in files:
|
||||
if re.search(r'\.(dylib|so)$', file):
|
||||
SignPath(os.path.join(root, file), developer_id)
|
||||
elif re.match(r'(clementine-spotifyblob|clementine-tagreader|gst-plugin-scanner)', file):
|
||||
SignPath(os.path.join(root, file), developer_id)
|
||||
|
||||
SignPath(app_bundle, developer_id)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1403,7 +1403,7 @@ if (APPLE)
|
|||
add_custom_target(
|
||||
sign
|
||||
COMMAND
|
||||
codesign --deep --preserve-metadata=identifier,entitlements,resource-rules,requirements -s ${APPLE_DEVELOPER_ID} -fv ${PROJECT_BINARY_DIR}/clementine.app
|
||||
${PROJECT_SOURCE_DIR}/dist/codesign.py ${APPLE_DEVELOPER_ID} ${PROJECT_BINARY_DIR}/clementine.app
|
||||
DEPENDS clementine
|
||||
VERBATIM
|
||||
)
|
||||
|
|
|
@ -145,8 +145,14 @@ QStandardItem* GlobalSearchModel::BuildContainers(
|
|||
sort_text = display_text;
|
||||
break;
|
||||
|
||||
case LibraryModel::GroupBy_Bitrate:
|
||||
display_text = QString(s.bitrate(), 1);
|
||||
sort_text = display_text;
|
||||
break;
|
||||
|
||||
case LibraryModel::GroupBy_None:
|
||||
return parent;
|
||||
|
||||
}
|
||||
|
||||
// Find a container for this level
|
||||
|
|
|
@ -188,7 +188,7 @@ QString CloudFileService::GuessMimeTypeForFile(const QString& filename) const {
|
|||
return "audio/mpeg";
|
||||
} else if (filename.endsWith(".m4a")) {
|
||||
return "audio/mpeg";
|
||||
} else if (filename.endsWith(".ogg")) {
|
||||
} else if (filename.endsWith(".ogg") || filename.endsWith(".opus")) {
|
||||
return "application/ogg";
|
||||
} else if (filename.endsWith(".flac")) {
|
||||
return "application/x-flac";
|
||||
|
|
|
@ -136,6 +136,12 @@ void DropboxService::RequestFileListFinished(QNetworkReply* reply) {
|
|||
continue;
|
||||
}
|
||||
|
||||
// Workaround: Since Dropbox doesn't recognize Opus files and thus treats them
|
||||
// as application/octet-stream, we overwrite the mime type here
|
||||
if (metadata["mime_type"].toString() == "application/octet-stream" &&
|
||||
url.toString().endsWith(".opus"))
|
||||
metadata["mime_type"] = GuessMimeTypeForFile(url.toString());
|
||||
|
||||
if (ShouldIndexFile(url, metadata["mime_type"].toString())) {
|
||||
QNetworkReply* reply = FetchContentUrl(url);
|
||||
NewClosure(reply, SIGNAL(finished()),
|
||||
|
|
|
@ -36,8 +36,9 @@ GroupByDialog::GroupByDialog(QWidget *parent)
|
|||
mapping_.insert(Mapping(LibraryModel::GroupBy_Genre, 6));
|
||||
mapping_.insert(Mapping(LibraryModel::GroupBy_Year, 7));
|
||||
mapping_.insert(Mapping(LibraryModel::GroupBy_YearAlbum, 8));
|
||||
mapping_.insert(Mapping(LibraryModel::GroupBy_Performer, 9));
|
||||
mapping_.insert(Mapping(LibraryModel::GroupBy_Grouping, 10));
|
||||
mapping_.insert(Mapping(LibraryModel::GroupBy_Bitrate, 9));
|
||||
mapping_.insert(Mapping(LibraryModel::GroupBy_Performer, 10));
|
||||
mapping_.insert(Mapping(LibraryModel::GroupBy_Grouping, 11));
|
||||
|
||||
connect(ui_->button_box->button(QDialogButtonBox::Reset), SIGNAL(clicked()),
|
||||
SLOT(Reset()));
|
||||
|
|
|
@ -88,6 +88,11 @@
|
|||
<string>Year - Album</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Bitrate</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
|
@ -144,6 +149,11 @@
|
|||
<string>Year - Album</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Bitrate</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
|
@ -200,6 +210,11 @@
|
|||
<string>Year - Album</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Bitrate</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
@ -190,6 +190,7 @@ void LibraryModel::SongsDiscovered(const SongList& songs) {
|
|||
case GroupBy_YearAlbum:
|
||||
key = PrettyYearAlbum(qMax(0, song.year()), song.album()); break;
|
||||
case GroupBy_FileType: key = song.filetype(); break;
|
||||
case GroupBy_Bitrate: key = song.bitrate(); break;
|
||||
case GroupBy_None:
|
||||
qLog(Error) << "GroupBy_None";
|
||||
break;
|
||||
|
@ -280,6 +281,9 @@ QString LibraryModel::DividerKey(GroupBy type, LibraryItem* item) const {
|
|||
case GroupBy_YearAlbum:
|
||||
return SortTextForYear(item->metadata.year());
|
||||
|
||||
case GroupBy_Bitrate:
|
||||
return SortTextForBitrate(item->metadata.bitrate());
|
||||
|
||||
case GroupBy_None:
|
||||
return QString();
|
||||
}
|
||||
|
@ -313,6 +317,11 @@ QString LibraryModel::DividerDisplayText(GroupBy type, const QString& key) const
|
|||
return tr("Unknown");
|
||||
return QString::number(key.toInt()); // To remove leading 0s
|
||||
|
||||
case GroupBy_Bitrate:
|
||||
if (key == "000")
|
||||
return tr("Unknown");
|
||||
return QString::number(key.toInt()); // To remove leading 0s
|
||||
|
||||
case GroupBy_None:
|
||||
// fallthrough
|
||||
;
|
||||
|
@ -739,6 +748,9 @@ void LibraryModel::InitQuery(GroupBy type, LibraryQuery* q) {
|
|||
case GroupBy_AlbumArtist:
|
||||
q->SetColumnSpec("DISTINCT effective_albumartist");
|
||||
break;
|
||||
case GroupBy_Bitrate:
|
||||
q->SetColumnSpec("DISTINCT bitrate");
|
||||
break;
|
||||
case GroupBy_None:
|
||||
q->SetColumnSpec("%songs_table.ROWID, " + Song::kColumnSpec);
|
||||
break;
|
||||
|
@ -796,6 +808,9 @@ void LibraryModel::FilterQuery(GroupBy type, LibraryItem* item, LibraryQuery* q)
|
|||
case GroupBy_FileType:
|
||||
q->AddWhere("filetype", item->metadata.filetype());
|
||||
break;
|
||||
case GroupBy_Bitrate:
|
||||
q->AddWhere("bitrate", item->key);
|
||||
break;
|
||||
case GroupBy_None:
|
||||
qLog(Error) << "Unknown GroupBy type" << type << "used in filter";
|
||||
break;
|
||||
|
@ -825,6 +840,7 @@ LibraryItem* LibraryModel::ItemFromQuery(GroupBy type,
|
|||
int container_level) {
|
||||
LibraryItem* item = InitItem(type, signal, parent, container_level);
|
||||
int year = 0;
|
||||
int bitrate = 0;
|
||||
|
||||
switch (type) {
|
||||
case GroupBy_Artist:
|
||||
|
@ -863,6 +879,12 @@ LibraryItem* LibraryModel::ItemFromQuery(GroupBy type,
|
|||
item->key = item->metadata.TextForFiletype();
|
||||
break;
|
||||
|
||||
case GroupBy_Bitrate:
|
||||
bitrate = qMax(0, row.value(0).toInt());
|
||||
item->key = QString::number(bitrate);
|
||||
item->sort_text = SortTextForBitrate(bitrate) + " ";
|
||||
break;
|
||||
|
||||
case GroupBy_None:
|
||||
item->metadata.InitFromQuery(row, true);
|
||||
item->key = item->metadata.title();
|
||||
|
@ -881,6 +903,7 @@ LibraryItem* LibraryModel::ItemFromSong(GroupBy type,
|
|||
int container_level) {
|
||||
LibraryItem* item = InitItem(type, signal, parent, container_level);
|
||||
int year = 0;
|
||||
int bitrate = 0;
|
||||
|
||||
switch (type) {
|
||||
case GroupBy_Artist:
|
||||
|
@ -918,6 +941,12 @@ LibraryItem* LibraryModel::ItemFromSong(GroupBy type,
|
|||
item->key = s.TextForFiletype();
|
||||
break;
|
||||
|
||||
case GroupBy_Bitrate:
|
||||
bitrate = qMax(0, s.bitrate());
|
||||
item->key = QString::number(bitrate);
|
||||
item->sort_text = SortTextForBitrate(bitrate) + " ";
|
||||
break;
|
||||
|
||||
case GroupBy_None:
|
||||
item->metadata = s;
|
||||
item->key = s.title();
|
||||
|
@ -1004,6 +1033,12 @@ QString LibraryModel::SortTextForYear(int year) {
|
|||
return QString("0").repeated(qMax(0, 4 - str.length())) + str;
|
||||
}
|
||||
|
||||
QString LibraryModel::SortTextForBitrate(int bitrate) {
|
||||
QString str = QString::number(bitrate);
|
||||
return QString("0").repeated(qMax(0, 3 - str.length())) + str;
|
||||
}
|
||||
|
||||
|
||||
QString LibraryModel::SortTextForSong(const Song& song) {
|
||||
QString ret = QString::number(qMax(0, song.disc()) * 1000 + qMax(0, song.track()));
|
||||
ret.prepend(QString("0").repeated(6 - ret.length()));
|
||||
|
|
|
@ -82,6 +82,7 @@ class LibraryModel : public SimpleTreeModel<LibraryItem> {
|
|||
GroupBy_FileType = 8,
|
||||
GroupBy_Performer = 9,
|
||||
GroupBy_Grouping = 10,
|
||||
GroupBy_Bitrate = 11,
|
||||
};
|
||||
|
||||
struct Grouping {
|
||||
|
@ -159,6 +160,7 @@ class LibraryModel : public SimpleTreeModel<LibraryItem> {
|
|||
static QString SortText(QString text);
|
||||
static QString SortTextForArtist(QString artist);
|
||||
static QString SortTextForYear(int year);
|
||||
static QString SortTextForBitrate(int bitrate);
|
||||
static QString SortTextForSong(const Song& song);
|
||||
|
||||
signals:
|
||||
|
|
Loading…
Reference in New Issue