1 /* This file is part of the KDE project
2 * Copyright (C) 2001-2007 by OpenMFG, LLC (info@openmfg.com)
3 * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk)
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "KReportDesignerSectionDetail.h"
20 #include "KReportDesignerSectionDetailGroup.h"
21 #include "KReportDesignerSection.h"
22 #include "KReportDesigner.h"
23 #include "KReportUtils.h"
24 #include "kreport_debug.h"
25
26 #include <QVBoxLayout>
27 #include <QDomDocument>
28
29 //! @internal
30 class Q_DECL_HIDDEN KReportDesignerSectionDetail::Private
31 {
32 public:
Private()33 explicit Private() {}
34
~Private()35 ~Private()
36 {
37 }
38
39 QString name;
40 KReportDesignerSection *detail;
41 KReportDesigner *reportDesigner;
42 QList<KReportDesignerSectionDetailGroup*> groupList;
43 QVBoxLayout *vboxlayout;
44 KReportDesignerSectionDetail::PageBreak pageBreak = KReportDesignerSectionDetail::PageBreak::None;
45 };
46
KReportDesignerSectionDetail(KReportDesigner * rptdes)47 KReportDesignerSectionDetail::KReportDesignerSectionDetail(KReportDesigner * rptdes)
48 : QWidget(rptdes)
49 , d(new Private())
50 {
51 Q_ASSERT(rptdes);
52 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
53 d->vboxlayout = new QVBoxLayout(this);
54 d->vboxlayout->setSpacing(0);
55 d->vboxlayout->setMargin(0);
56 d->reportDesigner = rptdes;
57 d->detail = d->reportDesigner->createSection();
58 d->vboxlayout->addWidget(d->detail);
59
60 this->setLayout(d->vboxlayout);
61 }
62
~KReportDesignerSectionDetail()63 KReportDesignerSectionDetail::~KReportDesignerSectionDetail()
64 {
65 delete d;
66 }
67
pageBreak() const68 KReportDesignerSectionDetail::PageBreak KReportDesignerSectionDetail::pageBreak() const
69 {
70 return d->pageBreak;
71 }
setPageBreak(PageBreak pb)72 void KReportDesignerSectionDetail::setPageBreak(PageBreak pb)
73 {
74 d->pageBreak = pb;
75 }
76
detailSection() const77 KReportDesignerSection * KReportDesignerSectionDetail::detailSection() const
78 {
79 return d->detail;
80 }
81
buildXML(QDomDocument * doc,QDomElement * section)82 void KReportDesignerSectionDetail::buildXML(QDomDocument *doc, QDomElement *section)
83 {
84 if (pageBreak() != KReportDesignerSectionDetail::PageBreak::None) {
85 QDomElement spagebreak = doc->createElement(QLatin1String("pagebreak"));
86 if (pageBreak() == KReportDesignerSectionDetail::PageBreak::AtEnd)
87 spagebreak.setAttribute(QLatin1String("when"), QLatin1String("at end"));
88 section->appendChild(spagebreak);
89 }
90
91 foreach(KReportDesignerSectionDetailGroup* rsdg, d->groupList) {
92 rsdg->buildXML(doc, section);
93 }
94
95 // detail section
96 QDomElement gdetail = doc->createElement(QLatin1String("report:section"));
97 gdetail.setAttribute(QLatin1String("report:section-type"), QLatin1String("detail"));
98 d->detail->buildXML(doc, &gdetail);
99 section->appendChild(gdetail);
100 }
101
initFromXML(QDomNode * section)102 void KReportDesignerSectionDetail::initFromXML(QDomNode *section)
103 {
104 QDomNodeList nl = section->childNodes();
105 QDomNode node;
106 QString n;
107
108 for (int i = 0; i < nl.count(); i++) {
109 node = nl.item(i);
110 n = node.nodeName();
111 //kreportDebug() << n;
112 if (n == QLatin1String("pagebreak")) {
113 QDomElement eThis = node.toElement();
114 if (eThis.attribute(QLatin1String("when")) == QLatin1String("at end"))
115 setPageBreak(PageBreak::AtEnd);
116 } else if (n == QLatin1String("report:group")) {
117 KReportDesignerSectionDetailGroup * rsdg = new KReportDesignerSectionDetailGroup(QLatin1String("unnamed"), this, this);
118 rsdg->initFromXML( node.toElement() );
119 insertGroupSection(groupSectionCount(), rsdg);
120 } else if (n == QLatin1String("report:section")
121 && KReportUtils::readSectionTypeNameAttribute(node.toElement()) == QLatin1String("detail"))
122 {
123 // kreportDebug() << "Creating detail section";
124 d->detail->initFromXML(node);
125 } else {
126 // unknown element
127 kreportWarning() << "while parsing section encountered and unknown element: " << n;
128 }
129 }
130
131 }
132
reportDesigner() const133 KReportDesigner * KReportDesignerSectionDetail::reportDesigner() const
134 {
135 return d->reportDesigner;
136 }
137
groupSectionCount() const138 int KReportDesignerSectionDetail::groupSectionCount() const
139 {
140 return d->groupList.count();
141 }
142
groupSection(int i) const143 KReportDesignerSectionDetailGroup * KReportDesignerSectionDetail::groupSection(int i) const
144 {
145 return d->groupList.at(i);
146 }
147
insertGroupSection(int idx,KReportDesignerSectionDetailGroup * rsd)148 void KReportDesignerSectionDetail::insertGroupSection(int idx, KReportDesignerSectionDetailGroup * rsd)
149 {
150 d->groupList.insert(idx, rsd);
151
152 rsd->groupHeader()->setParent(this);
153 rsd->groupFooter()->setParent(this);
154
155 idx = 0;
156 int gi = 0;
157 for (gi = 0; gi < (int) d->groupList.count(); gi++) {
158 rsd = d->groupList.at(gi);
159 d->vboxlayout->removeWidget(rsd->groupHeader());
160 d->vboxlayout->insertWidget(idx, rsd->groupHeader());
161 idx++;
162 }
163 d->vboxlayout->removeWidget(d->detail);
164 d->vboxlayout->insertWidget(idx, d->detail);
165 idx++;
166 for (gi = ((int) d->groupList.count() - 1); gi >= 0; --gi) {
167 rsd = d->groupList.at(gi);
168 d->vboxlayout->removeWidget(rsd->groupFooter());
169 d->vboxlayout->insertWidget(idx, rsd->groupFooter());
170 idx++;
171 }
172
173 if (d->reportDesigner) d->reportDesigner->setModified(true);
174 adjustSize();
175 }
176
indexOfGroupSection(const QString & column) const177 int KReportDesignerSectionDetail::indexOfGroupSection(const QString & column) const
178 {
179 // find the item by its name
180 for (uint i = 0; i < (uint)d->groupList.count(); i++) {
181 KReportDesignerSectionDetailGroup * rsd = d->groupList.at(i);
182 if (column == rsd->column()) return i;
183 }
184 return -1;
185 }
186
removeGroupSection(int idx,bool del)187 void KReportDesignerSectionDetail::removeGroupSection(int idx, bool del)
188 {
189 KReportDesignerSectionDetailGroup * rsd = d->groupList.at(idx);
190
191 d->vboxlayout->removeWidget(rsd->groupHeader());
192 d->vboxlayout->removeWidget(rsd->groupFooter());
193
194 d->groupList.removeAt(idx);
195
196 if (d->reportDesigner) d->reportDesigner->setModified(true);
197 if (del) delete rsd;
198 adjustSize();
199 }
200
sizeHint() const201 QSize KReportDesignerSectionDetail::sizeHint() const
202 {
203 QSize s;
204 foreach(KReportDesignerSectionDetailGroup* rsdg, d->groupList) {
205 if (rsdg->groupHeaderVisible()) s += rsdg->groupHeader()->size();
206 if (rsdg->groupFooterVisible()) s += rsdg->groupFooter()->size();
207 }
208 return s += d->detail->size();
209 }
210
setSectionCursor(const QCursor & c)211 void KReportDesignerSectionDetail::setSectionCursor(const QCursor& c)
212 {
213 if (d->detail)
214 d->detail->setSectionCursor(c);
215 foreach(KReportDesignerSectionDetailGroup* rsdg, d->groupList) {
216 if (rsdg->groupHeader())
217 rsdg->groupHeader()->setSectionCursor(c);
218 if (rsdg->groupFooter())
219 rsdg->groupFooter()->setSectionCursor(c);
220 }
221 }
222
unsetSectionCursor()223 void KReportDesignerSectionDetail::unsetSectionCursor()
224 {
225 if (d->detail)
226 d->detail->unsetSectionCursor();
227
228 foreach(KReportDesignerSectionDetailGroup* rsdg, d->groupList) {
229 if (rsdg->groupHeader())
230 rsdg->groupHeader()->unsetSectionCursor();
231 if (rsdg->groupFooter())
232 rsdg->groupFooter()->unsetSectionCursor();
233 }
234 }
235