Skip to content

Commit

Permalink
[FEATURE]: Copy paste for composer item. Provided by Anna Kratochvilo…
Browse files Browse the repository at this point in the history
…va in ticket #4070
  • Loading branch information
marco committed Nov 29, 2011
1 parent 66e2ab0 commit 376d45b
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 27 deletions.
200 changes: 173 additions & 27 deletions src/gui/qgscomposerview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
* *
***************************************************************************/

#include <QApplication>
#include <QMainWindow>
#include <QMouseEvent>
#include <QKeyEvent>
#include <QClipboard>
#include <QMimeData>

#include "qgscomposerview.h"
#include "qgscomposerarrow.h"
Expand Down Expand Up @@ -394,40 +397,56 @@ void QgsComposerView::keyPressEvent( QKeyEvent * e )
QList<QgsComposerItem*> composerItemList = composition()->selectedComposerItems();
QList<QgsComposerItem*>::iterator itemIt = composerItemList.begin();

//delete selected items
if ( e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace )
if ( e->matches( QKeySequence::Copy ) || e->matches( QKeySequence::Cut ) )
{
QDomDocument doc;
QDomElement documentElement = doc.createElement( "ComposerItemClipboard" );
for ( ; itemIt != composerItemList.end(); ++itemIt )
{
QgsComposerMap* map = dynamic_cast<QgsComposerMap *>( *itemIt );
if ( !map || !map->isDrawing() ) //don't delete a composer map while it draws
// copy each item in a group
QgsComposerItemGroup* itemGroup = dynamic_cast<QgsComposerItemGroup*>( *itemIt );
if ( itemGroup && composition() )
{
composition()->removeItem( *itemIt );
QgsComposerItemGroup* itemGroup = dynamic_cast<QgsComposerItemGroup*>( *itemIt );
if ( itemGroup && composition() )
{
//add add/remove item command for every item in the group
QUndoCommand* parentCommand = new QUndoCommand( tr( "Remove item group" ) );

QSet<QgsComposerItem*> groupedItems = itemGroup->items();
QSet<QgsComposerItem*>::iterator it = groupedItems.begin();
for ( ; it != groupedItems.end(); ++it )
{
QgsAddRemoveItemCommand* subcommand = new QgsAddRemoveItemCommand( QgsAddRemoveItemCommand::Removed, *it, composition(), "", parentCommand );
connectAddRemoveCommandSignals( subcommand );
emit itemRemoved( *it );
}

composition()->undoStack()->push( parentCommand );
delete itemGroup;
emit itemRemoved( itemGroup );
}
else
QSet<QgsComposerItem*> groupedItems = itemGroup->items();
QSet<QgsComposerItem*>::iterator it = groupedItems.begin();
for ( ; it != groupedItems.end(); ++it )
{
emit itemRemoved( *itemIt );
pushAddRemoveCommand( *itemIt, tr( "Item deleted" ), QgsAddRemoveItemCommand::Removed );
( *it )->writeXML( documentElement, doc );
}
}
( *itemIt )->writeXML( documentElement, doc );
if ( e->matches( QKeySequence::Cut ) )
{
removeItem( *itemIt );
}
}
doc.appendChild( documentElement );
QMimeData *mimeData = new QMimeData;
mimeData->setData( "text/xml", doc.toByteArray() );
QClipboard *clipboard = QApplication::clipboard();
clipboard->setMimeData( mimeData );
}

if ( e->matches( QKeySequence::Paste ) )
{
QDomDocument doc;
QClipboard *clipboard = QApplication::clipboard();
if ( doc.setContent( clipboard->mimeData()->data( "text/xml" ) ) )
{
QDomElement docElem = doc.documentElement();
if ( docElem.tagName() == "ComposerItemClipboard" )
{
addItemsfromXML( docElem, doc );
}
}
}

//delete selected items
if ( e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace )
{
for ( ; itemIt != composerItemList.end(); ++itemIt )
{
removeItem( *itemIt );
}
}

Expand Down Expand Up @@ -626,6 +645,133 @@ void QgsComposerView::addComposerTable( QgsComposerAttributeTable* table )
pushAddRemoveCommand( table, tr( "Table added" ) );
}

void QgsComposerView::removeItem( QgsComposerItem* item )
{
QgsComposerMap* map = dynamic_cast<QgsComposerMap *>( item );
if ( !map || !map->isDrawing() ) //don't delete a composer map while it draws
{
composition()->removeItem( item );
QgsComposerItemGroup* itemGroup = dynamic_cast<QgsComposerItemGroup*>( item );
if ( itemGroup && composition() )
{
//add add/remove item command for every item in the group
QUndoCommand* parentCommand = new QUndoCommand( tr( "Remove item group" ) );

QSet<QgsComposerItem*> groupedItems = itemGroup->items();
QSet<QgsComposerItem*>::iterator it = groupedItems.begin();
for ( ; it != groupedItems.end(); ++it )
{
QgsAddRemoveItemCommand* subcommand = new QgsAddRemoveItemCommand( QgsAddRemoveItemCommand::Removed, *it, composition(), "", parentCommand );
connectAddRemoveCommandSignals( subcommand );
emit itemRemoved( *it );
}

composition()->undoStack()->push( parentCommand );
delete itemGroup;
emit itemRemoved( itemGroup );
}
else
{
emit itemRemoved( item );
pushAddRemoveCommand( item, tr( "Item deleted" ), QgsAddRemoveItemCommand::Removed );
}
}
}

