Logo Search packages:      
Sourcecode: gambas version File versions  Download package

CWidget.cpp

/***************************************************************************

  CWidget.cpp

  The Control class

  (c) 2000-2003 Beno� Minisini <gambas@users.sourceforge.net>

  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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.

***************************************************************************/

#define __CWIDGET_CPP

#include "gambas.h"

#include <stdio.h>

#include "CWidget.h"
#include "CFont.h"
#include "CMouse.h"
#include "CKey.h"
#include "CWindow.h"
#include "CConst.h"
#include "CClipboard.h"

#include <qnamespace.h>
#include <qapplication.h>
#if QT_VERSION >= 0x030200
#include <qobjectlist.h>
#else
#include <qobjcoll.h>
#endif
#include <qpalette.h>
#include <qtooltip.h>
#include <qpushbutton.h>
#include <qscrollview.h>

CWIDGET *CWIDGET_destroy_list = 0;
CWIDGET *CWIDGET_destroy_last = 0;

static void *CLASS_Container = 0;


/* Control class */

void CWIDGET_new(QWidget *w, void *object, char *klass /* = NULL */, bool no_filter /* = false */, bool no_tag /* = false */)
{
  if (!CLASS_Container)
    CLASS_Container = GB.FindClass("Container");

  CWidget::add(w, object, no_filter);

  //qDebug("CWIDGET_new: %p: %p", object, w);

  ((CWIDGET *)object)->widget = w;
  ((CWIDGET *)object)->level = MAIN_loop_level;
  ((CWIDGET *)object)->next = 0;

  if (!no_tag)
    ((CWIDGET *)object)->tag.type = GB_T_NULL;

  if (GB.Is(object, CLASS_Container))
    CWIDGET_set_flag(object, WF_NO_EVENT);
}


int CWIDGET_check(void *object)
{
  return QWIDGET(object) == NULL;
}


QString CWIDGET_Utf8ToQString(GB_STRING *str)
{
  return QString::fromUtf8((const char *)(str->value.addr + str->value.start), str->value.len);
}


void CWIDGET_destroy(CWIDGET *object)
{
  if (!object->widget)
    return;

  if (CWIDGET_test_flag(object, WF_DELETED))
    return;

  //qDebug("CWIDGET_destroy: %p (%p) :%p:%ld", object, object->widget, object->ob.klass, object->ob.ref);

  if (!CWIDGET_destroy_list)
    CWIDGET_destroy_list = object;
  else
  {
    CWIDGET_destroy_last->next = object;
    object->prev = CWIDGET_destroy_last;
  }

  CWIDGET_destroy_last = object;

  CWIDGET_set_flag(object, WF_DELETED);
  //GB.Ref(object);
}


//#if QT_VERSION >= 0x030005
//  #define COORD(_c) (WIDGET->pos()._c())
//#else
#define COORD(_c) ((WIDGET->isTopLevel()) ? ((CWINDOW *)_object)->_c : WIDGET->pos()._c())
//#define WIDGET_POS(_c) ((WIDGET->isTopLevel()) ? ((CWINDOW *)_object)->_c : WIDGET->pos()._c())
#define WIDGET_SIZE(_c) ((WIDGET->isTopLevel()) ? ((CWINDOW *)_object)->_c : WIDGET->pos()._c())
//#endif

static QWidget *get_widget(void *_object)
{
  QWidget *w = THIS->widget;
  //if (w->isVisible() && CWIDGET_test_flag(THIS, WF_PARENT_GEOMETRY))
  //  w = w->parentWidget();
  return w;
}


static void move_widget(void *_object, int x, int y)
{
  QWidget *wid = get_widget(THIS);

  wid->move(x, y);

  if (WIDGET->isA("MyMainWindow"))
  {
    ((CWINDOW *)_object)->x = x;
    ((CWINDOW *)_object)->y = y;
  }
}


static void resize_widget(void *_object, int w, int h)
{
  QWidget *wid = get_widget(THIS);

  if (w < 0 && h < 0)
    return;

  if (w < 0)
    w = wid->width();

  if (h < 0)
    h = wid->height();

  wid->resize(QMAX(0, w), QMAX(0, h));

  if (WIDGET->isA("MyMainWindow"))
  {
    //qDebug("resize_widget: %d %d", w, h);

    ((CWINDOW *)_object)->w = w;
    ((CWINDOW *)_object)->h = h;
    // menu bar height is ignored
    ((CWINDOW *)_object)->container->resize(w, h);
  }
}


static void move_resize_widget(void *_object, int x, int y, int w, int h)
{
  QWidget *wid = get_widget(THIS);

  if (w < 0)
    w = wid->width();

  if (h < 0)
    h = wid->height();

  wid->setGeometry(x, y, QMAX(0, w), QMAX(0, h));

  if (WIDGET->isA("MyMainWindow"))
  {
    ((CWINDOW *)_object)->x = x;
    ((CWINDOW *)_object)->y = y;
    ((CWINDOW *)_object)->w = w;
    ((CWINDOW *)_object)->h = h;
    ((CWINDOW *)_object)->container->resize(w, h);
  }
}


