mirror of https://github.com/KLayout/klayout.git
Rework of the progress reporting scheme: LVS got a log now, the layout is horizontal for multiple progress objects, less flicker and more quiet display, cancel function should work more reliably now.
This commit is contained in:
parent
518145fd3e
commit
bb9ae20c32
|
|
@ -1671,7 +1671,9 @@ Layout::do_update ()
|
||||||
// HINT: because of some gcc bug, automatic destruction of the tl::Progress
|
// HINT: because of some gcc bug, automatic destruction of the tl::Progress
|
||||||
// object does not work. We overcome this problem by creating the object with new
|
// object does not work. We overcome this problem by creating the object with new
|
||||||
// and catching exceptions.
|
// and catching exceptions.
|
||||||
tl::RelativeProgress *pr = new tl::RelativeProgress (tl::to_string (tr ("Sorting layout")), m_cells_size, 1000);
|
// As this operation is critical we don't want to have it cancelled. Plus: do_update is called during ~LayoutLocker and
|
||||||
|
// if we throw exceptions then, we'll get a runtime assertion.
|
||||||
|
tl::RelativeProgress *pr = new tl::RelativeProgress (tl::to_string (tr ("Sorting layout")), m_cells_size, 0, false /*can't cancel*/);
|
||||||
pr->set_desc ("");
|
pr->set_desc ("");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -326,8 +326,7 @@ HelpSource::produce_index_file (const std::string &path)
|
||||||
m_title_map.clear ();
|
m_title_map.clear ();
|
||||||
m_parent_of.clear ();
|
m_parent_of.clear ();
|
||||||
|
|
||||||
tl::AbsoluteProgress progress (tl::to_string (QObject::tr ("Initializing help index")), 1);
|
tl::AbsoluteProgress progress (tl::to_string (QObject::tr ("Initializing help index")), 1, false /*can't cancel*/);
|
||||||
progress.can_cancel (false);
|
|
||||||
scan ("/index.xml", progress);
|
scan ("/index.xml", progress);
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,10 @@ static bool is_marked_alive (QObject *obj)
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
|
const double visibility_delay = 1.0;
|
||||||
|
|
||||||
ProgressReporter::ProgressReporter ()
|
ProgressReporter::ProgressReporter ()
|
||||||
: m_start_time (), mp_pb (0), m_pw_visible (false)
|
: mp_pb (0), m_pw_visible (false)
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
@ -94,22 +96,21 @@ ProgressReporter::register_object (tl::Progress *progress)
|
||||||
|
|
||||||
tl::ProgressAdaptor::register_object (progress);
|
tl::ProgressAdaptor::register_object (progress);
|
||||||
|
|
||||||
if (m_start_time == tl::Clock () && ! m_pw_visible) {
|
|
||||||
m_start_time = tl::Clock::current ();
|
|
||||||
}
|
|
||||||
|
|
||||||
// make dialog visible after some time has passed
|
|
||||||
if (! m_pw_visible && (tl::Clock::current () - m_start_time).seconds () > 1.0) {
|
|
||||||
set_visible (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (progress->is_abstract ()) {
|
if (progress->is_abstract ()) {
|
||||||
|
|
||||||
|
m_active.insert (progress);
|
||||||
|
|
||||||
|
if (! m_pw_visible) {
|
||||||
|
set_visible (true);
|
||||||
|
}
|
||||||
|
|
||||||
if (mp_pb) {
|
if (mp_pb) {
|
||||||
mp_pb->update_progress (progress);
|
mp_pb->update_progress (progress);
|
||||||
}
|
}
|
||||||
process_events ();
|
process_events ();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
update_and_yield ();
|
m_queued.insert (std::make_pair (progress, tl::Clock::current ()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,46 +122,64 @@ ProgressReporter::unregister_object (tl::Progress *progress)
|
||||||
// close or refresh window
|
// close or refresh window
|
||||||
if (begin () == end ()) {
|
if (begin () == end ()) {
|
||||||
|
|
||||||
|
m_queued.clear ();
|
||||||
|
m_active.clear ();
|
||||||
|
|
||||||
if (m_pw_visible) {
|
if (m_pw_visible) {
|
||||||
set_visible (false);
|
set_visible (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_start_time = tl::Clock ();
|
|
||||||
|
|
||||||
if (mp_pb) {
|
if (mp_pb) {
|
||||||
mp_pb->update_progress (0);
|
mp_pb->update_progress (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
process_events ();
|
process_events ();
|
||||||
|
|
||||||
QApplication::instance ()->removeEventFilter (this);
|
QApplication::instance ()->removeEventFilter (this);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
update_and_yield ();
|
|
||||||
|
m_queued.erase (progress);
|
||||||
|
|
||||||
|
std::set<tl::Progress *>::iterator a = m_active.find (progress);
|
||||||
|
if (a != m_active.end ()) {
|
||||||
|
m_active.erase (a);
|
||||||
|
update_and_yield ();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ProgressReporter::trigger (tl::Progress * /*progress*/)
|
ProgressReporter::trigger (tl::Progress *progress)
|
||||||
{
|
{
|
||||||
if (begin () != end ()) {
|
std::map<tl::Progress *, tl::Clock>::iterator q = m_queued.find (progress);
|
||||||
// make dialog visible after some time has passed
|
if (q != m_queued.end () && (tl::Clock::current () - q->second).seconds () > visibility_delay) {
|
||||||
if (! m_pw_visible && (tl::Clock::current () - m_start_time).seconds () > 1.0) {
|
if (! m_pw_visible) {
|
||||||
set_visible (true);
|
set_visible (true);
|
||||||
}
|
}
|
||||||
|
m_active.insert (progress);
|
||||||
|
m_queued.erase (q);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_active.find (progress) != m_active.end ()) {
|
||||||
update_and_yield ();
|
update_and_yield ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ProgressReporter::yield (tl::Progress * /*progress*/)
|
ProgressReporter::yield (tl::Progress *progress)
|
||||||
{
|
{
|
||||||
// make dialog visible after some time has passed
|
std::map<tl::Progress *, tl::Clock>::iterator q = m_queued.find (progress);
|
||||||
if (! m_pw_visible && (tl::Clock::current () - m_start_time).seconds () > 1.0) {
|
if (q != m_queued.end () && (tl::Clock::current () - q->second).seconds () > visibility_delay) {
|
||||||
set_visible (true);
|
if (! m_pw_visible) {
|
||||||
|
set_visible (true);
|
||||||
|
}
|
||||||
|
m_active.insert (progress);
|
||||||
|
m_queued.erase (q);
|
||||||
update_and_yield ();
|
update_and_yield ();
|
||||||
} else if (m_pw_visible) {
|
}
|
||||||
// process events if necessary
|
|
||||||
|
if (m_active.find (progress) != m_active.end ()) {
|
||||||
process_events ();
|
process_events ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -172,11 +191,17 @@ ProgressReporter::update_and_yield ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_pb && first ()) {
|
if (mp_pb) {
|
||||||
mp_pb->update_progress (first ());
|
if (first ()) {
|
||||||
QWidget *w = mp_pb->progress_get_widget ();
|
mp_pb->update_progress (first ());
|
||||||
if (w) {
|
QWidget *w = mp_pb->progress_get_widget ();
|
||||||
first ()->render_progress (w);
|
if (w) {
|
||||||
|
first ()->render_progress (w);
|
||||||
|
}
|
||||||
|
} else if (begin () != end ()) {
|
||||||
|
mp_pb->update_progress (begin ().operator-> ());
|
||||||
|
} else {
|
||||||
|
mp_pb->update_progress (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include "tlProgress.h"
|
#include "tlProgress.h"
|
||||||
#include "tlObject.h"
|
#include "tlObject.h"
|
||||||
|
|
@ -71,9 +73,10 @@ public:
|
||||||
void set_progress_bar (lay::ProgressBar *pb);
|
void set_progress_bar (lay::ProgressBar *pb);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
tl::Clock m_start_time;
|
|
||||||
lay::ProgressBar *mp_pb;
|
lay::ProgressBar *mp_pb;
|
||||||
bool m_pw_visible;
|
bool m_pw_visible;
|
||||||
|
std::map<tl::Progress *, tl::Clock> m_queued;
|
||||||
|
std::set<tl::Progress *> m_active;
|
||||||
|
|
||||||
void process_events ();
|
void process_events ();
|
||||||
void update_and_yield ();
|
void update_and_yield ();
|
||||||
|
|
|
||||||
|
|
@ -90,13 +90,13 @@ QSize
|
||||||
ProgressBarWidget::sizeHint () const
|
ProgressBarWidget::sizeHint () const
|
||||||
{
|
{
|
||||||
QFontMetrics fm (font ());
|
QFontMetrics fm (font ());
|
||||||
return QSize (m_width, fm.height () + 2);
|
return QSize (fm.width (QString::fromUtf8("100%")) * 4, fm.height () + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize
|
QSize
|
||||||
ProgressBarWidget::minimumSizeHint () const
|
ProgressBarWidget::minimumSizeHint () const
|
||||||
{
|
{
|
||||||
return QSize (m_width, 1);
|
return QSize (50, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -149,6 +149,11 @@ ProgressWidget::ProgressWidget (ProgressReporter *pr, QWidget *parent, bool fw)
|
||||||
|
|
||||||
QVBoxLayout *log_layout = new QVBoxLayout (mp_log_frame);
|
QVBoxLayout *log_layout = new QVBoxLayout (mp_log_frame);
|
||||||
|
|
||||||
|
mp_log_label = new QLabel (mp_log_frame);
|
||||||
|
mp_log_label->setText (QString ());
|
||||||
|
mp_log_label->setSizePolicy (QSizePolicy (QSizePolicy::Ignored, QSizePolicy::Preferred));
|
||||||
|
log_layout->addWidget (mp_log_label);
|
||||||
|
|
||||||
QListView *log_view = new QListView (this);
|
QListView *log_view = new QListView (this);
|
||||||
log_view->setModel (&m_log_file);
|
log_view->setModel (&m_log_file);
|
||||||
log_view->setUniformItemSizes (true);
|
log_view->setUniformItemSizes (true);
|
||||||
|
|
@ -200,22 +205,22 @@ ProgressWidget::ProgressWidget (ProgressReporter *pr, QWidget *parent, bool fw)
|
||||||
|
|
||||||
layout->addItem (new QSpacerItem (8, 8, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, col++, 1, 1);
|
layout->addItem (new QSpacerItem (8, 8, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, col++, 1, 1);
|
||||||
|
|
||||||
QFrame *progress_bar_frame = new QFrame (bar_frame);
|
mp_progress_bar_frame = new QFrame (bar_frame);
|
||||||
progress_bar_frame->setFrameStyle (QFrame::Box | QFrame::Plain);
|
mp_progress_bar_frame->setFrameStyle (QFrame::Box | QFrame::Plain);
|
||||||
progress_bar_frame->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding);
|
mp_progress_bar_frame->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
layout->addWidget (progress_bar_frame, 0, col, 1, 1);
|
layout->addWidget (mp_progress_bar_frame, 0, col, 1, 1);
|
||||||
|
|
||||||
QGridLayout *pbf_layout = new QGridLayout (progress_bar_frame);
|
QGridLayout *pbf_layout = new QGridLayout (mp_progress_bar_frame);
|
||||||
progress_bar_frame->setLayout (pbf_layout);
|
mp_progress_bar_frame->setLayout (pbf_layout);
|
||||||
pbf_layout->setMargin (0);
|
pbf_layout->setMargin (0);
|
||||||
pbf_layout->setSpacing (0);
|
pbf_layout->setSpacing (0);
|
||||||
|
|
||||||
mp_progress_bar1 = new ProgressBarWidget (progress_bar_frame);
|
mp_progress_bar1 = new ProgressBarWidget (mp_progress_bar_frame);
|
||||||
pbf_layout->addWidget (mp_progress_bar1, 0, 0, 1, 1);
|
pbf_layout->addWidget (mp_progress_bar1, 0, 2, 1, 1);
|
||||||
mp_progress_bar2 = new ProgressBarWidget (progress_bar_frame);
|
mp_progress_bar2 = new ProgressBarWidget (mp_progress_bar_frame);
|
||||||
pbf_layout->addWidget (mp_progress_bar2, 1, 0, 1, 1);
|
pbf_layout->addWidget (mp_progress_bar2, 0, 1, 1, 1);
|
||||||
mp_progress_bar3 = new ProgressBarWidget (progress_bar_frame);
|
mp_progress_bar3 = new ProgressBarWidget (mp_progress_bar_frame);
|
||||||
pbf_layout->addWidget (mp_progress_bar3, 2, 0, 1, 1);
|
pbf_layout->addWidget (mp_progress_bar3, 0, 0, 1, 1);
|
||||||
|
|
||||||
layout->addItem (new QSpacerItem (8, 8, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, col++, 1, 1);
|
layout->addItem (new QSpacerItem (8, 8, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, col++, 1, 1);
|
||||||
|
|
||||||
|
|
@ -236,11 +241,12 @@ ProgressWidget::ProgressWidget (ProgressReporter *pr, QWidget *parent, bool fw)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ProgressWidget::set_log_visible (bool f)
|
ProgressWidget::set_log_visible (tl::Progress *progress)
|
||||||
{
|
{
|
||||||
if (f != m_log_visible) {
|
if ((progress != 0) != m_log_visible) {
|
||||||
m_log_visible = f;
|
m_log_visible = (progress != 0);
|
||||||
mp_log_frame->setVisible (f);
|
mp_log_frame->setVisible (m_log_visible);
|
||||||
|
mp_log_label->setText (progress ? tl::to_qstring (progress->desc ()) : QString ());
|
||||||
set_full_width (m_full_width);
|
set_full_width (m_full_width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -290,11 +296,23 @@ ProgressWidget::remove_widget ()
|
||||||
void
|
void
|
||||||
ProgressWidget::set_progress (tl::Progress *progress)
|
ProgressWidget::set_progress (tl::Progress *progress)
|
||||||
{
|
{
|
||||||
|
lay::ProgressBarWidget *progress_bars[] = { mp_progress_bar1, mp_progress_bar2, mp_progress_bar3 };
|
||||||
|
|
||||||
if (! progress || progress->is_abstract ()) {
|
if (! progress || progress->is_abstract ()) {
|
||||||
m_log_file.clear ();
|
|
||||||
|
if (! progress) {
|
||||||
|
m_log_file.clear ();
|
||||||
|
}
|
||||||
m_log_file.set_max_entries (progress ? 1000 : 0);
|
m_log_file.set_max_entries (progress ? 1000 : 0);
|
||||||
set_log_visible (progress != 0);
|
|
||||||
|
set_log_visible (progress);
|
||||||
|
|
||||||
|
mp_progress_bar_frame->hide ();
|
||||||
|
mp_cancel_button->setEnabled (true);
|
||||||
|
mp_label->setText (QString ());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool can_cancel = false;
|
bool can_cancel = false;
|
||||||
|
|
@ -308,8 +326,6 @@ ProgressWidget::set_progress (tl::Progress *progress)
|
||||||
mp_cancel_button->setEnabled (can_cancel);
|
mp_cancel_button->setEnabled (can_cancel);
|
||||||
mp_label->setText (tl::to_qstring (text));
|
mp_label->setText (tl::to_qstring (text));
|
||||||
|
|
||||||
lay::ProgressBarWidget *progress_bars[] = { mp_progress_bar1, mp_progress_bar2, mp_progress_bar3 };
|
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof (progress_bars) / sizeof (progress_bars[0]); ++i) {
|
for (size_t i = 0; i < sizeof (progress_bars) / sizeof (progress_bars[0]); ++i) {
|
||||||
|
|
||||||
lay::ProgressBarWidget *pb = progress_bars[i];
|
lay::ProgressBarWidget *pb = progress_bars[i];
|
||||||
|
|
@ -330,6 +346,8 @@ ProgressWidget::set_progress (tl::Progress *progress)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mp_progress_bar_frame->show ();
|
||||||
|
|
||||||
// according to the doc this should not be required, but without, the progress bar does not resize
|
// according to the doc this should not be required, but without, the progress bar does not resize
|
||||||
mp_progress_bar1->parentWidget ()->updateGeometry ();
|
mp_progress_bar1->parentWidget ()->updateGeometry ();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ public slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QLabel *mp_label;
|
QLabel *mp_label;
|
||||||
|
QFrame *mp_progress_bar_frame;
|
||||||
ProgressBarWidget *mp_progress_bar1, *mp_progress_bar2, *mp_progress_bar3;
|
ProgressBarWidget *mp_progress_bar1, *mp_progress_bar2, *mp_progress_bar3;
|
||||||
QWidget *mp_widget;
|
QWidget *mp_widget;
|
||||||
int m_widget_col;
|
int m_widget_col;
|
||||||
|
|
@ -79,12 +80,13 @@ private:
|
||||||
QToolButton *mp_cancel_button;
|
QToolButton *mp_cancel_button;
|
||||||
ProgressReporter *mp_pr;
|
ProgressReporter *mp_pr;
|
||||||
lay::LogFile m_log_file;
|
lay::LogFile m_log_file;
|
||||||
|
QLabel *mp_log_label;
|
||||||
QFrame *mp_log_frame;
|
QFrame *mp_log_frame;
|
||||||
bool m_full_width;
|
bool m_full_width;
|
||||||
int m_left_col, m_right_col;
|
int m_left_col, m_right_col;
|
||||||
bool m_log_visible;
|
bool m_log_visible;
|
||||||
|
|
||||||
void set_log_visible (bool f);
|
void set_log_visible (tl::Progress *progress);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ module LVS
|
||||||
lvs._l2ndb_index = l2ndb_index
|
lvs._l2ndb_index = l2ndb_index
|
||||||
lvs._generator = generator
|
lvs._generator = generator
|
||||||
|
|
||||||
|
lvs_progress = RBA::AbstractProgress::new("LVS: " + macro.path)
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
# Set a debugger scope so that our errors end up with the debugger set to the LVS's line
|
# Set a debugger scope so that our errors end up with the debugger set to the LVS's line
|
||||||
|
|
@ -46,6 +48,9 @@ module LVS
|
||||||
# cleans up and creates layout and report views
|
# cleans up and creates layout and report views
|
||||||
lvs._finish
|
lvs._finish
|
||||||
|
|
||||||
|
# unlocks the UI
|
||||||
|
lvs_progress._destroy
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
timer.stop
|
timer.stop
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,11 @@ ProgressAdaptor::~ProgressAdaptor ()
|
||||||
void
|
void
|
||||||
ProgressAdaptor::register_object (Progress *progress)
|
ProgressAdaptor::register_object (Progress *progress)
|
||||||
{
|
{
|
||||||
|
bool cancelled = ! mp_objects.empty () && mp_objects.first ()->break_scheduled ();
|
||||||
mp_objects.push_back (progress); // this keeps the outmost one visible. push_front would make the latest one visible.
|
mp_objects.push_back (progress); // this keeps the outmost one visible. push_front would make the latest one visible.
|
||||||
|
if (cancelled) {
|
||||||
|
progress->signal_break ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -130,15 +134,19 @@ ProgressGarbageCollector::~ProgressGarbageCollector ()
|
||||||
// store a pointer but a pointer to a pointer.
|
// store a pointer but a pointer to a pointer.
|
||||||
static tl::ThreadStorage<ProgressAdaptor **> s_thread_data;
|
static tl::ThreadStorage<ProgressAdaptor **> s_thread_data;
|
||||||
|
|
||||||
Progress::Progress (const std::string &desc, size_t yield_interval)
|
const double yield_timeout = 0.3;
|
||||||
|
const size_t default_yield_interval = 1000;
|
||||||
|
|
||||||
|
Progress::Progress (const std::string &desc, size_t yield_interval, bool can_cancel)
|
||||||
: m_desc (desc), m_title (desc),
|
: m_desc (desc), m_title (desc),
|
||||||
m_interval_count (0),
|
m_interval_count (0),
|
||||||
m_yield_interval (yield_interval),
|
m_yield_interval (yield_interval == 0 ? default_yield_interval : yield_interval),
|
||||||
m_last_value (-1.0),
|
m_last_value (-1.0),
|
||||||
m_can_cancel (true),
|
m_can_cancel (can_cancel),
|
||||||
m_cancelled (false)
|
m_cancelled (false),
|
||||||
|
m_registered (false)
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
m_last_yield = tl::Clock::current ();
|
||||||
}
|
}
|
||||||
|
|
||||||
Progress::~Progress ()
|
Progress::~Progress ()
|
||||||
|
|
@ -149,9 +157,19 @@ Progress::~Progress ()
|
||||||
void
|
void
|
||||||
Progress::initialize ()
|
Progress::initialize ()
|
||||||
{
|
{
|
||||||
|
// The abstract progress does not get test() calls so we need to register it now.
|
||||||
ProgressAdaptor *a = adaptor ();
|
ProgressAdaptor *a = adaptor ();
|
||||||
if (a) {
|
if (a) {
|
||||||
|
|
||||||
a->register_object (this);
|
a->register_object (this);
|
||||||
|
m_registered = true;
|
||||||
|
|
||||||
|
// A pending cancel request may immediately kill the operation - "register_object" will set the cancelled flag then.
|
||||||
|
if (m_cancelled) {
|
||||||
|
m_cancelled = false;
|
||||||
|
throw tl::BreakException ();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,7 +177,7 @@ void
|
||||||
Progress::shutdown ()
|
Progress::shutdown ()
|
||||||
{
|
{
|
||||||
ProgressAdaptor *a = adaptor ();
|
ProgressAdaptor *a = adaptor ();
|
||||||
if (a) {
|
if (a && m_registered) {
|
||||||
a->unregister_object (this);
|
a->unregister_object (this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -192,29 +210,27 @@ Progress::adaptor ()
|
||||||
void
|
void
|
||||||
Progress::signal_break ()
|
Progress::signal_break ()
|
||||||
{
|
{
|
||||||
m_cancelled = true;
|
if (m_can_cancel) {
|
||||||
|
m_cancelled = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Progress::set_desc (const std::string &d)
|
Progress::set_desc (const std::string &d)
|
||||||
{
|
{
|
||||||
ProgressAdaptor *a = adaptor ();
|
if (d != m_desc) {
|
||||||
if (a && d != m_desc) {
|
|
||||||
|
|
||||||
m_desc = d;
|
m_desc = d;
|
||||||
a->trigger (this);
|
test (true);
|
||||||
a->yield (this);
|
|
||||||
|
|
||||||
if (m_cancelled) {
|
|
||||||
m_cancelled = false;
|
|
||||||
throw tl::BreakException ();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Progress::test(bool force_yield)
|
bool Progress::test (bool force_yield)
|
||||||
{
|
{
|
||||||
|
if (m_cancelled) {
|
||||||
|
m_cancelled = false;
|
||||||
|
throw tl::BreakException ();
|
||||||
|
}
|
||||||
|
|
||||||
if (++m_interval_count >= m_yield_interval || force_yield) {
|
if (++m_interval_count >= m_yield_interval || force_yield) {
|
||||||
|
|
||||||
ProgressAdaptor *a = adaptor ();
|
ProgressAdaptor *a = adaptor ();
|
||||||
|
|
@ -226,22 +242,28 @@ bool Progress::test(bool force_yield)
|
||||||
needs_trigger = true;
|
needs_trigger = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_desc != m_last_desc) {
|
||||||
|
m_last_desc = m_desc;
|
||||||
|
needs_trigger = true;
|
||||||
|
}
|
||||||
|
|
||||||
m_interval_count = 0;
|
m_interval_count = 0;
|
||||||
|
|
||||||
if (a) {
|
if (a) {
|
||||||
|
|
||||||
tl::Clock now = tl::Clock::current ();
|
tl::Clock now = tl::Clock::current ();
|
||||||
if ((now - m_last_yield).seconds () > 0.1) {
|
if ((now - m_last_yield).seconds () > yield_timeout) {
|
||||||
|
|
||||||
m_last_yield = now;
|
m_last_yield = now;
|
||||||
|
|
||||||
if (needs_trigger) {
|
if (needs_trigger) {
|
||||||
a->trigger (this);
|
a->trigger (this);
|
||||||
}
|
}
|
||||||
a->yield (this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_cancelled) {
|
a->yield (this);
|
||||||
m_cancelled = false;
|
|
||||||
throw tl::BreakException ();
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -268,8 +290,8 @@ AbstractProgress::~AbstractProgress ()
|
||||||
// ---------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------
|
||||||
// RelativeProgress implementation
|
// RelativeProgress implementation
|
||||||
|
|
||||||
RelativeProgress::RelativeProgress (const std::string &desc, size_t max_count, size_t yield_interval)
|
RelativeProgress::RelativeProgress (const std::string &desc, size_t max_count, size_t yield_interval, bool can_cancel)
|
||||||
: Progress (desc, yield_interval)
|
: Progress (desc, yield_interval, can_cancel)
|
||||||
{
|
{
|
||||||
m_format = "%.0f%%";
|
m_format = "%.0f%%";
|
||||||
m_unit = double (max_count) / 100.0;
|
m_unit = double (max_count) / 100.0;
|
||||||
|
|
@ -313,8 +335,8 @@ RelativeProgress::set (size_t count, bool force_yield)
|
||||||
// ---------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------
|
||||||
// Progress implementation
|
// Progress implementation
|
||||||
|
|
||||||
AbsoluteProgress::AbsoluteProgress (const std::string &desc, size_t yield_interval)
|
AbsoluteProgress::AbsoluteProgress (const std::string &desc, size_t yield_interval, bool can_cancel)
|
||||||
: Progress (desc, yield_interval)
|
: Progress (desc, yield_interval, can_cancel)
|
||||||
{
|
{
|
||||||
m_format = "%.0f";
|
m_format = "%.0f";
|
||||||
m_unit = 1.0;
|
m_unit = 1.0;
|
||||||
|
|
|
||||||
|
|
@ -185,8 +185,9 @@ public:
|
||||||
*
|
*
|
||||||
* @param desc The description and title string
|
* @param desc The description and title string
|
||||||
* @param yield_interval See above.
|
* @param yield_interval See above.
|
||||||
|
* @param can_cancel If set to true, the progress may be cancelled which results in a BreakException begin raised
|
||||||
*/
|
*/
|
||||||
Progress (const std::string &desc, size_t yield_interval = 1000);
|
Progress (const std::string &desc, size_t yield_interval = 0, bool can_cancel = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The destructor
|
* @brief The destructor
|
||||||
|
|
@ -228,17 +229,6 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void render_progress (QWidget * /*widget*/) const { }
|
virtual void render_progress (QWidget * /*widget*/) const { }
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set a value indicating whether the operation can be cancelled
|
|
||||||
*
|
|
||||||
* The progress object will throw a BreakException is cancelled and this
|
|
||||||
* flag is set to true. The default is "true".
|
|
||||||
*/
|
|
||||||
void can_cancel (bool f)
|
|
||||||
{
|
|
||||||
m_can_cancel = f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets a value indicating whether the operation can be cancelled
|
* @brief Gets a value indicating whether the operation can be cancelled
|
||||||
*/
|
*/
|
||||||
|
|
@ -273,6 +263,14 @@ public:
|
||||||
*/
|
*/
|
||||||
void signal_break ();
|
void signal_break ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns true, if a break is scheduled
|
||||||
|
*/
|
||||||
|
bool break_scheduled () const
|
||||||
|
{
|
||||||
|
return m_cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* @brief Indicates that a new value has arrived
|
* @brief Indicates that a new value has arrived
|
||||||
|
|
@ -296,13 +294,14 @@ private:
|
||||||
friend class ProgressAdaptor;
|
friend class ProgressAdaptor;
|
||||||
friend class ProgressGarbageCollector;
|
friend class ProgressGarbageCollector;
|
||||||
|
|
||||||
std::string m_desc;
|
std::string m_desc, m_last_desc;
|
||||||
std::string m_title;
|
std::string m_title;
|
||||||
size_t m_interval_count;
|
size_t m_interval_count;
|
||||||
size_t m_yield_interval;
|
size_t m_yield_interval;
|
||||||
double m_last_value;
|
double m_last_value;
|
||||||
bool m_can_cancel;
|
bool m_can_cancel;
|
||||||
bool m_cancelled;
|
bool m_cancelled;
|
||||||
|
bool m_registered;
|
||||||
tl::Clock m_last_yield;
|
tl::Clock m_last_yield;
|
||||||
|
|
||||||
static tl::ProgressAdaptor *adaptor ();
|
static tl::ProgressAdaptor *adaptor ();
|
||||||
|
|
@ -365,8 +364,9 @@ public:
|
||||||
* @param desc The description and title string
|
* @param desc The description and title string
|
||||||
* @param max_count The limit "max" value. 0 for absolute display of values.
|
* @param max_count The limit "max" value. 0 for absolute display of values.
|
||||||
* @param yield_interval See above.
|
* @param yield_interval See above.
|
||||||
|
* @param can_cancel If set to true, the progress may be cancelled which results in a BreakException begin raised
|
||||||
*/
|
*/
|
||||||
RelativeProgress (const std::string &desc, size_t max_count = 0, size_t yield_interval = 1000);
|
RelativeProgress (const std::string &desc, size_t max_count = 0, size_t yield_interval = 0, bool can_cancel = true);
|
||||||
|
|
||||||
~RelativeProgress ();
|
~RelativeProgress ();
|
||||||
|
|
||||||
|
|
@ -442,7 +442,7 @@ public:
|
||||||
* @param desc The description and title string
|
* @param desc The description and title string
|
||||||
* @param yield_interval See above.
|
* @param yield_interval See above.
|
||||||
*/
|
*/
|
||||||
AbsoluteProgress (const std::string &desc, size_t yield_interval = 1000);
|
AbsoluteProgress (const std::string &desc, size_t yield_interval = 0, bool can_cancel = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Destructor
|
* @brief Destructor
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue