mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-19 06:26:55 +00:00
Apply, delete and restore proxies in the box.
This commit is contained in:
parent
8bbea976ea
commit
a7c77682d7
@ -19,12 +19,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
QPointer<Ui::RoundButton> BoxContent::addButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback) {
|
||||
return addButton(std::move(textFactory), std::move(clickCallback), st::defaultBoxButton);
|
||||
QPointer<Ui::RoundButton> BoxContent::addButton(
|
||||
base::lambda<QString()> textFactory,
|
||||
base::lambda<void()> clickCallback) {
|
||||
return addButton(
|
||||
std::move(textFactory),
|
||||
std::move(clickCallback),
|
||||
st::defaultBoxButton);
|
||||
}
|
||||
|
||||
QPointer<Ui::RoundButton> BoxContent::addLeftButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback) {
|
||||
return getDelegate()->addLeftButton(std::move(textFactory), std::move(clickCallback), st::defaultBoxButton);
|
||||
QPointer<Ui::RoundButton> BoxContent::addLeftButton(
|
||||
base::lambda<QString()> textFactory,
|
||||
base::lambda<void()> clickCallback) {
|
||||
return getDelegate()->addLeftButton(
|
||||
std::move(textFactory),
|
||||
std::move(clickCallback),
|
||||
st::defaultBoxButton);
|
||||
}
|
||||
|
||||
void BoxContent::setInner(object_ptr<TWidget> inner) {
|
||||
@ -117,7 +127,7 @@ void BoxContent::updateShadowsVisibility() {
|
||||
(top > 0 || _innerTopSkip > 0),
|
||||
anim::type::normal);
|
||||
_bottomShadow->toggle(
|
||||
(top < _scroll->scrollTopMax()),
|
||||
(top < _scroll->scrollTopMax() || _innerBottomSkip > 0),
|
||||
anim::type::normal);
|
||||
}
|
||||
|
||||
@ -145,6 +155,16 @@ void BoxContent::setInnerTopSkip(int innerTopSkip, bool scrollBottomFixed) {
|
||||
}
|
||||
}
|
||||
|
||||
void BoxContent::setInnerBottomSkip(int innerBottomSkip) {
|
||||
if (_innerBottomSkip != innerBottomSkip) {
|
||||
auto delta = innerBottomSkip - _innerBottomSkip;
|
||||
_innerBottomSkip = innerBottomSkip;
|
||||
if (_scroll && width() > 0) {
|
||||
updateScrollAreaGeometry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BoxContent::setInnerVisible(bool scrollAreaVisible) {
|
||||
if (_scroll) {
|
||||
_scroll->setVisible(scrollAreaVisible);
|
||||
@ -169,13 +189,15 @@ void BoxContent::resizeEvent(QResizeEvent *e) {
|
||||
}
|
||||
|
||||
void BoxContent::updateScrollAreaGeometry() {
|
||||
auto newScrollHeight = height() - _innerTopSkip;
|
||||
auto newScrollHeight = height() - _innerTopSkip - _innerBottomSkip;
|
||||
auto changed = (_scroll->height() != newScrollHeight);
|
||||
_scroll->setGeometryToLeft(0, _innerTopSkip, width(), newScrollHeight);
|
||||
_topShadow->entity()->resize(width(), st::lineWidth);
|
||||
_topShadow->moveToLeft(0, _innerTopSkip);
|
||||
_bottomShadow->entity()->resize(width(), st::lineWidth);
|
||||
_bottomShadow->moveToLeft(0, height() - st::lineWidth);
|
||||
_bottomShadow->moveToLeft(
|
||||
0,
|
||||
height() - _innerBottomSkip - st::lineWidth);
|
||||
if (changed) {
|
||||
updateInnerVisibleTopBottom();
|
||||
|
||||
@ -184,7 +206,7 @@ void BoxContent::updateScrollAreaGeometry() {
|
||||
(top > 0 || _innerTopSkip > 0),
|
||||
anim::type::instant);
|
||||
_bottomShadow->toggle(
|
||||
(top < _scroll->scrollTopMax()),
|
||||
(top < _scroll->scrollTopMax() || _innerBottomSkip > 0),
|
||||
anim::type::instant);
|
||||
}
|
||||
}
|
||||
|
@ -130,19 +130,29 @@ protected:
|
||||
getDelegate()->setDimensions(newWidth, maxHeight);
|
||||
}
|
||||
void setInnerTopSkip(int topSkip, bool scrollBottomFixed = false);
|
||||
void setInnerBottomSkip(int bottomSkip);
|
||||
|
||||
template <typename Widget>
|
||||
QPointer<Widget> setInnerWidget(object_ptr<Widget> inner, const style::ScrollArea &st, int topSkip = 0) {
|
||||
QPointer<Widget> setInnerWidget(
|
||||
object_ptr<Widget> inner,
|
||||
const style::ScrollArea &st,
|
||||
int topSkip = 0,
|
||||
int bottomSkip = 0) {
|
||||
auto result = QPointer<Widget>(inner.data());
|
||||
setInnerTopSkip(topSkip);
|
||||
setInnerBottomSkip(bottomSkip);
|
||||
setInner(std::move(inner), st);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Widget>
|
||||
QPointer<Widget> setInnerWidget(object_ptr<Widget> inner, int topSkip = 0) {
|
||||
QPointer<Widget> setInnerWidget(
|
||||
object_ptr<Widget> inner,
|
||||
int topSkip = 0,
|
||||
int bottomSkip = 0) {
|
||||
auto result = QPointer<Widget>(inner.data());
|
||||
setInnerTopSkip(topSkip);
|
||||
setInnerBottomSkip(bottomSkip);
|
||||
setInner(std::move(inner));
|
||||
return result;
|
||||
}
|
||||
@ -183,6 +193,7 @@ private:
|
||||
bool _preparing = false;
|
||||
bool _noContentMargin = false;
|
||||
int _innerTopSkip = 0;
|
||||
int _innerBottomSkip = 0;
|
||||
object_ptr<Ui::ScrollArea> _scroll = { nullptr };
|
||||
object_ptr<Ui::FadeShadow> _topShadow = { nullptr };
|
||||
object_ptr<Ui::FadeShadow> _bottomShadow = { nullptr };
|
||||
|
@ -712,8 +712,10 @@ sendMediaFileThumbSkip: 10px;
|
||||
sendMediaFileNameTop: 7px;
|
||||
sendMediaFileStatusTop: 37px;
|
||||
|
||||
proxyUsePadding: margins(22px, 0px, 22px, 12px);
|
||||
proxyTryIPv6Padding: margins(22px, 12px, 22px, 0px);
|
||||
proxyRowPadding: margins(22px, 8px, 8px, 8px);
|
||||
proxyRowIconSkip: 16px;
|
||||
proxyRowIconSkip: 32px;
|
||||
proxyRowSkip: 2px;
|
||||
proxyRowRipple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: windowBgOver;
|
||||
|
@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
#include "ui/wrap/padding_wrap.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "ui/text_options.h"
|
||||
#include "history/history_location_manager.h"
|
||||
@ -29,6 +30,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto kSaveSettingsDelayedTimeout = TimeMs(1000);
|
||||
|
||||
class ProxyRow : public Ui::RippleButton {
|
||||
public:
|
||||
using View = ProxiesBoxController::ItemView;
|
||||
@ -72,12 +75,16 @@ protected:
|
||||
|
||||
private:
|
||||
void setupContent();
|
||||
void addNewProxy();
|
||||
void applyView(View &&view);
|
||||
void setupButtons(int id, not_null<ProxyRow*> button);
|
||||
|
||||
not_null<ProxiesBoxController*> _controller;
|
||||
object_ptr<Ui::VerticalLayout> _initialInner;
|
||||
QPointer<Ui::VerticalLayout> _inner;
|
||||
object_ptr<Ui::PaddingWrap<Ui::Checkbox>> _useProxy;
|
||||
object_ptr<Ui::PaddingWrap<Ui::Checkbox>> _tryIPv6;
|
||||
object_ptr<Ui::VerticalLayout> _initialWrap;
|
||||
QPointer<Ui::VerticalLayout> _wrap;
|
||||
|
||||
base::flat_map<int, QPointer<ProxyRow>> _rows;
|
||||
|
||||
};
|
||||
@ -145,6 +152,8 @@ void ProxyRow::updateFields(View &&view) {
|
||||
_edit->toggle(!_view.deleted, anim::type::instant);
|
||||
_restore->toggle(_view.deleted, anim::type::instant);
|
||||
|
||||
setPointerCursor(!_view.deleted);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
@ -171,7 +180,6 @@ int ProxyRow::resizeGetHeight(int newWidth) {
|
||||
right -= _edit->width();
|
||||
_skipRight = right;
|
||||
_skipLeft = st::proxyRowPadding.left()
|
||||
+ st::proxyRowSelectedIcon.width()
|
||||
+ st::proxyRowIconSkip;
|
||||
return result;
|
||||
}
|
||||
@ -240,7 +248,21 @@ ProxiesBox::ProxiesBox(
|
||||
QWidget*,
|
||||
not_null<ProxiesBoxController*> controller)
|
||||
: _controller(controller)
|
||||
, _initialInner(this) {
|
||||
, _useProxy(
|
||||
this,
|
||||
object_ptr<Ui::Checkbox>(
|
||||
this,
|
||||
lang(lng_proxy_use),
|
||||
Global::UseProxy()),
|
||||
st::proxyUsePadding)
|
||||
, _tryIPv6(
|
||||
this,
|
||||
object_ptr<Ui::Checkbox>(
|
||||
this,
|
||||
lang(lng_connection_try_ipv6),
|
||||
Global::TryIPv6()),
|
||||
st::proxyTryIPv6Padding)
|
||||
, _initialWrap(this) {
|
||||
_controller->views(
|
||||
) | rpl::start_with_next([=](View &&view) {
|
||||
applyView(std::move(view));
|
||||
@ -250,40 +272,73 @@ ProxiesBox::ProxiesBox(
|
||||
void ProxiesBox::prepare() {
|
||||
setTitle(langFactory(lng_proxy_settings));
|
||||
|
||||
addButton(langFactory(lng_proxy_add), [=] {
|
||||
Ui::show(_controller->addNewItemBox(), LayerOption::KeepOther);
|
||||
});
|
||||
addButton(langFactory(lng_close), [=] {
|
||||
closeBox();
|
||||
});
|
||||
addButton(langFactory(lng_proxy_add), [=] { addNewProxy(); });
|
||||
addButton(langFactory(lng_close), [=] { closeBox(); });
|
||||
|
||||
setupContent();
|
||||
}
|
||||
|
||||
void ProxiesBox::setupContent() {
|
||||
_inner = setInnerWidget(std::move(_initialInner));
|
||||
_useProxy->resizeToWidth(st::boxWideWidth);
|
||||
_useProxy->moveToLeft(0, 0);
|
||||
subscribe(_useProxy->entity()->checkedChanged, [=](bool checked) {
|
||||
if (!_controller->setProxyEnabled(checked)) {
|
||||
addNewProxy();
|
||||
}
|
||||
});
|
||||
subscribe(Global::RefConnectionTypeChanged(), [=] {
|
||||
_useProxy->entity()->setChecked(Global::UseProxy());
|
||||
});
|
||||
|
||||
_inner->resizeToWidth(st::boxWideWidth);
|
||||
_tryIPv6->resizeToWidth(st::boxWideWidth);
|
||||
|
||||
_inner->heightValue(
|
||||
) | rpl::map([](int height) {
|
||||
return std::min(height, st::boxMaxListHeight);
|
||||
const auto topSkip = _useProxy->heightNoMargins();
|
||||
const auto bottomSkip = _tryIPv6->heightNoMargins();
|
||||
const auto inner = setInnerWidget(
|
||||
object_ptr<Ui::VerticalLayout>(this),
|
||||
topSkip,
|
||||
bottomSkip);
|
||||
inner->add(object_ptr<Ui::FixedHeightWidget>(
|
||||
inner,
|
||||
st::proxyRowPadding.top()));
|
||||
_wrap = inner->add(std::move(_initialWrap));
|
||||
inner->add(object_ptr<Ui::FixedHeightWidget>(
|
||||
inner,
|
||||
st::proxyRowPadding.bottom()));
|
||||
|
||||
inner->resizeToWidth(st::boxWideWidth);
|
||||
|
||||
inner->heightValue(
|
||||
) | rpl::map([=](int height) {
|
||||
return std::min(
|
||||
topSkip + height + bottomSkip,
|
||||
st::boxMaxListHeight);
|
||||
}) | rpl::distinct_until_changed(
|
||||
) | rpl::start_with_next([=](int height) {
|
||||
setDimensions(st::boxWideWidth, height);
|
||||
}, lifetime());
|
||||
}, inner->lifetime());
|
||||
|
||||
heightValue(
|
||||
) | rpl::start_with_next([=](int height) {
|
||||
_tryIPv6->moveToLeft(0, height - _tryIPv6->heightNoMargins());
|
||||
}, _tryIPv6->lifetime());
|
||||
}
|
||||
|
||||
void ProxiesBox::addNewProxy() {
|
||||
Ui::show(_controller->addNewItemBox(), LayerOption::KeepOther);
|
||||
}
|
||||
|
||||
void ProxiesBox::applyView(View &&view) {
|
||||
const auto id = view.id;
|
||||
const auto i = _rows.find(id);
|
||||
if (i == _rows.end()) {
|
||||
const auto inner = _inner
|
||||
? _inner.data()
|
||||
: _initialInner.data();
|
||||
const auto [i, ok] = _rows.emplace(id, inner->add(
|
||||
const auto wrap = _wrap
|
||||
? _wrap.data()
|
||||
: _initialWrap.data();
|
||||
const auto [i, ok] = _rows.emplace(id, wrap->insert(
|
||||
0,
|
||||
object_ptr<ProxyRow>(
|
||||
inner,
|
||||
wrap,
|
||||
std::move(view))));
|
||||
setupButtons(id, i->second);
|
||||
} else {
|
||||
@ -306,6 +361,11 @@ void ProxiesBox::setupButtons(int id, not_null<ProxyRow*> button) {
|
||||
) | rpl::start_with_next([=] {
|
||||
Ui::show(_controller->editItemBox(id), LayerOption::KeepOther);
|
||||
}, button->lifetime());
|
||||
|
||||
button->clicks(
|
||||
) | rpl::start_with_next([=] {
|
||||
_controller->applyItem(id);
|
||||
}, button->lifetime());
|
||||
}
|
||||
|
||||
ProxyBox::ProxyBox(
|
||||
@ -346,7 +406,7 @@ void ConnectionBox::ShowApplyProxyConfirmation(
|
||||
*box = Ui::show(Box<ConfirmBox>(text, lang(lng_sure_enable), [=] {
|
||||
auto &proxies = Global::RefProxiesList();
|
||||
if (ranges::find(proxies, proxy) == end(proxies)) {
|
||||
proxies.insert(begin(proxies), proxy);
|
||||
proxies.push_back(proxy);
|
||||
}
|
||||
Global::SetSelectedProxy(proxy);
|
||||
Global::SetUseProxy(true);
|
||||
@ -662,7 +722,8 @@ void AutoDownloadBox::onSave() {
|
||||
closeBox();
|
||||
}
|
||||
|
||||
ProxiesBoxController::ProxiesBoxController() {
|
||||
ProxiesBoxController::ProxiesBoxController()
|
||||
: _saveTimer([] { Local::writeSettings(); }) {
|
||||
_list = ranges::view::all(
|
||||
Global::ProxiesList()
|
||||
) | ranges::view::transform([&](const ProxyData &proxy) {
|
||||
@ -679,7 +740,7 @@ object_ptr<BoxContent> ProxiesBoxController::CreateOwningBox() {
|
||||
|
||||
object_ptr<BoxContent> ProxiesBoxController::create() {
|
||||
auto result = Box<ProxiesBox>(this);
|
||||
for (const auto &item : _list) {
|
||||
for (const auto &item : base::reversed(_list)) {
|
||||
updateView(item);
|
||||
}
|
||||
return std::move(result);
|
||||
@ -694,6 +755,14 @@ auto ProxiesBoxController::findById(int id) -> std::vector<Item>::iterator {
|
||||
return result;
|
||||
}
|
||||
|
||||
auto ProxiesBoxController::findByProxy(const ProxyData &proxy)
|
||||
->std::vector<Item>::iterator {
|
||||
return ranges::find(
|
||||
_list,
|
||||
proxy,
|
||||
[](const Item &item) { return item.data; });
|
||||
}
|
||||
|
||||
void ProxiesBoxController::deleteItem(int id) {
|
||||
setDeleted(id, true);
|
||||
}
|
||||
@ -702,9 +771,68 @@ void ProxiesBoxController::restoreItem(int id) {
|
||||
setDeleted(id, false);
|
||||
}
|
||||
|
||||
void ProxiesBoxController::applyItem(int id) {
|
||||
auto item = findById(id);
|
||||
if (Global::UseProxy() && Global::SelectedProxy() == item->data) {
|
||||
return;
|
||||
} else if (item->deleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto j = findByProxy(Global::SelectedProxy());
|
||||
|
||||
Global::SetSelectedProxy(item->data);
|
||||
Global::SetUseProxy(true);
|
||||
applyChanges();
|
||||
|
||||
if (j != end(_list)) {
|
||||
updateView(*j);
|
||||
}
|
||||
updateView(*item);
|
||||
}
|
||||
|
||||
void ProxiesBoxController::setDeleted(int id, bool deleted) {
|
||||
auto item = findById(id);
|
||||
item->deleted = deleted;
|
||||
|
||||
if (deleted) {
|
||||
auto &proxies = Global::RefProxiesList();
|
||||
proxies.erase(ranges::remove(proxies, item->data), end(proxies));
|
||||
|
||||
if (item->data == Global::SelectedProxy()) {
|
||||
_lastSelectedProxy = base::take(Global::RefSelectedProxy());
|
||||
if (Global::UseProxy()) {
|
||||
_lastSelectedProxyUsed = true;
|
||||
Global::SetUseProxy(false);
|
||||
applyChanges();
|
||||
} else {
|
||||
_lastSelectedProxyUsed = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
auto &proxies = Global::RefProxiesList();
|
||||
if (ranges::find(proxies, item->data) == end(proxies)) {
|
||||
auto insertBefore = item + 1;
|
||||
while (insertBefore != end(_list) && insertBefore->deleted) {
|
||||
++insertBefore;
|
||||
}
|
||||
auto insertBeforeIt = (insertBefore == end(_list))
|
||||
? end(proxies)
|
||||
: ranges::find(proxies, insertBefore->data);
|
||||
proxies.insert(insertBeforeIt, item->data);
|
||||
}
|
||||
|
||||
if (!Global::SelectedProxy() && _lastSelectedProxy == item->data) {
|
||||
Assert(!Global::UseProxy());
|
||||
|
||||
Global::SetSelectedProxy(base::take(_lastSelectedProxy));
|
||||
if (base::take(_lastSelectedProxyUsed)) {
|
||||
Global::SetUseProxy(true);
|
||||
applyChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
saveDelayed();
|
||||
updateView(*item);
|
||||
}
|
||||
|
||||
@ -749,6 +877,34 @@ object_ptr<BoxContent> ProxiesBoxController::addNewItemBox() {
|
||||
});
|
||||
}
|
||||
|
||||
bool ProxiesBoxController::setProxyEnabled(bool enabled) {
|
||||
if (enabled) {
|
||||
if (Global::ProxiesList().empty()) {
|
||||
return false;
|
||||
} else if (!Global::SelectedProxy()) {
|
||||
Global::SetSelectedProxy(Global::ProxiesList().back());
|
||||
auto j = findByProxy(Global::SelectedProxy());
|
||||
if (j != end(_list)) {
|
||||
updateView(*j);
|
||||
}
|
||||
}
|
||||
}
|
||||
Global::SetUseProxy(enabled);
|
||||
applyChanges();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProxiesBoxController::applyChanges() {
|
||||
Sandbox::refreshGlobalProxy();
|
||||
Global::RefConnectionTypeChanged().notify();
|
||||
MTP::restart();
|
||||
saveDelayed();
|
||||
}
|
||||
|
||||
void ProxiesBoxController::saveDelayed() {
|
||||
_saveTimer.callOnce(kSaveSettingsDelayedTimeout);
|
||||
}
|
||||
|
||||
auto ProxiesBoxController::views() const -> rpl::producer<ItemView> {
|
||||
return _views.events();
|
||||
}
|
||||
@ -779,3 +935,12 @@ void ProxiesBoxController::updateView(const Item &item) {
|
||||
deleted,
|
||||
state });
|
||||
}
|
||||
|
||||
ProxiesBoxController::~ProxiesBoxController() {
|
||||
if (_saveTimer.isActive()) {
|
||||
App::CallDelayed(
|
||||
kSaveSettingsDelayedTimeout,
|
||||
QApplication::instance(),
|
||||
[] { Local::writeSettings(); });
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#pragma once
|
||||
|
||||
#include "boxes/abstract_box.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
namespace Ui {
|
||||
class InputField;
|
||||
@ -119,11 +120,15 @@ public:
|
||||
|
||||
void deleteItem(int id);
|
||||
void restoreItem(int id);
|
||||
void applyItem(int id);
|
||||
object_ptr<BoxContent> editItemBox(int id);
|
||||
object_ptr<BoxContent> addNewItemBox();
|
||||
bool setProxyEnabled(bool enabled);
|
||||
|
||||
rpl::producer<ItemView> views() const;
|
||||
|
||||
~ProxiesBoxController();
|
||||
|
||||
private:
|
||||
struct Item {
|
||||
int id = 0;
|
||||
@ -132,12 +137,19 @@ private:
|
||||
};
|
||||
|
||||
std::vector<Item>::iterator findById(int id);
|
||||
std::vector<Item>::iterator findByProxy(const ProxyData &proxy);
|
||||
void setDeleted(int id, bool deleted);
|
||||
void updateView(const Item &item);
|
||||
void applyChanges();
|
||||
void saveDelayed();
|
||||
|
||||
int _idCounter = 0;
|
||||
int _selected = -1;
|
||||
std::vector<Item> _list;
|
||||
rpl::event_stream<ItemView> _views;
|
||||
base::Timer _saveTimer;
|
||||
|
||||
ProxyData _lastSelectedProxy;
|
||||
bool _lastSelectedProxyUsed = false;
|
||||
|
||||
};
|
||||
|
@ -32,6 +32,7 @@ constexpr int kErrorAlreadyDefined = 805;
|
||||
constexpr int kErrorBadString = 806;
|
||||
constexpr int kErrorIconDuplicate = 807;
|
||||
constexpr int kErrorBadIconModifier = 808;
|
||||
constexpr int kErrorCyclicDependency = 809;
|
||||
|
||||
QString findInputFile(const Options &options) {
|
||||
for (const auto &dir : options.includePaths) {
|
||||
@ -148,14 +149,21 @@ Modifier GetModifier(const QString &name) {
|
||||
return modifiers.value(name);
|
||||
}
|
||||
|
||||
ParsedFile::ParsedFile(const Options &options)
|
||||
ParsedFile::ParsedFile(
|
||||
const Options &options,
|
||||
std::vector<QString> includeStack)
|
||||
: filePath_(findInputFile(options))
|
||||
, file_(filePath_)
|
||||
, options_(options) {
|
||||
, options_(options)
|
||||
, includeStack_(includeStack) {
|
||||
}
|
||||
|
||||
bool ParsedFile::read() {
|
||||
if (!file_.read()) {
|
||||
if (std::find(begin(includeStack_), end(includeStack_), filePath_)
|
||||
!= end(includeStack_)) {
|
||||
logError(kErrorCyclicDependency) << "include cycle detected.";
|
||||
return false;
|
||||
} else if (!file_.read()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -205,7 +213,11 @@ common::LogStream ParsedFile::logErrorTypeMismatch() {
|
||||
ParsedFile::ModulePtr ParsedFile::readIncluded() {
|
||||
if (auto usingFile = assertNextToken(BasicType::String)) {
|
||||
if (assertNextToken(BasicType::Semicolon)) {
|
||||
ParsedFile included(includedOptions(tokenValue(usingFile)));
|
||||
auto includeStack = includeStack_;
|
||||
includeStack.push_back(filePath_);
|
||||
ParsedFile included(
|
||||
includedOptions(tokenValue(usingFile)),
|
||||
includeStack);
|
||||
if (included.read()) {
|
||||
return included.getResult();
|
||||
} else {
|
||||
|
@ -24,7 +24,9 @@ Modifier GetModifier(const QString &name);
|
||||
// Parses an input file to the internal struct.
|
||||
class ParsedFile {
|
||||
public:
|
||||
explicit ParsedFile(const Options &options);
|
||||
explicit ParsedFile(
|
||||
const Options &options,
|
||||
std::vector<QString> includeStack = {});
|
||||
ParsedFile(const ParsedFile &other) = delete;
|
||||
ParsedFile &operator=(const ParsedFile &other) = delete;
|
||||
|
||||
@ -108,6 +110,8 @@ private:
|
||||
bool failed_ = false;
|
||||
ModulePtr module_;
|
||||
|
||||
std::vector<QString> includeStack_;
|
||||
|
||||
QMap<std::string, structure::Type> typeNames_ = {
|
||||
{ "int" , { structure::TypeTag::Int } },
|
||||
{ "double" , { structure::TypeTag::Double } },
|
||||
|
@ -1184,6 +1184,8 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
|
||||
Global::SetUseProxy(proxy ? true : false);
|
||||
if (proxy) {
|
||||
Global::SetProxiesList({ 1, proxy });
|
||||
} else {
|
||||
Global::SetProxiesList({});
|
||||
}
|
||||
Sandbox::refreshGlobalProxy();
|
||||
} break;
|
||||
@ -1221,16 +1223,20 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
|
||||
const auto proxy = readProxy();
|
||||
if (proxy) {
|
||||
list.push_back(proxy);
|
||||
} else if (index < -list.size()) {
|
||||
++index;
|
||||
} else if (index > list.size()) {
|
||||
--index;
|
||||
}
|
||||
}
|
||||
if (!_checkStreamStatus(stream)) {
|
||||
return false;
|
||||
}
|
||||
Global::SetProxiesList(list);
|
||||
Global::SetUseProxy(index >= 0 && index < count);
|
||||
Global::SetUseProxy(index > 0 && index <= list.size());
|
||||
index = std::abs(index);
|
||||
if (index >= 0 && index < count) {
|
||||
Global::SetSelectedProxy(list[index]);
|
||||
if (index > 0 && index <= list.size()) {
|
||||
Global::SetSelectedProxy(list[index - 1]);
|
||||
} else {
|
||||
Global::SetSelectedProxy(ProxyData());
|
||||
}
|
||||
@ -1239,12 +1245,17 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
|
||||
if (!_checkStreamStatus(stream)) {
|
||||
return false;
|
||||
}
|
||||
Global::SetProxiesList({ 1, proxy });
|
||||
if (connectionType == dbictTcpProxy
|
||||
|| connectionType == dbictHttpProxy) {
|
||||
if (proxy) {
|
||||
Global::SetProxiesList({ 1, proxy });
|
||||
Global::SetSelectedProxy(proxy);
|
||||
Global::SetUseProxy(true);
|
||||
if (connectionType == dbictTcpProxy
|
||||
|| connectionType == dbictHttpProxy) {
|
||||
Global::SetUseProxy(true);
|
||||
} else {
|
||||
Global::SetUseProxy(false);
|
||||
}
|
||||
} else {
|
||||
Global::SetProxiesList({});
|
||||
Global::SetSelectedProxy(ProxyData());
|
||||
Global::SetUseProxy(false);
|
||||
}
|
||||
@ -2438,8 +2449,8 @@ void writeSettings() {
|
||||
auto proxyIt = ranges::find(proxies, proxy);
|
||||
if (proxy.type != ProxyData::Type::None
|
||||
&& proxyIt == end(proxies)) {
|
||||
proxies.insert(begin(proxies), proxy);
|
||||
proxyIt = begin(proxies);
|
||||
proxies.push_back(proxy);
|
||||
proxyIt = end(proxies) - 1;
|
||||
}
|
||||
size += sizeof(quint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32);
|
||||
for (const auto &proxy : proxies) {
|
||||
@ -2472,7 +2483,7 @@ void writeSettings() {
|
||||
|
||||
data.stream << quint32(dbiConnectionType) << qint32(dbictProxiesList);
|
||||
data.stream << qint32(proxies.size());
|
||||
const auto index = qint32(proxyIt - begin(proxies));
|
||||
const auto index = qint32(proxyIt - begin(proxies)) + 1;
|
||||
data.stream << (Global::UseProxy() ? index : -index);
|
||||
for (const auto &proxy : proxies) {
|
||||
data.stream << qint32(kProxyTypeShift + int(proxy.type));
|
||||
|
@ -58,6 +58,7 @@ int PaddingWrap<RpWidget>::resizeGetHeight(int newWidth) {
|
||||
weak->resizeToWidth(newWidth
|
||||
- _padding.left()
|
||||
- _padding.right());
|
||||
SendPendingMoveResizeEvents(weak);
|
||||
} else {
|
||||
resize(QSize(
|
||||
_padding.left() + newWidth + _padding.right(),
|
||||
|
@ -92,12 +92,17 @@ void VerticalLayout::updateChildGeometry(
|
||||
width);
|
||||
}
|
||||
|
||||
RpWidget *VerticalLayout::addChild(
|
||||
RpWidget *VerticalLayout::insertChild(
|
||||
int atPosition,
|
||||
object_ptr<RpWidget> child,
|
||||
const style::margins &margin) {
|
||||
if (auto weak = AttachParentChild(this, child)) {
|
||||
_rows.push_back({ std::move(child), margin });
|
||||
auto margins = getMargins();
|
||||
Expects(atPosition >= 0 && atPosition <= _rows.size());
|
||||
|
||||
if (const auto weak = AttachParentChild(this, child)) {
|
||||
_rows.insert(
|
||||
begin(_rows) + atPosition,
|
||||
{ std::move(child), margin });
|
||||
const auto margins = getMargins();
|
||||
updateChildGeometry(
|
||||
margins,
|
||||
weak,
|
||||
@ -105,11 +110,11 @@ RpWidget *VerticalLayout::addChild(
|
||||
width() - margins.left() - margins.right(),
|
||||
height() - margins.top() - margins.bottom());
|
||||
weak->heightValue(
|
||||
) | rpl::start_with_next_done([this, weak] {
|
||||
) | rpl::start_with_next_done([=] {
|
||||
if (!_inResize) {
|
||||
childHeightUpdated(weak);
|
||||
}
|
||||
}, [this, weak] {
|
||||
}, [=] {
|
||||
removeChild(weak);
|
||||
}, lifetime());
|
||||
return weak;
|
||||
|
@ -15,6 +15,20 @@ class VerticalLayout : public RpWidget {
|
||||
public:
|
||||
using RpWidget::RpWidget;
|
||||
|
||||
template <
|
||||
typename Widget,
|
||||
typename = std::enable_if_t<
|
||||
std::is_base_of_v<RpWidget, Widget>>>
|
||||
Widget *insert(
|
||||
int atPosition,
|
||||
object_ptr<Widget> &&child,
|
||||
const style::margins &margin = style::margins()) {
|
||||
return static_cast<Widget*>(insertChild(
|
||||
atPosition,
|
||||
std::move(child),
|
||||
margin));
|
||||
}
|
||||
|
||||
template <
|
||||
typename Widget,
|
||||
typename = std::enable_if_t<
|
||||
@ -22,9 +36,7 @@ public:
|
||||
Widget *add(
|
||||
object_ptr<Widget> &&child,
|
||||
const style::margins &margin = style::margins()) {
|
||||
return static_cast<Widget*>(addChild(
|
||||
std::move(child),
|
||||
margin));
|
||||
return insert(_rows.size(), std::move(child), margin);
|
||||
}
|
||||
|
||||
QMargins getMargins() const override;
|
||||
@ -37,7 +49,8 @@ protected:
|
||||
int visibleBottom) override;
|
||||
|
||||
private:
|
||||
RpWidget *addChild(
|
||||
RpWidget *insertChild(
|
||||
int addPosition,
|
||||
object_ptr<RpWidget> child,
|
||||
const style::margins &margin);
|
||||
void childHeightUpdated(RpWidget *child);
|
||||
|
Loading…
Reference in New Issue
Block a user