00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 #include <config.h>
00023 #endif
00024 #include "KPrTextObject.h"
00025 #include "KPrTextObject.moc"
00026 #include "KPrGradient.h"
00027 #include "KPrCommand.h"
00028 #include "KPrCanvas.h"
00029 #include "KPrPage.h"
00030 #include "KPrView.h"
00031 #include "KPrDocument.h"
00032 #include "KPrBgSpellCheck.h"
00033 #include "KPrVariableCollection.h"
00034
00035 #include <KoAutoFormat.h>
00036 #include <KoTextParag.h>
00037 #include <KoTextObject.h>
00038 #include <KoStyleCollection.h>
00039 #include <KoTextFormatter.h>
00040 #include <KoTextZoomHandler.h>
00041 #include "KPrTextViewIface.h"
00042 #include "KPrTextObjectIface.h"
00043 #include <KoOasisContext.h>
00044 #include <KoStyleStack.h>
00045 #include <ktempfile.h>
00046 #include <klocale.h>
00047 #include <kdebug.h>
00048 #include <kdeversion.h>
00049 #include <kmultipledrag.h>
00050
00051 #include <qfont.h>
00052 #include <qfile.h>
00053 #include <qwidget.h>
00054 #include <qpicture.h>
00055 #include <qpainter.h>
00056 #include <qwmatrix.h>
00057 #include <qdom.h>
00058 #include <qapplication.h>
00059 #include <qfontdatabase.h>
00060 #include <qpopupmenu.h>
00061 #include <qclipboard.h>
00062
00063 #include <KoParagCounter.h>
00064 #include <kaction.h>
00065 #include <KoVariable.h>
00066 #include <KoCustomVariablesDia.h>
00067 #include <KoRuler.h>
00068 #include <KoSize.h>
00069 #include <KoXmlNS.h>
00070 #include <KoDom.h>
00071 #include <KoStore.h>
00072 #include <KoStoreDrag.h>
00073 #include <KoOasisStore.h>
00074
00075 #include <float.h>
00076 using namespace std;
00077
00078 #undef S_NONE // Solaris defines it in sys/signal.h
00079
00080 const QString &KPrTextObject::tagTEXTOBJ=KGlobal::staticQString("TEXTOBJ");
00081 const QString &KPrTextObject::attrLineSpacing=KGlobal::staticQString("lineSpacing");
00082 const QString &KPrTextObject::attrParagSpacing=KGlobal::staticQString("paragSpacing");
00083 const QString &KPrTextObject::attrMargin=KGlobal::staticQString("margin");
00084 const QString &KPrTextObject::attrBulletType1=KGlobal::staticQString("bulletType1");
00085 const QString &KPrTextObject::attrBulletType2=KGlobal::staticQString("bulletType2");
00086 const QString &KPrTextObject::attrBulletType3=KGlobal::staticQString("bulletType3");
00087 const QString &KPrTextObject::attrBulletType4=KGlobal::staticQString("bulletType4");
00088 const QString &KPrTextObject::attrBulletColor1=KGlobal::staticQString("bulletColor1");
00089 const QString &KPrTextObject::attrBulletColor2=KGlobal::staticQString("bulletColor2");
00090 const QString &KPrTextObject::attrBulletColor3=KGlobal::staticQString("bulletColor3");
00091 const QString &KPrTextObject::attrBulletColor4=KGlobal::staticQString("bulletColor4");
00092 const QString &KPrTextObject::tagP=KGlobal::staticQString("P");
00093 const QString &KPrTextObject::attrAlign=KGlobal::staticQString("align");
00094 const QString &KPrTextObject::attrType=KGlobal::staticQString("type");
00095 const QString &KPrTextObject::attrDepth=KGlobal::staticQString("depth");
00096 const QString &KPrTextObject::tagTEXT=KGlobal::staticQString("TEXT");
00097 const QString &KPrTextObject::attrFamily=KGlobal::staticQString("family");
00098 const QString &KPrTextObject::attrPointSize=KGlobal::staticQString("pointSize");
00099 const QString &KPrTextObject::attrBold=KGlobal::staticQString("bold");
00100 const QString &KPrTextObject::attrItalic=KGlobal::staticQString("italic");
00101 const QString &KPrTextObject::attrUnderline=KGlobal::staticQString("underline");
00102 const QString &KPrTextObject::attrStrikeOut=KGlobal::staticQString("strikeOut");
00103 const QString &KPrTextObject::attrColor=KGlobal::staticQString("color");
00104 const QString &KPrTextObject::attrWhitespace=KGlobal::staticQString("whitespace");
00105 const QString &KPrTextObject::attrTextBackColor=KGlobal::staticQString("textbackcolor");
00106 const QString &KPrTextObject::attrVertAlign=KGlobal::staticQString("VERTALIGN");
00107
00108
00109 KPrTextObject::KPrTextObject( KPrDocument *doc )
00110 : KPr2DObject()
00111 {
00112 m_doc=doc;
00113 m_textVertAlign = KP_TOP;
00114
00115 KoTextFormatCollection* fc = new KoTextFormatCollection( doc->defaultFont(), Qt::black, doc->globalLanguage(), doc->globalHyphenation() );
00116 KPrTextDocument * textdoc = new KPrTextDocument( this, fc );
00117 if ( m_doc->tabStopValue() != -1 )
00118 textdoc->setTabStops( m_doc->zoomHandler()->ptToLayoutUnitPixX( m_doc->tabStopValue() ));
00119
00120 m_textobj = new KoTextObject( textdoc, m_doc->styleCollection()->findStyle( "Standard" ), this );
00121 textdoc->setFlow( this );
00122
00123 m_doc->backSpeller()->registerNewTextObject( m_textobj );
00124 pen = defaultPen();
00125 drawEditRect = true;
00126 drawEmpty = true;
00127 editingTextObj = false;
00128
00129 bleft = 0.0;
00130 btop = 0.0;
00131 bright = 0.0;
00132 bbottom = 0.0;
00133 alignVertical = 0.0;
00134
00135 connect( m_textobj, SIGNAL( newCommand( KCommand * ) ),
00136 SLOT( slotNewCommand( KCommand * ) ) );
00137 connect( m_textobj, SIGNAL( availableHeightNeeded() ),
00138 SLOT( slotAvailableHeightNeeded() ) );
00139 connect( m_textobj, SIGNAL( repaintChanged( KoTextObject* ) ),
00140 SLOT( slotRepaintChanged() ) );
00141
00142
00143 connect( this, SIGNAL( repaintChanged( KPrTextObject * ) ),
00144 m_doc, SLOT( slotRepaintChanged( KPrTextObject * ) ) );
00145 connect(m_textobj, SIGNAL( showFormatObject(const KoTextFormat &) ),
00146 SLOT( slotFormatChanged(const KoTextFormat &)) );
00147 connect( m_textobj, SIGNAL( afterFormatting( int, KoTextParag*, bool* ) ),
00148 SLOT( slotAfterFormatting( int, KoTextParag*, bool* ) ) );
00149 connect( m_textobj, SIGNAL( paragraphDeleted( KoTextParag*) ),
00150 SLOT( slotParagraphDeleted(KoTextParag*) ));
00151
00152 }
00153
00154 KPrTextObject::~KPrTextObject()
00155 {
00156 textDocument()->takeFlow();
00157 m_doc = 0L;
00158 }
00159
00160 DCOPObject* KPrTextObject::dcopObject()
00161 {
00162 if ( !dcop )
00163 dcop = new KPrTextObjectIface( this );
00164 return dcop;
00165 }
00166
00167 void KPrTextObject::slotParagraphDeleted(KoTextParag*_parag)
00168 {
00169 m_doc->spellCheckParagraphDeleted( _parag, this);
00170 }
00171
00172 QBrush KPrTextObject::getBrush() const
00173 {
00174 QBrush tmpBrush( m_brush.getBrush() );
00175 if(!tmpBrush.color().isValid())
00176 tmpBrush.setColor(QApplication::palette().color( QPalette::Active, QColorGroup::Base ));
00177 return tmpBrush;
00178 }
00179
00180 void KPrTextObject::resizeTextDocument( bool widthChanged, bool heightChanged )
00181 {
00182 if ( heightChanged )
00183 {
00184
00185 slotAvailableHeightNeeded();
00186
00187 recalcVerticalAlignment();
00188 }
00189 if ( widthChanged )
00190 {
00191
00192
00193 textDocument()->setWidth( m_doc->zoomHandler()->ptToLayoutUnitPixX( innerWidth() ) );
00194 m_textobj->setLastFormattedParag( textDocument()->firstParag() );
00195 m_textobj->formatMore( 2 );
00196 }
00197 }
00198
00199 void KPrTextObject::setSize( double _width, double _height )
00200 {
00201 bool widthModified = KABS( _width - ext.width() ) > DBL_EPSILON ;
00202 bool heightModified = KABS( _height - ext.height() ) > DBL_EPSILON;
00203 if ( widthModified || heightModified )
00204 {
00205 KPrObject::setSize( _width, _height );
00206 resizeTextDocument( widthModified, heightModified );
00207 }
00208 }
00209
00210 QDomDocumentFragment KPrTextObject::save( QDomDocument& doc, double offset )
00211 {
00212 QDomDocumentFragment fragment=KPr2DObject::save(doc, offset);
00213 fragment.appendChild(saveKTextObject( doc ));
00214 return fragment;
00215 }
00216
00217 bool KPrTextObject::saveOasisObjectAttributes( KPOasisSaveContext &sc ) const
00218 {
00219 sc.xmlWriter.startElement( "draw:text-box" );
00220 m_textobj->saveOasisContent( sc.xmlWriter, sc.context );
00221 sc.xmlWriter.endElement();
00222 return true;
00223 }
00224
00225 const char * KPrTextObject::getOasisElementName() const
00226 {
00227 return "draw:frame";
00228 }
00229
00230 void KPrTextObject::saveOasisMarginElement( KoGenStyle &styleobjectauto ) const
00231 {
00232 kdDebug()<<"void KPrTextObject::saveOasisMarginElement( KoGenStyle &styleobjectauto )\n";
00233 if ( btop != 0.0 )
00234 styleobjectauto.addPropertyPt("fo:padding-top", btop );
00235 if ( bbottom != 0.0 )
00236 styleobjectauto.addPropertyPt("fo:padding-bottom", bbottom );
00237 if ( bleft != 0.0 )
00238 styleobjectauto.addPropertyPt("fo:padding-left", bleft );
00239 if ( bright != 0.0 )
00240 styleobjectauto.addPropertyPt("fo:padding-right", bright );
00241
00242
00243 switch( m_textVertAlign )
00244 {
00245 case KP_TOP:
00246 styleobjectauto.addProperty("draw:textarea-vertical-align", "top" );
00247 break;
00248 case KP_CENTER:
00249 styleobjectauto.addProperty("draw:textarea-vertical-align", "middle" );
00250 break;
00251 case KP_BOTTOM:
00252 styleobjectauto.addProperty("draw:textarea-vertical-align", "bottom" );
00253 break;
00254 }
00255
00256
00257 }
00258
00259 void KPrTextObject::loadOasis(const QDomElement &element, KoOasisContext& context,
00260 KPrLoadingInfo *info )
00261 {
00262 KPr2DObject::loadOasis(element, context, info);
00263
00264 KoStyleStack &styleStack = context.styleStack();
00265 styleStack.setTypeProperties( "graphic" );
00266 if( styleStack.hasAttributeNS( KoXmlNS::fo, "padding-top" ) )
00267 btop = KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::fo, "padding-top" ) );
00268 if( styleStack.hasAttributeNS( KoXmlNS::fo, "padding-bottom" ) )
00269 bbottom = KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::fo, "padding-bottom" ) );
00270 if( styleStack.hasAttributeNS( KoXmlNS::fo, "padding-left") )
00271 bleft = KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::fo, "padding-left" ) );
00272 if( styleStack.hasAttributeNS( KoXmlNS::fo, "padding-right" ) )
00273 bright = KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::fo, "padding-right" ) );
00274 kdDebug()<<" KPrTextObject::loadOasis : btp :"<<btop<<" bbottom :"<<bbottom<<" bleft :"<<bleft<<" bright :"<<bright<<endl;
00275
00276 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "textarea-vertical-align" ) )
00277 {
00278 QString alignment = styleStack.attributeNS( KoXmlNS::draw, "textarea-vertical-align" );
00279 if ( alignment == "top" )
00280 m_textVertAlign= KP_TOP;
00281 else if ( alignment == "middle" )
00282 m_textVertAlign= KP_CENTER;
00283 else if ( alignment == "bottom" )
00284 m_textVertAlign= KP_BOTTOM;
00285 }
00286 kdDebug()<<" vertical Alignment :"<< ( ( m_textVertAlign== KP_TOP ) ? "top" : ( m_textVertAlign== KP_CENTER ) ? "center": "bottom" )<<endl;
00287 QDomElement tmp = KoDom::namedItemNS( element, KoXmlNS::draw, "text-box");
00288 m_textobj->loadOasisContent( tmp, context, m_doc->styleCollection() );
00289 resizeTextDocument();
00290 }
00291
00292
00293 double KPrTextObject::load(const QDomElement &element)
00294 {
00295 double offset=KPr2DObject::load(element);
00296 QDomElement e=element.namedItem(tagTEXTOBJ).toElement();
00297 if(!e.isNull()) {
00298 if ( e.hasAttribute( "protectcontent"))
00299 setProtectContent((bool)e.attribute( "protectcontent" ).toInt());
00300 if (e.hasAttribute( "bleftpt"))
00301 bleft = e.attribute( "bleftpt").toDouble();
00302 if (e.hasAttribute( "brightpt"))
00303 bright = e.attribute( "brightpt").toDouble();
00304 if (e.hasAttribute( "btoppt"))
00305 btop = e.attribute( "btoppt").toDouble();
00306 if (e.hasAttribute( "bbottompt"))
00307 bbottom = e.attribute( "bbottompt").toDouble();
00308 if ( e.hasAttribute("verticalAlign"))
00309 {
00310 QString str =e.attribute("verticalAlign");
00311 if ( str == "bottom" )
00312 m_textVertAlign= KP_BOTTOM;
00313 else if ( str == "center" )
00314 m_textVertAlign= KP_CENTER;
00315 else if ( str == "top" )
00316 m_textVertAlign= KP_TOP;
00317 }
00318 if ( e.hasAttribute( "verticalValue" ))
00319 alignVertical = e.attribute( "verticalValue" ).toDouble();
00320
00321 loadKTextObject( e );
00322 }
00323
00324 shadowCompatibility();
00325
00326 resizeTextDocument();
00327 return offset;
00328 }
00329
00330 void KPrTextObject::shadowCompatibility()
00331 {
00332 if ( shadowDistance != 0)
00333 {
00334 int sx = 0;
00335 int sy = 0;
00336 switch ( shadowDirection )
00337 {
00338 case SD_LEFT_BOTTOM:
00339 case SD_LEFT:
00340 case SD_LEFT_UP:
00341 sx = - shadowDistance;
00342 case SD_RIGHT_UP:
00343 case SD_RIGHT:
00344 case SD_RIGHT_BOTTOM:
00345 sx = shadowDistance;
00346 default:
00347 break;
00348 }
00349 switch ( shadowDirection )
00350 {
00351 case SD_LEFT_UP:
00352 case SD_UP:
00353 case SD_RIGHT_UP:
00354 sy = - shadowDistance;
00355 case SD_LEFT_BOTTOM:
00356 case SD_BOTTOM:
00357 case SD_RIGHT_BOTTOM:
00358 sy = shadowDistance;
00359 default:
00360 break;
00361 }
00362 KoTextFormat tmpFormat;
00363 tmpFormat.setShadow( sx, sy, shadowColor );
00364 KCommand* cmd = m_textobj->setFormatCommand( &tmpFormat, KoTextFormat::ShadowText );
00365 delete cmd;
00366 }
00367
00368 shadowDirection = SD_RIGHT_BOTTOM;
00369 shadowDistance = 0;
00370 shadowColor = Qt::gray;
00371 }
00372
00373
00374
00375 void KPrTextObject::paint( QPainter *_painter, KoTextZoomHandler*_zoomHandler,
00376 int pageNum, bool drawingShadow, bool drawContour )
00377 {
00378
00379 KPrPage *p = m_doc->pageList().at( pageNum );
00380
00381 if ( p )
00382 recalcPageNum( p );
00383 if ( drawingShadow ) return;
00384 paint( _painter, _zoomHandler, false, 0L, true, drawContour );
00385 }
00386
00387
00388 void KPrTextObject::paintEdited( QPainter *_painter, KoTextZoomHandler*_zoomHandler,
00389 bool onlyChanged, KoTextCursor* cursor, bool resetChanged )
00390 {
00391 _painter->save();
00392 _painter->translate( _zoomHandler->zoomItX(orig.x()), _zoomHandler->zoomItY(orig.y()) );
00393
00394 if ( angle != 0 )
00395 rotateObject(_painter,_zoomHandler);
00396 paint( _painter, _zoomHandler, onlyChanged, cursor, resetChanged, false );
00397 _painter->restore();
00398 }
00399
00400
00401 void KPrTextObject::paint( QPainter *_painter, KoTextZoomHandler*_zoomHandler,
00402 bool onlyChanged, KoTextCursor* cursor, bool resetChanged,
00403 bool drawContour )
00404 {
00405 double ow = ext.width();
00406 double oh = ext.height();
00407 double pw = pen.pointWidth() / 2;
00408 if ( drawContour ) {
00409 QPen pen3( Qt::black, 1, Qt::DotLine );
00410 _painter->setPen( pen3 );
00411 _painter->setRasterOp( Qt::NotXorROP );
00412 _painter->drawRect( _zoomHandler->zoomItX(pw), _zoomHandler->zoomItY(pw),
00413 _zoomHandler->zoomItX(ow), _zoomHandler->zoomItY( oh) );
00414
00415 return;
00416 }
00417
00418 _painter->save();
00419 QPen pen2 = pen.zoomedPen(_zoomHandler);
00420
00421
00422
00423
00424 _painter->setPen( pen2 );
00425
00426 if ( editingTextObj && _painter->device() && _painter->device()->devType() != QInternal::Printer)
00427 _painter->setBrush( QBrush( m_doc->txtBackCol(), Qt::SolidPattern ) );
00428 else {
00429
00430 if ( getFillType() == FT_BRUSH || !gradient ) {
00431 _painter->setBrush( getBrush() );
00432 }
00433 else {
00434 QSize size( _zoomHandler->zoomSize( ext ) );
00435 gradient->setSize( size );
00436 _painter->drawPixmap( _zoomHandler->zoomItX(pw), _zoomHandler->zoomItX(pw), gradient->pixmap(), 0, 0,
00437 _zoomHandler->zoomItX( ow - 2 * pw ),
00438 _zoomHandler->zoomItY( oh - 2 * pw ) );
00439 }
00440 }
00441 if ( !editingTextObj || !onlyChanged )
00442 {
00444
00445 _painter->drawRect( _zoomHandler->zoomItX(pw), _zoomHandler->zoomItX(pw), _zoomHandler->zoomItX( ow - 2 * pw),
00446 _zoomHandler->zoomItY( oh - 2 * pw) );
00447 }
00448
00449 drawText( _painter, _zoomHandler, onlyChanged, cursor, resetChanged );
00450 _painter->restore();
00451
00452
00453
00454
00455
00456 if ( m_doc->firstView() && m_doc->firstView()->getCanvas()->getEditMode() &&
00457 getDrawEditRect() && getPen().style() == Qt::NoPen )
00458 {
00459 _painter->save();
00460
00461 _painter->setPen( QPen( Qt::gray, 1, Qt::DotLine ) );
00462 _painter->setBrush( Qt::NoBrush );
00463 _painter->setRasterOp( Qt::NotXorROP );
00464 _painter->drawRect( 0, 0, _zoomHandler->zoomItX(ow), _zoomHandler->zoomItY( oh) );
00465
00466 _painter->restore();
00467 }
00468 }
00469
00470
00471
00472 void KPrTextObject::drawText( QPainter* _painter, KoTextZoomHandler *zoomHandler, bool onlyChanged, KoTextCursor* cursor, bool resetChanged )
00473 {
00474
00475 recalcVerticalAlignment();
00476 QColorGroup cg = QApplication::palette().active();
00477 _painter->save();
00478 _painter->translate( m_doc->zoomHandler()->zoomItX( bLeft()), m_doc->zoomHandler()->zoomItY( bTop()+alignVertical));
00479 if ( !editingTextObj || (_painter->device() && _painter->device()->devType() == QInternal::Printer))
00480 cg.setBrush( QColorGroup::Base, NoBrush );
00481 else
00482 cg.setColor( QColorGroup::Base, m_doc->txtBackCol() );
00483
00484 QRect r = zoomHandler->zoomRect( KoRect( 0, 0, innerWidth(), innerHeight() ) );
00485 bool editMode = false;
00486 if( m_doc->firstView() && m_doc->firstView()->getCanvas())
00487 editMode = m_doc->firstView()->getCanvas()->getEditMode();
00488
00489 uint drawingFlags = 0;
00490 if ( _painter->device() && _painter->device()->devType() != QInternal::Printer )
00491 drawingFlags |= KoTextDocument::DrawSelections;
00492 if ( m_doc->backgroundSpellCheckEnabled() && editMode )
00493 drawingFlags |= KoTextDocument::DrawMisspelledLine;
00494 if ( !editMode )
00495 drawingFlags |= KoTextDocument::DontDrawNoteVariable;
00496 if ( m_doc->viewFormattingChars() && editMode )
00497 drawingFlags |= KoTextDocument::DrawFormattingChars;
00498
00499 if ( specEffects )
00500 {
00501 switch ( effect2 )
00502 {
00503 case EF2T_PARA:
00504
00505 drawParags( _painter, zoomHandler, cg, ( onlyCurrStep ? subPresStep : 0 ), subPresStep );
00506 break;
00507 default:
00508 textDocument()->drawWYSIWYG(
00509 _painter, r.x(), r.y(), r.width(), r.height(),
00510 cg, zoomHandler,
00511 onlyChanged, cursor != 0, cursor, resetChanged, drawingFlags );
00512 }
00513 }
00514 else
00515 {
00516
00517
00518 textDocument()->drawWYSIWYG(
00519 _painter, r.x(), r.y(), r.width(), r.height(),
00520 cg, zoomHandler,
00521 onlyChanged, cursor != 0, cursor, resetChanged, drawingFlags );
00522 }
00523 _painter->restore();
00524 }
00525
00526 int KPrTextObject::getSubPresSteps() const
00527 {
00528 int paragraphs = 0;
00529 KoTextParag * parag = textDocument()->firstParag();
00530 for ( ; parag ; parag = parag->next() )
00531 paragraphs++;
00532 return paragraphs;
00533 }
00534
00535
00536 QDomElement KPrTextObject::saveKTextObject( QDomDocument& doc )
00537 {
00538 #if 0
00539 KTextEditParag *parag = ktextobject.document()->firstParag();
00540 KTextEditDocument::TextSettings textSettings = ktextobject.document()->textSettings();
00541 #endif
00542
00543 QDomElement textobj=doc.createElement(tagTEXTOBJ);
00544 if ( isProtectContent() )
00545 textobj.setAttribute( "protectcontent", (int)isProtectContent());
00546 if (bleft !=0.0)
00547 textobj.setAttribute( "bleftpt", bleft );
00548 if (bright !=0.0)
00549 textobj.setAttribute( "brightpt", bright );
00550 if (btop !=0.0)
00551 textobj.setAttribute( "btoppt", btop );
00552 if (bbottom !=0.0)
00553 textobj.setAttribute( "bbottompt", bbottom );
00554 if ( m_textVertAlign != KP_TOP )
00555 {
00556 if ( m_textVertAlign == KP_BOTTOM )
00557 textobj.setAttribute( "verticalAlign", "bottom" );
00558 else if ( m_textVertAlign == KP_CENTER )
00559 textobj.setAttribute( "verticalAlign", "center" );
00560 else if ( m_textVertAlign == KP_TOP )
00561 textobj.setAttribute( "verticalAlign", "top" );
00562 textobj.setAttribute( "verticalValue",alignVertical );
00563 }
00564 #if 0
00565 textobj.setAttribute(attrLineSpacing, ktextobject.document()->lineSpacing());
00566 textobj.setAttribute(attrParagSpacing, ktextobject.document()->paragSpacing());
00567 textobj.setAttribute(attrMargin, ktextobject.document()->margin());
00568 textobj.setAttribute(attrBulletType1, (int)textSettings.bulletType[0]);
00569 textobj.setAttribute(attrBulletType2, (int)textSettings.bulletType[1]);
00570 textobj.setAttribute(attrBulletType3, (int)textSettings.bulletType[2]);
00571 textobj.setAttribute(attrBulletType4, (int)textSettings.bulletType[3]);
00572 textobj.setAttribute(attrBulletColor1, textSettings.bulletColor[0].name());
00573 textobj.setAttribute(attrBulletColor2, textSettings.bulletColor[1].name());
00574 textobj.setAttribute(attrBulletColor3, textSettings.bulletColor[2].name());
00575 textobj.setAttribute(attrBulletColor4, textSettings.bulletColor[3].name());
00576 #endif
00577 KoTextParag *parag = static_cast<KoTextParag*> (textDocument()->firstParag());
00578
00579 while ( parag ) {
00580 saveParagraph( doc, parag, textobj, 0, parag->length()-2 );
00581 parag = static_cast<KoTextParag*>( parag->next());
00582 }
00583 return textobj;
00584 }
00585
00586 void KPrTextObject::saveFormat( QDomElement & element, KoTextFormat*lastFormat )
00587 {
00588 QString tmpFamily, tmpColor, tmpTextBackColor;
00589 unsigned int tmpBold=false, tmpItalic=false, tmpUnderline=false,tmpStrikeOut=false;
00590 int tmpVerticalAlign=-1;
00591
00592 tmpFamily=lastFormat->font().family();
00593 tmpBold=static_cast<unsigned int>(lastFormat->font().bold());
00594 tmpItalic=static_cast<unsigned int>(lastFormat->font().italic());
00595 tmpUnderline=static_cast<unsigned int>(lastFormat->underline());
00596 tmpStrikeOut=static_cast<unsigned int>(lastFormat->strikeOut());
00597 tmpColor=lastFormat->color().name();
00598 tmpVerticalAlign=static_cast<unsigned int>(lastFormat->vAlign());
00599 if(lastFormat->textBackgroundColor().isValid())
00600 tmpTextBackColor=lastFormat->textBackgroundColor().name();
00601
00602 element.setAttribute(attrFamily, tmpFamily);
00603 element.setAttribute(attrPointSize, lastFormat->pointSize());
00604
00605 if(tmpBold)
00606 element.setAttribute(attrBold, tmpBold);
00607 if(tmpItalic)
00608 element.setAttribute(attrItalic, tmpItalic);
00609 if ( lastFormat->underlineType()!= KoTextFormat::U_NONE )
00610 {
00611 if(lastFormat->doubleUnderline())
00612 element.setAttribute(attrUnderline, "double");
00613 if(lastFormat->underlineType()==KoTextFormat::U_SIMPLE_BOLD)
00614 element.setAttribute(attrUnderline, "single-bold");
00615 else if( lastFormat->underlineType()==KoTextFormat::U_WAVE)
00616 element.setAttribute(attrUnderline, "wave");
00617 else if(tmpUnderline)
00618 element.setAttribute(attrUnderline, tmpUnderline);
00619 QString strLineType=KoTextFormat::underlineStyleToString( lastFormat->underlineStyle() );
00620 element.setAttribute( "underlinestyleline", strLineType );
00621 if ( lastFormat->textUnderlineColor().isValid() )
00622 element.setAttribute( "underlinecolor", lastFormat->textUnderlineColor().name() );
00623 }
00624 if ( lastFormat->strikeOutType()!= KoTextFormat::S_NONE )
00625 {
00626 if ( lastFormat->doubleStrikeOut() )
00627 element.setAttribute(attrStrikeOut, "double");
00628 else if ( lastFormat->strikeOutType()== KoTextFormat::S_SIMPLE_BOLD)
00629 element.setAttribute(attrStrikeOut, "single-bold");
00630 else if(tmpStrikeOut)
00631 element.setAttribute(attrStrikeOut, tmpStrikeOut);
00632 QString strLineType=KoTextFormat::strikeOutStyleToString( lastFormat->strikeOutStyle() );
00633 element.setAttribute( "strikeoutstyleline", strLineType );
00634
00635 }
00636 element.setAttribute(attrColor, tmpColor);
00637
00638 if(!tmpTextBackColor.isEmpty())
00639 element.setAttribute(attrTextBackColor, tmpTextBackColor);
00640 if(tmpVerticalAlign!=-1)
00641 {
00642 element.setAttribute(attrVertAlign,tmpVerticalAlign);
00643 if(lastFormat->relativeTextSize()!=0.66)
00644 element.setAttribute("relativetextsize",lastFormat->relativeTextSize());
00645 }
00646
00647 if ( lastFormat->shadowDistanceX() != 0
00648 || lastFormat->shadowDistanceY() != 0)
00649 element.setAttribute("text-shadow", lastFormat->shadowAsCss());
00650 if ( lastFormat->offsetFromBaseLine()!=0 )
00651 element.setAttribute( "offsetfrombaseline" , lastFormat->offsetFromBaseLine());
00652 if ( lastFormat->wordByWord() )
00653 element.setAttribute("wordbyword", true);
00654 if ( lastFormat->attributeFont()!= KoTextFormat::ATT_NONE )
00655 element.setAttribute("fontattribute", KoTextFormat::attributeFontToString(lastFormat->attributeFont() ));
00656 if ( !lastFormat->language().isEmpty())
00657 element.setAttribute("language", lastFormat->language());
00658 }
00659
00660 QDomElement KPrTextObject::saveHelper(const QString &tmpText,KoTextFormat*lastFormat , QDomDocument &doc)
00661 {
00662 QDomElement element=doc.createElement(tagTEXT);
00663
00664 saveFormat ( element, lastFormat );
00665
00666 if(tmpText.stripWhiteSpace().isEmpty())
00667
00668 element.setAttribute(attrWhitespace, tmpText.length());
00669 element.appendChild(doc.createTextNode(tmpText));
00670 return element;
00671 }
00672
00673 void KPrTextObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& mainStyles ) const
00674 {
00675 KPr2DObject::fillStyle( styleObjectAuto, mainStyles );
00676 saveOasisMarginElement( styleObjectAuto );
00677 }
00678
00679 void KPrTextObject::loadKTextObject( const QDomElement &elem )
00680 {
00681 QDomElement e = elem.firstChild().toElement();
00682 KoTextParag *lastParag = static_cast<KoTextParag *>(textDocument()->firstParag());
00683 int i = 0;
00684 int listNum = 0;
00685
00686
00687 int lineSpacing = elem.attribute( attrLineSpacing ).toInt();
00688 int bottomBorder = elem.attribute( attrParagSpacing ).toInt();
00689 int topBorder = 0;
00690
00691 while ( !e.isNull() ) {
00692 QValueList<QDomElement> listVariable;
00693 listVariable.clear();
00694
00695 if ( e.tagName() == tagP ) {
00696 QDomElement n = e.firstChild().toElement();
00697
00698
00699 if( e.hasAttribute( attrType ) && n.hasAttribute( attrWhitespace ) )
00700 if ( e.attribute( attrType )!="0" && n.attribute( attrWhitespace )=="1" ) {
00701 e = e.nextSibling().toElement();
00702 continue;
00703 }
00704
00705 KoParagLayout paragLayout = loadParagLayout(e, m_doc, true);
00706
00707
00708 double depth = 0.0;
00709 if( e.hasAttribute(attrDepth) ) {
00710 depth = e.attribute( attrDepth ).toDouble();
00711 paragLayout.margins[QStyleSheetItem::MarginLeft] = depth * MM_TO_POINT(10.0);
00712 }
00713
00714
00715
00716
00717 QString type;
00718 if( e.hasAttribute(attrType) )
00719 type = e.attribute( attrType );
00720
00721
00722
00723
00724 if(type == "1")
00725 {
00726 if(!paragLayout.counter)
00727 paragLayout.counter = new KoParagCounter;
00728 paragLayout.counter->setStyle(KoParagCounter::STYLE_DISCBULLET);
00729 paragLayout.counter->setNumbering(KoParagCounter::NUM_LIST);
00730 paragLayout.counter->setPrefix(QString::null);
00731 paragLayout.counter->setSuffix(QString::null);
00732 }
00733
00734
00735 if ( e.hasAttribute( attrLineSpacing ) )
00736 lineSpacing = e.attribute( attrLineSpacing ).toInt();
00737 if ( e.hasAttribute( "distBefore" ) )
00738 topBorder = e.attribute( "distBefore" ).toInt();
00739 if ( e.hasAttribute( "distAfter" ) )
00740 bottomBorder = e.attribute( "distAfter" ).toInt();
00741
00742
00743 if ( paragLayout.lineSpacingValue() == 0 )
00744 paragLayout.setLineSpacingValue(lineSpacing);
00745 if ( paragLayout.margins[ QStyleSheetItem::MarginTop ] == 0 )
00746 paragLayout.margins[ QStyleSheetItem::MarginTop ] = topBorder;
00747 if ( paragLayout.margins[ QStyleSheetItem::MarginBottom ] == 0 )
00748 paragLayout.margins[ QStyleSheetItem::MarginBottom ] = bottomBorder;
00749 lastParag->setParagLayout( paragLayout );
00750
00751
00752 if(e.hasAttribute(attrAlign))
00753 {
00754 int tmpAlign=e.attribute( attrAlign ).toInt();
00755 if(tmpAlign==1 || tmpAlign==0 )
00756 lastParag->setAlign(Qt::AlignLeft);
00757 else if(tmpAlign==2)
00758 lastParag->setAlign(Qt::AlignRight);
00759 else if(tmpAlign==4)
00760 lastParag->setAlign(Qt::AlignHCenter);
00761 else if(tmpAlign==8)
00762 lastParag->setAlign(Qt::AlignJustify);
00763 else
00764 kdDebug(33001) << "Error in e.attribute( attrAlign ).toInt()" << endl;
00765 }
00766
00767
00768
00769 bool firstTextTag = true;
00770 while ( !n.isNull() ) {
00771 if ( n.tagName() == tagTEXT ) {
00772
00773 if ( firstTextTag ) {
00774 lastParag->remove( 0, 1 );
00775 firstTextTag = false;
00776 }
00777 KoTextFormat fm = loadFormat( n, lastParag->paragraphFormat(), m_doc->defaultFont(), m_doc->globalLanguage(),
00778 m_doc->globalHyphenation() );
00779
00780 QString txt = n.firstChild().toText().data();
00781
00782 if(n.hasAttribute(attrWhitespace)) {
00783 int ws=n.attribute(attrWhitespace).toInt();
00784 txt.fill(' ', ws);
00785 }
00786 n=n.nextSibling().toElement();
00787 if ( n.isNull() )
00788 txt += ' ';
00789 lastParag->append( txt, true );
00790 lastParag->setFormat( i, txt.length(), textDocument()->formatCollection()->format( &fm ) );
00791
00792 i += txt.length();
00793 }
00794 else if ( n.tagName() == "CUSTOM" )
00795 {
00796 listVariable.append( n );
00797 n = n.nextSibling().toElement();
00798 }
00799 else
00800 n = n.nextSibling().toElement();
00801 }
00802 } else if ( e.tagName() == "UNSORTEDLISTTYPE" ) {
00803 if ( listNum < 4 ) {
00804
00805
00806 }
00807 }
00808 e = e.nextSibling().toElement();
00809 loadVariable( listVariable,lastParag );
00810 if ( e.isNull() )
00811 break;
00812 i = 0;
00813 if ( !lastParag->length() == 0 )
00814 lastParag = new KoTextParag( textDocument(), lastParag, 0 );
00815 }
00816 }
00817
00818 void KPrTextObject::loadVariable( QValueList<QDomElement> & listVariable,KoTextParag *lastParag, int offset )
00819 {
00820 QValueList<QDomElement>::Iterator it = listVariable.begin();
00821 QValueList<QDomElement>::Iterator end = listVariable.end();
00822 for ( ; it != end ; ++it )
00823 {
00824 QDomElement elem = *it;
00825 if ( !elem.hasAttribute("pos"))
00826 continue;
00827 int index = elem.attribute("pos").toInt();
00828 index+=offset;
00829 QDomElement varElem = elem.namedItem( "VARIABLE" ).toElement();
00830 if ( !varElem.isNull() )
00831 {
00832 QDomElement typeElem = varElem.namedItem( "TYPE" ).toElement();
00833 int type = typeElem.attribute( "type" ).toInt();
00834 QString key = typeElem.attribute( "key" );
00835 int correct = 0;
00836 if (typeElem.hasAttribute( "correct" ))
00837 correct = typeElem.attribute("correct").toInt();
00838 kdDebug(33001) << "loadKTextObject variable type=" << type << " key=" << key << endl;
00839 KoVariableFormat * varFormat = key.isEmpty() ? 0 : m_doc->variableFormatCollection()->format( key.latin1() );
00840
00841 KoVariable * var =m_doc->getVariableCollection()->createVariable( type, -1, m_doc->variableFormatCollection(),
00842 varFormat, lastParag->textDocument(),
00843 m_doc, correct, true );
00844 if ( var )
00845 {
00846 var->load( varElem );
00847 KoTextFormat format = loadFormat( *it, lastParag->paragraphFormat(), m_doc->defaultFont(), m_doc->globalLanguage(),
00848 m_doc->globalHyphenation() );
00849 lastParag->setCustomItem( index, var, lastParag->document()->formatCollection()->format( &format ));
00850 var->recalc();
00851 }
00852 }
00853 }
00854 }
00855
00856 KoTextFormat KPrTextObject::loadFormat( QDomElement &n, KoTextFormat * refFormat, const QFont & defaultFont,
00857 const QString & defaultLanguage, bool hyphen )
00858 {
00859 KoTextFormat format;
00860 format.setHyphenation( hyphen );
00861 QFont fn;
00862 if ( refFormat )
00863 {
00864 format = *refFormat;
00865 format.setCollection( 0 );
00866 fn = format.font();
00867 }
00868 else
00869 fn = defaultFont;
00870
00871 if ( !n.isNull() )
00872 {
00873 QFontDatabase fdb;
00874 QStringList families = fdb.families();
00875 if ( families.findIndex( n.attribute( attrFamily ) ) != -1 )
00876 fn.setFamily( n.attribute( attrFamily ) );
00877 else
00878 fn = defaultFont;
00879 }
00880 else if ( !refFormat )
00881 {
00882 fn = defaultFont;
00883 }
00884
00885
00886 int size = n.attribute( attrPointSize ).toInt();
00887 bool bold=false;
00888 if(n.hasAttribute(attrBold))
00889 bold = (bool)n.attribute( attrBold ).toInt();
00890 bool italic = false;
00891 if(n.hasAttribute(attrItalic))
00892 italic=(bool)n.attribute( attrItalic ).toInt();
00893
00894 if(n.hasAttribute( attrUnderline ))
00895 {
00896 QString value = n.attribute( attrUnderline );
00897 if ( value == "double" )
00898 format.setUnderlineType ( KoTextFormat::U_DOUBLE);
00899 else if ( value == "single" )
00900 format.setUnderlineType ( KoTextFormat::U_SIMPLE);
00901 else if ( value == "single-bold" )
00902 format.setUnderlineType ( KoTextFormat::U_SIMPLE_BOLD);
00903 else if( value =="wave" )
00904 format.setUnderlineType( KoTextFormat::U_WAVE);
00905 else
00906 format.setUnderlineType ( (bool)value.toInt() ? KoTextFormat::U_SIMPLE :KoTextFormat::U_NONE);
00907 }
00908 if (n.hasAttribute("underlinestyleline") )
00909 format.setUnderlineStyle( KoTextFormat::stringToUnderlineStyle( n.attribute("underlinestyleline") ));
00910
00911 if (n.hasAttribute("underlinecolor"))
00912 format.setTextUnderlineColor(QColor(n.attribute("underlinecolor")));
00913
00914 if(n.hasAttribute(attrStrikeOut))
00915 {
00916 QString value = n.attribute( attrStrikeOut );
00917 if ( value == "double" )
00918 format.setStrikeOutType ( KoTextFormat::S_DOUBLE);
00919 else if ( value == "single" )
00920 format.setStrikeOutType ( KoTextFormat::S_SIMPLE);
00921 else if ( value == "single-bold" )
00922 format.setStrikeOutType ( KoTextFormat::S_SIMPLE_BOLD);
00923 else
00924 format.setStrikeOutType ( (bool)value.toInt() ? KoTextFormat::S_SIMPLE :KoTextFormat::S_NONE);
00925 }
00926
00927 if (n.hasAttribute("strikeoutstyleline"))
00928 {
00929 QString strLineType = n.attribute("strikeoutstyleline");
00930 format.setStrikeOutStyle( KoTextFormat::stringToStrikeOutStyle( strLineType ));
00931 }
00932
00933 QString color = n.attribute( attrColor );
00934 fn.setPointSize( size );
00935 fn.setBold( bold );
00936 fn.setItalic( italic );
00937
00938 QColor col( color );
00939
00940 format.setFont( fn );
00941 format.setColor( col );
00942 QString textBackColor=n.attribute(attrTextBackColor);
00943 if(!textBackColor.isEmpty())
00944 {
00945 QColor tmpCol(textBackColor);
00946 tmpCol=tmpCol.isValid() ? tmpCol : QApplication::palette().color( QPalette::Active, QColorGroup::Base );
00947 format.setTextBackgroundColor(tmpCol);
00948 }
00949 if(n.hasAttribute(attrVertAlign))
00950 format.setVAlign( static_cast<KoTextFormat::VerticalAlignment>(n.attribute(attrVertAlign).toInt() ) );
00951 if ( n.hasAttribute("text-shadow") )
00952 format.parseShadowFromCss( n.attribute("text-shadow") );
00953 if ( n.hasAttribute("relativetextsize") )
00954 format.setRelativeTextSize( n.attribute("relativetextsize").toDouble() ) ;
00955 if ( n.hasAttribute("offsetfrombaseline") )
00956 format.setOffsetFromBaseLine( static_cast<int>(n.attribute("offsetfrombaseline").toInt() ) );
00957 if ( n.hasAttribute("wordbyword") )
00958 format.setWordByWord( static_cast<int>(n.attribute("wordbyword").toInt() ) );
00959
00960 if ( n.hasAttribute("fontattribute") )
00961 format.setAttributeFont( KoTextFormat::stringToAttributeFont(n.attribute("fontattribute") ) );
00962 if ( n.hasAttribute("language"))
00963 format.setLanguage( n.attribute("language"));
00964 else
00965 {
00966 format.setLanguage( defaultLanguage);
00967 }
00968
00969
00970 return format;
00971 }
00972
00973 KoParagLayout KPrTextObject::loadParagLayout( QDomElement & parentElem, KPrDocument *doc, bool findStyle)
00974 {
00975 KoParagLayout layout;
00976
00977
00978 if ( findStyle )
00979 {
00980 KoParagStyle *style;
00981
00982
00983 QDomElement element = parentElem.namedItem( "NAME" ).toElement();
00984 if ( !element.isNull() )
00985 {
00986 QString styleName = element.attribute( "value" );
00987 style = doc->styleCollection()->findStyle( styleName );
00988 if (!style)
00989 {
00990 kdError(33001) << "Cannot find style \"" << styleName << "\" specified in paragraph LAYOUT - using Standard" << endl;
00991 style = doc->styleCollection()->findStyle( "Standard" );
00992 }
00993
00994 }
00995 else
00996 {
00997 kdError(33001) << "Missing NAME tag in paragraph LAYOUT - using Standard" << endl;
00998 style = doc->styleCollection()->findStyle( "Standard" );
00999 }
01000 Q_ASSERT(style);
01001 layout.style = style;
01002 }
01003
01004 QDomElement element = parentElem.namedItem( "INDENTS" ).toElement();
01005 if ( !element.isNull() )
01006 {
01007 double val=0.0;
01008 if(element.hasAttribute("first"))
01009 val=element.attribute("first").toDouble();
01010 layout.margins[QStyleSheetItem::MarginFirstLine] = val;
01011 val=0.0;
01012 if(element.hasAttribute( "left"))
01013
01014 val=QMAX(0, element.attribute( "left").toDouble());
01015 layout.margins[QStyleSheetItem::MarginLeft] = val;
01016 val=0.0;
01017 if(element.hasAttribute("right"))
01018
01019 val=QMAX(0, element.attribute("right").toDouble());
01020 layout.margins[QStyleSheetItem::MarginRight] = val;
01021 }
01022 element = parentElem.namedItem( "LINESPACING" ).toElement();
01023 if ( !element.isNull() )
01024 {
01025
01026 if ( element.hasAttribute( "value" ))
01027 {
01028 QString value = element.attribute( "value" );
01029 if ( value == "oneandhalf" )
01030 {
01031 layout.lineSpacingType = KoParagLayout::LS_ONEANDHALF;
01032 layout.setLineSpacingValue(0);
01033 }
01034 else if ( value == "double" )
01035 {
01036 layout.lineSpacingType = KoParagLayout::LS_DOUBLE;
01037 layout.setLineSpacingValue(0);
01038 }
01039 else
01040 {
01041 layout.lineSpacingType = KoParagLayout::LS_CUSTOM;
01042 layout.setLineSpacingValue(value.toDouble());
01043 }
01044 }
01045 else
01046 {
01047 QString type = element.attribute( "type" );
01048 if ( type == "oneandhalf" )
01049 {
01050 layout.lineSpacingType = KoParagLayout::LS_ONEANDHALF;
01051 layout.setLineSpacingValue(0);
01052 }
01053 else if ( type == "double" )
01054 {
01055 layout.lineSpacingType = KoParagLayout::LS_DOUBLE;
01056 layout.setLineSpacingValue(0);
01057 }
01058 else if ( type == "custom" )
01059 {
01060 layout.lineSpacingType = KoParagLayout::LS_CUSTOM;
01061 layout.setLineSpacingValue(element.attribute( "spacingvalue" ).toDouble());
01062 }
01063 else if ( type == "atleast" )
01064 {
01065 layout.lineSpacingType = KoParagLayout::LS_AT_LEAST;
01066 layout.setLineSpacingValue(element.attribute( "spacingvalue" ).toDouble());
01067 }
01068 else if ( type == "multiple" )
01069 {
01070 layout.lineSpacingType = KoParagLayout::LS_MULTIPLE;
01071 layout.setLineSpacingValue(element.attribute( "spacingvalue" ).toDouble());
01072 }
01073 }
01074 }
01075
01076 element = parentElem.namedItem( "OFFSETS" ).toElement();
01077 if ( !element.isNull() )
01078 {
01079 double val =0.0;
01080 if(element.hasAttribute("before"))
01081 val=QMAX(0, element.attribute("before").toDouble());
01082 layout.margins[QStyleSheetItem::MarginTop] = val;
01083 val = 0.0;
01084 if(element.hasAttribute("after"))
01085 val=QMAX(0, element.attribute("after").toDouble());
01086 layout.margins[QStyleSheetItem::MarginBottom] = val;
01087 }
01088
01089
01090 element = parentElem.namedItem( "LEFTBORDER" ).toElement();
01091 if ( !element.isNull() )
01092 layout.leftBorder = KoBorder::loadBorder( element );
01093 else
01094 layout.leftBorder.setPenWidth( 0);
01095
01096 element = parentElem.namedItem( "RIGHTBORDER" ).toElement();
01097 if ( !element.isNull() )
01098 layout.rightBorder = KoBorder::loadBorder( element );
01099 else
01100 layout.rightBorder.setPenWidth( 0);
01101
01102 element = parentElem.namedItem( "TOPBORDER" ).toElement();
01103 if ( !element.isNull() )
01104 layout.topBorder = KoBorder::loadBorder( element );
01105 else
01106 layout.topBorder.setPenWidth(0);
01107
01108 element = parentElem.namedItem( "BOTTOMBORDER" ).toElement();
01109 if ( !element.isNull() )
01110 layout.bottomBorder = KoBorder::loadBorder( element );
01111 else
01112 layout.bottomBorder.setPenWidth(0);
01113
01114 element = parentElem.namedItem( "COUNTER" ).toElement();
01115 if ( !element.isNull() )
01116 {
01117 layout.counter = new KoParagCounter;
01118 layout.counter->load( element );
01119 }
01120
01121 KoTabulatorList tabList;
01122 element = parentElem.firstChild().toElement();
01123 for ( ; !element.isNull() ; element = element.nextSibling().toElement() )
01124 {
01125 if ( element.tagName() == "TABULATOR" )
01126 {
01127 KoTabulator tab;
01128 tab.type=T_LEFT;
01129 if(element.hasAttribute("type"))
01130 tab.type = static_cast<KoTabulators>( element.attribute("type").toInt());
01131 tab.ptPos=0.0;
01132 if(element.hasAttribute("ptpos"))
01133 tab.ptPos=element.attribute("ptpos").toDouble();
01134 tab.filling=TF_BLANK;
01135 if(element.hasAttribute("filling"))
01136 tab.filling = static_cast<KoTabulatorFilling>( element.attribute("filling").toInt());
01137 tab.ptWidth=0.5;
01138 if(element.hasAttribute("width"))
01139 tab.ptWidth=element.attribute("width").toDouble();
01140 tabList.append( tab );
01141 }
01142 }
01143 layout.setTabList( tabList );
01144
01145
01146 return layout;
01147 }
01148
01149 void KPrTextObject::saveParagLayout( const KoParagLayout& layout, QDomElement & parentElem )
01150 {
01151 QDomDocument doc = parentElem.ownerDocument();
01152 QDomElement element = doc.createElement( "NAME" );
01153 parentElem.appendChild( element );
01154 if ( layout.style )
01155 element.setAttribute( "value", layout.style->name() );
01156 else
01157 kdWarning() << "KWTextParag::saveParagLayout: style==0L!" << endl;
01158
01159
01160 if ( layout.margins[QStyleSheetItem::MarginFirstLine] != 0 ||
01161 layout.margins[QStyleSheetItem::MarginLeft] != 0 ||
01162 layout.margins[QStyleSheetItem::MarginRight] != 0 )
01163 {
01164 element = doc.createElement( "INDENTS" );
01165 parentElem.appendChild( element );
01166 if ( layout.margins[QStyleSheetItem::MarginFirstLine] != 0 )
01167 element.setAttribute( "first", layout.margins[QStyleSheetItem::MarginFirstLine] );
01168 if ( layout.margins[QStyleSheetItem::MarginLeft] != 0 )
01169 element.setAttribute( "left", layout.margins[QStyleSheetItem::MarginLeft] );
01170 if ( layout.margins[QStyleSheetItem::MarginRight] != 0 )
01171 element.setAttribute( "right", layout.margins[QStyleSheetItem::MarginRight] );
01172 }
01173
01174
01175 if ( layout.margins[QStyleSheetItem::MarginTop] != 0 ||
01176 layout.margins[QStyleSheetItem::MarginBottom] != 0 )
01177 {
01178 element = doc.createElement( "OFFSETS" );
01179 parentElem.appendChild( element );
01180 if ( layout.margins[QStyleSheetItem::MarginTop] != 0 )
01181 element.setAttribute( "before", layout.margins[QStyleSheetItem::MarginTop] );
01182 if ( layout.margins[QStyleSheetItem::MarginBottom] != 0 )
01183 element.setAttribute( "after", layout.margins[QStyleSheetItem::MarginBottom] );
01184 }
01185
01186 if ( layout.lineSpacingType != KoParagLayout::LS_SINGLE )
01187 {
01188 element = doc.createElement( "LINESPACING" );
01189 parentElem.appendChild( element );
01190 if ( layout.lineSpacingType == KoParagLayout::LS_ONEANDHALF )
01191 element.setAttribute( "type", "oneandhalf" );
01192 else if ( layout.lineSpacingType == KoParagLayout::LS_DOUBLE )
01193 element.setAttribute( "type", "double" );
01194 else if ( layout.lineSpacingType == KoParagLayout::LS_CUSTOM )
01195 {
01196 element.setAttribute( "type", "custom" );
01197 element.setAttribute( "spacingvalue", layout.lineSpacingValue());
01198 }
01199 else if ( layout.lineSpacingType == KoParagLayout::LS_AT_LEAST )
01200 {
01201 element.setAttribute( "type", "atleast" );
01202 element.setAttribute( "spacingvalue", layout.lineSpacingValue());
01203 }
01204 else if ( layout.lineSpacingType == KoParagLayout::LS_MULTIPLE )
01205 {
01206 element.setAttribute( "type", "multiple" );
01207 element.setAttribute( "spacingvalue", layout.lineSpacingValue());
01208 }
01209 else
01210 kdDebug(33001) << " error in lineSpacing Type" << endl;
01211 }
01212
01213 if ( layout.leftBorder.penWidth() > 0 )
01214 {
01215 element = doc.createElement( "LEFTBORDER" );
01216 parentElem.appendChild( element );
01217 layout.leftBorder.save( element );
01218 }
01219 if ( layout.rightBorder.penWidth() > 0 )
01220 {
01221 element = doc.createElement( "RIGHTBORDER" );
01222 parentElem.appendChild( element );
01223 layout.rightBorder.save( element );
01224 }
01225 if ( layout.topBorder.penWidth() > 0 )
01226 {
01227 element = doc.createElement( "TOPBORDER" );
01228 parentElem.appendChild( element );
01229 layout.topBorder.save( element );
01230 }
01231 if ( layout.bottomBorder.penWidth() > 0 )
01232 {
01233 element = doc.createElement( "BOTTOMBORDER" );
01234 parentElem.appendChild( element );
01235 layout.bottomBorder.save( element );
01236 }
01237
01238 if ( layout.counter && layout.counter->numbering() != KoParagCounter::NUM_NONE )
01239 {
01240 element = doc.createElement( "COUNTER" );
01241 parentElem.appendChild( element );
01242 if (layout.counter )
01243 layout.counter->save( element );
01244 }
01245
01246 KoTabulatorList tabList = layout.tabList();
01247 KoTabulatorList::ConstIterator it = tabList.begin();
01248 for ( ; it != tabList.end() ; it++ )
01249 {
01250 element = doc.createElement( "TABULATOR" );
01251 parentElem.appendChild( element );
01252 element.setAttribute( "type", (*it).type );
01253 element.setAttribute( "ptpos", (*it).ptPos );
01254 element.setAttribute( "filling", (*it).filling );
01255 element.setAttribute( "width", (*it).ptWidth );
01256 }
01257 }
01258
01259 void KPrTextObject::recalcPageNum( KPrPage *page )
01260 {
01261 int pgnum=m_doc->pageList().findRef(page);
01262
01263 pgnum+=1;
01264 QPtrListIterator<KoTextCustomItem> cit( textDocument()->allCustomItems() );
01265 for ( ; cit.current() ; ++cit )
01266 {
01267 KPrPgNumVariable * var = dynamic_cast<KPrPgNumVariable *>( cit.current() );
01268 if ( var && !var->isDeleted() )
01269 {
01270 switch ( var->subType() ) {
01271 case KPrPgNumVariable::VST_PGNUM_CURRENT:
01272 var->setPgNum( pgnum + kPresenterDocument()->getVariableCollection()->variableSetting()->startingPageNumber()-1);
01273 break;
01274 case KPrPgNumVariable::VST_CURRENT_SECTION:
01275 var->setSectionTitle( page->pageTitle() );
01276 break;
01277 case KPrPgNumVariable::VST_PGNUM_PREVIOUS:
01278 var->setPgNum( QMAX( pgnum -1 , 0) +
01279 kPresenterDocument()->getVariableCollection()->variableSetting()->startingPageNumber());
01280 break;
01281 case KPrPgNumVariable::VST_PGNUM_NEXT:
01282 var->setPgNum( QMIN( (int)m_doc->getPageNums(), pgnum+1 ) +
01283 kPresenterDocument()->getVariableCollection()->variableSetting()->startingPageNumber());
01284 break;
01285 default:
01286 break;
01287 }
01288
01289 var->resize();
01290 var->paragraph()->invalidate( 0 );
01291 var->paragraph()->setChanged( true );
01292 }
01293 }
01294 }
01295
01296 void KPrTextObject::layout()
01297 {
01298 invalidate();
01299
01300 m_textobj->formatMore( 2 );
01301 }
01302
01303 void KPrTextObject::invalidate()
01304 {
01305
01306 m_textobj->setLastFormattedParag( textDocument()->firstParag() );
01307 textDocument()->formatter()->setViewFormattingChars( m_doc->viewFormattingChars() );
01308 textDocument()->invalidate();
01309 }
01310
01311
01312 void KPrTextObject::drawParags( QPainter *painter, KoTextZoomHandler* zoomHandler, const QColorGroup& cg, int from, int to )
01313 {
01314
01315
01316
01317
01318
01319 Q_ASSERT( from <= to );
01320 int i = 0;
01321 bool editMode=false;
01322 if( m_doc->firstView() && m_doc->firstView()->getCanvas())
01323 editMode = m_doc->firstView()->getCanvas()->getEditMode();
01324
01325 QRect r = zoomHandler->zoomRect( KoRect( 0, 0, innerWidth(), innerHeight() ) );
01326 KoTextParag *parag = textDocument()->firstParag();
01327 while ( parag ) {
01328 if ( !parag->isValid() )
01329 parag->format();
01330 if ( i == from )
01331 r.setTop( m_doc->zoomHandler()->layoutUnitToPixelY( parag->rect().top() ) );
01332 if ( i == to ) {
01333 r.setBottom( m_doc->zoomHandler()->layoutUnitToPixelY( parag->rect().bottom() ) );
01334 break;
01335 }
01336 ++i;
01337 parag = parag->next();
01338 }
01339
01340 uint drawingFlags = 0;
01341 if ( m_doc->backgroundSpellCheckEnabled() && editMode )
01342 drawingFlags |= KoTextDocument::DrawMisspelledLine;
01343 textDocument()->drawWYSIWYG(
01344 painter, r.x(), r.y(), r.width(), r.height(),
01345 cg, m_doc->zoomHandler(),
01346 false , false , 0 ,
01347 true , drawingFlags );
01348 }
01349
01350 void KPrTextObject::drawCursor( QPainter *p, KoTextCursor *cursor, bool cursorVisible, KPrCanvas* canvas )
01351 {
01352
01353 KoTextZoomHandler *zh = m_doc->zoomHandler();
01354 QPoint origPix = zh->zoomPoint( orig+KoPoint(bLeft(), bTop()+alignVertical) );
01355
01356 p->translate( origPix.x(), origPix.y() );
01357 if ( angle != 0 )
01358 rotateObject( p, zh );
01359
01360 KoTextParag* parag = cursor->parag();
01361 QPoint topLeft = parag->rect().topLeft();
01362 int lineY;
01363
01364 int cursorHeight = zh->layoutUnitToPixelY( topLeft.y(), parag->lineHeightOfChar( cursor->index(), 0, &lineY ) );
01365 QPoint iPoint( topLeft.x() + cursor->x(),
01366 topLeft.y() + lineY );
01367
01368 iPoint = zh->layoutUnitToPixel( iPoint );
01369
01370 QPoint vPoint = iPoint;
01371
01372
01373
01374
01375
01376 QRect clip( vPoint.x() - 5, vPoint.y() , 10, cursorHeight );
01377 setupClipRegion( p, clip );
01378
01379
01380
01381
01382 QPixmap *pix = 0;
01383 QColorGroup cg = QApplication::palette().active();
01384 cg.setColor( QColorGroup::Base, m_doc->txtBackCol() );
01385
01386 uint drawingFlags = KoTextDocument::DrawSelections;
01387 if ( m_doc->backgroundSpellCheckEnabled() )
01388 drawingFlags |= KoTextDocument::DrawMisspelledLine;
01389 if ( m_doc->viewFormattingChars() )
01390 drawingFlags |= KoTextDocument::DrawFormattingChars;
01391
01392
01393 bool wasChanged = parag->hasChanged();
01394 int oldLineChanged = parag->lineChanged();
01395 int line;
01396 parag->lineStartOfChar( cursor->index(), 0, &line );
01397 parag->setChanged( false );
01398 parag->setLineChanged( line );
01399
01400
01401 textDocument()->drawParagWYSIWYG(
01402 p, parag,
01403 QMAX(0, iPoint.x() - 5),
01404 iPoint.y(), clip.width(), clip.height(),
01405 pix, cg, m_doc->zoomHandler(),
01406 cursorVisible, cursor, FALSE , drawingFlags );
01407
01408 if ( wasChanged )
01409 cursor->parag()->setLineChanged( oldLineChanged );
01410 else
01411 cursor->parag()->setChanged( false );
01412
01413
01414 QPoint ximPoint = vPoint;
01415 QFont f = parag->at( cursor->index() )->format()->font();
01416 canvas->setXimPosition( ximPoint.x() + origPix.x(), ximPoint.y() + origPix.y(),
01417 0, cursorHeight - parag->lineSpacing( line ), &f );
01418 }
01419
01420 KPrTextDocument * KPrTextObject::textDocument() const
01421 {
01422 return static_cast<KPrTextDocument*>(m_textobj->textDocument());
01423 }
01424
01425 void KPrTextObject::slotNewCommand( KCommand * cmd)
01426 {
01427 m_doc->addCommand(cmd);
01428 }
01429
01430 int KPrTextObject::availableHeight() const
01431 {
01432 return m_textobj->availableHeight();
01433 }
01434
01435 void KPrTextObject::slotAvailableHeightNeeded()
01436 {
01437 int ah = m_doc->zoomHandler()->ptToLayoutUnitPixY( innerHeight() );
01438 m_textobj->setAvailableHeight( ah );
01439
01440 }
01441
01442 void KPrTextObject::slotRepaintChanged()
01443 {
01444 emit repaintChanged( this );
01445 }
01446
01447 KPrTextView * KPrTextObject::createKPTextView( KPrCanvas * _canvas, bool temp )
01448 {
01449 return new KPrTextView( this, _canvas, temp );
01450 }
01451
01452 void KPrTextObject::removeHighlight ()
01453 {
01454 m_textobj->removeHighlight( true );
01455 }
01456
01457 void KPrTextObject::highlightPortion( KoTextParag * parag, int index, int length, KPrCanvas* canvas, bool repaint, KDialogBase* dialog )
01458 {
01459 m_textobj->highlightPortion( parag, index, length, repaint );
01460 if ( repaint )
01461 {
01462 KPrDocument* doc = canvas->getView()->kPresenterDoc();
01463
01464
01465 if ( canvas->activePage()->findTextObject( this ) )
01466 {
01467 kdDebug(33001) << k_funcinfo << "object in current page" << endl;
01468 }
01469 else
01470 {
01471
01472
01473 KPrPage* page = doc->findPage( this );
01474 if ( page ) {
01475 int pageNum = doc->pageList().findRef( page );
01476
01477 if ( pageNum > -1 )
01478 {
01479 canvas->getView()->skipToPage( pageNum );
01480 }
01481 } else
01482 kdWarning(33001) << "object " << this << " not found in any page!?" << endl;
01483 }
01484
01485 QRect rect = m_doc->zoomHandler()->zoomRect( getRect() );
01486 QRect expose = m_doc->zoomHandler()->layoutUnitToPixel( parag->rect() );
01487 expose.moveBy( rect.x(), rect.y() );
01488 canvas->ensureVisible( (expose.left()+expose.right()) / 2,
01489 (expose.top()+expose.bottom()) / 2,
01490 (expose.right()-expose.left()) / 2,
01491 (expose.bottom()-expose.top()) / 2);
01492 #if KDE_IS_VERSION(3,1,90)
01493 if ( dialog ) {
01494 QRect globalRect( expose );
01495 globalRect.moveTopLeft( canvas->mapToGlobal( globalRect.topLeft() ) );
01496 KDialog::avoidArea( dialog, globalRect );
01497 }
01498 #endif
01499 }
01500 }
01501
01502 KCommand * KPrTextObject::pasteOasis( KoTextCursor * cursor, const QByteArray & data, bool removeSelected )
01503 {
01504
01505 KMacroCommand * macroCmd = new KMacroCommand( i18n("Paste Text") );
01506 if ( removeSelected && textDocument()->hasSelection( KoTextDocument::Standard ) )
01507 macroCmd->addCommand( m_textobj->removeSelectedTextCommand( cursor, KoTextDocument::Standard ) );
01508 m_textobj->emitHideCursor();
01509 m_textobj->setLastFormattedParag( cursor->parag()->prev() ?
01510 cursor->parag()->prev() : cursor->parag() );
01511
01512
01513
01514 KPrOasisPasteTextCommand * cmd = new KPrOasisPasteTextCommand( textDocument(), cursor->parag()->paragId(), cursor->index(), data );
01515 textDocument()->addCommand( cmd );
01516
01517 macroCmd->addCommand( new KoTextCommand( m_textobj, QString::null ) );
01518 *cursor = *( cmd->execute( cursor ) );
01519
01520 m_textobj->formatMore( 2 );
01521 emit repaintChanged( this );
01522 m_textobj->emitEnsureCursorVisible();
01523 m_textobj->emitUpdateUI( true );
01524 m_textobj->emitShowCursor();
01525 m_textobj->selectionChangedNotify();
01526 return macroCmd;
01527 }
01528
01529
01530 void KPrTextObject::setShadowParameter(int _distance,ShadowDirection _direction,const QColor &_color)
01531 {
01532 int sx = 0;
01533 int sy = 0;
01534 switch ( _direction )
01535 {
01536 case SD_LEFT_BOTTOM:
01537 case SD_LEFT:
01538 case SD_LEFT_UP:
01539 sx = - _distance;
01540 case SD_RIGHT_UP:
01541 case SD_RIGHT:
01542 case SD_RIGHT_BOTTOM:
01543 sx = _distance;
01544 default:
01545 break;
01546 }
01547 switch ( _direction )
01548 {
01549 case SD_LEFT_UP:
01550 case SD_UP:
01551 case SD_RIGHT_UP:
01552 sy = - _distance;
01553 case SD_LEFT_BOTTOM:
01554 case SD_BOTTOM:
01555 case SD_RIGHT_BOTTOM:
01556 sy = _distance;
01557 default:
01558 break;
01559 }
01560 KoTextFormat tmpFormat;
01561 tmpFormat.setShadow( sx, sy, _color );
01562 KCommand* cmd = m_textobj->setFormatCommand( &tmpFormat, KoTextFormat::ShadowText );
01563 if ( cmd )
01564 m_doc->addCommand(cmd);
01565 }
01566
01567 void KPrTextObject::slotFormatChanged(const KoTextFormat &_format)
01568 {
01569 if(m_doc && m_doc->firstView())
01570 m_doc->firstView()->showFormat( _format );
01571 }
01572
01573 void KPrTextObject::applyStyleChange( KoStyleChangeDefMap changed )
01574 {
01575 m_textobj->applyStyleChange( changed );
01576 }
01577
01578 void KPrTextObject::slotAfterFormatting( int bottom, KoTextParag* lastFormatted, bool* abort)
01579 {
01580 recalcVerticalAlignment();
01581 int availHeight = availableHeight() - m_doc->zoomHandler()->ptToLayoutUnitPixY(alignmentValue());
01582 if ( ( bottom > availHeight ) ||
01583 ( lastFormatted && (bottom + lastFormatted->rect().height() > availHeight) ) )
01584 {
01585 int difference = ( bottom + 2 ) - availHeight;
01586 if( lastFormatted && bottom + lastFormatted->rect().height() > availHeight )
01587 {
01588 difference += lastFormatted->rect().height();
01589 }
01590 #if 0
01591 if(lastFormatted)
01592 kdDebug(33001) << "slotAfterFormatting We need more space in " << this
01593 << " bottom=" << bottom + lastFormatted->rect().height()
01594 << " availHeight=" << availHeight
01595 << " ->difference=" << difference << endl;
01596 else
01597 kdDebug(33001) << "slotAfterFormatting We need more space in " << this
01598 << " bottom2=" << bottom << " availHeight=" << availHeight
01599 << " ->difference=" << difference << endl;
01600 #endif
01601
01602 if(difference > 0 && !isProtect())
01603 {
01604 double wantedPosition = m_doc->zoomHandler()->layoutUnitPtToPt( m_doc->zoomHandler()->pixelYToPt( difference ) )
01605 + getRect().bottom();
01606 const KoPageLayout& p = m_doc->pageLayout();
01607 double pageBottom = p.ptHeight - p.ptBottom;
01608 double newBottom = QMIN( wantedPosition, pageBottom );
01609 newBottom = QMAX( newBottom, getOrig().y() );
01610
01611 if ( getRect().bottom() != newBottom )
01612 {
01613
01614
01615 KPrObject::setSize( getSize().width(), newBottom - getOrig().y() );
01616
01617 slotAvailableHeightNeeded();
01618 m_doc->updateRuler();
01619 m_doc->repaint( true );
01620 *abort = false;
01621 }
01622 }
01623 else if ( isProtect() )
01624 m_textobj->setLastFormattedParag( 0 );
01625 }
01626 }
01627
01628
01629 KCommand * KPrTextObject::textContentsToHeight()
01630 {
01631 if (isProtect() )
01632 return 0L;
01633
01634
01635 KoTextParag * parag = textDocument()->firstParag();
01636 int numLines = 0;
01637 int textHeightLU = 0;
01638 bool lineSpacingEqual = false;
01639 int oldLineSpacing = 0;
01640 for ( ; parag ; parag = parag->next() )
01641 {
01642 int lines = parag->lines();
01643 numLines += lines;
01644 for ( int line = 0 ; line < lines ; ++line )
01645 {
01646 int y, h, baseLine;
01647 parag->lineInfo( line, y, h, baseLine );
01648 int ls = parag->lineSpacing( line );
01649 lineSpacingEqual = (oldLineSpacing == ls);
01650 oldLineSpacing = ls;
01651 textHeightLU += h - ls;
01652 }
01653 }
01654
01655 double textHeight = m_doc->zoomHandler()->layoutUnitPtToPt( textHeightLU );
01656 double lineSpacing = ( innerHeight() - textHeight ) / numLines;
01657
01658
01659 if ( KABS( innerHeight() - textHeight ) < DBL_EPSILON )
01660 return 0L;
01661 bool oneLine =(textDocument()->firstParag() == textDocument()->lastParag() && numLines == 1);
01662 if ( lineSpacing < 0 || oneLine)
01663 lineSpacing = 0;
01664
01665 if ( (oneLine || lineSpacingEqual) && (textDocument()->firstParag()->kwLineSpacing() == lineSpacing))
01666 return 0L;
01667
01668 textDocument()->selectAll( KoTextDocument::Temp );
01669 KCommand* cmd = m_textobj->setLineSpacingCommand( 0L, lineSpacing, KoParagLayout::LS_CUSTOM, KoTextDocument::Temp );
01670 textDocument()->removeSelection( KoTextDocument::Temp );
01671 return cmd;
01672 }
01673
01674
01675 KCommand * KPrTextObject::textObjectToContents()
01676 {
01677 if ( isProtect() )
01678 return 0L;
01679
01680
01681 KoTextParag * parag = textDocument()->firstParag();
01682 double txtWidth = 10;
01683 for ( ; parag ; parag = parag->next() )
01684 txtWidth = QMAX( txtWidth, m_doc->zoomHandler()->layoutUnitPtToPt( parag->widthUsed() ));
01685
01686
01687 int heightLU = textDocument()->height();
01688 double txtHeight = m_doc->zoomHandler()->layoutUnitPtToPt( heightLU );
01689
01690
01691 KoSize sizeDiff = KoSize( txtWidth, txtHeight ) - innerRect().size();
01692 if( !sizeDiff.isNull() )
01693 {
01694
01695 return new KPrResizeCmd( QString::null, KoPoint( 0, 0 ), sizeDiff, this, m_doc);
01696 }
01697 return 0L;
01698 }
01699
01700 void KPrTextObject::setTextMargins( double _left, double _top, double _right, double _bottom)
01701 {
01702 bleft = _left;
01703 btop = _top;
01704 bright = _right;
01705 bbottom = _bottom;
01706 }
01707
01708 KoRect KPrTextObject::innerRect() const
01709 {
01710 KoRect inner( getRect());
01711 inner.moveBy( bLeft(), bTop());
01712 inner.setWidth( inner.width() - bLeft() - bRight() );
01713 inner.setHeight( inner.height() - bTop() - bBottom() );
01714 return inner;
01715 }
01716
01717 double KPrTextObject::innerWidth() const
01718 {
01719 return getSize().width() - bLeft() - bRight();
01720 }
01721
01722 double KPrTextObject::innerHeight() const
01723 {
01724 return getSize().height() - bTop() - bBottom();
01725 }
01726
01727 void KPrTextObject::setVerticalAligment( VerticalAlignmentType _type)
01728 {
01729 m_textVertAlign = _type;
01730 recalcVerticalAlignment();
01731 }
01732
01733 void KPrTextObject::recalcVerticalAlignment()
01734 {
01735 double txtHeight = m_doc->zoomHandler()->layoutUnitPtToPt( m_doc->zoomHandler()->pixelYToPt( textDocument()->height() ) ) + btop + bbottom;
01736 double diffy = getSize().height() - txtHeight;
01737
01738
01739
01740 if ( diffy <= 0.0 ) {
01741 alignVertical = 0.0;
01742 return;
01743 }
01744 switch( m_textVertAlign )
01745 {
01746 case KP_CENTER:
01747 alignVertical = diffy/2.0;
01748 break;
01749 case KP_TOP:
01750 alignVertical = 0.0;
01751 break;
01752 case KP_BOTTOM:
01753 alignVertical = diffy;
01754 break;
01755 }
01756 }
01757
01758 QPoint KPrTextObject::cursorPos(KPrCanvas *canvas, KoTextCursor *cursor) const
01759 {
01760 KoTextZoomHandler *zh = m_doc->zoomHandler();
01761 QPoint origPix = zh->zoomPoint( orig+KoPoint(bLeft(), bTop()+alignVertical) );
01762 KoTextParag* parag = cursor->parag();
01763 QPoint topLeft = parag->rect().topLeft();
01764 int lineY = 0;
01765
01766
01767 QPoint iPoint( topLeft.x() + cursor->x(), topLeft.y() + lineY );
01768 iPoint = zh->layoutUnitToPixel( iPoint );
01769 iPoint.rx() -= canvas->diffx();
01770 iPoint.ry() -= canvas->diffy();
01771 return origPix+iPoint;
01772 }
01773
01774 KPrTextView::KPrTextView( KPrTextObject * txtObj, KPrCanvas *_canvas, bool temp )
01775 : KoTextView( txtObj->textObject() )
01776 {
01777 setBackSpeller( txtObj->kPresenterDocument()->backSpeller() );
01778 m_canvas=_canvas;
01779 m_kptextobj=txtObj;
01780 if (temp)
01781 return;
01782 connect( txtObj->textObject(), SIGNAL( selectionChanged(bool) ),
01783 m_canvas, SIGNAL( selectionChanged(bool) ) );
01784 KoTextView::setReadWrite( txtObj->kPresenterDocument()->isReadWrite() );
01785 connect( textView(), SIGNAL( cut() ), SLOT( cut() ) );
01786 connect( textView(), SIGNAL( copy() ), SLOT( copy() ) );
01787 connect( textView(), SIGNAL( paste() ), SLOT( paste() ) );
01788 updateUI( true, true );
01789
01790 txtObj->setEditingTextObj( true );
01791 }
01792
01793 KPrTextView::~KPrTextView()
01794 {
01795 }
01796
01797 KoTextViewIface* KPrTextView::dcopObject()
01798 {
01799 if ( !dcop )
01800 dcop = new KPrTextViewIface( this );
01801
01802 return dcop;
01803 }
01804
01805 void KPrTextView::terminate(bool removeSelection)
01806 {
01807 disconnect( textView()->textObject(), SIGNAL( selectionChanged(bool) ),
01808 m_canvas, SIGNAL( selectionChanged(bool) ) );
01809 textView()->terminate(removeSelection);
01810 }
01811
01812 void KPrTextView::cut()
01813 {
01814 if ( textDocument()->hasSelection( KoTextDocument::Standard ) ) {
01815 copy();
01816 textObject()->removeSelectedText( cursor() );
01817 }
01818 }
01819
01820 void KPrTextView::copy()
01821 {
01822
01823 if ( textDocument()->hasSelection( KoTextDocument::Standard ) ) {
01824 QDragObject *drag = newDrag( 0 );
01825 QApplication::clipboard()->setData( drag );
01826 }
01827 }
01828
01829 void KPrTextView::paste()
01830 {
01831
01832
01833 QMimeSource *data = QApplication::clipboard()->data();
01834 QCString returnedMimeType = KoTextObject::providesOasis( data );
01835 if ( !returnedMimeType.isEmpty() )
01836 {
01837 QByteArray arr = data->encodedData( returnedMimeType );
01838 if ( arr.size() )
01839 {
01840 #if 0
01841 QFile paste( "/tmp/oasis.tmp" );
01842 paste.open( IO_WriteOnly );
01843 paste.writeBlock( arr );
01844 paste.close();
01845 #endif
01846 KCommand *cmd = kpTextObject()->pasteOasis( cursor(), arr, true );
01847 if ( cmd )
01848 kpTextObject()->kPresenterDocument()->addCommand(cmd);
01849 }
01850 }
01851 else
01852 {
01853
01854
01855 QString text = QApplication::clipboard()->text();
01856 if ( !text.isEmpty() )
01857 textObject()->pasteText( cursor(), text, currentFormat(), true );
01858 }
01859 kpTextObject()->layout();
01860 }
01861
01862 void KPrTextView::updateUI( bool updateFormat, bool force )
01863 {
01864 KoTextView::updateUI( updateFormat, force );
01865
01866 KoTextParag * parag = static_cast<KoTextParag*>( cursor()->parag());
01867 if ( m_paragLayout.alignment != parag->resolveAlignment() || force ) {
01868 m_paragLayout.alignment = parag->resolveAlignment();
01869 m_canvas->getView()->alignChanged( m_paragLayout.alignment );
01870 }
01871
01872
01873 if ( !m_paragLayout.counter )
01874 m_paragLayout.counter = new KoParagCounter;
01875 KoParagCounter::Style cstyle = m_paragLayout.counter->style();
01876 if ( parag->counter() )
01877 *m_paragLayout.counter = *parag->counter();
01878 else
01879 {
01880 m_paragLayout.counter->setNumbering( KoParagCounter::NUM_NONE );
01881 m_paragLayout.counter->setStyle( KoParagCounter::STYLE_NONE );
01882 }
01883
01884 if ( m_paragLayout.counter->style() != cstyle || force )
01885 m_canvas->getView()->showCounter( * m_paragLayout.counter );
01886
01887 if(m_paragLayout.leftBorder!=parag->leftBorder() ||
01888 m_paragLayout.rightBorder!=parag->rightBorder() ||
01889 m_paragLayout.topBorder!=parag->topBorder() ||
01890 m_paragLayout.bottomBorder!=parag->bottomBorder() || force )
01891 {
01892 m_paragLayout.leftBorder = parag->leftBorder();
01893 m_paragLayout.rightBorder = parag->rightBorder();
01894 m_paragLayout.topBorder = parag->topBorder();
01895 m_paragLayout.bottomBorder = parag->bottomBorder();
01896
01897
01898 }
01899
01900 if ( !parag->style() )
01901 kdWarning(33001) << "Paragraph " << parag->paragId() << " has no style" << endl;
01902 else if ( m_paragLayout.style != parag->style() || force )
01903 {
01904 m_paragLayout.style = parag->style();
01905 m_canvas->getView()->showStyle( m_paragLayout.style->name() );
01906 }
01907
01908 if( m_paragLayout.margins[QStyleSheetItem::MarginLeft] != parag->margin(QStyleSheetItem::MarginLeft)
01909 || m_paragLayout.margins[QStyleSheetItem::MarginFirstLine] != parag->margin(QStyleSheetItem::MarginFirstLine)
01910 || m_paragLayout.margins[QStyleSheetItem::MarginRight] != parag->margin(QStyleSheetItem::MarginRight)
01911 || force )
01912 {
01913 m_paragLayout.margins[QStyleSheetItem::MarginFirstLine] = parag->margin(QStyleSheetItem::MarginFirstLine);
01914 m_paragLayout.margins[QStyleSheetItem::MarginLeft] = parag->margin(QStyleSheetItem::MarginLeft);
01915 m_paragLayout.margins[QStyleSheetItem::MarginRight] = parag->margin(QStyleSheetItem::MarginRight);
01916 m_canvas->getView()->showRulerIndent( m_paragLayout.margins[QStyleSheetItem::MarginLeft],
01917 m_paragLayout.margins[QStyleSheetItem::MarginFirstLine],
01918 m_paragLayout.margins[QStyleSheetItem::MarginRight],
01919 parag->string()->isRightToLeft() );
01920 }
01921
01922 if( m_paragLayout.tabList() != parag->tabList() || force )
01923 {
01924 m_paragLayout.setTabList( parag->tabList() );
01925 KoRuler * hr = m_canvas->getView()->getHRuler();
01926 if ( hr )
01927 hr->setTabList( parag->tabList() );
01928 }
01929 }
01930
01931 void KPrTextView::ensureCursorVisible()
01932 {
01933
01934 KoTextParag * parag = cursor()->parag();
01935 kpTextObject()->textObject()->ensureFormatted( parag );
01936 KoTextStringChar *chr = parag->at( cursor()->index() );
01937 int h = parag->lineHeightOfChar( cursor()->index() );
01938 int x = parag->rect().x() + chr->x;
01939 int y = 0; int dummy;
01940
01941 parag->lineHeightOfChar( cursor()->index(), &dummy, &y );
01942 y += parag->rect().y();
01943 int w = 1;
01944 KPrDocument *doc= m_kptextobj->kPresenterDocument();
01945 KoPoint pt= kpTextObject()->getOrig();
01946 pt.setX( doc->zoomHandler()->layoutUnitPtToPt( doc->zoomHandler()->pixelXToPt( x) ) +pt.x());
01947 pt.setY( doc->zoomHandler()->layoutUnitPtToPt( doc->zoomHandler()->pixelYToPt( y ))+pt.y() );
01948
01949 QPoint p = m_kptextobj->kPresenterDocument()->zoomHandler()->zoomPoint( pt );
01950 w = m_kptextobj->kPresenterDocument()->zoomHandler()->layoutUnitToPixelX( w );
01951 h = m_kptextobj->kPresenterDocument()->zoomHandler()->layoutUnitToPixelY( h );
01952 m_canvas->ensureVisible( p.x(), p.y() + h / 2, w, h / 2 + 2 );
01953 }
01954
01955 bool KPrTextView::doCompletion( KoTextCursor* cursor, KoTextParag *parag, int index )
01956 {
01957 if( m_kptextobj->kPresenterDocument()->allowAutoFormat() )
01958 {
01959 KoAutoFormat * autoFormat = m_kptextobj->kPresenterDocument()->getAutoFormat();
01960 if( autoFormat )
01961 return autoFormat->doCompletion( cursor, parag, index, textObject());
01962 }
01963 return false;
01964 }
01965
01966 bool KPrTextView::doToolTipCompletion( KoTextCursor* cursor, KoTextParag *parag, int index,int keyPress )
01967 {
01968 if( m_kptextobj->kPresenterDocument()->allowAutoFormat() )
01969 {
01970 KoAutoFormat * autoFormat = m_kptextobj->kPresenterDocument()->getAutoFormat();
01971 if( autoFormat )
01972 return autoFormat->doToolTipCompletion( cursor, parag, index, textObject(), keyPress);
01973 }
01974 return false;
01975 }
01976 void KPrTextView::showToolTipBox(KoTextParag *parag, int index, QWidget *widget, const QPoint &pos)
01977 {
01978 if( m_kptextobj->kPresenterDocument()->allowAutoFormat() )
01979 {
01980 KoAutoFormat * autoFormat = m_kptextobj->kPresenterDocument()->getAutoFormat();
01981 if( autoFormat )
01982 autoFormat->showToolTipBox(parag, index, widget, pos);
01983 }
01984 }
01985
01986 void KPrTextView::removeToolTipCompletion()
01987 {
01988 if( m_kptextobj->kPresenterDocument()->allowAutoFormat() )
01989 {
01990 KoAutoFormat * autoFormat = m_kptextobj->kPresenterDocument()->getAutoFormat();
01991 if( autoFormat )
01992 autoFormat->removeToolTipCompletion();
01993 }
01994 }
01995 void KPrTextView::textIncreaseIndent()
01996 {
01997 m_canvas->setTextDepthPlus();
01998 }
01999
02000 bool KPrTextView::textDecreaseIndent()
02001 {
02002 if (m_paragLayout.margins[QStyleSheetItem::MarginLeft]>0)
02003 {
02004 m_canvas->setTextDepthMinus();
02005 return true;
02006 }
02007 else
02008 return false;
02009 }
02010
02011 void KPrTextView::doAutoFormat( KoTextCursor* cursor, KoTextParag *parag, int index, QChar ch )
02012 {
02013 if( m_kptextobj->kPresenterDocument()->allowAutoFormat())
02014 {
02015 KoAutoFormat * autoFormat = m_kptextobj->kPresenterDocument()->getAutoFormat();
02016 if ( autoFormat )
02017 autoFormat->doAutoFormat( cursor, parag, index, ch, textObject());
02018 }
02019 }
02020
02021 bool KPrTextView::doIgnoreDoubleSpace(KoTextParag * parag, int index,QChar ch )
02022 {
02023 if( m_kptextobj->kPresenterDocument()->allowAutoFormat())
02024 {
02025
02026 KoAutoFormat * autoFormat = m_kptextobj->kPresenterDocument()->getAutoFormat();
02027 if( autoFormat )
02028 return autoFormat->doIgnoreDoubleSpace( parag, index,ch );
02029 }
02030 return false;
02031 }
02032
02033 void KPrTextView::startDrag()
02034 {
02035 textView()->dragStarted();
02036 m_canvas->dragStarted();
02037 QDragObject *drag = newDrag( m_canvas );
02038 if ( !kpTextObject()->kPresenterDocument()->isReadWrite() )
02039 drag->dragCopy();
02040 else
02041 {
02042 if ( drag->drag() && QDragObject::target() != m_canvas )
02043 textObject()->removeSelectedText( cursor() );
02044 }
02045 }
02046
02047 void KPrTextView::showFormat( KoTextFormat *format )
02048 {
02049 m_canvas->getView()->showFormat( *format );
02050 }
02051
02052 bool KPrTextView::pgUpKeyPressed()
02053 {
02054 KoTextCursor *cursor = textView()->cursor();
02055 KoTextParag *s = cursor->parag();
02056 s = textDocument()->firstParag();
02057
02058 textView()->cursor()->setParag( s );
02059 textView()->cursor()->setIndex( 0 );
02060 return true;
02061 }
02062
02063 bool KPrTextView::pgDownKeyPressed()
02064 {
02065 KoTextCursor *cursor = textView()->cursor();
02066 KoTextParag *s = cursor->parag();
02067 s = textDocument()->lastParag();
02068 cursor->setParag( s );
02069 cursor->setIndex( s->length() - 1 );
02070 return true;
02071 }
02072
02073 void KPrTextView::keyPressEvent( QKeyEvent *e )
02074 {
02075
02076 const QPoint pos = kpTextObject()->cursorPos(m_canvas, cursor());
02077 textView()->handleKeyPressEvent( e, m_canvas, pos );
02078 }
02079
02080 void KPrTextView::keyReleaseEvent( QKeyEvent *e )
02081 {
02082 handleKeyReleaseEvent(e);
02083 }
02084
02085 void KPrTextView::imStartEvent( QIMEvent *e )
02086 {
02087 handleImStartEvent(e);
02088 }
02089
02090 void KPrTextView::imComposeEvent( QIMEvent *e )
02091 {
02092 handleImComposeEvent(e);
02093 }
02094
02095 void KPrTextView::imEndEvent( QIMEvent *e )
02096 {
02097 handleImEndEvent(e);
02098 }
02099
02100 void KPrTextView::clearSelection()
02101 {
02102 if ( textDocument()->hasSelection( KoTextDocument::Standard ) )
02103 textDocument()->removeSelection(KoTextDocument::Standard );
02104 }
02105
02106 void KPrTextView::selectAll(bool select)
02107 {
02108 textObject()->selectAll( select );
02109 }
02110
02111 void KPrTextView::drawCursor( bool b )
02112 {
02113 KoTextView::drawCursor( b );
02114 if ( !cursor()->parag() )
02115 return;
02116 if ( !kpTextObject()->kPresenterDocument()->isReadWrite() )
02117 return;
02118
02119 QPainter painter( m_canvas );
02120 painter.translate( -m_canvas->diffx(), -m_canvas->diffy() );
02121 painter.setBrushOrigin( -m_canvas->diffx(), -m_canvas->diffy() );
02122
02123 kpTextObject()->drawCursor( &painter, cursor(), b, m_canvas );
02124 }
02125
02126
02127 QPoint KPrTextView::viewToInternal( const QPoint & pos ) const
02128 {
02129 #if 0
02130 KoTextZoomHandler* zh = kpTextObject()->kPresenterDocument()->zoomHandler();
02131 QPoint tmp(pos);
02132 QWMatrix m;
02133 m.translate( zh->zoomItX(kpTextObject()->getSize().width() / 2.0),
02134 zh->zoomItY(kpTextObject()->getSize().height() / 2.0) );
02135 m.rotate( kpTextObject()->getAngle() );
02136
02137
02138
02139 m.translate( zh->zoomItX(kpTextObject()->getOrig().x()),
02140 zh->zoomItY(kpTextObject()->getOrig().y()) );
02141
02142 tmp = m * pos;
02143
02144 kdDebug(33001)<<" tmp.x() :"<<tmp.x()<<" tmp.y() "<<tmp.y()<<endl;
02145
02146 KoRect br = KoRect( 0, 0, kpTextObject()->getSize().width(), kpTextObject()->getSize().height() );
02147 double pw = br.width();
02148 double ph = br.height();
02149 KoRect rr = br;
02150 double yPos = -rr.y();
02151 double xPos = -rr.x();
02152 rr.moveTopLeft( KoPoint( -rr.width() / 2.0, -rr.height() / 2.0 ) );
02153
02154 m.translate( zh->zoomItX(pw / 2.0),
02155 zh->zoomItY(ph / 2.0 ));
02156 m.rotate( kpTextObject()->getAngle() );
02157 m.translate( zh->zoomItX(rr.left() + xPos),
02158 zh->zoomItY(rr.top() + yPos) );
02159
02160 m = m.invert();
02161
02162 tmp = m * pos;
02163
02164 kdDebug(33001)<<" tmp.x() :"<<tmp.x()<<" tmp.y() "<<tmp.y()<<endl;
02165 #endif
02166
02167 return kpTextObject()->viewToInternal( pos, m_canvas );
02168 }
02169
02170 void KPrTextView::mousePressEvent( QMouseEvent *e, const QPoint &)
02171 {
02172 bool addParag = handleMousePressEvent( e, viewToInternal( e->pos() ),true ,
02173 kpTextObject()->kPresenterDocument()->insertDirectCursor() );
02174
02175 if ( addParag )
02176 kpTextObject()->kPresenterDocument()->setModified( true );
02177 }
02178
02179 void KPrTextView::mouseDoubleClickEvent( QMouseEvent *e, const QPoint &pos)
02180 {
02181 handleMouseDoubleClickEvent( e, pos );
02182 }
02183
02184 void KPrTextView::mouseMoveEvent( QMouseEvent *e, const QPoint &_pos )
02185 {
02186 if ( textView()->maybeStartDrag( e ) )
02187 return;
02188 if ( _pos.y() > 0 )
02189 textView()->handleMouseMoveEvent( e,viewToInternal( e->pos() ) );
02190 }
02191
02192 bool KPrTextView::isLinkVariable( const QPoint & pos )
02193 {
02194 const QPoint iPoint = viewToInternal( pos );
02195 KoLinkVariable* linkVariable = dynamic_cast<KoLinkVariable *>( textObject()->variableAtPoint( iPoint ) );
02196 return linkVariable != 0;
02197 }
02198
02199 void KPrTextView::openLink()
02200 {
02201 KPrDocument * doc = kpTextObject()->kPresenterDocument();
02202 if ( doc->getVariableCollection()->variableSetting()->displayLink() ) {
02203 KoLinkVariable* v = linkVariable();
02204 if ( v )
02205 KoTextView::openLink( v );
02206 }
02207 }
02208
02209 void KPrTextView::mouseReleaseEvent( QMouseEvent *, const QPoint & )
02210 {
02211 handleMouseReleaseEvent();
02212 }
02213
02214 void KPrTextView::showPopup( KPrView *view, const QPoint &point, QPtrList<KAction>& actionList )
02215 {
02216 QString word = wordUnderCursor( *cursor() );
02217 view->unplugActionList( "datatools" );
02218 view->unplugActionList( "datatools_link" );
02219 view->unplugActionList( "spell_result_action" );
02220 view->unplugActionList( "variable_action" );
02221 QPtrList<KAction> &variableList = view->variableActionList();
02222 variableList.clear();
02223 actionList.clear();
02224
02225 view->kPresenterDoc()->getVariableCollection()->setVariableSelected(variable());
02226 KoVariable* var = variable();
02227 if ( var )
02228 {
02229 variableList = view->kPresenterDoc()->getVariableCollection()->popupActionList();
02230 }
02231
02232 if( variableList.count()>0)
02233 {
02234 view->plugActionList( "variable_action", variableList );
02235 QPopupMenu * popup = view->popupMenu("variable_popup");
02236 Q_ASSERT(popup);
02237 if (popup)
02238 popup->popup( point );
02239
02240 }
02241 else
02242 {
02243 bool singleWord= false;
02244 actionList = dataToolActionList(view->kPresenterDoc()->instance(), word, singleWord);
02245
02246 KoLinkVariable* linkVar = dynamic_cast<KoLinkVariable *>( var );
02247 QPopupMenu * popup;
02248 if ( !linkVar )
02249 {
02250 view->plugActionList( "datatools", actionList );
02251
02252 KoNoteVariable * noteVar = dynamic_cast<KoNoteVariable *>( var );
02253 KoCustomVariable * customVar = dynamic_cast<KoCustomVariable *>( var );
02254 if( noteVar )
02255 popup = view->popupMenu("note_popup");
02256 else if( customVar )
02257 popup = view->popupMenu("custom_var_popup");
02258 else
02259 {
02260 if ( singleWord )
02261 {
02262 QPtrList<KAction> actionCheckSpellList =view->listOfResultOfCheckWord( word );
02263 if ( actionCheckSpellList.count()>0)
02264 {
02265 view->plugActionList( "spell_result_action", actionCheckSpellList );
02266 popup = view->popupMenu("text_popup_spell_with_result");
02267 }
02268 else
02269 popup = view->popupMenu("text_popup_spell");
02270 }
02271 else
02272 popup = view->popupMenu("text_popup");
02273 }
02274 }
02275 else
02276 {
02277 view->plugActionList( "datatools_link", actionList );
02278 popup = view->popupMenu("text_popup_link");
02279 }
02280 Q_ASSERT(popup);
02281 if (popup)
02282 popup->popup( point );
02283 }
02284 }
02285
02286 void KPrTextView::insertCustomVariable( const QString &name)
02287 {
02288 KPrDocument * doc = kpTextObject()->kPresenterDocument();
02289 KoVariable * var = new KoCustomVariable( textDocument(), name, doc->variableFormatCollection()->format( "STRING" ),
02290 doc->getVariableCollection());
02291 insertVariable( var );
02292 }
02293
02294 void KPrTextView::insertLink(const QString &_linkName, const QString & hrefName)
02295 {
02296 KPrDocument * doc = kpTextObject()->kPresenterDocument();
02297 KoVariable * var = new KoLinkVariable( textDocument(), _linkName, hrefName,
02298 doc->variableFormatCollection()->format( "STRING" ),
02299 doc->getVariableCollection());
02300 insertVariable( var );
02301 }
02302
02303 void KPrTextView::insertComment(const QString &_comment)
02304 {
02305 KPrDocument * doc = kpTextObject()->kPresenterDocument();
02306
02307 KoVariable * var = new KoNoteVariable( textDocument(), _comment,
02308 doc->variableFormatCollection()->format( "STRING" ),
02309 doc->getVariableCollection());
02310 insertVariable( var );
02311 }
02312
02313 void KPrTextView::insertVariable( int type, int subtype )
02314 {
02315 KPrDocument * doc = kpTextObject()->kPresenterDocument();
02316 bool refreshCustomMenu = false;
02317 KoVariable * var = 0L;
02318 if ( type == VT_CUSTOM )
02319 {
02320 KoCustomVarDialog dia( m_canvas );
02321 if ( dia.exec() == QDialog::Accepted )
02322 {
02323 KoCustomVariable *v = new KoCustomVariable( textDocument(), dia.name(),
02324 doc->variableFormatCollection()->format( "STRING" ),
02325 doc->getVariableCollection() );
02326 v->setValue( dia.value() );
02327 var = v;
02328 refreshCustomMenu = true;
02329 }
02330 }
02331 else
02332 var = doc->getVariableCollection()->createVariable( type, subtype, doc->variableFormatCollection(), 0L, textDocument(),doc, 0);
02333 if ( var )
02334 {
02335 insertVariable( var, 0, refreshCustomMenu);
02336 doc->recalcPageNum();
02337 }
02338 }
02339
02340 void KPrTextView::insertVariable( KoVariable *var, KoTextFormat *format, bool refreshCustomMenu )
02341 {
02342 if ( var )
02343 {
02344 CustomItemsMap customItemsMap;
02345 customItemsMap.insert( 0, var );
02346 if (!format)
02347 format = currentFormat();
02348
02349 #ifdef DEBUG_FORMATS
02350 kdDebug(33001) << "KPrTextView::insertVariable currentFormat=" << currentFormat() << endl;
02351 #endif
02352 textObject()->insert( cursor(), format, KoTextObject::customItemChar(),
02353 i18n("Insert Variable"),
02354 KoTextDocument::Standard,
02355 KoTextObject::DoNotRemoveSelected,
02356 customItemsMap );
02357 if ( refreshCustomMenu && var->type() == VT_CUSTOM )
02358 kpTextObject()->kPresenterDocument()->refreshMenuCustomVariable();
02359 kpTextObject()->kPresenterDocument()->repaint( kpTextObject() );
02360 }
02361 }
02362
02363 bool KPrTextView::canDecode( QMimeSource *e )
02364 {
02365 return kpTextObject()->kPresenterDocument()->isReadWrite() && ( KoTextObject::providesOasis( e ) || QTextDrag::canDecode( e ) );
02366 }
02367
02368 QDragObject * KPrTextView::newDrag( QWidget * parent )
02369 {
02370 QBuffer buffer;
02371 const QCString mimeType = "application/vnd.oasis.opendocument.text";
02372 KoStore * store = KoStore::createStore( &buffer, KoStore::Write, mimeType );
02373 Q_ASSERT( store );
02374 Q_ASSERT( !store->bad() );
02375
02376 KoOasisStore oasisStore( store );
02377
02378
02379
02380 KPrDocument * doc = kpTextObject()->kPresenterDocument();
02381
02382 doc->getVariableCollection()->variableSetting()->setModificationDate( QDateTime::currentDateTime() );
02383 doc->recalcVariables( VT_DATE );
02384 doc->recalcVariables( VT_TIME );
02385 doc->recalcVariables( VT_STATISTIC );
02386
02387 KoGenStyles mainStyles;
02388 KoSavingContext savingContext( mainStyles, 0, false, KoSavingContext::Store );
02389
02390 doc->styleCollection()->saveOasis( mainStyles, KoGenStyle::STYLE_USER, savingContext );
02391
02392 KoXmlWriter* bodyWriter = oasisStore.bodyWriter();
02393 bodyWriter->startElement( "office:body" );
02394 bodyWriter->startElement( "office:text" );
02395
02396 const QString plainText = textDocument()->copySelection( *bodyWriter, savingContext, KoTextDocument::Standard );
02397
02398 bodyWriter->endElement();
02399 bodyWriter->endElement();
02400
02401 KoXmlWriter* contentWriter = oasisStore.contentWriter();
02402 Q_ASSERT( contentWriter );
02403
02404
02405 doc->writeAutomaticStyles( *contentWriter, mainStyles, savingContext, false );
02406
02407 oasisStore.closeContentWriter();
02408
02409 if ( !store->open( "styles.xml" ) )
02410 return false;
02411
02412 doc->saveOasisDocumentStyles( store, mainStyles, 0, savingContext, KPrDocument::SaveSelected );
02413 if ( !store->close() )
02414 return false;
02415
02416 delete store;
02417
02418 KMultipleDrag* multiDrag = new KMultipleDrag( parent );
02419 if ( !plainText.isEmpty() )
02420 multiDrag->addDragObject( new QTextDrag( plainText, 0 ) );
02421 KoStoreDrag* storeDrag = new KoStoreDrag( mimeType, 0 );
02422 kdDebug() << k_funcinfo << "setting zip data: " << buffer.buffer().size() << " bytes." << endl;
02423 storeDrag->setEncodedData( buffer.buffer() );
02424 multiDrag->addDragObject( storeDrag );
02425 return multiDrag;
02426 }
02427
02428 void KPrTextView::dragEnterEvent( QDragEnterEvent *e )
02429 {
02430 if ( !canDecode( e ) )
02431 {
02432 e->ignore();
02433 return;
02434 }
02435 e->acceptAction();
02436 }
02437
02438 void KPrTextView::dragMoveEvent( QDragMoveEvent *e, const QPoint & )
02439 {
02440 if ( !canDecode( e ) )
02441 {
02442 e->ignore();
02443 return;
02444 }
02445 QPoint iPoint = viewToInternal( e->pos() );
02446
02447 textObject()->emitHideCursor();
02448 placeCursor( iPoint );
02449 textObject()->emitShowCursor();
02450 e->acceptAction();
02451 }
02452
02453 void KPrTextView::dropEvent( QDropEvent * e )
02454 {
02455 if ( canDecode( e ) )
02456 {
02457 KPrDocument *doc = kpTextObject()->kPresenterDocument();
02458 e->acceptAction();
02459 KoTextCursor dropCursor( textDocument() );
02460 QPoint dropPoint = viewToInternal( e->pos() );
02461 KMacroCommand *macroCmd=new KMacroCommand(i18n("Paste Text"));
02462 bool addMacroCmd = false;
02463 dropCursor.place( dropPoint, textDocument()->firstParag() );
02464 kdDebug(33001) << "KPrTextView::dropEvent dropCursor at parag=" << dropCursor.parag()->paragId() << " index=" << dropCursor.index() << endl;
02465
02466 if ( ( e->source() == m_canvas ) &&
02467 e->action() == QDropEvent::Move &&
02468
02469 textDocument()->hasSelection( KoTextDocument::Standard )
02470 ) {
02471
02472 KCommand *cmd = textView()->prepareDropMove( dropCursor );
02473 if(cmd)
02474 {
02475 kpTextObject()->layout();
02476 macroCmd->addCommand(cmd);
02477 addMacroCmd = true;
02478 }
02479 else
02480 {
02481 delete macroCmd;
02482 return;
02483 }
02484 }
02485 else
02486 {
02487 textDocument()->removeSelection( KoTextDocument::Standard );
02488 textObject()->selectionChangedNotify();
02489 }
02490 QCString returnedTypeMime = KoTextObject::providesOasis( e );
02491 if ( !returnedTypeMime.isEmpty() )
02492 {
02493 QByteArray arr = e->encodedData( returnedTypeMime );
02494 if ( arr.size() )
02495 {
02496 KCommand *cmd = kpTextObject()->pasteOasis( cursor(), arr, false );
02497 if ( cmd )
02498 {
02499 macroCmd->addCommand(cmd);
02500 addMacroCmd = true;
02501 }
02502 }
02503 }
02504 else
02505 {
02506 QString text;
02507 if ( QTextDrag::decode( e, text ) )
02508 textObject()->pasteText( cursor(), text, currentFormat(),
02509 false );
02510 }
02511 if ( addMacroCmd )
02512 doc->addCommand(macroCmd);
02513 else
02514 delete macroCmd;
02515 }
02516 }
02517
02518 void KPrTextObject::saveParagraph( QDomDocument& doc,KoTextParag * parag,QDomElement &parentElem,
02519 int from ,
02520 int to )
02521 {
02522 if(!parag)
02523 return;
02524 QDomElement paragraph=doc.createElement(tagP);
02525 int tmpAlign=0;
02526 switch(parag->resolveAlignment())
02527 {
02528 case Qt::AlignLeft:
02529 tmpAlign=1;
02530 break;
02531 case Qt::AlignRight:
02532 tmpAlign=2;
02533 break;
02534 case Qt::AlignHCenter:
02535 tmpAlign=4;
02536 break;
02537 case Qt::AlignJustify:
02538 tmpAlign=8;
02539 }
02540 if(tmpAlign!=1)
02541 paragraph.setAttribute(attrAlign, tmpAlign);
02542
02543 saveParagLayout( parag->paragLayout(), paragraph );
02544 KoTextFormat *lastFormat = 0;
02545 QString tmpText;
02546 for ( int i = from; i <= to; ++i ) {
02547 KoTextStringChar &c = parag->string()->at(i);
02548 if ( c.isCustom() )
02549 {
02550 QDomElement variable = doc.createElement("CUSTOM");
02551 variable.setAttribute("pos", (i-from));
02552 saveFormat( variable, c.format() );
02553 paragraph.appendChild( variable );
02554 static_cast<KoTextCustomItem *>( c.customItem() )->save(variable );
02555 }
02556 if ( !lastFormat || c.format()->key() != lastFormat->key() ) {
02557 if ( lastFormat )
02558 paragraph.appendChild(saveHelper(tmpText, lastFormat, doc));
02559 lastFormat = static_cast<KoTextFormat*> (c.format());
02560 tmpText=QString::null;
02561 }
02562 tmpText+=QString(c.c);
02563 }
02564 if ( lastFormat )
02565 paragraph.appendChild(saveHelper(tmpText, lastFormat, doc));
02566 else
02567 paragraph.appendChild(saveHelper(tmpText, parag->string()->at(0).format(), doc));
02568
02569 parentElem.appendChild(paragraph);
02570 }
02571
02572 KoPen KPrTextObject::defaultPen() const
02573 {
02574 return KoPen( Qt::black, 1.0, Qt::NoPen );
02575 }
02576
02577 QPoint KPrTextObject::viewToInternal( const QPoint & pos, KPrCanvas* canvas ) const
02578 {
02579 KoTextZoomHandler* zh = kPresenterDocument()->zoomHandler();
02580 QPoint iPoint = pos - zh->zoomPoint(
02581 getOrig() + KoPoint( bLeft(),
02582 bTop() + alignmentValue()) );
02583 iPoint = zh->pixelToLayoutUnit(
02584 QPoint( iPoint.x() + canvas->diffx(), iPoint.y() + canvas->diffy() ) );
02585 return iPoint;
02586 }