static void set_mouse(QWidget *w, int mouse, void *cursor)
{
  QObjectList *children;
  QObject *child;

  if (mouse == CMOUSE_DEFAULT)
    w->unsetCursor();
  else if (mouse == CMOUSE_CUSTOM)
  {
    if (cursor)
      w->setCursor(*((CCURSOR *)cursor)->cursor);
    else
      w->unsetCursor();
  }
  else
    w->setCursor(mouse);

  children = (QObjectList *)(w->children());

  if (!children)
    return;

  child = children->first();
  while (child)
  {
    if (child->isWidgetType() && !CWidget::getReal(child))
      set_mouse((QWidget *)child, CMOUSE_DEFAULT, 0);

    child = children->next();
  }
}


BEGIN_PROPERTY(CWIDGET_x)

  if (READ_PROPERTY)
    GB.ReturnInteger(COORD(x));
  else
  {
    move_widget(_object, VPROP(GB_INTEGER), COORD(y));
    /*if (WIDGET->isTopLevel())
      qDebug("X: %d ==> X = %d", PROPERTY(long), WIDGET->x());*/
  }

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_screen_x)

  GB.ReturnInteger(get_widget(THIS)->mapToGlobal(QPoint(0, 0)).x());

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_y)

  if (READ_PROPERTY)
    GB.ReturnInteger(COORD(y));
  else
    move_widget(_object, COORD(x), VPROP(GB_INTEGER));

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_screen_y)

  GB.ReturnInteger(get_widget(THIS)->mapToGlobal(QPoint(0, 0)).y());

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_w)

  if (READ_PROPERTY)
    GB.ReturnInteger(get_widget(THIS)->width());
  else
    resize_widget(_object, VPROP(GB_INTEGER), -1);

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_h)

  if (READ_PROPERTY)
    GB.ReturnInteger(get_widget(THIS)->height());
  else
    resize_widget(_object, -1, VPROP(GB_INTEGER));

END_PROPERTY

/*
BEGIN_PROPERTY(CWIDGET_name)

  if (READ_PROPERTY)
    GB.ReturnString(QWIDGET(_object)->name(), 0);
  else
    CWidget::setName(OBJECT(CWIDGET), GB.ToZeroString(PROPERTY(GB_STRING)));

END_PROPERTY
*/

BEGIN_PROPERTY(CWIDGET_font)

  CFONT *font;

  if (READ_PROPERTY)
  {
    GB.ReturnObject(CFONT_create_control(THIS));
    //else
    //  GB.ReturnNull();
  }
  else
  {
    font = (CFONT *)VPROP(GB_OBJECT);

    if (font == 0)
      WIDGET->unsetFont();
    else
      WIDGET->setFont(*(font->font));
  }

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_design)

  if (READ_PROPERTY)
  {
    GB.ReturnBoolean(CWIDGET_test_flag(_object, WF_DESIGN));
    return;
  }

  if (VPROP(GB_BOOLEAN))
  {
    CWIDGET_set_flag(_object, WF_DESIGN);
    CWidget::removeFocusPolicy(WIDGET);
    set_mouse(WIDGET, CMOUSE_DEFAULT, 0);
    //CWidget::installFilter(QWIDGET(_object));
  }
  else if (CWIDGET_test_flag(_object, WF_DESIGN))
    GB.Error("Cannot reset Design property");
  //else
  //{
  //  CWIDGET_clear_flag(_object, WF_DESIGN);
  //  //CWidget::removeFilter(QWIDGET(_object));
  //}

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_visible)

  if (READ_PROPERTY)
    GB.ReturnBoolean(!QWIDGET(_object)->isHidden());
  else
  {
    if (VPROP(GB_BOOLEAN))
      QWIDGET(_object)->show();
    else
      QWIDGET(_object)->hide();
  }

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_enabled)

  if (READ_PROPERTY)
    GB.ReturnBoolean(QWIDGET(_object)->isEnabled());
  else
    QWIDGET(_object)->setEnabled(VPROP(GB_BOOLEAN));

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_expand)

  if (READ_PROPERTY)
    GB.ReturnBoolean(CWIDGET_test_flag(THIS, WF_EXPAND));
  else
  {
    QWidget *parent;

    if (VPROP(GB_BOOLEAN))
      CWIDGET_set_flag(THIS, WF_EXPAND);
    else
      CWIDGET_clear_flag(THIS, WF_EXPAND);

    parent = WIDGET->parentWidget();
    if (parent)
      parent = CWidget::get(parent)->widget;
    if (parent)
      qApp->postEvent(parent, new QEvent(EVENT_EXPAND));
  }

END_PROPERTY


BEGIN_METHOD(CWIDGET_move, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h)

  move_resize_widget(_object, VARG(x), VARG(y), VARGOPT(w, -1), VARGOPT(h, -1));

END_METHOD


BEGIN_METHOD(CWIDGET_resize, GB_INTEGER w; GB_INTEGER h)

  resize_widget(_object, VARG(w), VARG(h));

END_METHOD


BEGIN_METHOD_VOID(CWIDGET_delete)

  //if (WIDGET)
  //  qDebug("CWIDGET_delete: %p (%p)", THIS, WIDGET);

  CWIDGET_destroy(THIS);

END_METHOD


BEGIN_METHOD_VOID(CWIDGET_show)

  QWIDGET(_object)->show();

END_METHOD


BEGIN_METHOD_VOID(CWIDGET_hide)

  QWIDGET(_object)->hide();

END_METHOD


BEGIN_METHOD_VOID(CWIDGET_raise)

  QWIDGET(_object)->raise();

END_METHOD


BEGIN_METHOD_VOID(CWIDGET_lower)

  QWIDGET(_object)->lower();

