1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "contextpanewidgetimage.h"
35 #include "ui_contextpanewidgetimage.h"
36 #include "ui_contextpanewidgetborderimage.h"
37 #include <qmljs/qmljspropertyreader.h>
43 #include <QGraphicsEffect>
44 #include <QMouseEvent>
45 #include <QScrollArea>
49 namespace QmlEditorWidgets {
51 bool LabelFilter::eventFilter(QObject *obj, QEvent *event)
53 if (event->type() == QEvent::MouseButtonDblClick) {
58 return QObject::eventFilter(obj, event);
61 bool WheelFilter::eventFilter(QObject *obj, QEvent *event)
63 if (event->type() == QEvent::Wheel) {
65 && obj->isWidgetType()
67 QApplication::sendEvent(m_target, event);
71 return QObject::eventFilter(obj, event);
74 ContextPaneWidgetImage::ContextPaneWidgetImage(QWidget *parent, bool borderImage) :
76 ui(0), uiBorderImage(0), previewWasVisible(false)
78 LabelFilter *labelFilter = new LabelFilter(this);
80 m_borderImage = borderImage;
83 uiBorderImage = new Ui::ContextPaneWidgetBorderImage;
84 uiBorderImage->setupUi(this);
85 m_fileWidget = uiBorderImage->fileWidget;
86 m_sizeLabel = uiBorderImage->sizeLabel;
87 uiBorderImage->label->setToolTip(tr("double click for preview"));
88 uiBorderImage->label->installEventFilter(labelFilter);
91 connect(uiBorderImage->verticalTileRadioButton, SIGNAL(toggled(bool)), this, SLOT(onVerticalStretchChanged()));
92 connect(uiBorderImage->verticalStretchRadioButton, SIGNAL(toggled(bool)), this, SLOT(onVerticalStretchChanged()));
93 connect(uiBorderImage->verticalTileRadioButtonNoCrop, SIGNAL(toggled(bool)), this, SLOT(onVerticalStretchChanged()));
95 connect(uiBorderImage->horizontalTileRadioButton, SIGNAL(toggled(bool)), this, SLOT(onHorizontalStretchChanged()));
96 connect(uiBorderImage->horizontalStretchRadioButton, SIGNAL(toggled(bool)), this, SLOT(onHorizontalStretchChanged()));
97 connect(uiBorderImage->horizontalTileRadioButtonNoCrop, SIGNAL(toggled(bool)), this, SLOT(onHorizontalStretchChanged()));
98 connect(previewDialog()->previewLabel(), SIGNAL(leftMarginChanged()), this, SLOT(onLeftMarginsChanged()));
99 connect(previewDialog()->previewLabel(), SIGNAL(rightMarginChanged()), this, SLOT(onRightMarginsChanged()));
100 connect(previewDialog()->previewLabel(), SIGNAL(topMarginChanged()), this, SLOT(onTopMarginsChanged()));
101 connect(previewDialog()->previewLabel(), SIGNAL(bottomMarginChanged()), this, SLOT(onBottomMarginsChanged()));
104 ui = new Ui::ContextPaneWidgetImage;
106 ui->label->setToolTip(tr("double click for preview"));
107 ui->label->installEventFilter(labelFilter);
108 m_fileWidget = ui->fileWidget;
109 m_sizeLabel = ui->sizeLabel;
111 connect(ui->stretchRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
112 connect(ui->tileRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
113 connect(ui->horizontalStretchRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
114 connect(ui->verticalStretchRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
115 connect(ui->preserveAspectFitRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
116 connect(ui->cropAspectFitRadioButton, SIGNAL(toggled(bool)), this, SLOT(onStretchChanged()));
119 m_fileWidget->setShowComboBox(true);
120 m_fileWidget->setFilter("*.png *.gif *.jpg");
122 connect(m_fileWidget, SIGNAL(fileNameChanged(QUrl)), this, SLOT(onFileNameChanged()));
123 connect(labelFilter, SIGNAL(doubleClicked()), this, SLOT(onPixmapDoubleClicked()));
127 ContextPaneWidgetImage::~ContextPaneWidgetImage()
132 delete uiBorderImage;
135 void ContextPaneWidgetImage::setProperties(QmlJS::PropertyReader *propertyReader)
142 int bottomBorder = 0;
144 if (propertyReader->hasProperty(QLatin1String("border.left")))
145 leftBorder =propertyReader->readProperty(QLatin1String("border.left")).toInt();
146 if (propertyReader->hasProperty(QLatin1String("border.right")))
147 rightBorder =propertyReader->readProperty(QLatin1String("border.right")).toInt();
148 if (propertyReader->hasProperty(QLatin1String("border.top")))
149 topBorder =propertyReader->readProperty(QLatin1String("border.top")).toInt();
150 if (propertyReader->hasProperty(QLatin1String("border.bottom")))
151 bottomBorder =propertyReader->readProperty(QLatin1String("border.bottom")).toInt();
152 previewDialog()->previewLabel()->setMargins(leftBorder, topBorder, rightBorder, bottomBorder);
154 if (propertyReader->hasProperty(QLatin1String("horizontalTileMode"))) {
155 QString fillMode = propertyReader->readProperty(QLatin1String("horizontalTileMode")).toString();
156 if (fillMode.contains("BorderImage."))
157 fillMode.remove("BorderImage.");
159 uiBorderImage->horizontalStretchRadioButton->setChecked(true);
161 if (fillMode == "Stretch")
162 uiBorderImage->horizontalStretchRadioButton->setChecked(true);
163 if (fillMode == "Repeat")
164 uiBorderImage->horizontalTileRadioButton->setChecked(true);
165 if (fillMode == "Round")
166 uiBorderImage->horizontalTileRadioButtonNoCrop->setChecked(true);
169 uiBorderImage->horizontalStretchRadioButton->setChecked(true);
171 if (propertyReader->hasProperty(QLatin1String("verticalTileMode"))) {
172 QString fillMode = propertyReader->readProperty(QLatin1String("verticalTileMode")).toString();
173 if (fillMode.contains("BorderImage."))
174 fillMode.remove("BorderImage.");
176 uiBorderImage->verticalStretchRadioButton->setChecked(true);
178 if (fillMode == "Stretch")
179 uiBorderImage->verticalStretchRadioButton->setChecked(true);
180 if (fillMode == "Repeat")
181 uiBorderImage->verticalTileRadioButton->setChecked(true);
182 if (fillMode == "Round")
183 uiBorderImage->verticalTileRadioButtonNoCrop->setChecked(true);
186 uiBorderImage->verticalStretchRadioButton->setChecked(true);
189 if (propertyReader->hasProperty(QLatin1String("fillMode"))) {
190 QString fillMode = propertyReader->readProperty(QLatin1String("fillMode")).toString();
191 if (fillMode.contains("Image."))
192 fillMode.remove("Image.");
194 ui->stretchRadioButton->setChecked(true);
196 if (fillMode == "Image.Tile" || fillMode == "Tile")
197 ui->tileRadioButton->setChecked(true);
198 if (fillMode == "Image.TileVertically" || fillMode == "TileVertically")
199 ui->horizontalStretchRadioButton->setChecked(true);
200 if (fillMode == "Image.TileHorizontally" || fillMode == "TileHorizontally")
201 ui->verticalStretchRadioButton->setChecked(true);
202 if (fillMode == "Image.PreserveAspectFit" || fillMode == "PreserveAspectFit")
203 ui->preserveAspectFitRadioButton->setChecked(true);
204 if (fillMode == "Image.PreserveAspectCrop" || fillMode == "PreserveAspectCrop")
205 ui->cropAspectFitRadioButton->setChecked(true);
207 ui->stretchRadioButton->setChecked(true);
210 if (propertyReader->hasProperty(QLatin1String("source"))) {
211 QString source = propertyReader->readProperty(QLatin1String("source")).toString();
212 m_fileWidget->setFileName(source);
213 if (QFile::exists(m_path + '/' + source))
214 setPixmap(m_path + '/' + source);
218 m_sizeLabel->setText("");
222 void ContextPaneWidgetImage::setPath(const QString& path)
225 m_fileWidget->setPath(QUrl::fromLocalFile(m_path));
228 void PreviewDialog::setZoom(int z)
234 m_zoomLabel->setText("100%");
235 m_slider->setValue(1);
238 m_zoomLabel->setText("200%");
239 m_slider->setValue(2);
242 m_zoomLabel->setText("400%");
243 m_slider->setValue(3);
246 m_zoomLabel->setText("600%");
247 m_slider->setValue(4);
250 m_zoomLabel->setText("800%");
251 m_slider->setValue(5);
254 m_zoomLabel->setText("1000%");
255 m_slider->setValue(6);
259 setPixmap(m_pixmap, m_zoom);
262 void PreviewDialog::setIsBorderImage(bool b)
265 m_label->setIsBorderImage(b);
268 PreviewLabel *PreviewDialog::previewLabel() const
273 void ContextPaneWidgetImage::onStretchChanged()
276 if (ui->stretchRadioButton->isChecked())
277 stretch = QLatin1String("Image.Stretch");
278 else if (ui->tileRadioButton->isChecked())
279 stretch = QLatin1String("Image.Tile");
280 else if (ui->horizontalStretchRadioButton->isChecked())
281 stretch = QLatin1String("Image.TileVertically");
282 else if (ui->verticalStretchRadioButton->isChecked())
283 stretch = QLatin1String("Image.TileHorizontally");
284 else if (ui->preserveAspectFitRadioButton->isChecked())
285 stretch = QLatin1String("Image.PreserveAspectFit");
286 else if (ui->cropAspectFitRadioButton->isChecked())
287 stretch = QLatin1String("Image.PreserveAspectCrop");
289 if (stretch == QLatin1String("Image.Stretch"))
290 emit removeProperty(QLatin1String("fillMode"));
292 emit propertyChanged(QLatin1String("fillMode"), stretch);
295 void ContextPaneWidgetImage::onHorizontalStretchChanged()
298 if (uiBorderImage->horizontalStretchRadioButton->isChecked())
299 stretch = QLatin1String("BorderImage.Stretch");
300 if (uiBorderImage->horizontalTileRadioButton->isChecked())
301 stretch = QLatin1String("BorderImage.Repeat");
302 if (uiBorderImage->horizontalTileRadioButtonNoCrop->isChecked())
303 stretch = QLatin1String("BorderImage.Round");
305 if (stretch == QLatin1String("BorderImage.Stretch"))
306 emit removeProperty(QLatin1String("horizontalTileMode"));
308 emit propertyChanged(QLatin1String("horizontalTileMode"), stretch);
311 void ContextPaneWidgetImage::onVerticalStretchChanged()
314 if (uiBorderImage->verticalStretchRadioButton->isChecked())
315 stretch = QLatin1String("BorderImage.Stretch");
316 if (uiBorderImage->verticalTileRadioButton->isChecked())
317 stretch = QLatin1String("BorderImage.Repeat");
318 if (uiBorderImage->verticalTileRadioButtonNoCrop->isChecked())
319 stretch = QLatin1String("BorderImage.Round");
321 if (stretch == QLatin1String("BorderImage.Stretch"))
322 emit removeProperty(QLatin1String("verticalTileMode"));
324 emit propertyChanged(QLatin1String("verticalTileMode"), stretch);
328 void ContextPaneWidgetImage::onFileNameChanged()
330 if (m_fileWidget->fileName().isNull())
331 emit removeProperty(QLatin1String("source"));
333 emit propertyChanged(QLatin1String("source"), QString(QLatin1Char('\"') + m_fileWidget->fileName() + QLatin1Char('\"')));
336 void ContextPaneWidgetImage::onPixmapDoubleClicked()
338 previewDialog()->setParent(parentWidget()->parentWidget());
339 previewDialog()->setMaximumSize(previewDialog()->parentWidget()->size() - QSize(150, 100));
341 previewDialog()->setZoom(4);
342 previewDialog()->setIsBorderImage(m_borderImage);
344 QPoint p = parentWidget()->pos();
345 p = p + QPoint(-2, -2);
346 previewDialog()->show();
347 previewDialog()->update();
348 previewDialog()->move(p);
349 //previewDialog()->adjustSize();
350 if ((previewDialog()->pos().x() + previewDialog()->width()) > previewDialog()->parentWidget()->width())
351 previewDialog()->move(previewDialog()->parentWidget()->width() - (previewDialog()->width()) - 40, p.y());
353 if ((previewDialog()->pos().y() + previewDialog()->height()) > previewDialog()->parentWidget()->height())
354 previewDialog()->move(previewDialog()->pos().x(), previewDialog()->parentWidget()->height() - (previewDialog()->height()) - 40);
356 if (previewDialog()->pos().x() < 0)
357 previewDialog()->move(0, previewDialog()->pos().y());
358 if (previewDialog()->pos().y() < 0)
359 previewDialog()->move(previewDialog()->pos().x(), 0);
361 previewDialog()->raise();
364 void ContextPaneWidgetImage::onLeftMarginsChanged()
366 if (previewDialog()->previewLabel()->leftMarging())
367 propertyChanged(QLatin1String("border.left"), previewDialog()->previewLabel()->leftMarging());
369 emit removeProperty(QLatin1String("border.left"));
372 void ContextPaneWidgetImage::onRightMarginsChanged()
374 if (previewDialog()->previewLabel()->rightMarging())
375 propertyChanged(QLatin1String("border.right"), previewDialog()->previewLabel()->rightMarging());
377 emit removeProperty(QLatin1String("border.right"));
382 void ContextPaneWidgetImage::onTopMarginsChanged()
384 if (previewDialog()->previewLabel()->topMarging())
385 propertyChanged(QLatin1String("border.top"), previewDialog()->previewLabel()->topMarging());
387 emit removeProperty(QLatin1String("border.top"));
390 void ContextPaneWidgetImage::onBottomMarginsChanged()
392 if (previewDialog()->previewLabel()->bottomMarging())
393 propertyChanged(QLatin1String("border.bottom"), previewDialog()->previewLabel()->bottomMarging());
395 emit removeProperty(QLatin1String("border.bottom"));
399 static inline Qt::TileRule stringToRule(const QString &s)
401 if (s == QLatin1String("Stretch"))
402 return Qt::StretchTile;
403 if (s == QLatin1String("Repeat"))
404 return Qt::RepeatTile;
405 if (s == QLatin1String("Round"))
406 return Qt::RoundTile;
408 qWarning("QDeclarativeGridScaledImage: Invalid tile rule specified. Using Stretch.");
409 return Qt::StretchTile;
412 static inline bool parseSciFile(const QString &fileName, QString &pixmapFileName, int &left, int &right, int &top, int &bottom, Qt::TileRule &horizontalTileRule, Qt::TileRule &verticalTileRule)
420 QFile data(fileName);
421 data.open(QIODevice::ReadOnly);
424 while(raw = data.readLine(), !raw.isEmpty()) {
425 QString line = QString::fromUtf8(raw.trimmed());
426 if (line.isEmpty() || line.startsWith(QLatin1Char('#')))
429 QStringList list = line.split(QLatin1Char(':'));
430 if (list.count() != 2)
433 list[0] = list[0].trimmed();
434 list[1] = list[1].trimmed();
436 if (list[0] == QLatin1String("border.left"))
438 else if (list[0] == QLatin1String("border.right"))
440 else if (list[0] == QLatin1String("border.top"))
442 else if (list[0] == QLatin1String("border.bottom"))
444 else if (list[0] == QLatin1String("source"))
446 else if (list[0] == QLatin1String("horizontalTileRule"))
447 horizontalTileRule = stringToRule(list[1]);
448 else if (list[0] == QLatin1String("verticalTileRule"))
449 verticalTileRule = stringToRule(list[1]);
452 if (l < 0 || r < 0 || t < 0 || b < 0 || imgFile.isEmpty())
455 left = l; right = r; top = t; bottom = b;
457 pixmapFileName = imgFile;
462 void ContextPaneWidgetImage::setPixmap(const QString &fileName)
468 QString localFileName(fileName);
469 if (QFile(fileName).exists()) {
470 if (fileName.endsWith(QLatin1String("sci"))) {
471 QString pixmapFileName;
477 Qt::TileRule horizontalTileRule;
478 Qt::TileRule verticalTileRule;
479 if (parseSciFile(fileName, pixmapFileName, left, right, top, bottom, horizontalTileRule, verticalTileRule)) {
480 localFileName = QFileInfo(fileName).absoluteDir().absolutePath() + '/' + pixmapFileName;
481 previewDialog()->previewLabel()->setMargins(left, top, right, bottom);
482 } else { // sci file not parsed correctly
483 uiBorderImage->sizeLabel->setText("");
487 QPixmap source(localFileName);
490 previewDialog()->setPixmap(source, previewDialog()->zoom());
491 uiBorderImage->sizeLabel->setText(QString::number(source.width()) + 'x' + QString::number(source.height()));
493 Qt::TileRule horizontalTileMode = Qt::StretchTile;
494 Qt::TileRule verticalTileMode = Qt::StretchTile;
495 if (uiBorderImage->horizontalTileRadioButton->isChecked())
496 horizontalTileMode =Qt::RepeatTile;
497 if (uiBorderImage->horizontalTileRadioButtonNoCrop->isChecked())
498 horizontalTileMode =Qt::RoundTile;
499 if (uiBorderImage->verticalTileRadioButton->isChecked())
500 verticalTileMode =Qt::RepeatTile;
501 if (uiBorderImage->verticalTileRadioButtonNoCrop->isChecked())
502 verticalTileMode =Qt::RoundTile;
503 QTileRules rules(horizontalTileMode, verticalTileMode);
504 QMargins margins(previewDialog()->previewLabel()->leftMarging() ,previewDialog()->previewLabel()->topMarging() ,previewDialog()->previewLabel()->rightMarging(), previewDialog()->previewLabel()->bottomMarging());
505 qDrawBorderPixmap(&p, QRect(0, 0, 76, 76), margins, source, source.rect(), margins, rules);
506 //p.drawPixmap(0,0,76,76, source);
508 uiBorderImage->sizeLabel->setText("");
510 uiBorderImage->label->setPixmap(pix);
512 if (QFile(fileName).exists()) {
513 QPixmap source(fileName);
514 previewDialog()->setPixmap(source, 1);
515 ui->sizeLabel->setText(QString::number(source.width()) + 'x' + QString::number(source.height()));
517 if (ui->stretchRadioButton->isChecked()) {
518 p.drawPixmap(0,0,76,76, source);
519 } else if (ui->tileRadioButton->isChecked()) {
520 QPixmap small = source.scaled(38,38);
521 p.drawTiledPixmap(0,0,76,76, small);
522 } else if (ui->horizontalStretchRadioButton->isChecked()) {
523 QPixmap small = source.scaled(38,38);
524 QPixmap half = pix.scaled(38, 76);
526 p2.drawTiledPixmap(0,0,38,76, small);
527 p.drawPixmap(0,0,76,76, half);
528 } else if (ui->verticalStretchRadioButton->isChecked()) {
529 QPixmap small = source.scaled(38,38);
530 QPixmap half = pix.scaled(76, 38);
532 p2.drawTiledPixmap(0,0,76,38, small);
533 p.drawPixmap(0,0,76,76, half);
534 } else if (ui->preserveAspectFitRadioButton->isChecked()) {
535 QPixmap preserved = source.scaledToWidth(76);
536 int offset = (76 - preserved.height()) / 2;
537 p.drawPixmap(0, offset, 76, preserved.height(), source);
538 } else if (ui->cropAspectFitRadioButton->isChecked()) {
539 QPixmap cropped = source.scaledToHeight(76);
540 int offset = (76 - cropped.width()) / 2;
541 p.drawPixmap(offset, 0, cropped.width(), 76, source);
544 ui->sizeLabel->setText("");
547 ui->label->setPixmap(pix);
552 PreviewDialog* ContextPaneWidgetImage::previewDialog()
554 if (!m_previewDialog) {
555 m_previewDialog = new PreviewDialog(this);
556 m_previewDialog->hide();
559 return m_previewDialog.data();
562 void ContextPaneWidgetImage::changeEvent(QEvent *e)
564 QWidget::changeEvent(e);
566 case QEvent::LanguageChange:
568 ui->retranslateUi(this);
570 uiBorderImage->retranslateUi(this);
578 void ContextPaneWidgetImage::hideEvent(QHideEvent * event)
580 previewWasVisible = previewDialog()->isVisible();
581 previewDialog()->hide();
582 QWidget::hideEvent(event);
585 void ContextPaneWidgetImage::showEvent(QShowEvent* event)
587 if (previewWasVisible)
588 previewDialog()->show();
589 QWidget::showEvent(event);
592 PreviewLabel::PreviewLabel(QWidget *parent)
594 m_dragging_left(false), m_dragging_right(false),
595 m_dragging_top(false), m_dragging_bottom(false)
599 m_showBorders = false;
604 setMouseTracking(true);
605 setCursor(QCursor(Qt::ArrowCursor));
606 m_hooverInfo = new QLabel(parentWidget());
607 m_hooverInfo->hide();
609 m_hooverInfo->setFrameShape(QFrame::StyledPanel);
610 m_hooverInfo->setFrameShadow(QFrame::Sunken);
612 QGraphicsDropShadowEffect *dropShadowEffect = new QGraphicsDropShadowEffect;
613 dropShadowEffect->setBlurRadius(4);
614 dropShadowEffect->setOffset(2, 2);
615 m_hooverInfo->setGraphicsEffect(dropShadowEffect);
616 m_hooverInfo->setAutoFillBackground(true);
617 m_hooverInfo->raise();
620 void PreviewLabel::setZoom(int z)
625 void PreviewLabel::setIsBorderImage(bool b)
630 void PreviewLabel::setMargins(int left, int top, int right, int bottom)
638 void PreviewLabel::paintEvent(QPaintEvent *event)
640 QLabel::paintEvent(event);
647 p.setBackgroundMode(Qt::TransparentMode);
649 QPen pen(Qt::SolidLine);
650 pen.setColor("#F0F0F0");
654 p.drawLine(m_left * m_zoom, 4, m_left * m_zoom, height() - 4);
656 p.drawLine(width() - m_right * m_zoom, 4, width() - m_right * m_zoom, height() - 4);
658 p.drawLine(4, m_top * m_zoom, width() - 4, m_top * m_zoom);
660 p.drawLine(4, height() - m_bottom * m_zoom, width() - 4, height() - m_bottom * m_zoom);
664 QBrush brush(Qt::Dense4Pattern);
665 brush.setColor("#101010");
666 QPen pen(brush, 1, Qt::DotLine);
667 pen.setColor("#101010");
671 p.drawLine(m_left * m_zoom, 4, m_left * m_zoom, height() - 4);
673 p.drawLine(width() - m_right * m_zoom, 4, width() - m_right * m_zoom, height() - 4);
675 p.drawLine(4, m_top * m_zoom, width() - 4, m_top * m_zoom);
677 p.drawLine(4, height() - m_bottom * m_zoom, width() - 4, height() - m_bottom * m_zoom);
682 static inline bool rangeCheck(int target, int pos)
684 return (target - 10 < pos) && (target + 10 > pos);
687 void PreviewLabel::mousePressEvent(QMouseEvent * event)
690 return QLabel::mouseMoveEvent(event);
692 if (event->button() == Qt::LeftButton) {
693 if (QApplication::overrideCursor())
694 QApplication::restoreOverrideCursor();
695 if (rangeCheck(m_left * m_zoom, event->pos().x())) {
696 QApplication::setOverrideCursor(QCursor(Qt::SizeHorCursor));
697 m_dragging_left = true;
699 m_hooverInfo->setText("Left " + QString::number(m_left));
700 m_hooverInfo->show();
701 } else if (rangeCheck(m_top * m_zoom, event->pos().y())) {
702 QApplication::setOverrideCursor(QCursor(Qt::SizeVerCursor));
703 m_dragging_top = true;
705 m_hooverInfo->setText("Top " + QString::number(m_top));
706 m_hooverInfo->show();
707 } else if (rangeCheck(m_right * m_zoom, width() - event->pos().x())) {
708 QApplication::setOverrideCursor(QCursor(Qt::SizeHorCursor));
709 m_dragging_right = true;
711 m_hooverInfo->setText("Right " + QString::number(m_right));
712 m_hooverInfo->show();
713 } else if (rangeCheck(m_bottom * m_zoom, height() - event->pos().y())) {
714 QApplication::setOverrideCursor(QCursor(Qt::SizeVerCursor));
715 m_dragging_bottom = true;
717 m_hooverInfo->setText("Bottom " + QString::number(m_bottom));
718 m_hooverInfo->show();
720 QLabel::mousePressEvent(event);
722 m_startPos = event->pos();
723 m_hooverInfo->move(mapToParent(event->pos()) + QPoint(0, 40));
724 m_hooverInfo->resize(m_hooverInfo->sizeHint());
725 m_hooverInfo->raise();
729 void PreviewLabel::mouseReleaseEvent(QMouseEvent * event)
732 return QLabel::mouseMoveEvent(event);
734 if (m_dragging_left || m_dragging_top || m_dragging_right|| m_dragging_bottom) {
735 m_hooverInfo->hide();
737 emit leftMarginChanged();
740 emit topMarginChanged();
742 if (m_dragging_bottom)
743 emit bottomMarginChanged();
745 if (m_dragging_right)
746 emit rightMarginChanged();
748 m_dragging_left = false;
749 m_dragging_top = false;
750 m_dragging_right = false;
751 m_dragging_bottom = false;
752 QApplication::restoreOverrideCursor();
756 QLabel::mouseReleaseEvent(event);
761 static inline int limitPositive(int i)
768 static inline int limit(int i, int zoom)
770 static bool flag1 = 1;
771 static bool flag2 = 1;
780 return flag1 ? -1 : 0;
786 return flag1 && flag2 ? -1 : 0;
794 return flag1 ? 1 : 0;
800 return flag1 && flag2 ? 1 : 0;
805 void PreviewLabel::mouseMoveEvent(QMouseEvent * event)
808 return QLabel::mouseMoveEvent(event);
810 QPoint p = event->pos();
811 if (m_dragging_left) {
812 m_left = p.x() / m_zoom;
813 m_left = limitPositive(m_left);
815 m_hooverInfo->setText("Left " + QString::number(m_left));
817 } else if (m_dragging_top) {
818 m_top = p.y() / m_zoom;
819 m_top = limitPositive(m_top);
821 m_hooverInfo->setText("Top " + QString::number(m_top));
823 } else if (m_dragging_right) {
824 m_right = (width() - p.x()) / m_zoom;
825 m_right = limitPositive(m_right);
827 m_hooverInfo->setText("Right " + QString::number(m_right));
829 } else if (m_dragging_bottom) {
830 m_bottom = (height() - p.y()) / m_zoom;
831 m_bottom = limitPositive(m_bottom);
833 m_hooverInfo->setText("Bottom " + QString::number(m_bottom));
835 } else if (rangeCheck(m_left * m_zoom, p.x())) {
836 QApplication::setOverrideCursor(QCursor(Qt::SizeHorCursor));
838 m_hooverInfo->setText("Left " + QString::number(m_left));
839 m_hooverInfo->show();
840 } else if (rangeCheck(m_top * m_zoom, p.y())) {
841 QApplication::setOverrideCursor(QCursor(Qt::SizeVerCursor));
843 m_hooverInfo->setText("Top " + QString::number(m_top));
844 m_hooverInfo->show();
845 } else if (rangeCheck(m_right * m_zoom, width() - p.x())) {
846 QApplication::setOverrideCursor(QCursor(Qt::SizeHorCursor));
848 m_hooverInfo->setText("Right " + QString::number(m_right));
849 m_hooverInfo->show();
850 } else if (rangeCheck(m_bottom * m_zoom, height() - p.y())) {
851 QApplication::setOverrideCursor(QCursor(Qt::SizeVerCursor));
853 m_hooverInfo->setText("Bottom " + QString::number(m_bottom));
854 m_hooverInfo->show();
856 if (QApplication::overrideCursor())
857 QApplication::restoreOverrideCursor();
858 QLabel::mouseMoveEvent(event);
859 m_hooverInfo->hide();
862 m_hooverInfo->move(mapToParent(p) + QPoint(0, 40));
863 m_hooverInfo->resize(m_hooverInfo->sizeHint());
864 m_hooverInfo->raise();
867 void PreviewLabel::leaveEvent(QEvent* event )
869 while (QApplication::overrideCursor())
870 QApplication::restoreOverrideCursor();
871 m_hooverInfo->hide();
872 QLabel::leaveEvent(event);
875 PreviewDialog::PreviewDialog(QWidget *parent) : DragWidget(parent)
877 m_borderImage = false;
878 setAutoFillBackground(true);
880 m_label = new PreviewLabel(this);
881 m_slider = new QSlider(this);
883 m_zoomLabel = new QLabel(this);
887 QVBoxLayout *layout = new QVBoxLayout(this);
888 QHBoxLayout *horizontalLayout = new QHBoxLayout();
889 QHBoxLayout *horizontalLayout2 = new QHBoxLayout();
890 layout->setMargin(0);
891 layout->setContentsMargins(2, 2, 2, 6);
892 layout->setSpacing(4);
893 QToolButton *toolButton = new QToolButton(this);
894 QIcon icon(style()->standardIcon(QStyle::SP_DockWidgetCloseButton));
895 toolButton->setIcon(icon);
896 toolButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
897 toolButton->setFixedSize(icon.availableSizes().value(0) + QSize(4, 4));
898 connect(toolButton, SIGNAL(clicked()), this, SLOT(onTogglePane()));
900 QScrollArea *scrollArea = new QScrollArea(this);
901 WheelFilter *wheelFilter = new WheelFilter(scrollArea);
902 scrollArea->setWidget(m_label);
903 scrollArea->setFrameStyle(QFrame::NoFrame);
904 m_slider->setOrientation(Qt::Horizontal);
905 m_slider->setRange(1, 6);
906 m_slider->setFixedWidth(80);
907 m_zoomLabel->setFixedWidth(50);
909 horizontalLayout->addWidget(toolButton);
910 horizontalLayout->addSpacing(6);
911 horizontalLayout->addWidget(m_slider);
912 horizontalLayout->addSpacing(6);
913 horizontalLayout->addWidget(m_zoomLabel);
914 horizontalLayout->addStretch(1);
916 layout->addLayout(horizontalLayout);
917 horizontalLayout2->addSpacing(24);
918 horizontalLayout2->addWidget(scrollArea);
919 layout->addLayout(horizontalLayout2);
921 wheelFilter->setTarget(this);
923 connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(onSliderMoved(int)));
925 foreach (QWidget *childWidget, findChildren<QWidget*>()) {
926 childWidget->installEventFilter(wheelFilter);
930 void PreviewDialog::setPixmap(const QPixmap &p, int zoom)
934 m_label->setPixmap(p.scaled(p.width() * zoom, p.height() * zoom));
936 m_label->setPixmap(QPixmap());
937 m_label->adjustSize();
939 m_label->setZoom(m_zoom);
940 QSize size = m_label->pixmap()->size() + QSize(54, 44);
941 if (size.width() < 180)
946 void PreviewDialog::wheelEvent(QWheelEvent* event)
948 int delta = event->delta();
953 else if (m_zoom == 2)
955 else if (m_zoom == 4)
957 else if (m_zoom == 6)
959 else if (m_zoom == 8)
964 else if (m_zoom == 8)
966 else if (m_zoom == 6)
968 else if (m_zoom == 4)
970 else if (m_zoom == 2)
973 setPixmap(m_pixmap, m_zoom);
976 void PreviewDialog::onTogglePane()
981 void PreviewDialog::onSliderMoved(int value)
984 case 1: setZoom(1); break;
985 case 2: setZoom(2); break;
986 case 3: setZoom(4); break;
987 case 4: setZoom(6); break;
988 case 5: setZoom(8); break;
989 case 6: setZoom(10); break;