mirror of https://github.com/procxx/kepka.git
Ask export path with other export options.
This commit is contained in:
parent
10a0c6a086
commit
ae18ece549
|
@ -1676,7 +1676,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_export_option_gifs" = "Animated GIFs";
|
"lng_export_option_gifs" = "Animated GIFs";
|
||||||
"lng_export_option_files" = "Files";
|
"lng_export_option_files" = "Files";
|
||||||
"lng_export_option_size_limit" = "Size limit: {size}";
|
"lng_export_option_size_limit" = "Size limit: {size}";
|
||||||
"lng_export_header_format" = "Format";
|
"lng_export_header_format" = "Location and format";
|
||||||
|
"lng_export_option_location" = "Download path: {path}";
|
||||||
"lng_export_option_text" = "Human-readable text";
|
"lng_export_option_text" = "Human-readable text";
|
||||||
"lng_export_option_json" = "Machine-readable JSON";
|
"lng_export_option_json" = "Machine-readable JSON";
|
||||||
"lng_export_start" = "Export";
|
"lng_export_start" = "Export";
|
||||||
|
|
|
@ -31,7 +31,7 @@ void AboutBox::prepare() {
|
||||||
|
|
||||||
addButton(langFactory(lng_close), [this] { closeBox(); });
|
addButton(langFactory(lng_close), [this] { closeBox(); });
|
||||||
|
|
||||||
const auto linkHook = [](const ClickHandlerPtr &link, auto button) {
|
const auto linkFilter = [](const ClickHandlerPtr &link, auto button) {
|
||||||
if (const auto url = dynamic_cast<UrlClickHandler*>(link.get())) {
|
if (const auto url = dynamic_cast<UrlClickHandler*>(link.get())) {
|
||||||
url->UrlClickHandler::onClick(button);
|
url->UrlClickHandler::onClick(button);
|
||||||
return false;
|
return false;
|
||||||
|
@ -40,9 +40,9 @@ void AboutBox::prepare() {
|
||||||
};
|
};
|
||||||
|
|
||||||
_text3->setRichText(lng_about_text_3(lt_faq_open, qsl("[a href=\"%1\"]").arg(telegramFaqLink()), lt_faq_close, qsl("[/a]")));
|
_text3->setRichText(lng_about_text_3(lt_faq_open, qsl("[a href=\"%1\"]").arg(telegramFaqLink()), lt_faq_close, qsl("[/a]")));
|
||||||
_text1->setClickHandlerHook(linkHook);
|
_text1->setClickHandlerFilter(linkFilter);
|
||||||
_text2->setClickHandlerHook(linkHook);
|
_text2->setClickHandlerFilter(linkFilter);
|
||||||
_text3->setClickHandlerHook(linkHook);
|
_text3->setClickHandlerFilter(linkFilter);
|
||||||
|
|
||||||
_version->setClickedCallback([this] { showVersionHistory(); });
|
_version->setClickedCallback([this] { showVersionHistory(); });
|
||||||
|
|
||||||
|
|
|
@ -710,7 +710,7 @@ object_ptr<Ui::RpWidget> Controller::createInviteLinkEdit() {
|
||||||
_controls.inviteLink->setSelectable(true);
|
_controls.inviteLink->setSelectable(true);
|
||||||
_controls.inviteLink->setContextCopyText(QString());
|
_controls.inviteLink->setContextCopyText(QString());
|
||||||
_controls.inviteLink->setBreakEverywhere(true);
|
_controls.inviteLink->setBreakEverywhere(true);
|
||||||
_controls.inviteLink->setClickHandlerHook([this](auto&&...) {
|
_controls.inviteLink->setClickHandlerFilter([=](auto&&...) {
|
||||||
Application::clipboard()->setText(inviteLinkText());
|
Application::clipboard()->setText(inviteLinkText());
|
||||||
Ui::Toast::Show(lang(lng_group_invite_copied));
|
Ui::Toast::Show(lang(lng_group_invite_copied));
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -37,6 +37,12 @@ exportFileSizeLabel: LabelSimple(defaultLabelSimple) {
|
||||||
}
|
}
|
||||||
exportFileSizePadding: margins(22px, 8px, 22px, 8px);
|
exportFileSizePadding: margins(22px, 8px, 22px, 8px);
|
||||||
exportFileSizeLabelBottom: 18px;
|
exportFileSizeLabelBottom: 18px;
|
||||||
|
|
||||||
|
exportLocationLabel: FlatLabel(boxLabel) {
|
||||||
|
maxHeight: 21px;
|
||||||
|
}
|
||||||
|
exportLocationPadding: margins(22px, 8px, 22px, 8px);
|
||||||
|
|
||||||
exportErrorLabel: FlatLabel(boxLabel) {
|
exportErrorLabel: FlatLabel(boxLabel) {
|
||||||
minWidth: 175px;
|
minWidth: 175px;
|
||||||
align: align(top);
|
align: align(top);
|
||||||
|
|
|
@ -59,21 +59,13 @@ int SizeLimitByIndex(int index) {
|
||||||
|
|
||||||
SettingsWidget::SettingsWidget(QWidget *parent)
|
SettingsWidget::SettingsWidget(QWidget *parent)
|
||||||
: RpWidget(parent) {
|
: RpWidget(parent) {
|
||||||
if (Global::DownloadPath().isEmpty()) {
|
_data.path = psDownloadPath();
|
||||||
_data.path = psDownloadPath();
|
|
||||||
} else if (Global::DownloadPath() == qsl("tmp")) {
|
|
||||||
_data.path = cTempDir();
|
|
||||||
} else {
|
|
||||||
_data.path = Global::DownloadPath();
|
|
||||||
}
|
|
||||||
_data.internalLinksDomain = Global::InternalLinksDomain();
|
_data.internalLinksDomain = Global::InternalLinksDomain();
|
||||||
|
|
||||||
setupContent();
|
setupContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsWidget::setupContent() {
|
void SettingsWidget::setupContent() {
|
||||||
using namespace rpl::mappers;
|
|
||||||
|
|
||||||
const auto scroll = Ui::CreateChild<Ui::ScrollArea>(
|
const auto scroll = Ui::CreateChild<Ui::ScrollArea>(
|
||||||
this,
|
this,
|
||||||
st::boxLayerScroll);
|
st::boxLayerScroll);
|
||||||
|
@ -82,6 +74,148 @@ void SettingsWidget::setupContent() {
|
||||||
object_ptr<Ui::VerticalLayout>(scroll)));
|
object_ptr<Ui::VerticalLayout>(scroll)));
|
||||||
const auto content = static_cast<Ui::VerticalLayout*>(wrap->entity());
|
const auto content = static_cast<Ui::VerticalLayout*>(wrap->entity());
|
||||||
|
|
||||||
|
const auto buttons = setupButtons(scroll, wrap);
|
||||||
|
setupOptions(content);
|
||||||
|
setupPathAndFormat(content);
|
||||||
|
|
||||||
|
_refreshButtons.fire({});
|
||||||
|
|
||||||
|
sizeValue(
|
||||||
|
) | rpl::start_with_next([=](QSize size) {
|
||||||
|
scroll->resize(size.width(), size.height() - buttons->height());
|
||||||
|
wrap->resizeToWidth(size.width());
|
||||||
|
content->resizeToWidth(size.width());
|
||||||
|
}, lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsWidget::setupOptions(not_null<Ui::VerticalLayout*> container) {
|
||||||
|
addOption(
|
||||||
|
container,
|
||||||
|
lng_export_option_info,
|
||||||
|
Type::PersonalInfo | Type::Userpics);
|
||||||
|
addOption(container, lng_export_option_contacts, Type::Contacts);
|
||||||
|
addOption(container, lng_export_option_sessions, Type::Sessions);
|
||||||
|
addHeader(container, lng_export_header_chats);
|
||||||
|
addOption(
|
||||||
|
container,
|
||||||
|
lng_export_option_personal_chats,
|
||||||
|
Type::PersonalChats);
|
||||||
|
addOption(container, lng_export_option_bot_chats, Type::BotChats);
|
||||||
|
addChatOption(
|
||||||
|
container,
|
||||||
|
lng_export_option_private_groups,
|
||||||
|
Type::PrivateGroups);
|
||||||
|
addChatOption(
|
||||||
|
container,
|
||||||
|
lng_export_option_private_channels,
|
||||||
|
Type::PrivateChannels);
|
||||||
|
addChatOption(
|
||||||
|
container,
|
||||||
|
lng_export_option_public_groups,
|
||||||
|
Type::PublicGroups);
|
||||||
|
addChatOption(
|
||||||
|
container,
|
||||||
|
lng_export_option_public_channels,
|
||||||
|
Type::PublicChannels);
|
||||||
|
|
||||||
|
setupMediaOptions(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsWidget::setupMediaOptions(
|
||||||
|
not_null<Ui::VerticalLayout*> container) {
|
||||||
|
const auto mediaWrap = container->add(
|
||||||
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
|
container,
|
||||||
|
object_ptr<Ui::VerticalLayout>(container)));
|
||||||
|
const auto media = mediaWrap->entity();
|
||||||
|
addHeader(media, lng_export_header_media);
|
||||||
|
addMediaOption(media, lng_export_option_photos, MediaType::Photo);
|
||||||
|
addMediaOption(media, lng_export_option_video_files, MediaType::Video);
|
||||||
|
addMediaOption(media, lng_export_option_voice_messages, MediaType::VoiceMessage);
|
||||||
|
addMediaOption(media, lng_export_option_video_messages, MediaType::VideoMessage);
|
||||||
|
addMediaOption(media, lng_export_option_stickers, MediaType::Sticker);
|
||||||
|
addMediaOption(media, lng_export_option_gifs, MediaType::GIF);
|
||||||
|
addMediaOption(media, lng_export_option_files, MediaType::File);
|
||||||
|
addSizeSlider(media);
|
||||||
|
|
||||||
|
_dataTypesChanges.events_starting_with_copy(
|
||||||
|
_data.types
|
||||||
|
) | rpl::start_with_next([=](Settings::Types types) {
|
||||||
|
mediaWrap->toggle((types & (Type::PersonalChats
|
||||||
|
| Type::BotChats
|
||||||
|
| Type::PrivateGroups
|
||||||
|
| Type::PrivateChannels
|
||||||
|
| Type::PublicGroups
|
||||||
|
| Type::PublicChannels)) != 0, anim::type::normal);
|
||||||
|
}, mediaWrap->lifetime());
|
||||||
|
|
||||||
|
widthValue(
|
||||||
|
) | rpl::start_with_next([=](int width) {
|
||||||
|
mediaWrap->resizeToWidth(width);
|
||||||
|
}, mediaWrap->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsWidget::setupPathAndFormat(
|
||||||
|
not_null<Ui::VerticalLayout*> container) {
|
||||||
|
const auto formatGroup = std::make_shared<Ui::RadioenumGroup<Format>>(
|
||||||
|
_data.format);
|
||||||
|
formatGroup->setChangedCallback([=](Format format) {
|
||||||
|
_data.format = format;
|
||||||
|
});
|
||||||
|
const auto addFormatOption = [&](LangKey key, Format format) {
|
||||||
|
const auto radio = container->add(
|
||||||
|
object_ptr<Ui::Radioenum<Format>>(
|
||||||
|
container,
|
||||||
|
formatGroup,
|
||||||
|
format,
|
||||||
|
lang(key),
|
||||||
|
st::defaultBoxCheckbox),
|
||||||
|
st::exportSettingPadding);
|
||||||
|
};
|
||||||
|
addHeader(container, lng_export_header_format);
|
||||||
|
addLocationLabel(container);
|
||||||
|
addFormatOption(lng_export_option_text, Format::Text);
|
||||||
|
addFormatOption(lng_export_option_json, Format::Json);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsWidget::addLocationLabel(
|
||||||
|
not_null<Ui::VerticalLayout*> container) {
|
||||||
|
auto pathLabel = _locationChanges.events_starting_with_copy(
|
||||||
|
_data.path
|
||||||
|
) | rpl::map([](const QString &path) {
|
||||||
|
const auto text = (path == psDownloadPath())
|
||||||
|
? QString("Downloads/Telegram Desktop")
|
||||||
|
: path;
|
||||||
|
auto pathLink = TextWithEntities{
|
||||||
|
QDir::toNativeSeparators(text),
|
||||||
|
EntitiesInText()
|
||||||
|
};
|
||||||
|
pathLink.entities.push_back(EntityInText(
|
||||||
|
EntityInTextCustomUrl,
|
||||||
|
0,
|
||||||
|
text.size(),
|
||||||
|
"internal:edit_export_path"));
|
||||||
|
return lng_export_option_location__generic<TextWithEntities>(
|
||||||
|
lt_path,
|
||||||
|
pathLink);
|
||||||
|
});
|
||||||
|
const auto label = container->add(
|
||||||
|
object_ptr<Ui::FlatLabel>(
|
||||||
|
container,
|
||||||
|
std::move(pathLabel),
|
||||||
|
st::exportLocationLabel),
|
||||||
|
st::exportLocationPadding);
|
||||||
|
label->setClickHandlerFilter([=](auto&&...) {
|
||||||
|
chooseFolder();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
not_null<Ui::RpWidget*> SettingsWidget::setupButtons(
|
||||||
|
not_null<Ui::ScrollArea*> scroll,
|
||||||
|
not_null<Ui::RpWidget*> wrap) {
|
||||||
|
using namespace rpl::mappers;
|
||||||
|
|
||||||
const auto buttonsPadding = st::boxButtonPadding;
|
const auto buttonsPadding = st::boxButtonPadding;
|
||||||
const auto buttonsHeight = buttonsPadding.top()
|
const auto buttonsHeight = buttonsPadding.top()
|
||||||
+ st::defaultBoxButton.height
|
+ st::defaultBoxButton.height
|
||||||
|
@ -101,170 +235,125 @@ void SettingsWidget::setupContent() {
|
||||||
) | rpl::map([=](int top) {
|
) | rpl::map([=](int top) {
|
||||||
return top < scroll->scrollTopMax();
|
return top < scroll->scrollTopMax();
|
||||||
}));
|
}));
|
||||||
const auto refreshButtonsCallback = [=] {
|
|
||||||
|
_refreshButtons.events(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
refreshButtons(buttons);
|
refreshButtons(buttons);
|
||||||
};
|
topShadow->raise();
|
||||||
const auto addHeader = [&](
|
bottomShadow->raise();
|
||||||
not_null<Ui::VerticalLayout*> container,
|
}, buttons->lifetime());
|
||||||
LangKey key) {
|
|
||||||
container->add(
|
|
||||||
object_ptr<Ui::FlatLabel>(
|
|
||||||
container,
|
|
||||||
lang(key),
|
|
||||||
Ui::FlatLabel::InitType::Simple,
|
|
||||||
st::exportHeaderLabel),
|
|
||||||
st::exportHeaderPadding);
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto addOption = [&](LangKey key, Types types) {
|
|
||||||
const auto checkbox = content->add(
|
|
||||||
object_ptr<Ui::Checkbox>(
|
|
||||||
content,
|
|
||||||
lang(key),
|
|
||||||
((_data.types & types) == types),
|
|
||||||
st::defaultBoxCheckbox),
|
|
||||||
st::exportSettingPadding);
|
|
||||||
base::ObservableViewer(
|
|
||||||
checkbox->checkedChanged
|
|
||||||
) | rpl::start_with_next([=](bool checked) {
|
|
||||||
if (checked) {
|
|
||||||
_data.types |= types;
|
|
||||||
} else {
|
|
||||||
_data.types &= ~types;
|
|
||||||
}
|
|
||||||
_dataTypesChanges.fire_copy(_data.types);
|
|
||||||
refreshButtonsCallback();
|
|
||||||
}, lifetime());
|
|
||||||
return checkbox;
|
|
||||||
};
|
|
||||||
const auto addBigOption = [&](LangKey key, Types types) {
|
|
||||||
const auto checkbox = addOption(key, types);
|
|
||||||
const auto onlyMy = content->add(
|
|
||||||
object_ptr<Ui::SlideWrap<Ui::Checkbox>>(
|
|
||||||
content,
|
|
||||||
object_ptr<Ui::Checkbox>(
|
|
||||||
content,
|
|
||||||
lang(lng_export_option_only_my),
|
|
||||||
((_data.fullChats & types) != types),
|
|
||||||
st::defaultBoxCheckbox),
|
|
||||||
st::exportSubSettingPadding));
|
|
||||||
|
|
||||||
base::ObservableViewer(
|
|
||||||
onlyMy->entity()->checkedChanged
|
|
||||||
) | rpl::start_with_next([=](bool checked) {
|
|
||||||
if (checked) {
|
|
||||||
_data.fullChats &= ~types;
|
|
||||||
} else {
|
|
||||||
_data.fullChats |= types;
|
|
||||||
}
|
|
||||||
}, checkbox->lifetime());
|
|
||||||
|
|
||||||
onlyMy->toggleOn(base::ObservableViewer(
|
|
||||||
checkbox->checkedChanged
|
|
||||||
));
|
|
||||||
|
|
||||||
onlyMy->toggle(checkbox->checked(), anim::type::instant);
|
|
||||||
|
|
||||||
if (types & (Type::PublicGroups | Type::PublicChannels)) {
|
|
||||||
onlyMy->entity()->setChecked(true);
|
|
||||||
onlyMy->entity()->setDisabled(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
addOption(lng_export_option_info, Type::PersonalInfo | Type::Userpics);
|
|
||||||
addOption(lng_export_option_contacts, Type::Contacts);
|
|
||||||
addOption(lng_export_option_sessions, Type::Sessions);
|
|
||||||
addHeader(content, lng_export_header_chats);
|
|
||||||
addOption(lng_export_option_personal_chats, Type::PersonalChats);
|
|
||||||
addOption(lng_export_option_bot_chats, Type::BotChats);
|
|
||||||
addBigOption(lng_export_option_private_groups, Type::PrivateGroups);
|
|
||||||
addBigOption(lng_export_option_private_channels, Type::PrivateChannels);
|
|
||||||
addBigOption(lng_export_option_public_groups, Type::PublicGroups);
|
|
||||||
addBigOption(lng_export_option_public_channels, Type::PublicChannels);
|
|
||||||
const auto mediaWrap = content->add(
|
|
||||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
|
||||||
content,
|
|
||||||
object_ptr<Ui::VerticalLayout>(content)));
|
|
||||||
const auto media = mediaWrap->entity();
|
|
||||||
const auto addSubOption = [&](LangKey key, MediaType type) {
|
|
||||||
const auto checkbox = media->add(
|
|
||||||
object_ptr<Ui::Checkbox>(
|
|
||||||
media,
|
|
||||||
lang(key),
|
|
||||||
((_data.media.types & type) == type),
|
|
||||||
st::defaultBoxCheckbox),
|
|
||||||
st::exportSettingPadding);
|
|
||||||
base::ObservableViewer(
|
|
||||||
checkbox->checkedChanged
|
|
||||||
) | rpl::start_with_next([=](bool checked) {
|
|
||||||
if (checked) {
|
|
||||||
_data.media.types |= type;
|
|
||||||
} else {
|
|
||||||
_data.media.types &= ~type;
|
|
||||||
}
|
|
||||||
refreshButtonsCallback();
|
|
||||||
}, lifetime());
|
|
||||||
};
|
|
||||||
addHeader(media, lng_export_header_media);
|
|
||||||
addSubOption(lng_export_option_photos, MediaType::Photo);
|
|
||||||
addSubOption(lng_export_option_video_files, MediaType::Video);
|
|
||||||
addSubOption(lng_export_option_voice_messages, MediaType::VoiceMessage);
|
|
||||||
addSubOption(lng_export_option_video_messages, MediaType::VideoMessage);
|
|
||||||
addSubOption(lng_export_option_stickers, MediaType::Sticker);
|
|
||||||
addSubOption(lng_export_option_gifs, MediaType::GIF);
|
|
||||||
addSubOption(lng_export_option_files, MediaType::File);
|
|
||||||
createSizeSlider(media);
|
|
||||||
|
|
||||||
const auto formatGroup = std::make_shared<Ui::RadioenumGroup<Format>>(
|
|
||||||
_data.format);
|
|
||||||
formatGroup->setChangedCallback([=](Format format) {
|
|
||||||
_data.format = format;
|
|
||||||
});
|
|
||||||
const auto addFormatOption = [&](LangKey key, Format format) {
|
|
||||||
const auto radio = content->add(
|
|
||||||
object_ptr<Ui::Radioenum<Format>>(
|
|
||||||
content,
|
|
||||||
formatGroup,
|
|
||||||
format,
|
|
||||||
lang(key),
|
|
||||||
st::defaultBoxCheckbox),
|
|
||||||
st::exportSettingPadding);
|
|
||||||
};
|
|
||||||
addHeader(content, lng_export_header_format);
|
|
||||||
addFormatOption(lng_export_option_text, Format::Text);
|
|
||||||
addFormatOption(lng_export_option_json, Format::Json);
|
|
||||||
|
|
||||||
_dataTypesChanges.events_starting_with_copy(
|
|
||||||
_data.types
|
|
||||||
) | rpl::start_with_next([=](Settings::Types types) {
|
|
||||||
mediaWrap->toggle((types & (Type::PersonalChats
|
|
||||||
| Type::BotChats
|
|
||||||
| Type::PrivateGroups
|
|
||||||
| Type::PrivateChannels
|
|
||||||
| Type::PublicGroups
|
|
||||||
| Type::PublicChannels)) != 0, anim::type::normal);
|
|
||||||
}, mediaWrap->lifetime());
|
|
||||||
|
|
||||||
refreshButtonsCallback();
|
|
||||||
|
|
||||||
topShadow->raise();
|
|
||||||
bottomShadow->raise();
|
|
||||||
|
|
||||||
sizeValue(
|
sizeValue(
|
||||||
) | rpl::start_with_next([=](QSize size) {
|
) | rpl::start_with_next([=](QSize size) {
|
||||||
scroll->resize(size.width(), size.height() - buttons->height());
|
|
||||||
wrap->resizeToWidth(size.width());
|
|
||||||
content->resizeToWidth(size.width());
|
|
||||||
buttons->resizeToWidth(size.width());
|
buttons->resizeToWidth(size.width());
|
||||||
|
buttons->moveToLeft(0, size.height() - buttons->height());
|
||||||
topShadow->resizeToWidth(size.width());
|
topShadow->resizeToWidth(size.width());
|
||||||
mediaWrap->resizeToWidth(size.width());
|
|
||||||
topShadow->moveToLeft(0, 0);
|
topShadow->moveToLeft(0, 0);
|
||||||
bottomShadow->resizeToWidth(size.width());
|
bottomShadow->resizeToWidth(size.width());
|
||||||
bottomShadow->moveToLeft(0, scroll->height() - st::lineWidth);
|
bottomShadow->moveToLeft(0, buttons->y() - st::lineWidth);
|
||||||
buttons->moveToLeft(0, size.height() - buttons->height());
|
}, buttons->lifetime());
|
||||||
|
|
||||||
|
return buttons;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsWidget::addHeader(
|
||||||
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
LangKey key) {
|
||||||
|
container->add(
|
||||||
|
object_ptr<Ui::FlatLabel>(
|
||||||
|
container,
|
||||||
|
lang(key),
|
||||||
|
Ui::FlatLabel::InitType::Simple,
|
||||||
|
st::exportHeaderLabel),
|
||||||
|
st::exportHeaderPadding);
|
||||||
|
}
|
||||||
|
|
||||||
|
not_null<Ui::Checkbox*> SettingsWidget::addOption(
|
||||||
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
LangKey key,
|
||||||
|
Types types) {
|
||||||
|
const auto checkbox = container->add(
|
||||||
|
object_ptr<Ui::Checkbox>(
|
||||||
|
container,
|
||||||
|
lang(key),
|
||||||
|
((_data.types & types) == types),
|
||||||
|
st::defaultBoxCheckbox),
|
||||||
|
st::exportSettingPadding);
|
||||||
|
base::ObservableViewer(
|
||||||
|
checkbox->checkedChanged
|
||||||
|
) | rpl::start_with_next([=](bool checked) {
|
||||||
|
if (checked) {
|
||||||
|
_data.types |= types;
|
||||||
|
} else {
|
||||||
|
_data.types &= ~types;
|
||||||
|
}
|
||||||
|
_dataTypesChanges.fire_copy(_data.types);
|
||||||
|
_refreshButtons.fire({});
|
||||||
|
}, lifetime());
|
||||||
|
return checkbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsWidget::addChatOption(
|
||||||
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
LangKey key,
|
||||||
|
Types types) {
|
||||||
|
const auto checkbox = addOption(container, key, types);
|
||||||
|
const auto onlyMy = container->add(
|
||||||
|
object_ptr<Ui::SlideWrap<Ui::Checkbox>>(
|
||||||
|
container,
|
||||||
|
object_ptr<Ui::Checkbox>(
|
||||||
|
container,
|
||||||
|
lang(lng_export_option_only_my),
|
||||||
|
((_data.fullChats & types) != types),
|
||||||
|
st::defaultBoxCheckbox),
|
||||||
|
st::exportSubSettingPadding));
|
||||||
|
|
||||||
|
base::ObservableViewer(
|
||||||
|
onlyMy->entity()->checkedChanged
|
||||||
|
) | rpl::start_with_next([=](bool checked) {
|
||||||
|
if (checked) {
|
||||||
|
_data.fullChats &= ~types;
|
||||||
|
} else {
|
||||||
|
_data.fullChats |= types;
|
||||||
|
}
|
||||||
|
}, checkbox->lifetime());
|
||||||
|
|
||||||
|
onlyMy->toggleOn(base::ObservableViewer(
|
||||||
|
checkbox->checkedChanged
|
||||||
|
));
|
||||||
|
|
||||||
|
onlyMy->toggle(checkbox->checked(), anim::type::instant);
|
||||||
|
|
||||||
|
if (types & (Type::PublicGroups | Type::PublicChannels)) {
|
||||||
|
onlyMy->entity()->setChecked(true);
|
||||||
|
onlyMy->entity()->setDisabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsWidget::addMediaOption(
|
||||||
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
LangKey key,
|
||||||
|
MediaType type) {
|
||||||
|
const auto checkbox = container->add(
|
||||||
|
object_ptr<Ui::Checkbox>(
|
||||||
|
container,
|
||||||
|
lang(key),
|
||||||
|
((_data.media.types & type) == type),
|
||||||
|
st::defaultBoxCheckbox),
|
||||||
|
st::exportSettingPadding);
|
||||||
|
base::ObservableViewer(
|
||||||
|
checkbox->checkedChanged
|
||||||
|
) | rpl::start_with_next([=](bool checked) {
|
||||||
|
if (checked) {
|
||||||
|
_data.media.types |= type;
|
||||||
|
} else {
|
||||||
|
_data.media.types &= ~type;
|
||||||
|
}
|
||||||
|
_refreshButtons.fire({});
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsWidget::createSizeSlider(
|
void SettingsWidget::addSizeSlider(
|
||||||
not_null<Ui::VerticalLayout*> container) {
|
not_null<Ui::VerticalLayout*> container) {
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
|
|
||||||
|
@ -273,7 +362,6 @@ void SettingsWidget::createSizeSlider(
|
||||||
st::exportFileSizePadding);
|
st::exportFileSizePadding);
|
||||||
slider->resize(st::exportFileSizeSlider.seekSize);
|
slider->resize(st::exportFileSizeSlider.seekSize);
|
||||||
slider->setAlwaysDisplayMarker(true);
|
slider->setAlwaysDisplayMarker(true);
|
||||||
slider->setMoveByWheel(true);
|
|
||||||
slider->setDirection(Ui::ContinuousSlider::Direction::Horizontal);
|
slider->setDirection(Ui::ContinuousSlider::Direction::Horizontal);
|
||||||
for (auto i = 0; i != kSizeValueCount + 1; ++i) {
|
for (auto i = 0; i != kSizeValueCount + 1; ++i) {
|
||||||
if (_data.media.sizeLimit <= SizeLimitByIndex(i)) {
|
if (_data.media.sizeLimit <= SizeLimitByIndex(i)) {
|
||||||
|
@ -332,7 +420,9 @@ void SettingsWidget::refreshButtons(not_null<Ui::RpWidget*> container) {
|
||||||
: nullptr;
|
: nullptr;
|
||||||
if (start) {
|
if (start) {
|
||||||
start->show();
|
start->show();
|
||||||
start->addClickHandler([=] { chooseFolder(); });
|
start->addClickHandler([=] {
|
||||||
|
_startClicks.fire(base::duplicate(_data));
|
||||||
|
});
|
||||||
|
|
||||||
container->sizeValue(
|
container->sizeValue(
|
||||||
) | rpl::start_with_next([=](QSize size) {
|
) | rpl::start_with_next([=](QSize size) {
|
||||||
|
@ -363,7 +453,7 @@ void SettingsWidget::refreshButtons(not_null<Ui::RpWidget*> container) {
|
||||||
void SettingsWidget::chooseFolder() {
|
void SettingsWidget::chooseFolder() {
|
||||||
const auto ready = [=](QString &&result) {
|
const auto ready = [=](QString &&result) {
|
||||||
_data.path = result;
|
_data.path = result;
|
||||||
_startClicks.fire(base::duplicate(_data));
|
_locationChanges.fire(std::move(result));
|
||||||
};
|
};
|
||||||
FileDialog::GetFolder(this, lang(lng_export_folder), _data.path, ready);
|
FileDialog::GetFolder(this, lang(lng_export_folder), _data.path, ready);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "export/export_settings.h"
|
#include "export/export_settings.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
|
|
||||||
|
enum LangKey : int;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class VerticalLayout;
|
class VerticalLayout;
|
||||||
|
class Checkbox;
|
||||||
|
class ScrollArea;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Export {
|
namespace Export {
|
||||||
|
@ -32,9 +36,32 @@ private:
|
||||||
using Format = Output::Format;
|
using Format = Output::Format;
|
||||||
|
|
||||||
void setupContent();
|
void setupContent();
|
||||||
|
not_null<Ui::RpWidget*> setupButtons(
|
||||||
|
not_null<Ui::ScrollArea*> scroll,
|
||||||
|
not_null<Ui::RpWidget*> wrap);
|
||||||
|
void setupOptions(not_null<Ui::VerticalLayout*> container);
|
||||||
|
void setupMediaOptions(not_null<Ui::VerticalLayout*> container);
|
||||||
|
void setupPathAndFormat(not_null<Ui::VerticalLayout*> container);
|
||||||
|
void addHeader(
|
||||||
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
LangKey key);
|
||||||
|
not_null<Ui::Checkbox*> addOption(
|
||||||
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
LangKey key,
|
||||||
|
Types types);
|
||||||
|
void addChatOption(
|
||||||
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
LangKey key,
|
||||||
|
Types types);
|
||||||
|
void addMediaOption(
|
||||||
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
LangKey key,
|
||||||
|
MediaType type);
|
||||||
|
void addSizeSlider(not_null<Ui::VerticalLayout*> container);
|
||||||
|
void addLocationLabel(
|
||||||
|
not_null<Ui::VerticalLayout*> container);
|
||||||
void chooseFolder();
|
void chooseFolder();
|
||||||
void refreshButtons(not_null<Ui::RpWidget*> container);
|
void refreshButtons(not_null<Ui::RpWidget*> container);
|
||||||
void createSizeSlider(not_null<Ui::VerticalLayout*> container);
|
|
||||||
|
|
||||||
Settings _data;
|
Settings _data;
|
||||||
struct Wrap {
|
struct Wrap {
|
||||||
|
@ -43,11 +70,12 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<> value;
|
rpl::producer<> value;
|
||||||
|
|
||||||
};
|
};
|
||||||
rpl::event_stream<Settings> _startClicks;
|
rpl::event_stream<Settings> _startClicks;
|
||||||
rpl::variable<Wrap> _cancelClicks;
|
rpl::variable<Wrap> _cancelClicks;
|
||||||
rpl::event_stream<Settings::Types> _dataTypesChanges;
|
rpl::event_stream<Settings::Types> _dataTypesChanges;
|
||||||
|
rpl::event_stream<> _refreshButtons;
|
||||||
|
rpl::event_stream<QString> _locationChanges;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,7 @@ object_ptr<Ui::RpWidget> DetailsFiller::setupInfo() {
|
||||||
lng_info_link_label,
|
lng_info_link_label,
|
||||||
std::move(linkText),
|
std::move(linkText),
|
||||||
QString());
|
QString());
|
||||||
link->setClickHandlerHook([peer = _peer](auto&&...) {
|
link->setClickHandlerFilter([peer = _peer](auto&&...) {
|
||||||
auto link = Messenger::Instance().createInternalLinkFull(
|
auto link = Messenger::Instance().createInternalLinkFull(
|
||||||
peer->userName());
|
peer->userName());
|
||||||
if (!link.isEmpty()) {
|
if (!link.isEmpty()) {
|
||||||
|
|
|
@ -331,7 +331,7 @@ void GroupMembersWidget::refreshLimitReached() {
|
||||||
QString link = TextUtilities::EscapeForRichParsing(lang(lng_profile_migrate_learn_more));
|
QString link = TextUtilities::EscapeForRichParsing(lang(lng_profile_migrate_learn_more));
|
||||||
QString text = qsl("%1%2%3\n%4 [a href=\"https://telegram.org/blog/supergroups5k\"]%5[/a]").arg(textcmdStartSemibold()).arg(title).arg(textcmdStopSemibold()).arg(body).arg(link);
|
QString text = qsl("%1%2%3\n%4 [a href=\"https://telegram.org/blog/supergroups5k\"]%5[/a]").arg(textcmdStartSemibold()).arg(title).arg(textcmdStopSemibold()).arg(body).arg(link);
|
||||||
_limitReachedInfo->setRichText(text);
|
_limitReachedInfo->setRichText(text);
|
||||||
_limitReachedInfo->setClickHandlerHook([this](const ClickHandlerPtr &handler, Qt::MouseButton button) {
|
_limitReachedInfo->setClickHandlerFilter([=](auto&&...) {
|
||||||
Ui::show(Box<ConvertToSupergroupBox>(peer()->asChat()));
|
Ui::show(Box<ConvertToSupergroupBox>(peer()->asChat()));
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
|
@ -88,7 +88,7 @@ void InfoWidget::refreshUsername() {
|
||||||
TextWithEntities(),
|
TextWithEntities(),
|
||||||
copyText);
|
copyText);
|
||||||
if (auto text = _username->entity()->textLabel()) {
|
if (auto text = _username->entity()->textLabel()) {
|
||||||
text->setClickHandlerHook([](const ClickHandlerPtr &handler, Qt::MouseButton button) {
|
text->setClickHandlerFilter([](auto&&...) {
|
||||||
Ui::show(Box<UsernameBox>());
|
Ui::show(Box<UsernameBox>());
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
@ -115,7 +115,7 @@ void InfoWidget::refreshBio() {
|
||||||
TextWithEntities(),
|
TextWithEntities(),
|
||||||
QString());
|
QString());
|
||||||
if (auto text = _bio->entity()->textLabel()) {
|
if (auto text = _bio->entity()->textLabel()) {
|
||||||
text->setClickHandlerHook([](const ClickHandlerPtr &handler, Qt::MouseButton button) {
|
text->setClickHandlerFilter([](auto&&...) {
|
||||||
Ui::show(Box<EditBioBox>(App::self()));
|
Ui::show(Box<EditBioBox>(App::self()));
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
|
@ -272,8 +272,8 @@ void FlatLabel::setLink(uint16 lnkIndex, const ClickHandlerPtr &lnk) {
|
||||||
_text.setLink(lnkIndex, lnk);
|
_text.setLink(lnkIndex, lnk);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatLabel::setClickHandlerHook(ClickHandlerHook &&hook) {
|
void FlatLabel::setClickHandlerFilter(ClickHandlerFilter &&filter) {
|
||||||
_clickHandlerHook = std::move(hook);
|
_clickHandlerFilter = std::move(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatLabel::mouseMoveEvent(QMouseEvent *e) {
|
void FlatLabel::mouseMoveEvent(QMouseEvent *e) {
|
||||||
|
@ -358,7 +358,8 @@ Text::StateResult FlatLabel::dragActionFinish(const QPoint &p, Qt::MouseButton b
|
||||||
_selectionType = TextSelectType::Letters;
|
_selectionType = TextSelectType::Letters;
|
||||||
|
|
||||||
if (activated) {
|
if (activated) {
|
||||||
if (!_clickHandlerHook || _clickHandlerHook(activated, button)) {
|
if (!_clickHandlerFilter
|
||||||
|
|| _clickHandlerFilter(activated, button)) {
|
||||||
App::activateClickHandler(activated, button);
|
App::activateClickHandler(activated, button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,8 +112,8 @@ public:
|
||||||
|
|
||||||
void setLink(uint16 lnkIndex, const ClickHandlerPtr &lnk);
|
void setLink(uint16 lnkIndex, const ClickHandlerPtr &lnk);
|
||||||
|
|
||||||
using ClickHandlerHook = Fn<bool(const ClickHandlerPtr&, Qt::MouseButton)>;
|
using ClickHandlerFilter = Fn<bool(const ClickHandlerPtr&, Qt::MouseButton)>;
|
||||||
void setClickHandlerHook(ClickHandlerHook &&hook);
|
void setClickHandlerFilter(ClickHandlerFilter &&filter);
|
||||||
|
|
||||||
// ClickHandlerHost interface
|
// ClickHandlerHost interface
|
||||||
void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
|
void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
|
||||||
|
@ -207,7 +207,7 @@ private:
|
||||||
QString _contextCopyText;
|
QString _contextCopyText;
|
||||||
ExpandLinksMode _contextExpandLinksMode = ExpandLinksAll;
|
ExpandLinksMode _contextExpandLinksMode = ExpandLinksAll;
|
||||||
|
|
||||||
ClickHandlerHook _clickHandlerHook;
|
ClickHandlerFilter _clickHandlerFilter;
|
||||||
|
|
||||||
// text selection and context menu by touch support (at least Windows Surface tablets)
|
// text selection and context menu by touch support (at least Windows Surface tablets)
|
||||||
bool _touchSelect = false;
|
bool _touchSelect = false;
|
||||||
|
|
|
@ -243,7 +243,7 @@ void TermsBox::prepare() {
|
||||||
st::termsPadding),
|
st::termsPadding),
|
||||||
0,
|
0,
|
||||||
age ? age->height() : 0);
|
age ? age->height() : 0);
|
||||||
content->entity()->setClickHandlerHook([=](
|
content->entity()->setClickHandlerFilter([=](
|
||||||
const ClickHandlerPtr &handler,
|
const ClickHandlerPtr &handler,
|
||||||
Qt::MouseButton button) {
|
Qt::MouseButton button) {
|
||||||
const auto link = handler
|
const auto link = handler
|
||||||
|
|
Loading…
Reference in New Issue