Cleanly get rid of PyQt dependency.

* New: Hurricane::ErrorWidget, new widget exported to Python to replace
    helpers.io.ErrorWidget.
* New: Hurricane::AboutWindow, new window exported to Python to replace
    cumulus/plugins.aboutwindow.AboutWidget.
This commit is contained in:
Jean-Paul Chaput 2022-11-02 00:21:00 +01:00
parent 13795bec48
commit 8c182672dd
14 changed files with 710 additions and 287 deletions

View File

@ -19,157 +19,12 @@ import os
import os.path
import re
import traceback
pyQtIsEnabled = True
try:
from PyQt4.QtCore import Qt
from PyQt4.QtGui import QSizePolicy
from PyQt4.QtGui import QDialog
from PyQt4.QtGui import QPalette
from PyQt4.QtGui import QColor
from PyQt4.QtGui import QFont
from PyQt4.QtGui import QFontMetrics
from PyQt4.QtGui import QWidget
from PyQt4.QtGui import QFrame
from PyQt4.QtGui import QLabel
from PyQt4.QtGui import QPixmap
from PyQt4.QtGui import QPushButton
from PyQt4.QtGui import QTextEdit
from PyQt4.QtGui import QVBoxLayout
from PyQt4.QtGui import QHBoxLayout
from PyQt4.QtGui import QAction
from PyQt4.QtGui import QKeySequence
except Exception as e:
try:
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QSizePolicy
from PyQt5.QtWidgets import QDialog
from PyQt5.QtGui import QPalette
from PyQt5.QtGui import QColor
from PyQt5.QtGui import QFont
from PyQt5.QtGui import QFontMetrics
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import QFrame
from PyQt5.QtWidgets import QLabel
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QTextEdit
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QHBoxLayout
from PyQt5.QtWidgets import QAction
from PyQt5.QtGui import QKeySequence
except Exception:
print( '[WARNING] helpers.io, neither PyQt4 nor PyQt5 is available, disabling ErrorWidget.' )
pyQtIsEnabled = False
import Cfg
import helpers
from Hurricane import UpdateSession
import Viewer
# -------------------------------------------------------------------
# Class : "ErrorWidget".
def getErrorWidget ():
if pyQtIsEnabled:
class ErrorWidget ( QDialog ):
def __init__ ( self, e ):
QWidget.__init__ ( self, None )
self.setWindowTitle( 'Error' )
message = QLabel( e.getLinesAsString() )
message.setAlignment( Qt.AlignLeft )
message.setFont( QFont('Courier',10,QFont.Bold) )
error = QLabel( '[ERROR]' )
error.setAlignment( Qt.AlignLeft )
font = error.font()
font.setWeight( QFont.Bold )
error.setFont( font )
self._tryCont = QPushButton()
self._tryCont.setSizePolicy( QSizePolicy.Fixed, QSizePolicy.Fixed )
self._tryCont.setText ( 'Try to continue' )
self._abort = QPushButton()
self._abort.setSizePolicy( QSizePolicy.Fixed, QSizePolicy.Fixed )
self._abort.setText ( 'Abort' )
self._abort.setDefault ( True )
traceFont = QFont('Courier',10,QFont.Normal)
lineHeight = QFontMetrics( traceFont ).height()
traceText = helpers.textStackTrace( e.trace, False, e.scriptPath )
lineCount = traceText.count( '\n' ) + 2
minimumWidth = 400
if Viewer.Graphics.isHighDpi(): minimumWidth = 2100
self._trace = QTextEdit()
self._trace.setReadOnly ( True );
self._trace.setLineWrapMode( QTextEdit.NoWrap );
self._trace.setMinimumSize ( minimumWidth, lineCount*lineHeight );
self._trace.setFont ( traceFont )
self._trace.setText ( traceText )
buttonLayout = QHBoxLayout()
buttonLayout.addStretch( 1 )
buttonLayout.addWidget ( self._tryCont )
buttonLayout.addStretch( 1 )
buttonLayout.addWidget ( self._abort )
buttonLayout.addStretch( 1 )
vLayout = QVBoxLayout()
vLayout.addWidget ( error )
vLayout.addStretch( 1 )
vLayout.addWidget ( message )
vLayout.addStretch( 1 )
vLayout.addWidget ( self._trace )
vLayout.addStretch( 1 )
vLayout.addLayout ( buttonLayout )
pixmapWidth = 150
if not Viewer.Graphics.isHighDpi(): pixmapWidth = 70
pixmap = QPixmap( ':/images/angry-birds-red.png' )
pixmap = pixmap.scaledToWidth( pixmapWidth )
icon = QLabel()
icon.setPixmap( pixmap )
hLayout = QHBoxLayout()
hLayout.addWidget( icon )
hLayout.addLayout( vLayout )
self.setLayout( hLayout )
self._tryCont.clicked.connect( self.accept )
self._abort .clicked.connect( self.reject )
self._exitAction = QAction( '&Exit', self )
self._exitAction.setStatusTip( 'Exit Coriolis' )
self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
self._exitAction.triggered.connect( self.reject )
self.addAction( self._exitAction )
self._closeAction = QAction( '&Close', self )
self._closeAction.setStatusTip( 'Try to continue' )
self._closeAction.setShortcut ( QKeySequence('CTRL+W') )
self._closeAction.triggered.connect( self.reject )
self.addAction( self._closeAction )
return
def closeEvent ( self, event ):
if not pyQtIsEnabled: return
self.setResult( QDialog.Rejected )
event.accept()
return
else:
ErrorWidget = None
return ErrorWidget
# -------------------------------------------------------------------
# Class : "ErrorMessage".
@ -247,10 +102,8 @@ class ErrorMessage ( Exception ):
e = ErrorMessage( code, *arguments )
if not Viewer.Graphics.get().isEnabled():
raise e
classErrorWidget = getErrorWidget()
if not classErrorWidget:
raise e
tryCont = ErrorWidget( e ).exec_()
tryCont = Viewer.ErrorWidget.run( e.getLinesAsString()
, helpers.textStackTrace( e.trace, False, e.scriptPath ))
if not tryCont: raise e
return
@ -269,11 +122,10 @@ def catch ( errorObject ):
em.trace = traceback.extract_tb( sys.exc_info()[2] )
#em.scriptPath = __file__
print( em )
print( helpers.textStackTrace( em.trace, True, em.scriptPath ) )
print( helpers.textStackTrace( em.trace, True, em.scriptPath ))
if Viewer.Graphics.get().isEnabled():
classErrorWidget = getErrorWidget()
if classErrorWidget:
tryCont = classErrorWidget( em ).exec_()
Viewer.ErrorWidget.run( em.getLinesAsString()
, helpers.textStackTrace( em.trace, False, em.scriptPath ))
if UpdateSession.getStackSize() > 0: UpdateSession.close()
return

