75 changes: 74 additions & 1 deletion src/core/composer/qgscomposerscalebar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
#include <QPainter>
#include <cmath>

QgsComposerScaleBar::QgsComposerScaleBar( QgsComposition* composition ): QgsComposerItem( composition ), mComposerMap( 0 ), mStyle( 0 ), mSegmentMillimeters( 0.0 )
QgsComposerScaleBar::QgsComposerScaleBar( QgsComposition* composition ): QgsComposerItem( composition ), mComposerMap( 0 ), mStyle( 0 ),
mSegmentMillimeters( 0.0 ), mAlignment( Left )
{
applyDefaultSettings();
applyDefaultSize();
Expand Down Expand Up @@ -65,10 +66,57 @@ void QgsComposerScaleBar::paint( QPainter* painter, const QStyleOptionGraphicsIt
}
}

void QgsComposerScaleBar::setNumSegments( int nSegments )
{
if ( !mStyle )
{
mNumSegments = nSegments;
return;
}
double width = mStyle->calculateBoxSize().width();
mNumSegments = nSegments;
double widthAfter = mStyle->calculateBoxSize().width();
correctXPositionAlignment( width, widthAfter );
}

void QgsComposerScaleBar::setNumUnitsPerSegment( double units )
{
if ( !mStyle )
{
mNumUnitsPerSegment = units;
return;
}
double width = mStyle->calculateBoxSize().width();
mNumUnitsPerSegment = units;
refreshSegmentMillimeters();
double widthAfter = mStyle->calculateBoxSize().width();
correctXPositionAlignment( width, widthAfter );
}

void QgsComposerScaleBar::setNumSegmentsLeft( int nSegmentsLeft )
{
if ( !mStyle )
{
mNumSegmentsLeft = nSegmentsLeft;
return;
}
double width = mStyle->calculateBoxSize().width();
mNumSegmentsLeft = nSegmentsLeft;
double widthAfter = mStyle->calculateBoxSize().width();
correctXPositionAlignment( width, widthAfter );
}

void QgsComposerScaleBar::setBoxContentSpace( double space )
{
if ( !mStyle )
{
mBoxContentSpace = space;
return;
}
double width = mStyle->calculateBoxSize().width();
mBoxContentSpace = space;
double widthAfter = mStyle->calculateBoxSize().width();
correctXPositionAlignment( width, widthAfter );
}

void QgsComposerScaleBar::setComposerMap( const QgsComposerMap* map )
Expand Down Expand Up @@ -172,7 +220,14 @@ void QgsComposerScaleBar::update()

void QgsComposerScaleBar::updateSegmentSize()
{
if ( !mStyle )
{
return;
}
double width = mStyle->calculateBoxSize().width();
refreshSegmentMillimeters();
double widthAfter = mStyle->calculateBoxSize().width();
correctXPositionAlignment( width, widthAfter );
update();
}

Expand Down Expand Up @@ -309,6 +364,9 @@ bool QgsComposerScaleBar::writeXML( QDomElement& elem, QDomDocument & doc ) cons
colorElem.setAttribute( "blue", brushColor.blue() );
composerScaleBarElem.appendChild( colorElem );

//alignment
composerScaleBarElem.setAttribute( "alignment", QString::number(( int ) mAlignment ) );

elem.appendChild( composerScaleBarElem );
return _writeXML( composerScaleBarElem, doc );
}
Expand Down Expand Up @@ -357,6 +415,9 @@ bool QgsComposerScaleBar::readXML( const QDomElement& itemElem, const QDomDocume

refreshSegmentMillimeters();

//alignment
mAlignment = ( Alignment )( itemElem.attribute( "alignment", "0" ).toInt() );

//restore general composer item properties
QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
if ( composerItemList.size() > 0 )
Expand All @@ -368,4 +429,16 @@ bool QgsComposerScaleBar::readXML( const QDomElement& itemElem, const QDomDocume
return true;
}

void QgsComposerScaleBar::correctXPositionAlignment( double width, double widthAfter )
{
if ( mAlignment == Middle )
{
move( -( widthAfter - width ) / 2.0, 0 );
}
else if ( mAlignment == Right )
{
move( -( widthAfter - width ), 0 );
}
}


26 changes: 23 additions & 3 deletions src/core/composer/qgscomposerscalebar.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem

public:

/**Added in version 1.8*/
enum Alignment
{
Left = 0,
Middle,
Right
};

QgsComposerScaleBar( QgsComposition* composition );
~QgsComposerScaleBar();

Expand All @@ -43,10 +51,10 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem

//getters and setters
int numSegments() const {return mNumSegments;}
void setNumSegments( int nSegments ) {mNumSegments = nSegments;}
void setNumSegments( int nSegments );

int numSegmentsLeft() const {return mNumSegmentsLeft;}
void setNumSegmentsLeft( int nSegmentsLeft ) {mNumSegmentsLeft = nSegmentsLeft;}
void setNumSegmentsLeft( int nSegmentsLeft );

double numUnitsPerSegment() const {return mNumUnitsPerSegment;}
void setNumUnitsPerSegment( double units );
Expand Down Expand Up @@ -77,10 +85,17 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem
void setLabelBarSpace( double space ) {mLabelBarSpace = space;}

double boxContentSpace() const {return mBoxContentSpace;}
void setBoxContentSpace( double space ) {mBoxContentSpace = space;}
void setBoxContentSpace( double space );

double segmentMillimeters() const {return mSegmentMillimeters;}

/**Left / Middle/ Right
@note: this method was added in version 1.8*/
Alignment alignment() const { return mAlignment; }

/**@note: this method was added in version 1.8*/
void setAlignment( Alignment a ) { mAlignment = a; }

/**Apply default settings*/
void applyDefaultSettings();
/**Apply default size (scale bar 1/5 of map item width)
Expand Down Expand Up @@ -119,6 +134,9 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem
*/
bool readXML( const QDomElement& itemElem, const QDomDocument& doc );

/**Moves scalebar position to the left / right depending on alignment and change in item width*/
void correctXPositionAlignment( double width, double widthAfter );

public slots:
void updateSegmentSize();
/**Sets mCompositionMap to 0 if the map is deleted*/
Expand Down Expand Up @@ -159,6 +177,8 @@ class CORE_EXPORT QgsComposerScaleBar: public QgsComposerItem
/**Width of a segment (in mm)*/
double mSegmentMillimeters;

Alignment mAlignment;

/**Calculates with of a segment in mm and stores it in mSegmentMillimeters*/
void refreshSegmentMillimeters();
};
Expand Down
18 changes: 14 additions & 4 deletions src/core/composer/qgsnumericscalebarstyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
#include <QList>
#include <QPainter>

QgsNumericScaleBarStyle::QgsNumericScaleBarStyle( QgsComposerScaleBar* bar ): QgsScaleBarStyle( bar )
QgsNumericScaleBarStyle::QgsNumericScaleBarStyle( QgsComposerScaleBar* bar ): QgsScaleBarStyle( bar ), mLastScaleBarWidth( 0 )
{

}

QgsNumericScaleBarStyle::QgsNumericScaleBarStyle(): QgsScaleBarStyle( 0 )
QgsNumericScaleBarStyle::QgsNumericScaleBarStyle(): QgsScaleBarStyle( 0 ), mLastScaleBarWidth( 0 )
{

}
Expand Down Expand Up @@ -67,9 +67,17 @@ QRectF QgsNumericScaleBarStyle::calculateBoxSize() const
double textWidth = mScaleBar->textWidthMillimeters( mScaleBar->font(), scaleText() );
double textHeight = mScaleBar->fontAscentMillimeters( mScaleBar->font() );

