Skip to content

Commit c87e63a

Browse files
author
mhugent
committedJan 24, 2009
merge of advanced printing branch 2
git-svn-id: http://svn.osgeo.org/qgis/trunk@10006 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 037d3db commit c87e63a

36 files changed

+2106
-187
lines changed
 
430 Bytes
Loading
431 Bytes
Loading
455 Bytes
Loading
454 Bytes
Loading
444 Bytes
Loading
378 Bytes
Loading

‎src/app/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ SET(QGIS_APP_SRCS
6464
composer/qgscomposerlegenditemdialog.cpp
6565
composer/qgscomposerlegendwidget.cpp
6666
composer/qgscompositionwidget.cpp
67+
composer/qgsitempositiondialog.cpp
6768

6869
legend/qgslegendgroup.cpp
6970
legend/qgslegend.cpp
@@ -133,6 +134,7 @@ SET (QGIS_APP_MOC_HDRS
133134
composer/qgscomposerpicturewidget.h
134135
composer/qgscomposerscalebarwidget.h
135136
composer/qgscompositionwidget.h
137+
composer/qgsitempositiondialog.h
136138

137139
legend/qgslegend.h
138140
legend/qgslegendlayer.h

‎src/app/composer/qgscomposer.cpp

Lines changed: 243 additions & 37 deletions
Large diffs are not rendered by default.

‎src/app/composer/qgscomposer.h

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
9292
virtual void showEvent( QShowEvent * );
9393
#endif
9494

95+
signals:
96+
//! Is emitted every time the view zoom has changed
97+
void zoomLevelChanged();
98+
99+
95100
public slots:
96101
//! Zoom to full extent of the paper
97102
void on_mActionZoomAll_activated( void );
@@ -132,8 +137,13 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
132137
//! Add new picture
133138
void on_mActionAddImage_activated( void );
134139

140+
//! Save composer as template
141+
void on_mActionSaveAsTemplate_activated(void);
142+
143+
void on_mActionLoadFromTemplate_activated(void);
144+
135145
//! Set tool to move item content
136-
void on_mActionMoveItemContent_activated( void );
146+
void on_mActionMoveItemContent_activated(void);
137147

138148
//! Group selected items
139149
void on_mActionGroupItems_activated( void );
@@ -142,16 +152,34 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
142152
void on_mActionUngroupItems_activated( void );
143153

144154
//! Move selected items one position up
145-
void on_mActionRaiseItems_activated( void );
155+
void on_mActionRaiseItems_activated(void);
146156

147157
//!Move selected items one position down
148-
void on_mActionLowerItems_activated( void );
158+
void on_mActionLowerItems_activated(void);
149159

150160
//!Move selected items to top
151-
void on_mActionMoveItemsToTop_activated( void );
161+
void on_mActionMoveItemsToTop_activated(void);
152162

153163
//!Move selected items to bottom
154-
void on_mActionMoveItemsToBottom_activated( void );
164+
void on_mActionMoveItemsToBottom_activated(void);
165+
166+
//!Align selected composer items left
167+
void on_mActionAlignLeft_activated(void);
168+
169+
//!Align selected composere items horizontally centered
170+
void on_mActionAlignHCenter_activated(void);
171+
172+
//!Align selected composer items right
173+
void on_mActionAlignRight_activated(void);
174+
175+
//!Align selected composer items to top
176+
void on_mActionAlignTop_activated(void);
177+
178+
//!Align selected composer items vertically centered
179+
void on_mActionAlignVCenter_activated(void);
180+
181+
//!Align selected composer items to bottom
182+
void on_mActionAlignBottom_activated(void);
155183

156184
//! Save window state
157185
void saveWindowState();
@@ -212,6 +240,11 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
212240
//! Displays a warning because of possible min/max size in WMS
213241
void showWMSPrintingWarning();
214242

243+
//! Changes elements that are not suitable for this project
244+
void cleanupAfterTemplateRead();
245+
246+
//! Writes state under DOM element
247+
void writeXML(QDomNode& parentNode, QDomDocument& doc);
215248
//! Pointer to composer view
216249
QgsComposerView *mView;
217250

‎src/app/composer/qgscomposeritemwidget.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
#include "qgscomposeritemwidget.h"
1919
#include "qgscomposeritem.h"
20+
#include "qgsitempositiondialog.h"
21+
#include "qgspoint.h"
2022
#include <QColorDialog>
2123

2224
QgsComposerItemWidget::QgsComposerItemWidget( QWidget* parent, QgsComposerItem* item ): QWidget( parent ), mItem( item )
@@ -147,3 +149,14 @@ void QgsComposerItemWidget::setValuesForGuiElements()
147149
mFrameCheckBox->blockSignals( false );
148150

149151
}
152+
153+
void QgsComposerItemWidget::on_mPositionButton_clicked()
154+
{
155+
if(!mItem)
156+
{
157+
return;
158+
}
159+
160+
QgsItemPositionDialog d(mItem, 0);
161+
d.exec();
162+
}

‎src/app/composer/qgscomposeritemwidget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class QgsComposerItemWidget: public QWidget, private Ui::QgsComposerItemWidgetBa
3737
void on_mOpacitySlider_sliderReleased();
3838
void on_mOutlineWidthSpinBox_valueChanged( double d );
3939
void on_mFrameCheckBox_stateChanged( int state );
40+
void on_mPositionButton_clicked();
4041

4142
private:
4243
QgsComposerItemWidget();

‎src/app/composer/qgscomposermapwidget.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ QgsComposerMapWidget::QgsComposerMapWidget( QgsComposerMap* composerMap ): QWidg
3838
mYMaxLineEdit->setValidator( new QDoubleValidator( 0 ) );
3939

4040
mPreviewModeComboBox->insertItem( 0, tr( "Cache" ) );
41-
//MH: disabled because this option leads to frequent crashes with Qt 4.4.0 and 4.4.1
42-
//mPreviewModeComboBox->insertItem(1, tr("Render"));
41+
mPreviewModeComboBox->insertItem(1, tr("Render"));
4342
mPreviewModeComboBox->insertItem( 2, tr( "Rectangle" ) );
4443

4544
if ( composerMap )

‎src/app/composer/qgscomposerpicturewidget.cpp

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@
1616
***************************************************************************/
1717

1818
#include "qgscomposerpicturewidget.h"
19+
#include "qgsapplication.h"
1920
#include "qgscomposerpicture.h"
2021
#include "qgscomposeritemwidget.h"
2122
#include <QDoubleValidator>
2223
#include <QFileDialog>
2324
#include <QFileInfo>
25+
#include <QImageReader>
2426
#include <QMessageBox>
27+
#include <QPainter>
28+
#include <QProgressDialog>
29+
#include <QSvgRenderer>
2530

2631
QgsComposerPictureWidget::QgsComposerPictureWidget( QgsComposerPicture* picture ): QWidget(), mPicture( picture )
2732
{
@@ -36,6 +41,11 @@ QgsComposerPictureWidget::QgsComposerPictureWidget( QgsComposerPicture* picture
3641

3742
setGuiElementValues();
3843

44+
mPreviewListWidget->setIconSize(QSize(30, 30));
45+
46+
//add preview icons
47+
addStandardDirectoriesToPreview();
48+
3949
connect( mPicture, SIGNAL( settingsChanged() ), this, SLOT( setGuiElementValues() ) );
4050
}
4151

@@ -143,6 +153,51 @@ void QgsComposerPictureWidget::on_mRotationSpinBox_valueChanged( double d )
143153
}
144154
}
145155

156+
void QgsComposerPictureWidget::on_mPreviewListWidget_currentItemChanged( QListWidgetItem* current, QListWidgetItem* previous )
157+
{
158+
if(!mPicture || !current)
159+
{
160+
return;
161+
}
162+
163+
QString absoluteFilePath = current->data(Qt::UserRole).toString();
164+
mPicture->setPictureFile(absoluteFilePath);
165+
mPictureLineEdit->setText(absoluteFilePath);
166+
mPicture->update();
167+
}
168+
169+
void QgsComposerPictureWidget::on_mAddDirectoryButton_clicked()
170+
{
171+
//let user select a directory
172+
QString directory = QFileDialog::getExistingDirectory(0, tr("Select new preview directory"));
173+
if(directory.isNull())
174+
{
175+
return; //dialog canceled by user
176+
}
177+
178+
//add entry to mSearchDirectoriesComboBox
179+
mSearchDirectoriesComboBox->addItem(directory);
180+
181+
//and add icons to the preview
182+
addDirectoryToPreview(directory);
183+
}
184+
185+
void QgsComposerPictureWidget::on_mRemoveDirectoryButton_clicked()
186+
{
187+
QString directoryToRemove = mSearchDirectoriesComboBox->currentText();
188+
mSearchDirectoriesComboBox->removeItem(mSearchDirectoriesComboBox->currentIndex());
189+
190+
//remove entries from back to front (to have the indices of existing items constant)
191+
for(int i = (mPreviewListWidget->count() - 1); i >=0; --i)
192+
{
193+
QListWidgetItem* currentItem = mPreviewListWidget->item(i);
194+
if(currentItem && currentItem->data(Qt::UserRole).toString().startsWith(directoryToRemove))
195+
{
196+
delete(mPreviewListWidget->takeItem(i));
197+
}
198+
}
199+
}
200+
146201
void QgsComposerPictureWidget::setGuiElementValues()
147202
{
148203
//set initial gui values
@@ -165,3 +220,119 @@ void QgsComposerPictureWidget::setGuiElementValues()
165220
mPictureLineEdit->blockSignals( false );
166221
}
167222
}
223+
224+
int QgsComposerPictureWidget::addDirectoryToPreview(const QString& path)
225+
{
226+
//go through all files of a directory
227+
QDir directory(path);
228+
if(!directory.exists() || !directory.isReadable())
229+
{
230+
return 1; //error
231+
}
232+
233+
QFileInfoList fileList = directory.entryInfoList(QDir::Files);
234+
QFileInfoList::const_iterator fileIt = fileList.constBegin();
235+
236+
QProgressDialog progress("Adding Icons...", "Abort", 0, fileList.size() - 1, this);
237+
//cancel button does not seem to work properly with modal dialog
238+
//progress.setWindowModality(Qt::WindowModal);
239+
240+
int counter = 0;
241+
for(; fileIt != fileList.constEnd(); ++fileIt)
242+
{
243+
244+
progress.setLabelText(tr("Creating icon for file ") + fileIt->fileName());
245+
progress.setValue(counter);
246+
QCoreApplication::processEvents();
247+
if(progress.wasCanceled())
248+
{
249+
break;
250+
}
251+
QString filePath = fileIt->absoluteFilePath();
252+
253+
//test if file is svg or pixel format
254+
bool fileIsPixel = false;
255+
bool fileIsSvg = testSvgFile(filePath);
256+
if(!fileIsSvg)
257+
{
258+
fileIsPixel = testImageFile(filePath);
259+
}
260+
261+
//exclude files that are not svg or image
262+
if(!fileIsSvg && !fileIsPixel)
263+
{
264+
++counter; continue;
265+
}
266+
267+
QListWidgetItem * listItem = new QListWidgetItem(mPreviewListWidget);
268+
269+
if(fileIsSvg)
270+
{
271+
QIcon icon(filePath);
272+
listItem->setIcon(icon);
273+
}
274+
else if(fileIsPixel) //for pixel formats: create icon from scaled pixmap
275+
{
276+
QPixmap iconPixmap(filePath);
277+
if(iconPixmap.isNull())
278+
{
279+
++counter; continue; //unknown file format or other problem
280+
}
281+
//set pixmap hardcoded to 30/30, same as icon size for mPreviewListWidget
282+
QPixmap scaledPixmap(iconPixmap.scaled(QSize(30, 30), Qt::KeepAspectRatio));
283+
QIcon icon(scaledPixmap);
284+
listItem->setIcon(icon);
285+
}
286+
else
287+
{
288+
++counter; continue;
289+
}
290+
291+
listItem->setText( "" );
292+
//store the absolute icon file path as user data
293+
listItem->setData( Qt::UserRole, fileIt->absoluteFilePath());
294+
++counter;
295+
}
296+
297+
return 0;
298+
}
299+
300+
void QgsComposerPictureWidget::addStandardDirectoriesToPreview()
301+
{
302+
//list all directories in $prefix/share/qgis/svg
303+
QDir svgDirectory(QgsApplication::svgPath());
304+
if(!svgDirectory.exists() || !svgDirectory.isReadable())
305+
{
306+
return; //error
307+
}
308+
309+
QFileInfoList directoryList = svgDirectory.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
310+
QFileInfoList::const_iterator dirIt = directoryList.constBegin();
311+
for(; dirIt != directoryList.constEnd(); ++dirIt)
312+
{
313+
if(addDirectoryToPreview(dirIt->absoluteFilePath()) == 0)
314+
{
315+
mSearchDirectoriesComboBox->addItem(dirIt->absoluteFilePath());
316+
}
317+
}
318+
}
319+
320+
bool QgsComposerPictureWidget::testSvgFile(const QString& filename) const
321+
{
322+
QSvgRenderer svgRenderer(filename);
323+
if(svgRenderer.isValid())
324+
{
325+
return true;
326+
}
327+
return false;
328+
}
329+
330+
bool QgsComposerPictureWidget::testImageFile(const QString& filename) const
331+
{
332+
QString formatName = QString(QImageReader::imageFormat(filename));
333+
if(!formatName.isEmpty())
334+
{
335+
return true; //file is in a supported pixel format
336+
}
337+
return false;
338+
}

‎src/app/composer/qgscomposerpicturewidget.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,22 @@ class QgsComposerPictureWidget: public QWidget, private Ui::QgsComposerPictureWi
3939
void on_mRotationSpinBox_valueChanged( double d );
4040
void on_mWidthLineEdit_editingFinished();
4141
void on_mHeightLineEdit_editingFinished();
42+
void on_mPreviewListWidget_currentItemChanged( QListWidgetItem* current, QListWidgetItem* previous );
43+
void on_mAddDirectoryButton_clicked();
44+
void on_mRemoveDirectoryButton_clicked();
4245
/**Sets the GUI elements to the values of mPicture*/
4346
void setGuiElementValues();
4447

4548
private:
4649
QgsComposerPicture* mPicture;
50+
/**Add the icons of a directory to the preview. Returns 0 in case of success*/
51+
int addDirectoryToPreview(const QString& path);
52+
/**Add the icons of the standard directories to the preview*/
53+
void addStandardDirectoriesToPreview();
54+
/**Tests if a file is valid svg*/
55+
bool testSvgFile(const QString& filename) const;
56+
/**Tests if a file is a valid pixel format*/
57+
bool testImageFile(const QString& filename) const;
4758
};
4859

4960
#endif

‎src/app/composer/qgscompositionwidget.cpp

Lines changed: 162 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "qgscompositionwidget.h"
1818
#include "qgscomposition.h"
19+
#include <QColorDialog>
1920
#include <QWidget>
2021
#include <QPrinter> //for screen resolution
2122

@@ -38,10 +39,54 @@ QgsCompositionWidget::QgsCompositionWidget( QWidget* parent, QgsComposition* c )
3839
//read with/height from composition and find suitable entries to display
3940
displayCompositionWidthHeight();
4041

41-
//read printout resolution from composition
4242
if ( mComposition )
4343
{
44+
//read printout resolution from composition
4445
mResolutionLineEdit->setText( QString::number( mComposition->printResolution() ) );
46+
47+
//snap grid
48+
if( mComposition->snapToGridEnabled() )
49+
{
50+
mSnapToGridCheckBox->setCheckState(Qt::Checked);
51+
}
52+
else
53+
{
54+
mSnapToGridCheckBox->setCheckState(Qt::Unchecked);
55+
}
56+
mResolutionSpinBox->setValue( mComposition->snapGridResolution() );
57+
mOffsetXSpinBox->setValue( mComposition->snapGridOffsetX() );
58+
mOffsetYSpinBox->setValue( mComposition->snapGridOffsetY() );
59+
60+
61+
//grid pen width
62+
mPenWidthSpinBox->blockSignals(true);
63+
mPenWidthSpinBox->setValue(mComposition->gridPen().widthF());
64+
mPenWidthSpinBox->blockSignals(false);
65+
66+
//grid pen color
67+
mGridColorButton->blockSignals(true);
68+
mGridColorButton->setColor(mComposition->gridPen().color());
69+
mGridColorButton->blockSignals(false);
70+
71+
mGridStyleComboBox->blockSignals(true);
72+
mGridStyleComboBox->insertItem( 0, tr("Solid"));
73+
mGridStyleComboBox->insertItem( 1, tr("Dots"));
74+
mGridStyleComboBox->insertItem( 2, tr("Crosses"));
75+
76+
QgsComposition::GridStyle snapGridStyle = mComposition->gridStyle();
77+
if(snapGridStyle == QgsComposition::Solid)
78+
{
79+
mGridStyleComboBox->setCurrentIndex( 0 );
80+
}
81+
else if(snapGridStyle == QgsComposition::Dots)
82+
{
83+
mGridStyleComboBox->setCurrentIndex( 1 );
84+
}
85+
else
86+
{
87+
mGridStyleComboBox->setCurrentIndex( 2 );
88+
}
89+
mGridStyleComboBox->blockSignals(false);
4590
}
4691
}
4792

@@ -275,6 +320,37 @@ void QgsCompositionWidget::displayCompositionWidthHeight()
275320
mResolutionLineEdit->blockSignals( false );
276321
}
277322

323+
void QgsCompositionWidget::displaySnapingSettings()
324+
{
325+
if(!mComposition)
326+
{
327+
return;
328+
}
329+
330+
mSnapToGridCheckBox->blockSignals(true);
331+
mResolutionSpinBox->blockSignals(true);
332+
mOffsetXSpinBox->blockSignals(true);
333+
mOffsetYSpinBox->blockSignals(true);
334+
335+
if(mComposition->snapToGridEnabled())
336+
{
337+
mSnapToGridCheckBox->setCheckState(Qt::Checked);
338+
}
339+
else
340+
{
341+
mSnapToGridCheckBox->setCheckState(Qt::Unchecked);
342+
}
343+
344+
mResolutionSpinBox->setValue(mComposition->snapGridResolution());
345+
mOffsetXSpinBox->setValue(mComposition->snapGridOffsetX());
346+
mOffsetYSpinBox->setValue(mComposition->snapGridOffsetY());
347+
348+
mSnapToGridCheckBox->blockSignals(false);
349+
mResolutionSpinBox->blockSignals(false);
350+
mOffsetXSpinBox->blockSignals(false);
351+
mOffsetYSpinBox->blockSignals(false);
352+
}
353+
278354
void QgsCompositionWidget::on_mResolutionLineEdit_textChanged( const QString& text )
279355
{
280356
bool conversionOk;
@@ -290,3 +366,88 @@ void QgsCompositionWidget::on_mResolutionLineEdit_textChanged( const QString& te
290366
mComposition->setPrintResolution( resolutionInfo.resolution() );
291367
}
292368
}
369+
370+
void QgsCompositionWidget::on_mSnapToGridCheckBox_stateChanged(int state)
371+
{
372+
if(mComposition)
373+
{
374+
if(state == Qt::Checked)
375+
{
376+
mComposition->setSnapToGridEnabled(true);
377+
}
378+
else
379+
{
380+
mComposition->setSnapToGridEnabled(false);
381+
}
382+
}
383+
}
384+
385+
void QgsCompositionWidget::on_mResolutionSpinBox_valueChanged(double d)
386+
{
387+
if(mComposition)
388+
{
389+
mComposition->setSnapGridResolution(d);
390+
}
391+
}
392+
393+
void QgsCompositionWidget::on_mOffsetXSpinBox_valueChanged(double d)
394+
{
395+
if(mComposition)
396+
{
397+
mComposition->setSnapGridOffsetX(d);
398+
}
399+
}
400+
401+
void QgsCompositionWidget::on_mOffsetYSpinBox_valueChanged(double d)
402+
{
403+
if(mComposition)
404+
{
405+
mComposition->setSnapGridOffsetY(d);
406+
}
407+
}
408+
409+
void QgsCompositionWidget::on_mGridColorButton_clicked()
410+
{
411+
QColor newColor = QColorDialog::getColor(mGridColorButton->color());
412+
if( !newColor.isValid() )
413+
{
414+
return ; //dialog canceled by user
415+
}
416+
mGridColorButton->setColor(newColor);
417+
418+
if(mComposition)
419+
{
420+
QPen pen = mComposition->gridPen();
421+
pen.setColor(newColor);
422+
mComposition->setGridPen(pen);
423+
}
424+
}
425+
426+
void QgsCompositionWidget::on_mGridStyleComboBox_currentIndexChanged( const QString& text )
427+
{
428+
if(mComposition)
429+
{
430+
if( mGridStyleComboBox->currentText() == tr("Solid") )
431+
{
432+
mComposition->setGridStyle(QgsComposition::Solid);
433+
}
434+
else if( mGridStyleComboBox->currentText() == tr("Dots") )
435+
{
436+
mComposition->setGridStyle(QgsComposition::Dots);
437+
}
438+
else if( mGridStyleComboBox->currentText() == tr("Crosses"))
439+
{
440+
mComposition->setGridStyle(QgsComposition::Crosses);
441+
}
442+
}
443+
}
444+
445+
void QgsCompositionWidget::on_mPenWidthSpinBox_valueChanged(double d)
446+
{
447+
if(mComposition)
448+
{
449+
QPen pen = mComposition->gridPen();
450+
pen.setWidthF(d);
451+
mComposition->setGridPen(pen);
452+
}
453+
}

‎src/app/composer/qgscompositionwidget.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ class QgsCompositionWidget: public QWidget, private Ui::QgsCompositionWidgetBase
4646
void on_mPaperHeightLineEdit_editingFinished();
4747
void on_mResolutionLineEdit_textChanged( const QString& text );
4848