View File

@ -15,39 +15,6 @@
import sys
import traceback
pyQtIsEnabled = True
try:
from PyQt4.QtCore import Qt
from PyQt4.QtCore import QEventLoop
from PyQt4.QtGui import QDialog
from PyQt4.QtGui import QPalette
from PyQt4.QtGui import QColor
from PyQt4.QtGui import QFont
from PyQt4.QtGui import QWidget
from PyQt4.QtGui import QFrame
from PyQt4.QtGui import QLabel
from PyQt4.QtGui import QVBoxLayout
from PyQt4.QtGui import QAction
from PyQt4.QtGui import QKeySequence
from PyQt4.QtGui import QApplication
except:
try:
from PyQt5.QtCore import Qt
from PyQt5.QtCore import QEventLoop
from PyQt5.QtWidgets import QDialog
from PyQt5.QtGui import QPalette
from PyQt5.QtGui import QColor
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import QFrame
from PyQt5.QtWidgets import QLabel
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QAction
from PyQt5.QtGui import QKeySequence
from PyQt5.QtWidgets import QApplication
except:
print( '[WARNING] AboutWindow: Neither PyQt4 nor PyQt5 is available, disabling AboutWidget.' )
pyQtIsEnabled = False
import Viewer
import helpers
from helpers.io import ErrorMessage
@ -55,98 +22,6 @@ from helpers.io import WarningMessage
import plugins
# --------------------------------------------------------------------
# Class : "AboutWidget".
def getAboutWidget ():
aboutText = 'Coriolis CAD System 1.0 . . . . . . . . . . . . . . ccb 1.0\n' \
'Copyright (c) 2008-2022 . . . . . . . . Sorbonne Université\n' \
'Authors . . . . . . . . . . . . . . . . Christophe Alexandre\n' \
' . . . . . . . . . . . . . . . . . . Sophie Belloeil\n' \
' . . . . . . . . . . . . . . . . . . Jean-Paul Chaput\n' \
' . . . . . . . . . . . . . . . . . . . Damien Dupuis\n' \
' . . . . . . . . . . . . . . . . . . . Remy Escassut\n' \
' . . . . . . . . . . . . . . . . . . Christian Masson\n' \
'E-Mail . . . . . . . . . . . . . . Jean-Paul.Chaput@lip6.fr'
if pyQtIsEnabled:
class AboutWidget ( QDialog ):
def __init__ ( self, parent=None ):
QWidget.__init__ ( self, parent )
#self.setFixedSize( 500, 400 )
#self.setStyleSheet( 'background-color: #ffffdd;' )
topLine = QFrame()
topLine.setFrameShape( QFrame.HLine )
topLine.setLineWidth ( 2 )
botLine = QFrame()
botLine.setFrameShape( QFrame.HLine )
botLine.setLineWidth ( 2 )
title = QLabel( 'CGT' )
title.setAlignment( Qt.AlignCenter )
font = title.font()
font.setPointSize( 72 )
font.setWeight ( QFont.Bold )
title.setFont( font )
subTitle = QLabel( 'Coriolis Graphical Interface' )
subTitle.setAlignment( Qt.AlignCenter )
subTitle.setFont( QFont('Courier',10,QFont.Bold) )
authors = QLabel( aboutText )
authors.setAlignment( Qt.AlignCenter )
authors.setFont( QFont('Courier',10,QFont.Bold) )
vLayout = QVBoxLayout()
vLayout.addStretch(10)
vLayout.addWidget( topLine )
vLayout.addWidget( title )
vLayout.addStretch(1)
vLayout.addWidget( subTitle )
vLayout.addWidget( authors )
vLayout.addStretch(1)
vLayout.addWidget( botLine )
vLayout.addStretch(10)
frame = QFrame()
frame.setFrameShape ( QFrame.Box )
frame.setFrameShadow( QFrame.Sunken )
frame.setLayout ( vLayout )
frame.setLineWidth ( 1 )
vLayout = QVBoxLayout()
vLayout.addWidget( frame )
self.setLayout( vLayout )
self._exitAction = QAction( '&Exit', self )
self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' )
self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
#self._exitAction.triggered.connect( QApplication.closeAllWindows )
self._exitAction.triggered.connect( self.reject )
self.addAction( self._exitAction )
self._closeAction = QAction( '&Close', self )
self._closeAction.setStatusTip( 'Close the About Window' )
self._closeAction.setShortcut ( QKeySequence('CTRL+A') )
#self._closeAction.triggered.connect( self.close )
self._closeAction.triggered.connect( self.accept )
self.addAction( self._closeAction )
else:
class AboutWidget ( object ):
def __init__ ( self ):
self.aboutText = aboutText
return AboutWidget
# --------------------------------------------------------------------
# Plugin hook functions, unicornHook:menus, ScritMain:call
@ -162,14 +37,7 @@ def unicornHook ( **kw ):
def scriptMain ( **kw ):
try:
#helpers.setTraceLevel( 550 )
aboutWidget = getAboutWidget()()
if not pyQtIsEnabled:
print( aboutWidget.aboutText )
return True
answer = aboutWidget.exec_()
print( 'answer:', answer )
if not answer: return True
Viewer.AboutWindow.show()
except Exception as e:
helpers.io.catch( e )
sys.stdout.flush()

