Skip to content
Snippets Groups Projects
Commit 2da6e865 authored by Jan Möbius's avatar Jan Möbius
Browse files

Denis: Added-new-autohiding-graphics-scene-window-that-cont

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@5018 383ad7c9-94d9-4d36-a494-682f7c89f535
parent a6f19930
No related branches found
No related tags found
No related merge requests found
Icons/button-autohide.png

317 B

Icons/button-detach.png

347 B

......@@ -143,16 +143,22 @@ CoreWidget( QVector<ViewMode*>& _viewModes,
// ======================================================================
// Set up the logging window
// ======================================================================
slidingLogger_ = new QtSlideWindow ("Log Viewer", centerWidget_);
tempLogWidget = new QWidget;
logWidget_ = new LoggerWidget(splitter_);
logWidget_->setReadOnly(true);
logWidget_->setSizePolicy( QSizePolicy ( QSizePolicy::Preferred , QSizePolicy::Preferred ) );
logWidget_->resize( splitter_->width() ,120);
logWidget_->resize( splitter_->width() ,240);
logWidget_->setLineWrapMode( QTextEdit::NoWrap );
originalLoggerSize_ = 0;
QList<int> wsizes( splitter_->sizes() );
if (OpenFlipper::Options::hideLogger()) {
slidingLogger_->attachWidget (logWidget_);
splitter_->insertWidget (1, tempLogWidget);
wsizes[0] = 1;
wsizes[1] = 0;
splitter_->setSizes(wsizes);
......@@ -523,11 +529,41 @@ CoreWidget::showLogger(bool _state) {
// Remember old size
originalLoggerSize_ = wsizes[1];
int height = logWidget_->height ();
splitter_->insertWidget (1, tempLogWidget);
wsizes[0] = wsizes[0]+wsizes[1];
wsizes[1] = 0;
splitter_->setSizes(wsizes);
logWidget_->resize (logWidget_->width (), height);
slidingLogger_->attachWidget (logWidget_);
} else if (splitter_->widget (1) == logWidget_) {
if ( originalLoggerSize_ == 0)
originalLoggerSize_ = 240;
QList<int> wsizes( splitter_->sizes() );
if (wsizes[0] == 0)
wsizes[0] = height();
wsizes[0] = wsizes[0]+wsizes[1] - originalLoggerSize_;
wsizes[1] = originalLoggerSize_;
splitter_->setSizes(wsizes);
} else {
QList<int> wsizes( splitter_->sizes() );
int height = logWidget_->height ();
slidingLogger_->detachWidget ();
splitter_->insertWidget (1, logWidget_);
wsizes[0] = wsizes[0]+wsizes[1] - height;
wsizes[1] = height;
splitter_->setSizes(wsizes);
/*
if ( originalLoggerSize_ == 0)
originalLoggerSize_ = 240;
......@@ -539,6 +575,7 @@ CoreWidget::showLogger(bool _state) {
wsizes[0] = wsizes[0]+wsizes[1] - originalLoggerSize_;
wsizes[1] = originalLoggerSize_;
splitter_->setSizes(wsizes);
*/
}
}
......@@ -677,6 +714,7 @@ void
CoreWidget::sceneRectChanged(const QRectF &rect)
{
centerWidget_->setGeometry (rect);
slidingLogger_->updateGeometry ();
}
......
......@@ -60,6 +60,7 @@
#include <OpenFlipper/widgets/glWidget/QtGLGraphicsScene.hh>
#include <OpenFlipper/widgets/glWidget/QtGLGraphicsView.hh>
#include <OpenFlipper/widgets/glWidget/QtMultiViewLayout.hh>
#include <OpenFlipper/widgets/glWidget/QtSlideWindow.hh>
// QT INCLUDES
#include <QMainWindow>
......@@ -410,6 +411,12 @@ public:
/// Base layout that holds gl views
QtMultiViewLayout* baseLayout_;
/// Class that holds the animated log widget
QtSlideWindow* slidingLogger_;
/// Temporary widget
QWidget* tempLogWidget;
// widget showing the scenegraph
ACG::QtWidgets::QtSceneGraphDialog* sceneGraphDialog_;
......
//=============================================================================
//
// OpenFlipper
// Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
// www.openflipper.org
//
//-----------------------------------------------------------------------------
//
// License
//
// OpenFlipper is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenFlipper 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
// $Revision: 4430 $
// $Author: moebius $
// $Date: 2009-01-23 17:14:32 +0100 (Fr, 23. Jan 2009) $
//
//=============================================================================
//=============================================================================
//
// CLASS QtGraphicsButton - IMPLEMENTATION
//
//=============================================================================
//== INCLUDES =================================================================
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include "QtGraphicsButton.hh"
//== IMPLEMENTATION ==========================================================
QtGraphicsButton::QtGraphicsButton (const QImage &_image, QGraphicsItem *_parent, int _width, int _height) :
QGraphicsItem (_parent),
checkable_(false),
checked_(false),
pressed_(false),
over_(false),
width_(_width),
height_(_height)
{
if (width_ <= 0)
width_ = _image.width ();
if (height_ <= 0)
height_ = _image.height ();
// scale image to button dimensions
QImage i = _image.scaled (width_, height_, Qt::IgnoreAspectRatio, Qt::SmoothTransformation).convertToFormat (QImage::Format_ARGB32);
checkedPix_ = QPixmap::fromImage (i);
// generate black/white and transparent images for the other button states
QImage normal (width_, height_, QImage::Format_ARGB32);
QImage over (width_, height_, QImage::Format_ARGB32);
for (int x = 0; x < width_; x++)
for (int y = 0; y < height_; y++)
{
QRgb pix = i.pixel (x, y);
over.setPixel (x, y, qRgba (qRed (pix), qGreen (pix), qBlue (pix), qAlpha (pix) * 0.5));
normal.setPixel (x, y, qRgba (qGray (pix), qGray (pix), qGray (pix), qAlpha (pix) * 0.3));
}
overPix_ = QPixmap::fromImage (over);
normalPix_ = QPixmap::fromImage (normal);
setAcceptHoverEvents (true);
}
//-----------------------------------------------------------------------------
QRectF QtGraphicsButton::boundingRect () const
{
return QRectF (QPointF(0, 0), QSizeF (width_, height_));
}
//-----------------------------------------------------------------------------
void QtGraphicsButton::paint (QPainter *_painter, const QStyleOptionGraphicsItem *, QWidget *)
{
_painter->setClipping (false);
if (pressed_ || checked_)
_painter->drawPixmap (0, 0, checkedPix_);
else if (over_)
_painter->drawPixmap (0, 0, overPix_);
else
_painter->drawPixmap (0, 0, normalPix_);
}
//-----------------------------------------------------------------------------
void QtGraphicsButton::setCheckable (bool _value)
{
checkable_ = _value;
}
//-----------------------------------------------------------------------------
void QtGraphicsButton::setChecked (bool _value)
{
checked_ = _value;
}
//-----------------------------------------------------------------------------
bool QtGraphicsButton::isChecked () const
{
return checked_;
}
//-----------------------------------------------------------------------------
void QtGraphicsButton::hoverEnterEvent (QGraphicsSceneHoverEvent *)
{
over_ = true;
update ();
}
//-----------------------------------------------------------------------------
void QtGraphicsButton::hoverLeaveEvent (QGraphicsSceneHoverEvent *)
{
over_ = false;
update ();
}
//-----------------------------------------------------------------------------
void QtGraphicsButton::mousePressEvent ( QGraphicsSceneMouseEvent *_event)
{
_event->accept ();
pressed_ = true;
if (checkable_)
checked_ = !checked_;
update ();
emit pressed ();
}
//-----------------------------------------------------------------------------
void QtGraphicsButton::mouseReleaseEvent (QGraphicsSceneMouseEvent *_event)
{
_event->accept ();
pressed_ = false;
update ();
}
//-----------------------------------------------------------------------------
QVariant QtGraphicsButton::itemChange (GraphicsItemChange _change, const QVariant &_value)
{
// reset state if button was hidden
if (_change == QGraphicsItem::ItemVisibleHasChanged)
{
pressed_ = false;
over_ = false;
}
return QGraphicsItem::itemChange (_change, _value);
}
//=============================================================================
//=============================================================================
//
// OpenFlipper
// Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
// www.openflipper.org
//
//-----------------------------------------------------------------------------
//
// License
//
// OpenFlipper is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenFlipper 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
// $Revision: $
// $Author: $
// $Date: $
//
//=============================================================================
#ifndef QT_GRAPHICS_BUTTON_
#define QT_GRAPHICS_BUTTON_
//=============================================================================
//
// CLASS QtGraphicsButton - IMPLEMENTATION
//
//=============================================================================
//== INCLUDES =================================================================
#include <QGraphicsItem>
//== CLASS DEFINITION =========================================================
/** Simple Button implementation for QGraphicsScene
*/
class QtGraphicsButton : public QObject, public QGraphicsItem
{
Q_OBJECT
public:
/** Create a glViewer.
\param _image button imahe
\param _parent parent graphics scene item
\param _width button width
\param _height button height
*/
QtGraphicsButton (const QImage &_image, QGraphicsItem *_parent = 0, int _width = -1, int _height = -1);
public:
/// returns the bounding rect
virtual QRectF boundingRect () const;
/// paints the button
virtual void paint (QPainter *_painter, const QStyleOptionGraphicsItem *_option, QWidget *_widget = 0);
/// event tracking
virtual void hoverEnterEvent (QGraphicsSceneHoverEvent *_event);
virtual void hoverLeaveEvent (QGraphicsSceneHoverEvent *_event);
virtual void mousePressEvent (QGraphicsSceneMouseEvent *_event);
virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent *_event);
virtual QVariant itemChange (GraphicsItemChange _change, const QVariant &_value);
/// makes the button checkable
void setCheckable (bool _value);
/// sets button checked state
void setChecked (bool _value);
/// returns button checked state
bool isChecked () const;
signals:
/// signals a button press
void pressed ();
private:
/// button state
bool checkable_;
bool checked_;
bool pressed_;
bool over_;
/// button size
int width_;
int height_;
/// pixmaps for different button states
QPixmap normalPix_;
QPixmap overPix_;
QPixmap checkedPix_;
};
#endif
\ No newline at end of file
//=============================================================================
//
// OpenFlipper
// Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
// www.openflipper.org
//
//-----------------------------------------------------------------------------
//
// License
//
// OpenFlipper is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenFlipper 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
// $Revision: $
// $Author: $
// $Date: $
//
//=============================================================================
//=============================================================================
//
// CLASS QtSlideWindow
//
//=============================================================================
//== GLOBAL DEFINITIONS=========================================================
#define BACKGROUND_RED 0xff
#define BACKGROUND_GREEN 0xff
#define BACKGROUND_BLUE 0xff
#define BACKGROUND_ALPHA 0xcf
#define SLIDE_DURATION 500
//== INCLUDES =================================================================
#include <OpenFlipper/common/GlobalOptions.hh>
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include <QTimeLine>
#include <QGraphicsItemAnimation>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QDialog>
#include <QVBoxLayout>
#include "QtSlideWindow.hh"
#include "QtGraphicsButton.hh"
//== IMPLEMENTATION ==========================================================
QtSlideWindow::QtSlideWindow(QString _name, QGraphicsItem *_parent) :
QGraphicsProxyWidget(_parent),
name_(_name),
mainWidget_(0),
autohideButton_(0),
detachButton_(0),
hideAnimation_(0),
dialog_(0)
{
setCacheMode (QGraphicsItem::DeviceCoordinateCache);
setWindowFrameMargins (2, 15, 2, 2);
setZValue (2.0);
QImage autohide (OpenFlipper::Options::iconDirStr () + OpenFlipper::Options::dirSeparator () + "button-autohide.png");
QImage detach (OpenFlipper::Options::iconDirStr () + OpenFlipper::Options::dirSeparator () + "button-detach.png");
autohideButton_ = new QtGraphicsButton (autohide, this, 12, 12);
detachButton_ = new QtGraphicsButton (detach, this, 12, 12);
autohideButton_->setCheckable (true);
autohideButton_->setChecked (true);
autohideButton_->setPos (geometry().width() - 12, -13);
detachButton_->setPos (geometry().width() - 25, -13);
connect (detachButton_, SIGNAL(pressed ()), this, SLOT(detachPressed ()));
connect (autohideButton_, SIGNAL(pressed ()), this, SLOT(autohidePressed ()));
hideTimeLine_ = new QTimeLine (SLIDE_DURATION);
hideTimeLine_->setFrameRange (0, 100);
hideAnimation_ = new QGraphicsItemAnimation;
hideAnimation_->setItem (this);
hideAnimation_->setTimeLine (hideTimeLine_);
for (int i = 0; i < geometry ().height (); ++i)
hideAnimation_->setTranslationAt (i / geometry ().height (), 0, geometry ().height () - i);
hide ();
}
//-----------------------------------------------------------------------------
void QtSlideWindow::attachWidget (QWidget *_m)
{
if (!_m)
return;
mainWidget_ = _m;
mainWidget_->setParent(0);
setWidget (mainWidget_);
setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
show ();
if (autohideButton_->isChecked ())
{
hideTimeLine_->setCurrentTime (0);
hideAnimation_->setStep (0.0);
}
else
{
hideTimeLine_->setCurrentTime (SLIDE_DURATION);
hideAnimation_->setStep (1.0);
}
updateGeometry ();
}
//-----------------------------------------------------------------------------
void QtSlideWindow::detachWidget ()
{
setWidget (0);
hide ();
mainWidget_->setParent(0);
mainWidget_ = 0;
if (dialog_)
{
disconnect (dialog_, SIGNAL(finished (int)), this, SLOT(dialogClosed ()));
dialog_->close ();
delete dialog_;
dialog_ = 0;
}
}
//-----------------------------------------------------------------------------
void QtSlideWindow::paintWindowFrame(QPainter *_painter,
const QStyleOptionGraphicsItem *_option,
QWidget *_widget)
{
int w = geometry().width();
int h = geometry().height();
_painter->setRenderHint(QPainter::Antialiasing, true);
_painter->setBrush(QBrush(QColor(BACKGROUND_RED,
BACKGROUND_GREEN,
BACKGROUND_BLUE,
BACKGROUND_ALPHA)));
_painter->setPen(Qt::NoPen);
_painter->drawRoundedRect(-2, -15, w + 4, h + 40, 4, 4);
_painter->setPen(Qt::SolidLine);
_painter->drawText(2,-13,w - 4, 11, Qt::AlignCenter, name_);
}
//-----------------------------------------------------------------------------
bool QtSlideWindow::windowFrameEvent(QEvent *_e)
{
if (_e->type() == QEvent::GraphicsSceneMousePress ||
_e->type() == QEvent::GraphicsSceneMouseRelease)
{
QGraphicsSceneMouseEvent *ge = dynamic_cast<QGraphicsSceneMouseEvent*>(_e);
if (windowFrameSectionAt(ge->pos()) != Qt::TopSection)
{
_e->accept();
return false;
}
}
return QGraphicsProxyWidget::windowFrameEvent(_e);
}
//-----------------------------------------------------------------------------
Qt::WindowFrameSection QtSlideWindow::windowFrameSectionAt(const QPointF &_pos) const
{
if (_pos.x() >= 2 && _pos.x() < geometry().width() - 2 - (13 * 2) &&
_pos.y() >= -15 && _pos.y() <= -10)
{
return Qt::TopSection;
}
return Qt::NoSection;
}
//-----------------------------------------------------------------------------
void QtSlideWindow::hoverEnterEvent (QGraphicsSceneHoverEvent *)
{
if (autohideButton_->isChecked ())
{
hideTimeLine_->setDirection (QTimeLine::Forward);
if (hideTimeLine_->state () == QTimeLine::NotRunning)
hideTimeLine_->start ();
}
}
//-----------------------------------------------------------------------------
void QtSlideWindow::hoverLeaveEvent (QGraphicsSceneHoverEvent *)
{
if (autohideButton_->isChecked ())
{
hideTimeLine_->setDirection (QTimeLine::Backward);
if (hideTimeLine_->state () == QTimeLine::NotRunning)
hideTimeLine_->start ();
}
}
//-----------------------------------------------------------------------------
void QtSlideWindow::resizeEvent (QGraphicsSceneResizeEvent *_event)
{
QGraphicsProxyWidget::resizeEvent (_event);
if (hideAnimation_)
{
hideAnimation_->clear ();
for (int i = 0; i < geometry ().height (); ++i)
hideAnimation_->setTranslationAt (i / geometry ().height (), 0, geometry ().height () - i);
}
}
//-----------------------------------------------------------------------------
void QtSlideWindow::moveEvent (QGraphicsSceneMoveEvent *_event)
{
QGraphicsProxyWidget::moveEvent (_event);
if (hideAnimation_)
{
hideAnimation_->clear ();
for (int i = 0; i < geometry ().height (); ++i)
hideAnimation_->setTranslationAt (i / geometry ().height (), 0, geometry ().height () - i);
}
}
//-----------------------------------------------------------------------------
void QtSlideWindow::detachPressed ()
{
setWidget (0);
dialog_ = new QDialog(0, Qt::CustomizeWindowHint | Qt::WindowTitleHint);
dialog_->setWindowTitle (name_);
dialog_->setLayout (new QVBoxLayout);
dialog_->resize (mainWidget_->size ());
dialog_->layout ()->addWidget (mainWidget_);
hide ();
dialog_->show ();
mainWidget_->setAttribute(Qt::WA_DeleteOnClose, false);
connect (dialog_, SIGNAL(finished (int)), this, SLOT(dialogClosed ()));
}
//-----------------------------------------------------------------------------
void QtSlideWindow::dialogClosed ()
{
dialog_ = 0;
mainWidget_->setParent(0);
setWidget (mainWidget_);
setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
mainWidget_->setAttribute(Qt::WA_DeleteOnClose, true);
show ();
if (autohideButton_->isChecked ())
{
hideTimeLine_->setCurrentTime (0);
hideAnimation_->setStep (0.0);
}
else
{
hideTimeLine_->setCurrentTime (SLIDE_DURATION);
hideAnimation_->setStep (1.0);
}
updateGeometry ();
}
//-----------------------------------------------------------------------------
void QtSlideWindow::autohidePressed ()
{
if (!autohideButton_->isChecked ())
{
hideTimeLine_->setDirection (QTimeLine::Forward);
if (hideTimeLine_->state () == QTimeLine::NotRunning &&
hideTimeLine_->currentTime () != SLIDE_DURATION)
hideTimeLine_->start ();
}
}
//-----------------------------------------------------------------------------
void QtSlideWindow::updateGeometry ()
{
if (parentWidget () && mainWidget_)
{
setPos (8, parentWidget ()->geometry ().height () - geometry ().height ());
resize (parentWidget ()->geometry ().width () - 20,
mainWidget_->size ().height ());
if (autohideButton_)
autohideButton_->setPos (geometry().width() - 12, -13);
if (detachButton_)
detachButton_->setPos (geometry().width() - 25, -13);
}
}
//=============================================================================
//=============================================================================
//=============================================================================
//
// OpenFlipper
// Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
// www.openflipper.org
//
//-----------------------------------------------------------------------------
//
// License
//
// OpenFlipper is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenFlipper 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
// $Revision: $
// $Author: $
// $Date: $
//
//=============================================================================
#ifndef QT_SLIDE_WINDOW_
#define QT_SLIDE_WINDOW_
//=============================================================================
//
// CLASS QtSlideWindow
//
//=============================================================================
//== INCLUDES =================================================================
#include <QGraphicsProxyWidget>
//== FORWARDDECLARATIONS ======================================================
class QtGraphicsButton;
class QTimeLine;
class QGraphicsItemAnimation;
//== CLASS DEFINITION =========================================================
/** \class QtSlideWindow QtSlideWindow.hh <OpenFlipper/widgets/glWidget/QtSlideWindow.hh>
A graphics scene widget that has a hover slide effect and detach functionality
for a child widget
**/
class QtSlideWindow : public QGraphicsProxyWidget
{
Q_OBJECT
public:
/** Create a glViewer.
\param _name displayed titlebar name
\param _parent parent graphics item
*/
QtSlideWindow (QString _name = 0, QGraphicsItem *_parent = 0);
/// recalculate geometry
void updateGeometry ();
/// attach a child widget
void attachWidget (QWidget *_m);
/// detach child widget
void detachWidget ();
private:
/// paints decoration
virtual void paintWindowFrame(QPainter *_painter, const QStyleOptionGraphicsItem *_option, QWidget *_widget = 0);
/// track frame events
virtual bool windowFrameEvent(QEvent *_e);
/// categorize frame area
virtual Qt::WindowFrameSection windowFrameSectionAt(const QPointF &_pos) const;
/// hove event tracking
virtual void hoverEnterEvent (QGraphicsSceneHoverEvent *_event);
virtual void hoverLeaveEvent (QGraphicsSceneHoverEvent *_event);
/// size & position event tracking
virtual void resizeEvent (QGraphicsSceneResizeEvent *_event);
virtual void moveEvent (QGraphicsSceneMoveEvent *_event);
private slots:
/// detach button pressed
void detachPressed ();
/// detached dialog closed
void dialogClosed ();
/// autohide button presed
void autohidePressed ();
private:
// name
QString name_;
// child widget
QWidget *mainWidget_;
// buttons
QtGraphicsButton *autohideButton_;
QtGraphicsButton *detachButton_;
// animation
QTimeLine *hideTimeLine_;
QGraphicsItemAnimation *hideAnimation_;
// detached dialog
QDialog *dialog_;
};
//=============================================================================
//=============================================================================
#endif // QT_SLIDE_WINDOW_ defined
//=============================================================================
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment