• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

Kate

kateprinter.cpp

Go to the documentation of this file.
00001 /*
00002  *  This file is part of the KDE libraries
00003  *  Copyright (c) 2001-2002 Michael Goffioul <kdeprint@swing.be>
00004  *  Complete rewrite on Sat Jun 15 2002 (c) Anders Lund <anders@alweb.dk>
00005  *  Copyright (c) 2002, 2003 Anders Lund <anders@alweb.dk>
00006  *
00007  *  This library is free software; you can redistribute it and/or
00008  *  modify it under the terms of the GNU Library General Public
00009  *  License version 2 as published by the Free Software Foundation.
00010  *
00011  *  This library is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *  Library General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU Library General Public License
00017  *  along with this library; see the file COPYING.LIB.  If not, write to
00018  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  *  Boston, MA 02110-1301, USA.
00020  **/
00021 
00022 #include "kateprinter.h"
00023 
00024 #include "kateconfig.h"
00025 #include "katedocument.h"
00026 #include "kateglobal.h"
00027 #include "katehighlight.h"
00028 #include "katetextlayout.h"
00029 #include "katerenderer.h"
00030 #include "kateschema.h"
00031 #include "katetextline.h"
00032 #include "kateview.h"
00033 
00034 #include <kapplication.h>
00035 #include <kcolorbutton.h>
00036 #include <kdebug.h>
00037 #include <kdialog.h> // for spacingHint()
00038 #include <kfontdialog.h>
00039 #include <klocale.h>
00040 #include <kdeprintdialog.h>
00041 #include <kurl.h>
00042 #include <kuser.h> // for loginName
00043 
00044 #include <QtGui/QPainter>
00045 #include <QtGui/QCheckBox>
00046 #include <QtGui/QComboBox>
00047 #include <QtGui/QGroupBox>
00048 #include <QtGui/QPrintDialog>
00049 #include <QtGui/QPrinter>
00050 #include <QtGui/QApplication>
00051 
00052 #include <QtGui/QLabel>
00053 #include <QtGui/QLayout>
00054 #include <QtGui/QLineEdit>
00055 #include <QtGui/QSpinBox>
00056 #include <QtCore/QStringList>
00057 #include <kvbox.h>
00058 
00059 //BEGIN KatePrinter
00060 bool KatePrinter::print (KateDocument *doc)
00061 {
00062 
00063   QPrinter printer;
00064 
00065   // docname is now always there, including the right Untitled name
00066   printer.setDocName(doc->documentName());
00067 
00068   KatePrintTextSettings *kpts = new KatePrintTextSettings;
00069   KatePrintHeaderFooter *kphf = new KatePrintHeaderFooter;
00070   KatePrintLayout *kpl = new KatePrintLayout;
00071 
00072   QList<QWidget*> tabs;
00073   tabs << kpts;
00074   tabs << kphf;
00075   tabs << kpl;
00076 
00077   QWidget *parentWidget=doc->widget();
00078 
00079   if ( !parentWidget )
00080     parentWidget=QApplication::activeWindow();
00081 
00082   QPrintDialog *printDialog = KdePrint::createPrintDialog(&printer, tabs, parentWidget);
00083 
00084   if ( doc->activeView()->selection() )
00085     printDialog->addEnabledOption(QAbstractPrintDialog::PrintSelection);
00086 
00087   if ( printDialog->exec() )
00088   {
00089     KateRenderer renderer(doc, doc->activeKateView());
00090     renderer.config()->setSchema (kpl->colorScheme());
00091     renderer.setPrinterFriendly(true);
00092 
00093     QPainter paint( &printer );
00094     /*
00095      *        We work in tree cycles:
00096      *        1) initialize variables and retrieve print settings
00097      *        2) prepare data according to those settings
00098      *        3) draw to the printer
00099      */
00100     uint pdmWidth = printer.width();
00101     uint pdmHeight = printer.height();
00102     int y = 0;
00103     uint xstart = 0; // beginning point for painting lines
00104     uint lineCount = 0;
00105     uint maxWidth = pdmWidth;
00106     int headerWidth = pdmWidth;
00107     int startCol = 0;
00108     int endCol = 0;
00109     bool pageStarted = true;
00110     int remainder = 0; // remaining sublines from a wrapped line (for the top of a new page)
00111 
00112     // Text Settings Page
00113     bool selectionOnly = (printDialog->printRange() == QAbstractPrintDialog::Selection);
00114     bool useGuide = kpts->printGuide();
00115 
00116     bool printLineNumbers = kpts->printLineNumbers();
00117     uint lineNumberWidth( 0 );
00118 
00119     // Header/Footer Page
00120     QFont headerFont(kphf->font()); // used for header/footer
00121 
00122     bool useHeader = kphf->useHeader();
00123     QColor headerBgColor(kphf->headerBackground());
00124     QColor headerFgColor(kphf->headerForeground());
00125     uint headerHeight( 0 ); // further init only if needed
00126     QStringList headerTagList; // do
00127     bool headerDrawBg = false; // do
00128 
00129     bool useFooter = kphf->useFooter();
00130     QColor footerBgColor(kphf->footerBackground());
00131     QColor footerFgColor(kphf->footerForeground());
00132     uint footerHeight( 0 ); // further init only if needed
00133     QStringList footerTagList; // do
00134     bool footerDrawBg = false; // do
00135 
00136     // Layout Page
00137     renderer.config()->setSchema( kpl->colorScheme() );
00138     bool useBackground = kpl->useBackground();
00139     bool useBox = kpl->useBox();
00140     int boxWidth(kpl->boxWidth());
00141     QColor boxColor(kpl->boxColor());
00142     int innerMargin = useBox ? kpl->boxMargin() : 6;
00143 
00144     // Post initialization
00145     int maxHeight = (useBox ? pdmHeight-innerMargin : pdmHeight);
00146     uint currentPage( 1 );
00147     uint lastline = doc->lastLine(); // necessary to print selection only
00148     uint firstline( 0 );
00149     int fontHeight = renderer.fontHeight();
00150     KTextEditor::Range selectionRange;
00151 
00152     /*
00153     *        Now on for preparations...
00154     *        during preparations, variable names starting with a "_" means
00155     *        those variables are local to the enclosing block.
00156     */
00157     {
00158       if ( selectionOnly )
00159       {
00160         // set a line range from the first selected line to the last
00161         selectionRange = doc->activeView()->selectionRange();
00162         firstline = selectionRange.start().line();
00163         lastline = selectionRange.end().line();
00164         lineCount = firstline;
00165       }
00166 
00167       if ( printLineNumbers )
00168       {
00169         // figure out the horiizontal space required
00170         QString s( QString("%1 ").arg( doc->lines() ) );
00171         s.fill('5', -1); // some non-fixed fonts haven't equally wide numbers
00172         // FIXME calculate which is actually the widest...
00173         lineNumberWidth = renderer.currentFontMetrics().width( s );
00174         // a small space between the line numbers and the text
00175         int _adj = renderer.currentFontMetrics().width( "5" );
00176         // adjust available width and set horizontal start point for data
00177         maxWidth -= (lineNumberWidth + _adj);
00178         xstart += lineNumberWidth + _adj;
00179       }
00180 
00181       if ( useHeader || useFooter )
00182       {
00183         // Set up a tag map
00184         // This retrieves all tags, ued or not, but
00185         // none of theese operations should be expensive,
00186         // and searcing each tag in the format strings is avoided.
00187         QDateTime dt = QDateTime::currentDateTime();
00188         QMap<QString,QString> tags;
00189 
00190         KUser u (KUser::UseRealUserID);
00191         tags["u"] = u.loginName();
00192 
00193         tags["d"] = KGlobal::locale()->formatDateTime(dt, KLocale::ShortDate);
00194         tags["D"] =  KGlobal::locale()->formatDateTime(dt, KLocale::LongDate);
00195         tags["h"] =  KGlobal::locale()->formatTime(dt.time(), false);
00196         tags["y"] =  KGlobal::locale()->formatDate(dt.date(), KLocale::ShortDate);
00197         tags["Y"] =  KGlobal::locale()->formatDate(dt.date(), KLocale::LongDate);
00198         tags["f"] =  doc->url().fileName();
00199         tags["U"] =  doc->url().prettyUrl();
00200         if ( selectionOnly )
00201         {
00202           QString s( i18n("(Selection of) ") );
00203           tags["f"].prepend( s );
00204           tags["U"].prepend( s );
00205         }
00206 
00207         QRegExp reTags( "%([dDfUhuyY])" ); // TODO tjeck for "%%<TAG>"
00208 
00209         if (useHeader)
00210         {
00211           headerDrawBg = kphf->useHeaderBackground();
00212           headerHeight = QFontMetrics( headerFont ).height();
00213           if ( useBox || headerDrawBg )
00214             headerHeight += innerMargin * 2;
00215           else
00216             headerHeight += 1 + QFontMetrics( headerFont ).leading();
00217 
00218           headerTagList = kphf->headerFormat();
00219           QMutableStringListIterator it(headerTagList);
00220           while ( it.hasNext() ) {
00221             QString tag = it.next();
00222             int pos = reTags.indexIn( tag );
00223             QString rep;
00224             while ( pos > -1 )
00225             {
00226               rep = tags[reTags.cap( 1 )];
00227               tag.replace( (uint)pos, 2, rep );
00228               pos += rep.length();
00229               pos = reTags.indexIn( tag, pos );
00230             }
00231             it.setValue( tag );
00232           }
00233 
00234           if (!headerBgColor.isValid())
00235             headerBgColor = Qt::lightGray;
00236           if (!headerFgColor.isValid())
00237             headerFgColor = Qt::black;
00238         }
00239 
00240         if (useFooter)
00241         {
00242           footerDrawBg = kphf->useFooterBackground();
00243           footerHeight = QFontMetrics( headerFont ).height();
00244           if ( useBox || footerDrawBg )
00245             footerHeight += 2*innerMargin;
00246           else
00247             footerHeight += 1; // line only
00248 
00249           footerTagList = kphf->footerFormat();
00250           QMutableStringListIterator it(footerTagList);
00251           while ( it.hasNext() ) {
00252             QString tag = it.next();
00253             int pos = reTags.indexIn( tag );
00254             QString rep;
00255             while ( pos > -1 )
00256             {
00257               rep = tags[reTags.cap( 1 )];
00258               tag.replace( (uint)pos, 2, rep );
00259               pos += rep.length();
00260               pos = reTags.indexIn( tag, pos );
00261             }
00262             it.setValue( tag );
00263           }
00264 
00265           if (!footerBgColor.isValid())
00266             footerBgColor = Qt::lightGray;
00267           if (!footerFgColor.isValid())
00268             footerFgColor = Qt::black;
00269           // adjust maxheight, so we can know when/where to print footer
00270           maxHeight -= footerHeight;
00271         }
00272       } // if ( useHeader || useFooter )
00273 
00274       if ( useBackground )
00275       {
00276         if ( ! useBox )
00277         {
00278           xstart += innerMargin;
00279           maxWidth -= innerMargin * 2;
00280         }
00281       }
00282 
00283       if ( useBox )
00284       {
00285         if (!boxColor.isValid())
00286           boxColor = Qt::black;
00287         if (boxWidth < 1) // shouldn't be pssible no more!
00288           boxWidth = 1;
00289         // set maxwidth to something sensible
00290         maxWidth -= ( ( boxWidth + innerMargin )  * 2 );
00291         xstart += boxWidth + innerMargin;
00292         // maxheight too..
00293         maxHeight -= boxWidth;
00294       }
00295       else
00296         boxWidth = 0;
00297 
00298       // now that we know the vertical amount of space needed,
00299       // it is possible to calculate the total number of pages
00300       // if needed, that is if any header/footer tag contains "%P".
00301 #if 0
00302       if ( !headerTagList.filter("%P").isEmpty() || !footerTagList.filter("%P").isEmpty() )
00303       {
00304         kDebug(13020)<<"'%P' found! calculating number of pages...";
00305         uint _pages = 0;
00306         uint _ph = maxHeight;
00307         if ( useHeader )
00308           _ph -= ( headerHeight + innerMargin );
00309         if ( useFooter )
00310           _ph -= innerMargin;
00311         int _lpp = _ph / fontHeight;
00312         uint _lt = 0, _c=0;
00313 
00314         // add space for guide if required
00315 //         if ( useGuide )
00316 //           _lt += (guideHeight + (fontHeight /2)) / fontHeight;
00317         long _lw;
00318         for ( uint i = firstline; i < lastline; i++ )
00319         {
00320           //FIXME: _lw = renderer.textWidth( doc->kateTextLine( i ), -1 );
00321           _lw = 80 * renderer.spaceWidth(); //FIXME: just a stand-in
00322           while ( _lw >= 0 )
00323           {
00324             _c++;
00325             _lt++;
00326             if ( (int)_lt  == _lpp )
00327             {
00328               _pages++;
00329               _lt = 0;
00330             }
00331             _lw -= maxWidth;
00332             if ( ! _lw ) _lw--; // skip lines matching exactly!
00333           }
00334         }
00335         if ( _lt ) _pages++; // last page
00336 
00337         // substitute both tag lists
00338         QString re("%P");
00339         QStringList::Iterator it;
00340         for ( it=headerTagList.begin(); it!=headerTagList.end(); ++it )
00341           (*it).replace( re, QString( "%1" ).arg( _pages ) );
00342         for ( it=footerTagList.begin(); it!=footerTagList.end(); ++it )
00343           (*it).replace( re, QString( "%1" ).arg( _pages ) );
00344       }
00345 #endif
00346     } // end prepare block
00347 
00348      /*
00349         On to draw something :-)
00350      */
00351     while (  lineCount <= lastline  )
00352     {
00353       startCol = 0;
00354       endCol = 0;
00355 
00356       if ( y + fontHeight >= maxHeight )
00357       {
00358         kDebug(13020)<<"Starting new page,"<<lineCount<<"lines up to now.";
00359         printer.newPage();
00360         paint.resetTransform();
00361         currentPage++;
00362         pageStarted = true;
00363         y=0;
00364       }
00365 
00366       if ( pageStarted )
00367       {
00368         if ( useHeader )
00369         {
00370           paint.setPen(headerFgColor);
00371           paint.setFont(headerFont);
00372           if ( headerDrawBg )
00373             paint.fillRect(0, 0, headerWidth, headerHeight, headerBgColor);
00374           if (headerTagList.count() == 3)
00375           {
00376             int valign = ( (useBox||headerDrawBg||useBackground) ?
00377             Qt::AlignVCenter : Qt::AlignTop );
00378             int align = valign|Qt::AlignLeft;
00379             int marg = ( useBox || headerDrawBg ) ? innerMargin : 0;
00380             if ( useBox ) marg += boxWidth;
00381             QString s;
00382             for (int i=0; i<3; i++)
00383             {
00384               s = headerTagList[i];
00385               if (s.indexOf("%p") != -1) s.replace("%p", QString::number(currentPage));
00386               paint.drawText(marg, 0, headerWidth-(marg*2), headerHeight, align, s);
00387               align = valign|(i == 0 ? Qt::AlignHCenter : Qt::AlignRight);
00388             }
00389           }
00390           if ( ! ( headerDrawBg || useBox || useBackground ) ) // draw a 1 px (!?) line to separate header from contents
00391           {
00392             paint.drawLine( 0, headerHeight-1, headerWidth, headerHeight-1 );
00393             //y += 1; now included in headerHeight
00394           }
00395           y += headerHeight + innerMargin;
00396         }
00397 
00398         if ( useFooter )
00399         {
00400           paint.setPen(footerFgColor);
00401           if ( ! ( footerDrawBg || useBox || useBackground ) ) // draw a 1 px (!?) line to separate footer from contents
00402             paint.drawLine( 0, maxHeight + innerMargin - 1, headerWidth, maxHeight + innerMargin - 1 );
00403           if ( footerDrawBg )
00404             paint.fillRect(0, maxHeight+innerMargin+boxWidth, headerWidth, footerHeight, footerBgColor);
00405           if (footerTagList.count() == 3)
00406           {
00407             int align = Qt::AlignVCenter|Qt::AlignLeft;
00408             int marg = ( useBox || footerDrawBg ) ? innerMargin : 0;
00409             if ( useBox ) marg += boxWidth;
00410             QString s;
00411             for (int i=0; i<3; i++)
00412             {
00413               s = footerTagList[i];
00414               if (s.indexOf("%p") != -1) s.replace("%p", QString::number(currentPage));
00415               paint.drawText(marg, maxHeight+innerMargin, headerWidth-(marg*2), footerHeight, align, s);
00416               align = Qt::AlignVCenter|(i == 0 ? Qt::AlignHCenter : Qt::AlignRight);
00417             }
00418           }
00419         } // done footer
00420 
00421         if ( useBackground )
00422         {
00423           // If we have a box, or the header/footer has backgrounds, we want to paint
00424           // to the border of those. Otherwise just the contents area.
00425           int _y = y, _h = maxHeight - y;
00426           if ( useBox )
00427           {
00428             _y -= innerMargin;
00429             _h += 2 * innerMargin;
00430           }
00431           else
00432           {
00433             if ( headerDrawBg )
00434             {
00435               _y -= innerMargin;
00436               _h += innerMargin;
00437             }
00438             if ( footerDrawBg )
00439             {
00440               _h += innerMargin;
00441             }
00442           }
00443           paint.fillRect( 0, _y, pdmWidth, _h, renderer.config()->backgroundColor());
00444         }
00445 
00446         if ( useBox )
00447         {
00448           paint.setPen(QPen(boxColor, boxWidth));
00449           paint.drawRect(0, 0, pdmWidth, pdmHeight);
00450           if (useHeader)
00451             paint.drawLine(0, headerHeight, headerWidth, headerHeight);
00452           else
00453             y += innerMargin;
00454 
00455           if ( useFooter ) // drawline is not trustable, grr.
00456             paint.fillRect( 0, maxHeight+innerMargin, headerWidth, boxWidth, boxColor );
00457         }
00458 
00459         if ( useGuide && currentPage == 1 )
00460         {  // FIXME - this may span more pages...
00461           // draw a box unless we have boxes, in which case we end with a box line
00462           int _ystart = y;
00463           QString _hlName = doc->highlight()->name();
00464 
00465           QList<KateExtendedAttribute::Ptr> _attributes; // list of highlight attributes for the legend
00466           doc->highlight()->getKateExtendedAttributeList(kpl->colorScheme(), _attributes);
00467 
00468           KateAttributeList _defaultAttributes;
00469           KateHlManager::self()->getDefaults ( renderer.config()->schema(), _defaultAttributes );
00470 
00471           QColor _defaultPen = _defaultAttributes.at(0)->foreground().color();
00472           paint.setPen(_defaultPen);
00473           paint.setBrush(_defaultPen);
00474 
00475           int _marg = 0;
00476           if ( useBox )
00477             _marg += (2*boxWidth) + (2*innerMargin);
00478           else
00479           {
00480             if ( useBackground )
00481               _marg += 2*innerMargin;
00482             _marg += 1;
00483             y += 1 + innerMargin;
00484           }
00485 
00486           // draw a title string
00487           QFont _titleFont = renderer.config()->font();
00488           _titleFont.setBold(true);
00489           paint.setFont( _titleFont );
00490           QRect _r;
00491           paint.drawText( QRect(_marg, y, pdmWidth-(2*_marg), maxHeight - y),
00492             Qt::AlignTop|Qt::AlignHCenter,
00493             i18n("Typographical Conventions for %1", _hlName ), &_r );
00494           int _w = pdmWidth - (_marg*2) - (innerMargin*2);
00495           int _x = _marg + innerMargin;
00496           y += _r.height() + innerMargin;
00497           paint.drawLine( _x, y, _x + _w, y );
00498           y += 1 + innerMargin;
00499 
00500           int _widest( 0 );
00501           foreach (KateExtendedAttribute::Ptr attribute, _attributes)
00502             _widest = qMax(QFontMetrics(attribute->font()).width(attribute->name().section(':',1,1)), _widest);
00503 
00504           int _guideCols = _w/( _widest + innerMargin );
00505 
00506           // draw attrib names using their styles
00507           int _cw = _w/_guideCols;
00508           int _i(0);
00509 
00510           _titleFont.setUnderline(true);
00511           QString _currentHlName;
00512           foreach (KateExtendedAttribute::Ptr attribute, _attributes)
00513           {
00514             QString _hl = attribute->name().section(':',0,0);
00515             QString _name = attribute->name().section(':',1,1);
00516             if ( _hl != _hlName && _hl != _currentHlName ) {
00517               _currentHlName = _hl;
00518               if ( _i%_guideCols )
00519                 y += fontHeight;
00520               y += innerMargin;
00521               paint.setFont(_titleFont);
00522               paint.setPen(_defaultPen);
00523               paint.drawText( _x, y, _w, fontHeight, Qt::AlignTop, _hl + ' ' + i18n("text") );
00524               y += fontHeight;
00525               _i = 0;
00526             }
00527 
00528             KTextEditor::Attribute _attr =  *_defaultAttributes[attribute->defaultStyleIndex()];
00529             _attr += *attribute;
00530             paint.setPen( _attr.foreground().color() );
00531             paint.setFont( _attr.font() );
00532 
00533             if (_attr.hasProperty(QTextFormat::BackgroundBrush) ) {
00534               QRect _rect = QFontMetrics(_attr.font()).boundingRect(_name);
00535               _rect.moveTo(_x + ((_i%_guideCols)*_cw), y);
00536                paint.fillRect(_rect, _attr.background() );
00537             }
00538 
00539             paint.drawText(( _x + ((_i%_guideCols)*_cw)), y, _cw, fontHeight, Qt::AlignTop, _name );
00540 
00541             _i++;
00542             if ( _i && ! ( _i%_guideCols ) )
00543               y += fontHeight;
00544           }
00545 
00546           if ( _i%_guideCols )
00547             y += fontHeight;// last row not full
00548 
00549           // draw a box around the legend
00550           paint.setPen ( _defaultPen );
00551           if ( useBox )
00552             paint.fillRect( 0, y+innerMargin, headerWidth, boxWidth, boxColor );
00553           else
00554           {
00555             _marg -=1;
00556             paint.setBrush(QBrush());
00557             paint.drawRect( _marg, _ystart, pdmWidth-(2*_marg), y-_ystart+innerMargin );
00558           }
00559 
00560           y += ( useBox ? boxWidth : 1 ) + (innerMargin*2);
00561         } // useGuide
00562 
00563         paint.translate(xstart,y);
00564         pageStarted = false;
00565       } // pageStarted; move on to contents:)
00566 
00567       if ( printLineNumbers /*&& ! startCol*/ ) // don't repeat!
00568       {
00569         paint.setFont( renderer.config()->font() );
00570         paint.setPen( renderer.config()->lineNumberColor() );
00571         paint.drawText( (( useBox || useBackground ) ? innerMargin : 0)-xstart, 0,
00572                     lineNumberWidth, fontHeight,
00573                     Qt::AlignRight, QString("%1").arg( lineCount + 1 ) );
00574       }
00575 
00576       // HA! this is where we print [part of] a line ;]]
00577       // FIXME Convert this function + related functionality to a separate KatePrintView
00578       KateLineLayout range(doc);
00579       range.setLine(lineCount);
00580       KateLineLayoutPtr *rangeptr = new KateLineLayoutPtr(&range);
00581       renderer.layoutLine(*rangeptr, (int)maxWidth, false);
00582 
00583       // selectionOnly: clip non-selection parts and adjust painter position if needed
00584       int _xadjust = 0;
00585       if (selectionOnly) {
00586         if (doc->activeView()->blockSelection()) {
00587           int _x = renderer.cursorToX((*rangeptr)->viewLine(0), selectionRange.start());
00588           int _x1 = renderer.cursorToX((*rangeptr)->viewLine((*rangeptr)->viewLineCount()-1), selectionRange.end());
00589            _xadjust = _x;
00590            paint.translate(-_xadjust, 0);
00591           paint.setClipRegion(QRegion( _x, 0, _x1 - _x, (*rangeptr)->viewLineCount()*fontHeight));
00592         }
00593 
00594         else if (lineCount == firstline || lineCount == lastline) {
00595           QRegion region(0, 0, maxWidth, (*rangeptr)->viewLineCount()*fontHeight);
00596 
00597           if ( lineCount == firstline) {
00598             region = region.subtracted(QRegion(0, 0, renderer.cursorToX((*rangeptr)->viewLine(0), selectionRange.start()), fontHeight));
00599           }
00600 
00601           if (lineCount == lastline) {
00602             int _x = renderer.cursorToX((*rangeptr)->viewLine((*rangeptr)->viewLineCount()-1), selectionRange.end());
00603             region = region.subtracted(QRegion(_x, 0, maxWidth-_x, fontHeight));
00604           }
00605 
00606           paint.setClipRegion(region);
00607         }
00608       }
00609 
00610       // If the line is too long (too many 'viewlines') to fit the remaining vertical space,
00611       // clip and adjust the painter position as necessary
00612       int _lines = (*rangeptr)->viewLineCount()-remainder; // number of "sublines" to paint.
00613       int _yadjust = remainder * fontHeight; // if we need to clip at the start of the line, it's this much.
00614       bool _needWrap = (fontHeight*_lines > maxHeight-y);
00615 
00616       if (remainder || _needWrap) {
00617         remainder = _needWrap? _lines - ((maxHeight-y)/fontHeight) : 0;
00618         paint.translate(0, -_yadjust);
00619         paint.setClipRect(0,_yadjust,maxWidth,((_lines-remainder)*fontHeight)-1); //### drop the crosspatch in printerfriendly mode???
00620       }
00621 
00622       renderer.paintTextLine(paint, *rangeptr, 0, (int)maxWidth);
00623 
00624       paint.setClipping(false);
00625       paint.translate(_xadjust, (fontHeight * _lines)+_yadjust);
00626 
00627       y += fontHeight*_lines;
00628 
00629       if ( ! remainder )
00630       lineCount++;
00631     } // done lineCount <= lastline
00632 
00633     paint.end();
00634     return true;
00635   }
00636   return false;
00637 }
00638 //END KatePrinter
00639 
00640 //BEGIN KatePrintTextSettings
00641 KatePrintTextSettings::KatePrintTextSettings( QWidget *parent )
00642   : QWidget( parent )
00643 {
00644   setWindowTitle( i18n("Te&xt Settings") );
00645 
00646   QVBoxLayout *lo = new QVBoxLayout ( this );
00647   lo->setSpacing( KDialog::spacingHint() );
00648 
00649 //   cbSelection = new QCheckBox( i18n("Print &selected text only"), this );
00650 //   lo->addWidget( cbSelection );
00651 
00652   cbLineNumbers = new QCheckBox( i18n("Print line &numbers"), this );
00653   lo->addWidget( cbLineNumbers );
00654 
00655   cbGuide = new QCheckBox( i18n("Print &legend"), this );
00656   lo->addWidget( cbGuide );
00657 
00658   lo->addStretch( 1 );
00659 
00660   // set defaults - nothing to do :-)
00661 
00662   // whatsthis
00663 //   cbSelection->setWhatsThis(i18n(
00664 //         "<p>This option is only available if some text is selected in the document.</p>"
00665 //         "<p>If available and enabled, only the selected text is printed.</p>") );
00666   cbLineNumbers->setWhatsThis(i18n(
00667         "<p>If enabled, line numbers will be printed on the left side of the page(s).</p>") );
00668   cbGuide->setWhatsThis(i18n(
00669         "<p>Print a box displaying typographical conventions for the document type, as "
00670         "defined by the syntax highlighting being used.</p>") );
00671 }
00672 
00673 // bool KatePrintTextSettings::printSelection()
00674 // {
00675 //     return cbSelection->isChecked();
00676 // }
00677 
00678 bool KatePrintTextSettings::printLineNumbers()
00679 {
00680   return cbLineNumbers->isChecked();
00681 }
00682 
00683 bool KatePrintTextSettings::printGuide()
00684 {
00685   return cbGuide->isChecked();
00686 }
00687 
00688 // void KatePrintTextSettings::enableSelection( bool enable )
00689 // {
00690 //   cbSelection->setEnabled( enable );
00691 // }
00692 
00693 //END KatePrintTextSettings
00694 
00695 //BEGIN KatePrintHeaderFooter
00696 KatePrintHeaderFooter::KatePrintHeaderFooter( QWidget *parent )
00697   : QWidget( parent )
00698 {
00699   setWindowTitle( i18n("Hea&der && Footer") );
00700 
00701   QVBoxLayout *lo = new QVBoxLayout ( this );
00702   uint sp = KDialog::spacingHint();
00703   lo->setSpacing( sp );
00704 
00705   // enable
00706   QHBoxLayout *lo1 = new QHBoxLayout ();
00707   lo->addLayout( lo1 );
00708   cbEnableHeader = new QCheckBox( i18n("Pr&int header"), this );
00709   lo1->addWidget( cbEnableHeader );
00710   cbEnableFooter = new QCheckBox( i18n("Pri&nt footer"), this );
00711   lo1->addWidget( cbEnableFooter );
00712 
00713   // font
00714   QHBoxLayout *lo2 = new QHBoxLayout();
00715   lo->addLayout( lo2 );
00716   lo2->addWidget( new QLabel( i18n("Header/footer font:"), this ) );
00717   lFontPreview = new QLabel( this );
00718   lFontPreview->setFrameStyle( QFrame::Panel|QFrame::Sunken );
00719   lo2->addWidget( lFontPreview );
00720   lo2->setStretchFactor( lFontPreview, 1 );
00721   QPushButton *btnChooseFont = new QPushButton( i18n("Choo&se Font..."), this );
00722   lo2->addWidget( btnChooseFont );
00723   connect( btnChooseFont, SIGNAL(clicked()), this, SLOT(setHFFont()) );
00724 
00725   // header
00726   gbHeader = new QGroupBox( this );
00727   gbHeader->setTitle(i18n("Header Properties"));
00728   QGridLayout* grid = new QGridLayout(gbHeader);
00729   lo->addWidget( gbHeader );
00730 
00731   QLabel *lHeaderFormat = new QLabel( i18n("&Format:"), gbHeader );
00732   grid->addWidget(lHeaderFormat, 0, 0);
00733 
00734   KHBox *hbHeaderFormat = new KHBox( gbHeader );
00735   grid->addWidget(hbHeaderFormat, 0, 1);
00736 
00737   hbHeaderFormat->setSpacing( sp );
00738   leHeaderLeft = new QLineEdit( hbHeaderFormat );
00739   leHeaderCenter = new QLineEdit( hbHeaderFormat );
00740   leHeaderRight = new QLineEdit( hbHeaderFormat );
00741   lHeaderFormat->setBuddy( leHeaderLeft );
00742 
00743   grid->addWidget(new QLabel( i18n("Colors:"), gbHeader ), 1, 0);
00744 
00745   KHBox *hbHeaderColors = new KHBox( gbHeader );
00746   grid->addWidget(hbHeaderColors, 1, 1);
00747 
00748   hbHeaderColors->setSpacing( sp );
00749   QLabel *lHeaderFgCol = new QLabel( i18n("Foreground:"), hbHeaderColors );
00750   kcbtnHeaderFg = new KColorButton( hbHeaderColors );
00751   lHeaderFgCol->setBuddy( kcbtnHeaderFg );
00752   cbHeaderEnableBgColor = new QCheckBox( i18n("Bac&kground"), hbHeaderColors );
00753   kcbtnHeaderBg = new KColorButton( hbHeaderColors );
00754 
00755   gbFooter = new QGroupBox( this );
00756   gbFooter->setTitle(i18n("Footer Properties"));
00757   grid = new QGridLayout(gbFooter);
00758   lo->addWidget( gbFooter );
00759 
00760   // footer
00761   QLabel *lFooterFormat = new QLabel( i18n("For&mat:"), gbFooter );
00762   grid->addWidget(lFooterFormat, 0, 0);
00763 
00764   KHBox *hbFooterFormat = new KHBox( gbFooter );
00765   grid->addWidget(hbFooterFormat, 0, 1);
00766 
00767   hbFooterFormat->setSpacing( sp );
00768   leFooterLeft = new QLineEdit( hbFooterFormat );
00769   leFooterCenter = new QLineEdit( hbFooterFormat );
00770   leFooterRight = new QLineEdit( hbFooterFormat );
00771   lFooterFormat->setBuddy( leFooterLeft );
00772 
00773   grid->addWidget(new QLabel( i18n("Colors:"), gbFooter ), 1, 0);
00774 
00775   KHBox *hbFooterColors = new KHBox( gbFooter );
00776   grid->addWidget(hbFooterColors, 1, 1);
00777   hbFooterColors->setSpacing( sp );
00778 
00779   QLabel *lFooterBgCol = new QLabel( i18n("Foreground:"), hbFooterColors );
00780   kcbtnFooterFg = new KColorButton( hbFooterColors );
00781   lFooterBgCol->setBuddy( kcbtnFooterFg );
00782   cbFooterEnableBgColor = new QCheckBox( i18n("&Background"), hbFooterColors );
00783   kcbtnFooterBg = new KColorButton( hbFooterColors );
00784 
00785   lo->addStretch( 1 );
00786 
00787   // user friendly
00788   connect( cbEnableHeader, SIGNAL(toggled(bool)), gbHeader, SLOT(setEnabled(bool)) );
00789   connect( cbEnableFooter, SIGNAL(toggled(bool)), gbFooter, SLOT(setEnabled(bool)) );
00790   connect( cbHeaderEnableBgColor, SIGNAL(toggled(bool)), kcbtnHeaderBg, SLOT(setEnabled(bool)) );
00791   connect( cbFooterEnableBgColor, SIGNAL(toggled(bool)), kcbtnFooterBg, SLOT(setEnabled(bool)) );
00792 
00793   // set defaults
00794   cbEnableHeader->setChecked( true );
00795   leHeaderLeft->setText( "%y" );
00796   leHeaderCenter->setText( "%f" );
00797   leHeaderRight->setText( "%p" );
00798   kcbtnHeaderFg->setColor( QColor("black") );
00799   cbHeaderEnableBgColor->setChecked( false );
00800   kcbtnHeaderBg->setColor( QColor("lightgrey") );
00801 
00802   cbEnableFooter->setChecked( true );
00803   leFooterRight->setText( "%U" );
00804   kcbtnFooterFg->setColor( QColor("black") );
00805   cbFooterEnableBgColor->setChecked( false );
00806   kcbtnFooterBg->setColor( QColor("lightgrey") );
00807 
00808   // whatsthis
00809   QString  s = i18n("<p>Format of the page header. The following tags are supported:</p>");
00810   QString s1 = i18n(
00811       "<ul><li><tt>%u</tt>: current user name</li>"
00812       "<li><tt>%d</tt>: complete date/time in short format</li>"
00813       "<li><tt>%D</tt>: complete date/time in long format</li>"
00814       "<li><tt>%h</tt>: current time</li>"
00815       "<li><tt>%y</tt>: current date in short format</li>"
00816       "<li><tt>%Y</tt>: current date in long format</li>"
00817       "<li><tt>%f</tt>: file name</li>"
00818       "<li><tt>%U</tt>: full URL of the document</li>"
00819       "<li><tt>%p</tt>: page number</li>"
00820       "</ul><br />");
00821   leHeaderRight->setWhatsThis(s + s1 );
00822   leHeaderCenter->setWhatsThis(s + s1 );
00823   leHeaderLeft->setWhatsThis(s + s1 );
00824   s = i18n("<p>Format of the page footer. The following tags are supported:</p>");
00825   leFooterRight->setWhatsThis(s + s1 );
00826   leFooterCenter->setWhatsThis(s + s1 );
00827   leFooterLeft->setWhatsThis(s + s1 );
00828 }
00829 
00830 QFont KatePrintHeaderFooter::font()
00831 {
00832     return lFontPreview->font();
00833 }
00834 
00835 bool KatePrintHeaderFooter::useHeader()
00836 {
00837   return cbEnableHeader->isChecked();
00838 }
00839 
00840 QStringList KatePrintHeaderFooter::headerFormat()
00841 {
00842   QStringList l;
00843   l << leHeaderLeft->text() << leHeaderCenter->text() << leHeaderRight->text();
00844   return l;
00845 }
00846 
00847 QColor KatePrintHeaderFooter::headerForeground()
00848 {
00849   return kcbtnHeaderFg->color();
00850 }
00851 
00852 QColor KatePrintHeaderFooter::headerBackground()
00853 {
00854   return kcbtnHeaderBg->color();
00855 }
00856 
00857 bool KatePrintHeaderFooter::useHeaderBackground()
00858 {
00859   return cbHeaderEnableBgColor->isChecked();
00860 }
00861 
00862 bool KatePrintHeaderFooter::useFooter()
00863 {
00864   return cbEnableFooter->isChecked();
00865 }
00866 
00867 QStringList KatePrintHeaderFooter::footerFormat()
00868 {
00869   QStringList l;
00870   l<< leFooterLeft->text() << leFooterCenter->text() << leFooterRight->text();
00871   return l;
00872 }
00873 
00874 QColor KatePrintHeaderFooter::footerForeground()
00875 {
00876   return kcbtnFooterFg->color();
00877 }
00878 
00879 QColor KatePrintHeaderFooter::footerBackground()
00880 {
00881   return kcbtnFooterBg->color();
00882 }
00883 
00884 bool KatePrintHeaderFooter::useFooterBackground()
00885 {
00886   return cbFooterEnableBgColor->isChecked();
00887 }
00888 
00889 void KatePrintHeaderFooter::setHFFont()
00890 {
00891   QFont fnt( lFontPreview->font() );
00892   // display a font dialog
00893   if ( KFontDialog::getFont( fnt, false, this ) == KFontDialog::Accepted )
00894   {
00895     // set preview
00896     lFontPreview->setFont( fnt );
00897     lFontPreview->setText( (fnt.family() + ", %1pt").arg( fnt.pointSize() ) );
00898   }
00899 }
00900 
00901 //END KatePrintHeaderFooter
00902 
00903 //BEGIN KatePrintLayout
00904 
00905 KatePrintLayout::KatePrintLayout( QWidget *parent)
00906   : QWidget( parent )
00907 {
00908   setWindowTitle( i18n("L&ayout") );
00909 
00910   QVBoxLayout *lo = new QVBoxLayout ( this );
00911   lo->setSpacing( KDialog::spacingHint() );
00912 
00913   KHBox *hb = new KHBox( this );
00914   lo->addWidget( hb );
00915   QLabel *lSchema = new QLabel( i18n("&Schema:"), hb );
00916   cmbSchema = new QComboBox( hb );
00917   cmbSchema->setEditable( false );
00918   lSchema->setBuddy( cmbSchema );
00919 
00920   cbDrawBackground = new QCheckBox( i18n("Draw bac&kground color"), this );
00921   lo->addWidget( cbDrawBackground );
00922 
00923   cbEnableBox = new QCheckBox( i18n("Draw &boxes"), this );
00924   lo->addWidget( cbEnableBox );
00925 
00926   gbBoxProps = new QGroupBox( this );
00927   gbBoxProps->setTitle(i18n("Box Properties"));
00928   QGridLayout* grid = new QGridLayout(gbBoxProps);
00929   lo->addWidget( gbBoxProps );
00930 
00931   QLabel *lBoxWidth = new QLabel( i18n("W&idth:"), gbBoxProps );
00932   grid->addWidget(lBoxWidth, 0, 0);
00933   sbBoxWidth = new QSpinBox( gbBoxProps );
00934   sbBoxWidth->setRange( 1, 100 );
00935   sbBoxWidth->setSingleStep( 1 );
00936   grid->addWidget(sbBoxWidth, 0, 1);
00937   lBoxWidth->setBuddy( sbBoxWidth );
00938 
00939   QLabel *lBoxMargin = new QLabel( i18n("&Margin:"), gbBoxProps );
00940   grid->addWidget(lBoxMargin, 1, 0);
00941   sbBoxMargin = new QSpinBox( gbBoxProps );
00942   sbBoxMargin->setRange( 0, 100 );
00943   sbBoxMargin->setSingleStep( 1 );
00944   grid->addWidget(sbBoxMargin, 1, 1);
00945   lBoxMargin->setBuddy( sbBoxMargin );
00946 
00947   QLabel *lBoxColor = new QLabel( i18n("Co&lor:"), gbBoxProps );
00948   grid->addWidget(lBoxColor, 2, 0);
00949   kcbtnBoxColor = new KColorButton( gbBoxProps );
00950   grid->addWidget(kcbtnBoxColor, 2, 1);
00951   lBoxColor->setBuddy( kcbtnBoxColor );
00952 
00953   connect( cbEnableBox, SIGNAL(toggled(bool)), gbBoxProps, SLOT(setEnabled(bool)) );
00954 
00955   lo->addStretch( 1 );
00956   // set defaults:
00957   sbBoxMargin->setValue( 6 );
00958   gbBoxProps->setEnabled( false );
00959   cmbSchema->addItems (KateGlobal::self()->schemaManager()->list ());
00960   cmbSchema->setCurrentIndex( 1 );
00961 
00962   // whatsthis
00963   cmbSchema->setWhatsThis(i18n(
00964         "Select the color scheme to use for the print." ) );
00965   cbDrawBackground->setWhatsThis(i18n(
00966         "<p>If enabled, the background color of the editor will be used.</p>"
00967         "<p>This may be useful if your color scheme is designed for a dark background.</p>") );
00968   cbEnableBox->setWhatsThis(i18n(
00969         "<p>If enabled, a box as defined in the properties below will be drawn "
00970         "around the contents of each page. The Header and Footer will be separated "
00971         "from the contents with a line as well.</p>") );
00972   sbBoxWidth->setWhatsThis(i18n(
00973         "The width of the box outline" ) );
00974   sbBoxMargin->setWhatsThis(i18n(
00975         "The margin inside boxes, in pixels") );
00976   kcbtnBoxColor->setWhatsThis(i18n(
00977         "The line color to use for boxes") );
00978 }
00979 
00980 QString KatePrintLayout::colorScheme()
00981 {
00982   return cmbSchema->currentText();
00983 }
00984 
00985 bool KatePrintLayout::useBackground()
00986 {
00987   return cbDrawBackground->isChecked();
00988 }
00989 
00990 bool KatePrintLayout::useBox()
00991 {
00992   return cbEnableBox->isChecked();
00993 }
00994 
00995 int KatePrintLayout::boxWidth()
00996 {
00997   return sbBoxWidth->value();
00998 }
00999 
01000 int KatePrintLayout::boxMargin()
01001 {
01002   return sbBoxMargin->value();
01003 }
01004 
01005 QColor KatePrintLayout::boxColor()
01006 {
01007   return kcbtnBoxColor->color();
01008 }
01009 //END KatePrintLayout
01010 
01011 #include "kateprinter.moc"
01012 
01013 // kate: space-indent on; indent-width 2; replace-tabs on;

Kate

Skip menu "Kate"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal