LeechCraft 0.6.70-17335-ge406ffdcaf
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
statesaver.cpp
Go to the documentation of this file.
1/**********************************************************************
2 * LeechCraft - modular cross-platform feature rich internet client.
3 * Copyright (C) 2006-2014 Georg Rudoy
4 *
5 * Distributed under the Boost Software License, Version 1.0.
6 * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7 **********************************************************************/
8
9#include "statesaver.h"
10#include <numeric>
11#include <QHeaderView>
12#include <QSplitter>
14#include <util/sll/throttle.h>
15#include <util/sll/visitor.h>
16#include <xmlsettingsdialog/basesettingsmanager.h>
17
18namespace LC::Util
19{
20 namespace
21 {
22 QList<int> RedistributeWidths (int totalWidth, const Widths& widths)
23 {
24 const int occupiedWidth = std::accumulate (widths.begin (), widths.end (), 0,
25 [] (auto acc, auto elem) { return acc + elem.value_or (0); });
26 const int missingCount = std::count (widths.begin (), widths.end (), std::nullopt);
27
28 const auto widthPerMissing = missingCount ?
29 std::max (1, (totalWidth - occupiedWidth) / missingCount) :
30 0;
31
32 QList<int> result;
33 result.reserve (widths.size ());
34 for (const auto& w : widths)
35 result << w.value_or (widthPerMissing);
36 return result;
37 }
38
39 QList<int> RedistributeWidths (int totalWidth, const Factors& factors)
40 {
41 const auto totalFactors = std::accumulate (factors.begin (), factors.end (), 0);
42
43 QList<int> result;
44 result.reserve (factors.size ());
45 for (auto size : factors)
46 result << size * totalWidth / totalFactors;
47 return result;
48 }
49
50 QList<int> RedistributeWidths (int totalWidth, const InitialDistr& initial)
51 {
52 return Visit (initial, [&] (const auto& value) { return RedistributeWidths (totalWidth, value); });
53 }
54
55 QList<int> FromVariantList (const QVariantList& list)
56 {
57 QList<int> result;
58 result.reserve (list.size ());
59 for (const auto& var : list)
60 {
61 bool ok = true;
62 result << var.toInt (&ok);
63 if (!ok)
64 return {};
65 }
66 return result;
67 }
68
69 QVariantList ToVariantList (const QList<int>& list)
70 {
71 QVariantList result;
72 result.reserve (list.size ());
73 for (auto num : list)
74 result << num;
75 return result;
76 }
77
78 template<typename F>
79 auto SingleRun (F&& f)
80 {
81 return [f = std::forward<F> (f)] (QEvent*, QObject& pThis) mutable
82 {
83 std::invoke (std::forward<F> (f));
84 pThis.deleteLater ();
85 return false;
86 };
87 }
88
89 template<typename F>
90 void OnResize (QWidget& widget, F&& f)
91 {
92 widget.installEventFilter (MakeLambdaEventFilter<QEvent::Resize> (SingleRun (std::move (f)), widget));
93 }
94 }
95
96 void SetupStateSaver (QSplitter& splitter, const StateSaverParams& params)
97 {
98 OnResize (splitter,
99 [&splitter, params]
100 {
101 auto widths = FromVariantList (params.XSM_.Property (params.Id_, {}).value<QVariantList> ());
102 if (widths.isEmpty ())
103 widths = RedistributeWidths (splitter.width (), params.Initial_);
104 splitter.setSizes (widths);
105 });
106
107 using namespace std::chrono_literals;
108 QObject::connect (&splitter,
109 &QSplitter::splitterMoved,
110 Throttled (1s, &splitter,
111 [&xsm = params.XSM_, id = params.Id_, &splitter]
112 {
113 xsm.setProperty (id.c_str (), ToVariantList (splitter.sizes ()));
114 }));
115 }
116
117 void SetupStateSaver (QHeaderView& header, const StateSaverParams& params)
118 {
119 OnResize (header,
120 [&header, params]
121 {
122 const auto state = params.XSM_.Property (params.Id_, QByteArray {}).toByteArray ();
123 if (state.isEmpty () || !header.restoreState (state))
124 {
125 const auto scrollWidth = header.style ()->pixelMetric (QStyle::PM_ScrollBarExtent);
126 const auto slack = 10;
127 const auto totalWidth = header.width () - scrollWidth - slack;
128 const auto& widths = RedistributeWidths (totalWidth, params.Initial_);
129 for (int i = 0; i < widths.size (); ++i)
130 header.resizeSection (i, widths.at (i));
131 }
132 });
133
134 using namespace std::chrono_literals;
135 const auto saver = Throttled (5s, &header,
136 [&xsm = params.XSM_, id = params.Id_, &header] { xsm.setProperty (id.c_str (), header.saveState ()); });
137 QObject::connect (&header,
138 &QHeaderView::sectionMoved,
139 saver);
140 QObject::connect (&header,
141 &QHeaderView::sectionResized,
142 saver);
143 }
144}
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
Definition oral.h:936
void SetupStateSaver(QSplitter &splitter, const StateSaverParams &params)
auto Throttled(std::chrono::milliseconds ms, QObject *parent, F &&f)
Definition throttle.h:16
auto Visit(const Either< Left, Right > &either, Args &&... args)
Definition either.h:204
std::variant< Widths, Factors > InitialDistr
Definition statesaver.h:34
auto MakeLambdaEventFilter(F &&f, QObject &parent)
BaseSettingsManager & XSM_
Definition statesaver.h:38