mirror of
https://github.com/KLayout/klayout.git
synced 2026-08-22 14:07:15 +02:00
First version of XOR progress visualization.
This commit is contained in:
@@ -42,6 +42,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
namespace ext
|
namespace ext
|
||||||
{
|
{
|
||||||
@@ -157,6 +159,297 @@ struct RegionModeConverter
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CounterCompare
|
||||||
|
{
|
||||||
|
typedef std::pair<db::LayerProperties, size_t> value_type;
|
||||||
|
bool operator() (const value_type &a, const value_type &b) const
|
||||||
|
{
|
||||||
|
if (a.second != b.second) {
|
||||||
|
return a.second > b.second;
|
||||||
|
}
|
||||||
|
return a.first < b.first;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const size_t missing_in_a = std::numeric_limits<size_t>::max ();
|
||||||
|
const size_t missing_in_b = std::numeric_limits<size_t>::max () - 1;
|
||||||
|
|
||||||
|
class XORProgressWidget
|
||||||
|
: public QWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XORProgressWidget ()
|
||||||
|
: QWidget (0)
|
||||||
|
{
|
||||||
|
m_pixmap_size = 24;
|
||||||
|
m_max_lines = 5;
|
||||||
|
m_spacing = 2;
|
||||||
|
|
||||||
|
QFontMetrics fm (font ());
|
||||||
|
m_line_height = std::max (fm.height (), m_pixmap_size + 4);
|
||||||
|
m_font_height = fm.height () * 3 / 2;
|
||||||
|
m_first_column_width = fm.width (QString::fromUtf8 ("LAYERNAME"));
|
||||||
|
m_column_width = m_pixmap_size + 4 + m_spacing + fm.width (QString::fromUtf8 ("1.00G "));
|
||||||
|
|
||||||
|
m_ellipsis = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize sizeHint () const
|
||||||
|
{
|
||||||
|
return QSize (0, (m_line_height + m_spacing) * m_max_lines + m_font_height * 2 + m_spacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_results (double dbu, int nx, int ny, const std::map<std::pair<size_t, size_t>, std::map<std::pair<db::LayerProperties, db::Coord>, size_t> > &results, const std::map<db::LayerProperties, size_t> &count_per_layer, const std::vector<db::Coord> &tolerances)
|
||||||
|
{
|
||||||
|
m_labels.clear ();
|
||||||
|
m_layer_labels.clear ();
|
||||||
|
m_ellipsis = false;
|
||||||
|
m_red_images.clear ();
|
||||||
|
m_green_images.clear ();
|
||||||
|
m_blue_images.clear ();
|
||||||
|
m_yellow_images.clear ();
|
||||||
|
m_labels.clear ();
|
||||||
|
|
||||||
|
m_tolerance_labels.clear ();
|
||||||
|
for (std::vector<db::Coord>::const_iterator t = tolerances.begin (); t != tolerances.end (); ++t) {
|
||||||
|
m_tolerance_labels << tl::to_qstring (tl::sprintf ("%.12g", *t * dbu));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<db::LayerProperties, size_t> > counters;
|
||||||
|
counters.insert (counters.end (), count_per_layer.begin (), count_per_layer.end ());
|
||||||
|
std::sort (counters.begin (), counters.end (), CounterCompare ());
|
||||||
|
|
||||||
|
for (std::vector<std::pair<db::LayerProperties, size_t> >::const_iterator c = counters.begin (); c != counters.end (); ++c) {
|
||||||
|
|
||||||
|
if (m_layer_labels.size () == m_max_lines) {
|
||||||
|
m_ellipsis = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_layer_labels << tl::to_qstring (c->first.to_string ());
|
||||||
|
|
||||||
|
m_labels.push_back (QStringList ());
|
||||||
|
m_red_images.push_back (std::vector<QImage> ());
|
||||||
|
m_green_images.push_back (std::vector<QImage> ());
|
||||||
|
m_blue_images.push_back (std::vector<QImage> ());
|
||||||
|
m_yellow_images.push_back (std::vector<QImage> ());
|
||||||
|
|
||||||
|
for (std::vector<db::Coord>::const_iterator t = tolerances.begin (); t != tolerances.end (); ++t) {
|
||||||
|
|
||||||
|
m_labels.back ().push_back (QString ());
|
||||||
|
m_red_images.back ().push_back (QImage (m_pixmap_size, m_pixmap_size, QImage::Format_MonoLSB));
|
||||||
|
m_green_images.back ().push_back (QImage (m_pixmap_size, m_pixmap_size, QImage::Format_MonoLSB));
|
||||||
|
m_blue_images.back ().push_back (QImage (m_pixmap_size, m_pixmap_size, QImage::Format_MonoLSB));
|
||||||
|
m_yellow_images.back ().push_back (QImage (m_pixmap_size, m_pixmap_size, QImage::Format_MonoLSB));
|
||||||
|
|
||||||
|
m_red_images.back ().back ().fill (Qt::black);
|
||||||
|
m_green_images.back ().back ().fill (Qt::black);
|
||||||
|
m_blue_images.back ().back ().fill (Qt::black);
|
||||||
|
m_yellow_images.back ().back ().fill (Qt::black);
|
||||||
|
|
||||||
|
size_t tot_count = 0;
|
||||||
|
|
||||||
|
for (std::map<std::pair<size_t, size_t>, std::map<std::pair<db::LayerProperties, db::Coord>, size_t> >::const_iterator r = results.begin (); r != results.end (); ++r) {
|
||||||
|
|
||||||
|
const std::map<std::pair<db::LayerProperties, db::Coord>, size_t> &rm = r->second;
|
||||||
|
|
||||||
|
std::map<std::pair<db::LayerProperties, db::Coord>, size_t>::const_iterator rl = rm.find (std::make_pair (c->first, *t));
|
||||||
|
if (rl != rm.end ()) {
|
||||||
|
|
||||||
|
tot_count += rl->second;
|
||||||
|
|
||||||
|
QImage *img = 0;
|
||||||
|
if (rl->second == 0) {
|
||||||
|
img = &m_green_images.back ().back ();
|
||||||
|
} else if (rl->second == missing_in_a) {
|
||||||
|
m_blue_images.back ().back ().fill (Qt::white);
|
||||||
|
} else if (rl->second == missing_in_b) {
|
||||||
|
m_yellow_images.back ().back ().fill (Qt::white);
|
||||||
|
} else {
|
||||||
|
img = &m_red_images.back ().back ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (img) {
|
||||||
|
if (nx == 0 || ny == 0) {
|
||||||
|
img->fill (Qt::white);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
int ix = r->first.first;
|
||||||
|
int iy = r->first.second;
|
||||||
|
|
||||||
|
int y2 = m_pixmap_size - 1 - (iy * m_pixmap_size + m_pixmap_size / 2) / ny;
|
||||||
|
int y1 = m_pixmap_size - 1 - ((iy + 1) * m_pixmap_size + m_pixmap_size / 2) / ny;
|
||||||
|
int x1 = (ix * m_pixmap_size + m_pixmap_size / 2) / nx;
|
||||||
|
int x2 = ((ix + 1) * m_pixmap_size + m_pixmap_size / 2) / nx;
|
||||||
|
|
||||||
|
// "draw" the field
|
||||||
|
for (int y = y1; y <= y2 && y >= 0 && y < m_pixmap_size; ++y) {
|
||||||
|
*((uint32_t *) img->scanLine (y)) &= (((1 << x1) - 1) | ~((1 << (x2 + 1)) - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString text;
|
||||||
|
if (tot_count == missing_in_a) {
|
||||||
|
text = QString::fromUtf8 ("B");
|
||||||
|
} else if (tot_count == missing_in_b) {
|
||||||
|
text = QString::fromUtf8 ("A");
|
||||||
|
} else if (tot_count > 1000000000) {
|
||||||
|
text = QString::fromUtf8 ("%1G").arg (tot_count * 1e-9, 0, 'f', 2);
|
||||||
|
} else if (tot_count > 100000000) {
|
||||||
|
text = QString::fromUtf8 ("%1M").arg (tot_count * 1e-6, 0, 'f', 0);
|
||||||
|
} else if (tot_count > 10000000) {
|
||||||
|
text = QString::fromUtf8 ("%1M").arg (tot_count * 1e-6, 0, 'f', 1);
|
||||||
|
} else if (tot_count > 1000000) {
|
||||||
|
text = QString::fromUtf8 ("%1M").arg (tot_count * 1e-6, 0, 'f', 2);
|
||||||
|
} else if (tot_count > 100000) {
|
||||||
|
text = QString::fromUtf8 ("%1k").arg (tot_count * 1e-3, 0, 'f', 0);
|
||||||
|
} else if (tot_count > 10000) {
|
||||||
|
text = QString::fromUtf8 ("%1k").arg (tot_count * 1e-3, 0, 'f', 1);
|
||||||
|
} else if (tot_count > 1000) {
|
||||||
|
text = QString::fromUtf8 ("%1k").arg (tot_count * 1e-3, 0, 'f', 2);
|
||||||
|
} else {
|
||||||
|
text = QString::fromUtf8 ("%1").arg (tot_count);
|
||||||
|
}
|
||||||
|
m_labels.back ().back () = text;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
update ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void paintEvent (QPaintEvent * /*ev*/)
|
||||||
|
{
|
||||||
|
QPainter painter (this);
|
||||||
|
|
||||||
|
painter.drawText (QRect (QPoint (0, 0), QSize (m_first_column_width, m_font_height)),
|
||||||
|
tr ("Lay/Tol."),
|
||||||
|
QTextOption (Qt::AlignLeft | Qt::AlignTop));
|
||||||
|
|
||||||
|
for (int t = 0; t < m_tolerance_labels.size (); ++t) {
|
||||||
|
painter.drawText (QRect (QPoint (m_first_column_width + m_spacing + t * (m_column_width + m_spacing), 0), QSize (m_column_width, m_font_height)),
|
||||||
|
m_tolerance_labels [t],
|
||||||
|
QTextOption (Qt::AlignLeft | Qt::AlignTop));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int l = 0; l < m_layer_labels.size (); ++l) {
|
||||||
|
|
||||||
|
painter.drawText (QRect (QPoint (0, m_font_height + m_spacing + l * (m_line_height + m_spacing)), QSize (m_first_column_width, m_line_height)),
|
||||||
|
m_layer_labels [l],
|
||||||
|
QTextOption (Qt::AlignLeft | Qt::AlignVCenter));
|
||||||
|
|
||||||
|
for (int t = 0; t < m_tolerance_labels.size (); ++t) {
|
||||||
|
|
||||||
|
int x = m_first_column_width + m_spacing + t * (m_column_width + m_spacing);
|
||||||
|
int y = m_font_height + m_spacing + l * (m_line_height + m_spacing);
|
||||||
|
|
||||||
|
painter.drawText (QRect (QPoint (x + m_pixmap_size + 4 + m_spacing, y), QSize (m_column_width, m_line_height)),
|
||||||
|
m_labels [l][t],
|
||||||
|
QTextOption (Qt::AlignLeft | Qt::AlignVCenter));
|
||||||
|
|
||||||
|
painter.save ();
|
||||||
|
|
||||||
|
QLinearGradient grad (QPointF (0, 0), QPointF (1.0, 1.0));
|
||||||
|
grad.setCoordinateMode (QGradient::ObjectBoundingMode);
|
||||||
|
grad.setColorAt (0.0, QColor (248, 248, 248));
|
||||||
|
grad.setColorAt (1.0, QColor (224, 224, 224));
|
||||||
|
painter.setBrush (QBrush (grad));
|
||||||
|
painter.setPen (QPen (Qt::black));
|
||||||
|
painter.drawRect (QRect (QPoint (x - 2, y - 2), QSize (m_pixmap_size + 3, m_pixmap_size + 3)));
|
||||||
|
|
||||||
|
painter.setBackgroundMode (Qt::TransparentMode);
|
||||||
|
painter.setPen (QColor (128, 255, 128));
|
||||||
|
painter.drawPixmap (x, y, QBitmap::fromImage (m_green_images [l][t]));
|
||||||
|
painter.setPen (QColor (255, 128, 128));
|
||||||
|
painter.drawPixmap (x, y, QBitmap::fromImage (m_red_images [l][t]));
|
||||||
|
painter.setPen (QColor (128, 128, 255));
|
||||||
|
painter.drawPixmap (x, y, QBitmap::fromImage (m_blue_images [l][t]));
|
||||||
|
painter.setPen (QColor (255, 255, 128));
|
||||||
|
painter.drawPixmap (x, y, QBitmap::fromImage (m_yellow_images [l][t]));
|
||||||
|
painter.restore ();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_ellipsis) {
|
||||||
|
painter.drawText (QRect (QPoint (0, m_font_height + m_spacing + m_max_lines * (m_line_height + m_spacing)), QSize (m_first_column_width, m_font_height)),
|
||||||
|
QString::fromUtf8 ("..."),
|
||||||
|
QTextOption (Qt::AlignLeft | Qt::AlignTop));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_pixmap_size;
|
||||||
|
int m_line_height;
|
||||||
|
int m_font_height;
|
||||||
|
int m_max_lines;
|
||||||
|
int m_spacing;
|
||||||
|
int m_column_width;
|
||||||
|
int m_first_column_width;
|
||||||
|
QStringList m_tolerance_labels;
|
||||||
|
QStringList m_layer_labels;
|
||||||
|
std::vector<QStringList> m_labels;
|
||||||
|
std::vector<std::vector<QImage> > m_green_images;
|
||||||
|
std::vector<std::vector<QImage> > m_red_images;
|
||||||
|
std::vector<std::vector<QImage> > m_yellow_images;
|
||||||
|
std::vector<std::vector<QImage> > m_blue_images;
|
||||||
|
bool m_ellipsis;
|
||||||
|
};
|
||||||
|
|
||||||
|
class XORProgress
|
||||||
|
: public tl::RelativeProgress
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XORProgress (const std::string &title, size_t max_count, size_t yield_interval)
|
||||||
|
: tl::RelativeProgress (title, max_count, yield_interval), m_needs_update (true), m_dbu (1.0), m_nx (0), m_ny (0)
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual QWidget *progress_widget () const
|
||||||
|
{
|
||||||
|
return new XORProgressWidget ();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void render_progress (QWidget *widget) const
|
||||||
|
{
|
||||||
|
XORProgressWidget *pw = dynamic_cast<XORProgressWidget *> (widget);
|
||||||
|
if (pw) {
|
||||||
|
pw->set_results (m_dbu, m_nx, m_ny, m_results, m_count_per_layer, m_tolerances);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_results (double dbu, int nx, int ny, const std::map<std::pair<size_t, size_t>, std::map<std::pair<db::LayerProperties, db::Coord>, size_t> > &results, const std::map<db::LayerProperties, size_t> &count_per_layer, const std::vector<db::Coord> &tol)
|
||||||
|
{
|
||||||
|
if (m_count_per_layer != count_per_layer) {
|
||||||
|
m_dbu = dbu;
|
||||||
|
m_nx = nx;
|
||||||
|
m_ny = ny;
|
||||||
|
m_results = results;
|
||||||
|
m_tolerances = tol;
|
||||||
|
m_count_per_layer = count_per_layer;
|
||||||
|
m_needs_update = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<std::pair<size_t, size_t>, std::map<std::pair<db::LayerProperties, db::Coord>, size_t> > m_results;
|
||||||
|
std::map<db::LayerProperties, size_t> m_count_per_layer;
|
||||||
|
std::vector<db::Coord> m_tolerances;
|
||||||
|
bool m_needs_update;
|
||||||
|
double m_dbu;
|
||||||
|
int m_nx, m_ny;
|
||||||
|
};
|
||||||
|
|
||||||
XORToolDialog::XORToolDialog (QWidget *parent)
|
XORToolDialog::XORToolDialog (QWidget *parent)
|
||||||
: QDialog (parent), mp_view (0)
|
: QDialog (parent), mp_view (0)
|
||||||
{
|
{
|
||||||
@@ -348,6 +641,7 @@ XORToolDialog::output_changed (int index)
|
|||||||
mp_ui->layer_offset_le->setEnabled (enabled);
|
mp_ui->layer_offset_le->setEnabled (enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class XORJob
|
class XORJob
|
||||||
: public tl::JobBase
|
: public tl::JobBase
|
||||||
{
|
{
|
||||||
@@ -387,7 +681,9 @@ public:
|
|||||||
m_sub_output_layers (sub_output_layers),
|
m_sub_output_layers (sub_output_layers),
|
||||||
m_rdb (rdb),
|
m_rdb (rdb),
|
||||||
m_rdb_cell (rdb_cell),
|
m_rdb_cell (rdb_cell),
|
||||||
m_progress (0)
|
m_progress (0),
|
||||||
|
m_update_results (false),
|
||||||
|
m_nx (0), m_ny (0)
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
@@ -412,9 +708,11 @@ public:
|
|||||||
return m_has_tiles;
|
return m_has_tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void has_tiles (bool ht)
|
void has_tiles (bool ht, int nx, int ny)
|
||||||
{
|
{
|
||||||
m_has_tiles = ht;
|
m_has_tiles = ht;
|
||||||
|
m_nx = ht ? nx : 0;
|
||||||
|
m_ny = ht ? ny : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double dbu () const
|
double dbu () const
|
||||||
@@ -448,12 +746,31 @@ public:
|
|||||||
++m_progress;
|
++m_progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_progress (tl::RelativeProgress &progress)
|
void add_results (const db::LayerProperties &lp, db::Coord tol, size_t n, size_t ix, size_t iy)
|
||||||
|
{
|
||||||
|
QMutexLocker locker (&m_mutex);
|
||||||
|
if (n == missing_in_a || n == missing_in_b) {
|
||||||
|
m_results [std::make_pair (ix, iy)][std::make_pair (lp, tol)] = n;
|
||||||
|
m_count_per_layer [lp] = n;
|
||||||
|
} else {
|
||||||
|
// NOTE: we will not get a "normal" n after missing_in_a or missing_in_b
|
||||||
|
m_results [std::make_pair (ix, iy)][std::make_pair (lp, tol)] += n;
|
||||||
|
m_count_per_layer [lp] += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_update_results = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_progress (XORProgress &progress)
|
||||||
{
|
{
|
||||||
unsigned int p;
|
unsigned int p;
|
||||||
{
|
{
|
||||||
QMutexLocker locker (&m_mutex);
|
QMutexLocker locker (&m_mutex);
|
||||||
p = m_progress;
|
p = m_progress;
|
||||||
|
if (m_update_results) {
|
||||||
|
progress.set_results (m_dbu, m_nx, m_ny, m_results, m_count_per_layer, m_tolerances);
|
||||||
|
m_update_results = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.set (p, true /*force yield*/);
|
progress.set (p, true /*force yield*/);
|
||||||
@@ -524,14 +841,19 @@ private:
|
|||||||
rdb::Cell *m_rdb_cell;
|
rdb::Cell *m_rdb_cell;
|
||||||
unsigned int m_progress;
|
unsigned int m_progress;
|
||||||
QMutex m_mutex;
|
QMutex m_mutex;
|
||||||
|
std::string m_result_string;
|
||||||
|
bool m_update_results;
|
||||||
|
size_t m_nx, m_ny;
|
||||||
|
std::map<std::pair<size_t, size_t>, std::map<std::pair<db::LayerProperties, db::Coord>, size_t> > m_results;
|
||||||
|
std::map<db::LayerProperties, size_t> m_count_per_layer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class XORTask
|
class XORTask
|
||||||
: public tl::Task
|
: public tl::Task
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XORTask (const std::string &tile_desc, const db::Box &clip_box, const db::Box ®ion_a, const db::Box ®ion_b, unsigned int layer_index, const db::LayerProperties &lp, const std::vector<unsigned int> &la, const std::vector<unsigned int> &lb)
|
XORTask (const std::string &tile_desc, const db::Box &clip_box, const db::Box ®ion_a, const db::Box ®ion_b, unsigned int layer_index, const db::LayerProperties &lp, const std::vector<unsigned int> &la, const std::vector<unsigned int> &lb, int ix, int iy)
|
||||||
: m_tile_desc (tile_desc), m_clip_box (clip_box), m_region_a (region_a), m_region_b (region_b), m_layer_index (layer_index), m_lp (lp), m_la (la), m_lb (lb)
|
: m_tile_desc (tile_desc), m_clip_box (clip_box), m_region_a (region_a), m_region_b (region_b), m_layer_index (layer_index), m_lp (lp), m_la (la), m_lb (lb), m_ix (ix), m_iy (iy)
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
@@ -576,12 +898,23 @@ public:
|
|||||||
return m_lp;
|
return m_lp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ix () const
|
||||||
|
{
|
||||||
|
return m_ix;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iy () const
|
||||||
|
{
|
||||||
|
return m_iy;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_tile_desc;
|
std::string m_tile_desc;
|
||||||
db::Box m_clip_box, m_region_a, m_region_b;
|
db::Box m_clip_box, m_region_a, m_region_b;
|
||||||
unsigned int m_layer_index;
|
unsigned int m_layer_index;
|
||||||
db::LayerProperties m_lp;
|
db::LayerProperties m_lp;
|
||||||
std::vector<unsigned int> m_la, m_lb;
|
std::vector<unsigned int> m_la, m_lb;
|
||||||
|
int m_ix, m_iy;
|
||||||
};
|
};
|
||||||
|
|
||||||
class XORWorker
|
class XORWorker
|
||||||
@@ -789,6 +1122,8 @@ XORWorker::do_perform (const XORTask *xor_task)
|
|||||||
|
|
||||||
db::CplxTrans trans = db::CplxTrans (mp_job->dbu ());
|
db::CplxTrans trans = db::CplxTrans (mp_job->dbu ());
|
||||||
|
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
for (db::Shapes::shape_iterator s = xor_results_cell.shapes (0).begin (db::ShapeIterator::All); ! s.at_end (); ++s) {
|
for (db::Shapes::shape_iterator s = xor_results_cell.shapes (0).begin (db::ShapeIterator::All); ! s.at_end (); ++s) {
|
||||||
|
|
||||||
if (mp_job->has_tiles ()) {
|
if (mp_job->has_tiles ()) {
|
||||||
@@ -798,24 +1133,30 @@ XORWorker::do_perform (const XORTask *xor_task)
|
|||||||
|
|
||||||
for (std::vector <db::Polygon>::const_iterator cp = clipped_poly.begin (); cp != clipped_poly.end (); ++cp) {
|
for (std::vector <db::Polygon>::const_iterator cp = clipped_poly.begin (); cp != clipped_poly.end (); ++cp) {
|
||||||
mp_job->issue_polygon (tol_index, xor_task->layer_index (), *cp, trans);
|
mp_job->issue_polygon (tol_index, xor_task->layer_index (), *cp, trans);
|
||||||
|
++n;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
mp_job->issue_polygon (tol_index, xor_task->layer_index (), s->polygon (), trans);
|
mp_job->issue_polygon (tol_index, xor_task->layer_index (), s->polygon (), trans);
|
||||||
|
++n;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mp_job->add_results (xor_task->lp (), *t, n, xor_task->ix (), xor_task->iy ());
|
||||||
|
|
||||||
} else if (mp_job->op () == db::BooleanOp::Xor ||
|
} else if (mp_job->op () == db::BooleanOp::Xor ||
|
||||||
(mp_job->op () == db::BooleanOp::ANotB && !la.empty ()) ||
|
(mp_job->op () == db::BooleanOp::ANotB && !la.empty ()) ||
|
||||||
(mp_job->op () == db::BooleanOp::BNotA && !lb.empty ())) {
|
(mp_job->op () == db::BooleanOp::BNotA && !lb.empty ())) {
|
||||||
|
|
||||||
if (!la.empty ()) {
|
if (!la.empty ()) {
|
||||||
mp_job->issue_string (tol_index, xor_task->layer_index (), tl::to_string (QObject::tr ("Layer not present at all in layout B")));
|
mp_job->issue_string (tol_index, xor_task->layer_index (), tl::to_string (QObject::tr ("Layer not present at all in layout B")));
|
||||||
|
mp_job->add_results (xor_task->lp (), *t, missing_in_b, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lb.empty ()) {
|
if (!lb.empty ()) {
|
||||||
mp_job->issue_string (tol_index, xor_task->layer_index (), tl::to_string (QObject::tr ("Layer not present at all in layout A")));
|
mp_job->issue_string (tol_index, xor_task->layer_index (), tl::to_string (QObject::tr ("Layer not present at all in layout A")));
|
||||||
|
mp_job->add_results (xor_task->lp (), *t, missing_in_a, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1249,7 +1590,7 @@ XORToolDialog::run_xor ()
|
|||||||
db::Coord tile_enlargement_b = db::coord_traits<db::Coord>::rounded_up (tile_enlargement * dbu / cvb->layout ().dbu ());
|
db::Coord tile_enlargement_b = db::coord_traits<db::Coord>::rounded_up (tile_enlargement * dbu / cvb->layout ().dbu ());
|
||||||
|
|
||||||
if (ntiles_w > 1 || ntiles_h > 1 || region_mode != RMAll /*enforces clip*/) {
|
if (ntiles_w > 1 || ntiles_h > 1 || region_mode != RMAll /*enforces clip*/) {
|
||||||
job.has_tiles (true);
|
job.has_tiles (true, ntiles_w, ntiles_h);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the XOR tasks
|
// create the XOR tasks
|
||||||
@@ -1279,7 +1620,7 @@ XORToolDialog::run_xor ()
|
|||||||
|
|
||||||
unsigned int layer_index = 0;
|
unsigned int layer_index = 0;
|
||||||
for (std::map<db::LayerProperties, std::pair<std::vector<unsigned int>, std::vector<unsigned int> >, db::LPLogicalLessFunc>::const_iterator l = layers.begin (); l != layers.end (); ++l, ++layer_index) {
|
for (std::map<db::LayerProperties, std::pair<std::vector<unsigned int>, std::vector<unsigned int> >, db::LPLogicalLessFunc>::const_iterator l = layers.begin (); l != layers.end (); ++l, ++layer_index) {
|
||||||
job.schedule (new XORTask (tile_desc, clip_box, region_a, region_b, layer_index, l->first, l->second.first, l->second.second));
|
job.schedule (new XORTask (tile_desc, clip_box, region_a, region_b, layer_index, l->first, l->second.first, l->second.second, nw, nh));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1298,7 +1639,7 @@ XORToolDialog::run_xor ()
|
|||||||
|
|
||||||
// TODO: there should be a general scheme of how thread-specific progress is merged
|
// TODO: there should be a general scheme of how thread-specific progress is merged
|
||||||
// into a global one ..
|
// into a global one ..
|
||||||
tl::RelativeProgress progress (tl::to_string (QObject::tr ("Performing ")) + op_name, todo_count, 1);
|
XORProgress progress (tl::to_string (QObject::tr ("Performing ")) + op_name, todo_count, 1);
|
||||||
|
|
||||||
// We need to lock the layouts during the processing - in OMNewLayerA and OMNewLayerB mode
|
// We need to lock the layouts during the processing - in OMNewLayerA and OMNewLayerB mode
|
||||||
// we actually modify the layout we iterate over
|
// we actually modify the layout we iterate over
|
||||||
|
|||||||
@@ -150,6 +150,21 @@ public:
|
|||||||
mp_progress_widget->set_value (v, value);
|
mp_progress_widget->set_value (v, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_widget (QWidget *widget)
|
||||||
|
{
|
||||||
|
mp_progress_widget->add_widget (widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove_widget ()
|
||||||
|
{
|
||||||
|
mp_progress_widget->remove_widget ();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *get_widget () const
|
||||||
|
{
|
||||||
|
return mp_progress_widget->get_widget ();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
lay::ProgressWidget *mp_progress_widget;
|
lay::ProgressWidget *mp_progress_widget;
|
||||||
lay::ProgressReporter *mp_pr;
|
lay::ProgressReporter *mp_pr;
|
||||||
@@ -391,6 +406,30 @@ void TextProgressDelegate::show_progress_bar (bool show)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TextProgressDelegate::progress_wants_widget () const
|
||||||
|
{
|
||||||
|
return mp_mw != 0 && mp_mw->progress_wants_widget ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextProgressDelegate::progress_add_widget (QWidget *widget)
|
||||||
|
{
|
||||||
|
if (mp_mw) {
|
||||||
|
mp_mw->progress_add_widget (widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *TextProgressDelegate::progress_get_widget () const
|
||||||
|
{
|
||||||
|
return mp_mw ? mp_mw->progress_get_widget () : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextProgressDelegate::progress_remove_widget ()
|
||||||
|
{
|
||||||
|
if (mp_mw) {
|
||||||
|
mp_mw->progress_remove_widget ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------
|
// -------------------------------------------------------------
|
||||||
|
|
||||||
static MainWindow *mw_instance = 0;
|
static MainWindow *mw_instance = 0;
|
||||||
@@ -4593,6 +4632,18 @@ MainWindow::clear_current_pos ()
|
|||||||
mp_cpy_label->setText (QString ());
|
mp_cpy_label->setText (QString ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWidget *
|
||||||
|
MainWindow::progress_get_widget () const
|
||||||
|
{
|
||||||
|
if (mp_progress_dialog) {
|
||||||
|
return mp_progress_dialog->get_widget ();
|
||||||
|
} else if ( mp_progress_widget) {
|
||||||
|
return mp_progress_widget->get_widget ();
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MainWindow::set_progress_can_cancel (bool f)
|
MainWindow::set_progress_can_cancel (bool f)
|
||||||
{
|
{
|
||||||
@@ -4635,6 +4686,32 @@ MainWindow::set_progress_value (double v, const std::string &value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
MainWindow::progress_wants_widget () const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MainWindow::progress_add_widget (QWidget *widget)
|
||||||
|
{
|
||||||
|
if (mp_progress_dialog) {
|
||||||
|
mp_progress_dialog->add_widget (widget);
|
||||||
|
} else if (mp_progress_widget) {
|
||||||
|
mp_progress_widget->add_widget (widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MainWindow::progress_remove_widget ()
|
||||||
|
{
|
||||||
|
if (mp_progress_dialog) {
|
||||||
|
mp_progress_dialog->remove_widget ();
|
||||||
|
} else if (mp_progress_widget) {
|
||||||
|
mp_progress_widget->remove_widget ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MainWindow::show_progress_bar (bool show)
|
MainWindow::show_progress_bar (bool show)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -108,6 +108,10 @@ public:
|
|||||||
virtual void set_progress_text (const std::string &text);
|
virtual void set_progress_text (const std::string &text);
|
||||||
virtual void set_progress_value (double v, const std::string &value);
|
virtual void set_progress_value (double v, const std::string &value);
|
||||||
virtual void show_progress_bar (bool show);
|
virtual void show_progress_bar (bool show);
|
||||||
|
virtual bool progress_wants_widget () const;
|
||||||
|
virtual void progress_add_widget (QWidget *widget);
|
||||||
|
virtual QWidget *progress_get_widget () const;
|
||||||
|
virtual void progress_remove_widget ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MainWindow *mp_mw;
|
MainWindow *mp_mw;
|
||||||
@@ -388,6 +392,26 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool set_progress_value (double v, const std::string &value);
|
bool set_progress_value (double v, const std::string &value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation of the lay::ProgressBar interface: Returns a value indicating whether a progress widget is wanted
|
||||||
|
*/
|
||||||
|
bool progress_wants_widget () const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation of the lay::ProgressBar interface: adds a progress widget
|
||||||
|
*/
|
||||||
|
void progress_add_widget (QWidget *widget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation of the lay::ProgressBar interface: gets the progress widget
|
||||||
|
*/
|
||||||
|
QWidget *progress_get_widget () const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation of the lay::ProgressBar interface: removes a progress widget
|
||||||
|
*/
|
||||||
|
void progress_remove_widget ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Implementation of the lay::ProgressBar interface: Make the progress widget visible or invisible
|
* @brief Implementation of the lay::ProgressBar interface: Make the progress widget visible or invisible
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -168,6 +168,10 @@ ProgressReporter::update_and_yield ()
|
|||||||
mp_pb->set_progress_can_cancel (mp_objects.front ()->can_cancel ());
|
mp_pb->set_progress_can_cancel (mp_objects.front ()->can_cancel ());
|
||||||
mp_pb->set_progress_text (mp_objects.front ()->desc ());
|
mp_pb->set_progress_text (mp_objects.front ()->desc ());
|
||||||
mp_pb->set_progress_value (mp_objects.front ()->value (), mp_objects.front ()->formatted_value ());
|
mp_pb->set_progress_value (mp_objects.front ()->value (), mp_objects.front ()->formatted_value ());
|
||||||
|
QWidget *w = mp_pb->progress_get_widget ();
|
||||||
|
if (w) {
|
||||||
|
mp_objects.front ()->render_progress (w);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
process_events (); // Qt4 seems to need this
|
process_events (); // Qt4 seems to need this
|
||||||
}
|
}
|
||||||
@@ -189,12 +193,20 @@ ProgressReporter::set_visible (bool vis)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vis != m_pw_visible) {
|
if (vis != m_pw_visible) {
|
||||||
|
|
||||||
// prevent deferred method execution inside progress events - this might interfere with the
|
// prevent deferred method execution inside progress events - this might interfere with the
|
||||||
// actual operation
|
// actual operation
|
||||||
tl::DeferredMethodScheduler::enable (!vis);
|
tl::DeferredMethodScheduler::enable (!vis);
|
||||||
}
|
|
||||||
|
|
||||||
m_pw_visible = vis;
|
if (!vis) {
|
||||||
|
mp_pb->progress_remove_widget ();
|
||||||
|
} else if (mp_pb->progress_wants_widget () && mp_objects.front ()) {
|
||||||
|
mp_pb->progress_add_widget (mp_objects.front ()->progress_widget ());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pw_visible = vis;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (QApplication::instance()) {
|
if (QApplication::instance()) {
|
||||||
if (vis) {
|
if (vis) {
|
||||||
|
|||||||
@@ -50,6 +50,10 @@ public:
|
|||||||
virtual void set_progress_can_cancel (bool f) = 0;
|
virtual void set_progress_can_cancel (bool f) = 0;
|
||||||
virtual void set_progress_text (const std::string &text) = 0;
|
virtual void set_progress_text (const std::string &text) = 0;
|
||||||
virtual void set_progress_value (double v, const std::string &value) = 0;
|
virtual void set_progress_value (double v, const std::string &value) = 0;
|
||||||
|
virtual bool progress_wants_widget () const { return false; }
|
||||||
|
virtual void progress_add_widget (QWidget * /*widget*/) { }
|
||||||
|
virtual void progress_remove_widget () { }
|
||||||
|
virtual QWidget *progress_get_widget () const { return 0; }
|
||||||
virtual void show_progress_bar (bool show) = 0;
|
virtual void show_progress_bar (bool show) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <QFrame>
|
#include <QFrame>
|
||||||
|
#include <QGridLayout>
|
||||||
|
|
||||||
namespace lay
|
namespace lay
|
||||||
{
|
{
|
||||||
@@ -127,7 +128,7 @@ ProgressBarWidget::resizeEvent (QResizeEvent *)
|
|||||||
|
|
||||||
ProgressWidget::ProgressWidget (ProgressReporter *pr, QWidget *parent, bool full_width)
|
ProgressWidget::ProgressWidget (ProgressReporter *pr, QWidget *parent, bool full_width)
|
||||||
: QFrame (parent),
|
: QFrame (parent),
|
||||||
mp_pr (pr)
|
mp_widget (0), mp_pr (pr)
|
||||||
{
|
{
|
||||||
QVBoxLayout *top_layout = new QVBoxLayout (this);
|
QVBoxLayout *top_layout = new QVBoxLayout (this);
|
||||||
top_layout->addStretch (1);
|
top_layout->addStretch (1);
|
||||||
@@ -140,24 +141,30 @@ ProgressWidget::ProgressWidget (ProgressReporter *pr, QWidget *parent, bool full
|
|||||||
// this does not allow the label to control the overall size, so a long string does not hurt:
|
// this does not allow the label to control the overall size, so a long string does not hurt:
|
||||||
bar_frame->setSizePolicy (QSizePolicy::Ignored, QSizePolicy::Preferred);
|
bar_frame->setSizePolicy (QSizePolicy::Ignored, QSizePolicy::Preferred);
|
||||||
|
|
||||||
QHBoxLayout *layout = new QHBoxLayout (bar_frame);
|
QGridLayout *layout = new QGridLayout (bar_frame);
|
||||||
|
mp_layout = layout;
|
||||||
|
|
||||||
layout->setSpacing (4);
|
layout->setSpacing (4);
|
||||||
layout->setMargin (0);
|
layout->setMargin (0);
|
||||||
|
|
||||||
|
int col = 0;
|
||||||
|
|
||||||
if (! full_width) {
|
if (! full_width) {
|
||||||
layout->addStretch (1);
|
layout->addItem (new QSpacerItem (8, 8, QSizePolicy::Expanding, QSizePolicy::Expanding), 0, col, 1, 1);
|
||||||
|
layout->setColumnStretch (col++, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_label = new QLabel (bar_frame);
|
mp_label = new QLabel (bar_frame);
|
||||||
layout->addWidget (mp_label);
|
layout->addWidget (mp_label, 0, col++, 1, 1);
|
||||||
|
|
||||||
layout->addSpacing (8);
|
layout->addItem (new QSpacerItem (8, 8, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, col++, 1, 1);
|
||||||
|
|
||||||
QFrame *progress_bar_frame = new QFrame (bar_frame);
|
QFrame *progress_bar_frame = new QFrame (bar_frame);
|
||||||
progress_bar_frame->setFrameStyle (QFrame::Box | QFrame::Plain);
|
progress_bar_frame->setFrameStyle (QFrame::Box | QFrame::Plain);
|
||||||
progress_bar_frame->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Preferred);
|
progress_bar_frame->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||||
layout->addWidget (progress_bar_frame, 2);
|
layout->addWidget (progress_bar_frame, 0, col, 1, 1);
|
||||||
|
m_widget_col = col;
|
||||||
|
layout->setColumnStretch(col++, 2);
|
||||||
|
|
||||||
QHBoxLayout *pbf_layout = new QHBoxLayout (progress_bar_frame);
|
QHBoxLayout *pbf_layout = new QHBoxLayout (progress_bar_frame);
|
||||||
progress_bar_frame->setLayout (pbf_layout);
|
progress_bar_frame->setLayout (pbf_layout);
|
||||||
@@ -166,19 +173,47 @@ ProgressWidget::ProgressWidget (ProgressReporter *pr, QWidget *parent, bool full
|
|||||||
mp_progress_bar = new ProgressBarWidget (progress_bar_frame);
|
mp_progress_bar = new ProgressBarWidget (progress_bar_frame);
|
||||||
pbf_layout->addWidget (mp_progress_bar);
|
pbf_layout->addWidget (mp_progress_bar);
|
||||||
|
|
||||||
layout->addSpacing (8);
|
layout->addItem (new QSpacerItem (8, 8, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, col++, 1, 1);
|
||||||
|
|
||||||
mp_cancel_button = new QToolButton (bar_frame);
|
mp_cancel_button = new QToolButton (bar_frame);
|
||||||
mp_cancel_button->setText (QObject::tr ("Cancel"));
|
mp_cancel_button->setText (QObject::tr ("Cancel"));
|
||||||
layout->addWidget (mp_cancel_button);
|
layout->addWidget (mp_cancel_button, 0, col++, 1, 1);
|
||||||
|
|
||||||
if (! full_width) {
|
if (! full_width) {
|
||||||
layout->addStretch (1);
|
layout->addItem (new QSpacerItem (8, 8, QSizePolicy::Expanding, QSizePolicy::Expanding), 0, col, 1, 1);
|
||||||
|
layout->setColumnStretch (col++, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect (mp_cancel_button, SIGNAL (clicked ()), this, SLOT (signal_break ()));
|
connect (mp_cancel_button, SIGNAL (clicked ()), this, SLOT (signal_break ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWidget *
|
||||||
|
ProgressWidget::get_widget () const
|
||||||
|
{
|
||||||
|
return mp_widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ProgressWidget::add_widget (QWidget *widget)
|
||||||
|
{
|
||||||
|
remove_widget ();
|
||||||
|
|
||||||
|
if (widget) {
|
||||||
|
mp_widget = widget;
|
||||||
|
widget->setParent(this);
|
||||||
|
mp_layout->addWidget (widget, 1, m_widget_col, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ProgressWidget::remove_widget ()
|
||||||
|
{
|
||||||
|
if (mp_widget) {
|
||||||
|
delete mp_widget;
|
||||||
|
mp_widget = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ProgressWidget::set_can_cancel (bool f)
|
ProgressWidget::set_can_cancel (bool f)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
class QToolButton;
|
class QToolButton;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QToolButton;
|
class QToolButton;
|
||||||
|
class QGridLayout;
|
||||||
|
|
||||||
namespace lay
|
namespace lay
|
||||||
{
|
{
|
||||||
@@ -52,6 +53,9 @@ public:
|
|||||||
void set_text (const std::string &text);
|
void set_text (const std::string &text);
|
||||||
void set_value (double v, const std::string &value);
|
void set_value (double v, const std::string &value);
|
||||||
void set_can_cancel (bool f);
|
void set_can_cancel (bool f);
|
||||||
|
void add_widget (QWidget *widget);
|
||||||
|
void remove_widget ();
|
||||||
|
QWidget *get_widget () const;
|
||||||
|
|
||||||
QSize sizeHint () const;
|
QSize sizeHint () const;
|
||||||
|
|
||||||
@@ -61,6 +65,9 @@ public slots:
|
|||||||
private:
|
private:
|
||||||
QLabel *mp_label;
|
QLabel *mp_label;
|
||||||
ProgressBarWidget *mp_progress_bar;
|
ProgressBarWidget *mp_progress_bar;
|
||||||
|
QWidget *mp_widget;
|
||||||
|
int m_widget_col;
|
||||||
|
QGridLayout *mp_layout;
|
||||||
QToolButton *mp_cancel_button;
|
QToolButton *mp_cancel_button;
|
||||||
ProgressReporter *mp_pr;
|
ProgressReporter *mp_pr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
#include "tlException.h"
|
#include "tlException.h"
|
||||||
#include "tlTimer.h"
|
#include "tlTimer.h"
|
||||||
|
|
||||||
|
class QWidget;
|
||||||
|
|
||||||
namespace tl
|
namespace tl
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -120,6 +122,19 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual double value () const = 0;
|
virtual double value () const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a widget that renders the progress graphically
|
||||||
|
*
|
||||||
|
* The widget is not the progress bar - the progress bar is always shown.
|
||||||
|
* This method returns 0 if no graphical representation is required.
|
||||||
|
*/
|
||||||
|
virtual QWidget *progress_widget () const { return 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Renders the progress on the widget that was created by progress_widget
|
||||||
|
*/
|
||||||
|
virtual void render_progress (QWidget * /*widget*/) const { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set a value indicating whether the operation can be cancelled
|
* @brief Set a value indicating whether the operation can be cancelled
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user