mirror of https://github.com/KLayout/klayout.git
Bugfix: XOR was segfaulting when the window was closed during run
This fix consists of multiple parts: * Actual closing of the window is deferred until excecution is over * weak pointers in XOR for view so the view can be destroyed with out not knowing * The "keep data" message is not shown when the application window was closed.
This commit is contained in:
parent
f1cfe207ff
commit
8b1e76ed0b
|
|
@ -117,7 +117,7 @@ public:
|
|||
{
|
||||
int w = int (m_tolerance_labels.size ()) * (m_column_width + m_spacing) + m_first_column_width;
|
||||
int col = std::max (1, width () / w);
|
||||
return QSize (w * col, (m_line_height + m_spacing) * ((int (m_layer_labels.size ()) + col - 1) / col) + m_font_height * 2 + m_spacing);
|
||||
return QSize (w * std::min (int (m_layer_labels.size ()), col), (m_line_height + m_spacing) * ((int (m_layer_labels.size ()) + col - 1) / col) + m_font_height * 2 + m_spacing);
|
||||
}
|
||||
|
||||
void set_results (double dbu, int nx, int ny, const std::map<std::pair<db::LayerProperties, db::Coord>, std::vector<std::vector<size_t> > > &results, const std::map<db::LayerProperties, size_t> &count_per_layer, const std::vector<db::Coord> &tolerances)
|
||||
|
|
@ -261,7 +261,7 @@ public:
|
|||
bool ellipsis = false;
|
||||
|
||||
int visible_lines = std::max (1, (height () - m_font_height * 2 - m_spacing) / (m_line_height + m_spacing));
|
||||
int columns = std::max (1, width () / std::max (1, szh.width ()));
|
||||
int columns = std::min (std::max (1, width () / std::max (1, szh.width ())), int (m_layer_labels.size ()));
|
||||
|
||||
int x0 = std::max (0, (width () - szh.width () * columns) / 2);
|
||||
int visible_columns = std::max (0, (width () - m_first_column_width + 20) / (m_column_width + m_spacing));
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "layCellView.h"
|
||||
#include "layLayoutView.h"
|
||||
#include "layApplication.h"
|
||||
#include "layMainWindow.h"
|
||||
|
||||
#include "ui_XORToolDialog.h"
|
||||
|
||||
|
|
@ -1371,7 +1372,7 @@ XORToolDialog::run_xor ()
|
|||
}
|
||||
|
||||
if (job.has_error ()) {
|
||||
if (output_mode == OMMarkerDatabase) {
|
||||
if (mp_view && output_mode == OMMarkerDatabase) {
|
||||
mp_view->remove_rdb (rdb_index);
|
||||
}
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Errors occured during processing. First error message says:\n")) + job.error_messages ().front ());
|
||||
|
|
@ -1382,26 +1383,34 @@ XORToolDialog::run_xor ()
|
|||
if (was_cancelled && output_mode == OMMarkerDatabase) {
|
||||
// If the output mode is database, ask whether to keep the data collected so far.
|
||||
// If the answer is yes, remove the RDB.
|
||||
QMessageBox msgbox (QMessageBox::Question,
|
||||
QObject::tr ("Keep Data For Cancelled Job"),
|
||||
QObject::tr ("The job has been cancelled. Keep the data collected so far?"),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if (msgbox.exec () == QMessageBox::No) {
|
||||
mp_view->remove_rdb (rdb_index);
|
||||
output_mode = OMNone;
|
||||
}
|
||||
// Don't ask if the application has exit (window was closed)
|
||||
if (lay::Application::instance ()->main_window () && !lay::Application::instance ()->main_window ()->exited ()) {
|
||||
QMessageBox msgbox (QMessageBox::Question,
|
||||
QObject::tr ("Keep Data For Cancelled Job"),
|
||||
QObject::tr ("The job has been cancelled. Keep the data collected so far?"),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if (msgbox.exec () == QMessageBox::No) {
|
||||
if (mp_view) {
|
||||
mp_view->remove_rdb (rdb_index);
|
||||
}
|
||||
output_mode = OMNone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (output_mode == OMMarkerDatabase) {
|
||||
mp_view->open_rdb_browser (rdb_index, cv_index_a);
|
||||
}
|
||||
if (mp_view) {
|
||||
|
||||
mp_view->update_content ();
|
||||
if (output_mode == OMMarkerDatabase) {
|
||||
mp_view->open_rdb_browser (rdb_index, cv_index_a);
|
||||
}
|
||||
|
||||
if (output_mode == OMNewLayout && output_cell != 0 && output_cv >= 0) {
|
||||
mp_view->select_cell (output_cell->cell_index (), output_cv);
|
||||
mp_view->update_content ();
|
||||
|
||||
if (output_mode == OMNewLayout && output_cell != 0 && output_cv >= 0) {
|
||||
mp_view->select_cell (output_cell->cell_index (), output_cv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
#include <QDialog>
|
||||
|
||||
#include "tlObject.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class XORToolDialog;
|
||||
|
|
@ -71,7 +73,7 @@ protected slots:
|
|||
|
||||
private:
|
||||
Ui::XORToolDialog *mp_ui;
|
||||
lay::LayoutView *mp_view;
|
||||
tl::weak_ptr<lay::LayoutView> mp_view;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@
|
|||
#include "tlTimer.h"
|
||||
#include "tlLog.h"
|
||||
#include "tlAssert.h"
|
||||
#include "tlDeferredExecution.h"
|
||||
#include "tlStream.h"
|
||||
#include "tlExceptions.h"
|
||||
#include "dbMemStatistics.h"
|
||||
|
|
@ -451,7 +450,8 @@ MainWindow::MainWindow (QApplication *app, const char *name)
|
|||
m_disable_tab_selected (false),
|
||||
m_exited (false),
|
||||
dm_do_update_menu (this, &MainWindow::do_update_menu),
|
||||
m_grid_micron (0.001),
|
||||
dm_exit (this, &MainWindow::exit),
|
||||
m_grid_micron (0.001),
|
||||
m_default_grids_updated (true),
|
||||
m_new_cell_window_size (2.0),
|
||||
m_new_layout_current_panel (false),
|
||||
|
|
@ -691,7 +691,7 @@ MainWindow::MainWindow (QApplication *app, const char *name)
|
|||
connect (&m_file_changed_timer, SIGNAL (timeout ()), this, SLOT (file_changed_timer()));
|
||||
m_file_changed_timer.setSingleShot (true);
|
||||
|
||||
// install timer for menu update
|
||||
// install timer for menu update a
|
||||
connect (&m_menu_update_timer, SIGNAL (timeout ()), this, SLOT (update_action_states ()));
|
||||
m_menu_update_timer.setSingleShot (false);
|
||||
m_menu_update_timer.start (200);
|
||||
|
|
@ -1837,8 +1837,30 @@ void
|
|||
MainWindow::exit ()
|
||||
{
|
||||
m_exited = true;
|
||||
do_close ();
|
||||
QMainWindow::close ();
|
||||
|
||||
// If there is a operation ongoing, request a break and delay execution of the exit operation.
|
||||
if (mp_pr && mp_pr->is_busy ()) {
|
||||
mp_pr->signal_break ();
|
||||
dm_exit ();
|
||||
return;
|
||||
}
|
||||
|
||||
// We also don't exit if a dialog is shown (deferred execution may be called from
|
||||
// the dialog's exec loop).
|
||||
if (QApplication::activeModalWidget ()) {
|
||||
dm_exit ();
|
||||
return;
|
||||
}
|
||||
|
||||
// Only after other operation has finished we ask whether to save and close eventually
|
||||
if (can_close ()) {
|
||||
|
||||
do_close ();
|
||||
QMainWindow::close ();
|
||||
|
||||
emit closed ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -1950,23 +1972,12 @@ void
|
|||
MainWindow::closeEvent (QCloseEvent *event)
|
||||
{
|
||||
if (! m_exited) {
|
||||
|
||||
BEGIN_PROTECTED
|
||||
|
||||
if (mp_pr) {
|
||||
mp_pr->signal_break ();
|
||||
}
|
||||
|
||||
if (! can_close ()) {
|
||||
event->ignore ();
|
||||
} else {
|
||||
do_close ();
|
||||
emit closed ();
|
||||
}
|
||||
|
||||
exit ();
|
||||
END_PROTECTED
|
||||
|
||||
}
|
||||
|
||||
event->ignore ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -2074,10 +2085,7 @@ void
|
|||
MainWindow::cm_exit ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
if (can_close ()) {
|
||||
// actually exit.
|
||||
exit ();
|
||||
}
|
||||
exit ();
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "tlException.h"
|
||||
#include "tlDeferredExecution.h"
|
||||
#include "tlObjectCollection.h"
|
||||
#include "tlDeferredExecution.h"
|
||||
#include "gsi.h"
|
||||
|
||||
class QTabBar;
|
||||
|
|
@ -910,6 +911,7 @@ private:
|
|||
bool m_disable_tab_selected;
|
||||
bool m_exited;
|
||||
tl::DeferredMethod<MainWindow> dm_do_update_menu;
|
||||
tl::DeferredMethod<MainWindow> dm_exit;
|
||||
QTimer m_message_timer;
|
||||
QTimer m_file_changed_timer;
|
||||
QTimer m_menu_update_timer;
|
||||
|
|
|
|||
Loading…
Reference in New Issue