summaryrefslogtreecommitdiffstats
path: root/kate/part/kateprinter.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch)
tree5ac38a06f3dde268dc7927dc155896926aaf7012 /kate/part/kateprinter.cpp
downloadtdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz
tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kate/part/kateprinter.cpp')
-rw-r--r--kate/part/kateprinter.cpp1005
1 files changed, 1005 insertions, 0 deletions
diff --git a/kate/part/kateprinter.cpp b/kate/part/kateprinter.cpp
new file mode 100644
index 000000000..380c50216
--- /dev/null
+++ b/kate/part/kateprinter.cpp
@@ -0,0 +1,1005 @@
+/*
+ * This file is part of the KDE libraries
+ * Copyright (c) 2001-2002 Michael Goffioul <kdeprint@swing.be>
+ * Complete rewrite on Sat Jun 15 2002 (c) Anders Lund <anders@alweb.dk>
+ * Copyright (c) 2002, 2003 Anders Lund <anders@alweb.dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#include "kateprinter.h"
+
+#include <kateconfig.h>
+#include <katedocument.h>
+#include <katefactory.h>
+#include <katehighlight.h>
+#include <katelinerange.h>
+#include <katerenderer.h>
+#include <kateschema.h>
+#include <katetextline.h>
+
+#include <kapplication.h>
+#include <kcolorbutton.h>
+#include <kdebug.h>
+#include <kdialog.h> // for spacingHint()
+#include <kfontdialog.h>
+#include <klocale.h>
+#include <kprinter.h>
+#include <kurl.h>
+#include <kuser.h> // for loginName
+
+#include <qpainter.h>
+#include <qpopupmenu.h>
+#include <qpaintdevicemetrics.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qgroupbox.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qspinbox.h>
+#include <qstringlist.h>
+#include <qwhatsthis.h>
+
+//BEGIN KatePrinter
+bool KatePrinter::print (KateDocument *doc)
+{
+#ifndef Q_WS_WIN //TODO: reenable
+ KPrinter printer;
+
+ // docname is now always there, including the right Untitled name
+ printer.setDocName(doc->docName());
+
+ KatePrintTextSettings *kpts = new KatePrintTextSettings(&printer, NULL);
+ kpts->enableSelection( doc->hasSelection() );
+ printer.addDialogPage( kpts );
+ printer.addDialogPage( new KatePrintHeaderFooter(&printer, NULL) );
+ printer.addDialogPage( new KatePrintLayout(&printer, NULL) );
+
+ if ( printer.setup( kapp->mainWidget(), i18n("Print %1").arg(printer.docName()) ) )
+ {
+ KateRenderer renderer(doc);
+ //renderer.config()->setSchema (1);
+ renderer.setPrinterFriendly(true);
+
+ QPainter paint( &printer );
+ QPaintDeviceMetrics pdm( &printer );
+ /*
+ We work in tree cycles:
+ 1) initialize variables and retrieve print settings
+ 2) prepare data according to those settings
+ 3) draw to the printer
+ */
+ uint pdmWidth = pdm.width();
+ uint y = 0;
+ uint xstart = 0; // beginning point for painting lines
+ uint lineCount = 0;
+ uint maxWidth = pdmWidth;
+ uint headerWidth = pdmWidth;
+ int startCol = 0;
+ int endCol = 0;
+ bool needWrap = true;
+ bool pageStarted = true;
+
+ // Text Settings Page
+ bool selectionOnly = ( doc->hasSelection() &&
+ ( printer.option("app-kate-printselection") == "true" ) );
+ int selStartCol = 0;
+ int selEndCol = 0;
+
+ bool useGuide = ( printer.option("app-kate-printguide") == "true" );
+ int guideHeight = 0;
+ int guideCols = 0;
+
+ bool printLineNumbers = ( printer.option("app-kate-printlinenumbers") == "true" );
+ uint lineNumberWidth( 0 );
+
+ // Header/Footer Page
+ QFont headerFont; // used for header/footer
+ QString f = printer.option("app-kate-hffont");
+ if (!f.isEmpty())
+ headerFont.fromString( f );
+
+ bool useHeader = (printer.option("app-kate-useheader") == "true");
+ QColor headerBgColor(printer.option("app-kate-headerbg"));
+ QColor headerFgColor(printer.option("app-kate-headerfg"));
+ uint headerHeight( 0 ); // further init only if needed
+ QStringList headerTagList; // do
+ bool headerDrawBg = false; // do
+
+ bool useFooter = (printer.option("app-kate-usefooter") == "true");
+ QColor footerBgColor(printer.option("app-kate-footerbg"));
+ QColor footerFgColor(printer.option("app-kate-footerfg"));
+ uint footerHeight( 0 ); // further init only if needed
+ QStringList footerTagList = 0; // do
+ bool footerDrawBg = 0; // do
+
+ // Layout Page
+ renderer.config()->setSchema( KateFactory::self()->schemaManager()->number(
+ printer.option("app-kate-colorscheme") ) );
+ bool useBackground = ( printer.option("app-kate-usebackground") == "true" );
+ bool useBox = (printer.option("app-kate-usebox") == "true");
+ int boxWidth(printer.option("app-kate-boxwidth").toInt());
+ QColor boxColor(printer.option("app-kate-boxcolor"));
+ int innerMargin = useBox ? printer.option("app-kate-boxmargin").toInt() : 6;
+
+ // Post initialization
+ uint maxHeight = (useBox ? pdm.height()-innerMargin : pdm.height());
+ uint currentPage( 1 );
+ uint lastline = doc->lastLine(); // nessecary to print selection only
+ uint firstline( 0 );
+
+ KateHlItemDataList ilist;
+
+ if (useGuide)
+ doc->highlight()->getKateHlItemDataListCopy (renderer.config()->schema(), ilist);
+
+ /*
+ Now on for preparations...
+ during preparations, variable names starting with a "_" means
+ those variables are local to the enclosing block.
+ */
+ {
+ if ( selectionOnly )
+ {
+ // set a line range from the first selected line to the last
+ firstline = doc->selStartLine();
+ selStartCol = doc->selStartCol();
+ lastline = doc->selEndLine();
+ selEndCol = doc->selEndCol();
+
+ lineCount = firstline;
+ }
+
+ if ( printLineNumbers )
+ {
+ // figure out the horiizontal space required
+ QString s( QString("%1 ").arg( doc->numLines() ) );
+ s.fill('5', -1); // some non-fixed fonts haven't equally wide numbers
+ // FIXME calculate which is actually the widest...
+ lineNumberWidth = renderer.currentFontMetrics()->width( s );
+ // a small space between the line numbers and the text
+ int _adj = renderer.currentFontMetrics()->width( "5" );
+ // adjust available width and set horizontal start point for data
+ maxWidth -= (lineNumberWidth + _adj);
+ xstart += lineNumberWidth + _adj;
+ }
+
+ if ( useHeader || useFooter )
+ {
+ // Set up a tag map
+ // This retrieves all tags, ued or not, but
+ // none of theese operations should be expensive,
+ // and searcing each tag in the format strings is avoided.
+ QDateTime dt = QDateTime::currentDateTime();
+ QMap<QString,QString> tags;
+
+ KUser u (KUser::UseRealUserID);
+ tags["u"] = u.loginName();
+
+ tags["d"] = KGlobal::locale()->formatDateTime(dt, true, false);
+ tags["D"] = KGlobal::locale()->formatDateTime(dt, false, false);
+ tags["h"] = KGlobal::locale()->formatTime(dt.time(), false);
+ tags["y"] = KGlobal::locale()->formatDate(dt.date(), true);
+ tags["Y"] = KGlobal::locale()->formatDate(dt.date(), false);
+ tags["f"] = doc->url().fileName();
+ tags["U"] = doc->url().prettyURL();
+ if ( selectionOnly )
+ {
+ QString s( i18n("(Selection of) ") );
+ tags["f"].prepend( s );
+ tags["U"].prepend( s );
+ }
+
+ QRegExp reTags( "%([dDfUhuyY])" ); // TODO tjeck for "%%<TAG>"
+
+ if (useHeader)
+ {
+ headerDrawBg = ( printer.option("app-kate-headerusebg") == "true" );
+ headerHeight = QFontMetrics( headerFont ).height();
+ if ( useBox || headerDrawBg )
+ headerHeight += innerMargin * 2;
+ else
+ headerHeight += 1 + QFontMetrics( headerFont ).leading();
+
+ QString headerTags = printer.option("app-kate-headerformat");
+ int pos = reTags.search( headerTags );
+ QString rep;
+ while ( pos > -1 )
+ {
+ rep = tags[reTags.cap( 1 )];
+ headerTags.replace( (uint)pos, 2, rep );
+ pos += rep.length();
+ pos = reTags.search( headerTags, pos );
+ }
+ headerTagList = QStringList::split('|', headerTags, true);
+
+ if (!headerBgColor.isValid())
+ headerBgColor = Qt::lightGray;
+ if (!headerFgColor.isValid())
+ headerFgColor = Qt::black;
+ }
+
+ if (useFooter)
+ {
+ footerDrawBg = ( printer.option("app-kate-footerusebg") == "true" );
+ footerHeight = QFontMetrics( headerFont ).height();
+ if ( useBox || footerDrawBg )
+ footerHeight += 2*innerMargin;
+ else
+ footerHeight += 1; // line only
+
+ QString footerTags = printer.option("app-kate-footerformat");
+ int pos = reTags.search( footerTags );
+ QString rep;
+ while ( pos > -1 )
+ {
+ rep = tags[reTags.cap( 1 )];
+ footerTags.replace( (uint)pos, 2, rep );
+ pos += rep.length();
+ pos = reTags.search( footerTags, pos );
+ }
+
+ footerTagList = QStringList::split('|', footerTags, true);
+ if (!footerBgColor.isValid())
+ footerBgColor = Qt::lightGray;
+ if (!footerFgColor.isValid())
+ footerFgColor = Qt::black;
+ // adjust maxheight, so we can know when/where to print footer
+ maxHeight -= footerHeight;
+ }
+ } // if ( useHeader || useFooter )
+
+ if ( useBackground )
+ {
+ if ( ! useBox )
+ {
+ xstart += innerMargin;
+ maxWidth -= innerMargin * 2;
+ }
+ }
+
+ if ( useBox )
+ {
+ if (!boxColor.isValid())
+ boxColor = Qt::black;
+ if (boxWidth < 1) // shouldn't be pssible no more!
+ boxWidth = 1;
+ // set maxwidth to something sensible
+ maxWidth -= ( ( boxWidth + innerMargin ) * 2 );
+ xstart += boxWidth + innerMargin;
+ // maxheight too..
+ maxHeight -= boxWidth;
+ }
+ else
+ boxWidth = 0;
+
+ if ( useGuide )
+ {
+ // calculate the height required
+ // the number of columns is a side effect, saved for drawing time
+ // first width is needed
+ int _w = pdmWidth - innerMargin * 2;
+ if ( useBox )
+ _w -= boxWidth * 2;
+ else
+ {
+ if ( useBackground )
+ _w -= ( innerMargin * 2 );
+ _w -= 2; // 1 px line on each side
+ }
+
+ // base of height: margins top/bottom, above and below tetle sep line
+ guideHeight = ( innerMargin * 4 ) + 1;
+
+ // get a title and add the height required to draw it
+ QString _title = i18n("Typographical Conventions for %1").arg(doc->highlight()->name());
+ guideHeight += paint.boundingRect( 0, 0, _w, 1000, Qt::AlignTop|Qt::AlignHCenter, _title ).height();
+
+ // see how many columns we can fit in
+ int _widest( 0 );
+
+ QPtrListIterator<KateHlItemData> it( ilist );
+ KateHlItemData *_d;
+
+ int _items ( 0 );
+ while ( ( _d = it.current()) != 0 )
+ {
+ _widest = kMax( _widest, ((QFontMetrics)(
+ _d->bold() ?
+ _d->italic() ?
+ renderer.config()->fontStruct()->myFontMetricsBI :
+ renderer.config()->fontStruct()->myFontMetricsBold :
+ _d->italic() ?
+ renderer.config()->fontStruct()->myFontMetricsItalic :
+ renderer.config()->fontStruct()->myFontMetrics
+ ) ).width( _d->name ) );
+ _items++;
+ ++it;
+ }
+ guideCols = _w/( _widest + innerMargin );
+ // add height for required number of lines needed given columns
+ guideHeight += renderer.fontHeight() * ( _items/guideCols );
+ if ( _items%guideCols )
+ guideHeight += renderer.fontHeight();
+ }
+
+ // now that we know the vertical amount of space needed,
+ // it is possible to calculate the total number of pages
+ // if needed, that is if any header/footer tag contains "%P".
+ if ( headerTagList.grep("%P").count() || footerTagList.grep("%P").count() )
+ {
+ kdDebug(13020)<<"'%P' found! calculating number of pages..."<<endl;
+ uint _pages = 0;
+ uint _ph = maxHeight;
+ if ( useHeader )
+ _ph -= ( headerHeight + innerMargin );
+ if ( useFooter )
+ _ph -= innerMargin;
+ int _lpp = _ph / renderer.fontHeight();
+ uint _lt = 0, _c=0;
+
+ // add space for guide if required
+ if ( useGuide )
+ _lt += (guideHeight + (renderer.fontHeight() /2)) / renderer.fontHeight();
+ long _lw;
+ for ( uint i = firstline; i < lastline; i++ )
+ {
+ _lw = renderer.textWidth( doc->kateTextLine( i ), -1 );
+ while ( _lw >= 0 )
+ {
+ _c++;
+ _lt++;
+ if ( (int)_lt == _lpp )
+ {
+ _pages++;
+ _lt = 0;
+ }
+ _lw -= maxWidth;
+ if ( ! _lw ) _lw--; // skip lines matching exactly!
+ }
+ }
+ if ( _lt ) _pages++; // last page
+
+ // substitute both tag lists
+ QString re("%P");
+ QStringList::Iterator it;
+ for ( it=headerTagList.begin(); it!=headerTagList.end(); ++it )
+ (*it).replace( re, QString( "%1" ).arg( _pages ) );
+ for ( it=footerTagList.begin(); it!=footerTagList.end(); ++it )
+ (*it).replace( re, QString( "%1" ).arg( _pages ) );
+ }
+ } // end prepare block
+
+ /*
+ On to draw something :-)
+ */
+ uint _count = 0;
+ while ( lineCount <= lastline )
+ {
+ startCol = 0;
+ endCol = 0;
+ needWrap = true;
+
+ while (needWrap)
+ {
+ if ( y + renderer.fontHeight() >= (uint)(maxHeight) )
+ {
+ kdDebug(13020)<<"Starting new page, "<<_count<<" lines up to now."<<endl;
+ printer.newPage();
+ currentPage++;
+ pageStarted = true;
+ y=0;
+ }
+
+ if ( pageStarted )
+ {
+
+ if ( useHeader )
+ {
+ paint.setPen(headerFgColor);
+ paint.setFont(headerFont);
+ if ( headerDrawBg )
+ paint.fillRect(0, 0, headerWidth, headerHeight, headerBgColor);
+ if (headerTagList.count() == 3)
+ {
+ int valign = ( (useBox||headerDrawBg||useBackground) ?
+ Qt::AlignVCenter : Qt::AlignTop );
+ int align = valign|Qt::AlignLeft;
+ int marg = ( useBox || headerDrawBg ) ? innerMargin : 0;
+ if ( useBox ) marg += boxWidth;
+ QString s;
+ for (int i=0; i<3; i++)
+ {
+ s = headerTagList[i];
+ if (s.find("%p") != -1) s.replace("%p", QString::number(currentPage));
+ paint.drawText(marg, 0, headerWidth-(marg*2), headerHeight, align, s);
+ align = valign|(i == 0 ? Qt::AlignHCenter : Qt::AlignRight);
+ }
+ }
+ if ( ! ( headerDrawBg || useBox || useBackground ) ) // draw a 1 px (!?) line to separate header from contents
+ {
+ paint.drawLine( 0, headerHeight-1, headerWidth, headerHeight-1 );
+ //y += 1; now included in headerHeight
+ }
+ y += headerHeight + innerMargin;
+ }
+
+ if ( useFooter )
+ {
+ if ( ! ( footerDrawBg || useBox || useBackground ) ) // draw a 1 px (!?) line to separate footer from contents
+ paint.drawLine( 0, maxHeight + innerMargin - 1, headerWidth, maxHeight + innerMargin - 1 );
+ if ( footerDrawBg )
+ paint.fillRect(0, maxHeight+innerMargin+boxWidth, headerWidth, footerHeight, footerBgColor);
+ if (footerTagList.count() == 3)
+ {
+ int align = Qt::AlignVCenter|Qt::AlignLeft;
+ int marg = ( useBox || footerDrawBg ) ? innerMargin : 0;
+ if ( useBox ) marg += boxWidth;
+ QString s;
+ for (int i=0; i<3; i++)
+ {
+ s = footerTagList[i];
+ if (s.find("%p") != -1) s.replace("%p", QString::number(currentPage));
+ paint.drawText(marg, maxHeight+innerMargin, headerWidth-(marg*2), footerHeight, align, s);
+ align = Qt::AlignVCenter|(i == 0 ? Qt::AlignHCenter : Qt::AlignRight);
+ }
+ }
+ } // done footer
+
+ if ( useBackground )
+ {
+ // If we have a box, or the header/footer has backgrounds, we want to paint
+ // to the border of those. Otherwise just the contents area.
+ int _y = y, _h = maxHeight - y;
+ if ( useBox )
+ {
+ _y -= innerMargin;
+ _h += 2 * innerMargin;
+ }
+ else
+ {
+ if ( headerDrawBg )
+ {
+ _y -= innerMargin;
+ _h += innerMargin;
+ }
+ if ( footerDrawBg )
+ {
+ _h += innerMargin;
+ }
+ }
+ paint.fillRect( 0, _y, pdmWidth, _h, renderer.config()->backgroundColor());
+ }
+
+ if ( useBox )
+ {
+ paint.setPen(QPen(boxColor, boxWidth));
+ paint.drawRect(0, 0, pdmWidth, pdm.height());
+ if (useHeader)
+ paint.drawLine(0, headerHeight, headerWidth, headerHeight);
+ else
+ y += innerMargin;
+
+ if ( useFooter ) // drawline is not trustable, grr.
+ paint.fillRect( 0, maxHeight+innerMargin, headerWidth, boxWidth, boxColor );
+ }
+
+ if ( useGuide && currentPage == 1 )
+ { // FIXME - this may span more pages...
+ // draw a box unless we have boxes, in which case we end with a box line
+
+ // use color of dsNormal for the title string and the hline
+ KateAttributeList _dsList;
+ KateHlManager::self()->getDefaults ( renderer.config()->schema(), _dsList );
+ paint.setPen( _dsList.at(0)->textColor() );
+ int _marg = 0; // this could be available globally!??
+ if ( useBox )
+ {
+ _marg += (2*boxWidth) + (2*innerMargin);
+ paint.fillRect( 0, y+guideHeight-innerMargin-boxWidth, headerWidth, boxWidth, boxColor );
+ }
+ else
+ {
+ if ( useBackground )
+ _marg += 2*innerMargin;
+ paint.drawRect( _marg, y, pdmWidth-(2*_marg), guideHeight );
+ _marg += 1;
+ y += 1 + innerMargin;
+ }
+ // draw a title string
+ paint.setFont( renderer.config()->fontStruct()->myFontBold );
+ QRect _r;
+ paint.drawText( _marg, y, pdmWidth-(2*_marg), maxHeight - y,
+ Qt::AlignTop|Qt::AlignHCenter,
+ i18n("Typographical Conventions for %1").arg(doc->highlight()->name()), -1, &_r );
+ int _w = pdmWidth - (_marg*2) - (innerMargin*2);
+ int _x = _marg + innerMargin;
+ y += _r.height() + innerMargin;
+ paint.drawLine( _x, y, _x + _w, y );
+ y += 1 + innerMargin;
+ // draw attrib names using their styles
+
+ QPtrListIterator<KateHlItemData> _it( ilist );
+ KateHlItemData *_d;
+ int _cw = _w/guideCols;
+ int _i(0);
+
+ while ( ( _d = _it.current() ) != 0 )
+ {
+ paint.setPen( renderer.attribute(_i)->textColor() );
+ paint.setFont( renderer.attribute(_i)->font( *renderer.currentFont() ) );
+ paint.drawText(( _x + ((_i%guideCols)*_cw)), y, _cw, renderer.fontHeight(),
+ Qt::AlignVCenter|Qt::AlignLeft, _d->name, -1, &_r );
+ _i++;
+ if ( _i && ! ( _i%guideCols ) ) y += renderer.fontHeight();
+ ++_it;
+ }
+ if ( _i%guideCols ) y += renderer.fontHeight();// last row not full
+ y += ( useBox ? boxWidth : 1 ) + (innerMargin*2);
+ }
+
+ pageStarted = false;
+ } // pageStarted; move on to contents:)
+
+ if ( printLineNumbers && ! startCol ) // don't repeat!
+ {
+ paint.setFont( renderer.config()->fontStruct()->font( false, false ) );
+ paint.setPen( renderer.config()->lineNumberColor() );
+ paint.drawText( (( useBox || useBackground ) ? innerMargin : 0), y,
+ lineNumberWidth, renderer.fontHeight(),
+ Qt::AlignRight, QString("%1").arg( lineCount + 1 ) );
+ }
+ endCol = renderer.textWidth(doc->kateTextLine(lineCount), startCol, maxWidth, &needWrap);
+
+ if ( endCol < startCol )
+ {
+ //kdDebug(13020)<<"--- Skipping garbage, line: "<<lineCount<<" start: "<<startCol<<" end: "<<endCol<<" real EndCol; "<< buffer->line(lineCount)->length()<< " !?"<<endl;
+ lineCount++;
+ continue; // strange case...
+ // Happens if the line fits exactly.
+ // When it happens, a line of garbage would be printed.
+ // FIXME Most likely this is an error in textWidth(),
+ // failing to correctly set needWrap to false in this case?
+ }
+
+ // if we print only selection:
+ // print only selected range of chars.
+ bool skip = false;
+ if ( selectionOnly )
+ {
+ bool inBlockSelection = ( doc->blockSelectionMode() && lineCount >= firstline && lineCount <= lastline );
+ if ( lineCount == firstline || inBlockSelection )
+ {
+ if ( startCol < selStartCol )
+ startCol = selStartCol;
+ }
+ if ( lineCount == lastline || inBlockSelection )
+ {
+ if ( endCol > selEndCol )
+ {
+ endCol = selEndCol;
+ skip = true;
+ }
+ }
+ }
+
+ // HA! this is where we print [part of] a line ;]]
+ // FIXME Convert this function + related functionality to a separate KatePrintView
+ KateLineRange range;
+ range.line = lineCount;
+ range.startCol = startCol;
+ range.endCol = endCol;
+ range.wrap = needWrap;
+ paint.translate(xstart, y);
+ renderer.paintTextLine(paint, &range, 0, maxWidth);
+ paint.resetXForm();
+ if ( skip )
+ {
+ needWrap = false;
+ startCol = 0;
+ }
+ else
+ {
+ startCol = endCol;
+ }
+
+ y += renderer.fontHeight();
+ _count++;
+ } // done while ( needWrap )
+
+ lineCount++;
+ } // done lineCount <= lastline
+ return true;
+ }
+
+#endif //!Q_WS_WIN
+ return false;
+}
+//END KatePrinter
+
+#ifndef Q_WS_WIN //TODO: reenable
+//BEGIN KatePrintTextSettings
+KatePrintTextSettings::KatePrintTextSettings( KPrinter * /*printer*/, QWidget *parent, const char *name )
+ : KPrintDialogPage( parent, name )
+{
+ setTitle( i18n("Te&xt Settings") );
+
+ QVBoxLayout *lo = new QVBoxLayout ( this );
+ lo->setSpacing( KDialog::spacingHint() );
+
+ cbSelection = new QCheckBox( i18n("Print &selected text only"), this );
+ lo->addWidget( cbSelection );
+
+ cbLineNumbers = new QCheckBox( i18n("Print &line numbers"), this );
+ lo->addWidget( cbLineNumbers );
+
+ cbGuide = new QCheckBox( i18n("Print syntax &guide"), this );
+ lo->addWidget( cbGuide );
+
+ lo->addStretch( 1 );
+
+ // set defaults - nothing to do :-)
+
+ // whatsthis
+ QWhatsThis::add( cbSelection, i18n(
+ "<p>This option is only available if some text is selected in the document.</p>"
+ "<p>If available and enabled, only the selected text is printed.</p>") );
+ QWhatsThis::add( cbLineNumbers, i18n(
+ "<p>If enabled, line numbers will be printed on the left side of the page(s).</p>") );
+ QWhatsThis::add( cbGuide, i18n(
+ "<p>Print a box displaying typographical conventions for the document type, as "
+ "defined by the syntax highlighting being used.") );
+}
+
+void KatePrintTextSettings::getOptions( QMap<QString,QString>& opts, bool )
+{
+ opts["app-kate-printselection"] = cbSelection->isChecked() ? "true" : "false";
+ opts["app-kate-printlinenumbers"] = cbLineNumbers->isChecked() ? "true" : "false";
+ opts["app-kate-printguide"] = cbGuide->isChecked() ? "true" : "false" ;
+}
+
+void KatePrintTextSettings::setOptions( const QMap<QString,QString>& opts )
+{
+ QString v;
+ v = opts["app-kate-printselection"];
+ if ( ! v.isEmpty() )
+ cbSelection->setChecked( v == "true" );
+ v = opts["app-kate-printlinenumbers"];
+ if ( ! v.isEmpty() )
+ cbLineNumbers->setChecked( v == "true" );
+ v = opts["app-kate-printguide"];
+ if ( ! v.isEmpty() )
+ cbGuide->setChecked( v == "true" );
+}
+
+void KatePrintTextSettings::enableSelection( bool enable )
+{
+ cbSelection->setEnabled( enable );
+}
+
+//END KatePrintTextSettings
+
+//BEGIN KatePrintHeaderFooter
+KatePrintHeaderFooter::KatePrintHeaderFooter( KPrinter * /*printer*/, QWidget *parent, const char *name )
+ : KPrintDialogPage( parent, name )
+{
+ setTitle( i18n("Hea&der && Footer") );
+
+ QVBoxLayout *lo = new QVBoxLayout ( this );
+ uint sp = KDialog::spacingHint();
+ lo->setSpacing( sp );
+
+ // enable
+ QHBoxLayout *lo1 = new QHBoxLayout ( lo );
+ cbEnableHeader = new QCheckBox( i18n("Pr&int header"), this );
+ lo1->addWidget( cbEnableHeader );
+ cbEnableFooter = new QCheckBox( i18n("Pri&nt footer"), this );
+ lo1->addWidget( cbEnableFooter );
+
+ // font
+ QHBoxLayout *lo2 = new QHBoxLayout( lo );
+ lo2->addWidget( new QLabel( i18n("Header/footer font:"), this ) );
+ lFontPreview = new QLabel( this );
+ lFontPreview->setFrameStyle( QFrame::Panel|QFrame::Sunken );
+ lo2->addWidget( lFontPreview );
+ lo2->setStretchFactor( lFontPreview, 1 );
+ QPushButton *btnChooseFont = new QPushButton( i18n("Choo&se Font..."), this );
+ lo2->addWidget( btnChooseFont );
+ connect( btnChooseFont, SIGNAL(clicked()), this, SLOT(setHFFont()) );
+ // header
+ gbHeader = new QGroupBox( 2, Qt::Horizontal, i18n("Header Properties"), this );
+ lo->addWidget( gbHeader );
+
+ QLabel *lHeaderFormat = new QLabel( i18n("&Format:"), gbHeader );
+ QHBox *hbHeaderFormat = new QHBox( gbHeader );
+ hbHeaderFormat->setSpacing( sp );
+ leHeaderLeft = new QLineEdit( hbHeaderFormat );
+ leHeaderCenter = new QLineEdit( hbHeaderFormat );
+ leHeaderRight = new QLineEdit( hbHeaderFormat );
+ lHeaderFormat->setBuddy( leHeaderLeft );
+ new QLabel( i18n("Colors:"), gbHeader );
+ QHBox *hbHeaderColors = new QHBox( gbHeader );
+ hbHeaderColors->setSpacing( sp );
+ QLabel *lHeaderFgCol = new QLabel( i18n("Foreground:"), hbHeaderColors );
+ kcbtnHeaderFg = new KColorButton( hbHeaderColors );
+ lHeaderFgCol->setBuddy( kcbtnHeaderFg );
+ cbHeaderEnableBgColor = new QCheckBox( i18n("Bac&kground"), hbHeaderColors );
+ kcbtnHeaderBg = new KColorButton( hbHeaderColors );
+
+ gbFooter = new QGroupBox( 2, Qt::Horizontal, i18n("Footer Properties"), this );
+ lo->addWidget( gbFooter );
+
+ // footer
+ QLabel *lFooterFormat = new QLabel( i18n("For&mat:"), gbFooter );
+ QHBox *hbFooterFormat = new QHBox( gbFooter );
+ hbFooterFormat->setSpacing( sp );
+ leFooterLeft = new QLineEdit( hbFooterFormat );
+ leFooterCenter = new QLineEdit( hbFooterFormat );
+ leFooterRight = new QLineEdit( hbFooterFormat );
+ lFooterFormat->setBuddy( leFooterLeft );
+
+ new QLabel( i18n("Colors:"), gbFooter );
+ QHBox *hbFooterColors = new QHBox( gbFooter );
+ hbFooterColors->setSpacing( sp );
+ QLabel *lFooterBgCol = new QLabel( i18n("Foreground:"), hbFooterColors );
+ kcbtnFooterFg = new KColorButton( hbFooterColors );
+ lFooterBgCol->setBuddy( kcbtnFooterFg );
+ cbFooterEnableBgColor = new QCheckBox( i18n("&Background"), hbFooterColors );
+ kcbtnFooterBg = new KColorButton( hbFooterColors );
+
+ lo->addStretch( 1 );
+
+ // user friendly
+ connect( cbEnableHeader, SIGNAL(toggled(bool)), gbHeader, SLOT(setEnabled(bool)) );
+ connect( cbEnableFooter, SIGNAL(toggled(bool)), gbFooter, SLOT(setEnabled(bool)) );
+ connect( cbHeaderEnableBgColor, SIGNAL(toggled(bool)), kcbtnHeaderBg, SLOT(setEnabled(bool)) );
+ connect( cbFooterEnableBgColor, SIGNAL(toggled(bool)), kcbtnFooterBg, SLOT(setEnabled(bool)) );
+
+ // set defaults
+ cbEnableHeader->setChecked( true );
+ leHeaderLeft->setText( "%y" );
+ leHeaderCenter->setText( "%f" );
+ leHeaderRight->setText( "%p" );
+ kcbtnHeaderFg->setColor( QColor("black") );
+ cbHeaderEnableBgColor->setChecked( true );
+ kcbtnHeaderBg->setColor( QColor("lightgrey") );
+
+ cbEnableFooter->setChecked( true );
+ leFooterRight->setText( "%U" );
+ kcbtnFooterFg->setColor( QColor("black") );
+ cbFooterEnableBgColor->setChecked( true );
+ kcbtnFooterBg->setColor( QColor("lightgrey") );
+
+ // whatsthis
+ QString s = i18n("<p>Format of the page header. The following tags are supported:</p>");
+ QString s1 = i18n(
+ "<ul><li><tt>%u</tt>: current user name</li>"
+ "<li><tt>%d</tt>: complete date/time in short format</li>"
+ "<li><tt>%D</tt>: complete date/time in long format</li>"
+ "<li><tt>%h</tt>: current time</li>"
+ "<li><tt>%y</tt>: current date in short format</li>"
+ "<li><tt>%Y</tt>: current date in long format</li>"
+ "<li><tt>%f</tt>: file name</li>"
+ "<li><tt>%U</tt>: full URL of the document</li>"
+ "<li><tt>%p</tt>: page number</li>"
+ "</ul><br>"
+ "<u>Note:</u> Do <b>not</b> use the '|' (vertical bar) character.");
+ QWhatsThis::add(leHeaderRight, s + s1 );
+ QWhatsThis::add(leHeaderCenter, s + s1 );
+ QWhatsThis::add(leHeaderLeft, s + s1 );
+ s = i18n("<p>Format of the page footer. The following tags are supported:</p>");
+ QWhatsThis::add(leFooterRight, s + s1 );
+ QWhatsThis::add(leFooterCenter, s + s1 );
+ QWhatsThis::add(leFooterLeft, s + s1 );
+
+
+}
+
+void KatePrintHeaderFooter::getOptions(QMap<QString,QString>& opts, bool )
+{
+ opts["app-kate-hffont"] = strFont;
+
+ opts["app-kate-useheader"] = (cbEnableHeader->isChecked() ? "true" : "false");
+ opts["app-kate-headerfg"] = kcbtnHeaderFg->color().name();
+ opts["app-kate-headerusebg"] = (cbHeaderEnableBgColor->isChecked() ? "true" : "false");
+ opts["app-kate-headerbg"] = kcbtnHeaderBg->color().name();
+ opts["app-kate-headerformat"] = leHeaderLeft->text() + "|" + leHeaderCenter->text() + "|" + leHeaderRight->text();
+
+ opts["app-kate-usefooter"] = (cbEnableFooter->isChecked() ? "true" : "false");
+ opts["app-kate-footerfg"] = kcbtnFooterFg->color().name();
+ opts["app-kate-footerusebg"] = (cbFooterEnableBgColor->isChecked() ? "true" : "false");
+ opts["app-kate-footerbg"] = kcbtnFooterBg->color().name();
+ opts["app-kate-footerformat"] = leFooterLeft->text() + "|" + leFooterCenter->text() + "|" + leFooterRight->text();
+}
+
+void KatePrintHeaderFooter::setOptions( const QMap<QString,QString>& opts )
+{
+ QString v;
+ v = opts["app-kate-hffont"];
+ strFont = v;
+ QFont f = font();
+ if ( ! v.isEmpty() )
+ {
+ if (!strFont.isEmpty())
+ f.fromString( strFont );
+
+ lFontPreview->setFont( f );
+ }
+ lFontPreview->setText( (f.family() + ", %1pt").arg( f.pointSize() ) );
+
+ v = opts["app-kate-useheader"];
+ if ( ! v.isEmpty() )
+ cbEnableHeader->setChecked( v == "true" );
+ v = opts["app-kate-headerfg"];
+ if ( ! v.isEmpty() )
+ kcbtnHeaderFg->setColor( QColor( v ) );
+ v = opts["app-kate-headerusebg"];
+ if ( ! v.isEmpty() )
+ cbHeaderEnableBgColor->setChecked( v == "true" );
+ v = opts["app-kate-headerbg"];
+ if ( ! v.isEmpty() )
+ kcbtnHeaderBg->setColor( QColor( v ) );
+
+ QStringList tags = QStringList::split('|', opts["app-kate-headerformat"], "true");
+ if (tags.count() == 3)
+ {
+ leHeaderLeft->setText(tags[0]);
+ leHeaderCenter->setText(tags[1]);
+ leHeaderRight->setText(tags[2]);
+ }
+
+ v = opts["app-kate-usefooter"];
+ if ( ! v.isEmpty() )
+ cbEnableFooter->setChecked( v == "true" );
+ v = opts["app-kate-footerfg"];
+ if ( ! v.isEmpty() )
+ kcbtnFooterFg->setColor( QColor( v ) );
+ v = opts["app-kate-footerusebg"];
+ if ( ! v.isEmpty() )
+ cbFooterEnableBgColor->setChecked( v == "true" );
+ v = opts["app-kate-footerbg"];
+ if ( ! v.isEmpty() )
+ kcbtnFooterBg->setColor( QColor( v ) );
+
+ tags = QStringList::split('|', opts["app-kate-footerformat"], "true");
+ if (tags.count() == 3)
+ {
+ leFooterLeft->setText(tags[0]);
+ leFooterCenter->setText(tags[1]);
+ leFooterRight->setText(tags[2]);
+ }
+}
+
+void KatePrintHeaderFooter::setHFFont()
+{
+ QFont fnt( lFontPreview->font() );
+ // display a font dialog
+ if ( KFontDialog::getFont( fnt, false, this ) == KFontDialog::Accepted )
+ {
+ // change strFont
+ strFont = fnt.toString();
+ // set preview
+ lFontPreview->setFont( fnt );
+ lFontPreview->setText( (fnt.family() + ", %1pt").arg( fnt.pointSize() ) );
+ }
+}
+
+//END KatePrintHeaderFooter
+
+//BEGIN KatePrintLayout
+
+KatePrintLayout::KatePrintLayout( KPrinter * /*printer*/, QWidget *parent, const char *name )
+ : KPrintDialogPage( parent, name )
+{
+ setTitle( i18n("L&ayout") );
+
+ QVBoxLayout *lo = new QVBoxLayout ( this );
+ lo->setSpacing( KDialog::spacingHint() );
+
+ QHBox *hb = new QHBox( this );
+ lo->addWidget( hb );
+ QLabel *lSchema = new QLabel( i18n("&Schema:"), hb );
+ cmbSchema = new QComboBox( false, hb );
+ lSchema->setBuddy( cmbSchema );
+
+ cbDrawBackground = new QCheckBox( i18n("Draw bac&kground color"), this );
+ lo->addWidget( cbDrawBackground );
+
+ cbEnableBox = new QCheckBox( i18n("Draw &boxes"), this );
+ lo->addWidget( cbEnableBox );
+
+ gbBoxProps = new QGroupBox( 2, Qt::Horizontal, i18n("Box Properties"), this );
+ lo->addWidget( gbBoxProps );
+
+ QLabel *lBoxWidth = new QLabel( i18n("W&idth:"), gbBoxProps );
+ sbBoxWidth = new QSpinBox( 1, 100, 1, gbBoxProps );
+ lBoxWidth->setBuddy( sbBoxWidth );
+
+ QLabel *lBoxMargin = new QLabel( i18n("&Margin:"), gbBoxProps );
+ sbBoxMargin = new QSpinBox( 0, 100, 1, gbBoxProps );
+ lBoxMargin->setBuddy( sbBoxMargin );
+
+ QLabel *lBoxColor = new QLabel( i18n("Co&lor:"), gbBoxProps );
+ kcbtnBoxColor = new KColorButton( gbBoxProps );
+ lBoxColor->setBuddy( kcbtnBoxColor );
+
+ connect( cbEnableBox, SIGNAL(toggled(bool)), gbBoxProps, SLOT(setEnabled(bool)) );
+
+ lo->addStretch( 1 );
+ // set defaults:
+ sbBoxMargin->setValue( 6 );
+ gbBoxProps->setEnabled( false );
+ cmbSchema->insertStringList (KateFactory::self()->schemaManager()->list ());
+ cmbSchema->setCurrentItem( 1 );
+
+ // whatsthis
+ // FIXME uncomment when string freeze is over
+// QWhatsThis::add ( cmbSchema, i18n(
+// "Select the color scheme to use for the print." ) );
+ QWhatsThis::add( cbDrawBackground, i18n(
+ "<p>If enabled, the background color of the editor will be used.</p>"
+ "<p>This may be useful if your color scheme is designed for a dark background.</p>") );
+ QWhatsThis::add( cbEnableBox, i18n(
+ "<p>If enabled, a box as defined in the properties below will be drawn "
+ "around the contents of each page. The Header and Footer will be separated "
+ "from the contents with a line as well.</p>") );
+ QWhatsThis::add( sbBoxWidth, i18n(
+ "The width of the box outline" ) );
+ QWhatsThis::add( sbBoxMargin, i18n(
+ "The margin inside boxes, in pixels") );
+ QWhatsThis::add( kcbtnBoxColor, i18n(
+ "The line color to use for boxes") );
+}
+
+void KatePrintLayout::getOptions(QMap<QString,QString>& opts, bool )
+{
+ opts["app-kate-colorscheme"] = cmbSchema->currentText();
+ opts["app-kate-usebackground"] = cbDrawBackground->isChecked() ? "true" : "false";
+ opts["app-kate-usebox"] = cbEnableBox->isChecked() ? "true" : "false";
+ opts["app-kate-boxwidth"] = sbBoxWidth->cleanText();
+ opts["app-kate-boxmargin"] = sbBoxMargin->cleanText();
+ opts["app-kate-boxcolor"] = kcbtnBoxColor->color().name();
+}
+
+void KatePrintLayout::setOptions( const QMap<QString,QString>& opts )
+{
+ QString v;
+ v = opts["app-kate-colorscheme"];
+ if ( ! v.isEmpty() )
+ cmbSchema->setCurrentItem( KateFactory::self()->schemaManager()->number( v ) );
+ v = opts["app-kate-usebackground"];
+ if ( ! v.isEmpty() )
+ cbDrawBackground->setChecked( v == "true" );
+ v = opts["app-kate-usebox"];
+ if ( ! v.isEmpty() )
+ cbEnableBox->setChecked( v == "true" );
+ v = opts["app-kate-boxwidth"];
+ if ( ! v.isEmpty() )
+ sbBoxWidth->setValue( v.toInt() );
+ v = opts["app-kate-boxmargin"];
+ if ( ! v.isEmpty() )
+ sbBoxMargin->setValue( v.toInt() );
+ v = opts["app-kate-boxcolor"];
+ if ( ! v.isEmpty() )
+ kcbtnBoxColor->setColor( QColor( v ) );
+}
+//END KatePrintLayout
+
+#include "kateprinter.moc"
+#endif //!Q_WS_WIN
+
+// kate: space-indent on; indent-width 2; replace-tabs on;