• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • 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 <katefactory.h>
00027 #include <katehighlight.h>
00028 #include <katelinerange.h>
00029 #include <katerenderer.h>
00030 #include <kateschema.h>
00031 #include <katetextline.h>
00032 
00033 #include <kapplication.h>
00034 #include <kcolorbutton.h>
00035 #include <kdebug.h>
00036 #include <kdialog.h> // for spacingHint()
00037 #include <kfontdialog.h>
00038 #include <klocale.h>
00039 #include <kprinter.h>
00040 #include <kurl.h>
00041 #include <kuser.h> // for loginName
00042 
00043 #include <qpainter.h>
00044 #include <qpopupmenu.h>
00045 #include <qpaintdevicemetrics.h>
00046 #include <qcheckbox.h>
00047 #include <qcombobox.h>
00048 #include <qgroupbox.h>
00049 #include <qhbox.h>
00050 #include <qlabel.h>
00051 #include <qlayout.h>
00052 #include <qlineedit.h>
00053 #include <qspinbox.h>
00054 #include <qstringlist.h>
00055 #include <qwhatsthis.h>
00056 
00057 //BEGIN KatePrinter
00058 bool KatePrinter::print (KateDocument *doc)
00059 {
00060 #ifndef Q_WS_WIN //TODO: reenable
00061   KPrinter printer;
00062 
00063   // docname is now always there, including the right Untitled name
00064   printer.setDocName(doc->docName());
00065 
00066   KatePrintTextSettings *kpts = new KatePrintTextSettings(&printer, NULL);
00067   kpts->enableSelection( doc->hasSelection() );
00068   printer.addDialogPage( kpts );
00069   printer.addDialogPage( new KatePrintHeaderFooter(&printer, NULL) );
00070   printer.addDialogPage( new KatePrintLayout(&printer, NULL) );
00071 
00072    if ( printer.setup( kapp->mainWidget(), i18n("Print %1").arg(printer.docName()) ) )
00073    {
00074      KateRenderer renderer(doc);
00075      //renderer.config()->setSchema (1);
00076      renderer.setPrinterFriendly(true);
00077 
00078      QPainter paint( &printer );
00079      QPaintDeviceMetrics pdm( &printer );
00080      /*
00081         We work in tree cycles:
00082         1) initialize variables and retrieve print settings
00083         2) prepare data according to those settings
00084         3) draw to the printer
00085      */
00086      uint pdmWidth = pdm.width();
00087      uint y = 0;
00088      uint xstart = 0; // beginning point for painting lines
00089      uint lineCount = 0;
00090      uint maxWidth = pdmWidth;
00091      uint headerWidth = pdmWidth;
00092      int startCol = 0;
00093      int endCol = 0;
00094      bool needWrap = true;
00095      bool pageStarted = true;
00096 
00097      // Text Settings Page
00098      bool selectionOnly = ( doc->hasSelection() &&
00099                            ( printer.option("app-kate-printselection") == "true" ) );
00100      int selStartCol = 0;
00101      int selEndCol = 0;
00102 
00103      bool useGuide = ( printer.option("app-kate-printguide") == "true" );
00104      int guideHeight = 0;
00105      int guideCols = 0;
00106 
00107      bool printLineNumbers = ( printer.option("app-kate-printlinenumbers") == "true" );
00108      uint lineNumberWidth( 0 );
00109 
00110      // Header/Footer Page
00111      QFont headerFont; // used for header/footer
00112      QString f = printer.option("app-kate-hffont");
00113      if (!f.isEmpty())
00114        headerFont.fromString( f );
00115 
00116      bool useHeader = (printer.option("app-kate-useheader") == "true");
00117      QColor headerBgColor(printer.option("app-kate-headerbg"));
00118      QColor headerFgColor(printer.option("app-kate-headerfg"));
00119      uint headerHeight( 0 ); // further init only if needed
00120      QStringList headerTagList; // do
00121      bool headerDrawBg = false; // do
00122 
00123      bool useFooter = (printer.option("app-kate-usefooter") == "true");
00124      QColor footerBgColor(printer.option("app-kate-footerbg"));
00125      QColor footerFgColor(printer.option("app-kate-footerfg"));
00126      uint footerHeight( 0 ); // further init only if needed
00127      QStringList footerTagList = 0; // do
00128      bool footerDrawBg = 0; // do
00129 
00130      // Layout Page
00131      renderer.config()->setSchema( KateFactory::self()->schemaManager()->number(
00132            printer.option("app-kate-colorscheme") ) );
00133      bool useBackground = ( printer.option("app-kate-usebackground") == "true" );
00134      bool useBox = (printer.option("app-kate-usebox") == "true");
00135      int boxWidth(printer.option("app-kate-boxwidth").toInt());
00136      QColor boxColor(printer.option("app-kate-boxcolor"));
00137      int innerMargin = useBox ? printer.option("app-kate-boxmargin").toInt() : 6;
00138 
00139      // Post initialization
00140      uint maxHeight = (useBox ? pdm.height()-innerMargin : pdm.height());
00141      uint currentPage( 1 );
00142      uint lastline = doc->lastLine(); // nessecary to print selection only
00143      uint firstline( 0 );
00144 
00145      KateHlItemDataList ilist;
00146 
00147      if (useGuide)
00148        doc->highlight()->getKateHlItemDataListCopy (renderer.config()->schema(), ilist);
00149 
00150      /*
00151         Now on for preparations...
00152         during preparations, variable names starting with a "_" means
00153         those variables are local to the enclosing block.
00154      */
00155      {
00156        if ( selectionOnly )
00157        {
00158          // set a line range from the first selected line to the last
00159          firstline = doc->selStartLine();
00160          selStartCol = doc->selStartCol();
00161          lastline = doc->selEndLine();
00162          selEndCol = doc->selEndCol();
00163 
00164          lineCount = firstline;
00165        }
00166 
00167        if ( printLineNumbers )
00168        {
00169          // figure out the horiizontal space required
00170          QString s( QString("%1 ").arg( doc->numLines() ) );
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, true, false);
00194          tags["D"] =  KGlobal::locale()->formatDateTime(dt, false, false);
00195          tags["h"] =  KGlobal::locale()->formatTime(dt.time(), false);
00196          tags["y"] =  KGlobal::locale()->formatDate(dt.date(), true);
00197          tags["Y"] =  KGlobal::locale()->formatDate(dt.date(), false);
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 = ( printer.option("app-kate-headerusebg") == "true" );
00212            headerHeight = QFontMetrics( headerFont ).height();
00213            if ( useBox || headerDrawBg )
00214              headerHeight += innerMargin * 2;
00215            else
00216              headerHeight += 1 + QFontMetrics( headerFont ).leading();
00217 
00218            QString headerTags = printer.option("app-kate-headerformat");
00219            int pos = reTags.search( headerTags );
00220            QString rep;
00221            while ( pos > -1 )
00222            {
00223              rep = tags[reTags.cap( 1 )];
00224              headerTags.replace( (uint)pos, 2, rep );
00225              pos += rep.length();
00226              pos = reTags.search( headerTags, pos );
00227            }
00228            headerTagList = QStringList::split('|', headerTags, true);
00229 
00230            if (!headerBgColor.isValid())
00231              headerBgColor = Qt::lightGray;
00232            if (!headerFgColor.isValid())
00233              headerFgColor = Qt::black;
00234          }
00235 
00236          if (useFooter)
00237          {
00238            footerDrawBg = ( printer.option("app-kate-footerusebg") == "true" );
00239            footerHeight = QFontMetrics( headerFont ).height();
00240            if ( useBox || footerDrawBg )
00241              footerHeight += 2*innerMargin;
00242            else
00243              footerHeight += 1; // line only
00244 
00245            QString footerTags = printer.option("app-kate-footerformat");
00246            int pos = reTags.search( footerTags );
00247            QString rep;
00248            while ( pos > -1 )
00249            {
00250              rep = tags[reTags.cap( 1 )];
00251              footerTags.replace( (uint)pos, 2, rep );
00252              pos += rep.length();
00253              pos = reTags.search( footerTags, pos );
00254            }
00255 
00256            footerTagList = QStringList::split('|', footerTags, true);
00257            if (!footerBgColor.isValid())
00258              footerBgColor = Qt::lightGray;
00259            if (!footerFgColor.isValid())
00260              footerFgColor = Qt::black;
00261            // adjust maxheight, so we can know when/where to print footer
00262            maxHeight -= footerHeight;
00263          }
00264        } // if ( useHeader || useFooter )
00265 
00266        if ( useBackground )
00267        {
00268          if ( ! useBox )
00269          {
00270            xstart += innerMargin;
00271            maxWidth -= innerMargin * 2;
00272          }
00273        }
00274 
00275        if ( useBox )
00276        {
00277          if (!boxColor.isValid())
00278            boxColor = Qt::black;
00279          if (boxWidth < 1) // shouldn't be pssible no more!
00280            boxWidth = 1;
00281          // set maxwidth to something sensible
00282          maxWidth -= ( ( boxWidth + innerMargin )  * 2 );
00283          xstart += boxWidth + innerMargin;
00284          // maxheight too..
00285          maxHeight -= boxWidth;
00286        }
00287        else
00288          boxWidth = 0;
00289 
00290        if ( useGuide )
00291        {
00292          // calculate the height required
00293          // the number of columns is a side effect, saved for drawing time
00294          // first width is needed
00295          int _w = pdmWidth - innerMargin * 2;
00296          if ( useBox )
00297            _w -= boxWidth * 2;
00298          else
00299          {
00300            if ( useBackground )
00301              _w -= ( innerMargin * 2 );
00302            _w -= 2; // 1 px line on each side
00303          }
00304 
00305          // base of height: margins top/bottom, above and below tetle sep line
00306          guideHeight = ( innerMargin * 4 ) + 1;
00307 
00308          // get a title and add the height required to draw it
00309          QString _title = i18n("Typographical Conventions for %1").arg(doc->highlight()->name());
00310          guideHeight += paint.boundingRect( 0, 0, _w, 1000, Qt::AlignTop|Qt::AlignHCenter, _title ).height();
00311 
00312          // see how many columns we can fit in
00313          int _widest( 0 );
00314 
00315          QPtrListIterator<KateHlItemData> it( ilist );
00316          KateHlItemData *_d;
00317 
00318          int _items ( 0 );
00319          while ( ( _d = it.current()) != 0 )
00320          {
00321            _widest = kMax( _widest, ((QFontMetrics)(
00322                                 _d->bold() ?
00323                                   _d->italic() ?
00324                                     renderer.config()->fontStruct()->myFontMetricsBI :
00325                                     renderer.config()->fontStruct()->myFontMetricsBold :
00326                                   _d->italic() ?
00327                                     renderer.config()->fontStruct()->myFontMetricsItalic :
00328                                     renderer.config()->fontStruct()->myFontMetrics
00329                                     ) ).width( _d->name ) );
00330            _items++;
00331            ++it;
00332          }
00333          guideCols = _w/( _widest + innerMargin );
00334          // add height for required number of lines needed given columns
00335          guideHeight += renderer.fontHeight() * ( _items/guideCols );
00336          if ( _items%guideCols )
00337            guideHeight += renderer.fontHeight();
00338        }
00339 
00340        // now that we know the vertical amount of space needed,
00341        // it is possible to calculate the total number of pages
00342        // if needed, that is if any header/footer tag contains "%P".
00343        if ( headerTagList.grep("%P").count() || footerTagList.grep("%P").count() )
00344        {
00345          kdDebug(13020)<<"'%P' found! calculating number of pages..."<<endl;
00346          uint _pages = 0;
00347          uint _ph = maxHeight;
00348          if ( useHeader )
00349            _ph -= ( headerHeight + innerMargin );
00350          if ( useFooter )
00351            _ph -= innerMargin;
00352          int _lpp = _ph / renderer.fontHeight();
00353          uint _lt = 0, _c=0;
00354 
00355          // add space for guide if required
00356          if ( useGuide )
00357            _lt += (guideHeight + (renderer.fontHeight() /2)) / renderer.fontHeight();
00358          long _lw;
00359          for ( uint i = firstline; i < lastline; i++ )
00360          {
00361            _lw = renderer.textWidth( doc->kateTextLine( i ), -1 );
00362            while ( _lw >= 0 )
00363            {
00364              _c++;
00365              _lt++;
00366              if ( (int)_lt  == _lpp )
00367              {
00368                _pages++;
00369                _lt = 0;
00370              }
00371              _lw -= maxWidth;
00372              if ( ! _lw ) _lw--; // skip lines matching exactly!
00373            }
00374          }
00375          if ( _lt ) _pages++; // last page
00376 
00377          // substitute both tag lists
00378          QString re("%P");
00379          QStringList::Iterator it;
00380          for ( it=headerTagList.begin(); it!=headerTagList.end(); ++it )
00381            (*it).replace( re, QString( "%1" ).arg( _pages ) );
00382          for ( it=footerTagList.begin(); it!=footerTagList.end(); ++it )
00383            (*it).replace( re, QString( "%1" ).arg( _pages ) );
00384        }
00385      } // end prepare block
00386 
00387      /*
00388         On to draw something :-)
00389      */
00390      uint _count = 0;
00391      while (  lineCount <= lastline  )
00392      {
00393        startCol = 0;
00394        endCol = 0;
00395        needWrap = true;
00396 
00397        while (needWrap)
00398        {
00399          if ( y + renderer.fontHeight() >= (uint)(maxHeight) )
00400          {
00401            kdDebug(13020)<<"Starting new page, "<<_count<<" lines up to now."<<endl;
00402            printer.newPage();
00403            currentPage++;
00404            pageStarted = true;
00405            y=0;
00406          }
00407 
00408          if ( pageStarted )
00409          {
00410 
00411            if ( useHeader )
00412            {
00413              paint.setPen(headerFgColor);
00414              paint.setFont(headerFont);
00415              if ( headerDrawBg )
00416                 paint.fillRect(0, 0, headerWidth, headerHeight, headerBgColor);
00417              if (headerTagList.count() == 3)
00418              {
00419                int valign = ( (useBox||headerDrawBg||useBackground) ?
00420                               Qt::AlignVCenter : Qt::AlignTop );
00421                int align = valign|Qt::AlignLeft;
00422                int marg = ( useBox || headerDrawBg ) ? innerMargin : 0;
00423                if ( useBox ) marg += boxWidth;
00424                QString s;
00425                for (int i=0; i<3; i++)
00426                {
00427                  s = headerTagList[i];
00428                  if (s.find("%p") != -1) s.replace("%p", QString::number(currentPage));
00429                  paint.drawText(marg, 0, headerWidth-(marg*2), headerHeight, align, s);
00430                  align = valign|(i == 0 ? Qt::AlignHCenter : Qt::AlignRight);
00431                }
00432              }
00433              if ( ! ( headerDrawBg || useBox || useBackground ) ) // draw a 1 px (!?) line to separate header from contents
00434              {
00435                paint.drawLine( 0, headerHeight-1, headerWidth, headerHeight-1 );
00436                //y += 1; now included in headerHeight
00437              }
00438              y += headerHeight + innerMargin;
00439            }
00440 
00441            if ( useFooter )
00442            {
00443              if ( ! ( footerDrawBg || useBox || useBackground ) ) // draw a 1 px (!?) line to separate footer from contents
00444                paint.drawLine( 0, maxHeight + innerMargin - 1, headerWidth, maxHeight + innerMargin - 1 );
00445              if ( footerDrawBg )
00446                 paint.fillRect(0, maxHeight+innerMargin+boxWidth, headerWidth, footerHeight, footerBgColor);
00447              if (footerTagList.count() == 3)
00448              {
00449                int align = Qt::AlignVCenter|Qt::AlignLeft;
00450                int marg = ( useBox || footerDrawBg ) ? innerMargin : 0;
00451                if ( useBox ) marg += boxWidth;
00452                QString s;
00453                for (int i=0; i<3; i++)
00454                {
00455                  s = footerTagList[i];
00456                  if (s.find("%p") != -1) s.replace("%p", QString::number(currentPage));
00457                  paint.drawText(marg, maxHeight+innerMargin, headerWidth-(marg*2), footerHeight, align, s);
00458                  align = Qt::AlignVCenter|(i == 0 ? Qt::AlignHCenter : Qt::AlignRight);
00459                }
00460              }
00461            } // done footer
00462 
00463            if ( useBackground )
00464            {
00465              // If we have a box, or the header/footer has backgrounds, we want to paint
00466              // to the border of those. Otherwise just the contents area.
00467              int _y = y, _h = maxHeight - y;
00468              if ( useBox )
00469              {
00470                _y -= innerMargin;
00471                _h += 2 * innerMargin;
00472              }
00473              else
00474              {
00475                if ( headerDrawBg )
00476                {
00477                  _y -= innerMargin;
00478                  _h += innerMargin;
00479                }
00480                if ( footerDrawBg )
00481                {
00482                  _h += innerMargin;
00483                }
00484              }
00485              paint.fillRect( 0, _y, pdmWidth, _h, renderer.config()->backgroundColor());
00486            }
00487 
00488            if ( useBox )
00489            {
00490              paint.setPen(QPen(boxColor, boxWidth));
00491              paint.drawRect(0, 0, pdmWidth, pdm.height());
00492              if (useHeader)
00493                paint.drawLine(0, headerHeight, headerWidth, headerHeight);
00494              else
00495                y += innerMargin;
00496 
00497              if ( useFooter ) // drawline is not trustable, grr.
00498                paint.fillRect( 0, maxHeight+innerMargin, headerWidth, boxWidth, boxColor );
00499            }
00500 
00501            if ( useGuide && currentPage == 1 )
00502            {  // FIXME - this may span more pages...
00503              // draw a box unless we have boxes, in which case we end with a box line
00504 
00505              // use color of dsNormal for the title string and the hline
00506              KateAttributeList _dsList;
00507              KateHlManager::self()->getDefaults ( renderer.config()->schema(), _dsList );
00508              paint.setPen( _dsList.at(0)->textColor() );
00509              int _marg = 0; // this could be available globally!??
00510              if ( useBox )
00511              {
00512                _marg += (2*boxWidth) + (2*innerMargin);
00513                paint.fillRect( 0, y+guideHeight-innerMargin-boxWidth, headerWidth, boxWidth, boxColor );
00514              }
00515              else
00516              {
00517                if ( useBackground )
00518                  _marg += 2*innerMargin;
00519                paint.drawRect( _marg, y, pdmWidth-(2*_marg), guideHeight );
00520                _marg += 1;
00521                y += 1 + innerMargin;
00522              }
00523              // draw a title string
00524              paint.setFont( renderer.config()->fontStruct()->myFontBold );
00525              QRect _r;
00526              paint.drawText( _marg, y, pdmWidth-(2*_marg), maxHeight - y,
00527                 Qt::AlignTop|Qt::AlignHCenter,
00528                 i18n("Typographical Conventions for %1").arg(doc->highlight()->name()), -1, &_r );
00529              int _w = pdmWidth - (_marg*2) - (innerMargin*2);
00530              int _x = _marg + innerMargin;
00531              y += _r.height() + innerMargin;
00532              paint.drawLine( _x, y, _x + _w, y );
00533              y += 1 + innerMargin;
00534              // draw attrib names using their styles
00535 
00536              QPtrListIterator<KateHlItemData> _it( ilist );
00537              KateHlItemData *_d;
00538              int _cw = _w/guideCols;
00539              int _i(0);
00540 
00541              while ( ( _d = _it.current() ) != 0 )
00542              {
00543                paint.setPen( renderer.attribute(_i)->textColor() );
00544                paint.setFont( renderer.attribute(_i)->font( *renderer.currentFont() ) );
00545                paint.drawText(( _x + ((_i%guideCols)*_cw)), y, _cw, renderer.fontHeight(),
00546                         Qt::AlignVCenter|Qt::AlignLeft, _d->name, -1, &_r );
00547                _i++;
00548                if ( _i && ! ( _i%guideCols ) ) y += renderer.fontHeight();
00549                ++_it;
00550              }
00551              if ( _i%guideCols ) y += renderer.fontHeight();// last row not full
00552              y += ( useBox ? boxWidth : 1 ) + (innerMargin*2);
00553            }
00554 
00555            pageStarted = false;
00556          } // pageStarted; move on to contents:)
00557 
00558          if ( printLineNumbers && ! startCol ) // don't repeat!
00559          {
00560            paint.setFont( renderer.config()->fontStruct()->font( false, false ) );
00561            paint.setPen( renderer.config()->lineNumberColor() );
00562            paint.drawText( (( useBox || useBackground ) ? innerMargin : 0), y,
00563                         lineNumberWidth, renderer.fontHeight(),
00564                         Qt::AlignRight, QString("%1").arg( lineCount + 1 ) );
00565          }
00566          endCol = renderer.textWidth(doc->kateTextLine(lineCount), startCol, maxWidth, &needWrap);
00567 
00568          if ( endCol < startCol )
00569          {
00570            //kdDebug(13020)<<"--- Skipping garbage, line: "<<lineCount<<" start: "<<startCol<<" end: "<<endCol<<" real EndCol; "<< buffer->line(lineCount)->length()<< " !?"<<endl;
00571            lineCount++;
00572            continue; // strange case...
00573                      // Happens if the line fits exactly.
00574                      // When it happens, a line of garbage would be printed.
00575                      // FIXME Most likely this is an error in textWidth(),
00576                      // failing to correctly set needWrap to false in this case?
00577          }
00578 
00579          // if we print only selection:
00580          // print only selected range of chars.
00581          bool skip = false;
00582          if ( selectionOnly )
00583          {
00584            bool inBlockSelection = ( doc->blockSelectionMode() && lineCount >= firstline && lineCount <= lastline );
00585            if ( lineCount == firstline || inBlockSelection )
00586            {
00587              if ( startCol < selStartCol )
00588                startCol = selStartCol;
00589            }
00590            if ( lineCount == lastline  || inBlockSelection )
00591            {
00592              if ( endCol > selEndCol )
00593              {
00594                endCol = selEndCol;
00595                skip = true;
00596              }
00597            }
00598          }
00599 
00600          // HA! this is where we print [part of] a line ;]]
00601          // FIXME Convert this function + related functionality to a separate KatePrintView
00602          KateLineRange range;
00603          range.line = lineCount;
00604          range.startCol = startCol;
00605          range.endCol = endCol;
00606          range.wrap = needWrap;
00607          paint.translate(xstart, y);
00608          renderer.paintTextLine(paint, &range, 0, maxWidth);
00609          paint.resetXForm();
00610          if ( skip )
00611          {
00612            needWrap = false;
00613            startCol = 0;
00614          }
00615          else
00616          {
00617            startCol = endCol;
00618          }
00619 
00620          y += renderer.fontHeight();
00621          _count++;
00622        } // done while ( needWrap )
00623 
00624        lineCount++;
00625      } // done lineCount <= lastline
00626      return true;
00627   }
00628 
00629 #endif 
00630   return false;
00631 }
00632 //END KatePrinter
00633 
00634 #ifndef Q_WS_WIN //TODO: reenable
00635 //BEGIN KatePrintTextSettings
00636 KatePrintTextSettings::KatePrintTextSettings( KPrinter * /*printer*/, QWidget *parent, const char *name )
00637   : KPrintDialogPage( parent, name )
00638 {
00639   setTitle( i18n("Te&xt Settings") );
00640 
00641   QVBoxLayout *lo = new QVBoxLayout ( this );
00642   lo->setSpacing( KDialog::spacingHint() );
00643 
00644   cbSelection = new QCheckBox( i18n("Print &selected text only"), this );
00645   lo->addWidget( cbSelection );
00646 
00647   cbLineNumbers = new QCheckBox( i18n("Print &line numbers"), this );
00648   lo->addWidget( cbLineNumbers );
00649 
00650   cbGuide = new QCheckBox( i18n("Print syntax &guide"), this );
00651   lo->addWidget( cbGuide );
00652 
00653   lo->addStretch( 1 );
00654 
00655   // set defaults - nothing to do :-)
00656 
00657   // whatsthis
00658   QWhatsThis::add( cbSelection, i18n(
00659         "<p>This option is only available if some text is selected in the document.</p>"
00660         "<p>If available and enabled, only the selected text is printed.</p>") );
00661   QWhatsThis::add( cbLineNumbers, i18n(
00662         "<p>If enabled, line numbers will be printed on the left side of the page(s).</p>") );
00663   QWhatsThis::add( cbGuide, i18n(
00664         "<p>Print a box displaying typographical conventions for the document type, as "
00665         "defined by the syntax highlighting being used.") );
00666 }
00667 
00668 void KatePrintTextSettings::getOptions( QMap<QString,QString>& opts, bool )
00669 {
00670   opts["app-kate-printselection"] = cbSelection->isChecked() ? "true" : "false";
00671   opts["app-kate-printlinenumbers"] = cbLineNumbers->isChecked() ? "true" : "false";
00672   opts["app-kate-printguide"] = cbGuide->isChecked() ? "true" : "false" ;
00673 }
00674 
00675 void KatePrintTextSettings::setOptions( const QMap<QString,QString>& opts )
00676 {
00677   QString v;
00678   v = opts["app-kate-printselection"];
00679   if ( ! v.isEmpty() )
00680     cbSelection->setChecked( v == "true" );
00681   v = opts["app-kate-printlinenumbers"];
00682   if ( ! v.isEmpty() )
00683     cbLineNumbers->setChecked( v == "true" );
00684   v = opts["app-kate-printguide"];
00685   if ( ! v.isEmpty() )
00686     cbGuide->setChecked( v == "true" );
00687 }
00688 
00689 void KatePrintTextSettings::enableSelection( bool enable )
00690 {
00691   cbSelection->setEnabled( enable );
00692 }
00693 
00694 //END KatePrintTextSettings
00695 
00696 //BEGIN KatePrintHeaderFooter
00697 KatePrintHeaderFooter::KatePrintHeaderFooter( KPrinter * /*printer*/, QWidget *parent, const char *name )
00698   : KPrintDialogPage( parent, name )
00699 {
00700   setTitle( i18n("Hea&der && Footer") );
00701 
00702   QVBoxLayout *lo = new QVBoxLayout ( this );
00703   uint sp = KDialog::spacingHint();
00704   lo->setSpacing( sp );
00705 
00706   // enable
00707   QHBoxLayout *lo1 = new QHBoxLayout ( lo );
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( lo );
00715   lo2->addWidget( new QLabel( i18n("Header/footer font:"), this ) );
00716   lFontPreview = new QLabel( this );
00717   lFontPreview->setFrameStyle( QFrame::Panel|QFrame::Sunken );
00718   lo2->addWidget( lFontPreview );
00719   lo2->setStretchFactor( lFontPreview, 1 );
00720   QPushButton *btnChooseFont = new QPushButton( i18n("Choo&se Font..."), this );
00721   lo2->addWidget( btnChooseFont );
00722   connect( btnChooseFont, SIGNAL(clicked()), this, SLOT(setHFFont()) );
00723   // header
00724   gbHeader = new QGroupBox( 2, Qt::Horizontal, i18n("Header Properties"), this );
00725   lo->addWidget( gbHeader );
00726 
00727   QLabel *lHeaderFormat = new QLabel( i18n("&Format:"), gbHeader );
00728   QHBox *hbHeaderFormat = new QHBox( gbHeader );
00729   hbHeaderFormat->setSpacing( sp );
00730   leHeaderLeft = new QLineEdit( hbHeaderFormat );
00731   leHeaderCenter = new QLineEdit( hbHeaderFormat );
00732   leHeaderRight = new QLineEdit( hbHeaderFormat );
00733   lHeaderFormat->setBuddy( leHeaderLeft );
00734   new QLabel( i18n("Colors:"), gbHeader );
00735   QHBox *hbHeaderColors = new QHBox( gbHeader );
00736   hbHeaderColors->setSpacing( sp );
00737   QLabel *lHeaderFgCol = new QLabel( i18n("Foreground:"), hbHeaderColors );
00738   kcbtnHeaderFg = new KColorButton( hbHeaderColors );
00739   lHeaderFgCol->setBuddy( kcbtnHeaderFg );
00740   cbHeaderEnableBgColor = new QCheckBox( i18n("Bac&kground"), hbHeaderColors );
00741   kcbtnHeaderBg = new KColorButton( hbHeaderColors );
00742 
00743   gbFooter = new QGroupBox( 2, Qt::Horizontal, i18n("Footer Properties"), this );
00744   lo->addWidget( gbFooter );
00745 
00746   // footer
00747   QLabel *lFooterFormat = new QLabel( i18n("For&mat:"), gbFooter );
00748   QHBox *hbFooterFormat = new QHBox( gbFooter );
00749   hbFooterFormat->setSpacing( sp );
00750   leFooterLeft = new QLineEdit( hbFooterFormat );
00751   leFooterCenter = new QLineEdit( hbFooterFormat );
00752   leFooterRight = new QLineEdit( hbFooterFormat );
00753   lFooterFormat->setBuddy( leFooterLeft );
00754 
00755   new QLabel( i18n("Colors:"), gbFooter );
00756   QHBox *hbFooterColors = new QHBox( gbFooter );
00757   hbFooterColors->setSpacing( sp );
00758   QLabel *lFooterBgCol = new QLabel( i18n("Foreground:"), hbFooterColors );
00759   kcbtnFooterFg = new KColorButton( hbFooterColors );
00760   lFooterBgCol->setBuddy( kcbtnFooterFg );
00761   cbFooterEnableBgColor = new QCheckBox( i18n("&Background"), hbFooterColors );
00762   kcbtnFooterBg = new KColorButton( hbFooterColors );
00763 
00764   lo->addStretch( 1 );
00765 
00766   // user friendly
00767   connect( cbEnableHeader, SIGNAL(toggled(bool)), gbHeader, SLOT(setEnabled(bool)) );
00768   connect( cbEnableFooter, SIGNAL(toggled(bool)), gbFooter, SLOT(setEnabled(bool)) );
00769   connect( cbHeaderEnableBgColor, SIGNAL(toggled(bool)), kcbtnHeaderBg, SLOT(setEnabled(bool)) );
00770   connect( cbFooterEnableBgColor, SIGNAL(toggled(bool)), kcbtnFooterBg, SLOT(setEnabled(bool)) );
00771 
00772   // set defaults
00773   cbEnableHeader->setChecked( true );
00774   leHeaderLeft->setText( "%y" );
00775   leHeaderCenter->setText( "%f" );
00776   leHeaderRight->setText( "%p" );
00777   kcbtnHeaderFg->setColor( QColor("black") );
00778   cbHeaderEnableBgColor->setChecked( true );
00779   kcbtnHeaderBg->setColor( QColor("lightgrey") );
00780 
00781   cbEnableFooter->setChecked( true );
00782   leFooterRight->setText( "%U" );
00783   kcbtnFooterFg->setColor( QColor("black") );
00784   cbFooterEnableBgColor->setChecked( true );
00785   kcbtnFooterBg->setColor( QColor("lightgrey") );
00786 
00787   // whatsthis
00788   QString  s = i18n("<p>Format of the page header. The following tags are supported:</p>");
00789   QString s1 = i18n(
00790       "<ul><li><tt>%u</tt>: current user name</li>"
00791       "<li><tt>%d</tt>: complete date/time in short format</li>"
00792       "<li><tt>%D</tt>: complete date/time in long format</li>"
00793       "<li><tt>%h</tt>: current time</li>"
00794       "<li><tt>%y</tt>: current date in short format</li>"
00795       "<li><tt>%Y</tt>: current date in long format</li>"
00796       "<li><tt>%f</tt>: file name</li>"
00797       "<li><tt>%U</tt>: full URL of the document</li>"
00798       "<li><tt>%p</tt>: page number</li>"
00799       "</ul><br>"
00800       "<u>Note:</u> Do <b>not</b> use the '|' (vertical bar) character.");
00801   QWhatsThis::add(leHeaderRight, s + s1 );
00802   QWhatsThis::add(leHeaderCenter, s + s1 );
00803   QWhatsThis::add(leHeaderLeft, s + s1 );
00804   s = i18n("<p>Format of the page footer. The following tags are supported:</p>");
00805   QWhatsThis::add(leFooterRight, s + s1 );
00806   QWhatsThis::add(leFooterCenter, s + s1 );
00807   QWhatsThis::add(leFooterLeft, s + s1 );
00808 
00809 
00810 }
00811 
00812 void KatePrintHeaderFooter::getOptions(QMap<QString,QString>& opts, bool )
00813 {
00814   opts["app-kate-hffont"] = strFont;
00815 
00816   opts["app-kate-useheader"] = (cbEnableHeader->isChecked() ? "true" : "false");
00817   opts["app-kate-headerfg"] = kcbtnHeaderFg->color().name();
00818   opts["app-kate-headerusebg"] = (cbHeaderEnableBgColor->isChecked() ? "true" : "false");
00819   opts["app-kate-headerbg"] = kcbtnHeaderBg->color().name();
00820   opts["app-kate-headerformat"] = leHeaderLeft->text() + "|" + leHeaderCenter->text() + "|" + leHeaderRight->text();
00821 
00822   opts["app-kate-usefooter"] = (cbEnableFooter->isChecked() ? "true" : "false");
00823   opts["app-kate-footerfg"] = kcbtnFooterFg->color().name();
00824   opts["app-kate-footerusebg"] = (cbFooterEnableBgColor->isChecked() ? "true" : "false");
00825   opts["app-kate-footerbg"] = kcbtnFooterBg->color().name();
00826   opts["app-kate-footerformat"] = leFooterLeft->text() + "|" + leFooterCenter->text() + "|" + leFooterRight->text();
00827 }
00828 
00829 void KatePrintHeaderFooter::setOptions( const QMap<QString,QString>& opts )
00830 {
00831   QString v;
00832   v = opts["app-kate-hffont"];
00833   strFont = v;
00834   QFont f = font();
00835   if ( ! v.isEmpty() )
00836   {
00837     if (!strFont.isEmpty())
00838       f.fromString( strFont );
00839 
00840     lFontPreview->setFont( f );
00841   }
00842   lFontPreview->setText( (f.family() + ", %1pt").arg( f.pointSize() ) );
00843 
00844   v = opts["app-kate-useheader"];
00845   if ( ! v.isEmpty() )
00846     cbEnableHeader->setChecked( v == "true" );
00847   v = opts["app-kate-headerfg"];
00848   if ( ! v.isEmpty() )
00849     kcbtnHeaderFg->setColor( QColor( v ) );
00850   v = opts["app-kate-headerusebg"];
00851   if ( ! v.isEmpty() )
00852     cbHeaderEnableBgColor->setChecked( v == "true" );
00853   v = opts["app-kate-headerbg"];
00854   if ( ! v.isEmpty() )
00855     kcbtnHeaderBg->setColor( QColor( v ) );
00856 
00857   QStringList tags = QStringList::split('|', opts["app-kate-headerformat"], "true");
00858   if (tags.count() == 3)
00859   {
00860     leHeaderLeft->setText(tags[0]);
00861     leHeaderCenter->setText(tags[1]);
00862     leHeaderRight->setText(tags[2]);
00863   }
00864 
00865   v = opts["app-kate-usefooter"];
00866   if ( ! v.isEmpty() )
00867     cbEnableFooter->setChecked( v == "true" );
00868   v = opts["app-kate-footerfg"];
00869   if ( ! v.isEmpty() )
00870     kcbtnFooterFg->setColor( QColor( v ) );
00871   v = opts["app-kate-footerusebg"];
00872   if ( ! v.isEmpty() )
00873     cbFooterEnableBgColor->setChecked( v == "true" );
00874   v = opts["app-kate-footerbg"];
00875   if ( ! v.isEmpty() )
00876     kcbtnFooterBg->setColor( QColor( v ) );
00877 
00878   tags = QStringList::split('|', opts["app-kate-footerformat"], "true");
00879   if (tags.count() == 3)
00880   {
00881     leFooterLeft->setText(tags[0]);
00882     leFooterCenter->setText(tags[1]);
00883     leFooterRight->setText(tags[2]);
00884   }
00885 }
00886 
00887 void KatePrintHeaderFooter::setHFFont()
00888 {
00889   QFont fnt( lFontPreview->font() );
00890   // display a font dialog
00891   if ( KFontDialog::getFont( fnt, false, this ) == KFontDialog::Accepted )
00892   {
00893     // change strFont
00894     strFont = fnt.toString();
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( KPrinter * /*printer*/, QWidget *parent, const char *name )
00906   : KPrintDialogPage( parent, name )
00907 {
00908   setTitle( i18n("L&ayout") );
00909 
00910   QVBoxLayout *lo = new QVBoxLayout ( this );
00911   lo->setSpacing( KDialog::spacingHint() );
00912 
00913   QHBox *hb = new QHBox( this );
00914   lo->addWidget( hb );
00915   QLabel *lSchema = new QLabel( i18n("&Schema:"), hb );
00916   cmbSchema = new QComboBox( false, hb );
00917   lSchema->setBuddy( cmbSchema );
00918 
00919   cbDrawBackground = new QCheckBox( i18n("Draw bac&kground color"), this );
00920   lo->addWidget( cbDrawBackground );
00921 
00922   cbEnableBox = new QCheckBox( i18n("Draw &boxes"), this );
00923   lo->addWidget( cbEnableBox );
00924 
00925   gbBoxProps = new QGroupBox( 2, Qt::Horizontal, i18n("Box Properties"), this );
00926   lo->addWidget( gbBoxProps );
00927 
00928   QLabel *lBoxWidth = new QLabel( i18n("W&idth:"), gbBoxProps );
00929   sbBoxWidth = new QSpinBox( 1, 100, 1, gbBoxProps );
00930   lBoxWidth->setBuddy( sbBoxWidth );
00931 
00932   QLabel *lBoxMargin = new QLabel( i18n("&Margin:"), gbBoxProps );
00933   sbBoxMargin = new QSpinBox( 0, 100, 1, gbBoxProps );
00934   lBoxMargin->setBuddy( sbBoxMargin );
00935 
00936   QLabel *lBoxColor = new QLabel( i18n("Co&lor:"), gbBoxProps );
00937   kcbtnBoxColor = new KColorButton( gbBoxProps );
00938   lBoxColor->setBuddy( kcbtnBoxColor );
00939 
00940   connect( cbEnableBox, SIGNAL(toggled(bool)), gbBoxProps, SLOT(setEnabled(bool)) );
00941 
00942   lo->addStretch( 1 );
00943   // set defaults:
00944   sbBoxMargin->setValue( 6 );
00945   gbBoxProps->setEnabled( false );
00946   cmbSchema->insertStringList (KateFactory::self()->schemaManager()->list ());
00947   cmbSchema->setCurrentItem( 1 );
00948 
00949   // whatsthis
00950   // FIXME uncomment when string freeze is over
00951 //   QWhatsThis::add ( cmbSchema, i18n(
00952 //         "Select the color scheme to use for the print." ) );
00953   QWhatsThis::add( cbDrawBackground, i18n(
00954         "<p>If enabled, the background color of the editor will be used.</p>"
00955         "<p>This may be useful if your color scheme is designed for a dark background.</p>") );
00956   QWhatsThis::add( cbEnableBox, i18n(
00957         "<p>If enabled, a box as defined in the properties below will be drawn "
00958         "around the contents of each page. The Header and Footer will be separated "
00959         "from the contents with a line as well.</p>") );
00960   QWhatsThis::add( sbBoxWidth, i18n(
00961         "The width of the box outline" ) );
00962   QWhatsThis::add( sbBoxMargin, i18n(
00963         "The margin inside boxes, in pixels") );
00964   QWhatsThis::add( kcbtnBoxColor, i18n(
00965         "The line color to use for boxes") );
00966 }
00967 
00968 void KatePrintLayout::getOptions(QMap<QString,QString>& opts, bool )
00969 {
00970   opts["app-kate-colorscheme"] = cmbSchema->currentText();
00971   opts["app-kate-usebackground"] = cbDrawBackground->isChecked() ? "true" : "false";
00972   opts["app-kate-usebox"] = cbEnableBox->isChecked() ? "true" : "false";
00973   opts["app-kate-boxwidth"] = sbBoxWidth->cleanText();
00974   opts["app-kate-boxmargin"] = sbBoxMargin->cleanText();
00975   opts["app-kate-boxcolor"] = kcbtnBoxColor->color().name();
00976 }
00977 
00978 void KatePrintLayout::setOptions( const QMap<QString,QString>& opts )
00979 {
00980   QString v;
00981   v = opts["app-kate-colorscheme"];
00982   if ( ! v.isEmpty() )
00983     cmbSchema->setCurrentItem( KateFactory::self()->schemaManager()->number( v ) );
00984   v = opts["app-kate-usebackground"];
00985   if ( ! v.isEmpty() )
00986     cbDrawBackground->setChecked( v == "true" );
00987   v = opts["app-kate-usebox"];
00988   if ( ! v.isEmpty() )
00989     cbEnableBox->setChecked( v == "true" );
00990   v = opts["app-kate-boxwidth"];
00991   if ( ! v.isEmpty() )
00992     sbBoxWidth->setValue( v.toInt() );
00993   v = opts["app-kate-boxmargin"];
00994   if ( ! v.isEmpty() )
00995     sbBoxMargin->setValue( v.toInt() );
00996   v = opts["app-kate-boxcolor"];
00997   if ( ! v.isEmpty() )
00998     kcbtnBoxColor->setColor( QColor( v ) );
00999 }
01000 //END KatePrintLayout
01001 
01002 #include "kateprinter.moc"
01003 #endif 
01004 
01005 // 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

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
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