2016-03-19 06:57:51 +13:00
# include "tools/imagegrouping.h"
// TnzTools includes
# include "tools/strokeselection.h"
# include "tools/tool.h"
# include "tools/toolhandle.h"
# include "tools/toolutils.h"
# include "vectorselectiontool.h"
// TnzQt includes
# include "toonzqt/tselectionhandle.h"
# include "toonzqt/selectioncommandids.h"
// TnzLib includes
# include "toonz/tscenehandle.h"
# include "toonz/txshlevelhandle.h"
// TnzCore includes
# include "tvectorimage.h"
# include "tundo.h"
# include "tthreadmessage.h"
// Qt includes
# include <QMenu>
//=============================================================================
namespace
{
//-----------------------------------------------------------------------------
void groupWithoutUndo ( TVectorImage * vimg , StrokeSelection * selection )
{
int count = 0 , fromStroke = - 1 , lastSelected = - 1 ;
for ( int i = 0 ; i < ( int ) vimg - > getStrokeCount ( ) ; i + + )
if ( selection - > isSelected ( i ) ) {
if ( fromStroke = = - 1 )
fromStroke = i ;
else if ( lastSelected ! = i - 1 ) //non sono contigui gli stroke selezionati: faccio affiorare quelli sotto
{
int j = 0 ;
for ( j = 0 ; j < count ; j + + )
selection - > select ( fromStroke + j , false ) ;
vimg - > moveStrokes ( fromStroke , count , i ) ;
fromStroke = i - count ;
for ( j = 0 ; j < count ; j + + )
selection - > select ( fromStroke + j , true ) ;
}
lastSelected = i ;
count + + ;
}
assert ( count > 0 ) ;
vimg - > group ( fromStroke , count ) ;
TTool : : getApplication ( ) - > getCurrentTool ( ) - > getTool ( ) - > notifyImageChanged ( ) ;
}
//-----------------------------------------------------------------------------
void ungroupWithoutUndo ( TVectorImage * vimg , StrokeSelection * selection )
{
for ( int i = 0 ; i < ( int ) vimg - > getStrokeCount ( ) ; )
if ( selection - > isSelected ( i ) ) {
if ( ! vimg - > isStrokeGrouped ( i ) ) {
i + + ;
continue ;
}
i + = vimg - > ungroup ( i ) ;
} else
i + + ;
TTool : : getApplication ( ) - > getCurrentTool ( ) - > getTool ( ) - > notifyImageChanged ( ) ;
}
//=============================================================================
// GroupUndo
//-----------------------------------------------------------------------------
class GroupUndo : public ToolUtils : : TToolUndo
{
std : : auto_ptr < StrokeSelection > m_selection ;
public :
GroupUndo ( TXshSimpleLevel * level , const TFrameId & frameId , StrokeSelection * selection )
: ToolUtils : : TToolUndo ( level , frameId ) , m_selection ( selection ) { }
void undo ( ) const
{
TVectorImageP image = m_level - > getFrame ( m_frameId , true ) ;
if ( image )
ungroupWithoutUndo ( image . getPointer ( ) , m_selection . get ( ) ) ;
}
void redo ( ) const
{
TVectorImageP image = m_level - > getFrame ( m_frameId , true ) ;
if ( image )
groupWithoutUndo ( image . getPointer ( ) , m_selection . get ( ) ) ;
}
int getSize ( ) const
{
return sizeof ( * this ) ;
}
QString getToolName ( )
{
return QObject : : tr ( " Group " ) ;
}
} ;
//=============================================================================
// UngroupUndo
//-----------------------------------------------------------------------------
class UngroupUndo : public ToolUtils : : TToolUndo
{
std : : auto_ptr < StrokeSelection > m_selection ;
public :
UngroupUndo ( TXshSimpleLevel * level , const TFrameId & frameId , StrokeSelection * selection )
: ToolUtils : : TToolUndo ( level , frameId ) , m_selection ( selection ) { }
void undo ( ) const
{
TVectorImageP image = m_level - > getFrame ( m_frameId , true ) ;
if ( image )
groupWithoutUndo ( image . getPointer ( ) , m_selection . get ( ) ) ;
}
void redo ( ) const
{
TVectorImageP image = m_level - > getFrame ( m_frameId , true ) ;
if ( image )
ungroupWithoutUndo ( image . getPointer ( ) , m_selection . get ( ) ) ;
}
int getSize ( ) const
{
return sizeof ( * this ) ;
}
QString getToolName ( )
{
return QObject : : tr ( " Ungroup " ) ;
}
} ;
//=============================================================================
// MoveGroupUndo
//-----------------------------------------------------------------------------
class MoveGroupUndo : public ToolUtils : : TToolUndo
{
UCHAR m_moveType ;
int m_refStroke , m_count , m_moveBefore ;
2016-04-19 19:32:17 +12:00
std : : vector < std : : pair < TStroke * , int > > m_selectedGroups ;
2016-03-19 06:57:51 +13:00
public :
MoveGroupUndo ( TXshSimpleLevel * level , const TFrameId & frameId , UCHAR moveType ,
2016-04-19 19:32:17 +12:00
int refStroke , int count , int moveBefore , const std : : vector < std : : pair < TStroke * , int > > & selectedGroups )
2016-03-19 06:57:51 +13:00
: ToolUtils : : TToolUndo ( level , frameId ) , m_moveType ( moveType ) , m_refStroke ( refStroke ) , m_count ( count ) , m_moveBefore ( moveBefore ) , m_selectedGroups ( selectedGroups )
{
}
~ MoveGroupUndo ( )
{
}
void undo ( ) const
{
int refStroke ;
int moveBefore ;
switch ( m_moveType ) {
2016-05-13 22:49:17 +12:00
case TGroupCommand : : FRONT :
2016-03-19 06:57:51 +13:00
refStroke = m_moveBefore - m_count ;
moveBefore = m_refStroke ;
2016-05-13 22:49:17 +12:00
break ;
case TGroupCommand : : FORWARD :
refStroke = m_moveBefore - m_count ;
moveBefore = m_refStroke ;
break ;
case TGroupCommand : : BACK :
refStroke = m_moveBefore ;
moveBefore = m_refStroke + m_count ;
break ;
case TGroupCommand : : BACKWARD :
refStroke = m_moveBefore ;
moveBefore = m_refStroke + m_count ;
break ;
default :
2016-03-19 06:57:51 +13:00
assert ( ! " group move not defined! " ) ;
2016-05-13 22:49:17 +12:00
break ;
2016-03-19 06:57:51 +13:00
}
TVectorImageP image = m_level - > getFrame ( m_frameId , true ) ;
if ( ! image )
return ;
QMutexLocker lock ( image - > getMutex ( ) ) ;
image - > moveStrokes ( refStroke , m_count , moveBefore ) ;
StrokeSelection * selection = dynamic_cast < StrokeSelection * > ( TTool : : getApplication ( ) - > getCurrentSelection ( ) - > getSelection ( ) ) ;
if ( selection ) { //Se la selezione corrente e' la StrokeSelection
// seleziono gli stroke che ho modificato con l'undo
selection - > selectNone ( ) ;
for ( int i = 0 ; i < ( int ) m_selectedGroups . size ( ) ; i + + ) {
int index = image - > getStrokeIndex ( m_selectedGroups [ i ] . first ) ;
if ( index = = - 1 )
continue ;
for ( int j = index ; j < index + m_selectedGroups [ i ] . second ; j + + )
selection - > select ( j , true ) ;
}
}
TTool : : getApplication ( ) - > getCurrentScene ( ) - > notifySceneChanged ( ) ;
notifyImageChanged ( ) ;
}
void redo ( ) const
{
TVectorImageP image = m_level - > getFrame ( m_frameId , true ) ;
if ( ! image )
return ;
QMutexLocker lock ( image - > getMutex ( ) ) ;
image - > moveStrokes ( m_refStroke , m_count , m_moveBefore ) ;
StrokeSelection * selection = dynamic_cast < StrokeSelection * > ( TTool : : getApplication ( ) - > getCurrentSelection ( ) - > getSelection ( ) ) ;
if ( selection ) { //Se la selezione corrente e' la StrokeSelection
// seleziono gli stroke che ho modificato con il redo
selection - > selectNone ( ) ;
for ( int i = 0 ; i < ( int ) m_selectedGroups . size ( ) ; i + + ) {
int index = image - > getStrokeIndex ( m_selectedGroups [ i ] . first ) ;
if ( index = = - 1 )
continue ;
for ( int j = index ; j < index + m_selectedGroups [ i ] . second ; j + + )
selection - > select ( j , true ) ;
}
}
TTool : : getApplication ( ) - > getCurrentScene ( ) - > notifySceneChanged ( ) ;
notifyImageChanged ( ) ;
}
int getSize ( ) const
{
return sizeof ( * this ) ;
}
QString getToolName ( )
{
return QObject : : tr ( " Move Group " ) ;
}
} ;
//-----------------------------------------------------------------------------
} // namespace
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// TGroupCommand
//-----------------------------------------------------------------------------
namespace
{
2016-04-19 19:32:17 +12:00
std : : vector < std : : pair < TStroke * , int > > getSelectedGroups ( TVectorImage * vimg , StrokeSelection * sel )
2016-03-19 06:57:51 +13:00
{
UINT i , j ;
2016-04-19 19:32:17 +12:00
std : : vector < std : : pair < TStroke * , int > > ret ;
2016-03-19 06:57:51 +13:00
for ( i = 0 ; i < vimg - > getStrokeCount ( ) ; i + + )
if ( sel - > isSelected ( i ) ) {
if ( vimg - > isStrokeGrouped ( i ) ) {
for ( j = i + 1 ; j < vimg - > getStrokeCount ( ) & & vimg - > sameSubGroup ( i , j ) ; j + + )
if ( ! sel - > isSelected ( j ) )
2016-04-19 19:32:17 +12:00
return std : : vector < std : : pair < TStroke * , int > > ( ) ;
ret . push_back ( std : : pair < TStroke * , int > ( vimg - > getStroke ( i ) , j - i ) ) ;
2016-03-19 06:57:51 +13:00
i = j - 1 ;
} else
2016-04-19 19:32:17 +12:00
ret . push_back ( std : : pair < TStroke * , int > ( vimg - > getStroke ( i ) , 1 ) ) ;
2016-03-19 06:57:51 +13:00
}
return ret ;
}
} //namepsace
//--------------------------------------------------------------------------------------
UCHAR TGroupCommand : : getGroupingOptions ( )
{
TTool * tool = TTool : : getApplication ( ) - > getCurrentTool ( ) - > getTool ( ) ;
if ( ! tool )
return 0 ;
TVectorImage * vimg = dynamic_cast < TVectorImage * > ( tool - > getImage ( false ) ) ;
if ( ! vimg )
return 0 ;
UCHAR mask = 0 ;
int count = 0 ;
UINT i , j ;
//spostamento: si possono spostare solo gruppi interi oppure stroke non gruppate
2016-04-19 19:32:17 +12:00
std : : vector < std : : pair < TStroke * , int > > strokeIndexes = getSelectedGroups ( vimg , m_sel ) ;
2016-03-19 06:57:51 +13:00
/*
//spostamento: si puo' spostare solo un gruppo(e uno solo per volta) oppure una stroke singola non gruppata
for ( i = 0 ; i < vimg - > getStrokeCount ( ) ; i + + )
if ( m_sel - > isSelected ( i ) )
{
if ( strokeIndex ! = - 1 )
{
if ( ! vimg - > isStrokeGrouped ( i ) | | ! vimg - > sameSubGroup ( strokeIndex , i ) )
break ;
}
else
{
strokeIndex = i ;
if ( vimg - > isStrokeGrouped ( i ) )
{
for ( j = 0 ; j < vimg - > getStrokeCount ( ) ; j + + )
if ( ! m_sel - > isSelected ( j ) & & vimg - > sameSubGroup ( i , j ) )
break ; //non tutto il gruppo e' selezionato
if ( j < vimg - > getStrokeCount ( ) )
break ;
}
}
count + + ;
}
*/
if ( strokeIndexes . empty ( ) )
return 0 ; //no stroke selected
int strokeIndex = vimg - > getStrokeIndex ( strokeIndexes [ 0 ] . first ) ;
if ( strokeIndexes . size ( ) > 1 | | strokeIndex > 0 ) {
mask | = BACK ;
mask | = BACKWARD ;
}
if ( strokeIndexes . size ( ) > 1 | | strokeIndex + strokeIndexes [ 0 ] . second - 1 < ( int ) vimg - > getStrokeCount ( ) - 1 ) {
mask | = FRONT ;
mask | = FORWARD ;
}
/*
if ( i = = vimg - > getStrokeCount ( ) )
{
if ( strokeIndex + count < ( int ) vimg - > getStrokeCount ( ) )
{
mask | = FRONT ;
mask | = FORWARD ;
}
if ( strokeIndex > 0 )
{
mask | = BACK ;
mask | = BACKWARD ;
}
}
*/
//PER l'UNGROUP: si ungruppa solo se tutti gli stroke selezionati stanno nel gruppo (anche piu' gruppi insieme)
for ( i = 0 ; i < vimg - > getStrokeCount ( ) ; i + + ) {
if ( m_sel - > isSelected ( i ) ) {
if ( ! vimg - > isStrokeGrouped ( i ) )
break ;
for ( j = 0 ; j < vimg - > getStrokeCount ( ) ; j + + )
if ( ! m_sel - > isSelected ( j ) & & vimg - > sameSubGroup ( i , j ) )
break ;
if ( j < vimg - > getStrokeCount ( ) )
break ;
}
}
if ( i = = vimg - > getStrokeCount ( ) )
mask | = UNGROUP ;
//PER il GROUP: si raggruppa solo se:
// //almeno una delle stroke selezionate non fa parte di gruppi o e' di un gruppo diverso
// e se c'e' una stroke di un gruppo, allora tutto il gruppo della stroke e' selezionato
bool groupingMakesSense = false ;
int refStroke = - 1 ;
for ( i = 0 ; i < vimg - > getStrokeCount ( ) ; i + + )
if ( m_sel - > isSelected ( i ) ) {
if ( vimg - > isStrokeGrouped ( i ) ) {
if ( refStroke = = - 1 )
refStroke = i ;
else if ( ! vimg - > sameSubGroup ( refStroke , i ) )
groupingMakesSense = true ; //gli storke selezionati non sono gia' tutti dello stesso gruppo
for ( j = 0 ; j < vimg - > getStrokeCount ( ) ; j + + )
if ( ! m_sel - > isSelected ( j ) & & vimg - > sameGroup ( i , j ) )
return mask ;
} else
groupingMakesSense = true ;
}
if ( groupingMakesSense )
mask | = GROUP ;
return mask ;
}
//-----------------------------------------------------------------------------
# ifdef NUOVO
UCHAR TGroupCommand : : getGroupingOptions ( )
{
TTool * tool = TTool : : getApplication ( ) - > getCurrentTool ( ) - > getTool ( ) ;
if ( ! tool )
return 0 ;
TVectorImage * vimg = dynamic_cast < TVectorImage * > ( tool - > getImage ( false ) ) ;
if ( ! vimg )
return 0 ;
int strokeIndex = - 1 ;
UCHAR mask = 0 ;
int count = 0 ;
UINT i , j ;
bool valid = true ;
//spostamento: si puo' spostare solo un gruppo(e uno solo per volta) oppure una stroke singola non gruppata
2016-04-19 19:32:17 +12:00
std : : vector < pair < int , int > > groups ;
2016-03-19 06:57:51 +13:00
for ( i = 0 ; i < vimg - > getStrokeCount ( ) & & valid ; )
if ( m_sel - > isSelected ( i ) ) {
strokeIndex = i ;
count = 1 ;
if ( vimg - > isStrokeGrouped ( i ) ) {
for ( j = i + 1 ; j < vimg - > getStrokeCount ( ) & & valid ; j + + )
if ( m_sel - > isSelected ( j ) & & vimg - > sameSubGroup ( i , j ) )
count + + ;
else if ( ! m_sel - > isSelected ( j ) & & vimg - > sameSubGroup ( i , j ) )
valid = false ; //non tutto il gruppo e' selezionato
}
groups . push_back ( pair < int , int > ( strokeIndex , count ) ) ;
i = i + count ;
}
if ( groups . empty ( ) )
return 0 ; //no stroke selected
if ( ! valid )
return 0 ;
if ( strokeIndex + count < ( int ) vimg - > getStrokeCount ( ) ) {
mask | = FRONT ;
mask | = FORWARD ;
}
if ( strokeIndex > 0 ) {
mask | = BACK ;
mask | = BACKWARD ;
}
//PER l'UNGROUP: si ungruppa solo se tutti gli stroke selezionati stanno nel gruppo (anche piu' gruppi insieme)
for ( i = 0 ; i < vimg - > getStrokeCount ( ) ; i + + ) {
if ( m_sel - > isSelected ( i ) ) {
if ( ! vimg - > isStrokeGrouped ( i ) )
break ;
for ( j = 0 ; j < vimg - > getStrokeCount ( ) ; j + + )
if ( ! m_sel - > isSelected ( j ) & & vimg - > sameSubGroup ( i , j ) )
break ;
if ( j < vimg - > getStrokeCount ( ) )
break ;
}
}
if ( i = = vimg - > getStrokeCount ( ) )
mask | = UNGROUP ;
//PER il GROUP: si raggruppa solo se:
// //almeno una delle stroke selezionate non fa parte di gruppi o e' di un gruppo diverso
// e se c'e' una stroke di un gruppo, allora tutto il gruppo della stroke e' selezionato
bool groupingMakesSense = false ;
int refStroke = - 1 ;
for ( i = 0 ; i < vimg - > getStrokeCount ( ) ; i + + )
if ( m_sel - > isSelected ( i ) ) {
if ( vimg - > isStrokeGrouped ( i ) ) {
if ( refStroke = = - 1 )
refStroke = i ;
else if ( ! vimg - > sameSubGroup ( refStroke , i ) )
groupingMakesSense = true ; //gli storke selezionati non sono gia' tutti dello stesso gruppo
for ( j = 0 ; j < vimg - > getStrokeCount ( ) ; j + + )
if ( ! m_sel - > isSelected ( j ) & & vimg - > sameGroup ( i , j ) )
return mask ;
} else
groupingMakesSense = true ;
}
if ( groupingMakesSense )
mask | = GROUP ;
return mask ;
}
# endif
//-----------------------------------------------------------------------------
void TGroupCommand : : group ( )
{
if ( ! ( getGroupingOptions ( ) & GROUP ) )
return ;
TTool * tool = TTool : : getApplication ( ) - > getCurrentTool ( ) - > getTool ( ) ;
if ( ! tool )
return ;
TVectorImage * vimg = ( TVectorImage * ) tool - > getImage ( true ) ;
if ( ! vimg )
return ;
QMutexLocker lock ( vimg - > getMutex ( ) ) ;
groupWithoutUndo ( vimg , m_sel ) ;
TXshSimpleLevel * level = TTool : : getApplication ( ) - > getCurrentLevel ( ) - > getSimpleLevel ( ) ;
TUndoManager : : manager ( ) - > add ( new GroupUndo ( level , tool - > getCurrentFid ( ) , new StrokeSelection ( * m_sel ) ) ) ;
}
//-----------------------------------------------------------------------------
void TGroupCommand : : enterGroup ( )
{
TTool * tool = TTool : : getApplication ( ) - > getCurrentTool ( ) - > getTool ( ) ;
if ( ! tool )
return ;
TVectorImage * vimg = ( TVectorImage * ) tool - > getImage ( true ) ;
if ( ! vimg )
return ;
int index = - 1 ;
for ( int i = 0 ; i < ( int ) vimg - > getStrokeCount ( ) ; i + + )
if ( m_sel - > isSelected ( i ) ) {
index = i ;
break ;
}
if ( index = = - 1 )
return ;
if ( ! vimg - > canEnterGroup ( index ) )
return ;
vimg - > enterGroup ( index ) ;
TSelection * selection = TSelection : : getCurrent ( ) ;
if ( selection )
selection - > selectNone ( ) ;
TTool : : getApplication ( ) - > getCurrentScene ( ) - > notifySceneChanged ( ) ;
}
//-----------------------------------------------------------------------------
void TGroupCommand : : exitGroup ( )
{
TTool * tool = TTool : : getApplication ( ) - > getCurrentTool ( ) - > getTool ( ) ;
if ( ! tool )
return ;
TVectorImage * vimg = ( TVectorImage * ) tool - > getImage ( true ) ;
if ( ! vimg )
return ;
vimg - > exitGroup ( ) ;
TTool : : getApplication ( ) - > getCurrentScene ( ) - > notifySceneChanged ( ) ;
}
//-----------------------------------------------------------------------------
void TGroupCommand : : ungroup ( )
{
if ( ! ( getGroupingOptions ( ) & UNGROUP ) )
return ;
TTool * tool = TTool : : getApplication ( ) - > getCurrentTool ( ) - > getTool ( ) ;
if ( ! tool )
return ;
TVectorImage * vimg = ( TVectorImage * ) tool - > getImage ( true ) ;
if ( ! vimg )
return ;
QMutexLocker lock ( vimg - > getMutex ( ) ) ;
ungroupWithoutUndo ( vimg , m_sel ) ;
TXshSimpleLevel * level = TTool : : getApplication ( ) - > getCurrentLevel ( ) - > getSimpleLevel ( ) ;
TUndoManager : : manager ( ) - > add ( new UngroupUndo ( level , tool - > getCurrentFid ( ) , new StrokeSelection ( * m_sel ) ) ) ;
}
//-----------------------------------------------------------------------------
/*
void computeMovingBounds ( TVectorImage * vimg , int fromIndex , int toIndex , int & lower , int & upper )
{
lower = 0 ;
upper = vimg - > getStrokeCount ( ) ;
int refDepth = vimg - > getGroupDepth ( fromIndex ) - 1 ;
if ( refDepth = = 0 )
return ;
int i ;
for ( i = fromIndex - 1 ; i > = 0 ; i - - )
if ( vimg - > getCommonGroupDepth ( fromIndex , i ) < refDepth )
{
lower = i + 1 ;
break ;
}
for ( i = fromIndex + 1 ; i < vimg - > getStrokeCount ( ) ; i + + )
if ( vimg - > getCommonGroupDepth ( fromIndex , i ) < refDepth )
{
upper = i ;
break ;
}
}
*/
//-----------------------------------------------------------------------------
namespace
{
int commonDepth ( TVectorImage * vimg , int index1 , int count , int index2 )
{
int i , ret = 1000 ;
for ( i = index1 ; i < index1 + count ; i + + )
2016-05-18 16:03:37 +12:00
ret = std : : min ( ret , vimg - > getCommonGroupDepth ( i , index2 ) ) ;
2016-03-19 06:57:51 +13:00
return ret ;
}
//-----------------------------------------------------------------------------
/*
bool cantMove1 ( TVectorImage * vimg , int refStroke , int count , int moveBefore , bool rev )
{
if ( moveBefore < ( int ) vimg - > getStrokeCount ( ) & & moveBefore > 0 & &
vimg - > getCommonGroupDepth ( moveBefore - 1 , moveBefore ) > commonDepth ( vimg , refStroke , count , moveBefore ) & &
vimg - > getCommonGroupDepth ( moveBefore - 1 , moveBefore ) > commonDepth ( vimg , refStroke , count , moveBefore - 1 ) )
return true ;
int prev = ( rev ) ? moveBefore : moveBefore - 1 ;
if ( refStroke > 0 & & commonDepth ( vimg , refStroke , count , refStroke - 1 ) > commonDepth ( vimg , refStroke , count , prev ) )
return true ;
if ( refStroke + count < ( int ) vimg - > getStrokeCount ( ) & & commonDepth ( vimg , refStroke , count , refStroke + count ) > commonDepth ( vimg , refStroke , count , prev ) )
return true ;
return false ;
}
*/
} //namespace
//-----------------------------------------------------------------------------
/*
int i , refStroke = - 1 , count = 0 ;
for ( i = 0 ; i < ( int ) vimg - > getStrokeCount ( ) ; i + + )
if ( m_sel - > isSelected ( i ) )
{
assert ( refStroke = = - 1 | | i = = 0 | | m_sel - > isSelected ( i - 1 ) ) ;
if ( refStroke = = - 1 )
refStroke = i ;
count + + ;
}
if ( count = = 0 ) return ;
*/
2016-04-19 19:32:17 +12:00
int doMoveGroup ( UCHAR moveType , TVectorImage * vimg , const std : : vector < std : : pair < TStroke * , int > > & selectedGroups , int index )
2016-03-19 06:57:51 +13:00
{
int refStroke = vimg - > getStrokeIndex ( selectedGroups [ index ] . first ) ;
int count = selectedGroups [ index ] . second ;
int moveBefore ;
switch ( moveType ) {
case TGroupCommand : : FRONT :
moveBefore = vimg - > getStrokeCount ( ) ;
while ( moveBefore > = refStroke + count + 1 & & ! vimg - > canMoveStrokes ( refStroke , count , moveBefore ) )
moveBefore - - ;
if ( moveBefore = = refStroke + count )
return - 1 ;
2016-05-13 22:49:17 +12:00
break ;
case TGroupCommand : : FORWARD :
moveBefore = refStroke + count + 1 ;
2016-03-19 06:57:51 +13:00
while ( moveBefore < = ( int ) vimg - > getStrokeCount ( ) & & ! vimg - > canMoveStrokes ( refStroke , count , moveBefore ) )
moveBefore + + ;
if ( moveBefore = = vimg - > getStrokeCount ( ) + 1 )
return - 1 ;
2016-05-13 22:49:17 +12:00
break ;
case TGroupCommand : : BACK :
moveBefore = 0 ;
2016-03-19 06:57:51 +13:00
while ( moveBefore < = refStroke - 1 & & ! vimg - > canMoveStrokes ( refStroke , count , moveBefore ) )
moveBefore + + ;
if ( moveBefore = = refStroke )
return - 1 ;
2016-05-13 22:49:17 +12:00
break ;
case TGroupCommand : : BACKWARD :
moveBefore = refStroke - 1 ;
2016-03-19 06:57:51 +13:00
while ( moveBefore > = 0 & & ! vimg - > canMoveStrokes ( refStroke , count , moveBefore ) )
moveBefore - - ;
if ( moveBefore = = - 1 )
return - 1 ;
2016-05-13 22:49:17 +12:00
break ;
default :
2016-03-19 06:57:51 +13:00
assert ( false ) ;
}
vimg - > moveStrokes ( refStroke , count , moveBefore ) ;
TXshSimpleLevel * level = TTool : : getApplication ( ) - > getCurrentLevel ( ) - > getSimpleLevel ( ) ;
TTool * tool = TTool : : getApplication ( ) - > getCurrentTool ( ) - > getTool ( ) ;
TUndoManager : : manager ( ) - > add ( new MoveGroupUndo ( level , tool - > getCurrentFid ( ) , moveType ,
refStroke , count , moveBefore , selectedGroups ) ) ;
return moveBefore ;
}
//-----------------------------------------------------------------------------
void TGroupCommand : : moveGroup ( UCHAR moveType )
{
TTool * tool = TTool : : getApplication ( ) - > getCurrentTool ( ) - > getTool ( ) ;
if ( ! tool )
return ;
TVectorImage * vimg = ( TVectorImage * ) tool - > getImage ( true ) ;
if ( ! vimg )
return ;
2016-04-19 19:32:17 +12:00
std : : vector < std : : pair < TStroke * , int > > selectedGroups = getSelectedGroups ( vimg , m_sel ) ;
2016-03-19 06:57:51 +13:00
if ( selectedGroups . empty ( ) )
return ;
int i , j ;
TUndoManager : : manager ( ) - > beginBlock ( ) ;
switch ( moveType ) {
case TGroupCommand : : FRONT :
2016-05-13 22:49:17 +12:00
case TGroupCommand : : BACKWARD :
i = 0 ;
2016-03-19 06:57:51 +13:00
if ( moveType = = TGroupCommand : : BACKWARD & & vimg - > getStrokeIndex ( selectedGroups [ i ] . first ) = = 0 ) //tutti i gruppi adiacenti gia in fondo non possono essere backwardati
{
i + + ;
while ( i < ( int ) selectedGroups . size ( ) & &
vimg - > getStrokeIndex ( selectedGroups [ i - 1 ] . first ) + selectedGroups [ i - 1 ] . second - 1 = = vimg - > getStrokeIndex ( selectedGroups [ i ] . first ) - 1 )
i + + ;
}
for ( ; i < = ( int ) selectedGroups . size ( ) - 1 ; i + + )
doMoveGroup ( moveType , vimg , selectedGroups , i ) ; //vimg->getStrokeIndex(selectedGroups[i].first), selectedGroups[i].second);
2016-05-13 22:49:17 +12:00
break ;
case TGroupCommand : : BACK :
case TGroupCommand : : FORWARD :
i = selectedGroups . size ( ) - 1 ;
2016-03-19 06:57:51 +13:00
if ( moveType = = TGroupCommand : : FORWARD & & vimg - > getStrokeIndex ( selectedGroups [ i ] . first ) + selectedGroups [ i ] . second - 1 = = vimg - > getStrokeCount ( ) - 1 ) //tutti i gruppi adiacenti gia in cime non possono essere forwardati
{
i - - ;
while ( i > = 0 & &
vimg - > getStrokeIndex ( selectedGroups [ i + 1 ] . first ) - 1 = = vimg - > getStrokeIndex ( selectedGroups [ i ] . first ) + selectedGroups [ i ] . second - 1 )
i - - ;
}
for ( ; i > = 0 ; i - - )
doMoveGroup ( moveType , vimg , selectedGroups , i ) ;
2016-05-13 22:49:17 +12:00
break ;
default :
2016-03-19 06:57:51 +13:00
assert ( false ) ;
}
TUndoManager : : manager ( ) - > endBlock ( ) ;
m_sel - > selectNone ( ) ;
for ( i = 0 ; i < ( int ) selectedGroups . size ( ) ; i + + ) {
int index = vimg - > getStrokeIndex ( selectedGroups [ i ] . first ) ;
for ( j = index ; j < index + selectedGroups [ i ] . second ; j + + )
m_sel - > select ( j , true ) ;
}
tool - > notifyImageChanged ( ) ;
}
//-----------------------------------------------------------------------------
void TGroupCommand : : addMenuItems ( QMenu * menu )
{
UCHAR optionMask = getGroupingOptions ( ) ;
if ( optionMask = = 0 )
return ;
CommandManager * cm = CommandManager : : instance ( ) ;
if ( optionMask & TGroupCommand : : GROUP )
menu - > addAction ( cm - > getAction ( MI_Group ) ) ;
if ( optionMask & TGroupCommand : : UNGROUP )
menu - > addAction ( cm - > getAction ( MI_Ungroup ) ) ;
if ( optionMask & ( TGroupCommand : : GROUP | TGroupCommand : : UNGROUP ) & &
optionMask & ( TGroupCommand : : FORWARD | TGroupCommand : : BACKWARD ) )
menu - > addSeparator ( ) ;
if ( optionMask & TGroupCommand : : FORWARD ) {
menu - > addAction ( cm - > getAction ( MI_BringToFront ) ) ;
menu - > addAction ( cm - > getAction ( MI_BringForward ) ) ;
}
if ( optionMask & TGroupCommand : : BACKWARD ) {
menu - > addAction ( cm - > getAction ( MI_SendBack ) ) ;
menu - > addAction ( cm - > getAction ( MI_SendBackward ) ) ;
}
menu - > addSeparator ( ) ;
}