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