void QgsComposerView::addItemsfromXML( const QDomElement& docElem, const QDomDocument& doc )
{
QPointF scenePoint = mapToScene( mapFromGlobal( QCursor::pos() ) );

// label
QDomNodeList composerLabelList = docElem.elementsByTagName( "ComposerLabel" );
for ( int i = 0; i < composerLabelList.size(); ++i )
{
QDomElement currentComposerLabelElem = composerLabelList.at( i ).toElement();
QgsComposerLabel* newLabel = new QgsComposerLabel( composition() );
newLabel->readXML( currentComposerLabelElem, doc );
newLabel->setItemPosition( scenePoint.x(), scenePoint.y() );
addComposerLabel( newLabel );
emit actionFinished();
}
// map
QDomNodeList composerMapList = docElem.elementsByTagName( "ComposerMap" );
for ( int i = 0; i < composerMapList.size(); ++i )
{
QDomElement currentComposerMapElem = composerMapList.at( i ).toElement();
QgsComposerMap* newMap = new QgsComposerMap( composition() );
newMap->readXML( currentComposerMapElem, doc );
newMap->setItemPosition( scenePoint.x(), scenePoint.y() );
addComposerMap( newMap );
emit actionFinished();
}
// arrow
QDomNodeList composerArrowList = docElem.elementsByTagName( "ComposerArrow" );
for ( int i = 0; i < composerArrowList.size(); ++i )
{
QDomElement currentComposerArrowElem = composerArrowList.at( i ).toElement();
QgsComposerArrow* newArrow = new QgsComposerArrow( composition() );
newArrow->readXML( currentComposerArrowElem, doc );
newArrow->setItemPosition( scenePoint.x(), scenePoint.y() );
addComposerArrow( newArrow );
emit actionFinished();
}
// scalebar
QDomNodeList composerScaleBarList = docElem.elementsByTagName( "ComposerScaleBar" );
for ( int i = 0; i < composerScaleBarList.size(); ++i )
{
QDomElement currentComposerScaleBarElem = composerScaleBarList.at( i ).toElement();
QgsComposerScaleBar* newScaleBar = new QgsComposerScaleBar( composition() );
newScaleBar->readXML( currentComposerScaleBarElem, doc );
newScaleBar->setItemPosition( scenePoint.x(), scenePoint.y() );
addComposerScaleBar( newScaleBar );
emit actionFinished();
}
// shape
QDomNodeList composerShapeList = docElem.elementsByTagName( "ComposerShape" );
for ( int i = 0; i < composerShapeList.size(); ++i )
{
QDomElement currentComposerShapeElem = composerShapeList.at( i ).toElement();
QgsComposerShape* newShape = new QgsComposerShape( composition() );
newShape->readXML( currentComposerShapeElem, doc );
newShape->setItemPosition( scenePoint.x(), scenePoint.y() );
addComposerShape( newShape );
emit actionFinished();
}
// picture
QDomNodeList composerPictureList = docElem.elementsByTagName( "ComposerPicture" );
for ( int i = 0; i < composerPictureList.size(); ++i )
{
QDomElement currentComposerPictureElem = composerPictureList.at( i ).toElement();
QgsComposerPicture* newPicture = new QgsComposerPicture( composition() );
newPicture->readXML( currentComposerPictureElem, doc );
newPicture->setItemPosition( scenePoint.x(), scenePoint.y() );
addComposerPicture( newPicture );
emit actionFinished();
}
// legend
QDomNodeList composerLegendList = docElem.elementsByTagName( "ComposerLegend" );
for ( int i = 0; i < composerLegendList.size(); ++i )
{
QDomElement currentComposerLegendElem = composerLegendList.at( i ).toElement();
QgsComposerLegend* newLegend = new QgsComposerLegend( composition() );
newLegend->readXML( currentComposerLegendElem, doc );
newLegend->setItemPosition( scenePoint.x(), scenePoint.y() );
addComposerLegend( newLegend );
emit actionFinished();
}
// table
QDomNodeList composerTableList = docElem.elementsByTagName( "ComposerAttributeTable" );
for ( int i = 0; i < composerTableList.size(); ++i )
{
QDomElement currentComposerTableElem = composerTableList.at( i ).toElement();
QgsComposerAttributeTable* newTable = new QgsComposerAttributeTable( composition() );
newTable->readXML( currentComposerTableElem, doc );
newTable->setItemPosition( scenePoint.x(), scenePoint.y() );
addComposerTable( newTable );
emit actionFinished();
}
}

void QgsComposerView::groupItems()
{
if ( !composition() )
Expand Down
8 changes: 8 additions & 0 deletions src/gui/qgscomposerview.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <QGraphicsView>
#include "qgsaddremoveitemcommand.h"

class QDomDocument;
class QDomElement;
class QKeyEvent;
class QMainWindow;
class QMouseEvent;
Expand Down Expand Up @@ -95,6 +97,12 @@ class GUI_EXPORT QgsComposerView: public QGraphicsView
/**Adds a composer table to the graphics scene and advices composer to create a widget for it (through signal)*/
void addComposerTable( QgsComposerAttributeTable* table );

/**Remove item from the graphics scene*/
void removeItem( QgsComposerItem* item );

/**Add items from XML representation to the graphics scene (for pasting items from clipboard)*/
void addItemsfromXML( const QDomElement& docElem, const QDomDocument& doc );

/**Returns the composer main window*/
QMainWindow* composerWindow();

Expand Down

0 comments on commit 376d45b

Please sign in to comment.