49+
void on_mSnapToGridCheckBox_stateChanged(int state);
50+
void on_mResolutionSpinBox_valueChanged(double d);
51+
void on_mOffsetXSpinBox_valueChanged(double d);
52+
void on_mOffsetYSpinBox_valueChanged(double d);
53+
void on_mGridColorButton_clicked();
54+
void on_mGridStyleComboBox_currentIndexChanged( const QString& text );
55+
void on_mPenWidthSpinBox_valueChanged(double d);
56+
4957
private:
5058
QgsComposition* mComposition;
5159
QMap<QString, QgsCompositionPaper> mPaperMap;
@@ -59,6 +67,8 @@ class QgsCompositionWidget: public QWidget, private Ui::QgsCompositionWidgetBase
5967
void adjustOrientation();
6068
/**Sets GUI elements to width/height from composition*/
6169
void displayCompositionWidthHeight();
70+
/**Sets GUI elements to snaping distances of composition*/
71+
void displaySnapingSettings();
6272

6373
void createPaperEntries();
6474
void insertPaperEntries();
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
/***************************************************************************
2+
qgsitempositiondialog.cpp
3+
-------------------------
4+
begin : October 2008
5+
copyright : (C) 2008 by Marco Hugentobler
6+
email : marco dot hugentobler at karto dot baug dot ethz dot ch
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#include "qgsitempositiondialog.h"
19+
#include "qgspoint.h"
20+
#include <QButtonGroup>
21+
#include <QDoubleValidator>
22+
23+
QgsItemPositionDialog::QgsItemPositionDialog(QgsComposerItem* item, QWidget* parent): QDialog(parent), mItem(item)
24+
{
25+
setupUi(this);
26+
27+
//make button exclusive
28+
QButtonGroup* buttonGroup = new QButtonGroup(this);
29+
buttonGroup->addButton(mUpperLeftCheckBox);
30+
buttonGroup->addButton(mUpperMiddleCheckBox);
31+
buttonGroup->addButton(mUpperRightCheckBox);
32+
buttonGroup->addButton(mMiddleLeftCheckBox);
33+
buttonGroup->addButton(mMiddleCheckBox);
34+
buttonGroup->addButton(mMiddleRightCheckBox);
35+
buttonGroup->addButton(mLowerLeftCheckBox);
36+
buttonGroup->addButton(mLowerMiddleCheckBox);
37+
buttonGroup->addButton(mLowerRightCheckBox);
38+
buttonGroup->setExclusive(true);
39+
40+
mXLineEdit->setValidator(new QDoubleValidator(0));
41+
mYLineEdit->setValidator(new QDoubleValidator(0));
42+
43+
//set lower left position of item
44+
mUpperLeftCheckBox->setCheckState(Qt::Checked);
45+
}
46+
47+
QgsItemPositionDialog::QgsItemPositionDialog(): mItem(0)
48+
{
49+
}
50+
51+
QgsItemPositionDialog::~QgsItemPositionDialog()
52+
{
53+
54+
}
55+
56+
int QgsItemPositionDialog::position(QgsPoint& point) const
57+
{
58+
bool convXSuccess, convYSuccess;
59+
double x = mXLineEdit->text().toDouble(&convXSuccess);
60+
double y = mYLineEdit->text().toDouble(&convYSuccess);
61+
62+
if(!convXSuccess || !convYSuccess)
63+
{
64+
return 1;
65+
}
66+
67+
point.setX(x);
68+
point.setY(y);
69+
return 0;
70+
}
71+
72+
QgsComposerItem::ItemPositionMode QgsItemPositionDialog::positionMode() const
73+
{
74+
if(mUpperLeftCheckBox->checkState() == Qt::Checked)
75+
{
76+
return QgsComposerItem::UpperLeft;
77+
}
78+
else if(mUpperMiddleCheckBox->checkState() == Qt::Checked)
79+
{
80+
return QgsComposerItem::UpperMiddle;
81+
}
82+
else if(mUpperRightCheckBox->checkState() == Qt::Checked)
83+
{
84+
return QgsComposerItem::UpperRight;
85+
}
86+
else if(mMiddleLeftCheckBox->checkState() == Qt::Checked)
87+
{
88+
return QgsComposerItem::MiddleLeft;
89+
}
90+
else if(mMiddleCheckBox->checkState() == Qt::Checked)
91+
{
92+
return QgsComposerItem::Middle;
93+
}
94+
else if(mMiddleRightCheckBox->checkState() == Qt::Checked)
95+
{
96+
return QgsComposerItem::MiddleRight;
97+
}
98+
else if(mLowerLeftCheckBox->checkState() == Qt::Checked)
99+
{
100+
return QgsComposerItem::LowerLeft;
101+
}
102+
else if(mLowerMiddleCheckBox->checkState() == Qt::Checked)
103+
{
104+
return QgsComposerItem::LowerMiddle;
105+
}
106+
else if(mLowerRightCheckBox->checkState() == Qt::Checked)
107+
{
108+
return QgsComposerItem::LowerRight;
109+
}
110+
return QgsComposerItem::UpperLeft;
111+
}
112+
113+
void QgsItemPositionDialog::on_mCloseButton_clicked()
114+
{
115+
accept();
116+
}
117+
118+
void QgsItemPositionDialog::on_mSetPositionButton_clicked()
119+
{
120+
if(!mItem)
121+
{
122+
return;
123+
}
124+
125+
QgsPoint itemPosition;
126+
if(position(itemPosition) == 0)
127+
{
128+
//query position and mode from dialog
129+
mItem->setItemPosition(itemPosition.x(), itemPosition.y(), positionMode());
130+
mItem->update();
131+
}
132+
}
133+
134+
void QgsItemPositionDialog::on_mUpperLeftCheckBox_stateChanged(int state)
135+
{
136+
if(state == Qt::Checked && mItem)
137+
{
138+
mXLineEdit->setText(QString::number(mItem->transform().dx()));
139+
mYLineEdit->setText(QString::number(mItem->transform().dy()));
140+
}
141+
}
142+
143+
void QgsItemPositionDialog::on_mUpperMiddleCheckBox_stateChanged(int state)
144+
{
145+
146+
if(state == Qt::Checked && mItem)
147+
{
148+
mXLineEdit->setText(QString::number(mItem->transform().dx() + mItem->rect().width() / 2.0));
149+
mYLineEdit->setText(QString::number(mItem->transform().dy()));
150+
}
151+
}
152+
153+
void QgsItemPositionDialog::on_mUpperRightCheckBox_stateChanged(int state)
154+
{
155+
if(state == Qt::Checked && mItem)
156+
{
157+
mXLineEdit->setText(QString::number(mItem->transform().dx() + mItem->rect().width()));
158+
mYLineEdit->setText(QString::number(mItem->transform().dy()));
159+
}
160+
}
161+
162+
void QgsItemPositionDialog::on_mMiddleLeftCheckBox_stateChanged(int state)
163+
{
164+
if(state == Qt::Checked && mItem)
165+
{
166+
mXLineEdit->setText(QString::number(mItem->transform().dx()));
167+
mYLineEdit->setText(QString::number(mItem->transform().dy() + mItem->rect().height() / 2.0));
168+
}
169+
}
170+
171+
void QgsItemPositionDialog::on_mMiddleCheckBox_stateChanged(int state)
172+
{
173+
if(state == Qt::Checked && mItem)
174+
{
175+
mXLineEdit->setText(QString::number(mItem->transform().dx() + mItem->rect().width() / 2.0));
176+
mYLineEdit->setText(QString::number(mItem->transform().dy() + mItem->rect().height() / 2.0));
177+
}
178+
}
179+
180+
void QgsItemPositionDialog::on_mMiddleRightCheckBox_stateChanged(int state)
181+
{
182+
if(state == Qt::Checked && mItem)
183+
{
184+
mXLineEdit->setText(QString::number(mItem->transform().dx() + mItem->rect().width()));
185+
mYLineEdit->setText(QString::number(mItem->transform().dy() + mItem->rect().height() / 2.0));
186+
}
187+
}
188+
189+
void QgsItemPositionDialog::on_mLowerLeftCheckBox_stateChanged(int state)
190+
{
191+
if(state == Qt::Checked && mItem)
192+
{
193+
mXLineEdit->setText(QString::number(mItem->transform().dx()));
194+
mYLineEdit->setText(QString::number(mItem->transform().dy() + mItem->rect().height()));
195+
}
196+
}
197+
198+
void QgsItemPositionDialog::on_mLowerMiddleCheckBox_stateChanged(int state)
199+
{
200+
if(state == Qt::Checked && mItem)
201+
{
202+
mXLineEdit->setText(QString::number(mItem->transform().dx() + mItem->rect().width() / 2.0));
203+
mYLineEdit->setText(QString::number(mItem->transform().dy() + mItem->rect().height()));
204+
}
205+
}
206+
207+
void QgsItemPositionDialog::on_mLowerRightCheckBox_stateChanged(int state)
208+
{
209+
if(state == Qt::Checked && mItem)
210+
{
211+
mXLineEdit->setText(QString::number(mItem->transform().dx() + mItem->rect().width()));
212+
mYLineEdit->setText(QString::number(mItem->transform().dy() + mItem->rect().height()));
213+
}
214+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/***************************************************************************
2+
qgsitempositiondialog.h
3+
-------------------------
4+
begin : October 2008
5+
copyright : (C) 2008 by Marco Hugentobler
6+
email : marco dot hugentobler at karto dot baug dot ethz dot ch
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#ifndef QGSITEMPOSITIONDIALOG_H
19+
#define QGSITEMPOSITIONDIALOG_H
20+
21+
#include "ui_qgsitempositiondialogbase.h"
22+
#include "qgscomposeritem.h"
23+
class QgsPoint;
24+
25+
/**A dialog to set the position of upper/middle/lower left/middle/lower point of an item*/
26+
class QgsItemPositionDialog: public QDialog, private Ui::QgsItemPositionDialogBase
27+
{
28+
Q_OBJECT
29+
public:
30+
QgsItemPositionDialog(QgsComposerItem* item, QWidget* parent = 0);
31+
~QgsItemPositionDialog();
32+
33+
/**Get selected x- and y-coordinate as point. Returns 0 in case of success*/
34+
int position(QgsPoint& point) const;
35+
/**A combination of upper/middle/lower and left/middle/right*/
36+
QgsComposerItem::ItemPositionMode positionMode() const;
37+
38+
public slots:
39+
40+
void on_mCloseButton_clicked();
41+
void on_mSetPositionButton_clicked();
42+
43+
//adjust coordinates in line edits
44+
void on_mUpperLeftCheckBox_stateChanged(int state);
45+
void on_mUpperMiddleCheckBox_stateChanged(int state);
46+
void on_mUpperRightCheckBox_stateChanged(int state);
47+
void on_mMiddleLeftCheckBox_stateChanged(int state);
48+
void on_mMiddleCheckBox_stateChanged(int state);
49+
void on_mMiddleRightCheckBox_stateChanged(int state);
50+
void on_mLowerLeftCheckBox_stateChanged(int state);
51+
void on_mLowerMiddleCheckBox_stateChanged(int state);
52+
void on_mLowerRightCheckBox_stateChanged(int state);
53+
54+
private:
55+
QgsComposerItem* mItem;
56+
57+
//default constructor forbidden
58+
QgsItemPositionDialog();
59+
};
60+
61+
#endif

