tdesktop/Telegram/SourceFiles/settings/settings_main.cpp

302 lines
7.9 KiB
C++
Raw Normal View History

2018-09-05 19:05:49 +00:00
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "settings/settings_main.h"
#include "settings/settings_common.h"
2018-09-06 13:48:01 +00:00
#include "settings/settings_codes.h"
2018-09-05 19:05:49 +00:00
#include "boxes/abstract_box.h"
2018-09-05 21:01:50 +00:00
#include "boxes/language_box.h"
#include "boxes/confirm_box.h"
#include "boxes/about_box.h"
#include "boxes/photo_crop_box.h"
2018-09-05 19:05:49 +00:00
#include "ui/wrap/vertical_layout.h"
2018-09-05 21:01:50 +00:00
#include "ui/widgets/labels.h"
#include "ui/widgets/discrete_sliders.h"
2018-09-05 19:05:49 +00:00
#include "info/profile/info_profile_button.h"
2018-09-05 19:39:35 +00:00
#include "info/profile/info_profile_cover.h"
2018-09-05 19:05:49 +00:00
#include "lang/lang_keys.h"
2018-09-05 21:01:50 +00:00
#include "storage/localstorage.h"
#include "auth_session.h"
#include "apiwrap.h"
#include "core/file_utilities.h"
2018-09-05 19:05:49 +00:00
#include "styles/style_settings.h"
namespace Settings {
2018-09-05 21:01:50 +00:00
namespace {
void SetupUploadPhotoButton(
not_null<Ui::VerticalLayout*> container,
not_null<UserData*> self) {
AddDivider(container);
AddSkip(container);
const auto upload = [=] {
const auto imageExtensions = cImgExtensions();
const auto filter = qsl("Image files (*")
+ imageExtensions.join(qsl(" *"))
+ qsl(");;")
+ FileDialog::AllFilesFilter();
const auto callback = [=](const FileDialog::OpenResult &result) {
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
return;
}
const auto image = result.remoteContent.isEmpty()
? App::readImage(result.paths.front())
: App::readImage(result.remoteContent);
if (image.isNull()
|| image.width() > 10 * image.height()
|| image.height() > 10 * image.width()) {
Ui::show(Box<InformBox>(lang(lng_bad_photo)));
return;
}
auto box = Ui::show(Box<PhotoCropBox>(image, self));
box->ready(
) | rpl::start_with_next([=](QImage &&image) {
Auth().api().uploadPeerPhoto(self, std::move(image));
}, box->lifetime());
};
FileDialog::GetOpenPath(
container.get(),
lang(lng_choose_image),
filter,
crl::guard(container, callback));
};
2018-09-07 09:40:25 +00:00
AddButton(
container,
2018-09-07 09:40:25 +00:00
lng_settings_upload,
st::settingsSectionButton
)->addClickHandler(App::LambdaDelayed(
st::settingsSectionButton.ripple.hideDuration,
container,
upload));
AddSkip(container);
}
2018-09-05 21:01:50 +00:00
void SetupLanguageButton(not_null<Ui::VerticalLayout*> container) {
2018-09-07 09:40:25 +00:00
const auto button = AddButtonWithLabel(
2018-09-05 21:01:50 +00:00
container,
2018-09-07 09:40:25 +00:00
lng_settings_language,
Lang::Viewer(lng_language_name),
st::settingsSectionButton);
2018-09-05 21:01:50 +00:00
const auto guard = Ui::AttachAsChild(button, base::binary_guard());
button->addClickHandler([=] {
*guard = LanguageBox::Show();
});
}
void SetupSections(
not_null<Ui::VerticalLayout*> container,
Fn<void(Type)> showOther) {
AddDivider(container);
AddSkip(container);
const auto addSection = [&](LangKey label, Type type) {
2018-09-07 09:40:25 +00:00
AddButton(
container,
2018-09-07 09:40:25 +00:00
label,
st::settingsSectionButton
)->addClickHandler([=] { showOther(type); });
};
addSection(lng_settings_section_info, Type::Information);
addSection(lng_settings_section_notify, Type::Notifications);
addSection(lng_settings_section_privacy, Type::PrivacySecurity);
addSection(lng_settings_section_general, Type::General);
addSection(lng_settings_section_chat_settings, Type::Chat);
SetupLanguageButton(container);
AddSkip(container);
}
2018-09-05 21:01:50 +00:00
void SetupInterfaceScale(not_null<Ui::VerticalLayout*> container) {
if (cRetina()) {
return;
}
AddDivider(container);
AddSkip(container);
const auto toggled = Ui::AttachAsChild(
container,
rpl::event_stream<bool>());
const auto switched = (cConfigScale() == dbisAuto)
|| (cConfigScale() == cScreenScale());
2018-09-07 09:40:25 +00:00
const auto button = AddButton(
2018-09-05 21:01:50 +00:00
container,
2018-09-07 09:40:25 +00:00
lng_settings_default_scale,
st::settingsSectionButton
)->toggleOn(toggled->events_starting_with_copy(switched));
2018-09-05 21:01:50 +00:00
const auto slider = container->add(
object_ptr<Ui::SettingsSlider>(container, st::settingsSlider),
st::settingsScalePadding);
2018-09-05 21:01:50 +00:00
const auto inSetScale = Ui::AttachAsChild(container, false);
const auto setScale = std::make_shared<Fn<void(DBIScale)>>();
*setScale = [=](DBIScale scale) {
if (*inSetScale) return;
*inSetScale = true;
const auto guard = gsl::finally([=] { *inSetScale = false; });
if (scale == cScreenScale()) {
scale = dbisAuto;
}
toggled->fire(scale == dbisAuto);
const auto applying = scale;
if (scale == dbisAuto) {
scale = cScreenScale();
}
slider->setActiveSection(scale - 1);
if (cEvalScale(scale) != cEvalScale(cRealScale())) {
const auto confirmed = crl::guard(button, [=] {
cSetConfigScale(applying);
2018-09-05 21:01:50 +00:00
Local::writeSettings();
App::restart();
});
const auto cancelled = crl::guard(button, [=] {
App::CallDelayed(
st::defaultSettingsSlider.duration,
button,
[=] { (*setScale)(cRealScale()); });
});
Ui::show(Box<ConfirmBox>(
lang(lng_settings_need_restart),
lang(lng_settings_restart_now),
confirmed,
cancelled));
} else {
cSetConfigScale(scale);
Local::writeSettings();
}
};
button->toggledValue(
) | rpl::start_with_next([=](bool checked) {
auto scale = checked ? dbisAuto : cEvalScale(cConfigScale());
if (scale == cScreenScale()) {
if (scale != cScale()) {
scale = cScale();
} else {
switch (scale) {
case dbisOne: scale = dbisOneAndQuarter; break;
case dbisOneAndQuarter: scale = dbisOne; break;
case dbisOneAndHalf: scale = dbisOneAndQuarter; break;
case dbisTwo: scale = dbisOneAndHalf; break;
}
}
}
(*setScale)(scale);
}, button->lifetime());
const auto label = [](DBIScale scale) {
switch (scale) {
case dbisOne: return qsl("100%");
case dbisOneAndQuarter: return qsl("125%");
case dbisOneAndHalf: return qsl("150%");
case dbisTwo: return qsl("200%");
}
Unexpected("Value in scale label.");
};
const auto scaleByIndex = [](int index) {
switch (index) {
case 0: return dbisOne;
case 1: return dbisOneAndQuarter;
case 2: return dbisOneAndHalf;
case 3: return dbisTwo;
}
Unexpected("Index in scaleByIndex.");
};
slider->addSection(label(dbisOne));
slider->addSection(label(dbisOneAndQuarter));
slider->addSection(label(dbisOneAndHalf));
slider->addSection(label(dbisTwo));
slider->setActiveSectionFast(cEvalScale(cConfigScale()) - 1);
slider->sectionActivated(
) | rpl::start_with_next([=](int section) {
(*setScale)(scaleByIndex(section));
}, slider->lifetime());
AddSkip(container);
}
void SetupHelp(not_null<Ui::VerticalLayout*> container) {
AddDivider(container);
AddSkip(container);
2018-09-07 09:40:25 +00:00
AddButton(
container,
2018-09-07 09:40:25 +00:00
lng_settings_faq,
st::settingsSectionButton
)->addClickHandler([] {
QDesktopServices::openUrl(telegramFaqLink());
});
if (AuthSession::Exists()) {
2018-09-07 09:40:25 +00:00
const auto button = AddButton(
container,
2018-09-07 09:40:25 +00:00
lng_settings_ask_question,
st::settingsSectionButton);
button->addClickHandler([=] {
const auto ready = crl::guard(button, [](const MTPUser &data) {
const auto users = MTP_vector<MTPUser>(1, data);
if (const auto user = App::feedUsers(users)) {
Ui::showPeerHistory(user, ShowAtUnreadMsgId);
}
});
Auth().api().requestSupportContact(ready);
});
}
AddSkip(container);
}
2018-09-05 21:01:50 +00:00
} // namespace
2018-09-05 19:05:49 +00:00
2018-09-05 19:39:35 +00:00
Main::Main(
QWidget *parent,
not_null<Window::Controller*> controller,
not_null<UserData*> self)
2018-09-05 19:05:49 +00:00
: Section(parent)
, _self(self) {
2018-09-05 19:39:35 +00:00
setupContent(controller);
2018-09-05 19:05:49 +00:00
}
2018-09-06 13:48:01 +00:00
void Main::keyPressEvent(QKeyEvent *e) {
CodesFeedString(e->text());
return Section::keyPressEvent(e);
}
2018-09-05 19:39:35 +00:00
void Main::setupContent(not_null<Window::Controller*> controller) {
2018-09-05 19:05:49 +00:00
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
2018-09-05 19:39:35 +00:00
const auto cover = content->add(object_ptr<Info::Profile::Cover>(
content,
_self,
controller));
cover->setOnlineCount(rpl::single(0));
SetupUploadPhotoButton(content, _self);
SetupSections(content, [=](Type type) {
_showOther.fire_copy(type);
});
2018-09-05 21:01:50 +00:00
SetupInterfaceScale(content);
SetupHelp(content);
2018-09-05 21:01:50 +00:00
Ui::ResizeFitChild(this, content);
}
2018-09-05 19:05:49 +00:00
rpl::producer<Type> Main::sectionShowOther() {
return _showOther.events();
}
} // namespace Settings