View File

@ -0,0 +1,141 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | V L S I B a c k e n d D a t a - B a s e |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./AboutWindow.cpp" |
// +-----------------------------------------------------------------+
#include <unistd.h>
#include <csignal>
#include <memory>
#include <QAction>
#include <QCloseEvent>
#include <QLabel>
#include <QPushButton>
#include <QCheckBox>
#include <QTextEdit>
#include <QScrollArea>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFrame>
#include <QFont>
#include <QFontMetrics>
#include "hurricane/TextTranslator.h"
#include "hurricane/viewer/Graphics.h"
#include "hurricane/viewer/AboutWindow.h"
namespace Hurricane {
bool AboutWindow::show ()
{
AboutWindow* abw = new AboutWindow();
return (abw->exec() != QDialog::Rejected);
}
AboutWindow::AboutWindow ( QWidget* parent )
: QDialog( parent )
{
setAttribute ( Qt::WA_DeleteOnClose );
setModal ( true );
setWindowTitle( tr("Coriolis About Window") );
setToolTip ( tr("Sorbonne Université Proudly Present") );
QString about = "Coriolis EDA System 0.x . . . . . . . . . . . . . . cgt 1.0\n"
"Copyright (c) 2008-2022 . . . . . . . . Sorbonne Université\n"
"Authors . . . . . . . . . . . . . . . . Christophe Alexandre\n"
" . . . . . . . . . . . . . . . . . . Sophie Belloeil\n"
" . . . . . . . . . . . . . . . . . . Jean-Paul Chaput\n"
" . . . . . . . . . . . . . . . . . . . Damien Dupuis\n"
" . . . . . . . . . . . . . . . . . . . Remy Escassut\n"
" . . . . . . . . . . . . . . . . . . Gabriel Gouvine\n"
" . . . . . . . . . . . . . . . . . . Christian Masson\n"
"E-Mail . . . . . . . . . . . . . . Jean-Paul.Chaput@lip6.fr";
QFrame* topLine = new QFrame ();
topLine->setFrameShape( QFrame::HLine );
topLine->setLineWidth ( 2 );
QFrame* botLine = new QFrame ();
botLine->setFrameShape( QFrame::HLine );
botLine->setLineWidth ( 2 );
QLabel* logo = new QLabel ();
logo->setAlignment ( Qt::AlignCenter );
logo->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::MinimumExpanding );
logo->setPixmap ( QPixmap(":/images/Coriolis-logo-white-4.png").scaledToWidth( Graphics::isHighDpi() ? 200 : 80 ) );
QLabel* title = new QLabel( "CGT" );
title->setAlignment( Qt::AlignCenter );
QFont font = title->font();
font.setPointSize( 72 );
font.setWeight ( QFont::Bold );
title->setFont( font );
QLabel* subTitle = new QLabel ( "Coriolis Graphical Interface" );
subTitle->setAlignment( Qt::AlignCenter );
subTitle->setFont( QFont( "Courier", 10, QFont::Bold ));
QLabel* authors = new QLabel( about );
authors->setAlignment( Qt::AlignCenter );
authors->setFont( QFont( "Courier", 10, QFont::Bold ));
QLabel* documentation = new QLabel( "<a href=\"http://coriolis.lip6.fr\">http://coriolis.lip6.fr</a>" );
documentation->setAlignment( Qt::AlignCenter );
documentation->setFont( QFont( "Courier", 10, QFont::Bold ));
QPushButton* thanksButton = new QPushButton ();
//thanksButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
thanksButton->setText ( tr("Thanks for flying Coriolis") );
QAction* closeAction = new QAction( tr("Close AboutWindow"), this );
closeAction->setStatusTip( tr("CloseWindow") );
closeAction->setShortcut ( QKeySequence(tr("CTRL+W")) );
QVBoxLayout* vLayout = new QVBoxLayout ();
vLayout->addStretch( 10 );
vLayout->addWidget( topLine );
vLayout->addWidget( logo );
vLayout->addWidget( title );
vLayout->addStretch( 1 );
vLayout->addWidget( subTitle );
vLayout->addWidget( authors );
vLayout->addStretch( 10 );
vLayout->addWidget( documentation );
vLayout->addStretch( 1 );
vLayout->addWidget( botLine );
vLayout->addStretch( 10 );
QFrame* frame = new QFrame ();
frame->setFrameShape ( QFrame::Box );
frame->setFrameShadow( QFrame::Sunken );
frame->setLayout ( vLayout );
frame->setLineWidth ( 1 );
QHBoxLayout* hLayout = new QHBoxLayout ();
//hLayout->addStretch( 1 );
hLayout->addWidget ( thanksButton, Qt::AlignCenter );
//hLayout->addStretch( 1 );
vLayout = new QVBoxLayout ();
vLayout->addWidget( frame );
vLayout->addLayout( hLayout );
setLayout( vLayout );
connect( thanksButton, SIGNAL(clicked ()), this, SLOT(accept()) );
connect( closeAction , SIGNAL(triggered()), this, SLOT(accept()) );
}
} // End of Hurricane Namespace.