‎src/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ SET(QGIS_CORE_SRCS
5555
composer/qgscomposerscalebar.cpp
5656
composer/qgslegendmodel.cpp
5757
composer/qgscomposerlegend.cpp
58+
composer/qgspaperitem.cpp
5859
composer/qgsscalebarstyle.cpp
5960
composer/qgsdoubleboxscalebarstyle.cpp
6061
composer/qgsnumericscalebarstyle.cpp

‎src/core/composer/qgscomposeritem.cpp

Lines changed: 97 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
#define FONT_WORKAROUND_SCALE 10 //scale factor for upscaling fontsize and downscaling painter
3131

32-
QgsComposerItem::QgsComposerItem( QgsComposition* composition ): QGraphicsRectItem( 0 ), mComposition( composition ), mBoundingResizeRectangle( 0 ), mFrame( true )
32+
QgsComposerItem::QgsComposerItem( QgsComposition* composition, bool manageZValue): QGraphicsRectItem( 0 ), mComposition( composition ), mBoundingResizeRectangle( 0 ), mFrame( true )
3333
{
3434
setFlag( QGraphicsItem::ItemIsSelectable, true );
3535
setAcceptsHoverEvents( true );
@@ -41,13 +41,13 @@ QgsComposerItem::QgsComposerItem( QgsComposition* composition ): QGraphicsRectIt
4141
setPen( defaultPen );
4242

4343
//let z-Value be managed by composition
44-
if ( mComposition )
44+
if ( mComposition && manageZValue)
4545
{
4646
mComposition->addItemToZList( this );
4747
}
4848
}
4949

50-
QgsComposerItem::QgsComposerItem( qreal x, qreal y, qreal width, qreal height, QgsComposition* composition ): QGraphicsRectItem( 0, 0, width, height, 0 ), mComposition( composition ), mBoundingResizeRectangle( 0 ), mFrame( true )
50+
QgsComposerItem::QgsComposerItem( qreal x, qreal y, qreal width, qreal height, QgsComposition* composition, bool manageZValue): QGraphicsRectItem( 0, 0, width, height, 0 ), mComposition( composition ), mBoundingResizeRectangle( 0 ), mFrame( true )
5151
{
5252
setFlag( QGraphicsItem::ItemIsSelectable, true );
5353
setAcceptsHoverEvents( true );
@@ -63,7 +63,7 @@ QgsComposerItem::QgsComposerItem( qreal x, qreal y, qreal width, qreal height, Q
6363
setPen( defaultPen );
6464

6565
//let z-Value be managed by composition
66-
if ( mComposition )
66+
if ( mComposition && manageZValue)
6767
{
6868
mComposition->addItemToZList( this );
6969
}
@@ -222,35 +222,21 @@ void QgsComposerItem::mouseMoveEvent( QGraphicsSceneMouseEvent * event )
222222
qWarning( "QgsComposerItem::mouseMoveEvent" );
223223
if ( mBoundingResizeRectangle )
224224
{
225-
double diffX = event->lastPos().x() - mLastMouseEventPos.x();
226-
double diffY = event->lastPos().y() - mLastMouseEventPos.y();
225+
double diffX = event->lastScenePos().x() - mLastMouseEventPos.x();
226+
double diffY = event->lastScenePos().y() - mLastMouseEventPos.y();
227227

228228
double mx, my, rx, ry;
229-
230-
rectangleChange( diffX, diffY, mx, my, rx, ry );
231-
232-
QRectF r = mBoundingResizeRectangle->rect();
233-
double newWidth = r.width() + rx;
234-
double newHeight = r.height() + ry;
235-
236-
QTransform oldTransform = mBoundingResizeRectangle->transform();
237-
QTransform transform;
238-
transform.translate( oldTransform.dx() + mx, oldTransform.dy() + my );
239-
240-
QRectF newBoundingRect( 0, 0, newWidth, newHeight );
241-
242-
mBoundingResizeRectangle->setRect( newBoundingRect );
243-
mBoundingResizeRectangle->setTransform( transform );
229+
changeItemRectangle(event->lastScenePos(), mMouseMoveStartPos, this, diffX, diffY, mBoundingResizeRectangle);
244230
}
245-
mLastMouseEventPos = event->lastPos();
231+
mLastMouseEventPos = event->lastScenePos();
246232
}
247233

248234
void QgsComposerItem::mousePressEvent( QGraphicsSceneMouseEvent * event )
249235
{
250236
//set current position and type of mouse move action
251237
mMouseMoveStartPos = event->lastScenePos();
252-
mLastMouseEventPos = event->lastPos();
253-
mCurrentMouseMoveAction = mouseMoveActionForPosition( event->pos() );
238+
mLastMouseEventPos = event->lastScenePos();
239+
mCurrentMouseMoveAction = mouseMoveActionForPosition(event->pos());
254240

255241
//create and show bounding rectangle
256242
mBoundingResizeRectangle = new QGraphicsRectItem( 0 );
@@ -287,14 +273,7 @@ void QgsComposerItem::mouseReleaseEvent( QGraphicsSceneMouseEvent * event )
287273
}
288274

289275
double mx, my, rx, ry;
290-
rectangleChange( diffX, diffY, mx, my, rx, ry );
291-
292-
QRectF currentRect = rect();
293-
QRectF newRect( transform().dx() + mx, transform().dy() + my, currentRect.width() + rx, currentRect.height() + ry );
294-
setSceneRect( newRect );
295-
296-
update();
297-
scene()->update();
276+
changeItemRectangle(mouseMoveStopPoint, mMouseMoveStartPos, this, diffX, diffY, this);
298277

299278
//reset default action
300279
mCurrentMouseMoveAction = QgsComposerItem::MoveItem;
@@ -391,50 +370,92 @@ QgsComposerItem::MouseMoveAction QgsComposerItem::mouseMoveActionForPosition( co
391370
return QgsComposerItem::MoveItem; //default
392371
}
393372

394-
395-
void QgsComposerItem::rectangleChange( double dx, double dy, double& mx, double& my, double& rx, double& ry ) const
373+
void QgsComposerItem::changeItemRectangle(const QPointF& currentPosition, const QPointF& mouseMoveStartPos, const QGraphicsRectItem* originalItem, double dx, double dy, QGraphicsRectItem* changeItem)
396374
{
375+
if(!changeItem || !originalItem || !mComposition)
376+
{
377+
return;
378+
}
379+
380+
double mx, my, rx, ry;
381+
QPointF snappedPosition = mComposition->snapPointToGrid(currentPosition);
382+
//double diffX = snappedPosition.x() - mouseMoveStartPos.x();
383+
//double diffY = snappedPosition.y() - mouseMoveStartPos.y();
384+
double diffX = 0;
385+
double diffY = 0;
386+
397387
switch ( mCurrentMouseMoveAction )
398388
{
399389
//vertical resize
400390
case QgsComposerItem::ResizeUp:
401-
mx = 0; my = dy; rx = 0; ry = -dy;
391+
diffY = snappedPosition.y() - originalItem->transform().dy();
392+
mx = 0; my = diffY; rx = 0; ry = -diffY;
402393
break;
403394

404395
case QgsComposerItem::ResizeDown:
405-
mx = 0; my = 0; rx = 0; ry = dy;
396+
diffY = snappedPosition.y() - (originalItem->transform().dy() + originalItem->rect().height());
397+
mx = 0; my = 0; rx = 0; ry = diffY;
406398
break;
407399

408400
//horizontal resize
409401
case QgsComposerItem::ResizeLeft:
410-
mx = dx, my = 0; rx = -dx; ry = 0;
402+
diffX = snappedPosition.x() - originalItem->transform().dx();
403+
mx = diffX, my = 0; rx = -diffX; ry = 0;
411404
break;
412405

413406
case QgsComposerItem::ResizeRight:
414-
mx = 0; my = 0; rx = dx, ry = 0;
407+
diffX = snappedPosition.x() - (originalItem->transform().dx() + originalItem->rect().width());
408+
mx = 0; my = 0; rx = diffX, ry = 0;
415409
break;
416410

417411
//diagonal resize
418412
case QgsComposerItem::ResizeLeftUp:
419-
mx = dx, my = dy; rx = -dx; ry = -dy;
413+
diffX = snappedPosition.x() - originalItem->transform().dx();
414+
diffY = snappedPosition.y() - originalItem->transform().dy();
415+
mx = diffX, my = diffY; rx = -diffX; ry = -diffY;
420416
break;
421417

422418
case QgsComposerItem::ResizeRightDown:
423-
mx = 0; my = 0; rx = dx, ry = dy;
419+
diffX = snappedPosition.x() - (originalItem->transform().dx() + originalItem->rect().width());
420+
diffY = snappedPosition.y() - (originalItem->transform().dy() + originalItem->rect().height());
421+
mx = 0; my = 0; rx = diffX, ry = diffY;
424422
break;
425423

426424
case QgsComposerItem::ResizeRightUp:
427-
mx = 0; my = dy, rx = dx, ry = -dy;
425+
diffX = snappedPosition.x() - (originalItem->transform().dx() + originalItem->rect().width());
426+
diffY = snappedPosition.y() - originalItem->transform().dy();
427+
mx = 0; my = diffY, rx = diffX, ry = -diffY;
428428
break;
429429

430430
case QgsComposerItem::ResizeLeftDown:
431-
mx = dx, my = 0; rx = -dx; ry = dy;
431+
diffX = snappedPosition.x() - originalItem->transform().dx();
432+
diffY = snappedPosition.y() - (originalItem->transform().dy() + originalItem->rect().height());
433+
mx = diffX, my = 0; rx = -diffX; ry = diffY;
432434
break;
433435

434436
case QgsComposerItem::MoveItem:
435-
mx = dx; my = dy; rx = 0, ry = 0;
436-
break;
437-
}
437+
438+
//calculate total move difference
439+
double moveX = currentPosition.x() - mouseMoveStartPos.x();
440+
double moveY = currentPosition.y() - mouseMoveStartPos.y();
441+
442+
QPointF upperLeftPoint(originalItem->transform().dx() + moveX, originalItem->transform().dy() + moveY);
443+
QPointF snappedLeftPoint = mComposition->snapPointToGrid(upperLeftPoint);
444+
445+
double moveRectX = snappedLeftPoint.x() - originalItem->transform().dx();
446+
double moveRectY = snappedLeftPoint.y() - originalItem->transform().dy();
447+
448+
QTransform moveTransform;
449+
moveTransform.translate(originalItem->transform().dx() + moveRectX, originalItem->transform().dy() + moveRectY);
450+
changeItem->setTransform(moveTransform);
451+
return;
452+
}
453+
454+
QTransform itemTransform;
455+
itemTransform.translate(originalItem->transform().dx() + mx, originalItem->transform().dy() + my);
456+
changeItem->setTransform(itemTransform);
457+
QRectF itemRect(0, 0, originalItem->rect().width() + rx, originalItem->rect().height() + ry);
458+
changeItem->setRect(itemRect);
438459
}
439460

440461
void QgsComposerItem::drawSelectionBoxes( QPainter* p )
@@ -476,6 +497,37 @@ void QgsComposerItem::move( double dx, double dy )
476497
setSceneRect( newSceneRect );
477498
}
478499

