kword

KWPageManager.cpp
1/* This file is part of the KOffice project
2 * Copyright (C) 2005 Thomas Zander <zander@kde.org>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; version 2.
7
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Library General Public License for more details.
12 *
13 * You should have received a copy of the GNU Library General Public License
14 * along with this library; see the file COPYING.LIB. If not, write to
15 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301, USA.
17 */
18#include "KWPageManager.h"
19#include "KWPage.h"
20#include "KoRect.h"
21
22//#define DEBUG_PAGES
23
24KWPageManager::KWPageManager() {
25 m_firstPage = 1;
26 m_onlyAllowAppend = false;
27 m_pageList.setAutoDelete(true);
28 m_defaultPageLayout = KoPageLayout::standardLayout();
29}
30
31int KWPageManager::pageNumber(const KoRect &frame) const {
32 int page=m_firstPage;
33 double startOfpage = 0.0;
34 TQPtrListIterator<KWPage> pages(m_pageList);
35 while(pages.current() && startOfpage < frame.top()) {
36 startOfpage += pages.current()->height();
37 if(startOfpage >= frame.top())
38 break;
39 page++;
40 ++pages;
41 }
42 // Disable strict checks. Testcase: F10, drag rectangle, move the mouse under the bottom of the last page.
43 // Instead of a bunch of warnings and making the insertion-rectangle disappear, we simply want to bound
44 // the mouse position to the last page.
45 if ( !pages.current() )
46 page = m_firstPage + m_pageList.count() - 1;
47#if 0
48 if(!pages.current() || frame.right() > pages.current()->width() ||
49 frame.top() > pages.current()->height() + startOfpage) {
50#ifdef DEBUG_PAGES
51 if(!pages.current())
52 kdDebug(31001) << " KWPageManager::pageNumber of "<< frame << " is too high, no page there\n";
53 else if(frame.right() > pages.current()->width())
54 kdDebug(31001) << " KWPageManager::pageNumber right of "<< frame << " is out of bounds\n";
55 else if(frame.top() > pages.current()->height() + startOfpage)
56 kdDebug(31001) << " KWPageManager::pageNumber "<< frame << " spans multiple pages\n";
57
58kdDebug(31001) << kdBacktrace() << endl;
59#endif
60 return -1; // not inside the page...
61 }
62#endif
63 return page;
64}
65int KWPageManager::pageNumber(const KoPoint &point) const {
66 return pageNumber(KoRect(point, point));
67}
68int KWPageManager::pageNumber(const double ptY) const {
69 return pageNumber(KoRect(0, ptY, 0, 0));
70}
71int KWPageManager::pageNumber(const KoRect *rect) const {
72 KoRect tmp(*rect);
73 return pageNumber(tmp);
74}
75
77 return m_pageList.count();
78}
79
80KWPage* KWPageManager::page(int pageNum) const {
81 TQPtrListIterator<KWPage> pages(m_pageList);
82 while(pages.current()) {
83 if(pages.current()->pageNumber() == pageNum)
84 return pages.current();
85 ++pages;
86 }
87 kdWarning(31001) << "KWPageManager::page(" << pageNum << ") failed; Requested page does not exist ["<< m_firstPage << "-"<< lastPageNumber() << "]"<< endl;
88#ifdef DEBUG_PAGES
89 kdDebug(31001) << kdBacktrace();
90#endif
91 return 0;
92}
93KWPage* KWPageManager::page(const KoRect &frame) const {
94 return page(pageNumber(frame));
95}
96KWPage* KWPageManager::page(const KoPoint &point) const {
97 return page(pageNumber(point));
98}
99KWPage* KWPageManager::page(double ptY) const {
100 return page(pageNumber(ptY));
101}
102KWPage* KWPageManager::page(const KoRect *rect) const {
103 KoRect tmp(*rect);
104 return page(tmp);
105}
106
108 int offset = startPage - m_firstPage;
109 bool switchSides = startPage % 2 != m_firstPage % 2;
110 for(TQPtrListIterator<KWPage> pages(m_pageList); pages.current(); ++pages) {
111 KWPage *page = pages.current();
112 page->m_pageNum = page->m_pageNum + offset;
113 if(switchSides)
114 page->m_pageSide = page->m_pageSide == KWPage::Left ? KWPage::Right : KWPage::Left;
115 }
116 m_firstPage = startPage;
117}
118
120 return pageCount() + m_firstPage - 1;
121}
122
123KWPage* KWPageManager::insertPage(int index) {
124 if(m_onlyAllowAppend)
125 return appendPage();
126 KWPage *page = new KWPage(this, TQMIN( TQMAX(index, m_firstPage), lastPageNumber()+1 ));
127 TQPtrListIterator<KWPage> pages(m_pageList);
128 while(pages.current() && pages.current()->pageNumber() < index)
129 ++pages;
130 while(pages.current()) {
131 pages.current()->m_pageNum++;
132 ++pages;
133 }
134 m_pageList.inSort(page);
135 return page;
136}
137
139 KWPage *page = new KWPage(this, lastPageNumber() + 1);
140 m_pageList.append(page);
141 return page;
142}
143
144const KoPageLayout KWPageManager::pageLayout(int pageNumber) const {
145 KoPageLayout lay = m_defaultPageLayout;
146 if(pageNumber >= m_firstPage && pageNumber <= lastPageNumber()) {
147 KWPage *page = this->page(pageNumber);
148 lay.ptHeight = page->height();
149 lay.ptWidth = page->width();
150 lay.ptTop = page->topMargin();
151 lay.ptLeft = page->leftMargin();
152 lay.ptBottom = page->bottomMargin();
153 lay.ptRight = page->rightMargin();
154 }
155 return lay;
156}
157
158double KWPageManager::topOfPage(int pageNum) const {
159 return pageOffset(pageNum, false);
160}
161double KWPageManager::bottomOfPage(int pageNum) const {
162 return pageOffset(pageNum, true);
163}
164
165double KWPageManager::pageOffset(int pageNum, bool bottom) const {
166 if(pageNum < m_firstPage)
167 return 0;
168 TQPtrListIterator<KWPage> pages(m_pageList);
169 double offset = 0.0;
170 while(pages.current()) {
171 if(pages.current()->pageNumber() == pageNum) {
172 if(bottom)
173 offset += pages.current()->height();
174 break;
175 }
176 offset += pages.current()->height();
177 ++pages;
178 }
179 return offset;
180}
181
186 if(!page)
187 return;
188 TQPtrListIterator<KWPage> pages(m_pageList);
189 while(pages.current() && pages.current()->pageNumber() <= page->pageNumber())
190 ++pages;
191 while(pages.current()) {
192 pages.current()->m_pageNum--;
193 ++pages;
194 }
195 // TODO make the deletion of object page occur in a single shot
196 m_pageList.remove(page);
197}
198
199void KWPageManager::setDefaultPage(const KoPageLayout &layout) {
200 m_defaultPageLayout = layout;
201 // make sure we have 1 default, either pageBound or left/right bound.
202 if(m_defaultPageLayout.ptLeft < 0 || m_defaultPageLayout.ptRight < 0) {
203 m_defaultPageLayout.ptLeft = -1;
204 m_defaultPageLayout.ptRight = -1;
205 } else {
206 m_defaultPageLayout.ptPageEdge = -1;
207 m_defaultPageLayout.ptBindingSide = -1;
208 m_defaultPageLayout.ptLeft = TQMAX(m_defaultPageLayout.ptLeft, 0);
209 m_defaultPageLayout.ptRight = TQMAX(m_defaultPageLayout.ptRight, 0);
210 }
211 //kdDebug() << "setDefaultPage l:" << m_defaultPageLayout.ptLeft << ", r: " << m_defaultPageLayout.ptRight << ", a: " << m_defaultPageLayout.ptPageEdge << ", b: " << m_defaultPageLayout.ptBindingSide << endl;
212}
213
214KoPoint KWPageManager::clipToDocument(const KoPoint &point) {
215 int page=m_firstPage;
216 double startOfpage = 0.0;
217 TQPtrListIterator<KWPage> pages(m_pageList);
218 while(pages.current()) {
219 startOfpage += pages.current()->height();
220 if(startOfpage >= point.y())
221 break;
222 page++;
223 ++pages;
224 }
225 page = TQMIN(page, lastPageNumber());
226 KoRect rect = this->page(page)->rect();
227 if(rect.contains(point))
228 return point;
229
230 KoPoint rc(point);
231 if(rect.top() > rc.y())
232 rc.setY(rect.top());
233 else if(rect.bottom() < rc.y())
234 rc.setY(rect.bottom());
235
236 if(rect.left() > rc.x())
237 rc.setX(rect.left());
238 else if(rect.right() < rc.x())
239 rc.setX(rect.right());
240 return rc;
241}
242
243// **** PageList ****
244int KWPageManager::PageList::compareItems(TQPtrCollection::Item a, TQPtrCollection::Item b)
245{
246 int pa = ((KWPage *)a)->pageNumber();
247 int pb = ((KWPage *)b)->pageNumber();
248 if (pa == pb) return 0;
249 if (pa < pb) return -1;
250 return 1;
251}
const KoPageLayout pageLayout(int pageNumber) const
return the effective pageLayout of pageNumber combining the default and the page specific ones
double topOfPage(int pageNumber) const
Return the y-offset in this document of the top of page with pageNumber Note that pageNumber is NOT a...
KWPage * insertPage(int pageNumber)
Inserts a new page at the specified position in the document.
KoPoint clipToDocument(const KoPoint &point)
Returns the argument point, with altered coordinats if the point happens to be outside all pages.
void setStartPage(int startPage)
Set a new startpage for this document, renumbering all pages already added.
int pageNumber(const KoRect *rect) const
return pageNumber of frame, pagenumbers for a normal document start at 1.
KWPage * page(int pageNumber) const
return the KWPage of a specific page number. Returns 0 if page does not exist.
KWPage * appendPage()
Append a new page at the end of the document.
int pageCount() const
return total number of pages in this document.
void removePage(int pageNumber)
Remove the page with pageNumber renumbering all pages after pages already added.
double bottomOfPage(int pageNumber) const
Return the y-offset in this document of the bottom of page with pageNumber Note that pageNumber is NO...
int startPage() const
return the first pagenumber of this document
int lastPageNumber() const
return the highest page number we have in this document.
This class represents a printed page of the document.
Definition KWPage.h:30
const KoRect rect() const
return a KoRect with the (pt) sizes of this page. Margins are ignored for this function.
Definition KWPage.cpp:137