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