500+
void QgsComposerItem::setItemPosition(double x, double y, ItemPositionMode itemPoint)
501+
{
502+
double width = rect().width();
503+
double height = rect().height();
504+
505+
double upperLeftX = x;
506+
double upperLeftY = y;
507+
508+
//adjust x-coordinate if placement is not done to a left point
509+
if(itemPoint == UpperMiddle || itemPoint == Middle || itemPoint == LowerMiddle)
510+
{
511+
upperLeftX -= width / 2.0;
512+
}
513+
else if(itemPoint == UpperRight || itemPoint == MiddleRight || itemPoint == LowerRight)
514+
{
515+
upperLeftX -= width;
516+
}
517+
518+
//adjust y-coordinate if placement is not done to an upper point
519+
if(itemPoint == MiddleLeft || itemPoint == Middle || itemPoint == MiddleRight)
520+
{
521+
upperLeftY -= height / 2.0;
522+
}
523+
else if(itemPoint == LowerLeft || itemPoint == LowerMiddle || itemPoint == LowerRight)
524+
{
525+
upperLeftY -= height;
526+
}
527+
528+
setSceneRect(QRectF(upperLeftX, upperLeftY, width, height));
529+
}
530+
479531
void QgsComposerItem::setSceneRect( const QRectF& rectangle )
480532
{
481533
//setRect in item coordinates

‎src/core/composer/qgscomposeritem.h

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,25 @@ class CORE_EXPORT QgsComposerItem: public QGraphicsRectItem
4848
ResizeRightDown
4949
};
5050

51-
QgsComposerItem( QgsComposition* composition );
52-
QgsComposerItem( qreal x, qreal y, qreal width, qreal height, QgsComposition* composition );
51+
enum ItemPositionMode
52+
{
53+
UpperLeft,
54+
UpperMiddle,
55+
UpperRight,
56+
MiddleLeft,
57+
Middle,
58+
MiddleRight,
59+
LowerLeft,
60+
LowerMiddle,
61+
LowerRight
62+
};
63+
64+
/**Constructor
65+
@param manageZValue true if the z-Value of this object should be managed by mComposition*/
66+
QgsComposerItem( QgsComposition* composition, bool manageZValue = true);
67+
/**Constructor with box position and composer object
68+
@param manageZValue true if the z-Value of this object should be managed by mComposition*/
69+
QgsComposerItem( qreal x, qreal y, qreal width, qreal height, QgsComposition* composition, bool manageZValue = true);
5370
virtual ~QgsComposerItem();
5471

5572
/** \brief Set selected, selected item should be highlighted */
@@ -81,6 +98,9 @@ class CORE_EXPORT QgsComposerItem: public QGraphicsRectItem
8198
@param y y-position of mouse cursor (in item coordinates)*/
8299
virtual void zoomContent( int delta, double x, double y ) {}
83100

101+
/**Moves the item to a new position (in canvas coordinates)*/
102+
void setItemPosition(double x, double y, ItemPositionMode itemPoint = UpperLeft);
103+
84104
/**Sets this items bound in scene coordinates such that 1 item size units
85105
corresponds to 1 scene size unit*/
86106
virtual void setSceneRect( const QRectF& rectangle );
@@ -142,7 +162,7 @@ class CORE_EXPORT QgsComposerItem: public QGraphicsRectItem
142162
QgsComposerItem::MouseMoveAction mCurrentMouseMoveAction;
143163
/**Start point of the last mouse move action (in scene coordinates)*/
144164
QPointF mMouseMoveStartPos;
145-
/**Position of the last mouse move event (in item coordinates)*/
165+
/**Position of the last mouse move event (in scene coordinates)*/
146166
QPointF mLastMouseEventPos;
147167

148168
/**Rectangle used during move and resize actions*/
@@ -164,14 +184,15 @@ class CORE_EXPORT QgsComposerItem: public QGraphicsRectItem
164184
/**Finds out which mouse move action to choose depending on the cursor position inside the widget*/
165185
QgsComposerItem::MouseMoveAction mouseMoveActionForPosition( const QPointF& itemCoordPos );
166186

167-
/**Calculate rectangle changes according to mouse move (dx, dy) and the current mouse move action
168-
@param dx x-coordinate move of cursor
169-
@param dy y-coordinate move of cursor
170-
@param mx out: rectangle should be moved by mx in x-direction
171-
@param my out: rectangle should be moved by my in y-direction
172-
@param rx out: width of rectangle should be resized by rx
173-
@param ry out: height of rectangle should be resized by ry*/
174-
void rectangleChange( double dx, double dy, double& mx, double& my, double& rx, double& ry ) const;
187+
/**Changes the rectangle of an item depending on current mouse action (resize or move)
188+
@param currentPosition current position of mouse cursor
189+
@param mouseMoveStartPos cursor position at the start of the current mouse action
190+
@param originalItem Item position at the start of the mouse action
191+
@param dx x-Change of mouse cursor
192+
@param dy y-Change of mouse cursor
193+
@param changeItem Item to change size (can be the same as originalItem or a differen one)
194+
*/
195+
void changeItemRectangle(const QPointF& currentPosition, const QPointF& mouseMoveStartPos, const QGraphicsRectItem* originalItem, double dx, double dy, QGraphicsRectItem* changeItem);
175196

176197
/**Draw selection boxes around item*/
177198
virtual void drawSelectionBoxes( QPainter* p );

