mirror of https://github.com/procxx/kepka.git
Add UI to specify export time range.
This commit is contained in:
parent
0f535a98a7
commit
f362702856
|
@ -1744,6 +1744,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_export_option_location" = "Download path: {path}";
|
"lng_export_option_location" = "Download path: {path}";
|
||||||
"lng_export_option_html" = "Human-readable HTML";
|
"lng_export_option_html" = "Human-readable HTML";
|
||||||
"lng_export_option_json" = "Machine-readable JSON";
|
"lng_export_option_json" = "Machine-readable JSON";
|
||||||
|
"lng_export_limits" = "From: {from}, Till: {till}";
|
||||||
|
"lng_export_beginning" = "Beginning";
|
||||||
|
"lng_export_end" = "End";
|
||||||
|
"lng_export_from_beginning" = "From Beginning";
|
||||||
|
"lng_export_till_end" = "Till End";
|
||||||
"lng_export_start" = "Export";
|
"lng_export_start" = "Export";
|
||||||
"lng_export_state_initializing" = "Initializing...";
|
"lng_export_state_initializing" = "Initializing...";
|
||||||
"lng_export_state_userpics" = "Profile pictures";
|
"lng_export_state_userpics" = "Profile pictures";
|
||||||
|
|
|
@ -440,13 +440,19 @@ void CalendarBox::Title::paintEvent(QPaintEvent *e) {
|
||||||
p.drawTextLeft((width() - _textWidth) / 2, (height() - st::calendarTitleFont->height) / 2, width(), _text, _textWidth);
|
p.drawTextLeft((width() - _textWidth) / 2, (height() - st::calendarTitleFont->height) / 2, width(), _text, _textWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
CalendarBox::CalendarBox(QWidget*, QDate month, QDate highlighted, Fn<void(QDate date)> callback)
|
CalendarBox::CalendarBox(
|
||||||
|
QWidget*,
|
||||||
|
QDate month,
|
||||||
|
QDate highlighted,
|
||||||
|
Fn<void(QDate date)> callback,
|
||||||
|
FnMut<void(not_null<CalendarBox*>)> finalize)
|
||||||
: _context(std::make_unique<Context>(month, highlighted))
|
: _context(std::make_unique<Context>(month, highlighted))
|
||||||
, _inner(this, _context.get())
|
, _inner(this, _context.get())
|
||||||
, _title(this, _context.get())
|
, _title(this, _context.get())
|
||||||
, _previous(this, st::calendarPrevious)
|
, _previous(this, st::calendarPrevious)
|
||||||
, _next(this, st::calendarNext)
|
, _next(this, st::calendarNext)
|
||||||
, _callback(std::move(callback)) {
|
, _callback(std::move(callback))
|
||||||
|
, _finalize(std::move(finalize)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalendarBox::setMinDate(QDate date) {
|
void CalendarBox::setMinDate(QDate date) {
|
||||||
|
@ -477,6 +483,10 @@ void CalendarBox::prepare() {
|
||||||
subscribe(_context->month(), [this](QDate month) { monthChanged(month); });
|
subscribe(_context->month(), [this](QDate month) { monthChanged(month); });
|
||||||
|
|
||||||
_context->start();
|
_context->start();
|
||||||
|
|
||||||
|
if (_finalize) {
|
||||||
|
_finalize(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CalendarBox::isPreviousEnabled() const {
|
bool CalendarBox::isPreviousEnabled() const {
|
||||||
|
|
|
@ -15,7 +15,12 @@ class IconButton;
|
||||||
|
|
||||||
class CalendarBox : public BoxContent {
|
class CalendarBox : public BoxContent {
|
||||||
public:
|
public:
|
||||||
CalendarBox(QWidget*, QDate month, QDate highlighted, Fn<void(QDate date)> callback);
|
CalendarBox(
|
||||||
|
QWidget*,
|
||||||
|
QDate month,
|
||||||
|
QDate highlighted,
|
||||||
|
Fn<void(QDate date)> callback,
|
||||||
|
FnMut<void(not_null<CalendarBox*>)> finalize = nullptr);
|
||||||
|
|
||||||
void setMinDate(QDate date);
|
void setMinDate(QDate date);
|
||||||
void setMaxDate(QDate date);
|
void setMaxDate(QDate date);
|
||||||
|
@ -45,5 +50,6 @@ private:
|
||||||
object_ptr<Ui::IconButton> _next;
|
object_ptr<Ui::IconButton> _next;
|
||||||
|
|
||||||
Fn<void(QDate date)> _callback;
|
Fn<void(QDate date)> _callback;
|
||||||
|
FnMut<void(not_null<CalendarBox*>)> _finalize;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -41,6 +41,8 @@ bool Settings::validate() const {
|
||||||
return false;
|
return false;
|
||||||
} else if (!media.validate()) {
|
} else if (!media.validate()) {
|
||||||
return false;
|
return false;
|
||||||
|
} else if (singlePeerTill > 0 && singlePeerTill <= singlePeerFrom) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -78,6 +78,8 @@ struct Settings {
|
||||||
MediaSettings media;
|
MediaSettings media;
|
||||||
|
|
||||||
MTPInputPeer singlePeer = MTP_inputPeerEmpty();
|
MTPInputPeer singlePeer = MTP_inputPeerEmpty();
|
||||||
|
TimeId singlePeerFrom = 0;
|
||||||
|
TimeId singlePeerTill = 0;
|
||||||
|
|
||||||
TimeId availableAt = 0;
|
TimeId availableAt = 0;
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ exportLocationLabel: FlatLabel(boxLabel) {
|
||||||
maxHeight: 21px;
|
maxHeight: 21px;
|
||||||
}
|
}
|
||||||
exportLocationPadding: margins(22px, 8px, 22px, 8px);
|
exportLocationPadding: margins(22px, 8px, 22px, 8px);
|
||||||
|
exportLimitsPadding: margins(22px, 0px, 22px, 0px);
|
||||||
|
|
||||||
exportAboutOptionLabel: FlatLabel(defaultFlatLabel) {
|
exportAboutOptionLabel: FlatLabel(defaultFlatLabel) {
|
||||||
textFg: windowSubTextFg;
|
textFg: windowSubTextFg;
|
||||||
|
|
|
@ -158,6 +158,12 @@ void PanelController::showSettings() {
|
||||||
auto settings = base::make_unique_q<SettingsWidget>(
|
auto settings = base::make_unique_q<SettingsWidget>(
|
||||||
_panel,
|
_panel,
|
||||||
*_settings);
|
*_settings);
|
||||||
|
settings->setShowBoxCallback([=](object_ptr<BoxContent> box) {
|
||||||
|
_panel->showBox(
|
||||||
|
std::move(box),
|
||||||
|
LayerOption::KeepOther,
|
||||||
|
anim::type::normal);
|
||||||
|
});
|
||||||
|
|
||||||
settings->startClicks(
|
settings->startClicks(
|
||||||
) | rpl::start_with_next([=]() {
|
) | rpl::start_with_next([=]() {
|
||||||
|
|
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/wrap/fade_wrap.h"
|
#include "ui/wrap/fade_wrap.h"
|
||||||
#include "platform/platform_specific.h"
|
#include "platform/platform_specific.h"
|
||||||
#include "core/file_utilities.h"
|
#include "core/file_utilities.h"
|
||||||
|
#include "boxes/calendar_box.h"
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
#include "styles/style_export.h"
|
#include "styles/style_export.h"
|
||||||
|
@ -210,6 +211,7 @@ void SettingsWidget::setupPathAndFormat(
|
||||||
not_null<Ui::VerticalLayout*> container) {
|
not_null<Ui::VerticalLayout*> container) {
|
||||||
if (_singlePeerId != 0) {
|
if (_singlePeerId != 0) {
|
||||||
addLocationLabel(container);
|
addLocationLabel(container);
|
||||||
|
addLimitsLabel(container);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto formatGroup = std::make_shared<Ui::RadioenumGroup<Format>>(
|
const auto formatGroup = std::make_shared<Ui::RadioenumGroup<Format>>(
|
||||||
|
@ -271,6 +273,126 @@ void SettingsWidget::addLocationLabel(
|
||||||
#endif // OS_MAC_STORE
|
#endif // OS_MAC_STORE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsWidget::addLimitsLabel(
|
||||||
|
not_null<Ui::VerticalLayout*> container) {
|
||||||
|
auto pathLabel = value() | rpl::map([](const Settings &data) {
|
||||||
|
return std::make_tuple(data.singlePeerFrom, data.singlePeerTill);
|
||||||
|
}) | rpl::distinct_until_changed(
|
||||||
|
) | rpl::map([](TimeId from, TimeId till) {
|
||||||
|
const auto begin = from
|
||||||
|
? langDayOfMonthFull(ParseDateTime(from).date())
|
||||||
|
: lang(lng_export_beginning);
|
||||||
|
const auto end = till
|
||||||
|
? langDayOfMonthFull(ParseDateTime(till).date())
|
||||||
|
: lang(lng_export_end);
|
||||||
|
auto fromLink = TextWithEntities{ begin };
|
||||||
|
fromLink.entities.push_back(EntityInText(
|
||||||
|
EntityInTextCustomUrl,
|
||||||
|
0,
|
||||||
|
begin.size(),
|
||||||
|
QString("internal:edit_from")));
|
||||||
|
auto tillLink = TextWithEntities{ end };
|
||||||
|
tillLink.entities.push_back(EntityInText(
|
||||||
|
EntityInTextCustomUrl,
|
||||||
|
0,
|
||||||
|
end.size(),
|
||||||
|
QString("internal:edit_till")));
|
||||||
|
return lng_export_limits__generic<TextWithEntities>(
|
||||||
|
lt_from,
|
||||||
|
fromLink,
|
||||||
|
lt_till,
|
||||||
|
tillLink);
|
||||||
|
}) | rpl::after_next([=] {
|
||||||
|
container->resizeToWidth(container->width());
|
||||||
|
});
|
||||||
|
const auto label = container->add(
|
||||||
|
object_ptr<Ui::FlatLabel>(
|
||||||
|
container,
|
||||||
|
std::move(pathLabel),
|
||||||
|
st::exportLocationLabel),
|
||||||
|
st::exportLimitsPadding);
|
||||||
|
label->setClickHandlerFilter([=](
|
||||||
|
const ClickHandlerPtr &handler,
|
||||||
|
Qt::MouseButton) {
|
||||||
|
const auto url = handler->dragText();
|
||||||
|
if (url == qstr("internal:edit_from")) {
|
||||||
|
const auto done = [=](TimeId limit) {
|
||||||
|
changeData([&](Settings &settings) {
|
||||||
|
settings.singlePeerFrom = limit;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
editDateLimit(
|
||||||
|
readData().singlePeerFrom,
|
||||||
|
0,
|
||||||
|
readData().singlePeerTill,
|
||||||
|
lng_export_from_beginning,
|
||||||
|
done);
|
||||||
|
} else if (url == qstr("internal:edit_till")) {
|
||||||
|
const auto done = [=](TimeId limit) {
|
||||||
|
changeData([&](Settings &settings) {
|
||||||
|
settings.singlePeerTill = limit;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
editDateLimit(
|
||||||
|
readData().singlePeerTill,
|
||||||
|
readData().singlePeerFrom,
|
||||||
|
0,
|
||||||
|
lng_export_till_end,
|
||||||
|
done);
|
||||||
|
} else {
|
||||||
|
Unexpected("Click handler URL in export limits edit.");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsWidget::editDateLimit(
|
||||||
|
TimeId current,
|
||||||
|
TimeId min,
|
||||||
|
TimeId max,
|
||||||
|
LangKey resetLabel,
|
||||||
|
Fn<void(TimeId)> done) {
|
||||||
|
Expects(_showBoxCallback != nullptr);
|
||||||
|
|
||||||
|
const auto highlighted = current
|
||||||
|
? ParseDateTime(current).date()
|
||||||
|
: max
|
||||||
|
? ParseDateTime(max).date()
|
||||||
|
: min
|
||||||
|
? ParseDateTime(min).date()
|
||||||
|
: QDate::currentDate();
|
||||||
|
const auto month = highlighted;
|
||||||
|
const auto shared = std::make_shared<QPointer<CalendarBox>>();
|
||||||
|
const auto finalize = [=](not_null<CalendarBox*> box) {
|
||||||
|
box->setMaxDate(max
|
||||||
|
? ParseDateTime(max).date()
|
||||||
|
: QDate::currentDate());
|
||||||
|
box->setMinDate(min
|
||||||
|
? ParseDateTime(min).date()
|
||||||
|
: QDate(2013, 8, 1)); // Telegram was launched in August 2013 :)
|
||||||
|
box->addLeftButton(langFactory(resetLabel), crl::guard(this, [=] {
|
||||||
|
done(0);
|
||||||
|
if (const auto weak = shared->data()) {
|
||||||
|
weak->closeBox();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
const auto callback = crl::guard(this, [=](const QDate &date) {
|
||||||
|
done(ServerTimeFromParsed(QDateTime(date)));
|
||||||
|
if (const auto weak = shared->data()) {
|
||||||
|
weak->closeBox();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
auto box = Box<CalendarBox>(
|
||||||
|
month,
|
||||||
|
highlighted,
|
||||||
|
callback,
|
||||||
|
finalize);
|
||||||
|
*shared = make_weak(box.data());
|
||||||
|
_showBoxCallback(std::move(box));
|
||||||
|
}
|
||||||
|
|
||||||
not_null<Ui::RpWidget*> SettingsWidget::setupButtons(
|
not_null<Ui::RpWidget*> SettingsWidget::setupButtons(
|
||||||
not_null<Ui::ScrollArea*> scroll,
|
not_null<Ui::ScrollArea*> scroll,
|
||||||
not_null<Ui::RpWidget*> wrap) {
|
not_null<Ui::RpWidget*> wrap) {
|
||||||
|
|
|
@ -30,6 +30,10 @@ public:
|
||||||
rpl::producer<> startClicks() const;
|
rpl::producer<> startClicks() const;
|
||||||
rpl::producer<> cancelClicks() const;
|
rpl::producer<> cancelClicks() const;
|
||||||
|
|
||||||
|
void setShowBoxCallback(Fn<void(object_ptr<BoxContent>)> callback) {
|
||||||
|
_showBoxCallback = std::move(callback);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using Type = Settings::Type;
|
using Type = Settings::Type;
|
||||||
using Types = Settings::Types;
|
using Types = Settings::Types;
|
||||||
|
@ -70,16 +74,26 @@ private:
|
||||||
void addSizeSlider(not_null<Ui::VerticalLayout*> container);
|
void addSizeSlider(not_null<Ui::VerticalLayout*> container);
|
||||||
void addLocationLabel(
|
void addLocationLabel(
|
||||||
not_null<Ui::VerticalLayout*> container);
|
not_null<Ui::VerticalLayout*> container);
|
||||||
|
void addLimitsLabel(
|
||||||
|
not_null<Ui::VerticalLayout*> container);
|
||||||
void chooseFolder();
|
void chooseFolder();
|
||||||
void refreshButtons(
|
void refreshButtons(
|
||||||
not_null<Ui::RpWidget*> container,
|
not_null<Ui::RpWidget*> container,
|
||||||
bool canStart);
|
bool canStart);
|
||||||
|
|
||||||
|
void editDateLimit(
|
||||||
|
TimeId current,
|
||||||
|
TimeId min,
|
||||||
|
TimeId max,
|
||||||
|
LangKey resetLabel,
|
||||||
|
Fn<void(TimeId)> done);
|
||||||
|
|
||||||
const Settings &readData() const;
|
const Settings &readData() const;
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
void changeData(Callback &&callback);
|
void changeData(Callback &&callback);
|
||||||
|
|
||||||
PeerId _singlePeerId = 0;
|
PeerId _singlePeerId = 0;
|
||||||
|
Fn<void(object_ptr<BoxContent>)> _showBoxCallback;
|
||||||
|
|
||||||
// Use through readData / changeData wrappers.
|
// Use through readData / changeData wrappers.
|
||||||
Settings _internal_data;
|
Settings _internal_data;
|
||||||
|
|
|
@ -30,7 +30,8 @@ public:
|
||||||
[method = std::move(method), consumer](auto &&value) {
|
[method = std::move(method), consumer](auto &&value) {
|
||||||
auto copy = method;
|
auto copy = method;
|
||||||
consumer.put_next_copy(value);
|
consumer.put_next_copy(value);
|
||||||
std::move(copy)(
|
details::callable_invoke(
|
||||||
|
std::move(copy),
|
||||||
std::forward<decltype(value)>(value));
|
std::forward<decltype(value)>(value));
|
||||||
}, [consumer](auto &&error) {
|
}, [consumer](auto &&error) {
|
||||||
consumer.put_error_forward(
|
consumer.put_error_forward(
|
||||||
|
|
|
@ -4345,6 +4345,8 @@ void WriteExportSettings(const Export::Settings &settings) {
|
||||||
}, [&](const MTPDinputPeerEmpty &) {
|
}, [&](const MTPDinputPeerEmpty &) {
|
||||||
data.stream << kSinglePeerTypeEmpty;
|
data.stream << kSinglePeerTypeEmpty;
|
||||||
});
|
});
|
||||||
|
data.stream << qint32(settings.singlePeerFrom);
|
||||||
|
data.stream << qint32(settings.singlePeerTill);
|
||||||
|
|
||||||
FileWriteDescriptor file(_exportSettingsKey);
|
FileWriteDescriptor file(_exportSettingsKey);
|
||||||
file.writeEncrypted(data);
|
file.writeEncrypted(data);
|
||||||
|
@ -4366,6 +4368,7 @@ Export::Settings ReadExportSettings() {
|
||||||
QString path;
|
QString path;
|
||||||
qint32 singlePeerType = 0, singlePeerBareId = 0;
|
qint32 singlePeerType = 0, singlePeerBareId = 0;
|
||||||
quint64 singlePeerAccessHash = 0;
|
quint64 singlePeerAccessHash = 0;
|
||||||
|
qint32 singlePeerFrom = 0, singlePeerTill = 0;
|
||||||
file.stream
|
file.stream
|
||||||
>> types
|
>> types
|
||||||
>> fullChats
|
>> fullChats
|
||||||
|
@ -4387,6 +4390,9 @@ Export::Settings ReadExportSettings() {
|
||||||
default: return Export::Settings();
|
default: return Export::Settings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!file.stream.atEnd()) {
|
||||||
|
file.stream >> singlePeerFrom >> singlePeerTill;
|
||||||
|
}
|
||||||
auto result = Export::Settings();
|
auto result = Export::Settings();
|
||||||
result.types = Export::Settings::Types::from_raw(types);
|
result.types = Export::Settings::Types::from_raw(types);
|
||||||
result.fullChats = Export::Settings::Types::from_raw(fullChats);
|
result.fullChats = Export::Settings::Types::from_raw(fullChats);
|
||||||
|
@ -4414,6 +4420,8 @@ Export::Settings ReadExportSettings() {
|
||||||
}
|
}
|
||||||
Unexpected("Type in export data single peer.");
|
Unexpected("Type in export data single peer.");
|
||||||
}();
|
}();
|
||||||
|
result.singlePeerFrom = singlePeerFrom;
|
||||||
|
result.singlePeerTill = singlePeerTill;
|
||||||
return (file.stream.status() == QDataStream::Ok && result.validate())
|
return (file.stream.status() == QDataStream::Ok && result.validate())
|
||||||
? result
|
? result
|
||||||
: Export::Settings();
|
: Export::Settings();
|
||||||
|
|
Loading…
Reference in New Issue