Were okay but it showed that there was one case they didn't
cover: the first session receives a resize notification upon
startup whereas all other sessions don't. This means that
sessions restored from a previous run suddenly see the
size_finalized_ variable always staying at false - until the
user resizes the window.
While figuring out how to cover this case, I realized that
there is actually an easier way to perform all this:
instead of keeping an internal state of when and how we
received useless and useful resize notifications, we just
act upon the "show" event, which always comes after all
the widget resizing has been performed. This way, we can
remove the size_finalized_ variable completely and as it
is definitely always received when a session is shown,
we always end up in a sane and correct state.
Note: to reproduce, open up a 2nd session and use demo.
Then, when using the group handle to move the analog traces
upwards, you'll notice that the logic traces will move down
at the same time. This is because size_finalized_ is false
and the view will always center the traces vertically.
Sylvain Munaut [Sun, 28 May 2017 14:53:27 +0000 (16:53 +0200)]
viewport: Allow smoother zoom using vertical scroll events
The zoom supports 'double' as input type but since delta() and 120 are
integer, this wasn't used and any event with a delta lower than 120 was
ignored.
With this mod, the zoom level changes are _much_ smoother on trackpads
Soeren Apel [Sat, 27 May 2017 14:31:15 +0000 (16:31 +0200)]
DeviceManager: Show progress dialog while scanning for devices
We don't want users to wonder why nothing happens when they
start PV and no window shows up. Providing this dialog lets
them know that PV is starting and doing something.
Soeren Apel [Fri, 26 May 2017 14:19:56 +0000 (16:19 +0200)]
Rework signaling mechanism for trace repainting
Before, analog traces would request a repaint of the entire
view when they receive data. To understand how bad this was,
consider 4 enabled analog channels during capture. Every time
one channel would receive a bunch of sample data, it would
force a repaint of the view, resulting in 4 unnecessary
repaints.
To fix this, the analog traces no longer request a repaint
on incoming sample data. Instead, the mechanism now is such
that the view "collates" repaint requests from all used
signalbases by means of a one-shot timer, i.e. any repaint
request is ignored if the timer is already running.
With the timer, we can also establish an upper bound on
how often the trace should update at most, currently 25Hz.
Since this functionality is very useful for any kind of
view, the existing one-shot timer was moved to the ViewBase
and then extended as explained.
Soeren Apel [Thu, 25 May 2017 12:30:46 +0000 (14:30 +0200)]
Disable context menus that could lead to users removing UI parts
If a user removes the main toolbar then there's no way to get it
back. We don't want that.
If a user removes a dock window's contents he can get it back
by using the same context menu but it's a useless feature for us
and potentially very confusing, so we disable this, too.
Soeren Apel [Wed, 24 May 2017 21:50:37 +0000 (23:50 +0200)]
Fix #895 by adapting to Qt5 and cleaning up properly
Relevant Qt commit:
https://codereview.qt-project.org/#/c/72637/
"QProgressDialog: don't require setValue(0) to be called."
"Fixed by starting the timer in the constructor (most code doesn't reuse
progress dialogs, so this fixes the most common case)"
This messes us up because we're (ab-)using the dialog
in a non-standard way.
https://bugreports.qt.io/browse/QTBUG-47042
"QProgressDialog is designed to show itself automatically, based
on an internal estimate for the duration of the operation and the
minimumDuration property. You never call show() or exec() on it
manually. You're also not supposed to keep it around when it's not
used. In 5.4, the only way to start the internal duration estimation
was to call setValue(0). But we noticed that many people didn't call
setValue(0)"
Soeren Apel [Wed, 24 May 2017 11:44:43 +0000 (13:44 +0200)]
Fix #940 by updating the div spin boxes when needed
Also, prevent the autoranging algo from changing the div
assigment when the user is in the process of changing it.
This way, we only change the div assignment during
acquisition, which is when we actually need this feature.
Uwe Hermann [Tue, 9 May 2017 20:08:59 +0000 (22:08 +0200)]
Log settings location when using "-l 5".
This can have various types (e.g. a file or a registry entry) and it can
be in various locations on different OSes, so having this as part of the
log output is pretty useful.
Soeren Apel [Mon, 1 May 2017 13:04:10 +0000 (15:04 +0200)]
Segment: Rework append_samples() so it can handle large input
Before, adding large blocks of samples didn't work if they
would fill the current chunk, fill a new one and still have
data left to add. Using an iterative approach fixes this and
also makes the function more elegant.
Yeah, it violates the DRY principle and isn't nice OOP-wise
but it'll do for now. The entire group of Trace/Signal classes
needs to be reworked anyway to support device-independent
signal types anyway (think math traces and such).
Soeren Apel [Wed, 15 Mar 2017 18:22:17 +0000 (19:22 +0100)]
Use presence of logic/analog data as indicator of channel type
However, don't do this for the StoreSession. Reason is that we
only want to save the original data and not treat any converted
data as its own channel.
Uwe Hermann [Thu, 16 Mar 2017 22:29:24 +0000 (23:29 +0100)]
Increase session saving chunk size for much better performance.
Increasing the StoreSession chunk size from 1Msamples to 10Msamples
leads to massively faster session saving due to reduced overhead.
In some cases a 2x (or more) speed-up has been observed. A further increase
to, say, 100Msamples shows no further noticeable improvements.
This also has the additional benefit of generating fewer entries/files
within the sigrok session (*.sr) output/ZIP files, which can potentially
be beneficial for very long captures.
V1 will construct a temporary std::string from the string literal "foo",
another copy of that temporary object will be constructed and placed
into the vector 'v', then the temporary object's destructor will be called.
V2 will simply create a std::string directly in the vector 'v', i.e.
there's only one construction (not 2) and no destructor needs to be called.
Using make_shared() over manual construction has multiple advantages:
- It's shorter to write and easier to read.
V1: auto sb = shared_ptr<Foo>(new Foo());
V2: auto sb = make_shared<Foo>();
- The type "Foo" is repeated less often (less code duplication, lower
risk of forgetting to update one of the "Foo"s upon copy-paste etc.)
- Manual construction leads to two individual allocations (actual data and
the control block of the shared_ptr). Using make_shared() will only lead
to one allocation, which has performance, cache-locality and memory
consumption benefits.
- It's exception-safe, whereas manual construction is not necessarily: