00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <kdebug.h>
00023 #include <kgenericfactory.h>
00024 #include <kdialogbase.h>
00025 #include <klistview.h>
00026 #include <ktabwidget.h>
00027 #include <kiconloader.h>
00028 #include <kcombobox.h>
00029
00030 #include <kexiviewbase.h>
00031 #include <keximainwindow.h>
00032 #include <kexiproject.h>
00033 #include <kexipartitem.h>
00034 #include <kexidialogbase.h>
00035 #include <kexidatasourcecombobox.h>
00036 #include <kexidb/connection.h>
00037 #include <kexidb/fieldlist.h>
00038 #include <kexidb/field.h>
00039
00040 #include <form.h>
00041 #include <formIO.h>
00042 #include <widgetpropertyset.h>
00043 #include <widgetlibrary.h>
00044 #include <objecttreeview.h>
00045 #include <koproperty/property.h>
00046
00047 #include "kexiformview.h"
00048 #include "widgets/kexidbform.h"
00049 #include "kexiformscrollview.h"
00050 #include "kexiactionselectiondialog.h"
00051 #include "kexiformmanager.h"
00052 #include "kexiformpart.h"
00053 #include "kexidatasourcepage.h"
00054
00056
00057 KFormDesigner::WidgetLibrary* KexiFormPart::static_formsLibrary = 0L;
00058
00060 class KexiFormPart::Private
00061 {
00062 public:
00063 Private()
00064 {
00065 }
00066 ~Private()
00067 {
00068 delete static_cast<KFormDesigner::ObjectTreeView*>(objectTreeView);
00069 delete static_cast<KexiDataSourcePage*>(dataSourcePage);
00070 }
00071
00072 QGuardedPtr<KFormDesigner::ObjectTreeView> objectTreeView;
00073 QGuardedPtr<KexiDataSourcePage> dataSourcePage;
00074 KexiDataSourceComboBox *dataSourceCombo;
00075 };
00076
00077 KexiFormPart::KexiFormPart(QObject *parent, const char *name, const QStringList &l)
00078 : KexiPart::Part(parent, name, l)
00079 , d(new Private())
00080 {
00081
00082 m_registeredPartID = (int)KexiPart::FormObjectType;
00083
00084 kexipluginsdbg << "KexiFormPart::KexiFormPart()" << endl;
00085 m_names["instanceName"]
00086 = i18n("Translate this word using only lowercase alphanumeric characters (a..z, 0..9). "
00087 "Use '_' character instead of spaces. First character should be a..z character. "
00088 "If you cannot use latin characters in your language, use english word.",
00089 "form");
00090 m_names["instanceCaption"] = i18n("Form");
00091 m_supportedViewModes = Kexi::DataViewMode | Kexi::DesignViewMode;
00092 m_newObjectsAreDirty = true;
00093
00094
00095
00096 KFormDesigner::FormManager *formManager = KFormDesigner::FormManager::self();
00097 if (!formManager)
00098 formManager = new KexiFormManager(this, "kexi_form_and_report_manager");
00099
00100
00101
00102 QStringList supportedFactoryGroups;
00103 supportedFactoryGroups += "kexi";
00104 static_formsLibrary = KFormDesigner::FormManager::createWidgetLibrary(
00105 formManager, supportedFactoryGroups);
00106 static_formsLibrary->setAdvancedPropertiesVisible(false);
00107
00108 connect(KFormDesigner::FormManager::self()->propertySet(), SIGNAL(widgetPropertyChanged(QWidget *, const QCString &, const QVariant&)),
00109 this, SLOT(slotPropertyChanged(QWidget *, const QCString &, const QVariant&)));
00110 connect(KFormDesigner::FormManager::self(), SIGNAL(autoTabStopsSet(KFormDesigner::Form*,bool)),
00111 this, SLOT(slotAutoTabStopsSet(KFormDesigner::Form*,bool)));
00112 }
00113
00114 KexiFormPart::~KexiFormPart()
00115 {
00116 delete d;
00117 }
00118
00119 KFormDesigner::WidgetLibrary* KexiFormPart::library()
00120 {
00121 return static_formsLibrary;
00122 }
00123
00124 #if 0
00125 void KexiFormPart::initPartActions(KActionCollection *collection)
00126 {
00127
00128
00129
00130 kexipluginsdbg<<"FormPart INIT ACTIONS***********************************************************************"<<endl;
00131
00132
00133
00134
00135 }
00136
00137 void KexiFormPart::initInstanceActions( int mode, KActionCollection *col )
00138 {
00139 if (mode==Kexi::DesignViewMode) {
00140 KFormDesigner::FormManager::self()->createActions(col, 0);
00141 new KAction(i18n("Edit Tab Order"), "tab_order", KShortcut(0), KFormDesigner::FormManager::self(), SLOT(editTabOrder()), col, "taborder");
00142 new KAction(i18n("Adjust Size"), "viewmagfit", KShortcut(0), KFormDesigner::FormManager::self(), SLOT(ajustWidgetSize()), col, "adjust");
00143 }
00144
00145 }
00146 #endif
00147
00148 void KexiFormPart::initPartActions()
00149 {
00150
00151
00152 }
00153
00154 void KexiFormPart::initInstanceActions()
00155 {
00156 #ifdef KEXI_SHOW_DEBUG_ACTIONS
00157 new KAction(i18n("Show Form UI Code"), "compfile", CTRL+Key_U, KFormDesigner::FormManager::self(), SLOT(showFormUICode()),
00158 actionCollectionForMode(Kexi::DesignViewMode), "show_form_ui");
00159 #endif
00160
00161 KActionCollection *col = actionCollectionForMode(Kexi::DesignViewMode);
00162 KFormDesigner::FormManager::self()->createActions( library(), col );
00163
00164
00165 connect( col->action("widget_assign_action"), SIGNAL(activated()), this, SLOT(slotAssignAction()));
00166
00167 createSharedAction(Kexi::DesignViewMode, i18n("Clear Widget Contents"), "editclear", 0, "formpart_clear_contents");
00168 createSharedAction(Kexi::DesignViewMode, i18n("Edit Tab Order"), "tab_order", 0, "formpart_taborder");
00169
00170
00171
00172
00173
00174 KAction *action = createSharedAction(Kexi::DesignViewMode, i18n("Layout Widgets"), "", 0, "formpart_layout_menu", "KActionMenu");
00175 KActionMenu *menu = static_cast<KActionMenu*>(action);
00176
00177 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("&Horizontally"),
00178 QString::null, 0, "formpart_layout_hbox"));
00179 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("&Vertically"),
00180 QString::null, 0, "formpart_layout_vbox"));
00181 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("In &Grid"),
00182 QString::null, 0, "formpart_layout_grid"));
00183 #ifdef KEXI_SHOW_SPLITTER_WIDGET
00184 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("Horizontally in &Splitter"),
00185 QString::null, 0, "formpart_layout_hsplitter"));
00186 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("Verti&cally in Splitter"),
00187 QString::null, 0, "formpart_layout_vsplitter"));
00188 #endif
00189
00190 createSharedAction(Kexi::DesignViewMode, i18n("&Break Layout"), QString::null, 0, "formpart_break_layout");
00191
00192
00193
00194
00195
00196 createSharedAction(Kexi::DesignViewMode, i18n("Bring Widget to Front"), "raise", 0, "formpart_format_raise");
00197 createSharedAction(Kexi::DesignViewMode, i18n("Send Widget to Back"), "lower", 0, "formpart_format_lower");
00198
00199 #ifndef KEXI_NO_UNFINISHED
00200 action = createSharedAction(Kexi::DesignViewMode, i18n("Other Widgets"), "", 0, "other_widgets_menu", "KActionMenu");
00201 #endif
00202
00203 action = createSharedAction(Kexi::DesignViewMode, i18n("Align Widgets Position"), "aoleft", 0, "formpart_align_menu", "KActionMenu");
00204 menu = static_cast<KActionMenu*>(action);
00205 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("To Left"), "aoleft", 0, "formpart_align_to_left") );
00206 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("To Right"), "aoright", 0, "formpart_align_to_right") );
00207 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("To Top"), "aotop", 0, "formpart_align_to_top") );
00208 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("To Bottom"), "aobottom", 0, "formpart_align_to_bottom") );
00209 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("To Grid"), "aopos2grid", 0, "formpart_align_to_grid") );
00210
00211 action = createSharedAction(Kexi::DesignViewMode, i18n("Adjust Widgets Size"), "aogrid", 0, "formpart_adjust_size_menu", "KActionMenu");
00212 menu = static_cast<KActionMenu*>(action);
00213 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("To Fit"), "aofit", 0, "formpart_adjust_to_fit") );
00214 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("To Grid"), "aogrid", 0, "formpart_adjust_size_grid") );
00215 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("To Shortest"), "aoshortest", 0, "formpart_adjust_height_small") );
00216 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("To Tallest"), "aotallest", 0, "formpart_adjust_height_big") );
00217 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("To Narrowest"), "aonarrowest", 0, "formpart_adjust_width_small") );
00218 menu->insert( createSharedAction(Kexi::DesignViewMode, i18n("To Widest"), "aowidest", 0, "formpart_adjust_width_big") );
00219 }
00220
00221 KexiDialogTempData*
00222 KexiFormPart::createTempData(KexiDialogBase* dialog)
00223 {
00224 return new KexiFormPart::TempData(dialog);
00225 }
00226
00227 KexiViewBase* KexiFormPart::createView(QWidget *parent, KexiDialogBase* dialog,
00228 KexiPart::Item &item, int viewMode, QMap<QString,QString>*)
00229 {
00230 Q_UNUSED( viewMode );
00231
00232 kexipluginsdbg << "KexiFormPart::createView()" << endl;
00233 KexiMainWindow *win = dialog->mainWin();
00234 if (!win || !win->project() || !win->project()->dbConnection())
00235 return 0;
00236
00237 KexiFormView *view = new KexiFormView(win, parent, item.name().latin1(),
00238 win->project()->dbConnection() );
00239
00240 return view;
00241 }
00242
00243 void
00244 KexiFormPart::generateForm(KexiDB::FieldList *list, QDomDocument &domDoc)
00245 {
00246
00247
00248 domDoc = QDomDocument("UI");
00249 QDomElement uiElement = domDoc.createElement("UI");
00250 domDoc.appendChild(uiElement);
00251 uiElement.setAttribute("version", "3.1");
00252 uiElement.setAttribute("stdsetdef", 1);
00253
00254 QDomElement baseClass = domDoc.createElement("class");
00255 uiElement.appendChild(baseClass);
00256 QDomText baseClassV = domDoc.createTextNode("QWidget");
00257 baseClass.appendChild(baseClassV);
00258 QDomElement baseWidget = domDoc.createElement("widget");
00259 baseWidget.setAttribute("class", "QWidget");
00260
00261 int y=0;
00262
00263 for(unsigned int i=0; i < list->fieldCount(); i++)
00264 {
00265 QDomElement lclass = domDoc.createElement("widget");
00266 baseWidget.appendChild(lclass);
00267 lclass.setAttribute("class", "QLabel");
00268 QDomElement lNameProperty = domDoc.createElement("property");
00269 lNameProperty.setAttribute("name", "name");
00270 QDomElement lType = domDoc.createElement("cstring");
00271 QDomText lClassN = domDoc.createTextNode(QString("l%1").arg(list->field(i)->name()));
00272 lType.appendChild(lClassN);
00273 lNameProperty.appendChild(lType);
00274 lclass.appendChild(lNameProperty);
00275
00276 QDomElement gNameProperty = domDoc.createElement("property");
00277 gNameProperty.setAttribute("name", "geometry");
00278 QDomElement lGType = domDoc.createElement("rect");
00279
00280 QDomElement lx = domDoc.createElement("x");
00281 QDomText lxV = domDoc.createTextNode("10");
00282 lx.appendChild(lxV);
00283 QDomElement ly = domDoc.createElement("y");
00284 QDomText lyV = domDoc.createTextNode(QString::number(y + 10));
00285 ly.appendChild(lyV);
00286 QDomElement lWidth = domDoc.createElement("width");
00287 QDomText lWidthV = domDoc.createTextNode("100");
00288 lWidth.appendChild(lWidthV);
00289 QDomElement lHeight = domDoc.createElement("height");
00290 QDomText lHeightV = domDoc.createTextNode("20");
00291 lHeight.appendChild(lHeightV);
00292
00293 lGType.appendChild(lx);
00294 lGType.appendChild(ly);
00295 lGType.appendChild(lWidth);
00296 lGType.appendChild(lHeight);
00297
00298 gNameProperty.appendChild(lGType);
00299 lclass.appendChild(gNameProperty);
00300
00301 QDomElement tNameProperty = domDoc.createElement("property");
00302 tNameProperty.setAttribute("name", "text");
00303 QDomElement lTType = domDoc.createElement("string");
00304 QDomText lTextV = domDoc.createTextNode(list->field(i)->name());
00305 lTType.appendChild(lTextV);
00306 tNameProperty.appendChild(lTType);
00307 lclass.appendChild(tNameProperty);
00308
00309
00311
00312
00313 QDomElement vclass = domDoc.createElement("widget");
00314 baseWidget.appendChild(vclass);
00315 vclass.setAttribute("class", "KLineEdit");
00316 QDomElement vNameProperty = domDoc.createElement("property");
00317 vNameProperty.setAttribute("name", "name");
00318 QDomElement vType = domDoc.createElement("cstring");
00319 QDomText vClassN = domDoc.createTextNode(list->field(i)->name());
00320 vType.appendChild(vClassN);
00321 vNameProperty.appendChild(vType);
00322 vclass.appendChild(vNameProperty);
00323
00324 QDomElement vgNameProperty = domDoc.createElement("property");
00325 vgNameProperty.setAttribute("name", "geometry");
00326 QDomElement vGType = domDoc.createElement("rect");
00327
00328 QDomElement vx = domDoc.createElement("x");
00329 QDomText vxV = domDoc.createTextNode("110");
00330 vx.appendChild(vxV);
00331 QDomElement vy = domDoc.createElement("y");
00332 QDomText vyV = domDoc.createTextNode(QString::number(y + 10));
00333 vy.appendChild(vyV);
00334 QDomElement vWidth = domDoc.createElement("width");
00335 QDomText vWidthV = domDoc.createTextNode("200");
00336 vWidth.appendChild(vWidthV);
00337 QDomElement vHeight = domDoc.createElement("height");
00338 QDomText vHeightV = domDoc.createTextNode("20");
00339 vHeight.appendChild(vHeightV);
00340
00341 vGType.appendChild(vx);
00342 vGType.appendChild(vy);
00343 vGType.appendChild(vWidth);
00344 vGType.appendChild(vHeight);
00345
00346 vgNameProperty.appendChild(vGType);
00347 vclass.appendChild(vgNameProperty);
00348
00349 y += 20;
00350 }
00351
00352 QDomElement lNameProperty = domDoc.createElement("property");
00353 lNameProperty.setAttribute("name", "name");
00354 QDomElement lType = domDoc.createElement("cstring");
00355 QDomText lClassN = domDoc.createTextNode("DBForm");
00356 lType.appendChild(lClassN);
00357 lNameProperty.appendChild(lType);
00358 baseWidget.appendChild(lNameProperty);
00359
00360 QDomElement wNameProperty = domDoc.createElement("property");
00361 wNameProperty.setAttribute("name", "geometry");
00362 QDomElement wGType = domDoc.createElement("rect");
00363
00364 QDomElement wx = domDoc.createElement("x");
00365 QDomText wxV = domDoc.createTextNode("0");
00366 wx.appendChild(wxV);
00367 QDomElement wy = domDoc.createElement("y");
00368 QDomText wyV = domDoc.createTextNode("0");
00369 wy.appendChild(wyV);
00370 QDomElement wWidth = domDoc.createElement("width");
00371 QDomText wWidthV = domDoc.createTextNode("340");
00372 wWidth.appendChild(wWidthV);
00373 QDomElement wHeight = domDoc.createElement("height");
00374 QDomText wHeightV = domDoc.createTextNode(QString::number(y + 30));
00375 wHeight.appendChild(wHeightV);
00376
00377 wGType.appendChild(wx);
00378 wGType.appendChild(wy);
00379 wGType.appendChild(wWidth);
00380 wGType.appendChild(wHeight);
00381
00382 wNameProperty.appendChild(wGType);
00383 baseWidget.appendChild(wNameProperty);
00384
00385 uiElement.appendChild(baseWidget);
00386 }
00387
00388 void KexiFormPart::slotAutoTabStopsSet(KFormDesigner::Form *form, bool set)
00389 {
00390 Q_UNUSED( form );
00391
00392 (*KFormDesigner::FormManager::self()->propertySet())["autoTabStops"].setValue(QVariant(set, 4));
00393 }
00394
00395 void KexiFormPart::slotAssignAction()
00396 {
00397 KexiDBForm *dbform;
00398 if (!KFormDesigner::FormManager::self()->activeForm() || !KFormDesigner::FormManager::self()->activeForm()->designMode()
00399 || !(dbform = dynamic_cast<KexiDBForm*>(KFormDesigner::FormManager::self()->activeForm()->formWidget())))
00400 return;
00401
00402 KoProperty::Property &onClickActionProp = KFormDesigner::FormManager::self()->propertySet()->property("onClickAction");
00403 if (onClickActionProp.isNull())
00404 return;
00405 QString onClickActionValue( onClickActionProp.value().toString() );
00406
00407 KexiFormScrollView *scrollViewWidget = dynamic_cast<KexiFormScrollView*>(dbform->dataAwareObject());
00408 if (!scrollViewWidget)
00409 return;
00410 KexiFormView* formViewWidget = dynamic_cast<KexiFormView*>(scrollViewWidget->parent());
00411 if (!formViewWidget)
00412 return;
00413
00414 KexiMainWindow * mainWin = formViewWidget->parentDialog()->mainWin();
00415 KexiActionSelectionDialog dlg(mainWin, dbform, onClickActionValue,
00416 KFormDesigner::FormManager::self()->propertySet()->property("name").value().toCString());
00417
00418 if(dlg.exec() == QDialog::Accepted) {
00419 onClickActionValue = dlg.currentActionName();
00420
00421 (*KFormDesigner::FormManager::self()->propertySet())["onClickAction"].setValue(onClickActionValue);
00422 }
00423 }
00424
00425 QString
00426 KexiFormPart::i18nMessage(const QCString& englishMessage, KexiDialogBase* dlg) const
00427 {
00428 Q_UNUSED(dlg);
00429 if (englishMessage=="Design of object \"%1\" has been modified.")
00430 return i18n("Design of form \"%1\" has been modified.");
00431 if (englishMessage=="Object \"%1\" already exists.")
00432 return i18n("Form \"%1\" already exists.");
00433
00434 return englishMessage;
00435 }
00436
00437 void
00438 KexiFormPart::slotPropertyChanged(QWidget *w, const QCString &name, const QVariant &value)
00439 {
00440 Q_UNUSED( w );
00441
00442 if (!KFormDesigner::FormManager::self()->activeForm())
00443 return;
00444 if (name == "autoTabStops") {
00445
00446
00447 KFormDesigner::FormManager::self()->activeForm()->setAutoTabStops( value.toBool() );
00448 }
00449 if (KFormDesigner::FormManager::self()->activeForm()->widget() && name == "geometry") {
00450
00451 if (KFormDesigner::FormManager::self()->propertySet()->contains("sizeInternal"))
00452 KFormDesigner::FormManager::self()->propertySet()->property("sizeInternal").setValue(value.toRect().size());
00453 }
00454 }
00455
00456
00457
00458
00459
00460
00461
00462 KexiDataSourcePage* KexiFormPart::dataSourcePage() const
00463 {
00464 return d->dataSourcePage;
00465 }
00466
00467 void KexiFormPart::setupCustomPropertyPanelTabs(KTabWidget *tab, KexiMainWindow* mainWin)
00468 {
00469 if (!d->objectTreeView) {
00470 d->objectTreeView = new KFormDesigner::ObjectTreeView(0, "KexiFormPart:ObjectTreeView");
00471 KFormDesigner::FormManager::self()->setObjectTreeView(d->objectTreeView);
00472 d->dataSourcePage = new KexiDataSourcePage(0, "dataSourcePage");
00473 connect(d->dataSourcePage, SIGNAL(jumpToObjectRequested(const QCString&, const QCString&)),
00474 mainWin, SLOT(highlightObject(const QCString&, const QCString&)));
00475 connect(d->dataSourcePage, SIGNAL(formDataSourceChanged(const QCString&, const QCString&)),
00476 KFormDesigner::FormManager::self(), SLOT(setFormDataSource(const QCString&, const QCString&)));
00477 connect(d->dataSourcePage, SIGNAL(dataSourceFieldOrExpressionChanged(const QString&, const QString&, KexiDB::Field::Type)),
00478 KFormDesigner::FormManager::self(), SLOT(setDataSourceFieldOrExpression(const QString&, const QString&, KexiDB::Field::Type)));
00479 connect(d->dataSourcePage, SIGNAL(insertAutoFields(const QString&, const QString&, const QStringList&)),
00480 KFormDesigner::FormManager::self(), SLOT(insertAutoFields(const QString&, const QString&, const QStringList&)));
00481 }
00482
00483 KexiProject *prj = mainWin->project();
00484 d->dataSourcePage->setProject(prj);
00485
00486 tab->addTab( d->dataSourcePage, SmallIconSet("database"), "");
00487 tab->setTabToolTip( d->dataSourcePage, i18n("Data Source"));
00488
00489 tab->addTab( d->objectTreeView, SmallIconSet("widgets"), "");
00490 tab->setTabToolTip( d->objectTreeView, i18n("Widgets"));
00491 }
00492
00493
00494
00495 KexiFormPart::TempData::TempData(QObject* parent)
00496 : KexiDialogTempData(parent)
00497 {
00498 }
00499
00500 KexiFormPart::TempData::~TempData()
00501 {
00502 }
00503
00504 #include "kexiformpart.moc"