kword

KWPageManager.cpp

00001 /* This file is part of the KOffice project
00002  * Copyright (C) 2005 Thomas Zander <zander@kde.org>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; version 2.
00007 
00008  * This library is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011  * Library General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU Library General Public License
00014  * along with this library; see the file COPYING.LIB.  If not, write to
00015  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016  * Boston, MA 02110-1301, USA.
00017  */
00018 #include "KWPageManager.h"
00019 #include "KWPage.h"
00020 #include "KoRect.h"
00021 
00022 //#define DEBUG_PAGES
00023 
00024 KWPageManager::KWPageManager() {
00025     m_firstPage = 1;
00026     m_onlyAllowAppend = false;
00027     m_pageList.setAutoDelete(true);
00028     m_defaultPageLayout = KoPageLayout::standardLayout();
00029 }
00030 
00031 int KWPageManager::pageNumber(const KoRect &frame) const {
00032     int page=m_firstPage;
00033     double startOfpage = 0.0;
00034     QPtrListIterator<KWPage> pages(m_pageList);
00035     while(pages.current() && startOfpage < frame.top()) {
00036         startOfpage += pages.current()->height();
00037         if(startOfpage >= frame.top())
00038             break;
00039         page++;
00040         ++pages;
00041     }
00042     // Disable strict checks. Testcase: F10, drag rectangle, move the mouse under the bottom of the last page.
00043     // Instead of a bunch of warnings and making the insertion-rectangle disappear, we simply want to bound
00044     // the mouse position to the last page.
00045     if ( !pages.current() )
00046         page = m_firstPage + m_pageList.count() - 1;
00047 #if 0
00048     if(!pages.current() || frame.right() > pages.current()->width() ||
00049             frame.top() > pages.current()->height() + startOfpage) {
00050 #ifdef DEBUG_PAGES
00051     if(!pages.current())
00052         kdDebug(31001) << "  KWPageManager::pageNumber of "<< frame << " is too high, no page there\n";
00053     else if(frame.right() > pages.current()->width())
00054         kdDebug(31001) << "  KWPageManager::pageNumber right of "<< frame << " is out of bounds\n";
00055     else if(frame.top() > pages.current()->height() + startOfpage)
00056         kdDebug(31001) << "  KWPageManager::pageNumber "<< frame << " spans multiple pages\n";
00057 
00058 kdDebug(31001) << kdBacktrace() << endl;
00059 #endif
00060         return -1; // not inside the page...
00061     }
00062 #endif
00063     return page;
00064 }
00065 int KWPageManager::pageNumber(const KoPoint &point) const {
00066     return pageNumber(KoRect(point, point));
00067 }
00068 int KWPageManager::pageNumber(const double ptY) const {
00069     return pageNumber(KoRect(0, ptY, 0, 0));
00070 }
00071 int KWPageManager::pageNumber(const KoRect *rect) const {
00072     KoRect tmp(*rect);
00073     return pageNumber(tmp);
00074 }
00075 
00076 int KWPageManager::pageCount() const {
00077     return m_pageList.count();
00078 }
00079 
00080 KWPage* KWPageManager::page(int pageNum) const {
00081     QPtrListIterator<KWPage> pages(m_pageList);
00082     while(pages.current()) {
00083         if(pages.current()->pageNumber() == pageNum)
00084             return pages.current();
00085         ++pages;
00086     }
00087     kdWarning(31001) << "KWPageManager::page(" << pageNum << ") failed; Requested page does not exist ["<< m_firstPage << "-"<< lastPageNumber() << "]"<< endl;
00088 #ifdef DEBUG_PAGES
00089     kdDebug(31001) << kdBacktrace();
00090 #endif
00091     return 0;
00092 }
00093 KWPage* KWPageManager::page(const KoRect &frame) const {
00094     return page(pageNumber(frame));
00095 }
00096 KWPage* KWPageManager::page(const KoPoint &point) const {
00097     return page(pageNumber(point));
00098 }
00099 KWPage* KWPageManager::page(double ptY) const {
00100     return page(pageNumber(ptY));
00101 }
00102 KWPage* KWPageManager::page(const KoRect *rect) const {
00103     KoRect tmp(*rect);
00104     return page(tmp);
00105 }
00106 
00107 void KWPageManager::setStartPage(int startPage) {
00108     int offset = startPage - m_firstPage;
00109     bool switchSides = startPage % 2 != m_firstPage % 2;
00110     for(QPtrListIterator<KWPage> pages(m_pageList); pages.current(); ++pages) {
00111         KWPage *page = pages.current();
00112         page->m_pageNum = page->m_pageNum + offset;
00113         if(switchSides)
00114             page->m_pageSide = page->m_pageSide == KWPage::Left ? KWPage::Right : KWPage::Left;
00115     }
00116     m_firstPage = startPage;
00117 }
00118 
00119 int KWPageManager::lastPageNumber() const {
00120     return pageCount() + m_firstPage - 1;
00121 }
00122 
00123 KWPage* KWPageManager::insertPage(int index) {
00124     if(m_onlyAllowAppend)
00125         return appendPage();
00126     KWPage *page = new KWPage(this, QMIN( QMAX(index, m_firstPage), lastPageNumber()+1 ));
00127     QPtrListIterator<KWPage> pages(m_pageList);
00128     while(pages.current() && pages.current()->pageNumber() < index)
00129         ++pages;
00130     while(pages.current()) {
00131         pages.current()->m_pageNum++;
00132         ++pages;
00133     }
00134     m_pageList.inSort(page);
00135     return page;
00136 }
00137 
00138 KWPage* KWPageManager::appendPage() {
00139     KWPage *page = new KWPage(this, lastPageNumber() + 1);
00140     m_pageList.append(page);
00141     return page;
00142 }
00143 
00144 const KoPageLayout KWPageManager::pageLayout(int pageNumber) const {
00145     KoPageLayout lay = m_defaultPageLayout;
00146     if(pageNumber >= m_firstPage && pageNumber <= lastPageNumber()) {
00147         KWPage *page = this->page(pageNumber);
00148         lay.ptHeight = page->height();
00149         lay.ptWidth = page->width();
00150         lay.ptTop = page->topMargin();
00151         lay.ptLeft = page->leftMargin();
00152         lay.ptBottom = page->bottomMargin();
00153         lay.ptRight = page->rightMargin();
00154     }
00155     return lay;
00156 }
00157 
00158 double KWPageManager::topOfPage(int pageNum) const {
00159     return pageOffset(pageNum, false);
00160 }
00161 double KWPageManager::bottomOfPage(int pageNum) const {
00162     return pageOffset(pageNum, true);
00163 }
00164 
00165 double KWPageManager::pageOffset(int pageNum, bool bottom) const {
00166     if(pageNum < m_firstPage)
00167         return 0;
00168     QPtrListIterator<KWPage> pages(m_pageList);
00169     double offset = 0.0;
00170     while(pages.current()) {
00171         if(pages.current()->pageNumber() == pageNum) {
00172             if(bottom)
00173                 offset += pages.current()->height();
00174             break;
00175         }
00176         offset += pages.current()->height();
00177         ++pages;
00178     }
00179     return offset;
00180 }
00181 
00182 void KWPageManager::removePage(int pageNumber) {
00183     removePage(page(pageNumber));
00184 }
00185 void KWPageManager::removePage(KWPage *page) {
00186     if(!page)
00187         return;
00188     QPtrListIterator<KWPage> pages(m_pageList);
00189     while(pages.current() && pages.current()->pageNumber() <= page->pageNumber())
00190         ++pages;
00191     while(pages.current()) {
00192         pages.current()->m_pageNum--;
00193         ++pages;
00194     }
00195     // TODO make the deletion of object page occur in a single shot
00196     m_pageList.remove(page);
00197 }
00198 
00199 void KWPageManager::setDefaultPage(const KoPageLayout &layout) {
00200     m_defaultPageLayout = layout;
00201     // make sure we have 1 default, either pageBound or left/right bound.
00202     if(m_defaultPageLayout.ptLeft < 0 || m_defaultPageLayout.ptRight < 0) {
00203         m_defaultPageLayout.ptLeft = -1;
00204         m_defaultPageLayout.ptRight = -1;
00205     } else {
00206         m_defaultPageLayout.ptPageEdge = -1;
00207         m_defaultPageLayout.ptBindingSide = -1;
00208         m_defaultPageLayout.ptLeft = QMAX(m_defaultPageLayout.ptLeft, 0);
00209         m_defaultPageLayout.ptRight = QMAX(m_defaultPageLayout.ptRight, 0);
00210     }
00211     //kdDebug() << "setDefaultPage l:" << m_defaultPageLayout.ptLeft << ", r: " << m_defaultPageLayout.ptRight << ", a: " << m_defaultPageLayout.ptPageEdge << ", b: " << m_defaultPageLayout.ptBindingSide << endl;
00212 }
00213 
00214 KoPoint KWPageManager::clipToDocument(const KoPoint &point) {
00215     int page=m_firstPage;
00216     double startOfpage = 0.0;
00217     QPtrListIterator<KWPage> pages(m_pageList);
00218     while(pages.current()) {
00219         startOfpage += pages.current()->height();
00220         if(startOfpage >= point.y())
00221             break;
00222         page++;
00223         ++pages;
00224     }
00225     page = QMIN(page, lastPageNumber());
00226     KoRect rect = this->page(page)->rect();
00227     if(rect.contains(point))
00228         return point;
00229 
00230     KoPoint rc(point);
00231     if(rect.top() > rc.y())
00232         rc.setY(rect.top());
00233     else if(rect.bottom() < rc.y())
00234         rc.setY(rect.bottom());
00235 
00236     if(rect.left() > rc.x())
00237         rc.setX(rect.left());
00238     else if(rect.right() < rc.x())
00239         rc.setX(rect.right());
00240     return rc;
00241 }
00242 
00243 // **** PageList ****
00244 int KWPageManager::PageList::compareItems(QPtrCollection::Item a, QPtrCollection::Item b)
00245 {
00246     int pa = ((KWPage *)a)->pageNumber();
00247     int pb = ((KWPage *)b)->pageNumber();
00248     if (pa == pb) return 0;
00249     if (pa < pb) return -1;
00250     return 1;
00251 }
KDE Home | KDE Accessibility Home | Description of Access Keys