View File

@ -20,6 +20,7 @@
hurricane/viewer/PaletteExtensionGoItem.h
hurricane/viewer/PaletteWidget.h
hurricane/viewer/GraphicsWidget.h
hurricane/viewer/ErrorWidget.h
hurricane/viewer/ExceptionWidget.h
hurricane/viewer/BreakpointWidget.h
hurricane/viewer/GotoWidget.h
@ -44,6 +45,7 @@
hurricane/viewer/DisplayFilterWidget.h
hurricane/viewer/ControllerWidget.h
hurricane/viewer/ScriptWidget.h
hurricane/viewer/AboutWindow.h
)
set( includes hurricane/viewer/ScreenUtilities.h
hurricane/viewer/DisplayStyle.h
@ -70,6 +72,8 @@
hurricane/viewer/PyHApplication.h
hurricane/viewer/PyGraphics.h
hurricane/viewer/PyCellViewer.h
hurricane/viewer/PyErrorWidget.h
hurricane/viewer/PyAboutWindow.h
hurricane/viewer/Script.h
)
set( cpps HApplication.cpp
@ -78,6 +82,7 @@
ColorScale.cpp
Graphics.cpp
GraphicsWidget.cpp
ErrorWidget.cpp
ExceptionWidget.cpp
BreakpointWidget.cpp
GotoWidget.cpp
@ -101,7 +106,7 @@
CellViewer.cpp
CellPrinter.cpp
CellImage.cpp
OpenBlobDialog.cpp
OpenBlobDialog.cpp
RecordModel.cpp
InspectorWidget.cpp
SelectionPopupModel.cpp
@ -120,6 +125,7 @@
ScriptWidget.cpp
DesignBlob.cpp
JsonConfiguration.cpp
AboutWindow.cpp
)
set( pyCpps PyHSVr.cpp
PyDrawingStyle.cpp
@ -129,6 +135,8 @@
PyGraphics.cpp
PyViewer.cpp
PyCellViewer.cpp
PyErrorWidget.cpp
PyAboutWindow.cpp
Script.cpp
)

