/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * widget.cc * * Tue Jul 17 12:15:59 CEST 2007 * Copyright 2007 Bent Bisballe Nyeng and Lars Bisballe Jensen * deva@aasimon.org and elsenator@gmail.com ****************************************************************************/ /* * This file is part of Pracro. * * Pracro is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Pracro 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 Pracro; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "widget.h" #include "macrowindow.h" #include "luawidget.h" #include "../widgets.h" #include #include #include "debug.h" Widget::Widget(QDomNode &node, MacroWindow *macrowindow) { widget = NULL; hideChildren = false; QDomElement elem = node.toElement(); this->macrowindow = macrowindow; if(macrowindow) { this->lua = macrowindow->lua; } else { this->lua = NULL; } widget_type = elem.tagName(); if(elem.hasAttribute("name")) { widget_name = elem.attribute("name"); } widget_local = elem.hasAttribute("local") && elem.attribute("local") == "true"; has_lazy = elem.hasAttribute("name") && elem.hasAttribute("value"); lazy_value = elem.attribute("value", ""); lazy_source = elem.attribute("prefilled", "prefilled"); hasOnChangeEvent = elem.hasAttribute("onChange"); onChangeEventScript = elem.attribute("onChange", ""); hasOnInitEvent = elem.hasAttribute("onInit"); onInitEventScript = elem.attribute("onInit", ""); is_valid = true; connect(this, SIGNAL(eventOnChange()), this, SLOT(runEventOnChange()), Qt::QueuedConnection); connect(this, SIGNAL(eventOnInit()), this, SLOT(runEventOnInit()), Qt::QueuedConnection); DEBUG(widget, "Create Widget '%s' of type '%s'\n", name().toStdString().c_str(), type().toStdString().c_str()); } Widget::~Widget() { DEBUG(widget, "Delete Widget '%s' of type '%s'\n", name().toStdString().c_str(), type().toStdString().c_str()); QVector< Widget* >::iterator i = children.begin(); while(i != children.end()) { if(*i) delete *i; i++; } children.clear(); // This MUST be done after the deletion of the children Widget list. if(widget) { delete widget; widget = NULL; } } QString Widget::name() { return widget_name; } QString Widget::type() { return widget_type; } bool Widget::local() { return widget_local; } bool Widget::valid(bool deep) { if(enabled() == false) return true; if(visible() == false) return true; if(preValid() == false) return false; if(is_valid == false) return false; if(hideChildren && deep == false) return true; QVector< Widget* >::iterator i = children.begin(); while(i != children.end()) { if(*i && (*i)->valid() == false) return false; i++; } return true; } void Widget::setValid(bool valid, bool deep) { is_valid = valid; setWdgValid(valid); if(!deep) return; QVector< Widget* >::iterator i = children.begin(); while(i != children.end()) { if(*i) (*i)->setValid(valid, deep); i++; } } void Widget::runEventOnChange(bool deep) { if(enabled()) { //if(preValid() == false) setWdgValid(false); setWdgValid(valid()); if(hasOnChangeEvent) if(lua) lua->runScript(onChangeEventScript, this, "onChange"); } if(!deep) return; QVector< Widget* >::iterator i = children.begin(); while(i != children.end()) { if(*i) (*i)->runEventOnChange(deep); i++; } } void Widget::runEventOnInit(bool deep) { if(enabled()) { //if(preValid() == false) setWdgValid(false); setWdgValid(valid()); if(hasOnInitEvent) if(lua) lua->runScript(onInitEventScript, this, "onInit"); } if(!deep) return; QVector< Widget* >::iterator i = children.begin(); while(i != children.end()) { if(*i) (*i)->runEventOnInit(deep); i++; } } void Widget::setWdgValidRecursive(bool forcevalid) { if(forcevalid) setWdgValid(true); else setWdgValid(valid()); QVector< Widget* >::iterator i = children.begin(); while(i != children.end()) { if(*i) (*i)->setWdgValidRecursive(forcevalid); i++; } } void Widget::setEnabled(bool enabled) { widget->setEnabled(enabled); if(enabled == false) { setWdgValidRecursive(true); // Force all valid } else { setWdgValidRecursive(false); QVector< Widget* >::iterator i = children.begin(); while(i != children.end()) { if(*i) (*i)->runEventOnChange(true); i++; } } } bool Widget::enabled() { return widget->isEnabled(); } void Widget::setVisible(bool visible) { widget->setVisible(visible); if(visible) emit eventOnChange(); QVector< Widget* >::iterator i = children.begin(); while(i != children.end()) { if(*i) (*i)->runEventOnChange(true); i++; } } bool Widget::visible() { return widget->isVisible(); } bool Widget::setKeyboardFocus() { widget->setFocus(); return true; } Widget *Widget::findWidget(QString n, bool deep) { DEBUG(widget, "Find Widget this: %s\n", name().toStdString().c_str()); if(n == name()) return this; if(hideChildren && deep == false) return NULL; QVector< Widget* >::iterator i = children.begin(); while(i != children.end()) { if(*i) { Widget *w = (*i)->findWidget(n, deep); if(w) return w; } i++; } return NULL; } QVector< Widget* > Widget::widgetList(bool deep) { // DEBUG(widget, "Widget List %p\n", this); QVector< Widget* > lst; lst.push_back(this); if(hideChildren && deep == false) return lst; QVector< Widget* >::iterator i = children.begin(); while(i != children.end()) { if(*i) lst += (*i)->widgetList(deep); i++; } return lst; } void Widget::childWasChanged() { emit wasChanged(); } void Widget::addChild(Widget *widget) { if(widget == NULL) { WARN(widget, "Trying to add NULL child to '%s'\n", name().toStdString().c_str()); return; } children.push_back(widget); connect(widget, SIGNAL(wasChanged()), this, SLOT(childWasChanged())); //widget->setParent(this); } void Widget::addChildren(QDomNode &node, QLayout *layout) { QDomNodeList children = node.childNodes(); for(int i = 0; i < children.count(); i++) { QDomNode child = children.at(i); createWidget(child, layout); } } void Widget::setValues() { QVector< Widget* >::iterator i = children.begin(); while(i != children.end()) { if(*i) (*i)->setValues(); i++; } if(has_lazy) setValue(lazy_value, lazy_source); else emit eventOnChange(); // Make sure we run validation on the unset widget. } void Widget::createWidget(QDomNode &xml_node, QLayout *layout) { QDomElement xml_elem = xml_node.toElement(); // TODO: Why do we do this?? if(xml_elem.hasAttribute("prefilled") && xml_elem.attribute("prefilled") != "pracro") { if(macrowindow) macrowindow->macroChanged(); } Widget *widget = NULL; if(xml_elem.tagName() == "spacer") { if(layout) ((QBoxLayout*)layout)->addStretch(); return; // This is not a real widget. } else if(xml_elem.tagName() == "frame") { if(xml_elem.hasAttribute("caption")) { GroupBox *frame = new GroupBox(xml_elem, macrowindow); widget = frame; } else { Frame *frame = new Frame(xml_elem, macrowindow); widget = frame; } } else if(xml_elem.tagName() == "checkgroupbox") { CheckGroupBox *chkgrpbox = new CheckGroupBox(xml_elem, macrowindow); widget = chkgrpbox; } else if(xml_elem.tagName() == "label") { Label *label = new Label(xml_elem, macrowindow); widget = label; } else if(xml_elem.tagName() == "lineedit") { LineEdit *lineedit = new LineEdit(xml_elem, macrowindow); widget = lineedit; } else if(xml_elem.tagName() == "datetime") { DateTime *datetime = new DateTime(xml_elem, macrowindow); widget = datetime; } else if(xml_elem.tagName() == "button") { Button *button = new Button(xml_elem, macrowindow); widget = button; } else if(xml_elem.tagName() == "textedit") { TextEdit *textedit = new TextEdit(xml_elem, macrowindow); widget = textedit; } else if(xml_elem.tagName() == "checkbox") { CheckBox *checkbox = new CheckBox(xml_elem, macrowindow); widget = checkbox; } else if(xml_elem.tagName() == "radiobuttons") { RadioButtons *radiobuttons = new RadioButtons(xml_elem, macrowindow); widget = radiobuttons; } else if(xml_elem.tagName() == "combobox") { ComboBox *combobox = new ComboBox(xml_elem, macrowindow); widget = combobox; } else if(xml_elem.tagName() == "listbox") { ListBox *listbox = new ListBox(xml_elem, macrowindow); widget = listbox; } else if(xml_elem.tagName() == "multilist") { MultiList *multilist = new MultiList(xml_elem, macrowindow); widget = multilist; } else if(xml_elem.tagName() == "altcombobox") { AltComboBox *altcombobox = new AltComboBox(xml_elem, macrowindow); widget = altcombobox; } else if(xml_elem.tagName() == "metawidget") { MetaWidget *metawidget = new MetaWidget(xml_elem, macrowindow); widget = metawidget; } addChild(widget); if(layout) layout->addWidget(widget->qwidget()); if(widget && widget->qwidget()) widget->qwidget()->show(); } int wdg_name(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); lua_pushstring(L, wdgu->widget->name().toStdString().c_str()); return 1; } int wdg_type(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); // return error code lua_pushstring(L, wdgu->widget->type().toStdString().c_str()); return 1; } int wdg_value(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); lua_pushstring(L, wdgu->widget->value().toStdString().c_str()); return 1; } int wdg_set_value(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); const char *val = luaL_checkstring(L, 2); wdgu->widget->setValue(val, LUA_SRC); return 0; } int wdg_enabled(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); lua_pushboolean(L, wdgu->widget->enabled()); return 1; } int wdg_set_enabled(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); bool val = luaL_checkbool(L, 2); wdgu->widget->setEnabled(val); return 0; } int wdg_visible(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); lua_pushboolean(L, wdgu->widget->visible()); return 1; } int wdg_set_visible(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); bool val = luaL_checkbool(L, 2); wdgu->widget->setVisible(val); return 0; } int wdg_valid(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); lua_pushboolean(L, wdgu->widget->valid()); return 1; } int wdg_set_valid(lua_State *L) { wdg_userdata *wdgu; wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "ComboBox"); if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "LineEdit"); luaL_argcheck(L, wdgu, 1, "widget expected"); bool val = luaL_checkbool(L, 2); wdgu->widget->setValid(val); return 0; }