‎src/core/composer/qgscomposerlegend.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "qgsmaplayer.h"
2020
#include "qgsmaplayerregistry.h"
2121
#include "qgsmaprenderer.h"
22+
#include "qgsrenderer.h" //for brush scaling
2223
#include "qgssymbol.h"
2324
#include <QDomDocument>
2425
#include <QDomElement>
@@ -331,7 +332,15 @@ void QgsComposerLegend::drawPolygonSymbol( QPainter* p, QgsSymbol* s, double cur
331332

332333
if ( p )
333334
{
334-
p->setBrush( s->brush() );
335+
//scale brush
336+
QBrush symbolBrush = s->brush();
337+
QPaintDevice* paintDevice = p->device();
338+
if ( paintDevice )
339+
{
340+
double rasterScaleFactor = ( paintDevice->logicalDpiX() + paintDevice->logicalDpiY() ) / 2.0 / 25.4;
341+
QgsRenderer::scaleBrush(symbolBrush, rasterScaleFactor);
342+
}
343+
p->setBrush( symbolBrush );
335344
p->setPen( s->pen() );
336345
p->drawRect( QRectF( currentXPosition, currentYCoord, mSymbolWidth, mSymbolHeight ) );
337346
}

‎src/core/composer/qgscomposermap.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,13 @@ void QgsComposerMap::draw( QPainter *painter, const QgsRectangle& extent, const
116116
theMapRenderer.setProjectionsEnabled( mMapRenderer->hasCrsTransformEnabled() );
117117
theMapRenderer.setDestinationSrs( mMapRenderer->destinationSrs() );
118118

119+
//set antialiasing if enabled in options
120+
QSettings settings;
121+
if(settings.value( "/qgis/enable_anti_aliasing", false ).toBool())
122+
{
123+
painter->setRenderHint( QPainter::Antialiasing );
124+
}
125+
119126
QgsRenderContext* theRendererContext = theMapRenderer.rendererContext();
120127
if ( theRendererContext )
121128
{
@@ -142,14 +149,14 @@ void QgsComposerMap::cache( void )
142149
int w = rect().width() * horizontalViewScaleFactor();
143150
int h = rect().height() * horizontalViewScaleFactor();
144151

145-
if ( w > 3000 ) //limit size of image for better performance
152+
if ( w > 5000 ) //limit size of image for better performance
146153
{
147-
w = 3000;
154+
w = 5000;
148155
}
149156

150-
if ( h > 3000 )
157+
if ( h > 5000 )
151158
{
152-
h = 3000;
159+
h = 5000;
153160
}
154161

155162
mCachePixmap = QPixmap( w, h );
@@ -231,13 +238,21 @@ void QgsComposerMap::paint( QPainter* painter, const QStyleOptionGraphicsItem* i
231238
mLastScaleFactorX = currentScaleFactorX;
232239
}
233240

234-
void QgsComposerMap::mapCanvasChanged( void )
241+
void QgsComposerMap::updateCachedImage( void )
235242
{
236243
mCacheUpdated = false;
237244
cache();
238245
QGraphicsRectItem::update();
239246
}
240247

248+
void QgsComposerMap::renderModeUpdateCachedImage()
249+
{
250+
if(mPreviewMode == Render)
251+
{
252+
updateCachedImage();
253+
}
254+
}
255+
241256
void QgsComposerMap::setCacheUpdated( bool u )
242257
{
243258
mCacheUpdated = u;
@@ -461,8 +476,8 @@ void QgsComposerMap::connectUpdateSlot()
461476
QgsMapLayerRegistry* layerRegistry = QgsMapLayerRegistry::instance();
462477
if ( layerRegistry )
463478
{
464-
connect( layerRegistry, SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( mapCanvasChanged() ) );
465-
connect( layerRegistry, SIGNAL( layerWasAdded( QgsMapLayer* ) ), this, SLOT( mapCanvasChanged() ) );
479+
connect( layerRegistry, SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( updateCachedImage() ) );
480+
connect( layerRegistry, SIGNAL( layerWasAdded( QgsMapLayer* ) ), this, SLOT( updateCachedImage() ) );
466481
}
467482
}
468483

‎src/core/composer/qgscomposermap.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,10 @@ class CORE_EXPORT QgsComposerMap : /*public QWidget, private Ui::QgsComposerMapB
134134

135135
public slots:
136136

137-
// Called if map canvas has changed
138-
void mapCanvasChanged( );
137+
/**Called if map canvas has changed*/
138+
void updateCachedImage( );
139+
/**Call updateCachedImage if item is in render mode*/
140+
void renderModeUpdateCachedImage();
139141

140142
signals:
141143
/**Is emitted when width/height is changed as a result of user interaction*/

‎src/core/composer/qgscomposition.cpp

Lines changed: 355 additions & 5 deletions
Large diffs are not rendered by default.

‎src/core/composer/qgscomposition.h

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
class QgsComposerItem;
2323
class QgsComposerMap;
24+
class QgsPaperItem;
2425
class QGraphicsRectItem;
2526
class QgsMapRenderer;
2627

@@ -45,6 +46,14 @@ class CORE_EXPORT QgsComposition: public QGraphicsScene
4546
Postscript // Fonts need different scaling!
4647
};
4748

49+
/**Style to draw the snapping grid*/
50+
enum GridStyle
51+
{
52+
Solid,
53+
Dots,
54+
Crosses
55+
};
56+
4857
QgsComposition( QgsMapRenderer* mapRenderer );
4958
~QgsComposition();
5059

@@ -57,6 +66,24 @@ class CORE_EXPORT QgsComposition: public QGraphicsScene
5766
/**Returns width of paper item*/
5867
double paperWidth() const;
5968

69+
void setSnapToGridEnabled(bool b);
70+
bool snapToGridEnabled() const {return mSnapToGrid;}
71+
72+
void setSnapGridResolution(double r);
73+
double snapGridResolution() const {return mSnapGridResolution;}
74+
75+
void setSnapGridOffsetX(double offset);
76+
double snapGridOffsetX() const {return mSnapGridOffsetX;}
77+
78+
void setSnapGridOffsetY(double offset);
79+
double snapGridOffsetY() const {return mSnapGridOffsetY;}
80+
81+
void setGridPen(const QPen& p);
82+
const QPen& gridPen() const {return mGridPen;}
83+
84+
void setGridStyle(GridStyle s);
85+
GridStyle gridStyle() const {return mGridStyle;}
86+
6087
/**Returns the topmose composer item. Ignores mPaperItem*/
6188
QgsComposerItem* composerItemAt( const QPointF & position );
6289

@@ -97,6 +124,7 @@ class CORE_EXPORT QgsComposition: public QGraphicsScene
97124
/**Removes item from z list. Usually called from destructor of QgsComposerItem*/
98125
void removeItemFromZList( QgsComposerItem* item );
99126

127+
//functions to move selected items in hierarchy
100128
void raiseSelectedItems();
101129
void raiseItem( QgsComposerItem* item );
102130
void lowerSelectedItems();
@@ -106,27 +134,53 @@ class CORE_EXPORT QgsComposition: public QGraphicsScene
106134
void moveSelectedItemsToBottom();
107135
void moveItemToBottom( QgsComposerItem* item );
108136

137+
//functions to align selected items
138+
void alignSelectedItemsLeft();
139+
void alignSelectedItemsHCenter();
140+
void alignSelectedItemsRight();
141+
void alignSelectedItemsTop();
142+
void alignSelectedItemsVCenter();
143+
void alignSelectedItemsBottom();
144+
109145
/**Sorts the zList. The only time where this function needs to be called is from QgsComposer
110146
after reading all the items from xml file*/
111147
void sortZList();
112148

149+
/**Snaps a scene coordinate point to grid*/
150+
QPointF snapPointToGrid(const QPointF& scenePoint) const;
151+
113152

114153
private:
115154
/**Pointer to map renderer of QGIS main map*/
116155
QgsMapRenderer* mMapRenderer;
117156
QgsComposition::PlotStyle mPlotStyle;
118-
QGraphicsRectItem* mPaperItem;
157+
QgsPaperItem* mPaperItem;
119158

120159
/**Maintains z-Order of items. Starts with item at position 1 (position 0 is always paper item)*/
121160
QLinkedList<QgsComposerItem*> mItemZList;
122161

123162
/**Dpi for printout*/
124163
int mPrintResolution;
125164

165+
/**Parameters for snap to grid function*/
166+
bool mSnapToGrid;
167+
double mSnapGridResolution;
168+
double mSnapGridOffsetX;
169+
double mSnapGridOffsetY;
170+
QPen mGridPen;
171+
GridStyle mGridStyle;
172+
126173
QgsComposition(); //default constructor is forbidden
127174

128175
/**Reset z-values of items based on position in z list*/
129176
void updateZValues();
177+
178+
/**Returns the bounding rectangle of the selected items in scene coordinates
179+
@return 0 in case of success*/
180+
int boundingRectOfSelectedItems(QRectF& bRect);
181+
182+
void loadGridAppearanceSettings();
183+
void saveGridAppearanceSettings();
130184
};
131185

132186
#endif

‎src/core/composer/qgspaperitem.cpp

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/***************************************************************************
2+
qgspaperitem.cpp
3+
-------------------
4+
begin : September 2008
5+
copyright : (C) 2008 by Marco Hugentobler
6+
email : marco dot hugentobler at karto dot baug dot ethz dot ch
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#include "qgspaperitem.h"
19+
#include <QPainter>
20+
21+
QgsPaperItem::QgsPaperItem(QgsComposition* c): QgsComposerItem(c, false)
22+
{
23+
setFlag( QGraphicsItem::ItemIsSelectable, false );
24+
setZValue(0);
25+
}
26+
27+
QgsPaperItem::QgsPaperItem( qreal x, qreal y, qreal width, qreal height, QgsComposition* composition ): QgsComposerItem(x, y, width, height, composition, false)
28+
{
29+
setFlag( QGraphicsItem::ItemIsSelectable, false );
30+
setZValue(0);
31+
}
32+
33+
QgsPaperItem::QgsPaperItem(): QgsComposerItem(0, false)
34+
{
35+
36+
}
37+
38+
QgsPaperItem::~QgsPaperItem()
39+
{
40+
41+
}
42+
43+
void QgsPaperItem::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
44+
{
45+
if ( !painter )
46+
{
47+
return;
48+
}
49+
50+
drawBackground( painter );
51+
52+
//draw grid
53+
54+
if(mComposition)
55+
{
56+
if(mComposition->snapToGridEnabled() && mComposition->plotStyle() == QgsComposition::Preview
57+
&& mComposition->snapGridResolution() > 0)
58+
{
59+
int gridMultiplyX = (int)(mComposition->snapGridOffsetX() / mComposition->snapGridResolution());
60+
int gridMultiplyY = (int)(mComposition->snapGridOffsetY() / mComposition->snapGridResolution());
61+
double currentXCoord = mComposition->snapGridOffsetX() - gridMultiplyX * mComposition->snapGridResolution();
62+
double currentYCoord;
63+
double minYCoord = mComposition->snapGridOffsetY() - gridMultiplyY * mComposition->snapGridResolution();
64+
65+
if(mComposition->gridStyle() == QgsComposition::Solid)
66+
{
67+
painter->setPen(mComposition->gridPen());
68+
69+
//draw vertical lines
70+
71+
72+
for(; currentXCoord <= rect().width(); currentXCoord += mComposition->snapGridResolution())
73+
{
74+
painter->drawLine(QPointF(currentXCoord, 0), QPointF(currentXCoord, rect().height()));
75+
}
76+
77+
//draw horizontal lines
78+
currentYCoord = minYCoord;
79+
for(; currentYCoord <= rect().height(); currentYCoord += mComposition->snapGridResolution())
80+
{
81+
painter->drawLine(QPointF(0, currentYCoord), QPointF(rect().width(), currentYCoord));
82+
}
83+
}
84+
else //'Dots' or 'Crosses'
85+
{
86+
QPen gridPen = mComposition->gridPen();
87+
painter->setPen(gridPen);
88+
painter->setBrush(QBrush(gridPen.color()));
89+
double halfCrossLength = mComposition->snapGridResolution() / 6;
90+
91+
for(; currentXCoord <= rect().width(); currentXCoord += mComposition->snapGridResolution())
92+
{
93+
currentYCoord = minYCoord;
94+
for(; currentYCoord <= rect().height(); currentYCoord += mComposition->snapGridResolution())
95+
{
96+
if(mComposition->gridStyle() == QgsComposition::Dots)
97+
{
98+
QRectF pieRect(currentXCoord - gridPen.widthF() / 2, currentYCoord - gridPen.widthF() / 2, gridPen.widthF(), gridPen.widthF());
99+
painter->drawChord(pieRect, 0, 5760);
100+
}
101+
else if(mComposition->gridStyle() == QgsComposition::Crosses)
102+
{
103+
painter->drawLine(QPointF(currentXCoord - halfCrossLength, currentYCoord), QPointF(currentXCoord + halfCrossLength, currentYCoord));
104+
painter->drawLine(QPointF(currentXCoord, currentYCoord - halfCrossLength), QPointF(currentXCoord, currentYCoord + halfCrossLength));
105+
}
106+
}
107+
}
108+
}
109+
}
110+
}
111+
}
112+
113+
bool QgsPaperItem::writeXML( QDomElement& elem, QDomDocument & doc ) const
114+
{
115+
return true;
116+
}
117+
118+
bool QgsPaperItem::readXML( const QDomElement& itemElem, const QDomDocument& doc )
119+
{
120+
return true;
121+
}

‎src/core/composer/qgspaperitem.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/***************************************************************************
2+
qgspaperitem.h
3+
-------------------
4+
begin : September 2008
5+
copyright : (C) 2008 by Marco Hugentobler
6+
email : marco dot hugentobler at karto dot baug dot ethz dot ch
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#ifndef QGSPAPERITEM_H
19+
#define QGSPAPERITEM_H
20+
21+
#include "qgscomposeritem.h"
22+
23+
/**Item representing the paper. May draw the snapping grid lines if composition is in
24+
preview mode*/
25+
class QgsPaperItem: public QgsComposerItem
26+
{
27+
public:
28+
QgsPaperItem(QgsComposition* c);
29+
QgsPaperItem( qreal x, qreal y, qreal width, qreal height, QgsComposition* composition );
30+
~QgsPaperItem();
31+
32+
/** \brief Reimplementation of QCanvasItem::paint*/
33+
void paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget );
34+
35+
/** stores state in Dom node
36+
* @param node is Dom node corresponding to 'Composer' tag
37+
* @param temp write template file
38+
*/
39+
bool writeXML( QDomElement& elem, QDomDocument & doc ) const;
40+
41+
/** sets state from Dom document
42+
* @param itemElem is Dom node corresponding to item tag
43+
*/
44+
bool readXML( const QDomElement& itemElem, const QDomDocument& doc );
45+
46+
private:
47+
QgsPaperItem();
48+
};
49+
50+
#endif

‎src/core/renderer/qgsrenderer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ bool QgsRenderer::containsPixmap() const
5151
}
5252
}
5353

54-
void QgsRenderer::scaleBrush( QBrush& b, double rasterScaleFactor ) const
54+
void QgsRenderer::scaleBrush( QBrush& b, double rasterScaleFactor )
5555
{
5656
if ( rasterScaleFactor != 1.0 )
5757
{

‎src/core/renderer/qgsrenderer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,16 @@ class CORE_EXPORT QgsRenderer
8888
This is a hint for QgsVectorLayer to not use the transparency setting on layer level in this cases*/
8989
virtual bool usesTransparency() const {return false;}
9090

91+
/**Scales a brush to a given raster scale factor (e.g. for printing)*/
92+
static void scaleBrush( QBrush& b, double rasterScaleFactor );
93+
9194
protected:
9295
/**Color to draw selected features - static so we can change it in proj props and automatically
9396
all renderers are updated*/
9497
static QColor mSelectionColor;
9598

9699
/**Layer type*/
97100
QGis::GeometryType mGeometryType;
98-
99-
/**Scales a brush to a given raster scale factor (e.g. for printing)*/
100-
void scaleBrush( QBrush& b, double rasterScaleFactor ) const;
101101
};
102102

103103
#endif // QGSRENDERER_H

‎src/gui/qgscomposerview.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ void QgsComposerView::mousePressEvent( QMouseEvent* e )
4141
return;
4242
}
4343