END_METHOD


BEGIN_PROPERTY(CWIDGET_next)

  QWidget *parent;
  QObjectList *children;
  QObject *current = NULL;

  parent = WIDGET->parentWidget();
  if (parent)
  {
    children = (QObjectList *)WIDGET->parentWidget()->children();
    if (children)
    {
      children->first();
      for(;;)
      {
        current = children->current();
        if (!current)
          break;
        children->next();
        if (current == WIDGET)
        {
            current = children->current();
          break;
                        }
      }
    }
  }

  if (current)
    GB.ReturnObject(CWidget::get(current));
  else
    GB.ReturnNull();

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_previous)

  QWidget *parent;
  QObjectList *children;
  QObject *current = NULL;

  parent = WIDGET->parentWidget();
  if (parent)
  {
    children = (QObjectList *)WIDGET->parentWidget()->children();
    if (children)
    {
      children->first();
      for(;;)
      {
        current = children->current();
        if (!current)
          break;
        children->next();
        if (children->current() == WIDGET)
          break;
      }
    }
  }

  if (current)
    GB.ReturnObject(CWidget::get(current));
  else
    GB.ReturnNull();

END_PROPERTY


BEGIN_METHOD(CWIDGET_refresh, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h)

  int x, y, w, h;

  if (!MISSING(x) && !MISSING(y))
  {
    x = VARG(x);
    y = VARG(y);
    w = VARGOPT(w, QWIDGET(_object)->width());
    h = VARGOPT(h, QWIDGET(_object)->height());
    QWIDGET(_object)->repaint(x, y, w, h);
  }
  else
    QWIDGET(_object)->repaint();

END_METHOD


BEGIN_METHOD_VOID(CWIDGET_set_focus)

  QWidget *toplevel;
  CWINDOW *win;

  toplevel = WIDGET->topLevelWidget();

  if (toplevel->isVisible())
    WIDGET->setFocus();
  else if (toplevel != WIDGET)
  {
    win = (CWINDOW *)CWidget::get(toplevel);
    GB.Unref((void **)&win->focus);
    win->focus = THIS;
    GB.Ref(THIS);
  }

END_METHOD


BEGIN_PROPERTY(CWIDGET_tag)

  if (READ_PROPERTY)
    GB.ReturnPtr(GB_T_VARIANT, &OBJECT(CWIDGET)->tag);
  else
  {
    GB.StoreVariant(PROP(GB_VARIANT), (void *)&(OBJECT(CWIDGET)->tag));
    //printf("Set Tag %p : %i\n", _object, OBJECT(CWIDGET)->tag.type);
  }

END_METHOD


BEGIN_PROPERTY(CWIDGET_mouse)

  QWidget *wid = QWIDGET(_object);
  int shape;

  if (READ_PROPERTY)
  {
    if (wid->ownCursor())
    {
      shape = wid->cursor().shape();
      if (shape == Qt::BitmapCursor)
        GB.ReturnInteger(CMOUSE_CUSTOM);
      else
        GB.ReturnInteger(shape);
    }
    else
      GB.ReturnInteger(CMOUSE_DEFAULT);
  }
  else
    set_mouse(wid, VPROP(GB_INTEGER), THIS->cursor);

END_METHOD


BEGIN_PROPERTY(CWIDGET_cursor)

  if (READ_PROPERTY)
    GB.ReturnObject(THIS->cursor);
  else
  {
    GB.StoreObject(PROP(GB_OBJECT), &THIS->cursor);
    set_mouse(WIDGET, CMOUSE_CUSTOM, THIS->cursor);
  }

END_PROPERTY


#if 0

/*
static QColor get_background(CWIDGET *_object, QWidget *wid)
{
  QPalette pal(wid->palette());
  QColorGroup::ColorRole role = (QColorGroup::ColorRole)OBJECT(CWIDGET)->background;

  return pal.color(QPalette::Active, role);
}

static void test_color(CWIDGET *_object, QWidget *wid)
{
  QColor b, f, bp, fp;

  if (!wid->ownPalette() || !wid->parentWidget())
    return;

  f = wid->paletteForegroundColor();
  fp = wid->parentWidget()->paletteForegroundColor();

  if (f != fp)
    return;

  b = get_background(_object, wid);
  bp = get_background(CWidget::get(wid->parentWidget()), wid->parentWidget());

  if (b != bp)
    return;

  wid->unsetPalette();
}
*/

BEGIN_PROPERTY(CWIDGET_background)

  QWidget *wid = QWIDGET(_object);
  QPalette pal(wid->palette());
  QColorGroup::ColorRole role = (QColorGroup::ColorRole)OBJECT(CWIDGET)->background;

  //qDebug("bm = %d (%d %d)", wid->backgroundMode(), QWidget::PaletteButton, QWidget::PaletteBase);

  if (READ_PROPERTY)
    GB.ReturnInteger(pal.color(QPalette::Active, role).rgb() & 0xFFFFFF);
  else
  {
    pal.setColor(role, QColor((QRgb)VPROP(GB_INTEGER)));
    wid->setPalette(pal);
    //test_color((CWIDGET *)_object, wid);
  }

#if 0
  if (READ_PROPERTY)
    GB.ReturnInteger((long)(WIDGET->paletteBackgroundColor().rgb() & 0xFFFFFF));
  else
    WIDGET->setPaletteBackgroundColor(QColor((QRgb)PROPERTY(long)));