return QRectF( mScaleBar->transform().dx(), mScaleBar->transform().dy(), 2 * mScaleBar->boxContentSpace()
rect = QRectF( mScaleBar->transform().dx(), mScaleBar->transform().dy(), 2 * mScaleBar->boxContentSpace()
+ 2 * mScaleBar->pen().width() + textWidth,
textHeight + 2 * mScaleBar->boxContentSpace() );

if ( mLastScaleBarWidth != rect.width() && mLastScaleBarWidth > 0 && rect.width() > 0 )
{
//hack to move scale bar the the left / right in order to keep the bar alignment
const_cast<QgsComposerScaleBar*>( mScaleBar )->correctXPositionAlignment( mLastScaleBarWidth, rect.width() );
}
mLastScaleBarWidth = rect.width();
return rect;
}

QString QgsNumericScaleBarStyle::scaleText() const
Expand All @@ -78,12 +86,14 @@ QString QgsNumericScaleBarStyle::scaleText() const
if ( mScaleBar )
{
//find out scale
double scaleDenominator = 1;
const QgsComposerMap* composerMap = mScaleBar->composerMap();
if ( composerMap )
{
double scaleDenominator = composerMap->scale();
scaleDenominator = composerMap->scale();
scaleBarText = "1:" + QString::number( scaleDenominator, 'f', 0 );
}
scaleBarText = "1:" + QString::number( scaleDenominator, 'f', 0 );
}
return scaleBarText;
}
3 changes: 3 additions & 0 deletions src/core/composer/qgsnumericscalebarstyle.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class CORE_EXPORT QgsNumericScaleBarStyle: public QgsScaleBarStyle
QgsNumericScaleBarStyle(); //forbidden
/**Returns the text for the scale bar or an empty string in case of error*/
QString scaleText() const;

/**Store last width (in mm) to keep alignement to left/middle/right side*/
mutable double mLastScaleBarWidth;
};

#endif
31 changes: 29 additions & 2 deletions src/core/qgsdatasourceuri.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,20 @@
#include <QStringList>
#include <QRegExp>

QgsDataSourceURI::QgsDataSourceURI() : mSSLmode( SSLprefer ), mKeyColumn( "" ), mUseEstimatedMetadata( false )
QgsDataSourceURI::QgsDataSourceURI()
: mSSLmode( SSLprefer )
, mKeyColumn( "" )
, mUseEstimatedMetadata( false )
, mSelectAtIdDisabled( false )
{
// do nothing
}

QgsDataSourceURI::QgsDataSourceURI( QString uri ) : mSSLmode( SSLprefer ), mKeyColumn( "" ), mUseEstimatedMetadata( false )
QgsDataSourceURI::QgsDataSourceURI( QString uri )
: mSSLmode( SSLprefer )
, mKeyColumn( "" )
, mUseEstimatedMetadata( false )
, mSelectAtIdDisabled( false )
{
int i = 0;
while ( i < uri.length() )
Expand Down Expand Up @@ -115,6 +123,10 @@ QgsDataSourceURI::QgsDataSourceURI( QString uri ) : mSSLmode( SSLprefer ), mKeyC
{
mUseEstimatedMetadata = pval == "true";
}
else if ( pname == "selectatid" )
{
mSelectAtIdDisabled = pval == "false";
}
else if ( pname == "service" )
{
mService = pval;
Expand Down Expand Up @@ -309,6 +321,16 @@ bool QgsDataSourceURI::useEstimatedMetadata() const
return mUseEstimatedMetadata;
}

void QgsDataSourceURI::disableSelectAtId( bool theFlag )
{
mSelectAtIdDisabled = theFlag;
}

bool QgsDataSourceURI::selectAtIdDisabled() const
{
return mSelectAtIdDisabled;
}

void QgsDataSourceURI::setSql( QString sql )
{
mSql = sql;
Expand Down Expand Up @@ -461,6 +483,11 @@ QString QgsDataSourceURI::uri() const
theUri += QString( " estimatedmetadata=true" );
}

if ( mSelectAtIdDisabled )
{
theUri += QString( " selectatid=false" );
}

theUri += QString( " table=%1%2 sql=%3" )
.arg( quotedTablename() )
.arg( mGeometryColumn.isNull() ? QString() : QString( " (%1)" ).arg( mGeometryColumn ) )
Expand Down
5 changes: 5 additions & 0 deletions src/core/qgsdatasourceuri.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ class CORE_EXPORT QgsDataSourceURI
void setUseEstimatedMetadata( bool theFlag );
bool useEstimatedMetadata() const;

void disableSelectAtId( bool theFlag );
bool selectAtIdDisabled() const;

void clearSchema();
void setSql( QString sql );

Expand Down Expand Up @@ -147,6 +150,8 @@ class CORE_EXPORT QgsDataSourceURI
QString mKeyColumn;
//Use estimated metadata flag
bool mUseEstimatedMetadata;
//Disable SelectAtId capability (eg. to trigger the attribute table memory model for expensive views)
bool mSelectAtIdDisabled;
};