View File

@ -17,5 +17,6 @@
<file>images/angry-birds-red.png</file>
<file>images/angry-birds-chuck.png</file>
<file>images/angry-birds-bomb.png</file>
<file>images/Coriolis-logo-white-4.png</file>
</qresource>
</RCC>

View File

@ -0,0 +1,186 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | V L S I B a c k e n d D a t a - B a s e |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./ErrorWidget.cpp" |
// +-----------------------------------------------------------------+
#include <unistd.h>
#include <csignal>
#include <memory>
#include <QCloseEvent>
#include <QLabel>
#include <QPushButton>
#include <QCheckBox>
#include <QTextEdit>
#include <QScrollArea>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFrame>
#include <QFont>
#include <QFontMetrics>
#include "hurricane/Bug.h"
#include "hurricane/Error.h"
#include "hurricane/Error.h"
#include "hurricane/TextTranslator.h"
#include "hurricane/viewer/Graphics.h"
#include "hurricane/viewer/ErrorWidget.h"
namespace Hurricane {
bool ErrorWidget::run ( const QString& message, const QString& trace )
{
ErrorWidget* ew = new ErrorWidget();
ew->setMessage( message );
if (not trace.isEmpty())
ew->setTrace( trace );
if (ew->exec() == QDialog::Rejected) {
cerr << "\n[BUG] A Python exception was catched:\n" << endl;
cerr << TextTranslator::toTextTranslator().translate( message.toStdString() ) << endl;
cerr << "\n[Backtrace]" << endl;
cerr << TextTranslator::toTextTranslator().translate( trace.toStdString() ) << endl;
return false;
}
return true;
}
ErrorWidget::ErrorWidget ( QWidget* parent )
: QDialog (parent)
, _header (new QLabel())
, _message (new QTextEdit())
, _trace (new QTextEdit())
{
setAttribute ( Qt::WA_DeleteOnClose );
setModal ( true );
setWindowTitle( tr("<A Python exception was raised>") );
setToolTip ( tr("Caramba! Encore rate!") );
//_header->setMinimumWidth( Graphics::isHighDpi() ? 1500 : 400 );
_header->setTextFormat ( Qt::RichText );
_header->setText ( "<b>[ERROR]</b>" );
QString labelBackground = _header->palette().color( _header->backgroundRole() ).name();
_message->setFrameStyle ( QFrame::NoFrame|QFrame::Plain );
_message->setStyleSheet ( QString("p, li { white-space: wrap; } * { background-color: %1 }").arg(labelBackground) );
_message->setTextInteractionFlags( Qt::TextSelectableByMouse );
_message->setAcceptRichText ( false );
_message->setLineWrapMode ( QTextEdit::NoWrap );
_message->setWordWrapMode ( QTextOption::NoWrap );
_message->setMinimumSize ( Graphics::isHighDpi() ? QSize(2500,200) : QSize(1000,100) );
//_message->setTextFormat ( Qt::RichText );
_message->setFont ( Graphics::getFixedFont(QFont::Normal,false,false) );
_message->setPlainText ( "Oups! I did it again!" );
_trace->setTextInteractionFlags ( Qt::TextBrowserInteraction );
_trace->setAcceptRichText ( true );
_trace->setStyleSheet ( "* { white-space: pre; }" );
_trace->setPlainText ( "<b>No program trace sets yet.</b>" );
_trace->setMinimumSize ( Graphics::isHighDpi() ? QSize(2500,1000) : QSize(1000,500) );
_trace->setFont ( Graphics::getFixedFont(QFont::Normal,false,false,-2) );
_trace->setLineWrapMode ( QTextEdit::FixedColumnWidth );
_trace->setLineWrapColumnOrWidth( 140 );
_trace->setSizePolicy ( QSizePolicy::Expanding, QSizePolicy::Expanding );
_trace->setSizeAdjustPolicy ( QAbstractScrollArea::AdjustToContents );
_trace->hide ();
QCheckBox* showTrace = new QCheckBox ();
showTrace->setText ( "Show Program Trace" );
showTrace->setChecked( false );
QLabel* leftMargin = new QLabel ();
leftMargin->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::MinimumExpanding );
leftMargin->setPixmap ( QPixmap(":/images/angry-birds-red.png").scaledToWidth( Graphics::isHighDpi() ? 200 : 80 ) );
leftMargin->setStyleSheet( "QLabel { background-color: #FF9999;"
" padding: 5px }" );
QPushButton* abortButton = new QPushButton ();
abortButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
abortButton->setText ( tr("Abort") );
QPushButton* contButton = new QPushButton ();
contButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
contButton->setText ( tr("Try to Continue") );
QFrame* separator = new QFrame ();
separator->setFrameShape ( QFrame::HLine );
separator->setFrameShadow( QFrame::Sunken );
QHBoxLayout* hLayout2 = new QHBoxLayout ();
hLayout2->addStretch( 1 );
hLayout2->addWidget ( contButton, Qt::AlignCenter );
hLayout2->addStretch( 4 );
hLayout2->addWidget ( abortButton, Qt::AlignCenter );
hLayout2->addStretch( 1 );
QVBoxLayout* vLayout1 = new QVBoxLayout ();
vLayout1->setContentsMargins ( 10, 10, 10, 10 );
vLayout1->setSpacing( 0 );
vLayout1->addWidget ( _header , 0, Qt::AlignLeft );
vLayout1->addWidget ( _message , 0, Qt::AlignLeft );
vLayout1->addWidget ( separator );
vLayout1->addWidget ( showTrace , 0, Qt::AlignLeft );
vLayout1->addWidget ( _trace , 0, Qt::AlignLeft );
vLayout1->addSpacing( 10 );
vLayout1->addLayout ( hLayout2 , Qt::AlignCenter );
QHBoxLayout* hLayout1 = new QHBoxLayout ();
//hLayout1->setSizeConstraint ( QLayout::SetFixedSize );
hLayout1->setContentsMargins( 0, 0, 0, 0 );
hLayout1->addWidget ( leftMargin );
hLayout1->addLayout ( vLayout1 );
setLayout ( hLayout1 );
//setMinimumSize ( QSize(400,150) );
//setSizePolicy ( QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding) );
setSizeGripEnabled( true );
connect( contButton , SIGNAL(clicked()) , this, SLOT(accept()) );
connect( abortButton, SIGNAL(clicked()) , this, SLOT(reject()) );
connect( showTrace , SIGNAL(stateChanged(int)), this, SLOT(_showTrace(int)) );
}
void ErrorWidget::closeEvent ( QCloseEvent* event )
{ event->ignore(); }
void ErrorWidget::setMessage ( const QString& message )
{
QString contents = message;
_header->setText ("<b>[ERROR]</b>");
_message->setPlainText( contents );
}
void ErrorWidget::setTrace ( const QString& where )
{
_trace->setPlainText( where );
_trace->setStyleSheet( "* { white-space: pre; }" );
//cerr << _trace->toHtml().toStdString() << endl;
}
void ErrorWidget::_showTrace ( int state )
{
if (state == Qt::Checked) _trace->show();
else _trace->hide();
adjustPosition( NULL );
}
} // End of Hurricane Namespace.