44-
QPointF scenePoint = mapToScene( e->pos() );
44+
QPointF scenePoint = mapToScene( e->pos());
45+
QPointF snappedScenePoint = composition()->snapPointToGrid(scenePoint);
4546

4647
switch ( mCurrentTool )
4748
{
@@ -83,7 +84,7 @@ void QgsComposerView::mousePressEvent( QMouseEvent* e )
8384
{
8485
QTransform t;
8586
mRubberBandItem = new QGraphicsRectItem( 0, 0, 0, 0 );
86-
t.translate( scenePoint.x(), scenePoint.y() );
87+
t.translate( snappedScenePoint.x(), snappedScenePoint.y() );
8788
mRubberBandItem->setTransform( t );
8889
mRubberBandItem->setZValue( 100 );
8990
scene()->addItem( mRubberBandItem );
@@ -99,7 +100,7 @@ void QgsComposerView::mousePressEvent( QMouseEvent* e )
99100
scene()->addItem( newLabelItem );
100101
emit composerLabelAdded( newLabelItem );
101102
scene()->clearSelection();
102-
newLabelItem->setSceneRect( QRectF( scenePoint.x(), scenePoint.y(), newLabelItem->rect().width(), newLabelItem->rect().height() ) );
103+
newLabelItem->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), newLabelItem->rect().width(), newLabelItem->rect().height() ) );
103104
newLabelItem->setSelected( true );
104105
emit selectedItemChanged( newLabelItem );
105106
emit actionFinished();
@@ -117,7 +118,7 @@ void QgsComposerView::mousePressEvent( QMouseEvent* e )
117118
newScaleBar->setComposerMap( mapItemList.at( 0 ) );
118119
}
119120

120-
newScaleBar->setSceneRect( QRectF( scenePoint.x(), scenePoint.y(), 20, 20 ) );
121+
newScaleBar->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 20, 20 ) );
121122
newScaleBar->applyDefaultSettings(); //4 segments, 1/5 of composer map width
122123
scene()->addItem( newScaleBar );
123124
emit composerScaleBarAdded( newScaleBar );
@@ -134,7 +135,7 @@ void QgsComposerView::mousePressEvent( QMouseEvent* e )
134135
scene()->addItem( newLegend );
135136
emit composerLegendAdded( newLegend );
136137
scene()->clearSelection();
137-
newLegend->setSceneRect( QRectF( scenePoint.x(), scenePoint.y(), newLegend->rect().width(), newLegend->rect().height() ) );
138+
newLegend->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), newLegend->rect().width(), newLegend->rect().height() ) );
138139
newLegend->setSelected( true );
139140
emit selectedItemChanged( newLegend );
140141
emit actionFinished();
@@ -146,7 +147,7 @@ void QgsComposerView::mousePressEvent( QMouseEvent* e )
146147
scene()->addItem( newPicture );
147148
emit composerPictureAdded( newPicture );
148149
scene()->clearSelection();
149-
newPicture->setSceneRect( QRectF( scenePoint.x(), scenePoint.y(), 30, 30 ) );
150+
newPicture->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 30, 30 ) );
150151
newPicture->setSelected( true );
151152
emit selectedItemChanged( newPicture );
152153
emit actionFinished();

‎src/ui/qgscomposerbase.ui

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<rect>
66
<x>0</x>
77
<y>0</y>
8-
<width>710</width>
8+
<width>737</width>
99
<height>609</height>
1010
</rect>
1111
</property>
@@ -229,6 +229,8 @@
229229
<attribute name="toolBarBreak" >
230230
<bool>false</bool>
231231
</attribute>
232+
<addaction name="mActionLoadFromTemplate" />
233+
<addaction name="mActionSaveAsTemplate" />
232234
<addaction name="mActionExportAsImage" />
233235
<addaction name="mActionExportAsSVG" />
234236
<addaction name="mActionPrint" />
@@ -247,10 +249,6 @@
247249
<addaction name="mActionMoveItemContent" />
248250
<addaction name="mActionGroupItems" />
249251
<addaction name="mActionUngroupItems" />
250-
<addaction name="mActionRaiseItems" />
251-
<addaction name="mActionLowerItems" />
252-
<addaction name="mActionMoveItemsToTop" />
253-
<addaction name="mActionMoveItemsToBottom" />
254252
</widget>
255253
<action name="mActionPrint" >
256254
<property name="icon" >
@@ -430,6 +428,64 @@
430428
<string>Move selected items to bottom</string>
431429
</property>
432430
</action>
431+
<action name="mActionLoadFromTemplate" >
432+
<property name="text" >
433+
<string>Load From template</string>
434+
</property>
435+
</action>
436+
<action name="mActionSaveAsTemplate" >
437+
<property name="text" >
438+
<string>Save as template</string>
439+
</property>
440+
</action>
441+
<action name="mActionAlignLeft" >
442+
<property name="text" >
443+
<string>Align left</string>
444+
</property>
445+
<property name="toolTip" >
446+
<string>Align selected items left</string>
447+
</property>
448+
</action>
449+
<action name="mActionAlignHCenter" >
450+
<property name="text" >
451+
<string>Align center</string>
452+
</property>
453+
<property name="toolTip" >
454+
<string>Align center horizontal</string>
455+
</property>
456+
</action>
457+
<action name="mActionAlignRight" >
458+
<property name="text" >
459+
<string>Align right</string>
460+
</property>
461+
<property name="toolTip" >
462+
<string>Align selected items right</string>
463+
</property>
464+
</action>
465+
<action name="mActionAlignTop" >
466+
<property name="text" >
467+
<string>Align top</string>
468+
</property>
469+
<property name="toolTip" >
470+
<string>Align selected items to top</string>
471+
</property>
472+
</action>
473+
<action name="mActionAlignVCenter" >
474+
<property name="text" >
475+
<string>Align center vertical</string>
476+
</property>
477+
<property name="toolTip" >
478+
<string>Align center vertical</string>
479+
</property>
480+
</action>
481+
<action name="mActionAlignBottom" >
482+
<property name="text" >
483+
<string>Align bottom</string>
484+
</property>
485+
<property name="toolTip" >
486+
<string>Align selected items bottom</string>
487+
</property>
488+
</action>
433489
</widget>
434490
<tabstops>
435491
<tabstop>mOptionsTabWidget</tabstop>

‎src/ui/qgscomposeritemwidgetbase.ui

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
<rect>
66
<x>0</x>
77
<y>0</y>
8-
<width>355</width>
9-
<height>203</height>
8+
<width>347</width>
9+
<height>207</height>
1010
</rect>
1111
</property>
1212
<property name="windowTitle" >
@@ -68,6 +68,13 @@
6868
<widget class="QDoubleSpinBox" name="mOutlineWidthSpinBox" />
6969
</item>
7070
<item row="3" column="0" colspan="2" >
71+
<widget class="QPushButton" name="mPositionButton" >
72+
<property name="text" >
73+
<string>Position...</string>
74+
</property>
75+
</widget>
76+
</item>
77+
<item row="3" column="3" >
7178
<widget class="QCheckBox" name="mFrameCheckBox" >
7279
<property name="text" >
7380
<string>Frame</string>

‎src/ui/qgscomposerpicturewidgetbase.ui

Lines changed: 96 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
<rect>
66
<x>0</x>
77
<y>0</y>
8-
<width>274</width>
9-
<height>183</height>
8+
<width>342</width>
9+
<height>613</height>
1010
</rect>
1111
</property>
1212
<property name="sizePolicy" >
@@ -20,6 +20,98 @@
2020
</property>
2121
<layout class="QGridLayout" >
2222
<item row="0" column="0" >
23+
<widget class="QGroupBox" name="mSearchDirectoriesGroupBox" >
24+
<property name="sizePolicy" >
25+
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
26+
<horstretch>0</horstretch>
27+
<verstretch>0</verstretch>
28+
</sizepolicy>
29+
</property>
30+
<property name="title" >
31+
<string>Search directories</string>
32+
</property>
33+
<layout class="QGridLayout" >
34+
<item row="0" column="0" >
35+
<spacer>
36+
<property name="orientation" >
37+
<enum>Qt::Horizontal</enum>
38+
</property>
39+
<property name="sizeHint" >
40+
<size>
41+
<width>101</width>
42+
<height>20</height>
43+
</size>
44+
</property>
45+
</spacer>
46+
</item>
47+
<item row="0" column="1" >
48+
<widget class="QPushButton" name="mAddDirectoryButton" >
49+
<property name="text" >
50+
<string>Add...</string>
51+
</property>
52+
</widget>
53+
</item>
54+
<item row="0" column="2" >
55+
<widget class="QPushButton" name="mRemoveDirectoryButton" >
56+
<property name="text" >
57+
<string>Remove</string>
58+
</property>
59+
</widget>
60+
</item>
61+
<item row="1" column="0" colspan="3" >
62+
<widget class="QComboBox" name="mSearchDirectoriesComboBox" >
63+
<property name="sizePolicy" >
64+
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
65+
<horstretch>0</horstretch>
66+
<verstretch>0</verstretch>
67+
</sizepolicy>
68+
</property>
69+
</widget>
70+
</item>
71+
</layout>
72+
</widget>
73+
</item>
74+
<item row="1" column="0" >
75+
<widget class="QGroupBox" name="mPreviewGroupBox" >
76+
<property name="sizePolicy" >
77+
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
78+
<horstretch>0</horstretch>
79+
<verstretch>0</verstretch>
80+
</sizepolicy>
81+
</property>
82+
<property name="title" >
83+
<string>Preview</string>
84+
</property>
85+
<layout class="QGridLayout" >
86+
<item row="0" column="0" >
87+
<widget class="QListWidget" name="mPreviewListWidget" >
88+
<property name="movement" >
89+
<enum>QListView::Free</enum>
90+
</property>
91+
<property name="flow" >
92+
<enum>QListView::LeftToRight</enum>
93+
</property>
94+
<property name="isWrapping" stdset="0" >
95+
<bool>true</bool>
96+
</property>
97+
<property name="gridSize" >
98+
<size>
99+
<width>30</width>
100+
<height>30</height>
101+
</size>
102+
</property>
103+
<property name="viewMode" >
104+
<enum>QListView::IconMode</enum>
105+
</property>
106+
<property name="wordWrap" >
107+
<bool>true</bool>
108+
</property>
109+
</widget>
110+
</item>
111+
</layout>
112+
</widget>
113+
</item>
114+
<item row="2" column="0" >
23115
<layout class="QHBoxLayout" >
24116
<property name="spacing" >
25117
<number>6</number>
@@ -42,7 +134,7 @@
42134
<item>
43135
<widget class="QPushButton" name="mPictureBrowseButton" >
44136
<property name="sizePolicy" >
45-
<sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
137+
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
46138
<horstretch>0</horstretch>
47139
<verstretch>0</verstretch>
48140
</sizepolicy>
@@ -60,7 +152,7 @@
60152
</item>
61153
</layout>
62154
</item>
63-
<item row="1" column="0" >
155+
<item row="3" column="0" >
64156
<layout class="QGridLayout" >
65157
<item row="0" column="0" >
66158
<widget class="QLabel" name="textLabel3" >
@@ -121,19 +213,6 @@
121213
</item>
122214
</layout>
123215
</item>
124-
<item row="2" column="0" >
125-
<spacer>
126-
<property name="orientation" >
127-
<enum>Qt::Vertical</enum>
128-
</property>
129-
<property name="sizeHint" >
130-
<size>
131-
<width>20</width>
132-
<height>21</height>
133-
</size>
134-
</property>
135-
</spacer>
136-
</item>
137216
</layout>
138217
</widget>
139218
<layoutdefault spacing="6" margin="11" />

