23#include <tqmetaobject.h>
26#include <tqtextstream.h>
31#include <tqobjectlist.h>
32#include <tqdatetime.h>
36#include <tdefiledialog.h>
39#include <tdeaccelmanager.h>
43#include "objecttree.h"
44#include "formmanager.h"
45#include "widgetlibrary.h"
47#include "pixmapcollection.h"
50#include "kexiflowlayout.h"
51#include "widgetwithsubpropertiesinterface.h"
56: TQWidget(parent, name), m_className(className)
61CustomWidget::~CustomWidget()
72 p.drawText(
r, TQt::AlignTop, m_className);
77TQDict<TQLabel> *FormIO::m_buddies = 0;
79Form *FormIO::m_currentForm = 0;
80bool FormIO::m_savePixmapsInline =
false;
84KFORMEDITOR_EXPORT uint KFormDesigner::version()
86 return KFORMDESIGNER_VERSION;
102FormIO::saveFormToFile(
Form *form,
const TQString &filename)
105 if(!form->
filename().isNull() && filename.isNull())
108 if(filename.isNull())
110 m_filename = KFileDialog::getSaveFileName(TQString(),
i18n(
"*.ui|TQt Designer UI Files"));
119 if (!saveFormToDom(form,
domDoc))
134FormIO::saveFormToByteArray(
Form *form, TQByteArray &
dest)
137 if (!saveFormToDom(form,
domDoc))
147 if (!saveFormToDom(form,
domDoc))
154FormIO::saveFormToDom(
Form *form, TQDomDocument &
domDoc)
156 m_currentForm = form;
158 domDoc = TQDomDocument(
"UI");
161 uiElement.setAttribute(
"version",
"3.1");
206 form->pixmapCollection()->save(
uiElement);
208 form->connectionBuffer()->save(
uiElement);
210 form->commandHistory()->documentSaved();
220FormIO::loadFormFromByteArray(
Form *form, TQWidget *container, TQByteArray &
src,
bool preview)
236 if (!loadFormFromDom(form, container,
inBuf))
244FormIO::loadFormFromString(
Form *form, TQWidget *container, TQString &
src,
bool preview)
251 form->m_recentlyLoadedUICode =
src;
264 if (!loadFormFromDom(form, container,
inBuf))
272FormIO::loadFormFromFile(
Form *form, TQWidget *container,
const TQString &filename)
279 if(filename.isNull())
281 m_filename = KFileDialog::getOpenFileName(TQString(),
i18n(
"*.ui|TQt Designer UI Files"));
291 kdDebug() <<
"Cannot open the file " << filename <<
endl;
295 TQString text =
stream.read();
307 return loadFormFromDom(form, container,
inBuf);
311FormIO::loadFormFromDom(
Form *form, TQWidget *container, TQDomDocument &
inBuf)
313 m_currentForm = form;
321 while (!
attr.isNull() &&
attr.isAttr()) {
333 kdDebug() <<
"FormIO::loadFormFromDom(): original format version: " <<
ver <<
endl;
334 form->setOriginalFormatVersion(
ver );
335 if (
ver < KFormDesigner::version()) {
338 kdDebug() <<
"FormIO::loadFormFromDom(): original format is older than current: " << KFormDesigner::version() <<
endl;
339 form->setFormatVersion( KFormDesigner::version() );
342 form->setFormatVersion(
ver );
344 if (
ver > KFormDesigner::version()) {
346 kdDebug() <<
"FormIO::loadFormFromDom(): original format is newer than current: " << KFormDesigner::version() <<
endl;
350 m_savePixmapsInline = ( (
ui.namedItem(
"pixmapinproject").isNull()) || (!
ui.namedItem(
"images").isNull()) );
351 form->pixmapCollection()->load(
ui.namedItem(
"collection"));
354 createToplevelWidget(form, container,
element);
360 if(!tabStops.isNull()) {
363 for(
TQDomNode n = tabStops.firstChild(); !
n.isNull();
n =
n.nextSibling(),
i++)
365 TQString name =
n.toElement().text();
369 kdDebug() <<
"FormIO::loadFormFromDom ERROR : no ObjectTreeItem " <<
endl;
372 const int index = form->
tabStops()->findRef(item);
375 if((index != -1) && (index !=
realIndex))
382 kdDebug() <<
"FormIO: item '" << name <<
"' not in list" <<
endl;
388 form->connectionBuffer()->load(
ui.namedItem(
"connections"));
407 TQWidget *subwidget =
w;
409 int propertyId =
w->metaObject()->findProperty(name,
true);
417 kdDebug() <<
"FormIO::savePropertyValue() The object doesn't have this property. Let's try the WidgetLibrary." <<
endl;
419 lib->saveSpecialProperty(
w->className(), name, value,
w,
parentNode, parent);
424 if (!
meta->stored( subwidget ))
429 propertyE.setAttribute(
"subwidget",
"true");
437 if(
meta->isSetType())
439 TQStringList list = TQStringList::fromStrList(
meta->valueToKeys(value.toInt()));
440 type = parent.createElement(
"set");
441 valueE = parent.createTextNode(list.join(
"|"));
446 TQString
s =
meta->valueToKey(value.toInt());
447 type = parent.createElement(
"enum");
448 valueE = parent.createTextNode(
s);
456 if(value.type() == TQVariant::Pixmap) {
459 TQCString
property =
propertyE.attribute(
"name").latin1();
461 if(m_savePixmapsInline )
462 valueE = parent.createTextNode(saveImage(parent, value.toPixmap()));
464 valueE = parent.createTextNode(m_currentItem->pixmapName(property));
484 case TQVariant::String:
486 type = parent.createElement(
"string");
487 valueE = parent.createTextNode(value.toString());
491 case TQVariant::CString:
493 type = parent.createElement(
"cstring");
494 valueE = parent.createTextNode(value.toString());
498 case TQVariant::Rect:
500 type = parent.createElement(
"rect");
505 TQDomText valueX = parent.createTextNode(TQString::number(value.toRect().x()));
506 TQDomText valueY = parent.createTextNode(TQString::number(value.toRect().y()));
507 TQDomText valueW = parent.createTextNode(TQString::number(value.toRect().width()));
508 TQDomText valueH = parent.createTextNode(TQString::number(value.toRect().height()));
521 case TQVariant::Color:
523 type = parent.createElement(
"color");
527 TQDomText valueR = parent.createTextNode(TQString::number(value.toColor().red()));
528 TQDomText valueG = parent.createTextNode(TQString::number(value.toColor().green()));
529 TQDomText valueB = parent.createTextNode(TQString::number(value.toColor().blue()));
540 case TQVariant::Bool:
542 type = parent.createElement(
"bool");
544 valueE = parent.createTextNode(value.toBool() ?
"true" :
"false");
549 case TQVariant::UInt:
551 type = parent.createElement(
"number");
552 valueE = parent.createTextNode(TQString::number(value.toInt()));
556 case TQVariant::Size:
558 type = parent.createElement(
"size");
561 TQDomText valueW = parent.createTextNode(TQString::number(value.toSize().width()));
562 TQDomText valueH = parent.createTextNode(TQString::number(value.toSize().height()));
571 case TQVariant::Point:
573 type = parent.createElement(
"point");
576 TQDomText valueX = parent.createTextNode(TQString::number(value.toPoint().x()));
577 TQDomText valueY = parent.createTextNode(TQString::number(value.toPoint().y()));
586 case TQVariant::Font:
588 type = parent.createElement(
"font");
597 TQDomText valueP = parent.createTextNode(TQString::number(value.toFont().pointSize()));
598 TQDomText valueW = parent.createTextNode(TQString::number(value.toFont().weight()));
599 TQDomText valueB = parent.createTextNode(TQString::number(value.toFont().bold()));
600 TQDomText valueI = parent.createTextNode(TQString::number(value.toFont().italic()));
601 TQDomText valueU = parent.createTextNode(TQString::number(value.toFont().underline()));
602 TQDomText valueS = parent.createTextNode(TQString::number(value.toFont().strikeOut()));
621 case TQVariant::Cursor:
623 type = parent.createElement(
"cursor");
624 valueE = parent.createTextNode(TQString::number(value.toCursor().shape()));
628 case TQVariant::SizePolicy:
630 type = parent.createElement(
"sizepolicy");
635 TQDomText valueH = parent.createTextNode(TQString::number(value.toSizePolicy().horData()));
636 TQDomText valueV = parent.createTextNode(TQString::number(value.toSizePolicy().verData()));
637 TQDomText valueHS = parent.createTextNode(TQString::number(value.toSizePolicy().horStretch()));
638 TQDomText valueVS = parent.createTextNode(TQString::number(value.toSizePolicy().verStretch()));
647 type.appendChild(
hs);
648 type.appendChild(
vs);
651 case TQVariant::Time:
653 type = parent.createElement(
"time");
657 TQDomText valueH = parent.createTextNode(TQString::number(value.toTime().hour()));
658 TQDomText valueM = parent.createTextNode(TQString::number(value.toTime().minute()));
659 TQDomText valueS = parent.createTextNode(TQString::number(value.toTime().second()));
670 case TQVariant::Date:
672 type = parent.createElement(
"date");
676 TQDomText valueY = parent.createTextNode(TQString::number(value.toDate().year()));
677 TQDomText valueM = parent.createTextNode(TQString::number(value.toDate().month()));
678 TQDomText valueD = parent.createTextNode(TQString::number(value.toDate().day()));
689 case TQVariant::DateTime:
691 type = parent.createElement(
"datetime");
698 TQDomText valueH = parent.createTextNode(TQString::number(value.toDateTime().time().hour()));
699 TQDomText valueM = parent.createTextNode(TQString::number(value.toDateTime().time().minute()));
700 TQDomText valueS = parent.createTextNode(TQString::number(value.toDateTime().time().second()));
701 TQDomText valueY = parent.createTextNode(TQString::number(value.toDateTime().date().year()));
702 TQDomText valueMo = parent.createTextNode(TQString::number(value.toDateTime().date().month()));
703 TQDomText valueD = parent.createTextNode(TQString::number(value.toDateTime().date().day()));
716 type.appendChild(
mo);
731 propertyE.setAttribute(
"name", property);
737FormIO::readPropertyValue(
TQDomNode node, TQObject *
obj,
const TQString &name)
740 TQString text =
tag.text();
741 TQString type =
tag.tagName();
743 if(type ==
"string" || type ==
"cstring")
745 else if(type ==
"rect")
752 int rx =
x.text().toInt();
753 int ry =
y.text().toInt();
754 int rw =
w.text().toInt();
755 int rh =
h.text().toInt();
759 else if(type ==
"color")
765 int red =
r.text().toInt();
766 int green =
g.text().toInt();
767 int blue =
b.text().toInt();
771 else if(type ==
"bool")
774 return TQVariant(
true);
775 else if(text ==
"false")
776 return TQVariant(
false);
777 return TQVariant(text.toInt());
779 else if(type ==
"number")
783 else if(type ==
"size")
788 return TQSize(
w.text().toInt(),
h.text().toInt());
790 else if(type ==
"point")
795 return TQPoint(
x.text().toInt(),
y.text().toInt());
797 else if(type ==
"font")
808 f.setFamily(
fa.text());
809 f.setPointSize(
p.text().toInt());
810 f.setWeight(
w.text().toInt());
811 f.setBold(
b.text().toInt());
812 f.setItalic(
i.text().toInt());
813 f.setUnderline(
u.text().toInt());
814 f.setStrikeOut(
s.text().toInt());
818 else if(type ==
"cursor")
822 else if(type ==
"time")
828 return TQTime(
h.text().toInt(),
m.text().toInt(),
s.text().toInt());
830 else if(type ==
"date")
836 return TQDate(
y.text().toInt(),
m.text().toInt(), d.text().toInt());
838 else if(type ==
"datetime")
847 TQTime
t(
h.text().toInt(),
m.text().toInt(),
s.text().toInt());
848 TQDate da(
y.text().toInt(),
mo.text().toInt(), d.text().toInt());
850 return TQDateTime(
da,
t);
852 else if(type ==
"sizepolicy")
860 s.setHorData((TQSizePolicy::SizeType)
h.text().toInt());
861 s.setVerData((TQSizePolicy::SizeType)
v.text().toInt());
862 s.setHorStretch(
hs.text().toInt());
863 s.setVerStretch(
vs.text().toInt());
866 else if(type ==
"pixmap")
868 if(m_savePixmapsInline || !m_currentForm || !m_currentItem || !m_currentForm->pixmapCollection()->contains(text))
869 return loadImage(
tag.ownerDocument(), text);
872 m_currentItem->setPixmapName(name.latin1(), text);
873 return m_currentForm->pixmapCollection()->getPixmap(text);
875 return TQVariant(TQPixmap());
877 else if(type ==
"enum")
879 else if(type ==
"set")
883 const int count =
subobject->metaObject()->findProperty(name.latin1(),
true);
887 if (
meta->isSetType()) {
889 const TQStringList list( TQStringList::split(
"|", text) );
890 for (TQStringList::ConstIterator
it = list.constBegin();
it != list.constEnd(); ++
it)
891 keys.append((*it).latin1());
901 return TQStringList::split(
"|", text);
918 if(item->className() ==
"Spring")
925 m_currentItem = item;
941 parent.appendChild(
tclass);
945 tclass.setAttribute(
"row", item->gridRow());
946 tclass.setAttribute(
"column", item->gridCol());
947 if(item->spanMultipleCells())
949 tclass.setAttribute(
"rowspan", item->gridRowSpan());
950 tclass.setAttribute(
"colspan", item->gridColSpan());
955 tclass.setAttribute(
"class",
"TQWidget");
957 else if(item->widget()->isA(
"HBox") || item->widget()->isA(
"VBox") || item->widget()->isA(
"Grid")
958 || item->widget()->isA(
"HFlow") || item->widget()->isA(
"VFlow"))
959 tclass.setAttribute(
"class",
"TQLayoutWidget");
960 else if(item->widget()->isA(
"CustomWidget"))
961 tclass.setAttribute(
"class", item->className());
963 tclass.setAttribute(
"class",
lib->savingName(item->widget()->className()) );
965 savePropertyValue(
tclass,
domDoc,
"name", item->widget()->property(
"name"), item->widget());
975 if(item && !item->parent()) {
978 TQRect( TQPoint(0,0), item->widget()->size()),
982 else if(parent.tagName() ==
"widget" || parent.tagName() ==
"UI")
983 savePropertyValue(
tclass,
domDoc,
"geometry", item->widget()->property(
"geometry"), item->widget());
986 if(item->widget()->inherits(
"TQLabel") && ((TQLabel*)item->widget())->buddy())
987 savePropertyElement(
tclass,
domDoc,
"property",
"buddy", ((TQLabel*)item->widget())->buddy()->name());
991 TQStringVariantMap::ConstIterator
endIt =
map->constEnd();
992 for(TQStringVariantMap::ConstIterator
it =
map->constBegin();
it !=
endIt; ++
it)
994 const TQCString name(
it.key().latin1() );
995 if(name ==
"hAlign" || name ==
"vAlign" || name ==
"wordbreak" || name ==
"alignment") {
998 savePropertyValue(
tclass,
domDoc,
"alignment", item->widget()->property(
"alignment"), item->widget());
1002 else if(name ==
"name" || name ==
"geometry" || name ==
"layout") {
1006 savePropertyValue(
tclass,
domDoc,
it.key().latin1(), item->widget()->property(
it.key().latin1()),
1007 item->widget(),
lib);
1012 if(item->widget()->isA(
"CustomWidget")) {
1013 TQDomDocument doc(
"TEMP");
1014 doc.setContent(item->m_unknownProps);
1015 for(
TQDomNode n = doc.firstChild(); !
n.isNull();
n =
n.nextSibling()) {
1016 tclass.appendChild(
n.cloneNode());
1026 layout =
domDoc.createElement(
"temp");
1027 savePropertyValue(layout,
domDoc,
"name",
"unnamed", item->widget());
1032 tclass.appendChild(layout);
1037 switch(layoutType) {
1038 case Container::Grid:
1040 layout.setTagName(
"grid");
1045 case Container::HBox:
case Container::VBox:
1049 if(layout.tagName() ==
"hbox") {
1051 layout.setTagName(
"hbox");
1055 layout.setTagName(
"vbox");
1059 list->append(
objTree->widget());
1062 for(TQWidget *
obj = list->first();
obj;
obj = list->next()) {
1070 case Container::HFlow:
case Container::VFlow:
1072 layout.setTagName(
"grid");
1083 for(TQWidget *
obj = list->first();
obj;
obj = list->next()) {
1098 addIncludeFileName(
lib->includeFileName(item->widget()->className()),
domDoc);
1109 if(!
uiElement.namedItem(
"includes").isNull())
1112 if(!
uiElement.namedItem(
"connections").isNull())
1114 if(!
uiElement.namedItem(
"images").isNull())
1125 m_currentForm = container->
form();
1132 if((
n.toElement().tagName() ==
"property") && (
n.toElement().attribute(
"name") ==
"name"))
1134 wname =
n.toElement().text();
1142 if(
el.tagName() ==
"spacer")
1144 else if(
el.attribute(
"class") ==
"TQLayoutWidget")
1148 TQString
tagName =
n.toElement().tagName();
1158 if((
child.toElement().tagName() ==
"property")
1159 && (
child.toElement().attribute(
"name") ==
"customLayout"))
1200#if TDE_VERSION >= TDE_MAKE_VERSION(3,4,0)
1202 if (m_currentForm->designMode()) {
1204 TDEAcceleratorManager::setNoAccel(
w);
1207 w->setStyle(&(container->
widget()->style()));
1221 kdDebug() <<
"FORMIO :: ERROR no parent widget " <<
endl;
1232 m_currentItem = item;
1234 if(container->
layoutType() == Container::Grid) {
1236 if(
el.hasAttribute(
"rowspan")) {
1238 layout->addMultiCellWidget(
w,
el.attribute(
"row").toInt(),
el.attribute(
"row").toInt() +
el.attribute(
"rowspan").toInt()-1,
1239 el.attribute(
"column").toInt(),
el.attribute(
"column").toInt() +
el.attribute(
"colspan").toInt()-1);
1240 item->setGridPos(
el.attribute(
"row").toInt(),
el.attribute(
"column").toInt(),
el.attribute(
"rowspan").toInt(),
1241 el.attribute(
"colspan").toInt());
1245 layout->addWidget(
w,
el.attribute(
"row").toInt(),
el.attribute(
"column").toInt());
1246 item->setGridPos(
el.attribute(
"row").toInt(),
el.attribute(
"column").toInt(), 0, 0);
1249 else if(container->
layout())
1252 readChildNodes(item, container,
el,
w);
1258 TQValueList<TQCString> list(container->
form()->
library()->autoSaveProperties(
w->className()));
1259 TQValueList<TQCString>::ConstIterator
endIt = list.constEnd();
1263 for(TQValueList<TQCString>::ConstIterator
it = list.constBegin();
it !=
endIt; ++
it) {
1264 if(subwidget->metaObject()->findProperty(*
it,
true) != -1)
1280 if((
n.toElement().tagName() ==
"property") && (
n.toElement().attribute(
"name") ==
"name"))
1282 wname =
n.toElement().text();
1288 container->setName(
wname.latin1());
1296 m_buddies =
new TQDict<TQLabel>();
1303 for(;
it.current(); ++
it)
1306 if(!item || !item->widget())
1308 kdDebug() <<
"Cannot assign buddy for widget " <<
it.current()->name() <<
" to " <<
it.currentKey() <<
endl;
1311 it.current()->setBuddy(item->widget());
1324 TQString
eltag =
el.tagName();
1331 TQString
tag =
n.toElement().tagName();
1334 if((
tag ==
"property") || (
tag ==
"attribute"))
1336 TQString name =
node.attribute(
"name");
1343 if (
node.attribute(
"subwidget")==
"true") {
1346 const TQVariant
val( readPropertyValue(
node.firstChild(),
w, name) );
1356 m_buddies->insert(readPropertyValue(
node.firstChild(),
w, name).toString(), (TQLabel*)
w);
1357 else if(((
eltag ==
"grid") || (
eltag ==
"hbox") || (
eltag ==
"vbox")) &&
1360 if(name ==
"margin") {
1361 int margin = readPropertyValue(
node.firstChild(),
w, name).toInt();
1366 else if(name ==
"spacing") {
1367 int spacing = readPropertyValue(
node.firstChild(),
w, name).toInt();
1371 else if((name ==
"justify")){
1372 bool justify = readPropertyValue(
node.firstChild(),
w, name).toBool();
1379 else if(subwidget->metaObject()->findProperty(name.latin1(),
true) == -1)
1381 if(
w->className() == TQString::fromLatin1(
"CustomWidget"))
1382 item->storeUnknownProperty(
node);
1385 w->className(),
node,
w, item);
1387 item->storeUnknownProperty(
node);
1392 TQVariant
val( readPropertyValue(
node.firstChild(),
w, name) );
1393 if(name ==
"geometry" &&
dynamic_cast<FormWidget*
>(
w)) {
1395 TQRect
r(
val.toRect() );
1402 subwidget->setProperty(name.latin1(),
val);
1411 else if(
tag ==
"widget")
1416 loadWidget(container,
node,
w);
1418 else if(
tag ==
"spacer") {
1419 loadWidget(container,
node,
w);
1421 else if(
tag ==
"grid") {
1425 if((
child.toElement().tagName() ==
"property") && (
child.toElement().attribute(
"name") ==
"customLayout")) {
1432 item->
container()->m_layType = Container::HFlow;
1435 item->
container()->m_layout = (TQLayout*)layout;
1438 item->
container()->m_layType = Container::VFlow;
1441 item->
container()->m_layout = (TQLayout*)layout;
1444 item->
container()->m_layType = Container::Grid;
1446 item->
container()->m_layout = (TQLayout*)layout;
1448 readChildNodes(item, container,
node,
w);
1450 else if(
tag ==
"vbox") {
1451 item->
container()->m_layType = Container::VBox;
1453 item->
container()->m_layout = (TQLayout*)layout;
1454 readChildNodes(item, container,
node,
w);
1456 else if(
tag ==
"hbox") {
1457 item->
container()->m_layType = Container::HBox;
1459 item->
container()->m_layout = (TQLayout*)layout;
1460 readChildNodes(item, container,
node,
w);
1463 if(
w->className() == TQString::fromLatin1(
"CustomWidget"))
1464 item->storeUnknownProperty(
node);
1467 w->className(),
node,
w, item);
1469 item->storeUnknownProperty(
node);
1480FormIO::addIncludeFileName(
const TQString &
include, TQDomDocument &
domDoc)
1487 if(
uiEl.namedItem(
"includes").isNull())
1498 if(
n.toElement().text() ==
include)
1513FormIO::saveImage(TQDomDocument &
domDoc,
const TQPixmap &pixmap)
1526 int count =
images.childNodes().count();
1528 TQString name =
"image" + TQString::number(count);
1529 image.setAttribute(
"name", name);
1535 TQString
format =
img.depth() > 1 ?
"XPM" :
"XBM";
1544 data.setAttribute(
"format",
format +
".GZ");
1545 data.setAttribute(
"length",
ba.size());
1547 static const char hexchars[] =
"0123456789abcdef";
1549 for(
int i = 4;
i < (int)
len; ++
i)
1557 data.appendChild(text);
1558 image.appendChild(data);
1565FormIO::loadImage(TQDomDocument
domDoc,
const TQString& name)
1574 if((
n.toElement().tagName() ==
"image") && (
n.toElement().attribute(
"name") == name))
1582 TQString data =
image.namedItem(
"data").toElement().text();
1603 TQString
format =
image.namedItem(
"data").toElement().attribute(
"format",
"PNG");
1606 ulong
len =
image.attribute(
"length").toULong();
1607 if(
len < data.length() * 5)
1608 len = data.length() * 5;
1611 ba[0] = (
len & 0xff000000 ) >> 24;
1612 ba[1] = (
len & 0x00ff0000 ) >> 16;
1613 ba[2] = (
len & 0x0000ff00 ) >> 8;
1614 ba[3] = (
len & 0x000000ff );
1628#include "formIO.moc"
void setOrientation(TQt::Orientation orientation)
TQPtrList< TQWidget > * widgetList() const