View File

@ -0,0 +1,81 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | I s o b a r - Hurricane / Python Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyAboutWindow.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/viewer/PyAboutWindow.h"
namespace Hurricane {
using Isobar::HurricaneError;
using Isobar::HurricaneWarning;
extern "C" {
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(AboutWindow,abw,function)
// +=================================================================+
// | "PyAboutWindow" Python Module Code Part |
// +=================================================================+
#if defined(__PYTHON_MODULE__)
// Standart Destroy (Attribute).
DirectDestroyAttribute(PyAboutWindow_destroy, PyAboutWindow)
static PyObject* PyAboutWindow_show ( PyObject*, PyObject* args )
{
cdebug_log(20,0) << "PyAboutWindow_show()" << endl;
HTRY
if (AboutWindow::show())
Py_RETURN_TRUE;
HCATCH
Py_RETURN_FALSE;
}
// ---------------------------------------------------------------
// PyAboutWindow Attribute Method table.
PyMethodDef PyAboutWindow_Methods[] =
{ { "show" , (PyCFunction)PyAboutWindow_show, METH_STATIC|METH_VARARGS
, "Display the About window." }
, {NULL, NULL, 0, NULL} /* sentinel */
};
PythonOnlyDeleteMethod(AboutWindow)
PyTypeObjectLinkPyTypeWithoutObject(AboutWindow,AboutWindow)
#else // End of Python Module Code Part.
// +=================================================================+
// | "PyAboutWindow" Shared Library Code Part |
// +=================================================================+
PyTypeRootObjectDefinitions(AboutWindow)
#endif // Shared Library Code Part.
} // extern "C".
} // Hurricane namespace.

