#include "TQtWidget.h"
#include "TQtClientWidget.h"
#include "TQtClientFilter.h"
#include "TQtClientGuard.h"
#include "TGQt.h"
#include "TQtLock.h"
#include <QKeySequence>
#include <QShortcut>
#include <QKeyEvent>
#include <QCloseEvent>
#include <QEvent>
#include <QDebug>
#include "TGClient.h"
TQtClientWidget::TQtClientWidget(TQtClientGuard *guard, QWidget* mother, const char* name, Qt::WFlags f ):
QFrame(mother,f)
,fGrabButtonMask(kAnyModifier), fGrabEventPointerMask(kNoEventMask)
,fGrabEventButtonMask(kNoEventMask), fSelectEventMask(kNoEventMask), fSaveSelectInputMask(kNoEventMask)
,fButton(kAnyButton), fPointerOwner(kFALSE)
,fNormalPointerCursor(0),fGrabPointerCursor(0),fGrabButtonCursor(0)
,fIsClosing(false) ,fDeleteNotify(false), fGuard(guard)
,fCanvasWidget(0),fMyRootWindow(0),fEraseColor(0), fErasePixmap(0)
{
setObjectName(name);
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_PaintOutsidePaintEvent);
setAutoFillBackground(true);
}
TQtClientWidget::~TQtClientWidget()
{
TQtClientFilter *f = gQt->QClientFilter();
if (f) f->GrabPointer(this, 0, 0, 0, kFALSE);
disconnect();
if (fGuard) fGuard->DisconnectChildren(this);
fNormalPointerCursor = 0;
UnSetButtonMask(true);
UnSetKeyMask();
delete fEraseColor; fEraseColor = 0;
delete fErasePixmap; fErasePixmap = 0;
if (!IsClosing())
gQt->SendDestroyEvent(this);
}
void TQtClientWidget::closeEvent(QCloseEvent *ev)
{
printf("TQtClientWidget::closeEvent(QCloseEvent *ev)\n");
QWidget::closeEvent(ev);
}
void TQtClientWidget::setEraseColor(const QColor &color)
{
if (!fEraseColor)
fEraseColor = new QColor(color);
else
*fEraseColor = color;
QPalette pp = palette();
pp.setColor(QPalette::Window, *fEraseColor);
setPalette(pp);
}
void TQtClientWidget::setErasePixmap (const QPixmap &pixmap)
{
if (!fErasePixmap)
fErasePixmap = new QPixmap(pixmap);
else
*fErasePixmap = pixmap;
QPalette pp = palette();
pp.setBrush(QPalette::Window, QBrush(*fErasePixmap));
setPalette(pp);
}
bool TQtClientWidget::IsGrabbed(Event_t &ev)
{
bool grab = false;
QWidget *mother = parentWidget();
if ( ButtonEventMask()
&& !isHidden()
&& !( mother
&& dynamic_cast<TQtClientWidget*>(mother)
&& ((TQtClientWidget *)mother)->IsGrabbed(ev)
)
)
{
bool msk = (ev.fState & fGrabButtonMask) || (fGrabButtonMask & kAnyModifier);
if ((fButton == kAnyButton) && msk)
grab = true;
else
grab = (fButton == EMouseButton(ev.fCode)) && msk;
TQtClientWidget *w = (TQtClientWidget *)TGQt::wid(ev.fWindow);
if (grab && (w != this) ) {
QRect absRect = geometry();
QPoint absPos = mapToGlobal(QPoint(0,0));
absRect.moveTopLeft(absPos);
grab = absRect.contains(ev.fXRoot,ev.fYRoot);
}
if (grab) GrabEvent(ev);
}
return grab;
}
TQtClientWidget *TQtClientWidget::IsKeyGrabbed(const Event_t &ev)
{
TQtClientWidget *grabbed = 0;
UInt_t modifier = ev.fState;
if (SetKeyMask(ev.fCode, modifier, kTestKey)) grabbed = this;
if (grabbed && ( ev.fType == kKeyRelease)) {
SetKeyMask(ev.fCode, modifier, kRemove);
}
TQtClientWidget *wg = this;
if (!grabbed) {
do {
wg = (TQtClientWidget *)wg->parentWidget();
} while ( wg && (grabbed = wg->IsKeyGrabbed(ev)) );
}
if (!grabbed) {
const QObjectList &childList = children();
if (!childList.isEmpty()) {
QListIterator<QObject*> next(childList);
while(next.hasNext() && (wg = dynamic_cast<TQtClientWidget *>(next.next ())) && !(grabbed=wg->IsKeyGrabbed(ev)) ){;}
}
}
return grabbed;
}
void TQtClientWidget::GrabEvent(Event_t &ev, bool )
{
TQtClientWidget *w = (TQtClientWidget *)TGQt::wid(ev.fWindow);
if (w != this) {
QPoint mapped = mapFromGlobal(QPoint(ev.fXRoot,ev.fYRoot));
ev.fX = mapped.x();
ev.fY = mapped.y();
ev.fWindow = TGQt::wid(this);
}
}
void TQtClientWidget::SelectInput (UInt_t evmask)
{
fSelectEventMask=evmask;
assert(fSelectEventMask != (UInt_t) -1);
setMouseTracking( fSelectEventMask & kPointerMotionMask );
}
void TQtClientWidget::SetButtonMask(UInt_t modifier,EMouseButton button)
{
fGrabButtonMask = modifier; fButton = button;
TQtClientFilter *f = gQt->QClientFilter();
if (f) {
f->AppendButtonGrab(this);
connect(this,SIGNAL(destroyed(QObject *)),f,SLOT(RemoveButtonGrab(QObject *)));
}
}
void TQtClientWidget::UnSetButtonMask(bool dtor)
{
if (fGrabButtonMask) {
fGrabButtonMask = 0;
TQtClientFilter *f = gQt->QClientFilter();
if (f) {
if ( !dtor ) disconnect(this,SIGNAL(destroyed(QObject *)),f,SLOT(RemoveButtonGrab(QObject *)));
f->RemoveButtonGrab(this);
}
}
}
Bool_t TQtClientWidget::SetKeyMask(Int_t keycode, UInt_t modifier, int insert)
{
Bool_t found = kTRUE;
int ikeys = 0;
if (keycode) {
if (modifier & kKeyShiftMask) ikeys |= Qt::SHIFT;
if (modifier & kKeyLockMask) ikeys |= Qt::META;
if (modifier & kKeyControlMask) ikeys |= Qt::CTRL;
if (modifier & kKeyMod1Mask) ikeys |= Qt::ALT;
ikeys |= keycode;
}
QKeySequence keys(ikeys);
std::map<QKeySequence,QShortcut*>::iterator i = fGrabbedKey.find(keys);
switch (insert) {
case kInsert:
if (keycode) {
if ( i == fGrabbedKey.end()) {
fGrabbedKey.insert(
std::pair<QKeySequence,QShortcut*>(keys,new QShortcut(keys,this,SLOT(Accelerate()),SLOT(Accelerate()),Qt::ApplicationShortcut))
);
} else {
(*i).second->setEnabled(true);
}
}
break;
case kRemove:
if (keycode) {
if ( i != fGrabbedKey.end())
(*i).second->setEnabled(false);
} else {
std::map<QKeySequence,QShortcut*>::iterator j = fGrabbedKey.begin();
while (j != fGrabbedKey.end()) {
(*j).second->setEnabled(false);
++j;
}
}
break;
case kTestKey:
found = i != fGrabbedKey.end();
break;
default: break;
}
return found;
}
void TQtClientWidget::SetCanvasWidget(TQtWidget *widget)
{
TQtLock lock;
if (fCanvasWidget)
disconnect(fCanvasWidget,SIGNAL(destroyed()), this, SLOT(disconnect()));
fCanvasWidget = widget;
if (fCanvasWidget) {
#if QT_VERSION < 0x40000
setWFlags(getWFlags () | Qt::WRepaintNoErase | Qt:: WResizeNoErase );
#endif /* QT_VERSION */
connect(fCanvasWidget,SIGNAL(destroyed()),this,SLOT(Disconnect()));
}
}
void TQtClientWidget::UnSetKeyMask(Int_t keycode, UInt_t modifier)
{
SetKeyMask(keycode, modifier, kRemove);
}
void TQtClientWidget::Accelerate()
{
QShortcut *cut = (QShortcut *)sender();
QKeySequence key = cut->key ();
qDebug() << "TQtClientWidget::Accelerate()" << key;
int l = key.count();
int keycode = key[l-1];
Qt::KeyboardModifiers state = Qt::NoModifier;
if (keycode & Qt::SHIFT) state |= Qt::ShiftModifier;
if (keycode & Qt::META) state |= Qt::MetaModifier;
if (keycode & Qt::CTRL) state |= Qt::ControlModifier;
if (keycode & Qt::ALT) state |= Qt::AltModifier;
QKeyEvent ac(QEvent::KeyPress,keycode & 0x01FFFFFF,state);
TQtClientFilter *f = gQt->QClientFilter();
if (f) f->AddKeyEvent(ac,this);
QKeyEvent acRelease(QEvent::KeyRelease,keycode & 0x01FFFFFF,state);
if (f) f->AddKeyEvent(acRelease,this);
}
void TQtClientWidget::Disconnect()
{
SetCanvasWidget(0); }
void TQtClientWidget::paintEvent( QPaintEvent *e )
{
QFrame::paintEvent(e);
#if ROOT_VERSION_CODE >= ROOT_VERSION(9,15,9)
if (gClient) {
if (!fMyRootWindow)
fMyRootWindow = gClient->GetWindowById(TGQt::rootwid(this));
if (fMyRootWindow) {
gClient->NeedRedraw(fMyRootWindow,kTRUE);
}
}
#endif
}