#endif

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_foreground)

  QWidget *wid;

  if (GB.Is(_object, GB.FindClass("Container")))
    wid = ((CCONTAINER *)_object)->container;
  else
    wid = QWIDGET(_object);

  if (READ_PROPERTY)
  {
    GB.ReturnInteger((long)(wid->paletteForegroundColor().rgb() & 0xFFFFFF));
    return;
  }
  else
  {
    QPalette pal(QWIDGET(_object)->palette());

    pal.setColor(QColorGroup::Foreground, QColor((QRgb)VPROP(GB_INTEGER)));
    pal.setColor(QColorGroup::Text, QColor((QRgb)VPROP(GB_INTEGER)));
    wid->setPalette(pal);
    //test_color((CWIDGET *)_object, wid);
  }

END_PROPERTY
#endif

BEGIN_PROPERTY(CWIDGET_background)

  if (READ_PROPERTY)
    GB.ReturnInteger(WIDGET->paletteBackgroundColor().rgb() & 0xFFFFFF);
  else
    WIDGET->setPaletteBackgroundColor(QColor((QRgb)VPROP(GB_INTEGER)));

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_foreground)

  if (READ_PROPERTY)
    GB.ReturnInteger(WIDGET->paletteForegroundColor().rgb() & 0xFFFFFF);
  else
    WIDGET->setPaletteForegroundColor(QColor((QRgb)VPROP(GB_INTEGER)));

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_parent)

  QWidget *parent = QWIDGET(_object)->parentWidget();

  if (!parent)
    GB.ReturnObject(NULL);
  else
    GB.ReturnObject(CWidget::get(parent));

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_window)

  QWidget *wid = WIDGET->topLevelWidget();

  if (!wid)
    GB.ReturnObject(NULL);
  else
    GB.ReturnObject(CWidget::get(wid));

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_id)

  GB.ReturnInteger((long)WIDGET->winId());

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_tooltip)

  char *tooltip;

  if (READ_PROPERTY)
    GB.ReturnString(THIS->tooltip);
  else
  {
    GB.StoreString(PROP(GB_STRING), &(THIS->tooltip));
    tooltip = THIS->tooltip;
    if (tooltip)
      QToolTip::add(WIDGET, TO_QSTRING(tooltip));
    else
      QToolTip::remove(WIDGET);
  }

END_PROPERTY


BEGIN_METHOD_VOID(CWIDGET_grab)

  GB.ReturnObject(CPICTURE_grab(QWIDGET(_object)));

END_METHOD


BEGIN_METHOD(CWIDGET_drag, GB_VARIANT data; GB_STRING format)

  CDRAG_drag(OBJECT(CWIDGET), &VARG(data), MISSING(format) ? NULL : ARG(format));

END_METHOD


BEGIN_PROPERTY(CWIDGET_drop)

  if (READ_PROPERTY)
    GB.ReturnBoolean(WIDGET->acceptDrops());
  else
    WIDGET->setAcceptDrops(VPROP(GB_BOOLEAN));

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_border_full)

  QFrame *wid = (QFrame *)QWIDGET(_object);
  int border, lw;

  if (READ_PROPERTY)
  {
    if (wid->frameStyle() == (QFrame::Box + QFrame::Plain))
      border = BORDER_PLAIN;
    else if (wid->frameStyle() == (QFrame::StyledPanel + QFrame::Sunken))
      border = BORDER_SUNKEN;
    else if (wid->frameStyle() == (QFrame::StyledPanel + QFrame::Raised))
      border = BORDER_RAISED;
    else if (wid->frameStyle() == (QFrame::Box + QFrame::Sunken))
      border = BORDER_ETCHED;
    else
      border = BORDER_NONE;

    GB.ReturnInteger(border);
  }
  else
  {
    lw = 1;

    switch (VPROP(GB_INTEGER))
    {
      case BORDER_PLAIN: border = QFrame::Box + QFrame::Plain; break;
      case BORDER_SUNKEN: border = QFrame::StyledPanel + QFrame::Sunken; lw = 2; break;
      case BORDER_RAISED: border = QFrame::StyledPanel + QFrame::Raised; lw = 2; break;
      case BORDER_ETCHED: border = QFrame::Box + QFrame::Sunken; break;
      default: border = QFrame::NoFrame; break;
    }

    wid->setFrameStyle(border);
    wid->setLineWidth(lw);
    wid->repaint();
  }

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_border_simple)

  QFrame *wid = (QFrame *)QWIDGET(_object);

  if (READ_PROPERTY)
  {
    GB.ReturnBoolean(wid->frameStyle() != QFrame::NoFrame);
  }
  else
  {
    //qDebug("frameStyle = %d", wid->frameStyle());

    if (VPROP(GB_BOOLEAN))
    {
      wid->setFrameStyle(QFrame::LineEditPanel + QFrame::Sunken);
      //wid->setFrameStyle(QFrame::LineEditPanel);
      //wid->setLineWidth(2);
    }
    else
    {
      wid->setFrameStyle(QFrame::NoFrame);
    }

    //qDebug("--> %d", wid->frameStyle());

    wid->repaint();
  }

END_PROPERTY


