00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <qwidget.h>
00023 #include <qlabel.h>
00024 #include <qobjectlist.h>
00025 #include <qptrdict.h>
00026
00027 #include <kdebug.h>
00028 #include <klocale.h>
00029 #include <kcommand.h>
00030 #include <kaction.h>
00031 #include <kmessagebox.h>
00032
00033 #include "container.h"
00034 #include "objecttree.h"
00035 #include "widgetpropertyset.h"
00036 #include "formIO.h"
00037 #include "formmanager.h"
00038 #include "widgetlibrary.h"
00039 #include "spring.h"
00040 #include "pixmapcollection.h"
00041 #include "events.h"
00042 #include "utils.h"
00043 #include "form.h"
00044 #include <koproperty/property.h>
00045 #include <kexiutils/utils.h>
00046
00047 using namespace KFormDesigner;
00048
00049 FormPrivate::FormPrivate()
00050 {
00051 toplevel = 0;
00052 topTree = 0;
00053 widget = 0;
00054 resizeHandles.setAutoDelete(true);
00055 dirty = false;
00056 interactive = true;
00057 design = true;
00058 autoTabstops = false;
00059 tabstops.setAutoDelete(false);
00060 connBuffer = new ConnectionBuffer();
00061 formatVersion = KFormDesigner::version();
00062 originalFormatVersion = KFormDesigner::version();
00063 }
00064
00065 FormPrivate::~FormPrivate()
00066 {
00067 delete history;
00068 delete topTree;
00069 delete connBuffer;
00070 connBuffer = 0;
00071 resizeHandles.setAutoDelete(false);
00072
00073 }
00074
00075
00076
00077 FormWidget::FormWidget()
00078 : m_form(0)
00079 {
00080 }
00081
00082 FormWidget::~FormWidget()
00083 {
00084 if (m_form) {
00085 m_form->setFormWidget(0);
00086 }
00087 }
00088
00089
00090
00091 Form::Form(WidgetLibrary* library, const char *name, bool designMode)
00092 : QObject(library, name)
00093 , m_lib(library)
00094 {
00095 d = new FormPrivate();
00096
00097 d->design = designMode;
00098
00099
00100 d->collection = new KActionCollection(0, this);
00101 d->history = new KCommandHistory(d->collection, true);
00102 connect(d->history, SIGNAL(commandExecuted()), this, SLOT(slotCommandExecuted()));
00103 connect(d->history, SIGNAL(documentRestored()), this, SLOT(slotFormRestored()));
00104 }
00105
00106 Form::~Form()
00107 {
00108 emit destroying();
00109 delete d;
00110 d = 0;
00111 }
00112
00113 QWidget*
00114 Form::widget() const
00115 {
00116 if(d->topTree)
00117 return d->topTree->widget();
00118 else if(d->toplevel)
00119 return d->toplevel->widget();
00120 else
00121 return d->widget;
00122 }
00123
00125
00126 void
00127 Form::createToplevel(QWidget *container, FormWidget *formWidget, const QCString &)
00128 {
00129 kdDebug() << "Form::createToplevel() container= "<< (container ? container->name() : "<NULL>")
00130 << " formWidget=" << formWidget << "className=" << name() << endl;
00131
00132 setFormWidget( formWidget );
00133 d->toplevel = new Container(0, container, this, name());
00134 d->topTree = new ObjectTree(i18n("Form"), container->name(), container, d->toplevel);
00135 d->toplevel->setObjectTree(d->topTree);
00136 d->toplevel->setForm(this);
00137 d->pixcollection = new PixmapCollection(container->name(), this);
00138
00139 d->topTree->setWidget(container);
00141
00142
00143
00144 connect(container, SIGNAL(destroyed()), this, SLOT(formDeleted()));
00145
00146 kdDebug() << "Form::createToplevel(): d->toplevel=" << d->toplevel << endl;
00147 }
00148
00149
00150 Container*
00151 Form::activeContainer()
00152 {
00153 ObjectTreeItem *it;
00154 if(d->selected.count() == 0)
00155 return d->toplevel;
00156
00157 if(d->selected.count() == 1)
00158 it = d->topTree->lookup(d->selected.last()->name());
00159 else
00160 it = commonParentContainer( &(d->selected) );
00161
00162 if (!it)
00163 return 0;
00164 if(it->container())
00165 return it->container();
00166 else
00167 return it->parent()->container();
00168 }
00169
00170 ObjectTreeItem*
00171 Form::commonParentContainer(WidgetList *wlist)
00172 {
00173 ObjectTreeItem *item = 0;
00174 WidgetList *list = new WidgetList();
00175
00176
00177 for(QWidget *w = wlist->first(); w; w = wlist->next())
00178 {
00179 if(list->findRef(w->parentWidget()) == -1)
00180 list->append(w->parentWidget());
00181 }
00182
00183 removeChildrenFromList(*list);
00184
00185
00186 if(list->count() == 1)
00187 item = d->topTree->lookup(list->first()->name());
00188 else
00189 item = commonParentContainer(list);
00190
00191 delete list;
00192 return item;
00193 }
00194
00195 Container*
00196 Form::parentContainer(QWidget *w)
00197 {
00198 ObjectTreeItem *it;
00199 if(!w)
00200 return 0;
00201
00202
00203 it = d->topTree->lookup(w->name());
00204
00205 if(it->parent()->container())
00206 return it->parent()->container();
00207 else
00208 return it->parent()->parent()->container();
00209 }
00210
00211
00212
00213 void
00214 Form::setDesignMode(bool design)
00215 {
00216 d->design = design;
00217 if(!design)
00218 {
00219 ObjectTreeDict *dict = new ObjectTreeDict( *(d->topTree->dict()) );
00220 ObjectTreeDictIterator it(*dict);
00221 for(; it.current(); ++it)
00222 m_lib->previewWidget(it.current()->widget()->className(), it.current()->widget(), d->toplevel);
00223 delete dict;
00224
00225 d->widget = d->topTree->widget();
00226 delete (d->topTree);
00227 d->topTree = 0;
00228 delete (d->toplevel);
00229 d->toplevel = 0;
00230 }
00231 }
00232
00233
00235
00236 void
00237 Form::setSelectedWidget(QWidget *w, bool add, bool dontRaise, bool moreWillBeSelected)
00238 {
00239 if((d->selected.isEmpty()) || (w == widget()) || (d->selected.first() == widget()))
00240 add = false;
00241
00242 if(!w)
00243 {
00244 setSelectedWidget(widget());
00245 return;
00246 }
00247
00248
00249 QWidget *wtmp = w;
00250 while(!dontRaise && wtmp && wtmp->parentWidget() && (wtmp != widget()))
00251 {
00252 wtmp->raise();
00253 if(d->resizeHandles[ wtmp->name() ])
00254 d->resizeHandles[ wtmp->name() ]->raise();
00255 wtmp = wtmp->parentWidget();
00256 }
00257
00258 if (wtmp)
00259 wtmp->setFocus();
00260
00261 if(!add)
00262 {
00263 d->selected.clear();
00264 d->resizeHandles.clear();
00265 }
00266 d->selected.append(w);
00267 emit selectionChanged(w, add, moreWillBeSelected);
00268 emitActionSignals(false);
00269
00270
00271 if(!FormManager::self()->isTopLevel(w) && w->parentWidget() && w->parentWidget()->isA("QWidgetStack"))
00272 {
00273 w = w->parentWidget();
00274 if(w->parentWidget() && w->parentWidget()->inherits("QTabWidget"))
00275 w = w->parentWidget();
00276 }
00277
00278 if(w && w != widget())
00279 d->resizeHandles.insert(w->name(), new ResizeHandleSet(w, this));
00280 }
00281
00282 ResizeHandleSet*
00283 Form::resizeHandlesForWidget(QWidget* w)
00284 {
00285 return d->resizeHandles[w->name()];
00286 }
00287
00288 void
00289 Form::unSelectWidget(QWidget *w)
00290 {
00291 d->selected.remove(w);
00292 d->resizeHandles.remove(w->name());
00293 }
00294
00295 void
00296 Form::selectFormWidget()
00297 {
00298 setSelectedWidget(widget(), false);
00299 }
00300
00301 void
00302 Form::clearSelection()
00303 {
00304 d->selected.clear();
00305 d->resizeHandles.clear();
00306 emit selectionChanged(0, false);
00307 emitActionSignals(false);
00308 }
00309
00310 void
00311 Form::emitActionSignals(bool withUndoAction)
00312 {
00313
00314 if(d->selected.count() > 1)
00315 FormManager::self()->emitWidgetSelected(this, true);
00316 else if(d->selected.first() != widget())
00317 FormManager::self()->emitWidgetSelected(this, false);
00318 else
00319 FormManager::self()->emitFormWidgetSelected(this);
00320
00321 if(!withUndoAction)
00322 return;
00323
00324 KAction *undoAction = d->collection->action("edit_undo");
00325 if(undoAction)
00326 FormManager::self()->emitUndoEnabled(undoAction->isEnabled(), undoAction->text());
00327
00328 KAction *redoAction = d->collection->action("edit_redo");
00329 if(redoAction)
00330 FormManager::self()->emitRedoEnabled(redoAction->isEnabled(), redoAction->text());
00331 }
00332
00333 void
00334 Form::emitSelectionSignals()
00335 {
00336 emit selectionChanged(selectedWidgets()->first(), false);
00337
00338
00339 for (WidgetListIterator it(*selectedWidgets()); it.current(); ++it)
00340 emit selectionChanged(it.current(), true);
00341 }
00342
00344 void
00345 Form::formDeleted()
00346 {
00347
00348 d->selected.clear();
00349 d->resizeHandles.setAutoDelete(false);
00350 d->resizeHandles.clear();
00351 d->resizeHandles.setAutoDelete(true);
00352
00353
00354
00355 FormManager::self()->deleteForm(this);
00356
00357 deleteLater();
00358 }
00359
00360 void
00361 Form::changeName(const QCString &oldname, const QCString &newname)
00362 {
00363 if(oldname == newname)
00364 return;
00365 if(!d->topTree->rename(oldname, newname))
00366 {
00367 KMessageBox::sorry(widget()->topLevelWidget(),
00368 i18n("Renaming widget \"%1\" to \"%2\" failed.").arg(oldname).arg(newname));
00369
00370
00371
00372
00373 kdDebug() << "Form::changeName() : ERROR : A widget named " << newname << " already exists" << endl;
00374 FormManager::self()->propertySet()->property("name") = QVariant(oldname);
00375 }
00376 else
00377 {
00378 d->connBuffer->fixName(oldname, newname);
00379 ResizeHandleSet *temp = d->resizeHandles.take(oldname);
00380 d->resizeHandles.insert(newname, temp);
00381 }
00382 }
00383
00384 void
00385 Form::emitChildAdded(ObjectTreeItem *item)
00386 {
00387 addWidgetToTabStops(item);
00388 emit childAdded(item);
00389 }
00390
00391 void
00392 Form::emitChildRemoved(ObjectTreeItem *item)
00393 {
00394 d->tabstops.remove(item);
00395 if(d->connBuffer)
00396 d->connBuffer->removeAllConnectionsForWidget(item->name());
00397 emit childRemoved(item);
00398 }
00399
00400 void
00401 Form::addCommand(KCommand *command, bool execute)
00402 {
00403 emit FormManager::self()->dirty(this, true);
00404 d->dirty = true;
00405 d->history->addCommand(command, execute);
00406 if(!execute)
00407 slotCommandExecuted();
00408 }
00409
00410 void
00411 Form::clearCommandHistory()
00412 {
00413 d->history->clear();
00414 FormManager::self()->emitUndoEnabled(false, QString::null);
00415 FormManager::self()->emitRedoEnabled(false, QString::null);
00416 }
00417
00418 void
00419 Form::slotCommandExecuted()
00420 {
00421 emit FormManager::self()->dirty(this, true);
00422 d->dirty = true;
00423
00424 QTimer::singleShot(10, this, SLOT(emitUndoEnabled()));
00425 QTimer::singleShot(10, this, SLOT(emitRedoEnabled()));
00426 }
00427
00428 void
00429 Form::emitUndoEnabled()
00430 {
00431 KAction *undoAction = d->collection->action("edit_undo");
00432 if(undoAction)
00433 FormManager::self()->emitUndoEnabled(undoAction->isEnabled(), undoAction->text());
00434 }
00435
00436 void
00437 Form::emitRedoEnabled()
00438 {
00439 KAction *redoAction = d->collection->action("edit_redo");
00440 if(redoAction)
00441 FormManager::self()->emitRedoEnabled(redoAction->isEnabled(), redoAction->text());
00442 }
00443
00444 void
00445 Form::slotFormRestored()
00446 {
00447 emit FormManager::self()->dirty(this, false);
00448 d->dirty = false;
00449 }
00450
00451
00453
00454 void
00455 Form::addWidgetToTabStops(ObjectTreeItem *it)
00456 {
00457 QWidget *w = it->widget();
00458 if(!w)
00459 return;
00460 if(!(w->focusPolicy() & QWidget::TabFocus))
00461 {
00462 if (!w->children())
00463 return;
00464
00465 for(QObjectListIterator chIt(*w->children()); chIt.current(); ++chIt) {
00466 if(chIt.current()->isWidgetType()) {
00467 if(d->tabstops.findRef(it) == -1) {
00468 d->tabstops.append(it);
00469 return;
00470 }
00471 }
00472 }
00473 }
00474 else if(d->tabstops.findRef(it) == -1)
00475 d->tabstops.append(it);
00476 }
00477
00478 void
00479 Form::updateTabStopsOrder()
00480 {
00481 for (ObjectTreeListIterator it(d->tabstops);it.current();) {
00482 if(!(it.current()->widget()->focusPolicy() & QWidget::TabFocus)) {
00483 kexidbg << "Form::updateTabStopsOrder(): widget removed because has no TabFocus: " << it.current()->widget()->name() << endl;
00484 d->tabstops.remove( it.current() );
00485 }
00486 else
00487 ++it;
00488 }
00489 }
00490
00492 void collectContainers(ObjectTreeItem* item, QPtrDict<char>& containers)
00493 {
00494 if (!item->container())
00495 return;
00496 if (!containers[ item->container() ]) {
00497 kdDebug() << "collectContainers() " << item->container()->objectTree()->className()
00498 << " " << item->container()->objectTree()->name() << endl;
00499 containers.insert( item->container(), (const char *)1 );
00500 }
00501 for (ObjectTreeListIterator it(*item->children()); it.current(); ++it)
00502 collectContainers(it.current(), containers);
00503 }
00504
00505 void
00506 Form::autoAssignTabStops()
00507 {
00508 VerWidgetList list(toplevelContainer()->widget());
00509 HorWidgetList hlist(toplevelContainer()->widget());
00510
00511
00512 QPtrDict<char> containers;
00513
00514 collectContainers( toplevelContainer()->objectTree(), containers );
00515
00516 foreach_list(ObjectTreeListIterator, it, d->tabstops) {
00517 if(it.current()->widget()) {
00518 kdDebug() << "Form::autoAssignTabStops() widget to sort: " << it.current()->widget() << endl;
00519 list.append(it.current()->widget());
00520 }
00521 }
00522
00523 list.sort();
00524 foreach_list(QPtrListIterator<QWidget>, iter, list)
00525 kdDebug() << iter.current()->className() << " " << iter.current()->name() << endl;
00526
00527 d->tabstops.clear();
00528
00531 foreach_list(WidgetListIterator, it, list) {
00532 QWidget *w = it.current();
00533 hlist.append(w);
00534
00535 ++it;
00536 QWidget *nextw = it.current();
00537 QObject *page_w = 0;
00538 KFormDesigner::TabWidget *tab_w = KFormDesigner::findParent<KFormDesigner::TabWidget>(w, "KFormDesigner::TabWidget", page_w);
00539 while (nextw) {
00540 if (KexiUtils::hasParent(w, nextw))
00541 break;
00542 if (nextw->y() >= (w->y() + 20))
00543 break;
00544 if (tab_w) {
00545 QObject *page_nextw = 0;
00546 KFormDesigner::TabWidget *tab_nextw = KFormDesigner::findParent<KFormDesigner::TabWidget>(nextw, "KFormDesigner::TabWidget", page_nextw);
00547 if (tab_w == tab_nextw) {
00548 if (page_w != page_nextw)
00549 break;
00550 }
00551 }
00552 hlist.append(nextw);
00553 ++it;
00554 nextw = it.current();
00555 }
00556 hlist.sort();
00557
00558 for(WidgetListIterator it2(hlist); it2.current() != 0; ++it2) {
00559 ObjectTreeItem *tree = d->topTree->lookup(it2.current()->name());
00560 if(tree) {
00561 kdDebug() << "Form::autoAssignTabStops() adding " << tree->name() << endl;
00562 d->tabstops.append(tree);
00563 }
00564 }
00565
00566 --it;
00567 hlist.clear();
00568 }
00569 }
00570
00571 uint Form::formatVersion() const
00572 {
00573 return d->formatVersion;
00574 }
00575
00576 void Form::setFormatVersion(uint ver)
00577 {
00578 d->formatVersion = ver;
00579 }
00580 uint Form::originalFormatVersion() const
00581 {
00582 return d->originalFormatVersion;
00583 }
00584
00585 void Form::setOriginalFormatVersion(uint ver)
00586 {
00587 d->originalFormatVersion = ver;
00588 }
00589
00590 void Form::setFormWidget(FormWidget* w)
00591 {
00592 if (!d)
00593 return;
00594 d->formWidget = w;
00595 if (!d->formWidget)
00596 return;
00597 d->formWidget->m_form = this;
00598 }
00599
00600 #include "form.moc"