#endif //QGSDATASOURCEURI_H
Expand Down
12 changes: 12 additions & 0 deletions src/core/qgsdbtablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ QgsDbTableModel::QgsDbTableModel(): QStandardItemModel(), mTableCount( 0 )
headerLabels << tr( "Type" );
headerLabels << tr( "Geometry column" );
headerLabels << tr( "Primary key column" );
headerLabels << tr( "Select at id" );
headerLabels << tr( "Sql" );
setHorizontalHeaderLabels( headerLabels );
}
Expand Down Expand Up @@ -60,17 +61,27 @@ void QgsDbTableModel::addTableEntry( QString type, QString schemaName, QString t
QIcon iconFile = iconForType( wkbType );

QList<QStandardItem*> childItemList;

QStandardItem* schemaNameItem = new QStandardItem( schemaName );
schemaNameItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );

QStandardItem* typeItem = new QStandardItem( QIcon( iconFile ), type );
typeItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );

QStandardItem* tableItem = new QStandardItem( tableName );
tableItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );

QStandardItem* geomItem = new QStandardItem( geometryColName );
geomItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );

QStandardItem* pkItem = new QStandardItem( "" );
pkItem->setData( pkCols );
pkItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );

QStandardItem* selItem = new QStandardItem( "" );
selItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable );
selItem->setCheckState( Qt::Checked );

QStandardItem* sqlItem = new QStandardItem( sql );
sqlItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );

Expand All @@ -79,6 +90,7 @@ void QgsDbTableModel::addTableEntry( QString type, QString schemaName, QString t
childItemList.push_back( typeItem );
childItemList.push_back( geomItem );
childItemList.push_back( pkItem );
childItemList.push_back( selItem );
childItemList.push_back( sqlItem );

schemaItem->appendRow( childItemList );
Expand Down
8 changes: 7 additions & 1 deletion src/core/qgsdbtablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,19 @@ class CORE_EXPORT QgsDbTableModel : public QStandardItemModel
public:
QgsDbTableModel();
~QgsDbTableModel();

/**Adds entry for one database table to the model*/
void addTableEntry( QString type, QString schemaName, QString tableName, QString geometryColName, const QStringList &pkCols, QString Sql );

/**Sets an sql statement that belongs to a cell specified by a model index*/
void setSql( const QModelIndex& index, const QString& sql );

/**Sets one or more geometry types to a row. In case of several types, additional rows are inserted.
This is for tables where the type is dectected later by thread*/
void setGeometryTypesForTable( const QString& schema, const QString& table, const QString& attribute, const QString& type );

/**Returns the number of tables in the model*/
int tableCount() const {return mTableCount;}
int tableCount() const { return mTableCount; }

enum columns
{
Expand All @@ -45,6 +49,7 @@ class CORE_EXPORT QgsDbTableModel : public QStandardItemModel
dbtmType,
dbtmGeomCol,
dbtmPkCol,
dbtmSelectAtId,
dbtmSql,
dbtmColumns
};
Expand All @@ -55,6 +60,7 @@ class CORE_EXPORT QgsDbTableModel : public QStandardItemModel

QIcon iconForType( QGis::WkbType type ) const;
QString displayStringForType( QGis::WkbType type ) const;

/**Returns qgis wkbtype from database typename*/
QGis::WkbType qgisTypeFromDbType( const QString& dbType ) const;
};
Expand Down
57 changes: 43 additions & 14 deletions src/gui/attributetable/qgsattributetablememorymodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,59 @@
// In-Memory model //
/////////////////////

