diff options
author | deva <deva> | 2009-01-13 09:59:22 +0000 |
---|---|---|
committer | deva <deva> | 2009-01-13 09:59:22 +0000 |
commit | 9fcf15a06b9ec422dbad53508e8ce71d2d4145c3 (patch) | |
tree | d54147e52b1939ba9ebaf356e7047dfebea02887 | |
parent | 9d982a5b4fc9c7efaa56c8f7a4130361f26b0302 (diff) |
A huge amount of changes, based on the results of two usertest.
The changes are contained (but not limited to) in the following list:
- Make disabled widgets ignored in validation test.
- Do not commit values of disabled widgets to the database.
- Make storechildren attribute on metawidget, that enables storing of the child widgets in the database.
- Implement LUA resume generator.
- Make language attribute on resume tag, and switch parser (format/LUA).
- Case insensitive search in combobox.
- Click on macro name or line, expands macro.
- Greyed out widgets in AltComboBox should be hidden instead.
- Keyboard 'delete' should delete item from multilist.
- "Commit" button needs to be more visible? Icon?
- Upon opening of a second macro, the first macro should indicate itself as 'not saved'.
- After 'add' in multilist, the input widgets should be reset.
- First widget in a macro should have keyboard focus after expansion.
- "Endnu ikke udfyldt" needs to be more clear (darker).
- Meta widgets must recurse the isValid() call to its children.
- Greyed out widgets must be hidden.
- Multilist should be read as a list prior to its input fields.
- Visible field on widgets. Hides a widget without disabling it.
54 files changed, 1470 insertions, 234 deletions
diff --git a/client/client.pro b/client/client.pro index 61b63fb..6df6c3f 100644 --- a/client/client.pro +++ b/client/client.pro @@ -28,6 +28,7 @@ HEADERS += \ lua.h \ macrowindow.h \ mainwindow.h \ + macrodrawer.h \ netcom.h \ resumewidget.h \ widgetbuilder.h \ @@ -39,6 +40,7 @@ HEADERS += \ widgets/multilist.h \ widgets/textedit.h \ widgets/button.h \ + widgets/datetime.h \ widgets/dbwidget.h \ widgets/combobox.h \ widgets/listbox.h \ @@ -58,6 +60,7 @@ SOURCES += \ lua.cc \ macrowindow.cc \ mainwindow.cc \ + macrodrawer.cc \ netcom.cc \ resumewidget.cc \ widgetbuilder.cc \ @@ -69,6 +72,7 @@ SOURCES += \ widgets/textedit.cc \ widgets/button.cc \ widgets/combobox.cc \ + widgets/datetime.cc \ widgets/dbwidget.cc \ widgets/listbox.cc \ widgets/frame.cc \ diff --git a/client/collapser.cc b/client/collapser.cc index e06a5cf..ff1ab69 100644 --- a/client/collapser.cc +++ b/client/collapser.cc @@ -107,6 +107,8 @@ void Collapser::setCollapsed(bool setcollapsed) void Collapser::collapse() { + emit collapsing(); + t_anim.start(); is_collapsed = true; @@ -116,6 +118,8 @@ void Collapser::collapse() void Collapser::expand() { + emit expanding(); + t_anim.start(); // show expanded diff --git a/client/collapser.h b/client/collapser.h index fa25dd5..2a3581b 100644 --- a/client/collapser.h +++ b/client/collapser.h @@ -51,6 +51,10 @@ public slots: void expand(); void toggleCollapse(); +signals: + void collapsing(); + void expanding(); + protected: void timerEvent(QTimerEvent *); diff --git a/client/icons/arrows.png b/client/icons/arrows.png Binary files differindex ae56b01..960824b 100644 --- a/client/icons/arrows.png +++ b/client/icons/arrows.png diff --git a/client/lua.cc b/client/lua.cc index 9494ee2..2dcd279 100644 --- a/client/lua.cc +++ b/client/lua.cc @@ -119,7 +119,7 @@ static int _setValue(lua_State *L) int n = lua_gettop(L); // number of arguments if(n != 2) { char errstr[512]; - sprintf(errstr, "Number of args expected 0, got %d", n); + sprintf(errstr, "Number of args expected 2, got %d", n); lua_pushstring(L, errstr); lua_error(L); return 0; @@ -144,6 +144,37 @@ static int _setValue(lua_State *L) return 0; } +static int _setVisible(lua_State *L) +{ + int n = lua_gettop(L); // number of arguments + if(n != 2) { + char errstr[512]; + sprintf(errstr, "Number of args expected 2, got %d", n); + lua_pushstring(L, errstr); + lua_error(L); + return 0; + } + + bool value = lua_toboolean(L, lua_gettop(L)); + lua_pop(L, 1); + QString name = lua_tostring(L, lua_gettop(L)); + lua_pop(L, 1); + + lua_getglobal(L, GLOBAL_POINTER); + LUA *lua = (LUA*)lua_touserdata(L, lua_gettop(L)); + + if(!lua) { + lua_pushstring(L, "No LUA pointer!"); + lua_error(L); + return 1; + } + + lua->setVisible(name, value); + + return 0; +} + + LUA::LUA(MacroWindow *macrowindow) { this->macrowindow = macrowindow; @@ -163,6 +194,7 @@ LUA::LUA(MacroWindow *macrowindow) lua_register(L, "setValue", _setValue); lua_register(L, "enable", _enable); lua_register(L, "disable", _disable); + lua_register(L, "setVisible", _setVisible); } LUA::~LUA() @@ -180,19 +212,25 @@ QString LUA::getValue(QString name) void LUA::setValue(QString name, QString value) { Widget *widget = macrowindow->getWidget(name); - if(widget) return widget->setValue(value); + if(widget) widget->setValue(value); } void LUA::enable(QString name) { Widget *widget = macrowindow->getWidget(name); - if(widget) return widget->enable(); + if(widget) widget->enable(); } void LUA::disable(QString name) { Widget *widget = macrowindow->getWidget(name); - if(widget) return widget->disable(); + if(widget) widget->disable(); +} + +void LUA::setVisible(QString name, bool value) +{ + Widget *widget = macrowindow->getWidget(name); + if(widget) widget->setVisibility(value); } bool LUA::run(QString program, QString name, QString value) diff --git a/client/lua.h b/client/lua.h index a3867ca..4777dd4 100644 --- a/client/lua.h +++ b/client/lua.h @@ -45,6 +45,7 @@ public: void setValue(QString name, QString value); void enable(QString name); void disable(QString name); + void setVisible(QString name, bool value); void error(QString message); diff --git a/client/macrodrawer.cc b/client/macrodrawer.cc new file mode 100644 index 0000000..97868f8 --- /dev/null +++ b/client/macrodrawer.cc @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * macrodrawer.cc + * + * Tue Jan 6 15:49:48 CET 2009 + * Copyright 2009 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * 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 "macrodrawer.h" + +#include <QPushButton> + +MacroDrawer::MacroDrawer(MacroWindow *p, QString title) +{ + installEventFilter(this); + mw = p; + + if(!mw->isstatic) setTitle(" " + title); + setFlat(true); + + { + QFont f = font(); + f.setItalic(true); + setFont(f); + } + + if(!mw->isstatic) { + QPushButton *b = new QPushButton("±", this); + b->setFixedSize(16,16); + b->move(0,0); + { + QFont f = b->font(); + f.setBold(false); + f.setItalic(false); + b->setFont(f); + } + + connect(b, SIGNAL(clicked()), mw, SLOT(toggleMacro())); + } +} + +bool MacroDrawer::eventFilter(QObject *obj, QEvent *event) +{ + if(event->type() == QEvent::MouseButtonRelease) { + QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); + if(mouseEvent->y() < 16) mw->toggleMacro(); // Only activate when clicking the top. + } + return QObject::eventFilter(obj, event); +} diff --git a/client/macrodrawer.h b/client/macrodrawer.h new file mode 100644 index 0000000..b634198 --- /dev/null +++ b/client/macrodrawer.h @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * macrodrawer.h + * + * Tue Jan 6 15:49:48 CET 2009 + * Copyright 2009 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * 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. + */ +#ifndef __PRACRO_MACRODRAWER_H__ +#define __PRACRO_MACRODRAWER_H__ + +#include <QGroupBox> +#include <QString> +#include "macrowindow.h" + +class MacroDrawer : public QGroupBox { +Q_OBJECT +public: + MacroDrawer(MacroWindow *p, QString title); + +protected: + bool eventFilter(QObject *obj, QEvent *event); + +private: + MacroWindow *mw; +}; + +#endif/*__PRACRO_MACRODRAWER_H__*/ diff --git a/client/macrowindow.cc b/client/macrowindow.cc index ac44b06..2206929 100644 --- a/client/macrowindow.cc +++ b/client/macrowindow.cc @@ -47,6 +47,8 @@ MacroWindow::MacroWindow(NetCom *netcom, QDomNode &xml_doc, QString course, bool collapsed, bool compact) : Collapser() { + waschanged = false; + this->course = course; this->netcom = netcom; @@ -115,7 +117,7 @@ void MacroWindow::initMacro(QDomNode &node) widgets += widgetBuilder(child, mainwidget, this); } - // Insert their values (this must be done last for lua progs to work properly) + // Insert their values (this must be done last for scripts to work properly) for (int i=0; i<children.count();i++) { QDomNode child = children.at(i); setValues(child, this); @@ -140,7 +142,7 @@ bool MacroWindow::doCommit() QVector< Widget* >::iterator i = widgets.begin(); while (i != widgets.end()) { Widget* w = *i; - if(!w->isValid()) faulty++; // Regexp check, returns valid if entry passed + if(!w->isDisabled() && !w->isValid()) faulty++; // Regexp check, returns valid if entry passed i++; } @@ -167,24 +169,40 @@ void MacroWindow::commit() // close(); } else { QMessageBox::critical(NULL, "Fejl", - "Makroen er ikke udfyldt korrekt, prøv igen.\n" + "Makroen " + macrotitle + " er ikke udfyldt korrekt, prøv igen.\n" , QMessageBox::Ok); } } void MacroWindow::reset() { + /* QMessageBox::warning(NULL, tr("Reset"), tr("Du har valgt at nulstille de indtastede data.\n" "Er du sikker?"), QMessageBox::Yes | QMessageBox::Cancel); printf("MacroWindow -> resetting...\n"); + */ + QVector< Widget* >::iterator i = widgets.begin(); + while (i != widgets.end()) { + Widget* w = *i; + w->reset(); + i++; + } + + QVector< Widget* >::iterator j = auxwidgets.begin(); + while (j != auxwidgets.end()) { + Widget* w = *j; + w->reset(); + j++; + } + + waschanged = false; } void MacroWindow::cancel() { - printf("MacroWindow -> cancelling...\n"); - // close(); + collapseWrapper(); } void MacroWindow::cont(QString name) @@ -208,7 +226,7 @@ void MacroWindow::cont(QString name) // close(); } else { QMessageBox::critical(NULL, "Fejl", - "Makroen er ikke udfyldt korrekt, prøv igen.\n", + "Makroen " + macrotitle + " er ikke udfyldt korrekt, prøv igen.\n", QMessageBox::Ok); } printf("%s : MacroWindow -> continuing...\n", macro.toStdString().c_str()); @@ -235,7 +253,7 @@ void MacroWindow::cont_nocommit(QString name) // close(); } else { QMessageBox::critical(NULL, "Fejl", - "Makroen er ikke udfyldt korrekt, prøv igen.\n", + "Makroen " + macrotitle + " er ikke udfyldt korrekt, prøv igen.\n", QMessageBox::Ok); } printf("%s : MacroWindow -> continuing...\n", macro.toStdString().c_str()); @@ -272,49 +290,105 @@ void MacroWindow::addAuxWidgets(QVector< Widget* > ws) auxwidgets += ws; } -void MacroWindow::toggleMacro() +void MacroWindow::addWidgets(QVector< Widget* > ws) { - if(isCollapsed()) { - widgets.clear(); - auxwidgets.clear(); - luaprograms.clear(); + widgets += ws; +} - QDomDocument xml_doc = netcom->send(course, macro); +void MacroWindow::expandWrapper() +{ + if(!isCollapsed()) return; - // - // TODO: This is where the dependency checking should occur. - // + widgets.clear(); + auxwidgets.clear(); + luaprograms.clear(); + waschanged = false; + + QDomDocument xml_doc = netcom->send(course, macro); + + // + // TODO: This is where the dependency checking should occur. + // + + // Initiate the new macro window with the xml document and push + // it to the window list + QDomNodeList courses = xml_doc.documentElement().childNodes(); + QDomNode coursenode = courses.at(0); // There can be only one! (Swush, flomp) + QDomNodeList macronodes = coursenode.childNodes(); + for(int j = 0; j < macronodes.count(); j++) { + QDomNode macronode = macronodes.at(j); - // Initiate the new macro window with the xml document and push - // it to the window list - QDomNodeList courses = xml_doc.documentElement().childNodes(); - QDomNode coursenode = courses.at(0); // There can be only one! (Swush, flomp) - QDomNodeList macronodes = coursenode.childNodes(); - for(int j = 0; j < macronodes.count(); j++) { - QDomNode macronode = macronodes.at(j); + if(true || macronode.childNodes().count()) { + // macrowindows.push_back( new MacroWindow( netcom, macronode ) ); + QDomElement xml_elem = macronode.toElement(); - if(true || macronode.childNodes().count()) { - // macrowindows.push_back( new MacroWindow( netcom, macronode ) ); - QDomElement xml_elem = macronode.toElement(); + if(xml_elem.tagName() == "macro") { - if(xml_elem.tagName() == "macro") { - - // Assign the macro name and version to QStrings for use when comitting - QString macroname; - if(xml_elem.hasAttribute("name")) { - if(xml_elem.attribute("name") == macro) { - // update me! - initMacro(macronode); - } + // Assign the macro name and version to QStrings for use when comitting + QString macroname; + if(xml_elem.hasAttribute("name")) { + if(xml_elem.attribute("name") == macro) { + // update me! + initMacro(macronode); } - } - } + } + } } - setExpandedWidget(mainwidget); - expand(); + } + setExpandedWidget(mainwidget); + expand(); + + QVector< Widget* >::iterator i = widgets.begin(); + while (i != widgets.end()) { + Widget* w = *i; + if(w->setKeyboardFocus()) break; + i++; + } +} +void MacroWindow::collapseWrapper() +{ + if(isCollapsed()) return; + + if(waschanged) { + switch(QMessageBox::warning(NULL, + "Gem ændringerne i makroen?", + "Du har valgt at lukke makroen " + macrotitle + ".\n" + "Ønsker du at gemme inden du lukker?", + QMessageBox::Save | QMessageBox::Close | QMessageBox::Cancel)) { + case QMessageBox::Save: + if(doCommit()) setCollapsed(true); + else QMessageBox::critical(NULL, + "Fejl", + "Makroen " + macrotitle + " er ikke udfyldt korrekt, prøv igen.\n", + QMessageBox::Ok); + + break; + case QMessageBox::Close: + collapse(); + break; + case QMessageBox::Cancel: + default: + // emit expanding(); // signal the other to close again (if any) + break; + } } else { collapse(); - } } + +void MacroWindow::toggleMacro() +{ + if(isCollapsed()) { + expandWrapper(); + } else { + collapseWrapper(); + } +} + +void MacroWindow::macroChanged() +{ + printf("This macro was changed!\n"); + emit macroHasChanged(); + waschanged = true; +} diff --git a/client/macrowindow.h b/client/macrowindow.h index 76d068c..c34c978 100644 --- a/client/macrowindow.h +++ b/client/macrowindow.h @@ -58,11 +58,17 @@ public: LUA *lua; Widget *getWidget(QString name); + + // Add a widget that can be seen from script, and will be committed, and validated. + void addWidgets(QVector< Widget* >); + + // Add a widget that can only be seen from scripts, but will not be committed or validated. void addAuxWidgets(QVector< Widget* >); void update(QDomNode &xml_doc); QString macrotitle; + bool isstatic; public slots: void commit(); @@ -73,8 +79,14 @@ public slots: void toggleMacro(); + void macroChanged(); + + void collapseWrapper(); + void expandWrapper(); + signals: void updateOnCommit(); + void macroHasChanged(); private: void initMacro(QDomNode &node); @@ -92,6 +104,8 @@ private: void close(); NetCom *netcom; + + bool waschanged; }; #endif/*__PRACRO_MACROWINDOW_H__*/ diff --git a/client/mainwindow.cc b/client/mainwindow.cc index 86de48a..639c9d0 100644 --- a/client/mainwindow.cc +++ b/client/mainwindow.cc @@ -34,15 +34,20 @@ #include <QHBoxLayout> #include <QLabel> #include <QPushButton> -#include <QGroupBox> #include <QScrollArea> +#include <QSettings> +#include <QStatusBar> + +#include "macrodrawer.h" MainWindow::MainWindow(QString cpr, QString course, QString host, quint16 port, QString user) - : netcom(host, port, user, cpr) + : QMainWindow(0, Qt::WindowContextHelpButtonHint), + netcom(host, port, user, cpr) { - resize(768, 1024); + setWindowTitle("Pracro - " + cpr); - setWindowFlags(windowFlags() | Qt::WindowContextHelpButtonHint ); + QStatusBar *status = statusBar(); + status->addPermanentWidget(new QLabel("Pracro v.1.0.0 - test2")); QScrollArea *s = new QScrollArea(); setCentralWidget(s); @@ -54,14 +59,33 @@ MainWindow::MainWindow(QString cpr, QString course, QString host, quint16 port, this->course = course; init(); + + status->showMessage("Makroen blev succesfuldt indlæst."); } MainWindow::~MainWindow() { } +void MainWindow::closeEvent(QCloseEvent *) +{ + QSettings settings("Aasimon.org", "Pracro"); + + settings.beginGroup("MainWindow"); + settings.setValue("size", size()); + settings.setValue("pos", pos()); + settings.endGroup(); +} + void MainWindow::init() { + QSettings settings("Aasimon.org", "Pracro"); + + settings.beginGroup("MainWindow"); + resize(settings.value("size", QSize(700, 800)).toSize()); + move(settings.value("pos", QPoint(0, 0)).toPoint()); + settings.endGroup(); + initialising = true; update(); initialising = false; @@ -108,31 +132,10 @@ void MainWindow::update() if(xml_elem.attribute("static", "false") == "true") isstatic = true; if(xml_elem.attribute("compact", "false") == "true") iscompact = true; macros[macroname] = new MacroWindow(&netcom, macronode, course, !isstatic, iscompact); + macros[macroname]->isstatic = isstatic; - QGroupBox *g = new QGroupBox(); - g->setTitle(" " + xml_elem.attribute("caption", macroname)); - g->setFlat(true); - { - QFont f = g->font(); - //f.setBold(true); - f.setItalic(true); - g->setFont(f); - } + MacroDrawer *g = new MacroDrawer(macros[macroname], xml_elem.attribute("caption", macroname)); ((QBoxLayout*)w->layout())->addWidget(g); - - if(!isstatic) { - QPushButton *b = new QPushButton("±", g); - b->setFixedSize(16,16); - b->move(0,0); - { - QFont f = b->font(); - f.setBold(false); - f.setItalic(false); - b->setFont(f); - } - - connect(b, SIGNAL(clicked()), macros[macroname], SLOT(toggleMacro())); - } QHBoxLayout *l = new QHBoxLayout(); l->setContentsMargins(10,0,10,0); @@ -145,6 +148,7 @@ void MainWindow::update() f.setItalic(false); macros[macroname]->setFont(f); } + } else { macros[macroname]->update(macronode); @@ -155,5 +159,26 @@ void MainWindow::update() } } } -} + // Make sure that all macros will collapse when a new one is expanded. + QMap< QString, MacroWindow* >::iterator i = macros.begin(); + while(i != macros.end()) { + MacroWindow *m1 = i.value(); + + QMap< QString, MacroWindow* >::iterator j = macros.begin(); + while(j != macros.end()) { + MacroWindow *m2 = j.value(); + + if(m1 != m2 && m2->isstatic == false) { + // Remove old connection (if any), to avoid multiple connections. + disconnect(m1, SIGNAL(expanding()), m2, SLOT(collapseWrapper())); + + connect(m1, SIGNAL(expanding()), m2, SLOT(collapseWrapper())); + } + + j++; + } + + i++; + } +} diff --git a/client/mainwindow.h b/client/mainwindow.h index f4b12ec..f23ade1 100644 --- a/client/mainwindow.h +++ b/client/mainwindow.h @@ -39,6 +39,8 @@ public: MainWindow(QString cpr, QString course, QString host, quint16 port, QString user); ~MainWindow(); + void closeEvent(QCloseEvent *event); + public slots: void update(); @@ -52,7 +54,6 @@ private: bool initialising; void init(); - }; #endif/*__PRACRO_MAINWINDOW_H__*/ diff --git a/client/netcom.cc b/client/netcom.cc index ab2446e..b6b5bd9 100644 --- a/client/netcom.cc +++ b/client/netcom.cc @@ -101,7 +101,6 @@ void NetCom::send(QVector< Widget* > widgets, QString macro, QString version) printf("Socket state: %d\n", socket.state()); if(socket.state() != 3) printf("Socket state not connected: %s\n", socket.errorString().toStdString().c_str()); - qApp->activeWindow()->setEnabled(false); if(qApp->activeWindow()) qApp->activeWindow()->setEnabled(false); QDomDocument doc; @@ -125,10 +124,12 @@ void NetCom::send(QVector< Widget* > widgets, QString macro, QString version) while (i != widgets.end()) { Widget* w = *i; - QDomElement field_elem = doc.createElement("field"); - field_elem.setAttribute("name", w->getName()); - field_elem.setAttribute("value", w->getValue()); - commit_elem.appendChild(field_elem); + if(!w->isDisabled()) { + QDomElement field_elem = doc.createElement("field"); + field_elem.setAttribute("name", w->getName()); + field_elem.setAttribute("value", w->getValue()); + commit_elem.appendChild(field_elem); + } i++; } diff --git a/client/resumewidget.cc b/client/resumewidget.cc index f43c4df..6877c54 100644 --- a/client/resumewidget.cc +++ b/client/resumewidget.cc @@ -42,7 +42,7 @@ ResumeWidget::ResumeWidget(bool compact) this->compact = compact; setLayout(new QHBoxLayout()); layout()->setContentsMargins(10,2,2,2); - resume = new QLabel("<font style='color: #ccc;'>Endnu ikke udfyldt</font>"); + resume = new QLabel("<font style='color: #bbb;'>Endnu ikke udfyldt</font>"); #ifdef RICH resume->setTextFormat(Qt::RichText); diff --git a/client/widgetbuilder.cc b/client/widgetbuilder.cc index 3d47d41..848157c 100644 --- a/client/widgetbuilder.cc +++ b/client/widgetbuilder.cc @@ -28,7 +28,8 @@ #include <QLayout> #include "widgets.h" -QVector< Widget* > widgetBuilder(QDomNode xml_node, QWidget *parent, MacroWindow *macrowindow) +QVector< Widget* > widgetBuilder(QDomNode xml_node, QWidget *parent, + MacroWindow *macrowindow, bool watchChanges) { QVector< Widget* > widgets; @@ -42,11 +43,11 @@ QVector< Widget* > widgetBuilder(QDomNode xml_node, QWidget *parent, MacroWindow } else if(xml_elem.tagName() == "frame") { if(xml_elem.hasAttribute("caption")) { GroupBox *frame = new GroupBox(xml_elem, macrowindow); - widgets.push_back(frame); + // widgets.push_back(frame); widget = frame; } else { Frame *frame = new Frame(xml_elem, macrowindow); - widgets.push_back(frame); + // widgets.push_back(frame); widget = frame; } @@ -58,63 +59,91 @@ QVector< Widget* > widgetBuilder(QDomNode xml_node, QWidget *parent, MacroWindow LineEdit *lineedit = new LineEdit(xml_elem, macrowindow); widgets.push_back(lineedit); widget = lineedit; + if(watchChanges) + lineedit->connectFrom(SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged())); + + } else if(xml_elem.tagName() == "datetime") { + DateTime *datetime = new DateTime(xml_elem, macrowindow); + widgets.push_back(datetime); + widget = datetime; + if(watchChanges) + datetime->connectFrom(SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged())); } else if(xml_elem.tagName() == "button") { Button *button = new Button(xml_elem, macrowindow); //macrowindow->connect(pushbutton, SIGNAL(act_continue()), main, SLOT(get_macro())); - macrowindow->connect(button, SIGNAL(act_commit()), macrowindow, SLOT(commit())); - macrowindow->connect(button, SIGNAL(act_reset()), macrowindow, SLOT(reset())); - macrowindow->connect(button, SIGNAL(act_cancel()), macrowindow, SLOT(cancel())); - macrowindow->connect(button, SIGNAL(act_continue(QString)), macrowindow, SLOT(cont(QString))); - macrowindow->connect(button, SIGNAL(act_continue_nocommit(QString)), - macrowindow, SLOT(cont_nocommit(QString))); + QObject::connect(button, SIGNAL(act_commit()), macrowindow, SLOT(commit())); + QObject::connect(button, SIGNAL(act_reset()), macrowindow, SLOT(reset())); + QObject::connect(button, SIGNAL(act_cancel()), macrowindow, SLOT(cancel())); + QObject::connect(button, SIGNAL(act_continue(QString)), macrowindow, SLOT(cont(QString))); + QObject::connect(button, SIGNAL(act_continue_nocommit(QString)), + macrowindow, SLOT(cont_nocommit(QString))); + QObject::connect(macrowindow, SIGNAL(macroHasChanged()), button, SLOT(do_enable())); widget = button; } else if(xml_elem.tagName() == "textedit") { TextEdit *textedit = new TextEdit(xml_elem, macrowindow); widgets.push_back(textedit); widget = textedit; + if(watchChanges) + QObject::connect(textedit, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged())); } else if(xml_elem.tagName() == "checkbox") { CheckBox *checkbox = new CheckBox(xml_elem, macrowindow); widgets.push_back(checkbox); widget = checkbox; + if(watchChanges) + QObject::connect(checkbox, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged())); } else if(xml_elem.tagName() == "radiobuttons") { RadioButtons *radiobuttons = new RadioButtons(xml_elem, macrowindow); widgets.push_back(radiobuttons); widget = radiobuttons; + if(watchChanges) + QObject::connect(radiobuttons, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged())); //return; // Don't iterate children } else if(xml_elem.tagName() == "combobox") { ComboBox *combobox = new ComboBox(xml_elem, macrowindow); widgets.push_back(combobox); widget = combobox; + if(watchChanges) + QObject::connect(combobox, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged())); //return; // Don't iterate children } else if(xml_elem.tagName() == "dbwidget") { DBWidget *dbwidget = new DBWidget(xml_elem, macrowindow); widgets.push_back(dbwidget); widget = dbwidget; + if(watchChanges) + QObject::connect(dbwidget, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged())); } else if(xml_elem.tagName() == "listbox") { ListBox *listbox = new ListBox(xml_elem, macrowindow); widgets.push_back(listbox); widget = listbox; + if(watchChanges) + QObject::connect(listbox, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged())); //return; // Don't iterate children + } else if(xml_elem.tagName() == "multilist") { MultiList *multilist = new MultiList(xml_elem, macrowindow); widgets.push_back(multilist); widget = multilist; + if(watchChanges) + QObject::connect(multilist, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged())); if(parent && widget && parent->layout()) parent->layout()->addWidget(widget); if(widget) widget->show(); return widgets; // Don't iterate children + } else if(xml_elem.tagName() == "altcombobox") { AltComboBox *altcombobox = new AltComboBox(xml_elem, macrowindow); widgets.push_back(altcombobox); widget = altcombobox; + if(watchChanges) + QObject::connect(altcombobox, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged())); if(parent && widget && parent->layout()) parent->layout()->addWidget(widget); if(widget) widget->show(); @@ -124,6 +153,8 @@ QVector< Widget* > widgetBuilder(QDomNode xml_node, QWidget *parent, MacroWindow MetaWidget *metawidget = new MetaWidget(xml_elem, macrowindow); widgets.push_back(metawidget); widget = metawidget; + if(watchChanges) + QObject::connect(metawidget, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged())); if(parent && widget && parent->layout()) parent->layout()->addWidget(widget); if(widget) widget->show(); @@ -135,7 +166,7 @@ QVector< Widget* > widgetBuilder(QDomNode xml_node, QWidget *parent, MacroWindow for (int i=0; i<children.count();i++) { QDomNode child = children.at(i); - widgets += widgetBuilder(child, widget, macrowindow); + widgets += widgetBuilder(child, widget, macrowindow, watchChanges); } if(parent && widget && parent->layout()) parent->layout()->addWidget(widget); @@ -152,7 +183,7 @@ void setValues(QDomNode xml_node, MacroWindow *macrowindow) if(xml_elem.hasAttribute("name") && xml_elem.hasAttribute("value")) { Widget *widget = macrowindow->getWidget(xml_elem.attribute("name")); - if(widget) widget->setValue(xml_elem.attribute("value")); + if(widget) widget->setValue(xml_elem.attribute("value"), xml_elem.attribute("prefilled", "")); } QDomNodeList children = xml_node.childNodes(); diff --git a/client/widgetbuilder.h b/client/widgetbuilder.h index 21bf15e..7b77e67 100644 --- a/client/widgetbuilder.h +++ b/client/widgetbuilder.h @@ -33,7 +33,8 @@ #include "widgets/widget.h" #include "macrowindow.h" -QVector< Widget* > widgetBuilder(QDomNode xml_node, QWidget *parent, MacroWindow *macrowindow); +QVector< Widget* > widgetBuilder(QDomNode xml_node, QWidget *parent, + MacroWindow *macrowindow, bool watchChanges = true); void setValues(QDomNode xml_node, MacroWindow *macrowindow); #endif/*__PRACRO_WIDGETBUILDER_H__*/ diff --git a/client/widgets.h b/client/widgets.h index dda0213..bc0a83b 100644 --- a/client/widgets.h +++ b/client/widgets.h @@ -32,6 +32,7 @@ #include "widgets/lineedit.h" #include "widgets/textedit.h" #include "widgets/button.h" +#include "widgets/datetime.h" #include "widgets/dbwidget.h" #include "widgets/combobox.h" #include "widgets/listbox.h" diff --git a/client/widgets/altcombobox.cc b/client/widgets/altcombobox.cc index 01fd36f..c68f816 100644 --- a/client/widgets/altcombobox.cc +++ b/client/widgets/altcombobox.cc @@ -33,6 +33,7 @@ #include "widgetbuilder.h" #include <QObject> +#include "multilist.h" AltComboBox::AltComboBox(QDomNode &node, MacroWindow *macrowindow) : QFrame(), Widget(node, macrowindow) @@ -45,7 +46,11 @@ AltComboBox::AltComboBox(QDomNode &node, MacroWindow *macrowindow) combobox = new ComboBox(node, macrowindow); layout()->addWidget(combobox); combobox->show(); - + + altframerepl = new QFrame(); + QHBoxLayout *l = new QHBoxLayout(); + altframerepl->setLayout(l); + l->addStretch(); altframe = new QFrame(); layout()->addWidget(altframe); @@ -87,7 +92,7 @@ AltComboBox::AltComboBox(QDomNode &node, MacroWindow *macrowindow) QDomNodeList children = item.childNodes(); for(int i = 0; i < children.count(); i++) { QDomNode child = children.at(i); - widgets += widgetBuilder(child, altframe, macrowindow); + widgets += widgetBuilder(child, altframe, macrowindow, false); } } @@ -108,22 +113,31 @@ AltComboBox::AltComboBox(QDomNode &node, MacroWindow *macrowindow) iwname.toStdString().c_str()); } + // To detect if the altvalue has been selected: connect(combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(onValueChange(int))); connect(combobox, SIGNAL(editTextChanged(const QString&)), this, SLOT(onValueChange(const QString&))); + // To react to changes in any of the children: + connect(combobox, SIGNAL(wasChanged()), this, SLOT(onChildChange())); + innerwidget->connectFrom(SIGNAL(wasChanged()), this, SLOT(onChildChange())); + layout()->setContentsMargins(0,0,0,0); altframe->layout()->setContentsMargins(0,0,0,0); + + show(); // Force altframe to get resized to its real size. + altframerepl->setFixedHeight(altframe->height()); } + bool AltComboBox::isValid() { if(!combobox->isValid()) return false; if(innerwidget && combobox->getValue() == altvalue) { - return innerwidget->isValid(); + if(!innerwidget->isValid()) return false; } - return true; + return regexpValidator() && luaValidator(); } QString AltComboBox::getValue() @@ -136,25 +150,41 @@ QString AltComboBox::getValue() } } -void AltComboBox::setValue(QString value) +void AltComboBox::setValue(QString value, QString source) { - combobox->setValue(value); + // if(isUserSource(source)) emit wasChanged(); // No need for this, it will be enitted by the children. + + if(combobox->findData(value) != -1) { + + combobox->setValue(value, source); - if(combobox->isValid() == false) { // Combobox contain idx == -1 (invalid) if value didn't exist. + } else { combobox->setValue(altvalue); if(innerwidget) { - innerwidget->setValue(value); + innerwidget->setValue(value, source); } } + + setInitialValue(value); } void AltComboBox::onValueChange(int index) { if(combobox->itemData(index).toString() == altvalue) { - altframe->setEnabled(true); + // altframe->setEnabled(true); + altframerepl->setVisible(false); + layout()->removeWidget(altframerepl); + + layout()->addWidget(altframe); + altframe->setVisible(true); } else { - altframe->setEnabled(false); + // altframe->setEnabled(false); + altframe->setVisible(false); + layout()->removeWidget(altframe); + + layout()->addWidget(altframerepl); + altframerepl->setVisible(true); } } @@ -172,3 +202,35 @@ void AltComboBox::disable() { setEnabled(false); } + +void AltComboBox::onChildChange() +{ + emit wasChanged(); +} + +void AltComboBox::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} + +void AltComboBox::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} + +bool AltComboBox::setKeyboardFocus() +{ + if(combobox->getValue() == altvalue) { + if(innerwidget) return innerwidget->setKeyboardFocus(); + } + + combobox->setKeyboardFocus(); + return true; +} + +void AltComboBox::setVisibility(bool visible) +{ + setVisible(visible); +} diff --git a/client/widgets/altcombobox.h b/client/widgets/altcombobox.h index 222c797..5504f4a 100644 --- a/client/widgets/altcombobox.h +++ b/client/widgets/altcombobox.h @@ -44,20 +44,34 @@ public: bool isValid(); QString getValue(); - void setValue(QString value); + void setValue(QString value, QString source = ""); void enable(); void disable(); + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); + + bool setKeyboardFocus(); + void setVisibility(bool visible); + public slots: void onValueChange(int index); void onValueChange(const QString &text); + void onChildChange(); + +signals: + void wasChanged(); private: ComboBox *combobox; Widget *innerwidget; QString altvalue; QWidget *altframe; + QWidget *altframerepl; }; #endif/*__PRACRO_ALTCOMBOBOX_H__*/ diff --git a/client/widgets/button.cc b/client/widgets/button.cc index c524084..6032678 100644 --- a/client/widgets/button.cc +++ b/client/widgets/button.cc @@ -32,6 +32,7 @@ Button::Button(QDomNode &node, MacroWindow *macrowindow) : QPushButton(), Widget(node, macrowindow) { + resetToDisabled = false; setCommonAttributes(this, node); QDomElement elem = node.toElement(); @@ -49,12 +50,27 @@ Button::Button(QDomNode &node, MacroWindow *macrowindow) if(elem.hasAttribute("action")) { if(elem.attribute("action") == "commit") { connect(this, SIGNAL(clicked()), this, SLOT(commit())); + setIcon(QPixmap(":icons/add.png")); + setEnabled(false); + + // + // Hack to re-disable the commit button when the macro is reset. + // + resetToDisabled = true; + widget_name = "commit_button_" + QString::number((int)this); + QVector< Widget* > ws; + ws.push_back(this); + macrowindow->addAuxWidgets(ws); + } else if(elem.attribute("action") == "reset") { - connect(this, SIGNAL(clicked()), this, SLOT(reset())); + connect(this, SIGNAL(clicked()), this, SLOT(_reset())); + setIcon(QPixmap(":icons/del.png")); } else if(elem.attribute("action") == "cancel") { connect(this, SIGNAL(clicked()), this, SLOT(cancel())); + setIcon(QPixmap(":icons/del.png")); } else if(elem.attribute("action") == "continue") { connect(this, SIGNAL(clicked()), this, SLOT(cont())); + setIcon(QPixmap(":icons/add.png")); } else if(elem.attribute("action") == "continue_nocommit") { connect(this, SIGNAL(clicked()), this, SLOT(cont_nocommit())); } @@ -69,7 +85,7 @@ void Button::commit() printf("Emit: commit\n"); } -void Button::reset() +void Button::_reset() { emit act_reset(); printf("Emit: reset\n"); @@ -92,3 +108,36 @@ void Button::cont_nocommit() emit act_continue_nocommit(field); printf("Emit: continue_nocommit\n"); } + +void Button::do_enable() +{ + setEnabled(true); +} + +void Button::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} + +void Button::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} + +void Button::setVisibility(bool visible) +{ + setVisible(visible); +} + +bool Button::setKeyboardFocus() +{ + setFocus(); + return true; +} + +void Button::reset() +{ + if(resetToDisabled) setEnabled(false); +} diff --git a/client/widgets/button.h b/client/widgets/button.h index aba7ac7..d9d0b26 100644 --- a/client/widgets/button.h +++ b/client/widgets/button.h @@ -39,12 +39,25 @@ public: Button(QDomNode &node, MacroWindow *macrowindow); QString field; + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); + + void setVisibility(bool visible); + + bool setKeyboardFocus(); + + void reset(); + public slots: void commit(); - void reset(); + void _reset(); void cancel(); void cont(); void cont_nocommit(); + void do_enable(); signals: void act_commit(); @@ -54,6 +67,6 @@ signals: void act_continue_nocommit(QString); private: - + bool resetToDisabled; }; #endif/*__PRACRO_BUTTON_H__*/ diff --git a/client/widgets/checkbox.cc b/client/widgets/checkbox.cc index 1b8d64b..4fbdad1 100644 --- a/client/widgets/checkbox.cc +++ b/client/widgets/checkbox.cc @@ -31,6 +31,8 @@ CheckBox::CheckBox(QDomNode &node, MacroWindow *macrowindow) : QCheckBox(), Widget(node, macrowindow) { + changedByUser = true; + setCommonAttributes(this, node); QDomElement elem = node.toElement(); @@ -51,7 +53,7 @@ CheckBox::CheckBox(QDomNode &node, MacroWindow *macrowindow) falsevalue = "false"; } - connect(this, SIGNAL(stateChanged(int)), this, SLOT(state_change())); + connect(this, SIGNAL(stateChanged(int)), this, SLOT(state_change(int))); } QString CheckBox::getValue() @@ -60,8 +62,12 @@ QString CheckBox::getValue() return falsevalue; } -void CheckBox::setValue(QString value) +void CheckBox::setValue(QString value, QString source) { + if(isUserSource(source)) emit wasChanged(); + + changedByUser = false; + bool old = isChecked(); if(value == truevalue) { @@ -73,7 +79,11 @@ void CheckBox::setValue(QString value) } // If set operation did not change the value we must invocate the code manually. - if(old == isChecked()) state_change(); + if(old == isChecked()) state_change(0); + + setInitialValue(value); + + changedByUser = true; } /* bool CheckBox::isValid() @@ -81,7 +91,31 @@ bool CheckBox::isValid() return luaValidator(); } */ -void CheckBox::state_change() +void CheckBox::state_change(int) { + if(changedByUser) emit wasChanged(); luaValidator(); } + +void CheckBox::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} + +void CheckBox::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} + +void CheckBox::setVisibility(bool visible) +{ + setVisible(visible); +} + +bool CheckBox::setKeyboardFocus() +{ + setFocus(); + return true; +} diff --git a/client/widgets/checkbox.h b/client/widgets/checkbox.h index 89f1f1b..34cac6b 100644 --- a/client/widgets/checkbox.h +++ b/client/widgets/checkbox.h @@ -40,14 +40,29 @@ public: // bool isValid(); QString getValue(); - void setValue(QString value); + void setValue(QString value, QString source = ""); + + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); + + void setVisibility(bool visible); + + bool setKeyboardFocus(); public slots: - void state_change(); + void state_change(int); + +signals: + void wasChanged(); private: QString truevalue; QString falsevalue; + + bool changedByUser; }; #endif/*__PRACRO_CHECKBOX_H__*/ diff --git a/client/widgets/combobox.cc b/client/widgets/combobox.cc index 630a449..4db6172 100644 --- a/client/widgets/combobox.cc +++ b/client/widgets/combobox.cc @@ -77,7 +77,6 @@ ComboBox::ComboBox(QDomNode &node, MacroWindow *macrowindow) setEditable(true); connect(this, SIGNAL(editTextChanged(QString)), this, SLOT(changed())); - //setEditText(elem.attribute("value")); break; case SEARCH: @@ -90,6 +89,7 @@ ComboBox::ComboBox(QDomNode &node, MacroWindow *macrowindow) } rxs += ")"; rx = QRegExp(rxs); + rx.setCaseSensitivity(Qt::CaseInsensitive); } { QCompleter *completer = new QCompleter(itemlist, this); @@ -100,11 +100,12 @@ ComboBox::ComboBox(QDomNode &node, MacroWindow *macrowindow) } connect(this, SIGNAL(editTextChanged(QString)), this, SLOT(changed())); - //setEditText(elem.attribute("value")); break; } + ischangingbyuser = false; changed(); + ischangingbyuser = true; } QString ComboBox::getValue() @@ -119,13 +120,20 @@ QString ComboBox::getValue() return value; } -void ComboBox::setValue(QString value) +void ComboBox::setValue(QString value, QString source) { + if(isUserSource(source)) emit wasChanged(); + int idx = findData(value); printf("setValue(\"%s\") - %d\n", value.toStdString().c_str(), idx); + ischangingbyuser = false; setCurrentIndex(idx); + ischangingbyuser = true; + + setInitialValue(value); + } bool ComboBox::isValid() @@ -134,17 +142,12 @@ bool ComboBox::isValid() if(currentIndex() != -1) return true; else return false; } - return rx.exactMatch(currentText()); + return rx.exactMatch(currentText()) && luaValidator(); } void ComboBox::changed() { - /* - if(combotype == SELECT) { - luaValidator(); - return; - } - */ + if(ischangingbyuser) emit wasChanged(); QPalette palette; @@ -169,3 +172,34 @@ void ComboBox::disable() { setEnabled(false); } + +void ComboBox::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} + +void ComboBox::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} + +/* +bool ComboBox::eventFilter(QObject *, QEvent *event) +{ + if (event->type() == QEvent::KeyPress) emit wasChanged(); + return false; +} +*/ + +bool ComboBox::setKeyboardFocus() +{ + setFocus(); + return true; +} + +void ComboBox::setVisibility(bool visible) +{ + setVisible(visible); +} diff --git a/client/widgets/combobox.h b/client/widgets/combobox.h index f072bea..2691ec3 100644 --- a/client/widgets/combobox.h +++ b/client/widgets/combobox.h @@ -47,18 +47,34 @@ public: bool isValid(); QString getValue(); - void setValue(QString value); + void setValue(QString value, QString source = ""); void enable(); void disable(); + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); + + bool setKeyboardFocus(); + void setVisibility(bool visible); + public slots: void changed(); +signals: + void wasChanged(); + +protected: + // bool eventFilter(QObject *, QEvent *event); + private: QRegExp rx; QString combo_value; types_t combotype; + bool ischangingbyuser; }; #endif/*__PRACRO_COMBOBOX_H__*/ diff --git a/client/widgets/common.cc b/client/widgets/common.cc index f39c607..b650701 100644 --- a/client/widgets/common.cc +++ b/client/widgets/common.cc @@ -96,3 +96,10 @@ void setCommonLayout(QWidget *widget, QDomNode &node) widget->setContentsMargins(0,0,0,0); //widget->layout()->setContentsMargins(0,0,0,0); } + +bool isUserSource(QString source) +{ + if(source == "pentominos") return true; + if(source == "pracro") return false; + return false; +} diff --git a/client/widgets/common.h b/client/widgets/common.h index 11ce317..a3db783 100644 --- a/client/widgets/common.h +++ b/client/widgets/common.h @@ -32,5 +32,6 @@ void setCommonAttributes(QWidget *widget, QDomNode &node); void setCommonLayout(QWidget *widget, QDomNode &node); +bool isUserSource(QString source); #endif/*__PRACRO_COMMON_H__*/ diff --git a/client/widgets/datetime.cc b/client/widgets/datetime.cc new file mode 100644 index 0000000..1ca52ed --- /dev/null +++ b/client/widgets/datetime.cc @@ -0,0 +1,120 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * datetime.cc + * + * Fri Jan 9 09:00:12 CET 2009 + * Copyright 2009 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * 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 "datetime.h" + +#include "common.h" + +DateTime::DateTime(QDomNode &node, MacroWindow *macrowindow) + : QDateTimeEdit(), Widget(node, macrowindow) +{ + changedByUser = true; + setCommonAttributes(this, node); + + setCalendarPopup(true); + setMinimumDateTime(QDateTime::fromTime_t(0)); + + QDomElement elem = node.toElement(); + /* + if(elem.hasAttribute("readonly")) { + if(elem.attribute("readonly") == "true" || elem.attribute("readonly") == "1") { + setReadOnly(true); + } else if(elem.attribute("readonly") == "false" || elem.attribute("readonly") == "0") { + setReadOnly(false); + } else { + printf("Unknown value of readonly: %s\n", elem.attribute("readonly").toStdString().c_str()); + } + } + */ + connect(this, SIGNAL(dateTimeChanged(const QDateTime &)), + this, SLOT(changed(const QDateTime &))); +} + +void DateTime::changed(const QDateTime &) +{ + QPalette palette; + + if(luaValidator()) { + // valid string + palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255))); + } else { + // invalid string + palette.setBrush(QPalette::Base, QBrush(QColor(200, 230, 200))); + } + + setPalette(palette); + + if(changedByUser) emit wasChanged(); +} + +QString DateTime::getValue() +{ + return QString::number(dateTime().toUTC().toTime_t()); +} + +void DateTime::setValue(QString value, QString source) +{ + changedByUser = false; + if(isUserSource(source)) emit wasChanged(); + + setDateTime(QDateTime::fromTime_t(value.toUInt())); + + setInitialValue(value); + changedByUser = true; +} + +void DateTime::enable() +{ + setEnabled(true); +} + +void DateTime::disable() +{ + setEnabled(false); +} + +void DateTime::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} + +void DateTime::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} + +bool DateTime::setKeyboardFocus() +{ + setFocus(); + return true; +} + +void DateTime::setVisibility(bool visible) +{ + setVisible(visible); +} diff --git a/client/widgets/datetime.h b/client/widgets/datetime.h new file mode 100644 index 0000000..0fb5703 --- /dev/null +++ b/client/widgets/datetime.h @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * datetime.h + * + * Fri Jan 9 09:00:12 CET 2009 + * Copyright 2009 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * 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. + */ +#ifndef __PRACRO_DATETIME_H__ +#define __PRACRO_DATETIME_H__ + +#include "widget.h" +#include <QDateTimeEdit> +#include <QDomNode> + +class DateTime : public QDateTimeEdit, public Widget +{ +Q_OBJECT +public: + DateTime(QDomNode &node, MacroWindow *macrowindow); + + QString getValue(); + void setValue(QString value, QString source = ""); + void enable(); + void disable(); + + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); + + bool setKeyboardFocus(); + void setVisibility(bool visible); + +public slots: + void changed(const QDateTime &); + +signals: + void wasChanged(); + +private: + bool changedByUser; +}; + +#endif/*__PRACRO_DATETIME_H__*/ diff --git a/client/widgets/dbwidget.cc b/client/widgets/dbwidget.cc index 1a68d2a..00b3886 100644 --- a/client/widgets/dbwidget.cc +++ b/client/widgets/dbwidget.cc @@ -40,6 +40,8 @@ DBWidget::DBWidget(QDomNode &node, MacroWindow *macrowindow) : QComboBox(), Widget(node, macrowindow) { + changedByUser = true; + QDomElement elem = node.toElement(); if(!elem.hasAttribute("driver") || @@ -108,9 +110,15 @@ QString DBWidget::getValue() return value; } -void DBWidget::setValue(QString value) +void DBWidget::setValue(QString value, QString source) { + changedByUser = false; + if(isUserSource(source)) emit wasChanged(); + setEditText(value); + + setInitialValue(value); + changedByUser = true; } bool DBWidget::isValid() @@ -133,6 +141,8 @@ void DBWidget::changed() } lineEdit()->setPalette(palette); + + if(changedByUser) emit wasChanged(); } void DBWidget::update_list(QString prefix) @@ -175,6 +185,29 @@ void DBWidget::disable() { setEnabled(false); } + +void DBWidget::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} + +void DBWidget::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} + +bool DBWidget::setKeyboardFocus() +{ + setFocus(); + return true; +} + +void DBWidget::setVisibility(bool visible) +{ + setVisible(visible); +} /* $ psql -h sensei -d lms -U postgres =================================================================== diff --git a/client/widgets/dbwidget.h b/client/widgets/dbwidget.h index 98499b9..13e552d 100644 --- a/client/widgets/dbwidget.h +++ b/client/widgets/dbwidget.h @@ -45,15 +45,28 @@ public: bool isValid(); QString getValue(); - void setValue(QString value); + void setValue(QString value, QString source = ""); void enable(); void disable(); + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); + + void setVisibility(bool visible); + + bool setKeyboardFocus(); + public slots: void changed(); void update_list(QString prefix); +signals: + void wasChanged(); + protected: // void focusInEvent(QFocusEvent *); @@ -64,6 +77,8 @@ private: QString from; QString where; QString format; + + bool changedByUser; }; #endif/*__PRACRO_DBWIDGET_H__*/ diff --git a/client/widgets/frame.cc b/client/widgets/frame.cc index 79e060b..04a0e90 100644 --- a/client/widgets/frame.cc +++ b/client/widgets/frame.cc @@ -48,3 +48,20 @@ void Frame::disable() { setEnabled(false); } + +void Frame::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} + +void Frame::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} + +void Frame::setVisibility(bool visible) +{ + setVisible(visible); +} diff --git a/client/widgets/frame.h b/client/widgets/frame.h index 4fabd40..5375d06 100644 --- a/client/widgets/frame.h +++ b/client/widgets/frame.h @@ -38,6 +38,13 @@ public: void enable(); void disable(); + + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); + void setVisibility(bool visible); }; #endif/*__PRACRO_FRAME_H__*/ diff --git a/client/widgets/groupbox.cc b/client/widgets/groupbox.cc index c3947a7..f6c9b28 100644 --- a/client/widgets/groupbox.cc +++ b/client/widgets/groupbox.cc @@ -54,3 +54,20 @@ void GroupBox::disable() { setEnabled(false); } + +void GroupBox::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} + +void GroupBox::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} + +void GroupBox::setVisibility(bool visible) +{ + setVisible(visible); +} diff --git a/client/widgets/groupbox.h b/client/widgets/groupbox.h index 99e05ce..d1ffb86 100644 --- a/client/widgets/groupbox.h +++ b/client/widgets/groupbox.h @@ -38,6 +38,13 @@ public: void enable(); void disable(); + + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); + void setVisibility(bool visible); }; #endif/*__PRACRO_GROUPBOX_H__*/ diff --git a/client/widgets/label.cc b/client/widgets/label.cc index d4f5387..3f69861 100644 --- a/client/widgets/label.cc +++ b/client/widgets/label.cc @@ -59,5 +59,21 @@ Label::Label(QDomNode &node, MacroWindow *macrowindow) // Always center vertically in the addressed space setAlignment(Qt::AlignVCenter); +} + +void Label::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} +void Label::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} + +void Label::setVisibility(bool visible) +{ + setVisible(visible); } diff --git a/client/widgets/label.h b/client/widgets/label.h index cbf3e06..6c02d1b 100644 --- a/client/widgets/label.h +++ b/client/widgets/label.h @@ -37,6 +37,13 @@ class Label : public QLabel, public Widget Q_OBJECT public: Label(QDomNode &node, MacroWindow *macrowindow); + + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); + void setVisibility(bool visible); }; #endif/*__PRACRO_LABEL_H__*/ diff --git a/client/widgets/lineedit.cc b/client/widgets/lineedit.cc index 29ea06c..b699553 100644 --- a/client/widgets/lineedit.cc +++ b/client/widgets/lineedit.cc @@ -47,6 +47,7 @@ LineEdit::LineEdit(QDomNode &node, MacroWindow *macrowindow) } connect(this, SIGNAL(textChanged(QString)), this, SLOT(changed())); + connect(this, SIGNAL(textEdited(QString)), this, SLOT(user_changed())); } void LineEdit::changed() @@ -69,15 +70,24 @@ void LineEdit::changed() setPalette(palette); } +void LineEdit::user_changed() +{ + emit wasChanged(); +} + QString LineEdit::getValue() { return text(); } -void LineEdit::setValue(QString value) +void LineEdit::setValue(QString value, QString source) { + if(isUserSource(source)) emit wasChanged(); + if(text() == value) setText(value + " "); // Hack to make sure the textChanged signal is emitted. setText(value); + + setInitialValue(value); } void LineEdit::enable() @@ -89,3 +99,26 @@ void LineEdit::disable() { setEnabled(false); } + +void LineEdit::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} + +void LineEdit::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} + +bool LineEdit::setKeyboardFocus() +{ + setFocus(); + return true; +} + +void LineEdit::setVisibility(bool visible) +{ + setVisible(visible); +} diff --git a/client/widgets/lineedit.h b/client/widgets/lineedit.h index 3f0bb17..0e060d6 100644 --- a/client/widgets/lineedit.h +++ b/client/widgets/lineedit.h @@ -39,12 +39,25 @@ public: LineEdit(QDomNode &node, MacroWindow *macrowindow); QString getValue(); - void setValue(QString value); + void setValue(QString value, QString source = ""); void enable(); void disable(); + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); + + bool setKeyboardFocus(); + void setVisibility(bool visible); + public slots: void changed(); + void user_changed(); + +signals: + void wasChanged(); }; #endif/*__PRACRO_LINEEDIT_H__*/ diff --git a/client/widgets/listbox.cc b/client/widgets/listbox.cc index 88a5cd2..303d288 100644 --- a/client/widgets/listbox.cc +++ b/client/widgets/listbox.cc @@ -71,6 +71,8 @@ static QListWidgetItem *createItem(QDomElement &elem) ListBox::ListBox(QDomNode &node, MacroWindow *macrowindow) : QListWidget(), Widget(node, macrowindow) { + valueIsChangingByComputer = false; + setCommonAttributes(this, node); QDomNodeList children = node.childNodes(); @@ -80,6 +82,8 @@ ListBox::ListBox(QDomNode &node, MacroWindow *macrowindow) QDomElement list_elem = child.toElement(); addItem(createItem(list_elem)); } + + connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(changed())); } bool ListBox::isValid() @@ -94,8 +98,11 @@ QString ListBox::getValue() return value; } -void ListBox::setValue(QString value) +void ListBox::setValue(QString value, QString source) { + if(isUserSource(source)) emit wasChanged(); + + valueIsChangingByComputer = true; int sel = -1; // -1 is default for none selected for(int i = 0; i < count(); i++) { @@ -104,4 +111,35 @@ void ListBox::setValue(QString value) } setCurrentRow(sel); + + setInitialValue(value); + valueIsChangingByComputer = false; +} + +void ListBox::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} + +void ListBox::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} + +void ListBox::setVisibility(bool visible) +{ + setVisible(visible); +} + +void ListBox::changed() +{ + if(!valueIsChangingByComputer) emit wasChanged(); +} + +bool ListBox::setKeyboardFocus() +{ + setFocus(); + return true; } diff --git a/client/widgets/listbox.h b/client/widgets/listbox.h index 627d31e..1485225 100644 --- a/client/widgets/listbox.h +++ b/client/widgets/listbox.h @@ -33,13 +33,32 @@ class ListBox : public QListWidget, public Widget { +Q_OBJECT public: ListBox(QDomNode &node, MacroWindow *macrowindow); -public slots: bool isValid(); QString getValue(); - void setValue(QString value); + void setValue(QString value, QString source = ""); + + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); + + void setVisibility(bool visible); + + bool setKeyboardFocus(); + +public slots: + void changed(); + +signals: + void wasChanged(); + +private: + bool valueIsChangingByComputer; }; #endif/*__PRACRO_LISTBOX_H__*/ diff --git a/client/widgets/metawidget.cc b/client/widgets/metawidget.cc index 5f53153..91c62ec 100644 --- a/client/widgets/metawidget.cc +++ b/client/widgets/metawidget.cc @@ -29,6 +29,8 @@ #include <QHBoxLayout> #include <QVBoxLayout> +#include <QMessageBox> + #include "widgetbuilder.h" #include "formatparser.h" @@ -38,37 +40,21 @@ MetaWidget::MetaWidget(QDomNode &node, MacroWindow *macrowindow) : QFrame(), Widget(node, macrowindow) { setCommonAttributes(this, node); - - QDomElement elem = node.toElement(); - if(elem.hasAttribute("layout")) { - if(elem.attribute("layout") == "hbox") { - QHBoxLayout *layout = new QHBoxLayout(); - setLayout(layout); - } else if (elem.attribute("layout") == "vbox") { - QVBoxLayout *layout = new QVBoxLayout(); - setLayout(layout); - } - } else { - QHBoxLayout *layout = new QHBoxLayout(); - setLayout(layout); - } - - layout()->setContentsMargins(0,0,0,0); + setCommonLayout(this, node); + QDomElement elem = node.toElement(); + storechildren = elem.attribute("storechildren", "false") == "true"; + + // Create children QDomNodeList children = node.childNodes(); - for (int i=0; i<children.count();i++) { QDomNode child = children.at(i); - widgets += widgetBuilder(child, this, macrowindow); - } - macrowindow->addAuxWidgets(widgets); - - /* // This is done later - if(elem.hasAttribute("value")) { - setValue(elem.attribute("value")); + widgets += widgetBuilder(child, this, macrowindow, false); } - */ + if(storechildren) macrowindow->addWidgets(widgets); + else macrowindow->addAuxWidgets(widgets); + // Setup format string if(elem.hasAttribute("format")) { format = elem.attribute("format"); } else { @@ -81,19 +67,18 @@ MetaWidget::MetaWidget(QDomNode &node, MacroWindow *macrowindow) } } - if(elem.hasAttribute("width")) { - setMinimumWidth(elem.attribute("width").toInt()); + // Connect all children wasChanged signal, to catch changes. + QVector< Widget* >::iterator i = widgets.begin(); + while (i != widgets.end()) { + Widget* w = *i; + w->connectFrom(SIGNAL(wasChanged()), this, SLOT(changed())); + i++; } - - if(elem.hasAttribute("height")) { - setMinimumHeight(elem.attribute("height").toInt()); - } - - layout()->setContentsMargins(0,0,0,0); } void MetaWidget::changed() { + emit wasChanged(); } QString MetaWidget::getValue() @@ -101,7 +86,7 @@ QString MetaWidget::getValue() return format_parser(format, widgets); } -void MetaWidget::setValue(QString /*values*/) +void MetaWidget::setValue(QString, QString) { // Nothing reasonable we can do here. } @@ -115,3 +100,65 @@ void MetaWidget::disable() { setEnabled(false); } + +bool MetaWidget::isValid() +{ + // If children are stored they will validate themselves. + if(!storechildren) { + QVector< Widget* >::iterator i = widgets.begin(); + while (i != widgets.end()) { + Widget* w = *i; + if(w->isValid() == false) { + QMessageBox::critical(NULL, "Fejl", + "Et af inputfelterne (" + w->getName() + + ") er ikke udfyldt korrekt, prøv igen.\n" + , QMessageBox::Ok); + return false; + } + i++; + } + } + + return regexpValidator() && luaValidator(); +} + +void MetaWidget::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} + +void MetaWidget::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} + +bool MetaWidget::setKeyboardFocus() +{ + QVector< Widget* >::iterator i = widgets.begin(); + while (i != widgets.end()) { + Widget* w = *i; + if(w->setKeyboardFocus()) return true; + i++; + } + return false; +} + +void MetaWidget::reset() +{ + // If children are stored they will be reset individually. + if(!storechildren) { + QVector< Widget* >::iterator i = widgets.begin(); + while (i != widgets.end()) { + Widget* w = *i; + w->reset(); + i++; + } + } +} + +void MetaWidget::setVisibility(bool visible) +{ + setVisible(visible); +} diff --git a/client/widgets/metawidget.h b/client/widgets/metawidget.h index 5d0bbc9..e920236 100644 --- a/client/widgets/metawidget.h +++ b/client/widgets/metawidget.h @@ -40,18 +40,36 @@ Q_OBJECT public: MetaWidget(QDomNode &node, MacroWindow *macrowindow); -public slots: - void changed(); QString getValue(); - void setValue(QString value); + void setValue(QString value, QString source = ""); void enable(); void disable(); + bool isValid(); + + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); + + bool setKeyboardFocus(); + void setVisibility(bool visible); + + void reset(); + +public slots: + void changed(); + +signals: + void wasChanged(); + private: QListWidget *list; QVector< Widget* > widgets; QString format; + bool storechildren; }; #endif/*__PRACRO_METAWIDGET_H__*/ diff --git a/client/widgets/multilist.cc b/client/widgets/multilist.cc index bff3ad7..5f28368 100644 --- a/client/widgets/multilist.cc +++ b/client/widgets/multilist.cc @@ -43,9 +43,29 @@ MultiList::MultiList(QDomNode &node, MacroWindow *macrowindow) QGridLayout *layout = new QGridLayout(); setLayout(layout); + list = new QListWidget(this); + layout->addWidget(list, 0, 0, 1, 2, Qt::AlignTop); + list->installEventFilter(this); + + QPushButton *add = new QPushButton(this); + connect(add, SIGNAL(clicked()), this, SLOT(add())); + add->setText("Tilføj nedenstående til listen"); + add->setIcon(QIcon(QPixmap(":icons/add.png"))); + layout->addWidget(add, 1, 0, 1, 1, Qt::AlignTop); + + QPushButton *rem = new QPushButton(this); + connect(rem, SIGNAL(clicked()), this, SLOT(remove())); + rem->setText("Fjern det markerede element fra listen"); + rem->setIcon(QIcon(QPixmap(":icons/del.png"))); + layout->addWidget(rem, 1, 1, 1, 1, Qt::AlignTop); + + QLabel *arrows = new QLabel(); + arrows->setPixmap(QPixmap(":icons/arrows.png")); + layout->addWidget(arrows, 2, 0, 1, 2, Qt::AlignHCenter); + QWidget *inputbox = new QWidget(this); inputbox->setContentsMargins(0,0,0,0); - layout->addWidget(inputbox, 0, 0, 1, 2, Qt::AlignTop); + layout->addWidget(inputbox, 3, 0, 1, 2, Qt::AlignTop); QDomElement elem = node.toElement(); if(elem.hasAttribute("layout")) { @@ -68,7 +88,7 @@ MultiList::MultiList(QDomNode &node, MacroWindow *macrowindow) QVector< Widget* > widgets; for (int i=0; i<children.count();i++) { QDomNode child = children.at(i); - widgets += widgetBuilder(child, inputbox, macrowindow); + widgets += widgetBuilder(child, inputbox, macrowindow, false); } macrowindow->addAuxWidgets(widgets); @@ -88,35 +108,6 @@ MultiList::MultiList(QDomNode &node, MacroWindow *macrowindow) printf("ERROR: Missing 'innerwidget' attribute on multilist!\n"); } - QLabel *arrows = new QLabel(); - arrows->setPixmap(QPixmap(":icons/arrows.png")); - layout->addWidget(arrows, 1, 0, 1, 2, Qt::AlignHCenter); - - QPushButton *add = new QPushButton(this); - connect(add, SIGNAL(clicked()), this, SLOT(add())); - add->setText("Tilføj ovenstående til listen"); - add->setIcon(QIcon(QPixmap(":icons/add.png"))); - - // layout->addWidget(add, 0, 1, Qt::AlignTop); - layout->addWidget(add, 2, 0, 1, 1, Qt::AlignTop); - - QPushButton *rem = new QPushButton(this); - connect(rem, SIGNAL(clicked()), this, SLOT(remove())); - rem->setText("Fjern det markerede element fra listen"); - rem->setIcon(QIcon(QPixmap(":icons/del.png"))); - // layout->addWidget(rem, 1, 1, Qt::AlignTop); - layout->addWidget(rem, 2, 1, 1, 1, Qt::AlignTop); - - list = new QListWidget(this); - // layout->addWidget(list, 1, 0, Qt::AlignTop); - layout->addWidget(list, 3, 0, 1, 2, Qt::AlignTop); - - /* // This is done later - if(elem.hasAttribute("value")) { - setValue(elem.attribute("value")); - } - */ - layout->setContentsMargins(0,0,0,0); } @@ -140,8 +131,10 @@ QString MultiList::getValue() return values; } -void MultiList::setValue(QString values) +void MultiList::setValue(QString values, QString source) { + if(isUserSource(source)) emit wasChanged(); + QString value; list->clear(); @@ -152,26 +145,28 @@ void MultiList::setValue(QString values) if(value != "") list->addItem(value); idx++; } while(value != ""); + + setInitialValue(values); } void MultiList::remove() { - list->takeItem(list->currentRow()); + QListWidgetItem *item = list->currentItem(); + + if(item && item->isSelected()) { + delete item; + emit wasChanged(); + } } void MultiList::add() { - /* - QVector< Widget * >::iterator i = widgets.begin(); - while(i != widgets.end()) { - if(!(*i)->isValid()) return; - i++; - } - list->addItem(format_parser(format, widgets)); - */ + if(innerwidget && innerwidget->isValid()) { + list->addItem(innerwidget->getValue()); + emit wasChanged(); - if(innerwidget && innerwidget->isValid()) list->addItem(innerwidget->getValue()); - + innerwidget->reset(); + } } void MultiList::enable() @@ -183,3 +178,35 @@ void MultiList::disable() { setEnabled(false); } + +void MultiList::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} + +void MultiList::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} + +bool MultiList::setKeyboardFocus() +{ + if(innerwidget) return innerwidget->setKeyboardFocus(); + return false; +} + +bool MultiList::eventFilter(QObject *obj, QEvent *event) +{ + if(event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); + if(keyEvent->key() == Qt::Key_Delete) remove(); + } + return QObject::eventFilter(obj, event); +} + +void MultiList::setVisibility(bool visible) +{ + setVisible(visible); +} diff --git a/client/widgets/multilist.h b/client/widgets/multilist.h index 0a9e798..3bd7b9c 100644 --- a/client/widgets/multilist.h +++ b/client/widgets/multilist.h @@ -40,16 +40,31 @@ Q_OBJECT public: MultiList(QDomNode &node, MacroWindow *macrowindow); -public slots: - void changed(); QString getValue(); - void setValue(QString value); + void setValue(QString value, QString source = ""); + + void enable(); + void disable(); + + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); + bool setKeyboardFocus(); + void setVisibility(bool visible); + +public slots: + void changed(); void remove(); void add(); - void enable(); - void disable(); +signals: + void wasChanged(); + +protected: + bool eventFilter(QObject *obj, QEvent *event); private: QListWidget *list; diff --git a/client/widgets/radiobutton.h b/client/widgets/radiobutton.h index d0cf149..6dbae7e 100644 --- a/client/widgets/radiobutton.h +++ b/client/widgets/radiobutton.h @@ -35,6 +35,7 @@ class RadioButton : public QRadioButton { +Q_OBJECT public: RadioButton(QDomNode &node); diff --git a/client/widgets/radiobuttons.cc b/client/widgets/radiobuttons.cc index 1987459..ae40677 100644 --- a/client/widgets/radiobuttons.cc +++ b/client/widgets/radiobuttons.cc @@ -47,6 +47,9 @@ RadioButtons::RadioButtons(QDomNode &node, MacroWindow *macrowindow) // Create radiobutton from child, insert in this layout()->addWidget(radiobutton); + + connect(radiobutton, SIGNAL(clicked()), this, SLOT(childChanged())); + radiobutton_list.push_back(radiobutton); } @@ -79,8 +82,10 @@ QString RadioButtons::getValue() return value; } -void RadioButtons::setValue(QString value) +void RadioButtons::setValue(QString value, QString source) { + if(isUserSource(source)) emit wasChanged(); + QVector< RadioButton* >::iterator i; for (i = radiobutton_list.begin(); i != radiobutton_list.end(); ++i) { RadioButton *widget = *i; @@ -90,4 +95,48 @@ void RadioButtons::setValue(QString value) widget->setChecked(false); } } + + setInitialValue(value); +} + +void RadioButtons::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} + +void RadioButtons::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} + +bool RadioButtons::setKeyboardFocus() +{ + QVector< RadioButton* >::iterator i = radiobutton_list.begin(); + while(i != radiobutton_list.end()) { + RadioButton *rb = *i; + if(rb->isChecked()) { + rb->setFocus(); + return true; + } + i++; + } + + if(radiobutton_list.size()) { + radiobutton_list.at(0)->setFocus(); + return true; + } + + return false; +} + +void RadioButtons::setVisibility(bool visible) +{ + setVisible(visible); +} + +void RadioButtons::childChanged() +{ + emit wasChanged(); } diff --git a/client/widgets/radiobuttons.h b/client/widgets/radiobuttons.h index f1c89c4..cfdf1ef 100644 --- a/client/widgets/radiobuttons.h +++ b/client/widgets/radiobuttons.h @@ -36,13 +36,28 @@ class RadioButtons : public QFrame, public Widget { +Q_OBJECT public: RadioButtons(QDomNode &node, MacroWindow *macrowindow); -public slots: bool isValid(); QString getValue(); - void setValue(QString value); + void setValue(QString value, QString source = ""); + + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); + + bool setKeyboardFocus(); + void setVisibility(bool visible); + +public slots: + void childChanged(); + +signals: + void wasChanged(); private: QVector < RadioButton* > radiobutton_list; diff --git a/client/widgets/textedit.cc b/client/widgets/textedit.cc index cdbd8ad..ec7e3fc 100644 --- a/client/widgets/textedit.cc +++ b/client/widgets/textedit.cc @@ -49,6 +49,7 @@ TextEdit::TextEdit(QDomNode &node, MacroWindow *macrowindow) } connect(this, SIGNAL(textChanged()), this, SLOT(changed())); + installEventFilter(this); // Detect keyboard input. } void TextEdit::changed() @@ -76,7 +77,41 @@ QString TextEdit::getValue() return QTextEdit::toPlainText(); } -void TextEdit::setValue(QString value) +void TextEdit::setValue(QString value, QString source) { + if(isUserSource(source)) emit wasChanged(); setText(value); + setInitialValue(value); +} + +bool TextEdit::eventFilter(QObject *, QEvent *event) +{ + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); + if(keyEvent->text() != "") emit wasChanged(); + } + return false; +} + +void TextEdit::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} + +void TextEdit::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} + +bool TextEdit::setKeyboardFocus() +{ + setFocus(); + return true; +} + +void TextEdit::setVisibility(bool visible) +{ + setVisible(visible); } diff --git a/client/widgets/textedit.h b/client/widgets/textedit.h index c734f38..722abcd 100644 --- a/client/widgets/textedit.h +++ b/client/widgets/textedit.h @@ -31,6 +31,7 @@ #include <QTextEdit> #include <QWidget> #include <QDomNode> +#include <QKeyEvent> class TextEdit : public QTextEdit, public Widget { @@ -39,10 +40,27 @@ public: TextEdit(QDomNode &node, MacroWindow *macrowindow); QString getValue(); - void setValue(QString value); + void setValue(QString value, QString source = ""); + + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); + + bool setKeyboardFocus(); + + void setVisibility(bool visible); + +signals: + void wasChanged(); public slots: void changed(); + // void user_changed(); + +protected: + bool eventFilter(QObject *obj, QEvent *event); }; #endif/*__PRACRO_TEXTEDIT_H__*/ diff --git a/client/widgets/widget.cc b/client/widgets/widget.cc index de49968..0857d67 100644 --- a/client/widgets/widget.cc +++ b/client/widgets/widget.cc @@ -35,8 +35,10 @@ Widget::Widget(QDomNode &node, MacroWindow *macrowindow) if(elem.hasAttribute("name")) { widget_name = elem.attribute("name"); } else { - printf("XML ERROR!! Unnamed widget of type: %s\n", - elem.tagName().toStdString().c_str()); + if(elem.tagName() != "frame" && elem.tagName() != "label" + && elem.tagName() != "button" && elem.tagName() != "window") + printf("XML ERROR!! Unnamed widget of type: %s\n", + elem.tagName().toStdString().c_str()); } if(elem.hasAttribute("script")) { @@ -52,6 +54,9 @@ Widget::Widget(QDomNode &node, MacroWindow *macrowindow) } else { hasregexpvalidator = false; } + + has_initial_value = false; + initial_value = ""; } QString Widget::getName() @@ -59,12 +64,7 @@ QString Widget::getName() return widget_name; } -QString Widget::getValue() -{ - return ""; -} - -void Widget::setValue(QString) +void Widget::setValue(QString, QString) { } @@ -85,10 +85,15 @@ bool Widget::luaValidator() return macrowindow->lua->run(luaprogram, getName(), getValue()); } -void Widget::disable() +void Widget::setInitialValue(QString value) { + if(!has_initial_value) { + initial_value = value; + has_initial_value = true; + } } -void Widget::enable() +void Widget::reset() { + setValue(initial_value); } diff --git a/client/widgets/widget.h b/client/widgets/widget.h index 9b6a996..2977e3a 100644 --- a/client/widgets/widget.h +++ b/client/widgets/widget.h @@ -38,13 +38,35 @@ class Widget { public: Widget(QDomNode &node, MacroWindow *macrowindow); virtual ~Widget(){} - virtual QString getValue(); - virtual void setValue(QString value); + + virtual QString getValue() { return ""; } + virtual void setValue(QString value, QString source = ""); + virtual bool isValid(); - virtual void disable(); - virtual void enable(); + + virtual void disable() {} + virtual void enable() {} + virtual bool isDisabled() { return false; } + + virtual void setVisibility(bool) {} + QString getName(); + /** + * Connect some signal from this object to some slot in some other object. + */ + virtual void connectFrom(const char *, const QObject *, const char *) {} + + /** + * Connect some signal from some other object to some slot in this object. + */ + virtual void connectTo(const QObject *, const char *, const char *) {} + + virtual bool setKeyboardFocus() { return false; } + + void setInitialValue(QString value); + virtual void reset(); + protected: QString widget_name; @@ -60,6 +82,9 @@ private: QString luaprogram; LUA *lua; MacroWindow *macrowindow; + + QString initial_value; + bool has_initial_value; }; #endif/*__PRACRO_WIDGET_H__*/ diff --git a/client/widgets/window.cc b/client/widgets/window.cc index fa44875..e685e79 100644 --- a/client/widgets/window.cc +++ b/client/widgets/window.cc @@ -51,3 +51,15 @@ Window::Window(QDomNode &node, MacroWindow *macrowindow) setWindowTitle(elem.attribute("caption")); } } + +void Window::connectFrom(const char *signal, + const QObject *receiver, const char *method) +{ + connect(this, signal, receiver, method); +} + +void Window::connectTo(const QObject *sender, const char *signal, + const char *method) +{ + connect(sender, signal, this, method); +} diff --git a/client/widgets/window.h b/client/widgets/window.h index af1e3d7..6e3d5be 100644 --- a/client/widgets/window.h +++ b/client/widgets/window.h @@ -35,6 +35,12 @@ class Window : public QWidget, public Widget { public: Window(QDomNode &node, MacroWindow *macrowindow); + + void connectFrom(const char *signal, + const QObject *receiver, const char *method); + + void connectTo(const QObject *sender, const char *signal, + const char *method); }; #endif/*__PRACRO_WINDOW_H__*/ |