00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <kdebug.h>
00022
00023 #include <qmetaobject.h>
00024 #include <qdom.h>
00025 #include <qfile.h>
00026 #include <qtextstream.h>
00027 #include <qcursor.h>
00028 #include <qbuffer.h>
00029 #include <qimage.h>
00030 #include <qlayout.h>
00031 #include <qobjectlist.h>
00032 #include <qdatetime.h>
00033 #include <qlabel.h>
00034 #include <qpainter.h>
00035
00036 #include <kfiledialog.h>
00037 #include <klocale.h>
00038 #include <kcommand.h>
00039 #include <kaccelmanager.h>
00040
00041 #include "form.h"
00042 #include "container.h"
00043 #include "objecttree.h"
00044 #include "formmanager.h"
00045 #include "widgetlibrary.h"
00046 #include "spring.h"
00047 #include "pixmapcollection.h"
00048 #include "events.h"
00049 #include "utils.h"
00050 #include "kexiflowlayout.h"
00051
00052 #include "formIO.h"
00053
00055 CustomWidget::CustomWidget(const QCString &className, QWidget *parent, const char *name)
00056 : QWidget(parent, name), m_className(className)
00057 {
00058 setBackgroundMode(Qt::PaletteDark);
00059 }
00060
00061 CustomWidget::~CustomWidget()
00062 {
00063 }
00064
00065 void
00066 CustomWidget::paintEvent(QPaintEvent *)
00067 {
00068 QPainter p(this);
00069 p.setPen(palette().active().text());
00070 QRect r(rect());
00071 r.setX(r.x()+2);
00072 p.drawText(r, Qt::AlignTop, m_className);
00073 }
00074
00075 using namespace KFormDesigner;
00076
00077 QDict<QLabel> *FormIO::m_buddies = 0;
00078 ObjectTreeItem *FormIO::m_currentItem = 0;
00079 Form *FormIO::m_currentForm = 0;
00080 bool FormIO::m_savePixmapsInline = false;
00081
00082
00083
00084 KFORMEDITOR_EXPORT uint KFormDesigner::version()
00085 {
00086 return KFORMDESIGNER_VERSION;
00087 }
00088
00092
00093 FormIO::FormIO()
00094 {
00095 }
00096
00097 FormIO::~FormIO()
00098 {
00099 }
00100
00101 bool
00102 FormIO::saveFormToFile(Form *form, const QString &filename)
00103 {
00104 QString m_filename;
00105 if(!form->filename().isNull() && filename.isNull())
00106 m_filename = form->filename();
00107
00108 if(filename.isNull())
00109 {
00110 m_filename = KFileDialog::getSaveFileName(QString::null, i18n("*.ui|Qt Designer UI Files"));
00111 if(m_filename.isNull())
00112 return false;
00113 }
00114 else
00115 m_filename = filename;
00116 form->setFilename(m_filename);
00117
00118 QDomDocument domDoc;
00119 if (!saveFormToDom(form, domDoc))
00120 return false;
00121
00122 QFile file(m_filename);
00123 if (!file.open(IO_WriteOnly))
00124 return false;
00125
00126 QTextStream stream(&file);
00127 stream << domDoc.toString(3) << endl;
00128 file.close();
00129
00130 return true;
00131 }
00132
00133 bool
00134 FormIO::saveFormToByteArray(Form *form, QByteArray &dest)
00135 {
00136 QDomDocument domDoc;
00137 if (!saveFormToDom(form, domDoc))
00138 return false;
00139 dest = domDoc.toCString();
00140 return true;
00141 }
00142
00143 bool
00144 FormIO::saveFormToString(Form *form, QString &dest, int indent)
00145 {
00146 QDomDocument domDoc;
00147 if (!saveFormToDom(form, domDoc))
00148 return false;
00149 dest = domDoc.toString(indent);
00150 return true;
00151 }
00152
00153 bool
00154 FormIO::saveFormToDom(Form *form, QDomDocument &domDoc)
00155 {
00156 m_currentForm = form;
00157
00158 domDoc = QDomDocument("UI");
00159 QDomElement uiElement = domDoc.createElement("UI");
00160 domDoc.appendChild(uiElement);
00161 uiElement.setAttribute("version", "3.1");
00162 uiElement.setAttribute("stdsetdef", 1);
00163
00164
00165 form->headerProperties()->insert("version", QString::number(form->formatVersion()));
00166
00167 QDomElement headerPropertiesEl = domDoc.createElement("kfd:customHeader");
00168 for (QMapConstIterator<QCString,QString> it=form->headerProperties()->constBegin(); it!=form->headerProperties()->constEnd(); ++it) {
00169 headerPropertiesEl.setAttribute(it.key(), it.data());
00170 }
00171 uiElement.appendChild(headerPropertiesEl);
00172
00174 QDomElement inlinePix = domDoc.createElement("pixmapinproject");
00175 uiElement.appendChild(inlinePix);
00176
00177
00178 QDomElement baseClass = domDoc.createElement("class");
00179 uiElement.appendChild(baseClass);
00180 QDomText baseClassV = domDoc.createTextNode("QWidget");
00181 baseClass.appendChild(baseClassV);
00182
00183
00184 saveWidget(form->objectTree(), uiElement, domDoc);
00185
00186
00187 QDomElement layoutDefaults = domDoc.createElement("layoutDefaults");
00188 layoutDefaults.setAttribute("spacing", QString::number(form->defaultSpacing()));
00189 layoutDefaults.setAttribute("margin", QString::number(form->defaultMargin()));
00190 uiElement.appendChild(layoutDefaults);
00191
00193 if(form->autoTabStops())
00194 form->autoAssignTabStops();
00195 QDomElement tabStops = domDoc.createElement("tabstops");
00196 uiElement.appendChild(tabStops);
00197 for(ObjectTreeListIterator it( form->tabStopsIterator() ); it.current(); ++it)
00198 {
00199 QDomElement tabstop = domDoc.createElement("tabstop");
00200 tabStops.appendChild(tabstop);
00201 QDomText tabStopText = domDoc.createTextNode(it.current()->name());
00202 tabstop.appendChild(tabStopText);
00203 }
00204
00205
00206 form->pixmapCollection()->save(uiElement);
00207
00208 form->connectionBuffer()->save(uiElement);
00209
00210 form->commandHistory()->documentSaved();
00211
00212 m_currentForm = 0;
00213 m_currentItem = 0;
00214
00215
00216 return true;
00217 }
00218
00219 bool
00220 FormIO::loadFormFromByteArray(Form *form, QWidget *container, QByteArray &src, bool preview)
00221 {
00222 QString errMsg;
00223 int errLine;
00224 int errCol;
00225
00226 QDomDocument inBuf;
00227 bool parsed = inBuf.setContent(src, false, &errMsg, &errLine, &errCol);
00228
00229 if(!parsed)
00230 {
00231 kdDebug() << "WidgetWatcher::load(): " << errMsg << endl;
00232 kdDebug() << "WidgetWatcher::load(): line: " << errLine << " col: " << errCol << endl;
00233 return false;
00234 }
00235
00236 if (!loadFormFromDom(form, container, inBuf))
00237 return false;
00238 if(preview)
00239 form->setDesignMode(false);
00240 return true;
00241 }
00242
00243 bool
00244 FormIO::loadFormFromString(Form *form, QWidget *container, QString &src, bool preview)
00245 {
00246 QString errMsg;
00247 int errLine;
00248 int errCol;
00249
00250 #ifdef KEXI_SHOW_DEBUG_ACTIONS
00251 form->m_recentlyLoadedUICode = src;
00252 #endif
00253
00254 QDomDocument inBuf;
00255 bool parsed = inBuf.setContent(src, false, &errMsg, &errLine, &errCol);
00256
00257 if(!parsed)
00258 {
00259 kdDebug() << "WidgetWatcher::load(): " << errMsg << endl;
00260 kdDebug() << "WidgetWatcher::load(): line: " << errLine << " col: " << errCol << endl;
00261 return false;
00262 }
00263
00264 if (!loadFormFromDom(form, container, inBuf))
00265 return false;
00266 if(preview)
00267 form->setDesignMode(false);
00268 return true;
00269 }
00270
00271 bool
00272 FormIO::loadFormFromFile(Form *form, QWidget *container, const QString &filename)
00273 {
00274 QString errMsg;
00275 int errLine;
00276 int errCol;
00277 QString m_filename;
00278
00279 if(filename.isNull())
00280 {
00281 m_filename = KFileDialog::getOpenFileName(QString::null, i18n("*.ui|Qt Designer UI Files"));
00282 if(m_filename.isNull())
00283 return false;
00284 }
00285 else
00286 m_filename = filename;
00287
00288 QFile file(m_filename);
00289 if(!file.open(IO_ReadOnly))
00290 {
00291 kdDebug() << "Cannot open the file " << filename << endl;
00292 return false;
00293 }
00294 QTextStream stream(&file);
00295 QString text = stream.read();
00296
00297 QDomDocument inBuf;
00298 bool parsed = inBuf.setContent(text, false, &errMsg, &errLine, &errCol);
00299
00300 if(!parsed)
00301 {
00302 kdDebug() << "WidgetWatcher::load(): " << errMsg << endl;
00303 kdDebug() << "WidgetWatcher::load(): line: " << errLine << " col: " << errCol << endl;
00304 return false;
00305 }
00306
00307 return loadFormFromDom(form, container, inBuf);
00308 }
00309
00310 bool
00311 FormIO::loadFormFromDom(Form *form, QWidget *container, QDomDocument &inBuf)
00312 {
00313 m_currentForm = form;
00314
00315 QDomElement ui = inBuf.namedItem("UI").toElement();
00316
00317
00318 form->headerProperties()->clear();
00319 QDomElement headerPropertiesEl = ui.namedItem("kfd:customHeader").toElement();
00320 QDomAttr attr = headerPropertiesEl.firstChild().toAttr();
00321 while (!attr.isNull() && attr.isAttr()) {
00322 form->headerProperties()->insert(attr.name().latin1(), attr.value());
00323 attr = attr.nextSibling().toAttr();
00324 }
00325
00326 uint ver = 1;
00327 if (form->headerProperties()->contains("version")) {
00328 bool ok;
00329 uint v = (*form->headerProperties())["version"].toUInt(&ok);
00330 if (ok)
00331 ver = v;
00332 }
00333 kdDebug() << "FormIO::loadFormFromDom(): original format version: " << ver << endl;
00334 form->setOriginalFormatVersion( ver );
00335 if (ver < KFormDesigner::version()) {
00338 kdDebug() << "FormIO::loadFormFromDom(): original format is older than current: " << KFormDesigner::version() << endl;
00339 form->setFormatVersion( KFormDesigner::version() );
00340 }
00341 else
00342 form->setFormatVersion( ver );
00343
00344 if (ver > KFormDesigner::version()) {
00346 kdDebug() << "FormIO::loadFormFromDom(): original format is newer than current: " << KFormDesigner::version() << endl;
00347 }
00348
00349
00350 m_savePixmapsInline = ( (ui.namedItem("pixmapinproject").isNull()) || (!ui.namedItem("images").isNull()) );
00351 form->pixmapCollection()->load(ui.namedItem("collection"));
00352
00353 QDomElement element = ui.namedItem("widget").toElement();
00354 createToplevelWidget(form, container, element);
00355
00356
00357 QDomElement tabStops = ui.namedItem("tabstops").toElement();
00358
00359
00360 if(!tabStops.isNull()) {
00361 int i = 0;
00362 uint itemsNotFound = 0;
00363 for(QDomNode n = tabStops.firstChild(); !n.isNull(); n = n.nextSibling(), i++)
00364 {
00365 QString name = n.toElement().text();
00366 ObjectTreeItem *item = form->objectTree()->lookup(name);
00367 if(!item)
00368 {
00369 kdDebug() << "FormIO::loadFormFromDom ERROR : no ObjectTreeItem " << endl;
00370 continue;
00371 }
00372 const int index = form->tabStops()->findRef(item);
00373
00374 const int realIndex = i - itemsNotFound;
00375 if((index != -1) && (index != realIndex))
00376 {
00377 form->tabStops()->remove(item);
00378 form->tabStops()->insert(realIndex, item);
00379 }
00380 if(index == -1) {
00381 itemsNotFound++;
00382 kdDebug() << "FormIO: item '" << name << "' not in list" << endl;
00383 }
00384 }
00385 }
00386
00387
00388 form->connectionBuffer()->load(ui.namedItem("connections"));
00389
00390 m_currentForm = 0;
00391 m_currentItem = 0;
00392
00393 return true;
00394 }
00395
00399
00400 void
00401 FormIO::savePropertyValue(QDomElement &parentNode, QDomDocument &parent, const char *name,
00402 const QVariant &value, QWidget *w, WidgetLibrary *lib)
00403 {
00404
00405 kdDebug() << "FormIO::savePropertyValue() Saving the property: " << name << endl;
00406 const int propertyId = w->metaObject()->findProperty(name, true);
00407 if(propertyId == -1)
00408 {
00409 kdDebug() << "FormIO::savePropertyValue() The object doesn't have this property. Let's try the WidgetLibrary." << endl;
00410 if(lib)
00411 lib->saveSpecialProperty(w->className(), name, value, w, parentNode, parent);
00412 return;
00413 }
00414
00415 const QMetaProperty *meta = w->metaObject()->property(propertyId, true);
00416 if (!meta->stored( w ))
00417 return;
00418 QDomElement propertyE = parent.createElement("property");
00419 propertyE.setAttribute("name", name);
00420
00421 if(meta && meta->isEnumType())
00422 {
00423
00424 QDomElement type;
00425 QDomText valueE;
00426
00427 if(meta->isSetType())
00428 {
00429 QStringList list = QStringList::fromStrList(meta->valueToKeys(value.toInt()));
00430 type = parent.createElement("set");
00431 valueE = parent.createTextNode(list.join("|"));
00432 type.appendChild(valueE);
00433 }
00434 else
00435 {
00436 QString s = meta->valueToKey(value.toInt());
00437 type = parent.createElement("enum");
00438 valueE = parent.createTextNode(s);
00439 type.appendChild(valueE);
00440 }
00441 propertyE.appendChild(type);
00442 parentNode.appendChild(propertyE);
00443 return;
00444 }
00445
00446 if(value.type() == QVariant::Pixmap) {
00447 QDomText valueE;
00448 QDomElement type = parent.createElement("pixmap");
00449 QCString property = propertyE.attribute("name").latin1();
00450
00451 if(m_savePixmapsInline )
00452 valueE = parent.createTextNode(saveImage(parent, value.toPixmap()));
00453 else
00454 valueE = parent.createTextNode(m_currentItem->pixmapName(property));
00455 type.appendChild(valueE);
00456 propertyE.appendChild(type);
00457 parentNode.appendChild(propertyE);
00458 return;
00459 }
00460
00461
00462 writeVariant(parent, propertyE, value);
00463 parentNode.appendChild(propertyE);
00464 }
00465
00466 void
00467 FormIO::writeVariant(QDomDocument &parent, QDomElement &parentNode, QVariant value)
00468 {
00469 QDomElement type;
00470 QDomText valueE;
00471
00472 switch(value.type())
00473 {
00474 case QVariant::String:
00475 {
00476 type = parent.createElement("string");
00477 valueE = parent.createTextNode(value.toString());
00478 type.appendChild(valueE);
00479 break;
00480 }
00481 case QVariant::CString:
00482 {
00483 type = parent.createElement("cstring");
00484 valueE = parent.createTextNode(value.toString());
00485 type.appendChild(valueE);
00486 break;
00487 }
00488 case QVariant::Rect:
00489 {
00490 type = parent.createElement("rect");
00491 QDomElement x = parent.createElement("x");
00492 QDomElement y = parent.createElement("y");
00493 QDomElement w = parent.createElement("width");
00494 QDomElement h = parent.createElement("height");
00495 QDomText valueX = parent.createTextNode(QString::number(value.toRect().x()));
00496 QDomText valueY = parent.createTextNode(QString::number(value.toRect().y()));
00497 QDomText valueW = parent.createTextNode(QString::number(value.toRect().width()));
00498 QDomText valueH = parent.createTextNode(QString::number(value.toRect().height()));
00499
00500 x.appendChild(valueX);
00501 y.appendChild(valueY);
00502 w.appendChild(valueW);
00503 h.appendChild(valueH);
00504
00505 type.appendChild(x);
00506 type.appendChild(y);
00507 type.appendChild(w);
00508 type.appendChild(h);
00509 break;
00510 }
00511 case QVariant::Color:
00512 {
00513 type = parent.createElement("color");
00514 QDomElement r = parent.createElement("red");
00515 QDomElement g = parent.createElement("green");
00516 QDomElement b = parent.createElement("blue");
00517 QDomText valueR = parent.createTextNode(QString::number(value.toColor().red()));
00518 QDomText valueG = parent.createTextNode(QString::number(value.toColor().green()));
00519 QDomText valueB = parent.createTextNode(QString::number(value.toColor().blue()));
00520
00521 r.appendChild(valueR);
00522 g.appendChild(valueG);
00523 b.appendChild(valueB);
00524
00525 type.appendChild(r);
00526 type.appendChild(g);
00527 type.appendChild(b);
00528 break;
00529 }
00530 case QVariant::Bool:
00531 {
00532 type = parent.createElement("bool");
00533
00534 valueE = parent.createTextNode(value.toBool() ? "true" : "false");
00535 type.appendChild(valueE);
00536 break;
00537 }
00538 case QVariant::Int:
00539 case QVariant::UInt:
00540 {
00541 type = parent.createElement("number");
00542 valueE = parent.createTextNode(QString::number(value.toInt()));
00543 type.appendChild(valueE);
00544 break;
00545 }
00546 case QVariant::Size:
00547 {
00548 type = parent.createElement("size");
00549 QDomElement w = parent.createElement("width");
00550 QDomElement h = parent.createElement("height");
00551 QDomText valueW = parent.createTextNode(QString::number(value.toSize().width()));
00552 QDomText valueH = parent.createTextNode(QString::number(value.toSize().height()));
00553
00554 w.appendChild(valueW);
00555 h.appendChild(valueH);
00556
00557 type.appendChild(w);
00558 type.appendChild(h);
00559 break;
00560 }
00561 case QVariant::Point:
00562 {
00563 type = parent.createElement("point");
00564 QDomElement x = parent.createElement("x");
00565 QDomElement y = parent.createElement("y");
00566 QDomText valueX = parent.createTextNode(QString::number(value.toPoint().x()));
00567 QDomText valueY = parent.createTextNode(QString::number(value.toPoint().y()));
00568
00569 x.appendChild(valueX);
00570 y.appendChild(valueY);
00571
00572 type.appendChild(x);
00573 type.appendChild(y);
00574 break;
00575 }
00576 case QVariant::Font:
00577 {
00578 type = parent.createElement("font");
00579 QDomElement f = parent.createElement("family");
00580 QDomElement p = parent.createElement("pointsize");
00581 QDomElement w = parent.createElement("weight");
00582 QDomElement b = parent.createElement("bold");
00583 QDomElement i = parent.createElement("italic");
00584 QDomElement u = parent.createElement("underline");
00585 QDomElement s = parent.createElement("strikeout");
00586 QDomText valueF = parent.createTextNode(value.toFont().family());
00587 QDomText valueP = parent.createTextNode(QString::number(value.toFont().pointSize()));
00588 QDomText valueW = parent.createTextNode(QString::number(value.toFont().weight()));
00589 QDomText valueB = parent.createTextNode(QString::number(value.toFont().bold()));
00590 QDomText valueI = parent.createTextNode(QString::number(value.toFont().italic()));
00591 QDomText valueU = parent.createTextNode(QString::number(value.toFont().underline()));
00592 QDomText valueS = parent.createTextNode(QString::number(value.toFont().strikeOut()));
00593
00594 f.appendChild(valueF);
00595 p.appendChild(valueP);
00596 w.appendChild(valueW);
00597 b.appendChild(valueB);
00598 i.appendChild(valueI);
00599 u.appendChild(valueU);
00600 s.appendChild(valueS);
00601
00602 type.appendChild(f);
00603 type.appendChild(p);
00604 type.appendChild(w);
00605 type.appendChild(b);
00606 type.appendChild(i);
00607 type.appendChild(u);
00608 type.appendChild(s);
00609 break;
00610 }
00611 case QVariant::Cursor:
00612 {
00613 type = parent.createElement("cursor");
00614 valueE = parent.createTextNode(QString::number(value.toCursor().shape()));
00615 type.appendChild(valueE);
00616 break;
00617 }
00618 case QVariant::SizePolicy:
00619 {
00620 type = parent.createElement("sizepolicy");
00621 QDomElement h = parent.createElement("hsizetype");
00622 QDomElement v = parent.createElement("vsizetype");
00623 QDomElement hs = parent.createElement("horstretch");
00624 QDomElement vs = parent.createElement("verstretch");
00625 QDomText valueH = parent.createTextNode(QString::number(value.toSizePolicy().horData()));
00626 QDomText valueV = parent.createTextNode(QString::number(value.toSizePolicy().verData()));
00627 QDomText valueHS = parent.createTextNode(QString::number(value.toSizePolicy().horStretch()));
00628 QDomText valueVS = parent.createTextNode(QString::number(value.toSizePolicy().verStretch()));
00629
00630 h.appendChild(valueH);
00631 v.appendChild(valueV);
00632 hs.appendChild(valueHS);
00633 vs.appendChild(valueVS);
00634
00635 type.appendChild(h);
00636 type.appendChild(v);
00637 type.appendChild(hs);
00638 type.appendChild(vs);
00639 break;
00640 }
00641 case QVariant::Time:
00642 {
00643 type = parent.createElement("time");
00644 QDomElement h = parent.createElement("hour");
00645 QDomElement m = parent.createElement("minute");
00646 QDomElement s = parent.createElement("second");
00647 QDomText valueH = parent.createTextNode(QString::number(value.toTime().hour()));
00648 QDomText valueM = parent.createTextNode(QString::number(value.toTime().minute()));
00649 QDomText valueS = parent.createTextNode(QString::number(value.toTime().second()));
00650
00651 h.appendChild(valueH);
00652 m.appendChild(valueM);
00653 s.appendChild(valueS);
00654
00655 type.appendChild(h);
00656 type.appendChild(m);
00657 type.appendChild(s);
00658 break;
00659 }
00660 case QVariant::Date:
00661 {
00662 type = parent.createElement("date");
00663 QDomElement y = parent.createElement("year");
00664 QDomElement m = parent.createElement("month");
00665 QDomElement d = parent.createElement("day");
00666 QDomText valueY = parent.createTextNode(QString::number(value.toDate().year()));
00667 QDomText valueM = parent.createTextNode(QString::number(value.toDate().month()));
00668 QDomText valueD = parent.createTextNode(QString::number(value.toDate().day()));
00669
00670 y.appendChild(valueY);
00671 m.appendChild(valueM);
00672 d.appendChild(valueD);
00673
00674 type.appendChild(y);
00675 type.appendChild(m);
00676 type.appendChild(d);
00677 break;
00678 }
00679 case QVariant::DateTime:
00680 {
00681 type = parent.createElement("datetime");
00682 QDomElement h = parent.createElement("hour");
00683 QDomElement m = parent.createElement("minute");
00684 QDomElement s = parent.createElement("second");
00685 QDomElement y = parent.createElement("year");
00686 QDomElement mo = parent.createElement("month");
00687 QDomElement d = parent.createElement("day");
00688 QDomText valueH = parent.createTextNode(QString::number(value.toDateTime().time().hour()));
00689 QDomText valueM = parent.createTextNode(QString::number(value.toDateTime().time().minute()));
00690 QDomText valueS = parent.createTextNode(QString::number(value.toDateTime().time().second()));
00691 QDomText valueY = parent.createTextNode(QString::number(value.toDateTime().date().year()));
00692 QDomText valueMo = parent.createTextNode(QString::number(value.toDateTime().date().month()));
00693 QDomText valueD = parent.createTextNode(QString::number(value.toDateTime().date().day()));
00694
00695 h.appendChild(valueH);
00696 m.appendChild(valueM);
00697 s.appendChild(valueS);
00698 y.appendChild(valueY);
00699 mo.appendChild(valueMo);
00700 d.appendChild(valueD);
00701
00702 type.appendChild(h);
00703 type.appendChild(m);
00704 type.appendChild(s);
00705 type.appendChild(y);
00706 type.appendChild(mo);
00707 type.appendChild(d);
00708 break;
00709 }
00710 default:
00711 break;
00712 }
00713
00714 parentNode.appendChild(type);
00715 }
00716
00717 void
00718 FormIO::savePropertyElement(QDomElement &parentNode, QDomDocument &domDoc, const QString &tagName, const QString &property, const QVariant &value)
00719 {
00720 QDomElement propertyE = domDoc.createElement(tagName);
00721 propertyE.setAttribute("name", property);
00722 writeVariant(domDoc, propertyE, value);
00723 parentNode.appendChild(propertyE);
00724 }
00725
00726 QVariant
00727 FormIO::readPropertyValue(QDomNode node, QObject *obj, const QString &name)
00728 {
00729 QDomElement tag = node.toElement();
00730 QString text = tag.text();
00731 QString type = tag.tagName();
00732
00733 if(type == "string" || type == "cstring")
00734 return text;
00735 else if(type == "rect")
00736 {
00737 QDomElement x = node.namedItem("x").toElement();
00738 QDomElement y = node.namedItem("y").toElement();
00739 QDomElement w = node.namedItem("width").toElement();
00740 QDomElement h = node.namedItem("height").toElement();
00741
00742 int rx = x.text().toInt();
00743 int ry = y.text().toInt();
00744 int rw = w.text().toInt();
00745 int rh = h.text().toInt();
00746
00747 return QRect(rx, ry, rw, rh);
00748 }
00749 else if(type == "color")
00750 {
00751 QDomElement r = node.namedItem("red").toElement();
00752 QDomElement g = node.namedItem("green").toElement();
00753 QDomElement b = node.namedItem("blue").toElement();
00754
00755 int red = r.text().toInt();
00756 int green = g.text().toInt();
00757 int blue = b.text().toInt();
00758
00759 return QColor(red, green, blue);
00760 }
00761 else if(type == "bool")
00762 {
00763 if(text == "true")
00764 return QVariant(true, 3);
00765 else if(text == "false")
00766 return QVariant(false, 3);
00767 return QVariant(text.toInt(), 3);
00768 }
00769 else if(type == "number")
00770 {
00771 return text.toInt();
00772 }
00773 else if(type == "size")
00774 {
00775 QDomElement w = node.namedItem("width").toElement();
00776 QDomElement h = node.namedItem("height").toElement();
00777
00778 return QSize(w.text().toInt(), h.text().toInt());
00779 }
00780 else if(type == "point")
00781 {
00782 QDomElement x = node.namedItem("x").toElement();
00783 QDomElement y = node.namedItem("y").toElement();
00784
00785 return QPoint(x.text().toInt(), y.text().toInt());
00786 }
00787 else if(type == "font")
00788 {
00789 QDomElement fa = node.namedItem("family").toElement();
00790 QDomElement p = node.namedItem("pointsize").toElement();
00791 QDomElement w = node.namedItem("weight").toElement();
00792 QDomElement b = node.namedItem("bold").toElement();
00793 QDomElement i = node.namedItem("italic").toElement();
00794 QDomElement u = node.namedItem("underline").toElement();
00795 QDomElement s = node.namedItem("strikeout").toElement();
00796
00797 QFont f;
00798 f.setFamily(fa.text());
00799 f.setPointSize(p.text().toInt());
00800 f.setWeight(w.text().toInt());
00801 f.setBold(b.text().toInt());
00802 f.setItalic(i.text().toInt());
00803 f.setUnderline(u.text().toInt());
00804 f.setStrikeOut(s.text().toInt());
00805
00806 return f;
00807 }
00808 else if(type == "cursor")
00809 {
00810 return QCursor(text.toInt());
00811 }
00812 else if(type == "time")
00813 {
00814 QDomElement h = node.namedItem("hour").toElement();
00815 QDomElement m = node.namedItem("minute").toElement();
00816 QDomElement s = node.namedItem("second").toElement();
00817
00818 return QTime(h.text().toInt(), m.text().toInt(), s.text().toInt());
00819 }
00820 else if(type == "date")
00821 {
00822 QDomElement y = node.namedItem("year").toElement();
00823 QDomElement m = node.namedItem("month").toElement();
00824 QDomElement d = node.namedItem("day").toElement();
00825
00826 return QDate(y.text().toInt(), m.text().toInt(), d.text().toInt());
00827 }
00828 else if(type == "datetime")
00829 {
00830 QDomElement h = node.namedItem("hour").toElement();
00831 QDomElement m = node.namedItem("minute").toElement();
00832 QDomElement s = node.namedItem("second").toElement();
00833 QDomElement y = node.namedItem("year").toElement();
00834 QDomElement mo = node.namedItem("month").toElement();
00835 QDomElement d = node.namedItem("day").toElement();
00836
00837 QTime t(h.text().toInt(), m.text().toInt(), s.text().toInt());
00838 QDate da(y.text().toInt(), mo.text().toInt(), d.text().toInt());
00839
00840 return QDateTime(da, t);
00841 }
00842 else if(type == "sizepolicy")
00843 {
00844 QDomElement h = node.namedItem("hsizetype").toElement();
00845 QDomElement v = node.namedItem("vsizetype").toElement();
00846 QDomElement hs = node.namedItem("horstretch").toElement();
00847 QDomElement vs = node.namedItem("verstretch").toElement();
00848
00849 QSizePolicy s;
00850 s.setHorData((QSizePolicy::SizeType)h.text().toInt());
00851 s.setVerData((QSizePolicy::SizeType)v.text().toInt());
00852 s.setHorStretch(hs.text().toInt());
00853 s.setVerStretch(vs.text().toInt());
00854 return s;
00855 }
00856 else if(type == "pixmap")
00857 {
00858 if(m_savePixmapsInline || !m_currentForm || !m_currentItem || !m_currentForm->pixmapCollection()->contains(text))
00859 return loadImage(tag.ownerDocument(), text);
00860 else
00861 {
00862 m_currentItem->setPixmapName(name.latin1(), text);
00863 return m_currentForm->pixmapCollection()->getPixmap(text);
00864 }
00865 return QVariant(QPixmap());
00866 }
00867 else if(type == "enum")
00868 return text;
00869 else if(type == "set")
00870 {
00871 int count = obj->metaObject()->findProperty(name.latin1(), true);
00872 const QMetaProperty *meta = count!=-1 ? obj->metaObject()->property(count, true) : 0;
00873
00874 if(meta && meta->isSetType())
00875 {
00876 QStrList keys;
00877 QStringList list = QStringList::split("|", text);
00878 for(QStringList::iterator it = list.begin(); it != list.end(); ++it)
00879 keys.append((*it).latin1());
00880
00881 return QVariant(meta->keysToValue(keys));
00882 }
00883 }
00884 return QVariant();
00885 }
00886
00890
00891 void
00892 FormIO::saveWidget(ObjectTreeItem *item, QDomElement &parent, QDomDocument &domDoc, bool insideGridLayout)
00893 {
00894 if (!item)
00895 return;
00896 bool savedAlignment = false;
00897
00898 if(item->className() == "Spring")
00899 {
00900 Spring::saveSpring(item, parent, domDoc, insideGridLayout);
00901 return;
00902 }
00903
00904 bool resetCurrentForm = false;
00905 m_currentItem = item;
00906 if(!m_currentForm)
00907 {
00908 resetCurrentForm = true;
00909 m_currentForm = item->container() ? item->container()->form() : item->parent()->container()->form();
00910 }
00911
00912
00913 WidgetLibrary *lib = m_currentForm->library();
00914
00915
00916
00917
00918
00919
00920 QDomElement tclass = domDoc.createElement("widget");
00921 parent.appendChild(tclass);
00922
00923 if(insideGridLayout)
00924 {
00925 tclass.setAttribute("row", item->gridRow());
00926 tclass.setAttribute("column", item->gridCol());
00927 if(item->spanMultipleCells())
00928 {
00929 tclass.setAttribute("rowspan", item->gridRowSpan());
00930 tclass.setAttribute("colspan", item->gridColSpan());
00931 }
00932 }
00933
00934 if(!item->parent())
00935 tclass.setAttribute("class", "QWidget");
00936
00937 else if(item->widget()->isA("HBox") || item->widget()->isA("VBox") || item->widget()->isA("Grid")
00938 || item->widget()->isA("HFlow") || item->widget()->isA("VFlow"))
00939 tclass.setAttribute("class", "QLayoutWidget");
00940 else if(item->widget()->isA("CustomWidget"))
00941 tclass.setAttribute("class", item->className());
00942 else
00943 tclass.setAttribute("class", lib->savingName(item->widget()->className()) );
00944
00945 savePropertyValue(tclass, domDoc, "name", item->widget()->property("name"), item->widget());
00946
00947
00948 if(item && !item->parent()) {
00949
00950 savePropertyValue(tclass, domDoc, "geometry",
00951 QRect( QPoint(0,0), item->widget()->size()),
00952 item->widget());
00953 }
00954
00955 else if(parent.tagName() == "widget" || parent.tagName() == "UI")
00956 savePropertyValue(tclass, domDoc, "geometry", item->widget()->property("geometry"), item->widget());
00957
00958
00959 if(item->widget()->inherits("QLabel") && ((QLabel*)item->widget())->buddy())
00960 savePropertyElement(tclass, domDoc, "property", "buddy", ((QLabel*)item->widget())->buddy()->name());
00961
00962
00963
00964 QVariantMap *map = new QVariantMap( *(item->modifiedProperties()) );
00965 QMap<QString,QVariant>::ConstIterator endIt = map->constEnd();
00966 for(QMap<QString,QVariant>::ConstIterator it = map->constBegin(); it != endIt; ++it)
00967 {
00968 QString name = it.key();
00969 if((name == QString::fromLatin1("hAlign")) || (name == QString::fromLatin1("vAlign")) || (name == QString::fromLatin1("wordbreak")))
00970 {
00971 if(!savedAlignment)
00972 {
00973 savePropertyValue(tclass, domDoc, "alignment", item->widget()->property("alignment"), item->widget());
00974 savedAlignment = true;
00975 }
00976 }
00977
00978 else if(name == "name" || name == "geometry" || name == "layout") {
00979
00980 }
00981 else {
00982 savePropertyValue(tclass, domDoc, it.key().latin1(), item->widget()->property(it.key().latin1()),
00983 item->widget(), lib);
00984 }
00985 }
00986 delete map;
00987
00988 if(item->widget()->isA("CustomWidget")) {
00989 QDomDocument doc("TEMP");
00990 doc.setContent(item->m_unknownProps);
00991 for(QDomNode n = doc.firstChild(); !n.isNull(); n = n.nextSibling()) {
00992 tclass.appendChild(n.cloneNode());
00993 }
00994
00995 }
00996
00997 QDomElement layout;
00998 if(item->container() && item->container()->layoutType() != Container::NoLayout)
00999 {
01000 if(item->container()->layout())
01001 {
01002 layout = domDoc.createElement("temp");
01003 savePropertyValue(layout, domDoc, "name", "unnamed", item->widget());
01004 if(item->modifiedProperties()->contains("layoutMargin"))
01005 savePropertyElement(layout, domDoc, "property", "margin", item->container()->layoutMargin());
01006 if(item->modifiedProperties()->contains("layoutSpacing"))
01007 savePropertyElement(layout, domDoc, "property", "spacing", item->container()->layoutSpacing());
01008 tclass.appendChild(layout);
01009 }
01010 }
01011
01012 int layoutType = item->container() ? item->container()->layoutType() : Container::NoLayout;
01013 switch(layoutType) {
01014 case Container::Grid:
01015 {
01016 layout.setTagName("grid");
01017 for(ObjectTreeItem *objIt = item->children()->first(); objIt; objIt = item->children()->next())
01018 saveWidget(objIt, layout, domDoc, true);
01019 break;
01020 }
01021 case Container::HBox: case Container::VBox:
01022 {
01023
01024 WidgetList *list;
01025 if(layout.tagName() == "hbox") {
01026 list = new HorWidgetList();
01027 layout.setTagName("hbox");
01028 }
01029 else {
01030 list = new VerWidgetList();
01031 layout.setTagName("vbox");
01032 }
01033
01034 for(ObjectTreeItem *objTree = item->children()->first(); objTree; objTree = item->children()->next())
01035 list->append(objTree->widget());
01036 list->sort();
01037
01038 for(QWidget *obj = list->first(); obj; obj = list->next()) {
01039 ObjectTreeItem *titem = item->container()->form()->objectTree()->lookup(obj->name());
01040 if(item)
01041 saveWidget(titem, layout, domDoc);
01042 }
01043 delete list;
01044 break;
01045 }
01046 case Container::HFlow: case Container::VFlow:
01047 {
01048 layout.setTagName("grid");
01049 KexiFlowLayout *flow = static_cast<KexiFlowLayout*>(item->container()->layout());
01050 if(!flow) break;
01051 WidgetList *list = (WidgetList*)flow->widgetList();
01052
01053
01054 savePropertyElement(layout, domDoc, "property", "customLayout", Container::layoutTypeToString(item->container()->layoutType()) );
01055 savePropertyElement(layout, domDoc, "property", "justify", QVariant(static_cast<KexiFlowLayout*>(item->container()->layout())->isJustified(), 3) );
01056
01057
01058 item->container()->createGridLayout(true);
01059 for(QWidget *obj = list->first(); obj; obj = list->next()) {
01060 ObjectTreeItem *titem = item->container()->form()->objectTree()->lookup(obj->name());
01061 if(item)
01062 saveWidget(titem, layout, domDoc, true);
01063 }
01064 delete list;
01065 break;
01066 }
01067 default:
01068 {
01069 for(ObjectTreeItem *objIt = item->children()->first(); objIt; objIt = item->children()->next())
01070 saveWidget(objIt, tclass, domDoc);
01071 }
01072 }
01073
01074 addIncludeFileName(lib->includeFileName(item->widget()->className()), domDoc);
01075
01076 if(resetCurrentForm)
01077 m_currentForm = 0;
01078 m_currentItem = 0;
01079 }
01080
01081 void
01082 FormIO::cleanClipboard(QDomElement &uiElement)
01083 {
01084
01085 if(!uiElement.namedItem("includehints").isNull())
01086 uiElement.removeChild(uiElement.namedItem("includehints"));
01087
01088 if(!uiElement.namedItem("connections").isNull())
01089 uiElement.insertAfter(uiElement.namedItem("connections"), QDomNode());
01090 if(!uiElement.namedItem("images").isNull())
01091 uiElement.insertAfter(uiElement.namedItem("images"), QDomNode());
01092 }
01093
01094 void
01095 FormIO::loadWidget(Container *container, const QDomElement &el, QWidget *parent)
01096 {
01097 bool resetCurrentForm = false;
01098 if(!m_currentForm)
01099 {
01100 resetCurrentForm = true;
01101 m_currentForm = container->form();
01102 }
01103
01104
01105 QString wname;
01106 for(QDomNode n = el.firstChild(); !n.isNull(); n = n.nextSibling())
01107 {
01108 if((n.toElement().tagName() == "property") && (n.toElement().attribute("name") == "name"))
01109 {
01110 wname = n.toElement().text();
01111 break;
01112 }
01113 }
01114
01115 QWidget *w;
01116 QCString classname, alternate;
01117
01118 if(el.tagName() == "spacer")
01119 classname = "Spring";
01120 else if(el.attribute("class") == "QLayoutWidget")
01121 {
01122 for(QDomNode n = el.firstChild(); !n.isNull(); n = n.nextSibling())
01123 {
01124 QString tagName = n.toElement().tagName();
01125 if(tagName == "property")
01126 continue;
01127 if(tagName == "hbox")
01128 classname = "HBox";
01129 else if(tagName == "vbox")
01130 classname = "VBox";
01131 else if(tagName == "grid") {
01132
01133 for(QDomNode child = n.firstChild(); !child.isNull(); child = child.nextSibling()) {
01134 if((child.toElement().tagName() == "property")
01135 && (child.toElement().attribute("name") == "customLayout"))
01136 {
01137 classname = child.toElement().text().latin1();
01138 break;
01139 }
01140 }
01141
01142 if(classname.isEmpty())
01143 classname = "Grid";
01144 }
01145 }
01146 }
01147 else
01148
01149 {
01150 classname = el.attribute("class").local8Bit();
01151 alternate = container->form()->library()->classNameForAlternate(classname);
01152 }
01153
01154 if(alternate == "CustomWidget")
01155 w = new CustomWidget(classname, container->widget(), wname.latin1());
01156 else
01157 {
01158 if(!alternate.isNull())
01159 classname = alternate;
01160
01161 int widgetOptions = WidgetFactory::DefaultOptions;
01162 if (!container->form()->designMode()) {
01163 widgetOptions ^= WidgetFactory::DesignViewMode;
01164 }
01165
01166 if(!parent)
01167 w = container->form()->library()->createWidget(classname, container->widget(),
01168 wname.latin1(), container, widgetOptions);
01169 else
01170 w = container->form()->library()->createWidget(classname, parent, wname.latin1(),
01171 container, widgetOptions);
01172 }
01173
01174 if(!w)
01175 return;
01176 #if KDE_VERSION >= KDE_MAKE_VERSION(3,4,0)
01178 if (m_currentForm->designMode()) {
01179
01180 KAcceleratorManager::setNoAccel(w);
01181 }
01182 #endif
01183 w->setStyle(&(container->widget()->style()));
01184 w->show();
01185
01186
01187 ObjectTreeItem *item = container->form()->objectTree()->lookup(wname);
01188 if (!item) {
01189
01190 item = new ObjectTreeItem(container->form()->library()->displayName(classname),
01191 wname, w, container);
01192 if(parent) {
01193 ObjectTreeItem *titem = container->form()->objectTree()->lookup(parent->name());
01194 if(titem)
01195 container->form()->objectTree()->addItem(titem, item);
01196 else
01197 kdDebug() << "FORMIO :: ERROR no parent widget " << endl;
01198 }
01199 else
01200 container->form()->objectTree()->addItem(container->objectTree(), item);
01201 }
01202
01203
01204 if (container->form()->designMode() && dynamic_cast<DesignTimeDynamicChildWidgetHandler*>(w)) {
01205 dynamic_cast<DesignTimeDynamicChildWidgetHandler*>(w)->assignItem(item);
01206 }
01207
01208 m_currentItem = item;
01209
01210 if(container->layoutType() == Container::Grid) {
01211 QGridLayout *layout = (QGridLayout*)container->layout();
01212 if(el.hasAttribute("rowspan")) {
01213 if(layout)
01214 layout->addMultiCellWidget(w, el.attribute("row").toInt(), el.attribute("row").toInt() + el.attribute("rowspan").toInt()-1,
01215 el.attribute("column").toInt(), el.attribute("column").toInt() + el.attribute("colspan").toInt()-1);
01216 item->setGridPos(el.attribute("row").toInt(), el.attribute("column").toInt(), el.attribute("rowspan").toInt(),
01217 el.attribute("colspan").toInt());
01218 }
01219 else {
01220 if(layout)
01221 layout->addWidget(w, el.attribute("row").toInt(), el.attribute("column").toInt());
01222 item->setGridPos(el.attribute("row").toInt(), el.attribute("column").toInt(), 0, 0);
01223 }
01224 }
01225 else if(container->layout())
01226 container->layout()->add(w);
01227
01228 readChildNodes(item, container, el, w);
01229
01230 if(item->container() && item->container()->layout())
01231 item->container()->layout()->activate();
01232
01233
01234 QValueList<QCString> list(container->form()->library()->autoSaveProperties(w->className()));
01235 QValueList<QCString>::ConstIterator endIt = list.constEnd();
01236 for(QValueList<QCString>::ConstIterator it = list.constBegin(); it != endIt; ++it) {
01237 if(w->metaObject()->findProperty(*it, true) != -1)
01238 item->addModifiedProperty(*it, w->property(*it));
01239 }
01240
01241 if(resetCurrentForm)
01242 m_currentForm = 0;
01243 m_currentItem = 0;
01244 }
01245
01246 void
01247 FormIO::createToplevelWidget(Form *form, QWidget *container, QDomElement &el)
01248 {
01249
01250 QString wname;
01251 for(QDomNode n = el.firstChild(); !n.isNull(); n = n.nextSibling())
01252 {
01253 if((n.toElement().tagName() == "property") && (n.toElement().attribute("name") == "name"))
01254 {
01255 wname = n.toElement().text();
01256 break;
01257 }
01258
01259 }
01260
01261 container->setName(wname.latin1());
01262 if(form->objectTree())
01263 form->objectTree()->rename(form->objectTree()->name(), wname);
01264 form->setInteractiveMode(false);
01265
01266 QDict<QLabel> *oldBuddies = 0;
01267 if(m_buddies)
01268 oldBuddies = m_buddies;
01269 m_buddies = new QDict<QLabel>();
01270 m_currentItem = form->objectTree();
01271
01272 readChildNodes(form->objectTree(), form->toplevelContainer(), el, container);
01273
01274
01275 QDictIterator<QLabel> it(*m_buddies);
01276 for(; it.current(); ++it)
01277 {
01278 ObjectTreeItem *item = form->objectTree()->lookup(it.currentKey());
01279 if(!item || !item->widget())
01280 {
01281 kdDebug() << "Cannot assign buddy for widget " << it.current()->name() << " to " << it.currentKey() << endl;
01282 continue;
01283 }
01284 it.current()->setBuddy(item->widget());
01285 }
01286 delete m_buddies;
01287 m_buddies = oldBuddies;
01288
01289 m_currentItem = 0;
01290
01291 form->setInteractiveMode(true);
01292 }
01293
01294 void
01295 FormIO::readChildNodes(ObjectTreeItem *item, Container *container, const QDomElement &el, QWidget *w)
01296 {
01297 QString eltag = el.tagName();
01298
01299 for(QDomNode n = el.firstChild(); !n.isNull(); n = n.nextSibling())
01300 {
01301 QString tag = n.toElement().tagName();
01302 QDomElement node = n.toElement();
01303
01304 if((tag == "property") || (tag == "attribute"))
01305 {
01306 QString name = node.attribute("name");
01307
01308
01309 if( ((eltag == "grid") || (eltag == "hbox") || (eltag == "vbox")) &&
01310 (name == "name"))
01311 continue;
01312
01313
01314 if(name == "buddy")
01315 m_buddies->insert(readPropertyValue(node.firstChild(), w, name).toString(), (QLabel*)w);
01316 else if(((eltag == "grid") || (eltag == "hbox") || (eltag == "vbox")) &&
01317 item->container() && item->container()->layout()) {
01318
01319 if(name == "margin") {
01320 int margin = readPropertyValue(node.firstChild(), w, name).toInt();
01321 item->container()->setLayoutMargin(margin);
01322 item->container()->layout()->setMargin(margin);
01323 }
01324
01325 else if(name == "spacing") {
01326 int spacing = readPropertyValue(node.firstChild(), w, name).toInt();
01327 item->container()->setLayoutSpacing(spacing);
01328 item->container()->layout()->setSpacing(spacing);
01329 }
01330 else if((name == "justify")){
01331 bool justify = readPropertyValue(node.firstChild(), w, name).toBool();
01332 KexiFlowLayout *flow = static_cast<KexiFlowLayout*>(item->container()->layout());
01333 if(flow)
01334 flow->setJustified(justify);
01335 }
01336 }
01337
01338 else if(w->metaObject()->findProperty(name.latin1(), true) == -1)
01339 {
01340 if(w->className() == QString::fromLatin1("CustomWidget"))
01341 item->storeUnknownProperty(node);
01342 else {
01343 bool read = container->form()->library()->readSpecialProperty(
01344 w->className(), node, w, item);
01345 if(!read)
01346 item->storeUnknownProperty(node);
01347 }
01348 }
01349 else
01350 {
01351 QVariant val( readPropertyValue(node.firstChild(), w, name) );
01352 if(name == "geometry" && dynamic_cast<FormWidget*>(w)) {
01353
01354 QRect r( val.toRect() );
01355 if (r.left()<0)
01356 r.moveLeft(0);
01357 if (r.top()<0)
01358 r.moveTop(0);
01359 val = r;
01360 }
01361 w->setProperty(name.latin1(), val);
01362
01363
01364
01365
01366
01367 item->addModifiedProperty(name.latin1(), val);
01368 }
01369 }
01370 else if(tag == "widget")
01371 {
01372 if(item->container())
01373 loadWidget(item->container(), node);
01374 else
01375 loadWidget(container, node, w);
01376 }
01377 else if(tag == "spacer") {
01378 loadWidget(container, node, w);
01379 }
01380 else if(tag == "grid") {
01381
01382 QString layoutName;
01383 for(QDomNode child = node.firstChild(); !child.isNull(); child = child.nextSibling()) {
01384 if((child.toElement().tagName() == "property") && (child.toElement().attribute("name") == "customLayout")) {
01385 layoutName = child.toElement().text();
01386 break;
01387 }
01388 }
01389
01390 if(layoutName == "HFlow") {
01391 item->container()->m_layType = Container::HFlow;
01392 KexiFlowLayout *layout = new KexiFlowLayout(item->widget());
01393 layout->setOrientation(Horizontal);
01394 item->container()->m_layout = (QLayout*)layout;
01395 }
01396 else if(layoutName == "VFlow") {
01397 item->container()->m_layType = Container::VFlow;
01398 KexiFlowLayout *layout = new KexiFlowLayout(item->widget());
01399 layout->setOrientation(Vertical);
01400 item->container()->m_layout = (QLayout*)layout;
01401 }
01402 else {
01403 item->container()->m_layType = Container::Grid;
01404 QGridLayout *layout = new QGridLayout(item->widget(), 1, 1);
01405 item->container()->m_layout = (QLayout*)layout;
01406 }
01407 readChildNodes(item, container, node, w);
01408 }
01409 else if(tag == "vbox") {
01410 item->container()->m_layType = Container::VBox;
01411 QVBoxLayout *layout = new QVBoxLayout(item->widget());
01412 item->container()->m_layout = (QLayout*)layout;
01413 readChildNodes(item, container, node, w);
01414 }
01415 else if(tag == "hbox") {
01416 item->container()->m_layType = Container::HBox;
01417 QHBoxLayout *layout = new QHBoxLayout(item->widget());
01418 item->container()->m_layout = (QLayout*)layout;
01419 readChildNodes(item, container, node, w);
01420 }
01421 else {
01422 if(w->className() == QString::fromLatin1("CustomWidget"))
01423 item->storeUnknownProperty(node);
01424 else {
01425 bool read = container->form()->library()->readSpecialProperty(
01426 w->className(), node, w, item);
01427 if(!read)
01428 item->storeUnknownProperty(node);
01429 }
01430 }
01431 }
01432 }
01433
01437
01438 void
01439 FormIO::addIncludeFileName(const QString &include, QDomDocument &domDoc)
01440 {
01441 if(include.isEmpty())
01442 return;
01443
01444 QDomElement includes;
01445 QDomElement uiEl = domDoc.namedItem("UI").toElement();
01446 if(uiEl.namedItem("includehints").isNull())
01447 {
01448 includes = domDoc.createElement("includehints");
01449 uiEl.appendChild(includes);
01450 }
01451 else
01452 includes = uiEl.namedItem("includehints").toElement();
01453
01454
01455 for(QDomNode n = includes.firstChild(); !n.isNull(); n = n.nextSibling())
01456 {
01457 if(n.toElement().text() == include)
01458 return;
01459 }
01460
01461 QDomElement includeHint = domDoc.createElement("includehint");
01462 includes.appendChild(includeHint);
01463 QDomText includeText = domDoc.createTextNode(include);
01464 includeHint.appendChild(includeText);
01465 }
01466
01468
01469 QString
01470 FormIO::saveImage(QDomDocument &domDoc, const QPixmap &pixmap)
01471 {
01472 QDomNode node = domDoc.namedItem("images");
01473 QDomElement images;
01474 if(node.isNull())
01475 {
01476 images = domDoc.createElement("images");
01477 QDomElement ui = domDoc.namedItem("UI").toElement();
01478 ui.appendChild(images);
01479 }
01480 else
01481 images = node.toElement();
01482
01483 int count = images.childNodes().count();
01484 QDomElement image = domDoc.createElement("image");
01485 QString name = "image" + QString::number(count);
01486 image.setAttribute("name", name);
01487
01488 QImage img = pixmap.convertToImage();
01489 QByteArray ba;
01490 QBuffer buf(ba);
01491 buf.open( IO_WriteOnly | IO_Translate );
01492 QString format = img.depth() > 1 ? "XPM" : "XBM";
01493 QImageIO iio( &buf, format.latin1() );
01494 iio.setImage( img );
01495 iio.write();
01496 buf.close();
01497 QByteArray bazip = qCompress( ba );
01498 ulong len = bazip.size();
01499
01500 QDomElement data = domDoc.createElement("data");
01501 data.setAttribute("format", format + ".GZ");
01502 data.setAttribute("length", ba.size());
01503
01504 static const char hexchars[] = "0123456789abcdef";
01505 QString content;
01506 for(int i = 4; i < (int)len; ++i)
01507 {
01508 uchar s = (uchar) bazip[i];
01509 content += hexchars[s >> 4];
01510 content += hexchars[s & 0x0f];
01511 }
01512
01513 QDomText text = domDoc.createTextNode(content);
01514 data.appendChild(text);
01515 image.appendChild(data);
01516 images.appendChild(image);
01517
01518 return name;
01519 }
01520
01521 QPixmap
01522 FormIO::loadImage(QDomDocument domDoc, const QString& name)
01523 {
01524 QDomElement images = domDoc.namedItem("UI").namedItem("images").toElement();
01525 if(images.isNull())
01526 return 0;
01527
01528 QDomElement image;
01529 for(QDomNode n = images.firstChild(); !n.isNull(); n = n.nextSibling())
01530 {
01531 if((n.toElement().tagName() == "image") && (n.toElement().attribute("name") == name))
01532 {
01533 image = n.toElement();
01534 break;
01535 }
01536 }
01537
01538 QPixmap pix;
01539 QString data = image.namedItem("data").toElement().text();
01540 const int lengthOffset = 4;
01541 int baSize = data.length() / 2 + lengthOffset;
01542 uchar *ba = new uchar[baSize];
01543 for(int i = lengthOffset; i < baSize; ++i)
01544 {
01545 char h = data[2 * (i-lengthOffset)].latin1();
01546 char l = data[2 * (i-lengthOffset) + 1].latin1();
01547 uchar r = 0;
01548 if(h <= '9')
01549 r += h - '0';
01550 else
01551 r += h - 'a' + 10;
01552 r = r << 4;
01553 if(l <= '9')
01554 r += l - '0';
01555 else
01556 r += l - 'a' + 10;
01557 ba[i] = r;
01558 }
01559
01560 QString format = image.namedItem("data").toElement().attribute("format", "PNG");
01561 if((format == "XPM.GZ") || (format == "XBM.GZ"))
01562 {
01563 ulong len = image.attribute("length").toULong();
01564 if(len < data.length() * 5)
01565 len = data.length() * 5;
01566
01567
01568 ba[0] = ( len & 0xff000000 ) >> 24;
01569 ba[1] = ( len & 0x00ff0000 ) >> 16;
01570 ba[2] = ( len & 0x0000ff00 ) >> 8;
01571 ba[3] = ( len & 0x000000ff );
01572 QByteArray baunzip = qUncompress(ba, baSize);
01573 pix.loadFromData( (const uchar*)baunzip.data(), baunzip.size(), format.left(format.find('.')).latin1() );
01574 }
01575 else
01576 pix.loadFromData( (const uchar*)ba+lengthOffset, baSize-lengthOffset, format.latin1() );
01577
01578 delete[] ba;
01579
01580 return pix;
01581 }
01582
01584
01585 #include "formIO.moc"