QgsAttributeTableMemoryModel::QgsAttributeTableMemoryModel( QgsVectorLayer *theLayer )
: QgsAttributeTableModel( theLayer )
{
QgsDebugMsg( "entered." );
}

void QgsAttributeTableMemoryModel::loadLayer()
{
QgsAttributeTableModel::loadLayer();
mLayer->select( mLayer->pendingAllAttributesList(), QgsRectangle(), false );
QgsDebugMsg( "entered." );

QSettings settings;
int behaviour = settings.value( "/qgis/attributeTableBehaviour", 0 ).toInt();

QgsRectangle rect;
if ( behaviour == 2 )
{
// current canvas only
rect = mCurrentExtent;
}

mLayer->select( mLayer->pendingAllAttributesList(), rect, false );

mFeatureMap.reserve( mLayer->pendingFeatureCount() + 50 );
if( behaviour != 1 )
mFeatureMap.reserve( mLayer->pendingFeatureCount() + 50 );
else
mFeatureMap.reserve( mLayer->selectedFeatureCount() );

int n = 0;

QgsFeature f;
while ( mLayer->nextFeature( f ) )
{
if( behaviour == 1 && !mLayer->selectedFeaturesIds().contains( f.id() ) )
continue;

mIdRowMap.insert( f.id(), n );
mRowIdMap.insert( n, f.id() );
mFeatureMap.insert( f.id(), f );
n++;
}

mFieldCount = mAttributes.size();
}

QgsAttributeTableMemoryModel::QgsAttributeTableMemoryModel
( QgsVectorLayer *theLayer )
: QgsAttributeTableModel( theLayer )
int QgsAttributeTableMemoryModel::rowCount( const QModelIndex &parent ) const
{
loadLayer();
Q_UNUSED( parent );
return mFeatureMap.size();
}

