Merge branch 'master' of https://github.com/clementine-player/Clementine
This commit is contained in:
commit
c1cea0890b
@ -797,7 +797,7 @@ void Song::BindToQuery(QSqlQuery *query) const {
|
||||
&& Utilities::UrlOnSameDriveAsClementine(d->url_)) {
|
||||
query->bindValue(":filename", Utilities::GetRelativePathToClementineBin(d->url_));
|
||||
} else {
|
||||
query->bindValue(":filename", d->url_);
|
||||
query->bindValue(":filename", d->url_.toEncoded());
|
||||
}
|
||||
|
||||
query->bindValue(":mtime", notnullintval(d->mtime_));
|
||||
|
@ -457,9 +457,9 @@ QByteArray Sha256(const QByteArray& data) {
|
||||
}
|
||||
|
||||
// File must not be open and will be closed afterwards!
|
||||
QByteArray Md5File(QFile &file) {
|
||||
QByteArray Sha1File(QFile &file) {
|
||||
file.open(QIODevice::ReadOnly);
|
||||
QCryptographicHash hash(QCryptographicHash::Md5);
|
||||
QCryptographicHash hash(QCryptographicHash::Sha1);
|
||||
QByteArray data;
|
||||
|
||||
while(!file.atEnd()) {
|
||||
|
@ -67,7 +67,7 @@ namespace Utilities {
|
||||
QByteArray HmacSha256(const QByteArray& key, const QByteArray& data);
|
||||
QByteArray HmacSha1(const QByteArray& key, const QByteArray& data);
|
||||
QByteArray Sha256(const QByteArray& data);
|
||||
QByteArray Md5File(QFile& file);
|
||||
QByteArray Sha1File(QFile& file);
|
||||
QByteArray Sha1CoverHash(const QString& artist, const QString& album);
|
||||
|
||||
|
||||
|
@ -39,20 +39,38 @@ LibraryQuery::LibraryQuery(const QueryOptions& options)
|
||||
// expected with sqlite's FTS3:
|
||||
// 1) Append * to all tokens.
|
||||
// 2) Prefix "fts" to column names.
|
||||
// 3) Remove colons which don't correspond to column names.
|
||||
|
||||
// Split on whitespace
|
||||
QStringList tokens(options.filter().split(QRegExp("\\s+")));
|
||||
QStringList tokens(options.filter().split(
|
||||
QRegExp("\\s+"), QString::SkipEmptyParts));
|
||||
QString query;
|
||||
foreach (QString token, tokens) {
|
||||
token.remove('(');
|
||||
token.remove(')');
|
||||
token.remove('"');
|
||||
token.replace('-', ' ');
|
||||
|
||||
if (token.contains(':'))
|
||||
query += "fts" + token + "* ";
|
||||
else
|
||||
if (token.contains(':')) {
|
||||
// Only prefix fts if the token is a valid column name.
|
||||
if (Song::kFtsColumns.contains("fts" + token.section(':', 0, 0),
|
||||
Qt::CaseInsensitive)) {
|
||||
// Account for multiple colons.
|
||||
QString columntoken = token.section(
|
||||
':', 0, 0, QString::SectionIncludeTrailingSep);
|
||||
QString subtoken = token.section(':', 1, -1);
|
||||
subtoken.replace(":", " ");
|
||||
subtoken = subtoken.trimmed();
|
||||
query += "fts" + columntoken + subtoken + "* ";
|
||||
} else {
|
||||
token.replace(":", " ");
|
||||
token = token.trimmed();
|
||||
query += token + "* ";
|
||||
}
|
||||
} else {
|
||||
query += token + "* ";
|
||||
}
|
||||
}
|
||||
|
||||
where_clauses_ << "fts.%fts_table_noprefix MATCH ?";
|
||||
bound_values_ << query;
|
||||
|
@ -642,9 +642,9 @@ void OutgoingDataCreator::SendSingleSong(RemoteClient* client, const Song &song,
|
||||
// Open the file
|
||||
QFile file(song.url().toLocalFile());
|
||||
|
||||
// Get md5 for file
|
||||
QByteArray md5 = Utilities::Md5File(file).toHex();
|
||||
qLog(Debug) << "md5 for file" << song.url().toLocalFile() << "=" << md5;
|
||||
// Get sha1 for file
|
||||
QByteArray sha1 = Utilities::Sha1File(file).toHex();
|
||||
qLog(Debug) << "sha1 for file" << song.url().toLocalFile() << "=" << sha1;
|
||||
|
||||
file.open(QIODevice::ReadOnly);
|
||||
|
||||
@ -670,7 +670,7 @@ void OutgoingDataCreator::SendSingleSong(RemoteClient* client, const Song &song,
|
||||
chunk->set_file_number(song_no);
|
||||
chunk->set_size(file.size());
|
||||
chunk->set_data(data.data(), data.size());
|
||||
chunk->set_file_hash(md5.data(), md5.size());
|
||||
chunk->set_file_hash(sha1.data(), sha1.size());
|
||||
|
||||
// On the first chunk send the metadata, so the client knows
|
||||
// what file it receives.
|
||||
@ -753,9 +753,9 @@ void OutgoingDataCreator::SendLibrary(RemoteClient *client) {
|
||||
// Open the file
|
||||
QFile file(temp_file_name);
|
||||
|
||||
// Get the md5 hash
|
||||
QByteArray md5 = Utilities::Md5File(file).toHex();
|
||||
qLog(Debug) << "Library md5" << md5;
|
||||
// Get the sha1 hash
|
||||
QByteArray sha1 = Utilities::Sha1File(file).toHex();
|
||||
qLog(Debug) << "Library sha1" << sha1;
|
||||
|
||||
file.open(QIODevice::ReadOnly);
|
||||
|
||||
@ -777,7 +777,7 @@ void OutgoingDataCreator::SendLibrary(RemoteClient *client) {
|
||||
chunk->set_chunk_number(chunk_number);
|
||||
chunk->set_size(file.size());
|
||||
chunk->set_data(data.data(), data.size());
|
||||
chunk->set_file_hash(md5.data(), md5.size());
|
||||
chunk->set_file_hash(sha1.data(), sha1.size());
|
||||
|
||||
// Send data directly to the client
|
||||
client->SendData(&msg);
|
||||
|
@ -1254,3 +1254,24 @@ void PlaylistView::FadePreviousBackgroundImage(qreal value) {
|
||||
void PlaylistView::PlayerStopped() {
|
||||
CurrentSongChanged(Song(), QString(), QImage());
|
||||
}
|
||||
|
||||
void PlaylistView::focusInEvent(QFocusEvent* event) {
|
||||
QTreeView::focusInEvent(event);
|
||||
|
||||
if (event->reason() == Qt::TabFocusReason ||
|
||||
event->reason() == Qt::BacktabFocusReason) {
|
||||
// If there's a current item but no selection it probably means the list was
|
||||
// filtered, and the selected item does not match the filter. If there's
|
||||
// only 1 item in the view it is now impossible to select that item without
|
||||
// using the mouse.
|
||||
const QModelIndex& current = selectionModel()->currentIndex();
|
||||
if (current.isValid() &&
|
||||
selectionModel()->selectedIndexes().isEmpty()) {
|
||||
QItemSelection new_selection(
|
||||
current.sibling(current.row(), 0),
|
||||
current.sibling(current.row(),
|
||||
current.model()->columnCount(current.parent()) - 1));
|
||||
selectionModel()->select(new_selection, QItemSelectionModel::Select);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,6 +134,7 @@ class PlaylistView : public QTreeView {
|
||||
void dropEvent(QDropEvent *event);
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
bool eventFilter(QObject* object, QEvent* event);
|
||||
void focusInEvent(QFocusEvent* event);
|
||||
|
||||
// QAbstractScrollArea
|
||||
void scrollContentsBy(int dx, int dy);
|
||||
|
@ -138,7 +138,7 @@ void UltimateLyricsProvider::LyricsFetched() {
|
||||
|
||||
// Apply exclude rules
|
||||
foreach (const Rule& rule, exclude_rules_) {
|
||||
ApplyExcludeRule(rule, &lyrics);
|
||||
ApplyExcludeRule(rule, &content);
|
||||
}
|
||||
|
||||
if (!content.isEmpty() and HTMLHasAlphaNumeric(content)) {
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1700,7 +1700,10 @@ void MainWindow::ShowInLibrary() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
QString search = "artist:"+songs[0].artist()+" album:"+songs[0].album();
|
||||
QString search;
|
||||
if (!songs.isEmpty()) {
|
||||
search = "artist:" + songs.first().artist() + " album:" + songs.first().album();
|
||||
}
|
||||
library_view_->filter()->ShowInLibrary(search);
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,6 @@ void ExtendedEditor::Paint(QPaintDevice* device) {
|
||||
}
|
||||
} else {
|
||||
clear_button_->setVisible(has_clear_button_);
|
||||
Resize();
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,16 +142,19 @@ LineEdit::LineEdit(QWidget* parent)
|
||||
ExtendedEditor(this)
|
||||
{
|
||||
connect(reset_button_, SIGNAL(clicked()), SIGNAL(Reset()));
|
||||
connect(this, SIGNAL(textChanged(QString)), SLOT(text_changed(QString)));
|
||||
}
|
||||
|
||||
void LineEdit::set_text(const QString& text) {
|
||||
QLineEdit::setText(text);
|
||||
|
||||
void LineEdit::text_changed(const QString& text) {
|
||||
if (text.isEmpty()) {
|
||||
// Consider empty string as LTR
|
||||
set_rtl(false);
|
||||
} else {
|
||||
// For some reason Qt will detect any text with LTR at the end as LTR, so instead
|
||||
// compare only the first character
|
||||
if (!text.isEmpty()) {
|
||||
set_rtl(QString(text.at(0)).isRightToLeft());
|
||||
}
|
||||
Resize();
|
||||
}
|
||||
|
||||
void LineEdit::paintEvent(QPaintEvent* e) {
|
||||
|
@ -103,7 +103,7 @@ public:
|
||||
// ExtendedEditor
|
||||
void set_focus() { QLineEdit::setFocus(); }
|
||||
QString text() const { return QLineEdit::text(); }
|
||||
void set_text(const QString& text);
|
||||
void set_text(const QString& text) { QLineEdit::setText(text); }
|
||||
void set_enabled(bool enabled) { QLineEdit::setEnabled(enabled); }
|
||||
|
||||
protected:
|
||||
@ -114,6 +114,9 @@ private:
|
||||
bool is_rtl() const { return is_rtl_; }
|
||||
void set_rtl(bool rtl) { is_rtl_ = rtl; }
|
||||
|
||||
private slots:
|
||||
void text_changed(const QString& text);
|
||||
|
||||
signals:
|
||||
void Reset();
|
||||
};
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
|
||||
const int StretchHeaderView::kMinimumColumnWidth = 10;
|
||||
const int StretchHeaderView::kMinimumColumnWidth = 20;
|
||||
const int StretchHeaderView::kMagicNumber = 0x502c950f;
|
||||
|
||||
StretchHeaderView::StretchHeaderView(Qt::Orientation orientation, QWidget* parent)
|
||||
@ -33,6 +33,7 @@ StretchHeaderView::StretchHeaderView(Qt::Orientation orientation, QWidget* paren
|
||||
in_mouse_move_event_(false)
|
||||
{
|
||||
connect(this, SIGNAL(sectionResized(int,int,int)), SLOT(SectionResized(int,int,int)));
|
||||
setMinimumSectionSize(kMinimumColumnWidth);
|
||||
}
|
||||
|
||||
void StretchHeaderView::setModel(QAbstractItemModel* model) {
|
||||
@ -90,7 +91,6 @@ void StretchHeaderView::UpdateWidths(const QList<int>& sections) {
|
||||
hideSection(i);
|
||||
else if (pixels != 0 && isSectionHidden(i)) {
|
||||
showSection(i);
|
||||
AssertMinimalColumnWidth(i);
|
||||
}
|
||||
|
||||
if (pixels != 0)
|
||||
@ -145,7 +145,6 @@ void StretchHeaderView::SetSectionHidden(int logical, bool hidden) {
|
||||
HideSection(logical);
|
||||
} else {
|
||||
ShowSection(logical);
|
||||
AssertMinimalColumnWidth(logical);
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,13 +224,6 @@ void StretchHeaderView::SetColumnWidth(int logical, ColumnWidthType width) {
|
||||
NormaliseWidths(other_columns);
|
||||
}
|
||||
|
||||
// makes sure the column will apear no matter what
|
||||
void StretchHeaderView::AssertMinimalColumnWidth(int logical) {
|
||||
if (sectionSize(logical) < kMinimumColumnWidth) {
|
||||
resizeSection(logical, kMinimumColumnWidth);
|
||||
}
|
||||
}
|
||||
|
||||
bool StretchHeaderView::RestoreState(const QByteArray& data) {
|
||||
QDataStream s(data);
|
||||
s.setVersion(QDataStream::Qt_4_6);
|
||||
|
@ -71,11 +71,6 @@ protected:
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
|
||||
private:
|
||||
// If the width of the given column is less than a sensible threshold, resize
|
||||
// it to make it bigger. Workaround for a QHeaderView oddity that means a
|
||||
// column can be visible but with a width of 0.
|
||||
void AssertMinimalColumnWidth(int logical);
|
||||
|
||||
// Scales column_widths_ values so the total is 1.0.
|
||||
void NormaliseWidths(const QList<int>& sections = QList<int>());
|
||||
|
||||
|
@ -38,10 +38,6 @@ TrackSlider::TrackSlider(QWidget* parent)
|
||||
{
|
||||
ui_->setupUi(this);
|
||||
|
||||
QFont font("Comic Sans MS");
|
||||
ui_->elapsed->setFont(font);
|
||||
ui_->remaining->setFont(font);
|
||||
|
||||
UpdateLabelWidth();
|
||||
|
||||
// Load settings
|
||||
|
Loading…
x
Reference in New Issue
Block a user