ShareDialog: fix auto completion to actualy auto complete

This commit is contained in:
Olivier Goffart 2015-11-16 14:18:01 +01:00
parent 786b602c26
commit 0d21503ee5
6 changed files with 90 additions and 55 deletions

View file

@ -23,8 +23,8 @@ OcsShareeJob::OcsShareeJob(AccountPtr account)
}
void OcsShareeJob::getSharees(const QString search,
const QString itemType,
void OcsShareeJob::getSharees(const QString &search,
const QString &itemType,
int page,
int perPage)
{

View file

@ -36,10 +36,7 @@ public:
*
* @param path Path to request shares for (default all shares)
*/
void getSharees(const QString search,
const QString itemType,
int page = 1,
int perPage = 50);
void getSharees(const QString& search, const QString& itemType, int page = 1, int perPage = 50);
signals:
/**
* Result of the OCS request

View file

@ -53,22 +53,14 @@ Sharee::Type Sharee::type() const
return _type;
}
ShareeModel::ShareeModel(AccountPtr account,
const QString search,
const QString type,
const QVector<QSharedPointer<Sharee>> &shareeBlacklist,
QObject *parent)
: QAbstractListModel(parent),
_account(account),
_search(search),
_type(type),
_shareeBlacklist(shareeBlacklist)
{
ShareeModel::ShareeModel(const AccountPtr &account, const QString &type, QObject *parent)
: QAbstractListModel(parent), _account(account), _type(type)
{ }
}
void ShareeModel::fetch()
void ShareeModel::fetch(const QString &search, const ShareeSet &blacklist)
{
_search = search;
_shareeBlacklist = blacklist;
OcsShareeJob *job = new OcsShareeJob(_account);
connect(job, SIGNAL(shareeJobFinished(QVariantMap)), SLOT(shareesFetched(QVariantMap)));
job->getSharees(_search, _type, 1, 50);
@ -134,11 +126,8 @@ void ShareeModel::shareesFetched(const QVariantMap &reply)
filteredSharees.append(sharee);
}
}
beginInsertRows(QModelIndex(), _sharees.size(), filteredSharees.size());
_sharees += filteredSharees;
endInsertRows();
setNewSharees(filteredSharees);
shareesReady();
}
@ -151,6 +140,41 @@ QSharedPointer<Sharee> ShareeModel::parseSharee(const QVariantMap &data)
return QSharedPointer<Sharee>(new Sharee(shareWith, shareWith, type));
}
/* Set the new sharee
Do that while preserving the model index so the selection stays
*/
void ShareeModel::setNewSharees(const QVector<QSharedPointer<Sharee>>& newSharees)
{
layoutAboutToBeChanged();
const auto persistent = persistentIndexList();
QVector<QSharedPointer<Sharee>> oldPersistantSharee;
oldPersistantSharee.reserve(persistent.size());
std::transform(persistent.begin(), persistent.end(), std::back_inserter(oldPersistantSharee),
[](const QModelIndex &idx) { return idx.data(Qt::UserRole).value<QSharedPointer<Sharee>>(); });
_sharees = newSharees;
QModelIndexList newPersistant;
newPersistant.reserve(persistent.size());
foreach(const QSharedPointer<Sharee> &sharee, oldPersistantSharee) {
auto it = std::find_if(_sharees.constBegin(), _sharees.constEnd(),
[&sharee](const QSharedPointer<Sharee> &s2) {
return s2->format() == sharee->format() && s2->displayName() == sharee->format();
});
if (it == _sharees.constEnd()) {
newPersistant << QModelIndex();
} else {
newPersistant << index(it - _sharees.constBegin());
}
}
changePersistentIndexList(persistent, newPersistant);
layoutChanged();
}
int ShareeModel::rowCount(const QModelIndex &) const
{
return _sharees.size();

View file

@ -44,23 +44,21 @@ public:
QString shareWith() const;
QString displayName() const;
Type type() const;
private:
QString _shareWith;
QString _displayName;
Type _type;
};
class ShareeModel : public QAbstractListModel {
Q_OBJECT
public:
explicit ShareeModel(AccountPtr account,
const QString search,
const QString type,
const QVector<QSharedPointer<Sharee>> &shareeBlacklist,
QObject *parent = 0);
explicit ShareeModel(const AccountPtr &account, const QString &type, QObject *parent = 0);
void fetch();
typedef QVector<QSharedPointer<Sharee>> ShareeSet; // FIXME: make it a QSet<Sharee> when Sharee can be compared
void fetch(const QString &search, const ShareeSet &blacklist);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role) const;
@ -74,6 +72,7 @@ private slots:
private:
QSharedPointer<Sharee> parseSharee(const QVariantMap &data);
void setNewSharees(const QVector<QSharedPointer<Sharee>> &newSharees);
AccountPtr _account;
QString _search;

View file

@ -55,6 +55,12 @@ ShareUserGroupWidget::ShareUserGroupWidget(AccountPtr account, const QString &sh
_isFile = QFileInfo(localPath).isFile();
_completer = new QCompleter(this);
_completerModel = new ShareeModel(_account,
_isFile ? QLatin1String("file") : QLatin1String("folder"),
_completer);
connect(_completerModel, SIGNAL(shareesReady()), this, SLOT(slotShareesReady()));
_completer->setModel(_completerModel);
_ui->shareeLineEdit->setCompleter(_completer);
_ui->searchPushButton->setEnabled(false);
@ -65,6 +71,12 @@ ShareUserGroupWidget::ShareUserGroupWidget(AccountPtr account, const QString &sh
// connect(_ui->shareeLineEdit, SIGNAL(returnPressed()), SLOT(on_searchPushButton_clicked()));
connect(_completer, SIGNAL(activated(QModelIndex)), SLOT(slotCompleterActivated(QModelIndex)));
// Queued connection so this signal is recieved after textChanged
connect(_ui->shareeLineEdit, SIGNAL(textEdited(QString)),
this, SLOT(slotLineEditTextEdited(QString)), Qt::QueuedConnection);
connect(&_completionTimer, SIGNAL(timeout()), this, SLOT(on_searchPushButton_clicked()));
_completionTimer.setSingleShot(true);
_completionTimer.setInterval(600);
}
ShareUserGroupWidget::~ShareUserGroupWidget()
@ -74,6 +86,7 @@ ShareUserGroupWidget::~ShareUserGroupWidget()
void ShareUserGroupWidget::on_shareeLineEdit_textChanged(const QString &text)
{
_completionTimer.stop();
if (text == "") {
_ui->searchPushButton->setEnabled(false);
} else {
@ -81,38 +94,34 @@ void ShareUserGroupWidget::on_shareeLineEdit_textChanged(const QString &text)
}
}
void ShareUserGroupWidget::slotLineEditTextEdited(const QString& text)
{
// First textChanged is called first and we stopped the timer when the text is changed, programatically or not
// Then we restart the timer here if the user touched a key
if (!text.isEmpty()) {
_completionTimer.start();
}
}
void ShareUserGroupWidget::on_searchPushButton_clicked()
{
QVector<QSharedPointer<Sharee>> sharees;
_completionTimer.stop();
ShareeModel::ShareeSet blacklist;
// Add the current user to _sharees since we can't share with ourself
QSharedPointer<Sharee> currentUser(new Sharee(_account->credentials()->user(), "", Sharee::Type::User));
sharees.append(currentUser);
blacklist << currentUser;
for(int i = 0; i < _ui->sharesLayout->count(); i++) {
QWidget *w = _ui->sharesLayout->itemAt(i)->widget();
if (w != NULL) {
const QSharedPointer<Sharee> x = static_cast<ShareWidget *>(w)->share()->getShareWith();
sharees.append(x);
if (auto sw = qobject_cast<ShareWidget *>(w)) {
blacklist << sw->share()->getShareWith();
}
}
_sharees.append(currentUser);
_completerModel->fetch(_ui->shareeLineEdit->text(), blacklist);
_completerModel = new ShareeModel(_account,
_ui->shareeLineEdit->text(),
_isFile ? QLatin1String("file") : QLatin1String("folder"),
sharees,
_completer);
connect(_completerModel, SIGNAL(shareesReady()), SLOT(slotUpdateCompletion()));
_completerModel->fetch();
_completer->setModel(_completerModel);
}
void ShareUserGroupWidget::slotUpdateCompletion()
{
_completer->complete();
}
void ShareUserGroupWidget::getShares()
@ -141,6 +150,11 @@ void ShareUserGroupWidget::slotSharesFetched(const QList<QSharedPointer<Share>>
}
}
void ShareUserGroupWidget::slotShareesReady()
{
_completer->complete();
}
void ShareUserGroupWidget::slotCompleterActivated(const QModelIndex & index)
{
// The index is an index from the QCompletion model which is itelf a proxy
@ -150,12 +164,11 @@ void ShareUserGroupWidget::slotCompleterActivated(const QModelIndex & index)
return;
}
_manager->createShare(_sharePath,
_manager->createShare(_sharePath,
(Share::ShareType)sharee->type(),
sharee->shareWith(),
Share::PermissionRead);
_completer->setModel(NULL);
_ui->shareeLineEdit->setText(QString());
}

View file

@ -22,6 +22,7 @@
#include <QSharedPointer>
#include <QList>
#include <QVector>
#include <QTimer>
class QCompleter;
class QModelIndex;
@ -97,9 +98,10 @@ private slots:
void on_shareeLineEdit_textChanged(const QString &text);
void on_searchPushButton_clicked();
void slotLineEditTextEdited(const QString &text);
void slotUpdateCompletion();
void slotCompleterActivated(const QModelIndex & index);
void slotShareesReady();
private:
Ui::ShareUserGroupWidget *_ui;
@ -109,12 +111,12 @@ private:
QCompleter *_completer;
ShareeModel *_completerModel;
QTimer _completionTimer;
bool _resharingAllowed;
bool _isFile;
ShareManager *_manager;
QVector<QSharedPointer<Sharee>> _sharees;
};
}