bool QgsAttributeTableMemoryModel::featureAtId( QgsFeatureId fid )
bool QgsAttributeTableMemoryModel::featureAtId( QgsFeatureId fid ) const
{
QgsDebugMsg( QString( "entered featureAtId: %1." ).arg( fid ) );
if ( mFeatureMap.contains( fid ) )
{
mFeat = mFeatureMap[ fid ];
Expand All @@ -70,17 +102,14 @@ void QgsAttributeTableMemoryModel::featureDeleted( QgsFeatureId fid )
void QgsAttributeTableMemoryModel::featureAdded( QgsFeatureId fid )
{
QgsDebugMsg( "entered." );
QgsFeature f;
mLayer->featureAtId( fid, f, false, true );
mFeatureMap.insert( fid, f );
QgsAttributeTableModel::featureAdded( fid );
Q_UNUSED( fid );
loadLayer();
}

void QgsAttributeTableMemoryModel::layerDeleted()
{
QgsDebugMsg( "entered." );
mFeatureMap.clear();
QgsAttributeTableModel::layerDeleted();
loadLayer();
}

void QgsAttributeTableMemoryModel::attributeValueChanged( QgsFeatureId fid, int idx, const QVariant &value )
Expand Down
10 changes: 8 additions & 2 deletions src/gui/attributetable/qgsattributetablememorymodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

class QgsAttributeTableMemoryModel : public QgsAttributeTableModel
{
Q_OBJECT;
Q_OBJECT

public:
/**
Expand All @@ -39,6 +39,12 @@ class QgsAttributeTableMemoryModel : public QgsAttributeTableModel
*/
QgsAttributeTableMemoryModel( QgsVectorLayer *theLayer );

/**
* Returns the number of rows
* @param parent parent index
*/
virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;

/**
* Remove rows
*/
Expand Down Expand Up @@ -75,7 +81,7 @@ class QgsAttributeTableMemoryModel : public QgsAttributeTableModel
* @param fid feature id
* @return feature exists
*/
virtual bool featureAtId( QgsFeatureId fid );
virtual bool featureAtId( QgsFeatureId fid ) const;

/**
* Loads the layer into the model
Expand Down
4 changes: 2 additions & 2 deletions src/gui/attributetable/qgsattributetablemodel.cpp
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ QgsRectangle QgsAttributeTableModel::mCurrentExtent; // static member
QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayer *theLayer, QObject *parent )
: QAbstractTableModel( parent )
{
QgsDebugMsg( "entered." );

mFeat.setFeatureId( std::numeric_limits<int>::min() );
mFeatureMap.clear();
mFeatureQueue.clear();
Expand All @@ -44,8 +46,6 @@ QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayer *theLayer, QObjec
connect( mLayer, SIGNAL( featureDeleted( QgsFeatureId ) ), this, SLOT( featureDeleted( QgsFeatureId ) ) );
connect( mLayer, SIGNAL( attributeAdded( int ) ), this, SLOT( attributeAdded( int ) ) );
connect( mLayer, SIGNAL( attributeDeleted( int ) ), this, SLOT( attributeDeleted( int ) ) );

loadLayer();
}

bool QgsAttributeTableModel::featureAtId( QgsFeatureId fid ) const
Expand Down
20 changes: 9 additions & 11 deletions src/gui/attributetable/qgsattributetablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,16 @@ class GUI_EXPORT QgsAttributeTableModel: public QAbstractTableModel
* @param parent parent pointer
*/
QgsAttributeTableModel( QgsVectorLayer *theLayer, QObject *parent = 0 );

/**
* Returns the number of rows
* @param parent parent index
*/
int rowCount( const QModelIndex &parent = QModelIndex() ) const;
virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;
/**
* Returns the number of columns
* @param parent parent index
*/
int columnCount( const QModelIndex &parent = QModelIndex() ) const;

/**
* Returns header data
* @param section required section
Expand Down Expand Up @@ -214,26 +212,26 @@ class GUI_EXPORT QgsAttributeTableModel: public QAbstractTableModel
*/
void initIdMaps();

/**
* Gets mFieldCount, mAttributes and mValueMaps
*/
virtual void loadAttributes();

public:
/**
* Loads the layer into the model
*/
virtual void loadLayer();

/**
* Gets mFieldCount, mAttributes and mValueMaps
*/
virtual void loadAttributes();
private:
mutable QQueue<QgsFeatureId> mFeatureQueue;

/**
* load feature fid into mFeat
* @param fid feature id
* @return feature exists
*/
virtual bool featureAtId( QgsFeatureId fid ) const;

private:
mutable QQueue<QgsFeatureId> mFeatureQueue;

};


Expand Down
10 changes: 9 additions & 1 deletion src/gui/attributetable/qgsattributetableview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
#include "qgsattributetablememorymodel.h"
#include "qgsattributetabledelegate.h"
#include "qgsattributetablefiltermodel.h"

#include "qgsvectorlayer.h"
#include "qgsvectordataprovider.h"
#include "qgslogger.h"

QgsAttributeTableView::QgsAttributeTableView( QWidget* parent )
: QTableView( parent ), mModel( 0 ), mFilterModel( 0 ), mActionPopup( 0 )
Expand Down Expand Up @@ -63,9 +63,17 @@ void QgsAttributeTableView::setLayer( QgsVectorLayer* layer )
// features in the current view. Otherwise we'll have to store
// everything in the memory because using featureAtId() would be too slow
if ( layer->dataProvider()->capabilities() & QgsVectorDataProvider::SelectAtId )
{
QgsDebugMsg( "SelectAtId supported" );
mModel = new QgsAttributeTableModel( layer );
}
else
{
QgsDebugMsg( "SelectAtId NOT supported" );
mModel = new QgsAttributeTableMemoryModel( layer );
}

mModel->loadLayer();

mFilterModel = new QgsAttributeTableFilterModel( layer );
mFilterModel->setSourceModel( mModel );
Expand Down
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
2 changes: 2 additions & 0 deletions src/providers/postgres/qgspgsourceselect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ QString QgsPgSourceSelect::layerURI( const QModelIndex &index )
QString tableName = mTableModel.itemFromIndex( index.sibling( index.row(), QgsDbTableModel::dbtmTable ) )->text();
QString geomColumnName = mTableModel.itemFromIndex( index.sibling( index.row(), QgsDbTableModel::dbtmGeomCol ) )->text();
QString pkColumnName = mTableModel.itemFromIndex( index.sibling( index.row(), QgsDbTableModel::dbtmPkCol ) )->text();
bool selectAtId = mTableModel.itemFromIndex( index.sibling( index.row(), QgsDbTableModel::dbtmSelectAtId ) )->checkState() == Qt::Checked;
QString sql = mTableModel.itemFromIndex( index.sibling( index.row(), QgsDbTableModel::dbtmSql ) )->text();

if ( geomColumnName.contains( " AS " ) )
Expand Down Expand Up @@ -389,6 +390,7 @@ QString QgsPgSourceSelect::layerURI( const QModelIndex &index )
QgsDataSourceURI uri( m_connInfo );
uri.setDataSource( schemaName, tableName, geomColumnName, sql, pkColumnName );
uri.setUseEstimatedMetadata( mUseEstimatedMetadata );
uri.disableSelectAtId( !selectAtId );

return uri.uri();
}
Expand Down
3 changes: 1 addition & 2 deletions src/providers/postgres/qgspgsourceselect.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,7 @@ class QgsPgSourceSelect : public QDialog, private Ui::QgsDbSourceSelectBase
void setSql( const QModelIndex& index );
//! Store the selected database
void on_cmbConnections_activated( int );
void setLayerType( QString schema, QString table, QString column,
QString type );
void setLayerType( QString schema, QString table, QString column, QString type );
void on_mTablesTreeView_clicked( const QModelIndex &index );
void on_mTablesTreeView_doubleClicked( const QModelIndex &index );
//!Sets a new regular expression to the model
Expand Down
32 changes: 19 additions & 13 deletions src/providers/postgres/qgspostgresprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ QgsPostgresProvider::QgsPostgresProvider( QString const & uri )
, geomType( QGis::WKBUnknown )
, mFeatureQueueSize( 200 )
, mUseEstimatedMetadata( false )
, mSelectAtIdDisabled( false )
, mPrimaryKeyDefault( QString::null )
{
// assume this is a valid layer until we determine otherwise
Expand Down Expand Up @@ -463,6 +464,7 @@ QgsPostgresProvider::QgsPostgresProvider( QString const & uri )

primaryKey = mUri.keyColumn();
mUseEstimatedMetadata = mUri.useEstimatedMetadata();
mSelectAtIdDisabled = mUri.selectAtIdDisabled();

QgsDebugMsg( "Connection info is " + mUri.connectionInfo() );
QgsDebugMsg( "Geometry column is: " + geometryColumn );
Expand Down Expand Up @@ -1327,20 +1329,18 @@ void QgsPostgresProvider::select( QgsAttributeList fetchAttributes, QgsRectangle
if ( whereClause.isEmpty() )
{
QString qBox = QString( "%1('BOX3D(%2)'::box3d,%3)" )
.arg( connectionRO->majorVersion() < 2 ? "setsrid"
: "st_setsrid" )
.arg( rect.asWktCoordinates() )
.arg( srid );
.arg( connectionRO->majorVersion() < 2 ? "setsrid" : "st_setsrid" )
.arg( rect.asWktCoordinates() )
.arg( srid );
whereClause = QString( "%1 && %2" )
.arg( quotedIdentifier( geometryColumn ) )
.arg( qBox );
.arg( quotedIdentifier( geometryColumn ) )
.arg( qBox );
if ( useIntersect )
{
whereClause += QString( " and %1(%2,%3))" )
.arg( connectionRO->majorVersion() < 2 ? "intersects"
: "st_intersects" )
.arg( quotedIdentifier( geometryColumn ) )
.arg( qBox );
whereClause += QString( " and %1(%2,%3)" )
.arg( connectionRO->majorVersion() < 2 ? "intersects" : "st_intersects" )
.arg( quotedIdentifier( geometryColumn ) )
.arg( qBox );
}
}
}
Expand Down Expand Up @@ -1836,7 +1836,10 @@ bool QgsPostgresProvider::hasSufficientPermsAndCapabilities()

// postgres has fast access to features at id (thanks to primary key / unique index)
// the latter flag is here just for compatibility
enabledCapabilities = QgsVectorDataProvider::SelectAtId | QgsVectorDataProvider::SelectGeometryAtId;
if ( !mSelectAtIdDisabled )
{
enabledCapabilities = QgsVectorDataProvider::SelectAtId | QgsVectorDataProvider::SelectGeometryAtId;
}

if ( !inRecovery )
{
Expand Down Expand Up @@ -1965,7 +1968,10 @@ bool QgsPostgresProvider::hasSufficientPermsAndCapabilities()
return false;
}

enabledCapabilities = QgsVectorDataProvider::SelectAtId | QgsVectorDataProvider::SelectGeometryAtId;
if ( !mSelectAtIdDisabled )
{
enabledCapabilities = QgsVectorDataProvider::SelectAtId | QgsVectorDataProvider::SelectGeometryAtId;
}
}

return true;
Expand Down
3 changes: 3 additions & 0 deletions src/providers/postgres/qgspostgresprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,9 @@ class QgsPostgresProvider : public QgsVectorDataProvider
/* Use estimated metadata. Uses fast table counts, geometry type and extent determination */
bool mUseEstimatedMetadata;

/* Disable support for SelectAtId */
bool mSelectAtIdDisabled;

// Produces a QMessageBox with the given title and text. Doesn't
// return until the user has dismissed the dialog box.
static void showMessageBox( const QString& title, const QString &text );
Expand Down
32 changes: 21 additions & 11 deletions src/ui/qgscomposerscalebarwidgetbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>307</width>
<height>616</height>
<width>298</width>
<height>545</height>
</rect>
</property>
<attribute name="label">
Expand Down Expand Up @@ -143,7 +143,7 @@
</property>
</widget>
</item>
<item row="10" column="0">
<item row="12" column="0">
<widget class="QSpinBox" name="mHeightSpinBox">
<property name="suffix">
<string> mm</string>
Expand All @@ -153,7 +153,7 @@
</property>
</widget>
</item>
<item row="11" column="0">
<item row="13" column="0">
<widget class="QDoubleSpinBox" name="mLineWidthSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
Expand All @@ -178,7 +178,7 @@
</property>
</widget>
</item>
<item row="12" column="0">
<item row="14" column="0">
<widget class="QDoubleSpinBox" name="mLabelBarSpaceSpinBox">
<property name="prefix">
<string>Label space </string>
Expand All @@ -188,7 +188,7 @@
</property>
</widget>
</item>
<item row="13" column="0">
<item row="15" column="0">
<widget class="QDoubleSpinBox" name="mBoxSizeSpinBox">
<property name="prefix">
<string>Box space </string>
Expand All @@ -198,7 +198,7 @@
</property>
</widget>
</item>
<item row="14" column="0">
<item row="16" column="0">
<widget class="QLabel" name="mUnitLabelLabel">
<property name="text">
<string>Unit label</string>
Expand All @@ -211,10 +211,10 @@
</property>
</widget>
</item>
<item row="15" column="0">
<item row="17" column="0">
<widget class="QLineEdit" name="mUnitLabelLineEdit"/>
</item>
<item row="16" column="0">
<item row="18" column="0">
<widget class="QPushButton" name="mFontButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
Expand All @@ -227,14 +227,14 @@
</property>
</widget>
</item>
<item row="17" column="0">
<item row="19" column="0">
<widget class="QPushButton" name="mColorPushButton">
<property name="text">
<string>Color...</string>
</property>
</widget>
</item>
<item row="18" column="0">
<item row="20" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
Expand All @@ -247,6 +247,16 @@
</property>
</spacer>
</item>
<item row="11" column="0">
<widget class="QComboBox" name="mAlignmentComboBox"/>
</item>
<item row="10" column="0">
<widget class="QLabel" name="mAlignmentLabel">
<property name="text">
<string>Alignment</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
Expand Down