View File

@ -0,0 +1,85 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | I s o b a r - Hurricane / Python Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyErrorWidget.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/viewer/PyErrorWidget.h"
namespace Isobar {
using namespace Hurricane;
extern "C" {
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(ErrorWidget,ew,function)
// +=================================================================+
// | "PyErrorWidget" Python Module Code Part |
// +=================================================================+
#if defined(__PYTHON_MODULE__)
// Standart Destroy (Attribute).
DirectDestroyAttribute(PyErrorWidget_destroy, PyErrorWidget)
static PyObject* PyErrorWidget_run ( PyObject*, PyObject* args )
{
cdebug_log(20,0) << "PyErrorWidget_run()" << endl;
HTRY
char* message = NULL;
char* trace = NULL;
if (not PyArg_ParseTuple(args,"s|s:ErrorWidget.run()", &message,&trace)) {
PyErr_SetString( ConstructorError, "ErrorWidget.run(): Takes one or two *string* arguments." );
return NULL;
}
if (ErrorWidget::run( QString(message), QString(trace) ))
Py_RETURN_TRUE;
HCATCH
Py_RETURN_FALSE;
}
// ---------------------------------------------------------------
// PyErrorWidget Attribute Method table.
PyMethodDef PyErrorWidget_Methods[] =
{ { "run" , (PyCFunction)PyErrorWidget_run, METH_STATIC|METH_VARARGS
, "Launch the error widget. Return True if continue." }
, {NULL, NULL, 0, NULL} /* sentinel */
};
PythonOnlyDeleteMethod(ErrorWidget)
PyTypeObjectLinkPyTypeWithoutObject(ErrorWidget,ErrorWidget)
#else // End of Python Module Code Part.
// +=================================================================+
// | "PyErrorWidget" Shared Library Code Part |
// +=================================================================+
PyTypeRootObjectDefinitions(ErrorWidget)
#endif // Shared Library Code Part.
} // extern "C".
} // Isobar namespace.

View File

