mirror of https://github.com/KLayout/klayout.git
[consider merging] Reader format error with details showing dump or text
This commit is contained in:
parent
49fe816294
commit
46364c2420
|
|
@ -91,7 +91,13 @@ Reader::Reader (tl::InputStream &stream)
|
|||
}
|
||||
|
||||
if (! mp_actual_reader) {
|
||||
throw db::ReaderException (tl::to_string (tr ("Stream has unknown format: ")) + stream.source ());
|
||||
|
||||
m_stream.reset ();
|
||||
std::string head = m_stream.read_all (4000);
|
||||
bool has_more (m_stream.get (1) != 0);
|
||||
|
||||
throw db::ReaderUnknownFormatException (tl::to_string (tr ("Stream has unknown format: ")) + stream.source (), head, has_more);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,35 @@ public:
|
|||
{ }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A class representing the "unknown format" reader error
|
||||
*
|
||||
* The purpose of this class is supply the header bytes of the
|
||||
* data stream for analysis.
|
||||
*/
|
||||
class DB_PUBLIC ReaderUnknownFormatException
|
||||
: public ReaderException
|
||||
{
|
||||
public:
|
||||
ReaderUnknownFormatException (const std::string &msg, const std::string &data, bool has_more)
|
||||
: ReaderException (msg), m_data (data), m_has_more (has_more)
|
||||
{ }
|
||||
|
||||
const std::string &data () const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
bool has_more () const
|
||||
{
|
||||
return m_has_more;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_data;
|
||||
bool m_has_more;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Joins layer names into a single, combined layer
|
||||
* @param s The first layer name and output
|
||||
|
|
|
|||
|
|
@ -0,0 +1,278 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ReaderErrorForm</class>
|
||||
<widget class="QDialog" name="ReaderErrorForm">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>496</width>
|
||||
<height>297</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Script Error</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="2" column="3">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>411</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>411</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="msg_label">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" rowspan="3">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>71</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="3">
|
||||
<widget class="QLabel" name="icon_label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>X</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="3">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>71</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="details_frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="details_text">
|
||||
<property name="lineWrapMode">
|
||||
<enum>QTextEdit::NoWrap</enum>
|
||||
</property>
|
||||
<property name="html">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Liberation Mono';"><br /></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="details_pb">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string> Details >> </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>341</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="ok_button">
|
||||
<property name="text">
|
||||
<string>OK</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>ok_button</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>ReaderErrorForm</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>457</x>
|
||||
<y>330</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>271</x>
|
||||
<y>177</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
|
|
@ -31,6 +31,7 @@ HEADERS = \
|
|||
layProgressWidget.h \
|
||||
layResourceHelpProvider.h \
|
||||
layRuntimeErrorForm.h \
|
||||
layReaderErrorForm.h \
|
||||
laySearchReplaceConfigPage.h \
|
||||
laySearchReplaceDialog.h \
|
||||
laySearchReplacePropertiesWidgets.h \
|
||||
|
|
@ -87,6 +88,7 @@ FORMS = \
|
|||
ReplacePropertiesShape.ui \
|
||||
ReplacePropertiesText.ui \
|
||||
RuntimeErrorForm.ui \
|
||||
ReaderErrorForm.ui \
|
||||
SearchPropertiesBox.ui \
|
||||
SearchPropertiesInstance.ui \
|
||||
SearchPropertiesPath.ui \
|
||||
|
|
@ -139,6 +141,7 @@ SOURCES = \
|
|||
layProgressWidget.cc \
|
||||
layResourceHelpProvider.cc \
|
||||
layRuntimeErrorForm.cc \
|
||||
layReaderErrorForm.cc \
|
||||
laySearchReplaceConfigPage.cc \
|
||||
laySearchReplaceDialog.cc \
|
||||
laySearchReplacePlugin.cc \
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "layVersion.h"
|
||||
#include "laySignalHandler.h"
|
||||
#include "layRuntimeErrorForm.h"
|
||||
#include "layReaderErrorForm.h"
|
||||
#include "layProgress.h"
|
||||
#include "layTextProgress.h"
|
||||
#include "layBackgroundAwareTreeStyle.h"
|
||||
|
|
@ -106,6 +107,7 @@ static void ui_exception_handler_tl (const tl::Exception &ex, QWidget *parent)
|
|||
const tl::ExitException *gsi_exit = dynamic_cast <const tl::ExitException *> (&ex);
|
||||
const tl::BreakException *gsi_break = dynamic_cast <const tl::BreakException *> (&ex);
|
||||
const tl::ScriptError *gsi_excpt = dynamic_cast <const tl::ScriptError *> (&ex);
|
||||
const db::ReaderUnknownFormatException *reader_excpt = dynamic_cast <const db::ReaderUnknownFormatException *> (&ex);
|
||||
|
||||
if (gsi_exit || gsi_break) {
|
||||
// exit and break exceptions are not shown - they are issued when a script is aborted or
|
||||
|
|
@ -131,11 +133,19 @@ static void ui_exception_handler_tl (const tl::Exception &ex, QWidget *parent)
|
|||
error_dialog.exec ();
|
||||
|
||||
} else {
|
||||
|
||||
tl::error << ex.msg ();
|
||||
if (! parent) {
|
||||
parent = QApplication::activeWindow () ? QApplication::activeWindow () : lay::MainWindow::instance ();
|
||||
}
|
||||
QMessageBox::critical (parent, QObject::tr ("Error"), tl::to_qstring (ex.msg ()));
|
||||
|
||||
if (reader_excpt) {
|
||||
lay::ReaderErrorForm error_dialog (parent, "reader_error_form", reader_excpt);
|
||||
error_dialog.exec ();
|
||||
} else {
|
||||
QMessageBox::critical (parent, QObject::tr ("Error"), tl::to_qstring (ex.msg ()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,123 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2022 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "layReaderErrorForm.h"
|
||||
#include "layQtTools.h"
|
||||
#include "dbReader.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
static bool is_text (const std::string &s)
|
||||
{
|
||||
for (std::string::const_iterator i = s.begin (); i != s.end (); ++i) {
|
||||
unsigned char uc = (unsigned char) *i;
|
||||
if (uc < 32 && uc != '\t' && uc != '\r' && uc != '\n') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string format_hex_dump (const std::string &s)
|
||||
{
|
||||
const int bytes_per_line = 16;
|
||||
|
||||
std::string hex_dump;
|
||||
// Some rough estimate of the capacity
|
||||
hex_dump.reserve ((s.size () / bytes_per_line + 1) * (8 + bytes_per_line * 4) + 100);
|
||||
|
||||
const char *ce = s.c_str () + s.size ();
|
||||
for (const char *c = s.c_str (); c + bytes_per_line <= ce; c += bytes_per_line) {
|
||||
|
||||
hex_dump += tl::sprintf ("%04x ", c - s.c_str ());
|
||||
for (int i = 0; i < bytes_per_line; ++i) {
|
||||
hex_dump += tl::sprintf ("%02x ", (unsigned char) c [i]);
|
||||
}
|
||||
hex_dump += " ";
|
||||
for (int i = 0; i < bytes_per_line; ++i) {
|
||||
unsigned char uc = (unsigned char) c[i];
|
||||
hex_dump += (uc < 32 || uc >= 128) ? '.' : c[i];
|
||||
}
|
||||
|
||||
hex_dump += "\n";
|
||||
|
||||
}
|
||||
|
||||
return hex_dump;
|
||||
}
|
||||
|
||||
ReaderErrorForm::ReaderErrorForm (QWidget *parent, const char *name, const db::ReaderUnknownFormatException *error)
|
||||
: QDialog (parent), Ui::ReaderErrorForm ()
|
||||
{
|
||||
setObjectName (QString::fromUtf8 (name));
|
||||
|
||||
Ui::ReaderErrorForm::setupUi (this);
|
||||
|
||||
msg_label->setText (tl::to_qstring (error->basic_msg ()));
|
||||
|
||||
if (is_text (error->data ())) {
|
||||
details_text->setText (tl::to_qstring (error->msg () + "\n\n" + error->data () + (error->has_more () ? "..." : "")));
|
||||
} else {
|
||||
details_text->setText (tl::to_qstring (error->msg () + "\n\n" + format_hex_dump (error->data ()) + (error->has_more () ? "..." : "")));
|
||||
}
|
||||
|
||||
details_text->setFont (lay::monospace_font ());
|
||||
details_frame->hide ();
|
||||
|
||||
// "borrow" the error pixmap from the message box
|
||||
QMessageBox *mb = new QMessageBox (QMessageBox::Critical, QString (), QString ());
|
||||
QPixmap error_icon = mb->iconPixmap ();
|
||||
delete mb;
|
||||
icon_label->setPixmap (error_icon);
|
||||
|
||||
connect (details_pb, SIGNAL (clicked ()), this, SLOT (show_details ()));
|
||||
|
||||
resize (size ().width (), 50);
|
||||
}
|
||||
|
||||
void
|
||||
ReaderErrorForm::show_details ()
|
||||
{
|
||||
QString t (details_pb->text ());
|
||||
if (details_frame->isVisible ()) {
|
||||
details_frame->hide ();
|
||||
t.replace (QString::fromUtf8 ("<<"), QString::fromUtf8 (">>"));
|
||||
// It looks like the minimum size is set to a too large value internally.
|
||||
// Resetting it helps to keep a small-as-possible dialog size.
|
||||
setMinimumSize (QSize (0, 0));
|
||||
resize (size ().width (), 0);
|
||||
} else {
|
||||
details_frame->show ();
|
||||
t.replace (QString::fromUtf8 (">>"), QString::fromUtf8 ("<<"));
|
||||
resize (size ().width (), sizeHint ().height ());
|
||||
}
|
||||
details_pb->setText (t);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2022 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_rbaReaderErrorForm
|
||||
#define HDR_rbaReaderErrorForm
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include "ui_ReaderErrorForm.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
class ReaderUnknownFormatException;
|
||||
}
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
class ReaderErrorForm
|
||||
: public QDialog, private Ui::ReaderErrorForm
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ReaderErrorForm (QWidget *parent, const char *name, const db::ReaderUnknownFormatException *error);
|
||||
|
||||
public slots:
|
||||
void show_details ();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue