void DomainMapper_Impl::finishParagraph()

in main/writerfilter/source/dmapper/DomainMapper_Impl.cxx [707:1076]


void DomainMapper_Impl::finishParagraph( PropertyMapPtr pPropertyMap )
{
#ifdef DEBUG_DOMAINMAPPER
    dmapper_logger->startElement("finishParagraph");
#endif
    
    ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pPropertyMap.get() );
    TextAppendContext& rAppendContext = m_aTextAppendStack.top();
    uno::Reference< text::XTextAppend >  xTextAppend = rAppendContext.xTextAppend;
    PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
    
#ifdef DEBUG_DOMAINMAPPER
    dmapper_logger->attribute("isTextAppend", xTextAppend.is());
#endif 
    
    if(xTextAppend.is() && ! getTableManager( ).isIgnore() && pParaContext != NULL)
    {
        try
        {
            /*the following combinations of previous and current frame settings can occur:
                (1) - no old frame and no current frame     -> no special action
                (2) - no old frame and current DropCap      -> save DropCap for later use, don't call finishParagraph
                                                            remove character properties of the DropCap?
                (3) - no old frame and current Frame        -> save Frame for later use
                (4) - old DropCap and no current frame      -> add DropCap to the properties of the finished paragraph, delete previous setting
                (5) - old DropCap and current frame         -> add DropCap to the properties of the finished paragraph, save current frame settings
                (6) - old Frame and new DropCap             -> add old Frame, save DropCap for later use
                (7) - old Frame and new same Frame          -> continue
                (8) - old Frame and new different Frame     -> add old Frame, save new Frame for later use
                (9) - old Frame and no current frame        -> add old Frame, delete previous settings

              old _and_ new DropCap must not occur
             */

            bool bIsDropCap = 
                pParaContext->IsFrameMode() && 
                sal::static_int_cast<Id>(pParaContext->GetDropCap()) != NS_ooxml::LN_Value_wordprocessingml_ST_DropCap_none;

            style::DropCapFormat aDrop;
            ParagraphPropertiesPtr pToBeSavedProperties;
            bool bKeepLastParagraphProperties = false;
            if( bIsDropCap )
            {
                uno::Reference<text::XParagraphCursor> xParaCursor(
                    xTextAppend->createTextCursorByRange(xTextAppend->getEnd()), uno::UNO_QUERY_THROW);
                //select paragraph
                xParaCursor->gotoStartOfParagraph( true );
                uno::Reference< beans::XPropertyState > xParaProperties( xParaCursor, uno::UNO_QUERY_THROW );
                xParaProperties->setPropertyToDefault(rPropNameSupplier.GetName(PROP_CHAR_ESCAPEMENT));
                xParaProperties->setPropertyToDefault(rPropNameSupplier.GetName(PROP_CHAR_HEIGHT));
                //handles (2) and part of (6)
                pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
                sal_Int32 nCount = xParaCursor->getString().getLength();
                pToBeSavedProperties->SetDropCapLength(nCount > 0 && nCount < 255 ? (sal_Int8)nCount : 1);
            }
            if( rAppendContext.pLastParagraphProperties.get() )
            {
                if( sal::static_int_cast<Id>(rAppendContext.pLastParagraphProperties->GetDropCap()) != NS_ooxml::LN_Value_wordprocessingml_ST_DropCap_none)
                {
                    //handles (4) and part of (5)
                    //create a DropCap property, add it to the property sequence of finishParagraph
                    sal_Int32 nLines = rAppendContext.pLastParagraphProperties->GetLines();
                    aDrop.Lines = nLines > 0 && nLines < 254 ? (sal_Int8)++nLines : 2;
                    aDrop.Count = rAppendContext.pLastParagraphProperties->GetDropCapLength();
                    aDrop.Distance  = 0; //TODO: find distance value
                    //completes (5)
                    if( pParaContext->IsFrameMode() )
                        pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
                }
                else if(*rAppendContext.pLastParagraphProperties == *pParaContext )
                {
                    //handles (7)
                    rAppendContext.pLastParagraphProperties->SetEndingRange(xTextAppend->getEnd());
                    bKeepLastParagraphProperties = true;
                }
                else
                {
                    //handles (8)(9) and completes (6)
                    try
                    {
                        //
                        StyleSheetEntryPtr pParaStyle =
                            m_pStyleSheetTable->FindStyleSheetByConvertedStyleName(rAppendContext.pLastParagraphProperties->GetParaStyleName());
                        
                        PropertySequence aPropSequence;
                        if ( pParaStyle.get( ) )
                        {
                            const ParagraphProperties* pStyleProperties = dynamic_cast<const ParagraphProperties*>( pParaStyle->pProperties.get() );
                            sal_Int32 nWidth =
                                rAppendContext.pLastParagraphProperties->Getw() > 0 ?
                                rAppendContext.pLastParagraphProperties->Getw() :
                                pStyleProperties->Getw();
                            bool bAutoWidth = nWidth < 1;
                            if( bAutoWidth )
                                nWidth = DEFAULT_FRAME_MIN_WIDTH;
                            aPropSequence.set(PROP_WIDTH, nWidth);
                            
                            if (rAppendContext.pLastParagraphProperties->Geth())
                            {
                                aPropSequence.set(PROP_HEIGHT, rAppendContext.pLastParagraphProperties->Geth());
                            }
                            else
                            {
                                aPropSequence.set(PROP_HEIGHT, pStyleProperties->Geth());
                            }
                            
                            if (rAppendContext.pLastParagraphProperties->GethRule() >= 0)
                            {
                                aPropSequence.set(PROP_SIZE_TYPE, rAppendContext.pLastParagraphProperties->GethRule());
                            }
                            else if (pStyleProperties->GethRule() >=0)
                            {
                                aPropSequence.set(PROP_SIZE_TYPE, pStyleProperties->GethRule());
                            }
                            else
                            {
                                aPropSequence.set(PROP_SIZE_TYPE, text::SizeType::VARIABLE);
                            }
                            
                            if (bAutoWidth)
                            {
                                aPropSequence.set(PROP_WIDTH_TYPE,  text::SizeType::MIN);
                            }                                     
                            else
                            {
                                aPropSequence.set(PROP_WIDTH_TYPE,  text::SizeType::FIX);
                            }
                            
                            sal_Int16 nHoriOrient = text::HoriOrientation::NONE;
                            if ( rAppendContext.pLastParagraphProperties->GetxAlign() >= 0)
                            {
                                nHoriOrient = static_cast<sal_Int16>(rAppendContext.pLastParagraphProperties->GetxAlign());
                            }
                            else if (pStyleProperties->GetxAlign() >= 0)
                            {
                                nHoriOrient = static_cast<sal_Int16>(pStyleProperties->GetxAlign());
                            }

                            aPropSequence.set(PROP_HORI_ORIENT, nHoriOrient);

                            if (rAppendContext.pLastParagraphProperties->IsxValid())
                            {
                                aPropSequence.set(PROP_HORI_ORIENT_POSITION, 
                                                  rAppendContext.pLastParagraphProperties->Getx());
                            }
                            else
                            {
                                aPropSequence.set(PROP_HORI_ORIENT_POSITION, 
                                                  pStyleProperties->Getx());
                            }
                            
                            if (rAppendContext.pLastParagraphProperties->GethAnchor() >= 0)
                            {
                                aPropSequence.set(PROP_HORI_ORIENT_RELATION, 
                                                  rAppendContext.pLastParagraphProperties->GethAnchor());
                            }
                            else
                            {
                                aPropSequence.set(PROP_HORI_ORIENT_RELATION, pStyleProperties->GethAnchor());
                            }
                            
                            sal_Int16 nVertOrient =  text::VertOrientation::NONE;
                            if ( rAppendContext.pLastParagraphProperties->GetyAlign() >= 0)
                            {
                                nVertOrient = static_cast<sal_Int16>(rAppendContext.pLastParagraphProperties->GetyAlign());
                            }
                            else if ( pStyleProperties->GetyAlign() >= 0)
                            {
                                nVertOrient =  static_cast<sal_Int16>(pStyleProperties->GetyAlign());
                            }

                            aPropSequence.set(PROP_VERT_ORIENT, nVertOrient);
                            
                            if ( rAppendContext.pLastParagraphProperties->IsyValid())
                            {
                                aPropSequence.set(PROP_VERT_ORIENT_POSITION, rAppendContext.pLastParagraphProperties->Gety());                                   }
                            else
                            {
                                aPropSequence.set(PROP_VERT_ORIENT_POSITION,  pStyleProperties->Gety());
                            }
                            
                            if (rAppendContext.pLastParagraphProperties->GetvAnchor() >= 0)
                            {
                                aPropSequence.set(PROP_VERT_ORIENT_RELATION, 
                                                  rAppendContext.pLastParagraphProperties->GetvAnchor());
                            }
                            else
                            {
                                aPropSequence.set(PROP_VERT_ORIENT_RELATION, 
                                                  pStyleProperties->GetvAnchor());
                            }
                            
                            if (rAppendContext.pLastParagraphProperties->GetWrap() >= 0)
                            {
                                aPropSequence.set(PROP_SURROUND, 
                                                  rAppendContext.pLastParagraphProperties->GetWrap());
                            }
                            else
                            {
                                aPropSequence.set(PROP_SURROUND, 
                                                  pStyleProperties->GetWrap());
                            }
                            
                            sal_Int32 nTopDist;

                            if (nVertOrient == text::VertOrientation::TOP)
                            {
                                nTopDist = 0;
                            }
                            else
                            {
                                if (rAppendContext.pLastParagraphProperties->GethSpace() >= 0)
                                {
                                    nTopDist = rAppendContext.pLastParagraphProperties->GethSpace();
                                }
                                else
                                {
                                    nTopDist = pStyleProperties->GethSpace();
                                }
                            }

                            aPropSequence.set(PROP_TOP_MARGIN, nTopDist);
                            
                            sal_Int32 nBottomDist = nTopDist;
                            if (nVertOrient == text::VertOrientation::BOTTOM)
                            {
                                nBottomDist = 0;
                            }
                            
                            aPropSequence.set(PROP_BOTTOM_MARGIN, nBottomDist);

                            sal_Int32 nLeftDist = 0;
                            if (nHoriOrient == text::HoriOrientation::LEFT)
                            {
                                nLeftDist = 0;
                            }
                            else if (rAppendContext.pLastParagraphProperties->GetvSpace() >= 0)
                            {
                                nLeftDist = rAppendContext.pLastParagraphProperties->GetvSpace();
                            }
                            else if (pStyleProperties->GetvSpace() >= 0)
                            {
                                nLeftDist = pStyleProperties->GetvSpace();
                            }
                            else
                            {
                                nLeftDist = 0;
                            }

                            aPropSequence.set(PROP_LEFT_MARGIN, nLeftDist);
                            
                            sal_Int32 nRightDist = nLeftDist;
                                                        
                            if ( nHoriOrient == text::HoriOrientation::RIGHT)
                            {
                                nRightDist = 0;
                            }

                            aPropSequence.set(PROP_RIGHT_MARGIN, nRightDist);
                            
                            lcl_MoveBorderPropertiesToFrame(aPropSequence,
                                                            rAppendContext.pLastParagraphProperties->GetStartingRange(),
                                                            rAppendContext.pLastParagraphProperties->GetEndingRange());
                            lcl_CorrectIndents(aPropSequence);                            
                        }
                        //frame conversion has to be executed after table conversion
                        RegisterFrameConversion(rAppendContext.pLastParagraphProperties->GetStartingRange(),
                                                rAppendContext.pLastParagraphProperties->GetEndingRange(),
                                                aPropSequence.getSequence() );
                        // next frame follows directly
                        if( pParaContext->IsFrameMode() )
                        {
                            pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
                            lcl_AddRangeAndStyle(pToBeSavedProperties, xTextAppend, pPropertyMap);
                        }
                    }
                    catch( const uno::Exception& rEx )
                    {
                        (void)rEx;
                    }
                }

            }
            else //
            {
                // (1) doesn't need handling
                //
                if( !bIsDropCap && pParaContext->IsFrameMode() )
                {
                    pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
                    lcl_AddRangeAndStyle(pToBeSavedProperties, xTextAppend, pPropertyMap);
                }
            }
            
            PropertySequence::Pointer_t pPropSeq(new PropertySequence());

            if( pPropertyMap.get() )
            {
                pPropSeq.reset(new PropertySequence(pPropertyMap->GetPropertyValues()));
            }

            if( !bIsDropCap )
            {
                if( aDrop.Lines > 1 )
                {
                    uno::Any aAny(aDrop);

                    pPropSeq->set(PROP_DROP_CAP_FORMAT, aAny);
                }

                lcl_CorrectIndents(*pPropSeq);

                uno::Reference< text::XTextRange > xTextRange =
                    xTextAppend->finishParagraph( pPropSeq->getSequence() );
                getTableManager( ).handle(xTextRange);
            
                // Set the anchor of the objects to the created paragraph
                while ( m_aAnchoredStack.size( ) > 0 && !m_bIsInShape )
                {
                    uno::Reference< text::XTextContent > xObj = m_aAnchoredStack.top( );
                    try 
                    {
#if DEBUG
                        rtl::OUString sText( xTextRange->getString( ) );
#endif
                        xObj->attach( xTextRange );
                    } 
                    catch ( uno::RuntimeException& e)
                    {
                        // this is normal: the shape is already attached
                        (void) e;
                    }   
                    m_aAnchoredStack.pop( );
                }
    
                // Get the end of paragraph character inserted
                uno::Reference< text::XTextCursor > xCur = xTextRange->getText( )->createTextCursor( );
                xCur->gotoEnd( false );
                xCur->goLeft( 1 , true );
                uno::Reference< text::XTextRange > xParaEnd( xCur, uno::UNO_QUERY );
                CheckParaRedline( xParaEnd );

                // Remove the last empty section paragraph if needed
                if ( m_bIsLastParaInSection && !m_bParaChanged )
                {
                    RemoveLastParagraph( );
                    m_bIsLastParaInSection = false;
                }

                m_bParaChanged = false;
            }
            if( !bKeepLastParagraphProperties )
                rAppendContext.pLastParagraphProperties = pToBeSavedProperties;
        }
        catch(const lang::IllegalArgumentException& rIllegal)
        {
            (void)rIllegal;
            OSL_ENSURE( false, "IllegalArgumentException in DomainMapper_Impl::finishParagraph" );
        }
        catch(const uno::Exception& rEx)
        {
            (void)rEx;
            //OSL_ENSURE( false, "ArgumentException in DomainMapper_Impl::finishParagraph" );
        }
    }

#ifdef DEBUG_DOMAINMAPPER
    dmapper_logger->endElement("finishParagraph");
#endif
}