1
/* This file is part of the KDE project
2
Copyright (C) 2004 Lucijan Busch <lucijan@kde.org>
3
Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
4
Copyright (C) 2005 Jarosław Staniek <staniek@kde.org>
6
This library is free software; you can redistribute it and/or
7
modify it under the terms of the GNU Library General Public
8
License as published by the Free Software Foundation; either
9
version 2 of the License, or (at your option) any later version.
11
This library is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
Library General Public License for more details.
16
You should have received a copy of the GNU Library General Public License
17
along with this library; see the file COPYING.LIB. If not, write to
18
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19
* Boston, MA 02110-1301, USA.
24
#include <k3listview.h>
25
#include <ktabwidget.h>
26
#include <kiconloader.h>
27
#include <kcombobox.h>
28
#include <kapplication.h>
31
#include <KActionMenu>
32
#include <KActionCollection>
35
#include <KexiWindow.h>
36
#include <KexiMainWindowIface.h>
37
#include <kexiproject.h>
38
#include <kexipartitem.h>
39
#include <kexidatasourcecombobox.h>
40
#include <kexidb/connection.h>
41
#include <kexidb/fieldlist.h>
42
#include <kexidb/field.h>
43
#include <kexiutils/utils.h>
45
#include <kexi_global.h>
46
#include <formeditor/form.h>
47
#include <formeditor/formIO.h>
48
//2.0 #include <formeditor/widgetpropertyset.h>
49
#include <formeditor/objecttreeview.h>
51
#include <koproperty/Property.h>
52
#include <koproperty/Set.h>
54
#include "kexiformview.h"
55
#include "widgets/kexidbform.h"
56
#include "kexiformscrollview.h"
57
#include "kexiformmanager.h"
58
#include "kexiformpart.h"
59
#include "kexidatasourcepage.h"
61
//! @todo #define KEXI_SHOW_SPLITTER_WIDGET
64
class KexiFormPart::Private
68
#ifndef KEXI_NO_OBJECTTREEVIEW
69
objectTreeView = new KFormDesigner::ObjectTreeView(0);
70
objectTreeView->setObjectName("KexiFormPart:ObjectTreeView");
74
#ifndef KEXI_NO_OBJECTTREEVIEW
75
delete static_cast<KFormDesigner::ObjectTreeView*>(objectTreeView);
77
delete static_cast<KexiDataSourcePage*>(dataSourcePage);
79
QPointer<KFormDesigner::ObjectTreeView> objectTreeView;
80
QPointer<KexiDataSourcePage> dataSourcePage;
81
KexiDataSourceComboBox *dataSourceCombo;
84
KexiFormPart::KexiFormPart(QObject *parent, const QVariantList &l)
85
: KexiPart::Part(parent, l)
89
setInternalPropertyValue("instanceName",
90
i18nc("Translate this word using only lowercase alphanumeric characters (a..z, 0..9). "
91
"Use '_' character instead of spaces. First character should be a..z character. "
92
"If you cannot use latin characters in your language, use english word.",
94
setInternalPropertyValue("instanceCaption", i18n("Form"));
95
setInternalPropertyValue("instanceToolTip", i18nc("tooltip", "Create new form"));
96
setInternalPropertyValue("instanceWhatsThis", i18nc("what's this", "Creates new form."));
97
setSupportedViewModes(Kexi::DataViewMode | Kexi::DesignViewMode);
98
setInternalPropertyValue("newObjectsAreDirty", true);
100
// Only create form manager if it's not yet created.
101
// KexiReportPart could have created it already.
104
KFormDesigner::FormManager *formManager = KFormDesigner::FormManager::self();
105
if (!formManager) {*/
106
KexiFormManager::self()->init(this, d->objectTreeView); // this should create KexiFormManager singleton
109
/* 2.0 slotPropertyChanged() code moved to Form so this connection can be removed
110
connect(KFormDesigner::FormManager::self()->propertySet(),
111
SIGNAL(widgetPropertyChanged(QWidget *, const QByteArray &, const QVariant&)),
112
this, SLOT(slotPropertyChanged(QWidget *, const QByteArray &, const QVariant&)));*/
113
//2.0 not needed, the code from slot receiving this signal is moved to Form itself
114
// connect(KFormDesigner::FormManager::self(), SIGNAL(autoTabStopsSet(KFormDesigner::Form*, bool)),
115
// this, SLOT(slotAutoTabStopsSet(KFormDesigner::Form*, bool)));
118
KexiFormPart::~KexiFormPart()
120
//2.0 static_formsLibrary = 0;
124
/* moved to KexiFormManager
125
KFormDesigner::WidgetLibrary* KexiFormPart::library()
127
return static_formsLibrary;
133
void KexiFormPart::initPartActions(KActionCollection *collection)
135
//this is automatic? -no
136
//create child guicilent: guiClient()->setXMLFile("kexidatatableui.rc");
138
kDebug() << "FormPart INIT ACTIONS***********************************************************************";
141
//guiClient()->setXMLFile("kexiformui.rc");
142
//js m_manager->createActions(collection, 0);
145
void KexiFormPart::initInstanceActions(int mode, KActionCollection *col)
147
if (mode == Kexi::DesignViewMode) {
148
KFormDesigner::FormManager::self()->createActions(col, 0);
149
new KAction(i18n("Edit Tab Order..."), "tab_order", KShortcut(0), KFormDesigner::FormManager::self(), SLOT(editTabOrder()), col, "taborder");
150
new KAction(i18n("Adjust Size"), "zoom-fit-best", KShortcut(0), KFormDesigner::FormManager::self(), SLOT(adjustWidgetSize()), col, "adjust");
156
void KexiFormPart::initPartActions()
160
void KexiFormPart::initInstanceActions()
162
// KActionCollection *col = actionCollectionForMode(Kexi::DesignViewMode);
164
//moved to KexiFormManager::init()
165
//KexiFormManager::self()->createActions(library(), col,
166
// (KXMLGUIClient*)col->parentGUIClient());
168
//connect actions provided by widget factories
169
//2.0 moved connect(col->action("widget_assign_action"), SIGNAL(activated()),
170
//2.0 moved this, SLOT(slotAssignAction()));
172
createSharedAction(Kexi::DesignViewMode, i18n("Clear Widget Contents"),
173
"edit-clear", KShortcut(), "formpart_clear_contents");
174
createSharedAction(Kexi::DesignViewMode, i18n("Edit Tab Order..."),
175
"tab_order", KShortcut(), "formpart_taborder");
176
//TODO createSharedAction(Kexi::DesignViewMode, i18n("Edit Pixmap Collection"), "icons", 0, "formpart_pixmap_collection");
177
//TODO createSharedAction(Kexi::DesignViewMode, i18n("Edit Form Connections"), "connections", 0, "formpart_connections");
179
// KFormDesigner::CreateLayoutCommand
181
KAction *action = createSharedAction(Kexi::DesignViewMode, i18n("Layout Widgets"),
182
QString(), KShortcut(), "formpart_layout_menu", "KActionMenu");
183
KActionMenu *menu = static_cast<KActionMenu*>(action);
185
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("&Horizontally"),
186
QString(), KShortcut(), "formpart_layout_hbox"));
187
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("&Vertically"),
188
QString(), KShortcut(), "formpart_layout_vbox"));
189
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("In &Grid"),
190
QString(), KShortcut(), "formpart_layout_grid"));
191
#ifdef KEXI_SHOW_SPLITTER_WIDGET
192
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("Horizontally in &Splitter"),
193
QString(), KShortcut(), "formpart_layout_hsplitter"));
194
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("Verti&cally in Splitter"),
195
QString(), KShortcut(), "formpart_layout_vsplitter"));
198
createSharedAction(Kexi::DesignViewMode, i18n("&Break Layout"), QString(),
199
KShortcut(), "formpart_break_layout");
201
createSharedAction(Kexi::DesignViewMode, i18n("Lay Out Widgets &Horizontally"), QString(), 0, "formpart_layout_hbox");
202
createSharedAction(Kexi::DesignViewMode, i18n("Lay Out Widgets &Vertically"), QString(), 0, "formpart_layout_vbox");
203
createSharedAction(Kexi::DesignViewMode, i18n("Lay Out Widgets in &Grid"), QString(), 0, "formpart_layout_grid");
205
createSharedAction(Kexi::DesignViewMode, i18n("Bring Widget to Front"), "raise",
206
KShortcut(), "formpart_format_raise");
207
createSharedAction(Kexi::DesignViewMode, i18n("Send Widget to Back"), "lower",
208
KShortcut(), "formpart_format_lower");
210
#ifndef KEXI_NO_UNFINISHED
211
action = createSharedAction(Kexi::DesignViewMode, i18n("Other Widgets"), QString(),
212
KShortcut(), "other_widgets_menu", "KActionMenu");
215
action = createSharedAction(Kexi::DesignViewMode, i18n("Align Widgets Position"),
216
"aoleft", KShortcut(), "formpart_align_menu", "KActionMenu");
217
menu = static_cast<KActionMenu*>(action);
218
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("To Left"), "aoleft",
219
KShortcut(), "formpart_align_to_left"));
220
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("To Right"), "aoright",
221
KShortcut(), "formpart_align_to_right"));
222
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("To Top"), "aotop",
223
KShortcut(), "formpart_align_to_top"));
224
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("To Bottom"), "aobottom",
225
KShortcut(), "formpart_align_to_bottom"));
226
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("To Grid"), "aopos2grid",
227
KShortcut(), "formpart_align_to_grid"));
229
action = createSharedAction(Kexi::DesignViewMode, i18n("Adjust Widgets Size"), "aogrid",
230
KShortcut(), "formpart_adjust_size_menu", "KActionMenu");
231
menu = static_cast<KActionMenu*>(action);
232
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("To Fit"), "aofit",
233
KShortcut(), "formpart_adjust_to_fit"));
234
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("To Grid"), "aogrid",
235
KShortcut(), "formpart_adjust_size_grid"));
236
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("To Shortest"), "aoshortest",
237
KShortcut(), "formpart_adjust_height_small"));
238
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("To Tallest"), "aotallest",
239
KShortcut(), "formpart_adjust_height_big"));
240
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("To Narrowest"), "aonarrowest",
241
KShortcut(), "formpart_adjust_width_small"));
242
menu->addAction(createSharedAction(Kexi::DesignViewMode, i18n("To Widest"), "aowidest",
243
KShortcut(), "formpart_adjust_width_big"));
247
KexiFormPart::createWindowData(KexiWindow* window)
249
return new KexiFormPart::TempData(window);
252
KexiView* KexiFormPart::createView(QWidget *parent, KexiWindow* window,
253
KexiPart::Item &item, Kexi::ViewMode viewMode, QMap<QString, QVariant>*)
259
KexiMainWindowIface *win = KexiMainWindowIface::global();
260
if (!win || !win->project() || !win->project()->dbConnection())
263
KexiFormView *view = new KexiFormView(parent, win->project()->dbConnection());
264
view->setObjectName(item.name().toLatin1());
269
KexiFormPart::generateForm(KexiDB::FieldList *list, QDomDocument &domDoc)
271
//this form generates a .ui from FieldList list
272
//basically that is a Label and a LineEdit for each field
273
domDoc = QDomDocument("UI");
274
QDomElement uiElement = domDoc.createElement("UI");
275
domDoc.appendChild(uiElement);
276
uiElement.setAttribute("version", "3.1");
277
uiElement.setAttribute("stdsetdef", 1);
279
QDomElement baseClass = domDoc.createElement("class");
280
uiElement.appendChild(baseClass);
281
QDomText baseClassV = domDoc.createTextNode("QWidget");
282
baseClass.appendChild(baseClassV);
283
QDomElement baseWidget = domDoc.createElement("widget");
284
baseWidget.setAttribute("class", "QWidget");
288
for (unsigned int i = 0; i < list->fieldCount(); i++) {
289
QDomElement lclass = domDoc.createElement("widget");
290
baseWidget.appendChild(lclass);
291
lclass.setAttribute("class", "QLabel");
292
QDomElement lNameProperty = domDoc.createElement("property");
293
lNameProperty.setAttribute("name", "name");
294
QDomElement lType = domDoc.createElement("cstring");
295
QDomText lClassN = domDoc.createTextNode(QString("l%1").arg(list->field(i)->name()));
296
lType.appendChild(lClassN);
297
lNameProperty.appendChild(lType);
298
lclass.appendChild(lNameProperty);
300
QDomElement gNameProperty = domDoc.createElement("property");
301
gNameProperty.setAttribute("name", "geometry");
302
QDomElement lGType = domDoc.createElement("rect");
304
QDomElement lx = domDoc.createElement("x");
305
QDomText lxV = domDoc.createTextNode("10");
307
QDomElement ly = domDoc.createElement("y");
308
QDomText lyV = domDoc.createTextNode(QString::number(y + 10));
310
QDomElement lWidth = domDoc.createElement("width");
311
QDomText lWidthV = domDoc.createTextNode("100");
312
lWidth.appendChild(lWidthV);
313
QDomElement lHeight = domDoc.createElement("height");
314
QDomText lHeightV = domDoc.createTextNode("20");
315
lHeight.appendChild(lHeightV);
317
lGType.appendChild(lx);
318
lGType.appendChild(ly);
319
lGType.appendChild(lWidth);
320
lGType.appendChild(lHeight);
322
gNameProperty.appendChild(lGType);
323
lclass.appendChild(gNameProperty);
325
QDomElement tNameProperty = domDoc.createElement("property");
326
tNameProperty.setAttribute("name", "text");
327
QDomElement lTType = domDoc.createElement("string");
328
QDomText lTextV = domDoc.createTextNode(list->field(i)->name());
329
lTType.appendChild(lTextV);
330
tNameProperty.appendChild(lTType);
331
lclass.appendChild(tNameProperty);
337
QDomElement vclass = domDoc.createElement("widget");
338
baseWidget.appendChild(vclass);
339
vclass.setAttribute("class", "KLineEdit");
340
QDomElement vNameProperty = domDoc.createElement("property");
341
vNameProperty.setAttribute("name", "name");
342
QDomElement vType = domDoc.createElement("cstring");
343
QDomText vClassN = domDoc.createTextNode(list->field(i)->name());
344
vType.appendChild(vClassN);
345
vNameProperty.appendChild(vType);
346
vclass.appendChild(vNameProperty);
348
QDomElement vgNameProperty = domDoc.createElement("property");
349
vgNameProperty.setAttribute("name", "geometry");
350
QDomElement vGType = domDoc.createElement("rect");
352
QDomElement vx = domDoc.createElement("x");
353
QDomText vxV = domDoc.createTextNode("110");
355
QDomElement vy = domDoc.createElement("y");
356
QDomText vyV = domDoc.createTextNode(QString::number(y + 10));
358
QDomElement vWidth = domDoc.createElement("width");
359
QDomText vWidthV = domDoc.createTextNode("200");
360
vWidth.appendChild(vWidthV);
361
QDomElement vHeight = domDoc.createElement("height");
362
QDomText vHeightV = domDoc.createTextNode("20");
363
vHeight.appendChild(vHeightV);
365
vGType.appendChild(vx);
366
vGType.appendChild(vy);
367
vGType.appendChild(vWidth);
368
vGType.appendChild(vHeight);
370
vgNameProperty.appendChild(vGType);
371
vclass.appendChild(vgNameProperty);
376
QDomElement lNameProperty = domDoc.createElement("property");
377
lNameProperty.setAttribute("name", "name");
378
QDomElement lType = domDoc.createElement("cstring");
379
QDomText lClassN = domDoc.createTextNode("DBForm");
380
lType.appendChild(lClassN);
381
lNameProperty.appendChild(lType);
382
baseWidget.appendChild(lNameProperty);
384
QDomElement wNameProperty = domDoc.createElement("property");
385
wNameProperty.setAttribute("name", "geometry");
386
QDomElement wGType = domDoc.createElement("rect");
388
QDomElement wx = domDoc.createElement("x");
389
QDomText wxV = domDoc.createTextNode("0");
391
QDomElement wy = domDoc.createElement("y");
392
QDomText wyV = domDoc.createTextNode("0");
394
QDomElement wWidth = domDoc.createElement("width");
395
QDomText wWidthV = domDoc.createTextNode("340");
396
wWidth.appendChild(wWidthV);
397
QDomElement wHeight = domDoc.createElement("height");
398
QDomText wHeightV = domDoc.createTextNode(QString::number(y + 30));
399
wHeight.appendChild(wHeightV);
401
wGType.appendChild(wx);
402
wGType.appendChild(wy);
403
wGType.appendChild(wWidth);
404
wGType.appendChild(wHeight);
406
wNameProperty.appendChild(wGType);
407
baseWidget.appendChild(wNameProperty);
409
uiElement.appendChild(baseWidget);
412
//2.0 not needed, the code from slot receiving this signal is moved to Form itself
413
/*void KexiFormPart::slotAutoTabStopsSet(KFormDesigner::Form *form, bool set)
415
if (form->propertySet().contains("autoTabStops")) {
416
form->propertySet().changeProperty("autoTabStops", set);
420
KLocalizedString KexiFormPart::i18nMessage(
421
const QString& englishMessage, KexiWindow* window) const
424
if (englishMessage == "Design of object \"%1\" has been modified.")
425
return ki18n(I18N_NOOP("Design of form \"%1\" has been modified."));
426
if (englishMessage == "Object \"%1\" already exists.")
427
return ki18n(I18N_NOOP("Form \"%1\" already exists."));
429
return Part::i18nMessage(englishMessage, window);
434
KexiFormPart::slotPropertyChanged(QWidget *w, const QByteArray &name, const QVariant &value)
438
if (!KFormDesigner::FormManager::self()->activeForm())
440
if (name == "autoTabStops") {
441
//QWidget *w = KFormDesigner::FormManager::self()->activeForm()->selectedWidget();
442
//update autoTabStops setting at KFD::Form level
443
KFormDesigner::FormManager::self()->activeForm()->setAutoTabStops(value.toBool());
445
if (KFormDesigner::FormManager::self()->activeForm()->widget() && name == "geometry") {
446
//fall back to sizeInternal property....
447
if (KFormDesigner::FormManager::self()->propertySet()->contains("sizeInternal"))
448
KFormDesigner::FormManager::self()->propertySet()->property("sizeInternal").setValue(
449
value.toRect().size());
453
/*KFormDesigner::FormManager*
454
KexiFormPart::manager() const
459
KexiDataSourcePage* KexiFormPart::dataSourcePage() const
461
return d->dataSourcePage;
464
void KexiFormPart::setupCustomPropertyPanelTabs(KTabWidget *tab)
466
if (!d->dataSourcePage) {
467
d->dataSourcePage = new KexiDataSourcePage(0);
468
d->dataSourcePage->setObjectName("dataSourcePage");
469
connect(d->dataSourcePage,
470
SIGNAL(jumpToObjectRequested(const QString&, const QString&)),
471
KexiMainWindowIface::global()->thisWidget(),
472
SLOT(highlightObject(const QString&, const QString&)));
473
connect(d->dataSourcePage,
474
SIGNAL(formDataSourceChanged(const QString&, const QString&)),
475
KexiFormManager::self(),
476
SLOT(setFormDataSource(const QString&, const QString&)));
477
connect(d->dataSourcePage,
478
SIGNAL(dataSourceFieldOrExpressionChanged(const QString&, const QString&, KexiDB::Field::Type)),
479
KexiFormManager::self(),
480
SLOT(setDataSourceFieldOrExpression(const QString&, const QString&, KexiDB::Field::Type)));
481
connect(d->dataSourcePage,
482
SIGNAL(insertAutoFields(const QString&, const QString&, const QStringList&)),
483
KexiFormManager::self(),
484
SLOT(insertAutoFields(const QString&, const QString&, const QStringList&)));
487
KexiProject *prj = KexiMainWindowIface::global()->project();
488
d->dataSourcePage->setProject(prj);
490
tab->addTab(d->dataSourcePage, KIcon("server-database"), QString());
491
tab->setTabToolTip(tab->indexOf(d->dataSourcePage), i18n("Data Source"));
494
tab->addTab(d->objectTreeView, KIcon("widgets"), QString());
495
tab->setTabToolTip(tab->indexOf(d->objectTreeView), i18n("Widgets"));
505
KexiFormPart::TempData::TempData(QObject* parent)
506
: KexiWindowData(parent)
510
KexiFormPart::TempData::~TempData()
514
#include "kexiformpart.moc"