kate Library API Documentation

kateprinter.cpp

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