1 /*
2 * Kexi Report Plugin
3 * Copyright (C) 2007-2009 by Adam Pigg <adam@piggz.co.uk>
4 * Copyright (C) 2011-2017 Jarosław Staniek <staniek@kde.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
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 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "kexireportdesignview.h"
21 #include <core/KexiMainWindowIface.h>
22 #include <core/KexiWindow.h>
23 #include "kexisourceselector.h"
24 #include <KexiIcon.h>
25 #include <kexiutils/utils.h>
26
27 #include <KDbConnection>
28
29 #include <QShortcut>
30 #include <QDebug>
31 #include <QScrollArea>
32 #include <QLayout>
33
34 #include <KStandardGuiItem>
35
KexiReportDesignView(QWidget * parent,KexiSourceSelector * s)36 KexiReportDesignView::KexiReportDesignView(QWidget *parent, KexiSourceSelector *s)
37 : KexiView(parent)
38 {
39 m_scrollArea = new QScrollArea(this);
40 layout()->addWidget(m_scrollArea);
41 m_sourceSelector = s;
42
43 m_reportDesigner = 0;
44
45 m_editCutAction = KStandardAction::cut(this);
46 m_editCutAction->setProperty("iconOnly", true);
47 m_editCopyAction = KStandardAction::copy(this);
48 m_editCopyAction->setProperty("iconOnly", true);
49 m_editPasteAction = KStandardAction::paste(this);
50 m_editPasteAction->setProperty("iconOnly", true);
51 const KGuiItem del = KStandardGuiItem::del();
52 m_editDeleteAction = new QAction(del.icon(), del.text(), this);
53 m_editDeleteAction->setObjectName("editdelete");
54 m_editDeleteAction->setToolTip(del.toolTip());
55 m_editDeleteAction->setWhatsThis(del.whatsThis());
56 m_editDeleteAction->setProperty("iconOnly", true);
57
58 m_editSectionAction = new QAction(xi18n("Edit Sections"), this);
59 m_editSectionAction->setObjectName("sectionedit");
60
61 m_itemRaiseAction = new QAction(koIcon("object-order-front"), xi18n("Raise"), this);
62 m_itemRaiseAction->setObjectName("itemraise");
63 m_itemLowerAction = new QAction(koIcon("object-order-back"), xi18n("Lower"), this);
64 m_itemLowerAction->setObjectName("itemlower");
65 QList<QAction*> al;
66 QAction *sep = new QAction(QString(), this);
67 sep->setSeparator(true);
68
69 al << m_editCutAction << m_editCopyAction << m_editPasteAction << m_editDeleteAction << sep << m_editSectionAction << sep << m_itemLowerAction << m_itemRaiseAction;
70 setViewActions(al);
71
72 }
73
~KexiReportDesignView()74 KexiReportDesignView::~KexiReportDesignView()
75 {
76 }
77
propertySet()78 KPropertySet *KexiReportDesignView::propertySet()
79 {
80 return m_reportDesigner->selectedItemPropertySet();
81 }
82
slotDesignerPropertySetChanged()83 void KexiReportDesignView::slotDesignerPropertySetChanged()
84 {
85 propertySetReloaded(true);
86 propertySetSwitched();
87 }
88
storeNewData(const KDbObject & object,KexiView::StoreNewDataOptions options,bool * cancel)89 KDbObject* KexiReportDesignView::storeNewData(const KDbObject& object,
90 KexiView::StoreNewDataOptions options,
91 bool *cancel)
92 {
93 KDbObject *s = KexiView::storeNewData(object, options, cancel);
94 if (!s || *cancel) {
95 delete s;
96 return 0;
97 }
98 qDebug() << "new id:" << s->id();
99
100 if (!storeData()) {
101 //failure: remove object's object data to avoid garbage
102 KDbConnection *conn = KexiMainWindowIface::global()->project()->dbConnection();
103 conn->removeObject(s->id());
104 delete s;
105 return 0;
106 }
107 return s;
108
109 }
110
storeData(bool dontAsk)111 tristate KexiReportDesignView::storeData(bool dontAsk)
112 {
113 Q_UNUSED(dontAsk);
114
115 QDomDocument doc("kexireport");
116 QDomElement root = doc.createElement("kexireport");
117 QDomElement conndata = connectionData();
118
119 if (conndata.isNull())
120 qDebug() << "Null conn data!";
121
122 root.appendChild(m_reportDesigner->document());
123 root.appendChild(conndata);
124 doc.appendChild(root);
125
126 QString src = doc.toString();
127 qDebug() << src;
128
129 if (storeDataBlock(src, "layout")) {
130 qDebug() << "Saved OK";
131 setDirty(false);
132 return true;
133 }
134
135 qDebug() << "NOT Saved OK";
136 return false;
137 }
138
beforeSwitchTo(Kexi::ViewMode mode,bool * dontStore)139 tristate KexiReportDesignView::beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore)
140 {
141 //qDebug() << mode;
142 *dontStore = true;
143 if (m_reportDesigner && mode == Kexi::DataViewMode) {
144 //qDebug() << "Saving temp data";
145 tempData()->reportDefinition = m_reportDesigner->document();
146 //qDebug() << m_reportDesigner->document().toDocument().toString();
147 tempData()->reportSchemaChangedInPreviousView = true;
148 }
149 return true;
150 }
151
afterSwitchFrom(Kexi::ViewMode mode)152 tristate KexiReportDesignView::afterSwitchFrom(Kexi::ViewMode mode)
153 {
154 Q_UNUSED(mode);
155
156 if (tempData()->reportDefinition.isNull()) {
157 m_reportDesigner = new KReportDesigner(this);
158 } else {
159 if (m_reportDesigner) {
160 m_scrollArea->takeWidget();
161 delete m_reportDesigner;
162 m_reportDesigner = 0;
163 }
164
165 m_reportDesigner = new KReportDesigner(this, tempData()->reportDefinition);
166 setConnectionData(tempData()->connectionDefinition);
167 m_reportDesigner->setScriptSource(qobject_cast<KexiReportPart*>(part()));
168 }
169 connect(m_reportDesigner, SIGNAL(itemInserted(QString)), this, SIGNAL(itemInserted(QString)));
170
171 m_scrollArea->setWidget(m_reportDesigner);
172
173 connect(m_reportDesigner, SIGNAL(propertySetChanged()), this, SLOT(slotDesignerPropertySetChanged()));
174 connect(m_reportDesigner, SIGNAL(dirty()), this, SLOT(setDirty()));
175
176 //Added default keyboard shortcuts for the actions
177 QShortcut *cutShortcut = new QShortcut(QKeySequence(QKeySequence::Cut), m_reportDesigner);
178 QShortcut *copyShortcut = new QShortcut(QKeySequence(QKeySequence::Copy), m_reportDesigner);
179 QShortcut *pasteShortcut = new QShortcut(QKeySequence(QKeySequence::Paste), m_reportDesigner);
180 QShortcut *deleteShortcut = new QShortcut(QKeySequence(QKeySequence::Delete), m_reportDesigner);
181
182 connect(cutShortcut, SIGNAL(activated()), m_reportDesigner, SLOT(slotEditCut()));
183 connect(copyShortcut, SIGNAL(activated()), m_reportDesigner, SLOT(slotEditCopy()));
184 connect(pasteShortcut, SIGNAL(activated()), m_reportDesigner, SLOT(slotEditPaste()));
185 connect(deleteShortcut, SIGNAL(activated()), m_reportDesigner, SLOT(slotEditDelete()));
186
187 //Edit Actions
188 connect(m_editCutAction, SIGNAL(triggered()), m_reportDesigner, SLOT(slotEditCut()));
189 connect(m_editCopyAction, SIGNAL(triggered()), m_reportDesigner, SLOT(slotEditCopy()));
190 connect(m_editPasteAction, SIGNAL(triggered()), m_reportDesigner, SLOT(slotEditPaste()));
191 connect(m_editDeleteAction, SIGNAL(triggered()), m_reportDesigner, SLOT(slotEditDelete()));
192
193 connect(m_editSectionAction, SIGNAL(triggered()), m_reportDesigner, SLOT(slotSectionEditor()));
194
195 //Raise/Lower
196 connect(m_itemRaiseAction, SIGNAL(triggered()), m_reportDesigner, SLOT(slotRaiseSelected()));
197 connect(m_itemLowerAction, SIGNAL(triggered()), m_reportDesigner, SLOT(slotLowerSelected()));
198 return true;
199 }
200
tempData() const201 KexiReportPartTempData* KexiReportDesignView::tempData() const
202 {
203 return static_cast<KexiReportPartTempData*>(window()->data());
204 }
205
slotDataSourceChanged()206 void KexiReportDesignView::slotDataSourceChanged()
207 {
208 if (m_sourceSelector->isSelectionValid()) {
209 m_reportDesigner->setDataSource(new KexiDBReportDataSource(
210 m_sourceSelector->selectedName(), m_sourceSelector->selectedPluginId(), tempData()));
211 tempData()->connectionDefinition = connectionData();
212 } else {
213 m_reportDesigner->setDataSource(nullptr);
214 tempData()->connectionDefinition = QDomElement();
215 }
216 setDirty(true);
217 }
218
triggerAction(const QString & action)219 void KexiReportDesignView::triggerAction(const QString &action)
220 {
221 m_reportDesigner->slotItem(action);
222 }
223
connectionData() const224 QDomElement KexiReportDesignView::connectionData() const
225 {
226 QDomDocument dd;
227 QDomElement conndata = dd.createElement("connection");
228 conndata.setAttribute("type", "internal"); // for backward compatibility, currently always
229 // internal, we used to have "external" in old Kexi
230 conndata.setAttribute("source", m_sourceSelector->selectedName());
231 conndata.setAttribute("class", m_sourceSelector->selectedPluginId());
232 return conndata;
233 }
234
setConnectionData(const QDomElement & c)235 void KexiReportDesignView::setConnectionData(const QDomElement &c)
236 {
237 //qDebug() << c;
238 if (c.attribute("type") == "internal") {
239 QString sourceClass(c.attribute("class"));
240 if (sourceClass != "org.kexi-project.table" && sourceClass != "org.kexi-project.query") {
241 sourceClass.clear(); // KexiDataSourceComboBox will try to find table, then query
242 }
243 m_sourceSelector->setDataSource(sourceClass, c.attribute("source"));
244 slotDataSourceChanged();
245 }
246 }
247