@ -21,7 +21,9 @@
#include "hurricane/viewer/PyDrawingGroup.h"
#include "hurricane/viewer/PyDisplayStyle.h"
#include "hurricane/viewer/PyHSVr.h"
#include "hurricane/viewer/PyErrorWidget.h"
#include "hurricane/viewer/PyCellViewer.h"
#include "hurricane/viewer/PyAboutWindow.h"
namespace Hurricane {
@ -89,7 +91,9 @@ extern "C" {
PyDisplayStyleVector_LinkPyType ();
PyHApplication_LinkPyType ();
PyGraphics_LinkPyType ();
PyErrorWidget_LinkPyType ();
PyCellViewer_LinkPyType ();
PyAboutWindow_LinkPyType ();
PYTYPE_READY ( HSVr );
PYTYPE_READY ( RawDrawingStyle );
@ -103,7 +107,9 @@ extern "C" {
PYTYPE_READY ( DisplayStyleVectorIterator );
PYTYPE_READY ( HApplication );
PYTYPE_READY ( Graphics );
PYTYPE_READY ( ErrorWidget );
PYTYPE_READY ( CellViewer );
PYTYPE_READY ( AboutWindow );
// Identifier string can take up to 10 characters.
__cs.addType ( "hsvr" , &PyTypeHSVr , "<HSVr>" , false );
@ -125,7 +131,11 @@ extern "C" {
Py_INCREF ( &PyTypeGraphics );
PyModule_AddObject ( module, "Graphics" , (PyObject*)&PyTypeGraphics );
Py_INCREF ( &PyTypeCellViewer );
PyModule_AddObject ( module, "ErrorWidget" , (PyObject*)&PyTypeErrorWidget );
Py_INCREF ( &PyTypeErrorWidget );
PyModule_AddObject ( module, "CellViewer" , (PyObject*)&PyTypeCellViewer );
Py_INCREF ( &PyTypeAboutWindow );
PyModule_AddObject ( module, "AboutWindow" , (PyObject*)&PyTypeAboutWindow );
PyDisplayStyle_postModuleInit();
PyCellViewer_postModuleInit();

View File

@ -0,0 +1,36 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | V L S I B a c k e n d D a t a - B a s e |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./hurricane/viewer/AboutWindow.h" |
// +-----------------------------------------------------------------+
#pragma once
#include <exception>
#include <QDialog>
class QLabel;
class QTextEdit;
namespace Hurricane {
class AboutWindow : public QDialog {
Q_OBJECT;
public:
static bool show ();
public:
AboutWindow ( QWidget* parent=NULL);
};
} // Hurricane namespace.

View File

@ -0,0 +1,47 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | V L S I B a c k e n d D a t a - B a s e |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./hurricane/viewer/ErrorWidget.h" |
// +-----------------------------------------------------------------+
#pragma once
#include <exception>
#include <functional>
#include <QDialog>
class QLabel;
class QTextEdit;
namespace Hurricane {
class ErrorWidget : public QDialog {
Q_OBJECT;
public:
static bool run ( const QString& message, const QString& trace="" );
public:
ErrorWidget ( QWidget* parent=NULL);
void setMessage ( const QString& );
void setTrace ( const QString& );
protected:
virtual void closeEvent ( QCloseEvent* );
private slots:
void _showTrace ( int state );
private:
QLabel* _header;
QTextEdit* _message;
QTextEdit* _trace;
};
} // Hurricane namespace.

View File

@ -0,0 +1,54 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | I s o b a r - Hurricane / Python Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./hurricane/viewer/PyAboutWindow.cpp" |
// +-----------------------------------------------------------------+
#pragma once
#include "hurricane/isobar/PyHurricane.h"
#include "hurricane/viewer/AboutWindow.h"
namespace Hurricane {
extern "C" {
// -------------------------------------------------------------------
// Python Object : "PyAboutWindow".
typedef struct {
PyObject_HEAD
Hurricane::AboutWindow* _object;
} PyAboutWindow;
// -------------------------------------------------------------------
// Functions & Types exported to "PyHurricane.cpp".
extern PyTypeObject PyTypeAboutWindow;
extern PyMethodDef PyAboutWindow_Methods[];
extern PyObject* PyAboutWindow_create ( PyObject* self, PyObject* args );
extern void PyAboutWindow_LinkPyType ();
#define IsPyAboutWindow(v) ( (v)->ob_type == &PyTypeAboutWindow )
#define PYABOUTWINDOW(v) ( (PyAboutWindow*)(v) )
#define PYABOUTWINDOW_O(v) ( PYABOUTWINDOW(v)->_object )
} // extern "C".
} // Isobar namespace.

View File

@ -0,0 +1,54 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | I s o b a r - Hurricane / Python Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./hurricane/viewer/PyErrorWidget.cpp" |
// +-----------------------------------------------------------------+
#pragma once
#include "hurricane/isobar/PyHurricane.h"
#include "hurricane/viewer/ErrorWidget.h"
namespace Hurricane {
extern "C" {
// -------------------------------------------------------------------
// Python Object : "PyErrorWidget".
typedef struct {
PyObject_HEAD
Hurricane::ErrorWidget* _object;
} PyErrorWidget;
// -------------------------------------------------------------------
// Functions & Types exported to "PyHurricane.cpp".
extern PyTypeObject PyTypeErrorWidget;
extern PyMethodDef PyErrorWidget_Methods[];
extern PyObject* PyErrorWidget_create ( PyObject* self, PyObject* args );
extern void PyErrorWidget_LinkPyType ();
#define IsPyErrorWidget(v) ( (v)->ob_type == &PyTypeErrorWidget )
#define PYERRORWIDGET(v) ( (PyErrorWidget*)(v) )
#define PYERRORWIDGET_O(v) ( PYERRORWIDGET(v)->_object )
} // extern "C".
} // Isobar namespace.

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B