You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
402 lines
13 KiB
402 lines
13 KiB
/* This file is part of the KDE project
|
|
Copyright (C) 2001 David Faure <faure@kde.org>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "KoTextCommand.h"
|
|
#include "KoTextObject.h"
|
|
#include "KoTextParag.h"
|
|
#include "KoVariable.h"
|
|
#include <kdebug.h>
|
|
#include <tdelocale.h>
|
|
|
|
// This is automatically called by KCommandHistory's redo action when redo is activated
|
|
void KoTextCommand::execute()
|
|
{
|
|
m_textobj->redo();
|
|
}
|
|
|
|
// This is automatically called by KCommandHistory's undo action when undo is activated
|
|
void KoTextCommand::unexecute()
|
|
{
|
|
m_textobj->undo();
|
|
}
|
|
|
|
KoTextDeleteCommand::KoTextDeleteCommand(
|
|
KoTextDocument *d, int i, int idx, const TQMemArray<KoTextStringChar> &str,
|
|
const CustomItemsMap & customItemsMap,
|
|
const TQValueList<KoParagLayout> &oldParagLayouts )
|
|
: KoTextDocDeleteCommand( d, i, idx, str ),
|
|
m_oldParagLayouts( oldParagLayouts ),
|
|
m_customItemsMap( customItemsMap )
|
|
{
|
|
Q_ASSERT( id >= 0 );
|
|
}
|
|
|
|
KoTextCursor * KoTextDeleteCommand::execute( KoTextCursor *c )
|
|
{
|
|
KoTextParag *s = doc ? doc->paragAt( id ) : parag;
|
|
if ( !s ) {
|
|
kdWarning() << "can't locate parag at " << id << ", last parag: " << doc->lastParag()->paragId() << endl;
|
|
return 0;
|
|
}
|
|
cursor.setParag( s );
|
|
cursor.setIndex( index );
|
|
int len = text.size();
|
|
// Detach from custom items. They are already in the map, and we don't
|
|
// want them to be deleted
|
|
for ( int i = 0; i < len; ++i )
|
|
{
|
|
KoTextStringChar * ch = cursor.parag()->at( cursor.index() );
|
|
if ( ch->isCustom() )
|
|
{
|
|
ch->customItem()->setDeleted( true );
|
|
cursor.parag()->removeCustomItem(cursor.index());
|
|
}
|
|
cursor.gotoRight();
|
|
}
|
|
|
|
return KoTextDocDeleteCommand::execute(c);
|
|
}
|
|
|
|
KoTextCursor * KoTextDeleteCommand::unexecute( KoTextCursor *c )
|
|
{
|
|
// Let TQRichText re-create the text and formatting
|
|
KoTextCursor * cr = KoTextDocDeleteCommand::unexecute(c);
|
|
|
|
KoTextParag *s = doc ? doc->paragAt( id ) : parag;
|
|
if ( !s ) {
|
|
kdWarning() << "can't locate parag at " << id << ", last parag: " << (doc ? doc->lastParag()->paragId() : -1) << endl;
|
|
return 0;
|
|
}
|
|
cursor.setParag( s );
|
|
cursor.setIndex( index );
|
|
// Set any custom item that we had
|
|
m_customItemsMap.insertItems( cursor, text.size() );
|
|
|
|
// Now restore the parag layouts (i.e. libkotext specific stuff)
|
|
TQValueList<KoParagLayout>::Iterator lit = m_oldParagLayouts.begin();
|
|
kdDebug(32500) << "KoTextDeleteCommand::unexecute " << m_oldParagLayouts.count() << " parag layouts. First parag=" << s->paragId() << endl;
|
|
Q_ASSERT( id == s->paragId() );
|
|
KoTextParag *p = s;
|
|
while ( p ) {
|
|
if ( lit != m_oldParagLayouts.end() )
|
|
{
|
|
kdDebug(32500) << "KoTextDeleteCommand::unexecute applying paraglayout to parag " << p->paragId() << endl;
|
|
p->setParagLayout( *lit );
|
|
}
|
|
else
|
|
break;
|
|
//if ( s == cr->parag() )
|
|
// break;
|
|
p = p->next();
|
|
++lit;
|
|
}
|
|
return cr;
|
|
}
|
|
|
|
KoTextParagCommand::KoTextParagCommand( KoTextDocument *d, int fParag, int lParag,
|
|
const TQValueList<KoParagLayout> &oldParagLayouts,
|
|
KoParagLayout newParagLayout,
|
|
int flags,
|
|
TQStyleSheetItem::Margin margin )
|
|
: KoTextDocCommand( d ), firstParag( fParag ), lastParag( lParag ), m_oldParagLayouts( oldParagLayouts ),
|
|
m_newParagLayout( newParagLayout ), m_flags( flags ), m_margin( margin )
|
|
{
|
|
Q_ASSERT( fParag >= 0 );
|
|
Q_ASSERT( lParag >= 0 );
|
|
}
|
|
|
|
KoTextCursor * KoTextParagCommand::execute( KoTextCursor *c )
|
|
{
|
|
//kdDebug(32500) << "KoTextParagCommand::execute" << endl;
|
|
KoTextParag *p = doc->paragAt( firstParag );
|
|
if ( !p )
|
|
{
|
|
kdWarning() << "KoTextParagCommand::execute paragraph " << firstParag << "not found" << endl;
|
|
return c;
|
|
}
|
|
while ( p ) {
|
|
if ( ( m_flags & KoParagLayout::Margins ) && m_margin != (TQStyleSheetItem::Margin)-1 ) // all
|
|
p->setMargin( static_cast<TQStyleSheetItem::Margin>(m_margin), m_newParagLayout.margins[m_margin] );
|
|
else
|
|
{
|
|
p->setParagLayout( m_newParagLayout, m_flags );
|
|
}
|
|
if ( p->paragId() == lastParag )
|
|
break;
|
|
p = p->next();
|
|
}
|
|
//kdDebug(32500) << "KoTextParagCommand::execute done" << endl;
|
|
// Set cursor to end of selection. Like in KoTextFormatCommand::[un]execute...
|
|
c->setParag( p );
|
|
c->setIndex( p->length()-1 );
|
|
return c;
|
|
}
|
|
|
|
KoTextCursor * KoTextParagCommand::unexecute( KoTextCursor *c )
|
|
{
|
|
kdDebug(32500) << "KoTextParagCommand::unexecute" << endl;
|
|
KoTextParag *p = doc->paragAt( firstParag );
|
|
if ( !p )
|
|
{
|
|
kdDebug(32500) << "KoTextParagCommand::unexecute paragraph " << firstParag << "not found" << endl;
|
|
return c;
|
|
}
|
|
TQValueList<KoParagLayout>::Iterator lit = m_oldParagLayouts.begin();
|
|
while ( p ) {
|
|
if ( lit == m_oldParagLayouts.end() )
|
|
{
|
|
kdDebug(32500) << "KoTextParagCommand::unexecute m_oldParagLayouts not big enough!" << endl;
|
|
break;
|
|
}
|
|
if ( m_flags & KoParagLayout::Margins && m_margin != (TQStyleSheetItem::Margin)-1 ) // just one
|
|
p->setMargin( static_cast<TQStyleSheetItem::Margin>(m_margin), (*lit).margins[m_margin] );
|
|
else
|
|
{
|
|
p->setParagLayout( *lit, m_flags );
|
|
}
|
|
if ( p->paragId() == lastParag )
|
|
break;
|
|
p = p->next();
|
|
++lit;
|
|
}
|
|
// Set cursor to end of selection. Like in KoTextFormatCommand::[un]execute...
|
|
c->setParag( p );
|
|
c->setIndex( p->length()-1 );
|
|
return c;
|
|
}
|
|
|
|
//////////
|
|
|
|
KoParagFormatCommand::KoParagFormatCommand( KoTextDocument *d, int fParag, int lParag,
|
|
const TQValueList<KoTextFormat *> &oldFormats,
|
|
KoTextFormat * newFormat )
|
|
: KoTextDocCommand( d ), firstParag( fParag ), lastParag( lParag ), m_oldFormats( oldFormats ),
|
|
m_newFormat( newFormat )
|
|
{
|
|
TQValueList<KoTextFormat *>::Iterator lit = m_oldFormats.begin();
|
|
for ( ; lit != m_oldFormats.end() ; ++lit )
|
|
(*lit)->addRef();
|
|
}
|
|
|
|
KoParagFormatCommand::~KoParagFormatCommand()
|
|
{
|
|
TQValueList<KoTextFormat *>::Iterator lit = m_oldFormats.begin();
|
|
for ( ; lit != m_oldFormats.end() ; ++lit )
|
|
(*lit)->removeRef();
|
|
}
|
|
|
|
KoTextCursor * KoParagFormatCommand::execute( KoTextCursor *c )
|
|
{
|
|
KoTextParag *p = doc->paragAt( firstParag );
|
|
if ( !p )
|
|
{
|
|
kdDebug(32500) << "KoTextParagCommand::execute paragraph " << firstParag << "not found" << endl;
|
|
return c;
|
|
}
|
|
while ( p ) {
|
|
p->setFormat( m_newFormat );
|
|
p->invalidate(0);
|
|
if ( p->paragId() == lastParag )
|
|
break;
|
|
p = p->next();
|
|
}
|
|
return c;
|
|
}
|
|
|
|
KoTextCursor * KoParagFormatCommand::unexecute( KoTextCursor *c )
|
|
{
|
|
kdDebug(32500) << "KoParagFormatCommand::unexecute" << endl;
|
|
KoTextParag *p = doc->paragAt( firstParag );
|
|
if ( !p )
|
|
{
|
|
kdDebug(32500) << "KoParagFormatCommand::unexecute paragraph " << firstParag << "not found" << endl;
|
|
return c;
|
|
}
|
|
TQValueList<KoTextFormat *>::Iterator lit = m_oldFormats.begin();
|
|
while ( p ) {
|
|
if ( lit == m_oldFormats.end() )
|
|
{
|
|
kdDebug(32500) << "KoParagFormatCommand::unexecute m_oldFormats not big enough!" << endl;
|
|
break;
|
|
}
|
|
p->setFormat( (*lit) );
|
|
if ( p->paragId() == lastParag )
|
|
break;
|
|
p = p->next();
|
|
++lit;
|
|
}
|
|
return c;
|
|
}
|
|
|
|
KoTextFormatCommand::KoTextFormatCommand(KoTextDocument *d, int sid, int sidx, int eid, int eidx, const TQMemArray<KoTextStringChar> &old, const KoTextFormat *f, int fl )
|
|
: KoTextDocFormatCommand(d, sid, sidx, eid, eidx, old, f, fl)
|
|
{
|
|
}
|
|
|
|
|
|
KoTextFormatCommand::~KoTextFormatCommand()
|
|
{
|
|
}
|
|
|
|
void KoTextFormatCommand::resizeCustomItems()
|
|
{
|
|
KoTextParag *sp = doc->paragAt( startId );
|
|
KoTextParag *ep = doc->paragAt( endId );
|
|
if ( !sp || !ep )
|
|
return;
|
|
|
|
KoTextCursor start( doc );
|
|
start.setParag( sp );
|
|
start.setIndex( startIndex );
|
|
KoTextCursor end( doc );
|
|
end.setParag( ep );
|
|
end.setIndex( endIndex );
|
|
|
|
doc->setSelectionStart( KoTextDocument::Temp, &start );
|
|
doc->setSelectionEnd( KoTextDocument::Temp, &end );
|
|
|
|
// TODO use the visitor pattern (some 'ResizeCustomItemVisitor')
|
|
|
|
if ( start.parag() == end.parag() )
|
|
{
|
|
TQString text = start.parag()->string()->toString().mid( start.index(), end.index() - start.index() );
|
|
for ( int i = start.index(); i < end.index(); ++i )
|
|
{
|
|
if( start.parag()->at(i)->isCustom())
|
|
{
|
|
start.parag()->at(i)->customItem()->resize();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
TQString text = start.parag()->string()->toString().mid( start.index(), start.parag()->length() - 1 - start.index() );
|
|
for ( i = start.index(); i < start.parag()->length(); ++i )
|
|
if( start.parag()->at(i)->isCustom())
|
|
{
|
|
start.parag()->at(i)->customItem()->resize();
|
|
}
|
|
|
|
KoTextParag *p = start.parag()->next();
|
|
while ( p && p != end.parag() )
|
|
{
|
|
text = p->string()->toString().left( p->length() - 1 );
|
|
for ( i = 0; i < p->length(); ++i )
|
|
{
|
|
if( p->at(i)->isCustom())
|
|
{
|
|
p->at(i)->customItem()->resize();
|
|
}
|
|
}
|
|
p = p->next();
|
|
}
|
|
text = end.parag()->string()->toString().left( end.index() );
|
|
for ( i = 0; i < end.index(); ++i )
|
|
{
|
|
if( end.parag()->at(i)->isCustom())
|
|
{
|
|
end.parag()->at(i)->customItem()->resize();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
KoTextCursor *KoTextFormatCommand::execute( KoTextCursor *c )
|
|
{
|
|
c = KoTextDocFormatCommand::execute( c );
|
|
resizeCustomItems();
|
|
return c;
|
|
}
|
|
|
|
KoTextCursor *KoTextFormatCommand::unexecute( KoTextCursor *c )
|
|
{
|
|
kdDebug(32500) << "KoTextFormatCommand::unexecute c:" << c << " index:" << c->index() << endl;
|
|
c = KoTextDocFormatCommand::unexecute( c );
|
|
kdDebug(32500) << "KoTextFormatCommand::unexecute after KoTextFormatCommand c:" << c << " index:" << c->index() << endl;
|
|
resizeCustomItems();
|
|
return c;
|
|
}
|
|
|
|
////
|
|
|
|
KoChangeVariableSubType::KoChangeVariableSubType(
|
|
short int _oldValue, short int _newValue,
|
|
KoVariable *var):
|
|
KCommand(),
|
|
m_newValue(_newValue),
|
|
m_oldValue(_oldValue),
|
|
m_var(var)
|
|
{
|
|
}
|
|
|
|
void KoChangeVariableSubType::execute()
|
|
{
|
|
Q_ASSERT(m_var);
|
|
m_var->setVariableSubType(m_newValue);
|
|
m_var->recalcAndRepaint();
|
|
}
|
|
|
|
void KoChangeVariableSubType::unexecute()
|
|
{
|
|
Q_ASSERT(m_var);
|
|
m_var->setVariableSubType(m_oldValue);
|
|
m_var->recalcAndRepaint();
|
|
}
|
|
|
|
TQString KoChangeVariableSubType::name() const
|
|
{
|
|
return i18n( "Change Variable Subtype" );
|
|
}
|
|
|
|
////
|
|
|
|
KoChangeVariableFormatProperties::KoChangeVariableFormatProperties(
|
|
const TQString &_oldValue, const TQString &_newValue,
|
|
KoVariable *var)
|
|
: KCommand(),
|
|
m_newValue(_newValue),
|
|
m_oldValue(_oldValue),
|
|
m_var(var)
|
|
{
|
|
}
|
|
|
|
void KoChangeVariableFormatProperties::execute()
|
|
{
|
|
Q_ASSERT(m_var);
|
|
// Wrong! m_var->variableFormat()->setFormatProperties( m_newValue );
|
|
KoVariableFormatCollection* coll = m_var->variableColl()->formatCollection();
|
|
m_var->setVariableFormat( coll->format( m_var->variableFormat()->getKey( m_newValue ) ) );
|
|
m_var->recalcAndRepaint();
|
|
}
|
|
|
|
void KoChangeVariableFormatProperties::unexecute()
|
|
{
|
|
Q_ASSERT(m_var);
|
|
// Wrong! m_var->variableFormat()->setFormatProperties( m_oldValue );
|
|
KoVariableFormatCollection* coll = m_var->variableColl()->formatCollection();
|
|
m_var->setVariableFormat( coll->format( m_var->variableFormat()->getKey( m_oldValue ) ) );
|
|
m_var->recalcAndRepaint();
|
|
}
|
|
|
|
TQString KoChangeVariableFormatProperties::name() const
|
|
{
|
|
return i18n( "Change Variable Format" );
|
|
}
|