Added ability to filter languages in dictionaries manager.

This commit is contained in:
23rd 2020-02-09 02:22:39 +03:00
parent a0f995b134
commit 311678af80
2 changed files with 87 additions and 9 deletions

View File

@ -16,12 +16,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "mainwidget.h"
#include "mtproto/dedicated_file_loader.h"
#include "spellcheck/spellcheck_utils.h"
#include "styles/style_layers.h"
#include "styles/style_settings.h"
#include "styles/style_boxes.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/multi_select.h"
#include "ui/widgets/popup_menu.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/effects/animations.h"
@ -34,6 +36,13 @@ using namespace Storage::CloudBlob;
using Loading = MTP::DedicatedLoader::Progress;
using DictState = BlobState;
using QueryCallback = Fn<void(const QString &)>;
constexpr auto kMaxQueryLength = 15;
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
#define OLD_QT
using QStringView = QString;
#endif
class Loader : public BlobLoader {
public:
@ -58,11 +67,13 @@ public:
Inner(QWidget *parent, Dictionaries enabledDictionaries);
Dictionaries enabledRows() const;
QueryCallback queryCallback() const;
private:
void setupContent(Dictionaries enabledDictionaries);
Dictionaries _enabledRows;
QueryCallback _queryCallback;
};
@ -115,12 +126,27 @@ void Loader::unpack(const QString &path) {
void Loader::destroy() {
}
auto CreateMultiSelect(QWidget *parent) {
const auto result = Ui::CreateChild<Ui::MultiSelect>(
parent,
st::contactsMultiSelect,
tr::lng_participant_filter());
result->resizeToWidth(st::boxWidth);
result->moveToLeft(0, 0);
return result;
}
Inner::Inner(
QWidget *parent,
Dictionaries enabledDictionaries) : RpWidget(parent) {
setupContent(std::move(enabledDictionaries));
}
QueryCallback Inner::queryCallback() const {
return _queryCallback;
}
Dictionaries Inner::enabledRows() const {
return _enabledRows;
}
@ -128,11 +154,19 @@ Dictionaries Inner::enabledRows() const {
auto AddButtonWithLoader(
not_null<Ui::VerticalLayout*> content,
const Spellchecker::Dict &dict,
bool buttonEnabled) {
bool buttonEnabled,
rpl::producer<QStringView> query) {
const auto id = dict.id;
buttonEnabled &= DictExists(id);
const auto button = content->add(
const auto locale = Spellchecker::LocaleFromLangId(id);
const std::vector<QString> indexList = {
dict.name,
QLocale::languageToString(locale.language()),
QLocale::countryToString(locale.country())
};
const auto wrap = content->add(
object_ptr<Ui::SlideWrap<Ui::SettingsButton>>(
content,
object_ptr<Ui::SettingsButton>(
@ -141,8 +175,18 @@ auto AddButtonWithLoader(
st::dictionariesSectionButton
)
)
)->entity();
);
const auto button = wrap->entity();
std::move(
query
) | rpl::start_with_next([=](auto string) {
wrap->toggle(
ranges::any_of(indexList, [&](const QString &s) {
return s.startsWith(string, Qt::CaseInsensitive);
}),
anim::type::instant);
}, button->lifetime());
const auto localLoader = button->lifetime()
.make_state<base::unique_qptr<Loader>>();
@ -283,12 +327,16 @@ auto AddButtonWithLoader(
void Inner::setupContent(Dictionaries enabledDictionaries) {
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
const auto queryStream = content->lifetime()
.make_state<rpl::event_stream<QStringView>>();
for (const auto &dict : Spellchecker::Dictionaries()) {
const auto id = dict.id;
const auto row = AddButtonWithLoader(
content,
dict,
ranges::contains(enabledDictionaries, id));
ranges::contains(enabledDictionaries, id),
queryStream->events());
row->toggledValue(
) | rpl::start_with_next([=](auto enabled) {
if (enabled) {
@ -300,6 +348,13 @@ void Inner::setupContent(Dictionaries enabledDictionaries) {
}, row->lifetime());
}
_queryCallback = [=](const QString &query) {
if (query.size() >= kMaxQueryLength) {
return;
}
queryStream->fire_copy(query);
};
content->resizeToWidth(st::boxWidth);
Ui::ResizeFitChild(this, content);
}
@ -312,10 +367,25 @@ ManageDictionariesBox::ManageDictionariesBox(
: _session(session) {
}
void ManageDictionariesBox::setInnerFocus() {
_setInnerFocus();
}
void ManageDictionariesBox::prepare() {
const auto inner = setInnerWidget(object_ptr<Inner>(
this,
_session->settings().dictionariesEnabled()));
const auto multiSelect = CreateMultiSelect(this);
const auto inner = setInnerWidget(
object_ptr<Inner>(
this,
_session->settings().dictionariesEnabled()),
st::boxScroll,
multiSelect->height()
);
multiSelect->setQueryChangedCallback(inner->queryCallback());
_setInnerFocus = [=] {
multiSelect->setInnerFocus();
};
// The initial list of enabled rows may differ from the list of languages
// in settings, so we should store it when box opens
@ -342,10 +412,16 @@ void ManageDictionariesBox::prepare() {
setDimensionsToContent(st::boxWidth, inner);
inner->heightValue(
using namespace rpl::mappers;
const auto max = lifetime().make_state<int>(0);
rpl::combine(
inner->heightValue(),
multiSelect->heightValue(),
_1 + _2
) | rpl::start_with_next([=](int height) {
using std::min;
setDimensions(st::boxWidth, min(height, st::boxMaxListHeight));
accumulate_max(*max, height);
setDimensions(st::boxWidth, min(*max, st::boxMaxListHeight), true);
}, inner->lifetime());
}

View File

@ -25,9 +25,11 @@ public:
protected:
void prepare() override;
void setInnerFocus() override;
private:
const not_null<Main::Session*> _session;
Fn<void()> _setInnerFocus;
};