BEGIN_PROPERTY(CWIDGET_scrollbar)

  QScrollView *wid = (QScrollView *)QWIDGET(_object);
  long scroll;

  if (READ_PROPERTY)
  {
    scroll = 0;
    if (wid->hScrollBarMode() == QScrollView::Auto)
      scroll += 1;
    if (wid->vScrollBarMode() == QScrollView::Auto)
      scroll += 2;

    GB.ReturnInteger(scroll);
  }
  else
  {
    scroll = VPROP(GB_INTEGER) & 3;
    wid->setHScrollBarMode( (scroll & 1) ? QScrollView::Auto : QScrollView::AlwaysOff);
    wid->setVScrollBarMode( (scroll & 2) ? QScrollView::Auto : QScrollView::AlwaysOff);
  }

END_PROPERTY


GB_DESC CWidgetDesc[] =
{
  GB_DECLARE("Control", sizeof(CWIDGET)),

  GB_HOOK_NEW(NULL),
  GB_HOOK_CHECK(CWIDGET_check),

  GB_METHOD("_free", NULL, CWIDGET_delete, NULL),

  GB_METHOD("Move", NULL, CWIDGET_move, "(X)i(Y)i[(Width)i(Height)i]"),
  GB_METHOD("Resize", NULL, CWIDGET_resize, "(Width)i(Height)i"),
  GB_METHOD("Delete", NULL, CWIDGET_delete, NULL),
  GB_METHOD("Show", NULL, CWIDGET_show, NULL),
  GB_METHOD("Hide", NULL, CWIDGET_hide, NULL),

  GB_METHOD("Raise", NULL, CWIDGET_raise, NULL),
  GB_METHOD("Lower", NULL, CWIDGET_lower, NULL),
  //GB_METHOD("MoveUnder", NULL, CWIDGET_move_under, "(Control)Control;"),
  GB_PROPERTY_READ("Next", "Control", CWIDGET_next),
  GB_PROPERTY_READ("Previous", "Control", CWIDGET_previous),

  GB_METHOD("SetFocus", NULL, CWIDGET_set_focus, NULL),
  GB_METHOD("Refresh", NULL, CWIDGET_refresh, "[(X)i(Y)i(Width)i(Height)i]"),
  GB_METHOD("Grab", "Picture", CWIDGET_grab, NULL),
  GB_METHOD("Drag", NULL, CWIDGET_drag, "(Data)v[(Format)s]"),

  GB_PROPERTY("X", "i", CWIDGET_x),
  GB_PROPERTY("Y", "i", CWIDGET_y),
  GB_PROPERTY_READ("ScreenX", "i", CWIDGET_screen_x),
  GB_PROPERTY_READ("ScreenY", "i", CWIDGET_screen_y),
  GB_PROPERTY("W", "i", CWIDGET_w),
  GB_PROPERTY("H", "i", CWIDGET_h),
  GB_PROPERTY("Left", "i", CWIDGET_x),
  GB_PROPERTY("Top", "i", CWIDGET_y),
  GB_PROPERTY("Width", "i", CWIDGET_w),
  GB_PROPERTY("Height", "i", CWIDGET_h),

  //GB_PROPERTY("Name", "s", CWIDGET_name),

  GB_PROPERTY("Visible", "b", CWIDGET_visible),
  GB_PROPERTY("Enabled", "b", CWIDGET_enabled),
  GB_PROPERTY("Expand", "b", CWIDGET_expand),

  GB_PROPERTY("Font", "Font", CWIDGET_font),
  GB_PROPERTY("Background", "i", CWIDGET_background),
  GB_PROPERTY("BackColor", "i", CWIDGET_background),
  GB_PROPERTY("Foreground", "i", CWIDGET_foreground),
  GB_PROPERTY("ForeColor", "i", CWIDGET_foreground),

  GB_PROPERTY("Design", "b", CWIDGET_design),
  GB_PROPERTY("Tag", "v", CWIDGET_tag),
  GB_PROPERTY("Mouse", "i" MOUSE_CONSTANTS, CWIDGET_mouse),
  GB_PROPERTY("Cursor", "Cursor", CWIDGET_cursor),
  GB_PROPERTY("ToolTip", "s", CWIDGET_tooltip),
  GB_PROPERTY("Drop", "b", CWIDGET_drop),

  GB_PROPERTY_READ("Parent", "Container", CWIDGET_parent),
  GB_PROPERTY_READ("Window", "Window", CWIDGET_window),
  GB_PROPERTY_READ("Id", "i", CWIDGET_id),
  GB_PROPERTY_READ("Handle", "i", CWIDGET_id),

  //GB_EVENT("Delete", NULL, NULL, &EVENT_Destroy),
  GB_EVENT("Enter", NULL, NULL, &EVENT_Enter),
  GB_EVENT("GotFocus", NULL, NULL, &EVENT_GotFocus),
  GB_EVENT("LostFocus", NULL, NULL, &EVENT_LostFocus),
  GB_EVENT("KeyPress", NULL, NULL, &EVENT_KeyPress),
  GB_EVENT("KeyRelease", NULL, NULL, &EVENT_KeyRelease),
  GB_EVENT("Leave", NULL, NULL, &EVENT_Leave),
  GB_EVENT("MouseDown", NULL, NULL, &EVENT_MouseDown),
  GB_EVENT("MouseMove", NULL, NULL, &EVENT_MouseMove),
  GB_EVENT("MouseUp", NULL, NULL, &EVENT_MouseUp),
  GB_EVENT("MouseWheel", NULL, NULL, &EVENT_MouseWheel),
  GB_EVENT("DblClick", NULL, NULL, &EVENT_DblClick),
  GB_EVENT("Menu", NULL, NULL, &EVENT_Menu),
  GB_EVENT("Drag", NULL, NULL, &EVENT_Drag),
  GB_EVENT("DragMove", NULL, NULL, &EVENT_DragMove),
  GB_EVENT("Drop", NULL, NULL, &EVENT_Drop),
  //GB_EVENT("Move", NULL, NULL, &EVENT_Move),
  //GB_EVENT("Resize", NULL, NULL, &EVENT_Resize),
  //GB_EVENT("Show", "b", NULL, &EVENT_Show),
  //GB_EVENT("Hide", "b", NULL, &EVENT_Hide),

  GB_CONSTANT("_DefaultEvent", "s", "MouseDown"),
  GB_CONSTANT("_Properties", "s", CWIDGET_PROPERTIES),

  GB_END_DECLARE
};