‎src/ui/qgscompositionwidgetbase.ui

Lines changed: 95 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
<rect>
66
<x>0</x>
77
<y>0</y>
8-
<width>243</width>
9-
<height>422</height>
8+
<width>301</width>
9+
<height>735</height>
1010
</rect>
1111
</property>
1212
<property name="sizePolicy" >
@@ -19,24 +19,6 @@
1919
<string>Composition</string>
2020
</property>
2121
<layout class="QGridLayout" >
22-
<property name="leftMargin" >
23-
<number>9</number>
24-
</property>
25-
<property name="topMargin" >
26-
<number>9</number>
27-
</property>
28-
<property name="rightMargin" >
29-
<number>9</number>
30-
</property>
31-
<property name="bottomMargin" >
32-
<number>9</number>
33-
</property>
34-
<property name="horizontalSpacing" >
35-
<number>6</number>
36-
</property>
37-
<property name="verticalSpacing" >
38-
<number>6</number>
39-
</property>
4022
<item row="0" column="0" colspan="2" >
4123
<widget class="QGroupBox" name="groupBox" >
4224
<property name="title" >
@@ -189,23 +171,93 @@
189171
</layout>
190172
</widget>
191173
</item>
192-
<item row="2" column="0" colspan="2" >
193-
<spacer>
194-
<property name="orientation" >
195-
<enum>Qt::Vertical</enum>
196-
</property>
197-
<property name="sizeType" >
198-
<enum>QSizePolicy::Expanding</enum>
199-
</property>
200-
<property name="sizeHint" >
201-
<size>
202-
<width>223</width>
203-
<height>41</height>
204-
</size>
174+
<item row="1" column="0" colspan="2" >
175+
<widget class="QGroupBox" name="mSnapGroupBox" >
176+
<property name="title" >
177+
<string>Snapping</string>
205178
</property>
206-
</spacer>
179+
<layout class="QGridLayout" >
180+
<item row="0" column="0" colspan="2" >
181+
<widget class="QCheckBox" name="mSnapToGridCheckBox" >
182+
<property name="text" >
183+
<string>Snap to grid</string>
184+
</property>
185+
</widget>
186+
</item>
187+
<item row="1" column="0" colspan="2" >
188+
<widget class="QLabel" name="mResolutionLabel_2" >
189+
<property name="text" >
190+
<string>Grid resolution:</string>
191+
</property>
192+
</widget>
193+
</item>
194+
<item row="1" column="2" >
195+
<widget class="QDoubleSpinBox" name="mResolutionSpinBox" />
196+
</item>
197+
<item row="2" column="0" colspan="2" >
198+
<widget class="QLabel" name="mXOffsetLabel" >
199+
<property name="text" >
200+
<string>Offset x:</string>
201+
</property>
202+
</widget>
203+
</item>
204+
<item row="2" column="2" >
205+
<widget class="QDoubleSpinBox" name="mOffsetXSpinBox" />
206+
</item>
207+
<item row="3" column="0" colspan="2" >
208+
<widget class="QLabel" name="mYOffsetLabel" >
209+
<property name="text" >
210+
<string>Offset y:</string>
211+
</property>
212+
</widget>
213+
</item>
214+
<item row="3" column="2" >
215+
<widget class="QDoubleSpinBox" name="mOffsetYSpinBox" />
216+
</item>
217+
<item row="4" column="0" >
218+
<widget class="QLabel" name="mPenWidthLabel" >
219+
<property name="text" >
220+
<string>Pen width:</string>
221+
</property>
222+
</widget>
223+
</item>
224+
<item row="4" column="2" >
225+
<widget class="QDoubleSpinBox" name="mPenWidthSpinBox" />
226+
</item>
227+
<item row="5" column="0" >
228+
<widget class="QLabel" name="mGridColorLabel" >
229+
<property name="text" >
230+
<string>Grid color:</string>
231+
</property>
232+
</widget>
233+
</item>
234+
<item row="5" column="2" >
235+
<widget class="QgsColorButton" name="mGridColorButton" >
236+
<property name="sizePolicy" >
237+
<sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
238+
<horstretch>0</horstretch>
239+
<verstretch>0</verstretch>
240+
</sizepolicy>
241+
</property>
242+
<property name="text" >
243+
<string/>
244+
</property>
245+
</widget>
246+
</item>
247+
<item row="6" column="0" >
248+
<widget class="QLabel" name="mGridStyleLabel" >
249+
<property name="text" >
250+
<string>Grid style:</string>
251+
</property>
252+
</widget>
253+
</item>
254+
<item row="6" column="1" colspan="2" >
255+
<widget class="QComboBox" name="mGridStyleComboBox" />
256+
</item>
257+
</layout>
258+
</widget>
207259
</item>
208-
<item row="1" column="0" >
260+
<item row="2" column="0" >
209261
<widget class="QLabel" name="mResolutionLabel" >
210262
<property name="sizePolicy" >
211263
<sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
@@ -221,12 +273,19 @@
221273
</property>
222274
</widget>
223275
</item>
224-
<item row="1" column="1" >
276+
<item row="2" column="1" >
225277
<widget class="QLineEdit" name="mResolutionLineEdit" />
226278
</item>
227279
</layout>
228280
</widget>
229281
<layoutdefault spacing="6" margin="11" />
282+
<customwidgets>
283+
<customwidget>
284+
<class>QgsColorButton</class>
285+
<extends>QToolButton</extends>
286+
<header>qgscolorbutton.h</header>
287+
</customwidget>
288+
</customwidgets>
230289
<resources/>
231290
<connections/>
232291
</ui>

‎src/ui/qgsitempositiondialogbase.ui

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
<ui version="4.0" >
2+
<class>QgsItemPositionDialogBase</class>
3+
<widget class="QDialog" name="QgsItemPositionDialogBase" >
4+
<property name="geometry" >
5+
<rect>
6+
<x>0</x>
7+
<y>0</y>
8+
<width>434</width>
9+
<height>274</height>
10+
</rect>
11+
</property>
12+
<property name="windowTitle" >
13+
<string>Set item position</string>
14+
</property>
15+
<layout class="QGridLayout" >
16+
<item row="0" column="0" >
17+
<widget class="QGroupBox" name="mPositionGroupBox" >
18+
<property name="title" >
19+
<string>Item Point</string>
20+
</property>
21+
<layout class="QGridLayout" >
22+
<item row="0" column="0" >
23+
<widget class="QCheckBox" name="mUpperLeftCheckBox" >
24+
<property name="text" >
25+
<string/>
26+
</property>
27+
</widget>
28+
</item>
29+
<item row="0" column="1" >
30+
<widget class="QCheckBox" name="mUpperMiddleCheckBox" >
31+
<property name="text" >
32+
<string/>
33+
</property>
34+
</widget>
35+
</item>
36+
<item row="0" column="2" >
37+
<widget class="QCheckBox" name="mUpperRightCheckBox" >
38+
<property name="text" >
39+
<string/>
40+
</property>
41+
</widget>
42+
</item>
43+
<item row="1" column="0" >
44+
<widget class="QCheckBox" name="mMiddleLeftCheckBox" >
45+
<property name="text" >
46+
<string/>
47+
</property>
48+
</widget>
49+
</item>
50+
<item row="1" column="1" >
51+
<widget class="QCheckBox" name="mMiddleCheckBox" >
52+
<property name="text" >
53+
<string/>
54+
</property>
55+
</widget>
56+
</item>
57+
<item row="1" column="2" >
58+
<widget class="QCheckBox" name="mMiddleRightCheckBox" >
59+
<property name="text" >
60+
<string/>
61+
</property>
62+
</widget>
63+
</item>
64+
<item row="2" column="0" >
65+
<widget class="QCheckBox" name="mLowerLeftCheckBox" >
66+
<property name="text" >
67+
<string/>
68+
</property>
69+
</widget>
70+
</item>
71+
<item row="2" column="1" >
72+
<widget class="QCheckBox" name="mLowerMiddleCheckBox" >
73+
<property name="text" >
74+
<string/>
75+
</property>
76+
</widget>
77+
</item>
78+
<item row="2" column="2" >
79+
<widget class="QCheckBox" name="mLowerRightCheckBox" >
80+
<property name="text" >
81+
<string/>
82+
</property>
83+
</widget>
84+
</item>
85+
</layout>
86+
</widget>
87+
</item>
88+
<item row="0" column="1" colspan="2" >
89+
<widget class="QGroupBox" name="mCoordinatesGroupBox" >
90+
<property name="title" >
91+
<string>Coordinates</string>
92+
</property>
93+
<layout class="QGridLayout" >
94+
<item row="0" column="0" >
95+
<layout class="QHBoxLayout" >
96+
<item>
97+
<widget class="QLabel" name="mXLabel" >
98+
<property name="text" >
99+
<string>x:</string>
100+
</property>
101+
</widget>
102+
</item>
103+
<item>
104+
<widget class="QLineEdit" name="mXLineEdit" />
105+
</item>
106+
</layout>
107+
</item>
108+
<item row="1" column="0" >
109+
<layout class="QHBoxLayout" >
110+
<item>
111+
<widget class="QLabel" name="mYLabel" >
112+
<property name="text" >
113+
<string>y:</string>
114+
</property>
115+
</widget>
116+
</item>
117+
<item>
118+
<widget class="QLineEdit" name="mYLineEdit" />
119+
</item>
120+
</layout>
121+
</item>
122+
</layout>
123+
</widget>
124+
</item>
125+
<item row="1" column="0" colspan="2" >
126+
<spacer>
127+
<property name="orientation" >
128+
<enum>Qt::Horizontal</enum>
129+
</property>
130+
<property name="sizeHint" >
131+
<size>
132+
<width>201</width>
133+
<height>20</height>
134+
</size>
135+
</property>
136+
</spacer>
137+
</item>
138+
<item row="1" column="2" >
139+
<layout class="QHBoxLayout" >
140+
<item>
141+
<widget class="QPushButton" name="mSetPositionButton" >
142+
<property name="text" >
143+
<string>Set Position</string>
144+
</property>
145+
</widget>
146+
</item>
147+
<item>
148+
<widget class="QPushButton" name="mCloseButton" >
149+
<property name="text" >
150+
<string>Close</string>
151+
</property>
152+
</widget>
153+
</item>
154+
</layout>
155+
</item>
156+
</layout>
157+
</widget>
158+
<resources/>
159+
<connections/>
160+
</ui>

0 commit comments

Comments
 (0)
Please sign in to comment.