/* Classe CWidget */

CWidget CWidget::manager;
QPtrDict<CWIDGET> CWidget::dict;
bool CWidget::real;
CWIDGET *CWidget::enter = NULL;
//QPtrDict<char> CWidget::propDict;

bool haveChildren;

void CWidget::installFilter(QObject *o)
{
  QObjectList *children;
  QObject *child;

  children = (QObjectList *)(o->children());

  o->installEventFilter(&manager);

  if (!children)
    return;

  child = children->first();
  while (child)
  {
    if (child->isWidgetType())
    {
      haveChildren = true;
      //child->installEventFilter(&manager);
      CWidget::installFilter(child);
    }

    child = children->next();
  }
}

void CWidget::removeFilter(QObject *o)
{
  QObjectList *children = (QObjectList *)(o->children());
  QObject *child;

  if (!o->isWidgetType())
    return;

  o->removeEventFilter(&manager);

  if (!children)
    return;

  child = children->first();
  while (child)
  {
    //child->installEventFilter(&manager);
    CWidget::removeFilter(child);
    child = children->next();
  }
}


void CWidget::removeFocusPolicy(QWidget *w)
{
  QObjectList *children;
  QObject *child;

  w->setFocusPolicy(QWidget::NoFocus);

  children = (QObjectList *)(w->children());

  if (!children)
    return;

  child = children->first();
  while (child)
  {
    if (child->isWidgetType())
      CWidget::removeFocusPolicy((QWidget *)child);

    child = children->next();
  }
}


void CWidget::add(QObject *o, void *object, bool no_filter)
{
  //if (!no_filter)
  QObject::connect(o, SIGNAL(destroyed()), &manager, SLOT(destroy()));

  dict.insert(o, (CWIDGET *)object);

  if (!no_filter)
  {
    haveChildren = false;
    CWidget::installFilter(o);
    if (haveChildren)
      CWIDGET_set_flag(object, WF_NO_EVENT);
  }


  GB.Ref(object);
}


CWIDGET *CWidget::get(QObject *o)
{
  CWIDGET *ob;

  real = true;

  while (o)
  {
    ob = dict[o];
    if (ob != NULL)
      return ob;

    o = o->parent();
    real = false;
  }

  return NULL;
}

CWIDGET *CWidget::getReal(QObject *o)
{
  return dict[o];
}


QWidget *CWidget::getContainerWidget(CCONTAINER *object)
{
  if (GB.CheckObject(object))
    GB.Propagate();

  if (object->container == NULL)
  {
    GB.Error("Null container");
    GB.Propagate();
  }

  //qDebug("Container = %p", object->container);

  return (object->container);
}


#if 0
void CWidget::setName(CWIDGET *object, const char *name)
{
  QWidget *w = QWIDGET(object);
  CTOPLEVEL *top = (CTOPLEVEL *)CWidget::get(w->topLevelWidget());

  if (QWIDGET(top) == w)
    return;

  if (w->name() != NULL)
  {
    /*qDebug("- %s", w->name());*/
    top->dict->remove(w->name());
  }

  if (name != NULL)
  {
    top->dict->insert((const char *)name, object);
    w->setName(name);
    /*qDebug("+ %s", w->name());*/
  }
}
#endif

void CWidget::resetTooltip(CWIDGET *_object)
{
  QToolTip::remove(WIDGET);

  if (THIS->tooltip)
    QToolTip::add(WIDGET, TO_QSTRING(THIS->tooltip));
}

void CWidget::destroy()
{
  QWidget *w = (QWidget *)sender();
  CWIDGET *ob = CWidget::get(w);
  //MyMainWindow *top = (MyMainWindow *)w->topLevelWidget();

  //if (w->isTopLevel())

  if (ob == NULL)
    return;

  //qDebug(">> CWidget::destroy %p (%p) :%p:%ld", ob, ob->widget, ob->ob.klass, ob->ob.ref);

  //w->blockSignals(TRUE);
  //w->disconnect();

  if (CWIDGET_destroy_list == ob)
    CWIDGET_destroy_list = ob->next;
  if (CWIDGET_destroy_last == ob)
    CWIDGET_destroy_last = ob->prev;
  if (ob->prev)
    ob->prev->next = ob->next;
  if (ob->next)
    ob->next->prev = ob->prev;

  if (enter == ob)
    enter = NULL;

  //printf("#1\n");

  /*
  if (w->inherits("QPushButton"))
  {
    qDebug("Inherits QPushButton");
    top->setDefaultButton((QPushButton *)w, false);
    top->setCancelButton((QPushButton *)w, false);
  }
  */

  //printf("#2\n");

  //CWidget::setName(ob, NULL);
  dict.remove(w);
  QWIDGET(ob) = NULL;

  //printf("#3\n");

  GB.StoreVariant(NULL, &ob->tag);
  GB.FreeString(&ob->tooltip);
  GB.Unref((void **)&ob->cursor);

  // Oblige les widgets n'h�itant pas de Control �poss�er cet ��ement en premier !
  //GB.Raise(ob, EVENT_Destroy, 0);

  //qDebug(">> CWidget::destroy %p (%p) :%p:%ld #2", ob, ob->widget, ob->ob.klass, ob->ob.ref);
  GB.Detach(ob);

  //printf("#4\n");

  //qDebug("<< CWidget::destroy %p (%p)", ob, ob->widget);

  GB.Unref((void **)&ob);
}


static void post_dblclick_event(void *control)
{
  GB.Raise(control, EVENT_DblClick, 0);
  GB.Unref(&control);
}

bool CWidget::eventFilter(QObject *widget, QEvent *event)
{
  CWIDGET *control;
  int event_id;
  int type = event->type();
  bool real;
  bool design;
  bool original;
  int state;
  bool cancel;
  QPoint p;

  control = CWidget::get(widget);
  if (!control)
    goto _STANDARD;

  real = CWidget::real;
  design = CWIDGET_test_flag(control, WF_DESIGN);
  //child = (!real && (widget->children() == 0)) || !CWIDGET_test_flag(control, WF_NO_EVENT);
  original = event->spontaneous(); //QApplication::originalEvent; // event->accepted() || real;

  if (type == QEvent::Enter)
  {
    if (real)
      GB.Raise(control, EVENT_Enter, 0);
  }
  else if (type == QEvent::Leave)
  {
    if (real)
      GB.Raise(control, EVENT_Leave, 0);
  }
  else if (type == QEvent::FocusIn)
  {
    GB.Raise(control, EVENT_GotFocus, 0);
  }
  else if (type == QEvent::FocusOut)
  {
    GB.Raise(control, EVENT_LostFocus, 0);
  }
  else if (type == QEvent::ContextMenu)
  {
    // if (real && GB.CanRaise(control, EVENT_Menu))
    if (GB.CanRaise(control, EVENT_Menu))
    {
      ((QContextMenuEvent *)event)->accept();
      GB.Raise(control, EVENT_Menu, 0);
      return true;
    }
  }
  else if ((type == QEvent::MouseButtonPress)
           || (type == QEvent::MouseButtonRelease)
           || (type == QEvent::MouseMove))
  {
    QMouseEvent *mevent = (QMouseEvent *)event;

    //qDebug("Event on %p %s%s%s", widget,
    //  real ? "REAL " : "", design ? "DESIGN " : "", child ? "CHILD " : "");

    if (!original)
      goto _DESIGN;

    if (type == QEvent::MouseButtonPress)
    {
      event_id = EVENT_MouseDown;
      state = mevent->stateAfter();
      //qDebug("MouseEvent: %d %d", mevent->x(), mevent->y());
    }
    else
    {
      event_id = (type == QEvent::MouseButtonRelease) ? EVENT_MouseUp : EVENT_MouseMove;
      state = mevent->state();
    }

    if (GB.CanRaise(control, event_id))
    {
      p.setX(mevent->globalX());
      p.setY(mevent->globalY());

      //if (event_id != EVENT_MouseMove)
      //  qDebug("X = %d  Y = %d", p.x(), p.y());

      //p = ((QWidget *)widget)->mapTo(QWIDGET(control), p);
      p = QWIDGET(control)->mapFromGlobal(p);

      //if (event_id != EVENT_MouseMove)
      //  qDebug("=> X = %d  Y = %d", p.x(), p.y());

      CMOUSE_clear(true);
      CMOUSE_info.x = p.x();
      CMOUSE_info.y = p.y();
      CMOUSE_info.state = state;

      GB.Raise(control, event_id, 0); //, GB_T_INTEGER, p.x(), GB_T_INTEGER, p.y(), GB_T_INTEGER, state);

      CMOUSE_clear(false);
    }
  }
  else if (type == QEvent::MouseButtonDblClick)
  {
    if (!original)
      goto _DESIGN;

            if (GB.CanRaise(control, EVENT_DblClick))
            {
                  GB.Ref(control);
                  GB.Post((void (*)())post_dblclick_event, (long)control);
            }
  }
  else if ((type == QEvent::KeyPress)
           || (type == QEvent::KeyRelease))
  {
    QKeyEvent *kevent = (QKeyEvent *)event;

    /*if (type == QEvent::KeyPress)
      qDebug("QKeyEvent: %s %p (%d): %p (R%d S%d): %d %s",
        widget->className(), widget, ((QWidget *)widget)->isTopLevel(),
        control, real, original, kevent->key(), (char *)kevent->text().latin1());*/

    #if QT_VERSION <= 0x030005
    if (!real || !original)
      goto _DESIGN;
    #endif

    event_id = (type == QEvent::KeyPress) ? EVENT_KeyPress : EVENT_KeyRelease;

    #if QT_VERSION > 0x030005
    if (!original)
      goto _ACCEL;
    #endif

    //if (type == QEvent::KeyPress)
    //  qDebug("CWINDOW_main = %p", CWINDOW_Main);

    if (GB.CanRaise(control, event_id))
    {
      CKEY_clear(true);

      GB.FreeString(&CKEY_info.text);
      GB.NewString(&CKEY_info.text, TO_UTF8(kevent->text()), 0);
      CKEY_info.state = kevent->state();
      //qDebug("state = %d", CKEY_info.state);
      CKEY_info.code = kevent->key();

      cancel = GB.Raise(control, event_id, 0);

      CKEY_clear(false);

      if (cancel && (type == QEvent::KeyPress))
        return true;
    }

_ACCEL:

    if (event_id == EVENT_KeyPress && CWINDOW_Main && ((QWidget *)widget)->isTopLevel())
    {
      //CWIDGET *top = CWidget::get(((QWidget *)widget)->topLevelWidget());
      CWIDGET *top = CWidget::get((QWidget *)widget);

      //qDebug("top = %p", top);

      if (!CWINDOW_Current && top && top != (CWIDGET *)CWINDOW_Main && QWIDGET(CWINDOW_Main))
      {
        //qDebug("post Accel to %p", CWINDOW_Main);
        //QMAINWINDOW(CWINDOW_Main)->setState(MyMainWindow::StateNormal);
        qApp->postEvent(QWIDGET(CWINDOW_Main),
          new QKeyEvent(QEvent::Accel, kevent->key(), kevent->ascii(), kevent->state(), kevent->text(), kevent->isAutoRepeat(), kevent->count()));
      }
    }
  }
  else if (type == QEvent::Wheel)
  {
    QWheelEvent *ev = (QWheelEvent *)event;

    //qDebug("Event on %p %s%s%s", widget,
    //  real ? "REAL " : "", design ? "DESIGN " : "", child ? "CHILD " : "");

    if (!original)
      goto _DESIGN;

    if (GB.CanRaise(control, EVENT_MouseWheel))
    {
      p.setX(ev->x());
      p.setY(ev->y());

      p = ((QWidget *)widget)->mapTo(QWIDGET(control), p);

      CMOUSE_clear(true);
      CMOUSE_info.x = p.x();
      CMOUSE_info.y = p.y();
      CMOUSE_info.state = ev->state();
      CMOUSE_info.orientation = ev->orientation();
      CMOUSE_info.delta = ev->delta();

      GB.Raise(control, EVENT_MouseWheel, 0);
        //GB_T_INTEGER, p.x(),
        //GB_T_INTEGER, p.y(),
        //GB_T_INTEGER, ev->state(),
        //GB_T_INTEGER, ev->orientation(),
        //GB_T_FLOAT, (double)ev->delta() / 120);

      CMOUSE_clear(false);
    }
  }
  else if (type == QEvent::DragEnter)
  {
    if (GB.CanRaise(control, EVENT_Drag))
    {
      CDRAG_clear(true);
      CDRAG_info.drop = (QDropEvent *)event;

      cancel = GB.Raise(control, EVENT_Drag, 0);
      CDRAG_info.drop->accept(!cancel);

      CDRAG_clear(false);
    }
    else
      ((QDropEvent *)event)->accept();
  }
  else if (type == QEvent::DragMove)
  {
    if (GB.CanRaise(control, EVENT_DragMove))
    {
      QDropEvent *ev = (QDropEvent *)event;
      CDRAG_clear(true);
      CDRAG_info.drop = (QDropEvent *)event;

      p = ev->pos();
      p = ((QWidget *)widget)->mapTo(QWIDGET(control), p);
      CDRAG_info.x = p.x();
      CDRAG_info.y = p.y();

      cancel = GB.Raise(control, EVENT_DragMove, 0);
      CDRAG_info.drop->accept(!cancel);

      CDRAG_clear(false);
    }
  }
  else if (type == QEvent::Drop)
  {
    if (GB.CanRaise(control, EVENT_Drop))
    {
      QDropEvent *ev = (QDropEvent *)event;
      CDRAG_clear(true);
      CDRAG_info.drop = ev;

      p = ev->pos();
      p = ((QWidget *)widget)->mapTo(QWIDGET(control), p);
      CDRAG_info.x = p.x();
      CDRAG_info.y = p.y();

      GB.Raise(control, EVENT_Drop, 0);

      CDRAG_clear(false);
    }
  }

  if (CWIDGET_check(control))
  {
    qDebug("CWidget::eventFilter: %p was destroyed", control);
    return true;
  }

_DESIGN:

  if (design)
  {
    if ((type == QEvent::MouseButtonPress)
        || (type == QEvent::MouseButtonRelease)
        || (type == QEvent::MouseButtonDblClick)
        || (type == QEvent::MouseMove)
        || (type == QEvent::Wheel)
        || (type == QEvent::ContextMenu)
        || (type == QEvent::KeyPress)
        || (type == QEvent::KeyRelease)
        || (type == QEvent::Accel)
        || (type == QEvent::Enter)
        || (type == QEvent::Leave)
        || (type == QEvent::FocusIn)
        || (type == QEvent::FocusOut)
        || (type == QEvent::DragEnter)
        || (type == QEvent::DragMove)
        || (type == QEvent::DragLeave)
        || (type == QEvent::Drop)
        )
    return true;
  }

_STANDARD:

  return QObject::eventFilter(widget, event);    // standard event processing
}


Generated by  Doxygen 1.6.0   Back to index