Warning, file /office/calligra/libs/widgets/KoResourcePopupAction.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 * Made by Tomislav Lukman (tomislav.lukman@ck.tel.hr) 0003 * Copyright (C) 2012 Jean-Nicolas Artaud <jeannicolasartaud@gmail.com> 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Library General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Library General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Library General Public License 0016 * along with this library; see the file COPYING.LIB. If not, write to 0017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "KoResourcePopupAction.h" 0022 0023 #include "KoResourceServerAdapter.h" 0024 #include "KoResourceItemView.h" 0025 #include "KoResourceModel.h" 0026 #include "KoResourceItemDelegate.h" 0027 #include "KoResource.h" 0028 #include "KoCheckerBoardPainter.h" 0029 #include "KoShapeBackground.h" 0030 #include <KoAbstractGradient.h> 0031 #include <KoPattern.h> 0032 #include <KoGradientBackground.h> 0033 #include <KoPatternBackground.h> 0034 #include <KoImageCollection.h> 0035 0036 #include <QMenu> 0037 #include <QHBoxLayout> 0038 #include <QHeaderView> 0039 #include <QPainter> 0040 #include <QGradient> 0041 #include <QToolButton> 0042 #include <QRect> 0043 #include <QWidgetAction> 0044 0045 #include <utility> 0046 0047 class KoResourcePopupAction::Private 0048 { 0049 public: 0050 Private() : resourceList(0), background(0), checkerPainter(4) 0051 {} 0052 QMenu *menu; 0053 KoResourceItemView *resourceList; 0054 QSharedPointer<KoShapeBackground> background; 0055 KoCheckerBoardPainter checkerPainter; 0056 }; 0057 0058 KoResourcePopupAction::KoResourcePopupAction(QSharedPointer<KoAbstractResourceServerAdapter>resourceAdapter, QObject *parent) 0059 : QAction(parent) 0060 , d(new Private()) 0061 { 0062 Q_ASSERT(resourceAdapter); 0063 0064 d->menu = new QMenu(); 0065 QWidget *widget = new QWidget(); 0066 QWidgetAction *wdgAction = new QWidgetAction(this); 0067 0068 d->resourceList = new KoResourceItemView(widget); 0069 d->resourceList->setModel(new KoResourceModel(resourceAdapter, widget)); 0070 d->resourceList->setItemDelegate(new KoResourceItemDelegate(widget)); 0071 KoResourceModel * resourceModel = qobject_cast<KoResourceModel*>(d->resourceList->model()); 0072 if (resourceModel) { 0073 resourceModel->setColumnCount(1); 0074 } 0075 0076 KoResource *resource = 0; 0077 if (resourceAdapter->resources().count() > 0) { 0078 resource = resourceAdapter->resources().at(0); 0079 } 0080 0081 KoAbstractGradient *gradient = dynamic_cast<KoAbstractGradient*>(resource); 0082 KoPattern *pattern = dynamic_cast<KoPattern*>(resource); 0083 if (gradient) { 0084 QGradient *qg = gradient->toQGradient(); 0085 qg->setCoordinateMode(QGradient::ObjectBoundingMode); 0086 d->background = QSharedPointer<KoShapeBackground>(new KoGradientBackground(qg)); 0087 } else if (pattern) { 0088 KoImageCollection *collection = new KoImageCollection(); 0089 d->background = QSharedPointer<KoShapeBackground>(new KoPatternBackground(collection)); 0090 static_cast<KoPatternBackground*>(d->background.data())->setPattern(pattern->pattern()); 0091 } 0092 0093 QHBoxLayout *layout = new QHBoxLayout(widget); 0094 layout->addWidget(d->resourceList); 0095 widget->setLayout(layout); 0096 0097 wdgAction->setDefaultWidget(widget); 0098 d->menu->addAction(wdgAction); 0099 setMenu(d->menu); 0100 new QHBoxLayout(d->menu); 0101 d->menu->layout()->addWidget(widget); 0102 d->menu->layout()->setMargin(0); 0103 0104 connect(d->resourceList, SIGNAL(clicked(QModelIndex)), this, SLOT(indexChanged(QModelIndex))); 0105 0106 updateIcon(); 0107 } 0108 0109 KoResourcePopupAction::~KoResourcePopupAction() 0110 { 0111 /* Removing the actions here make them be deleted together with their default widget. 0112 * This happens only if the actions are QWidgetAction, and we know they are since 0113 * the only ones added are in KoResourcePopupAction constructor. */ 0114 int i = 0; 0115 while(!d->menu->actions().empty()) { 0116 d->menu->removeAction(d->menu->actions().at(i)); 0117 ++i; 0118 } 0119 0120 delete d->menu; 0121 0122 delete d; 0123 } 0124 0125 QSharedPointer<KoShapeBackground> KoResourcePopupAction::currentBackground() const 0126 { 0127 return d->background; 0128 } 0129 0130 void KoResourcePopupAction::setCurrentBackground(QSharedPointer<KoShapeBackground> background) 0131 { 0132 d->background = std::move(background); 0133 0134 updateIcon(); 0135 } 0136 0137 0138 void KoResourcePopupAction::indexChanged(const QModelIndex &modelIndex) 0139 { 0140 if (! modelIndex.isValid()) { 0141 return; 0142 } 0143 0144 d->menu->hide(); 0145 0146 KoResource *resource = static_cast<KoResource*>(modelIndex.internalPointer()); 0147 if(resource) { 0148 KoAbstractGradient *gradient = dynamic_cast<KoAbstractGradient*>(resource); 0149 KoPattern *pattern = dynamic_cast<KoPattern*>(resource); 0150 if (gradient) { 0151 QGradient *qg = gradient->toQGradient(); 0152 qg->setCoordinateMode(QGradient::ObjectBoundingMode); 0153 d->background = QSharedPointer<KoShapeBackground>(new KoGradientBackground(qg)); 0154 } else if (pattern) { 0155 KoImageCollection *collection = new KoImageCollection(); 0156 d->background = QSharedPointer<KoShapeBackground>(new KoPatternBackground(collection)); 0157 qSharedPointerDynamicCast<KoPatternBackground>(d->background)->setPattern(pattern->pattern()); 0158 } 0159 0160 emit resourceSelected(d->background); 0161 0162 updateIcon(); 0163 } 0164 } 0165 0166 void KoResourcePopupAction::updateIcon() 0167 { 0168 QSize iconSize; 0169 QToolButton *toolButton = dynamic_cast<QToolButton*>(parentWidget()); 0170 if (toolButton) { 0171 iconSize = QSize(toolButton->iconSize()); 0172 } else { 0173 iconSize = QSize(16, 16); 0174 } 0175 0176 // This must be a QImage, as drawing to a QPixmap outside the 0177 // UI thread will cause sporadic crashes. 0178 QImage pm = QImage(iconSize, QImage::Format_ARGB32_Premultiplied); 0179 0180 pm.fill(Qt::transparent); 0181 0182 QPainter p(&pm); 0183 QSharedPointer<KoGradientBackground> gradientBackground = qSharedPointerDynamicCast<KoGradientBackground>(d->background); 0184 QSharedPointer<KoPatternBackground> patternBackground = qSharedPointerDynamicCast<KoPatternBackground>(d->background); 0185 0186 if (gradientBackground) { 0187 QRect innerRect(0, 0, iconSize.width(), iconSize.height()); 0188 QLinearGradient paintGradient; 0189 paintGradient.setStops(gradientBackground->gradient()->stops()); 0190 paintGradient.setStart(innerRect.topLeft()); 0191 paintGradient.setFinalStop(innerRect.topRight()); 0192 0193 d->checkerPainter.paint(p, innerRect); 0194 p.fillRect(innerRect, QBrush(paintGradient)); 0195 } else if (patternBackground) { 0196 d->checkerPainter.paint(p, QRect(QPoint(),iconSize)); 0197 p.fillRect(0, 0, iconSize.width(), iconSize.height(), patternBackground->pattern()); 0198 } 0199 0200 p.end(); 0201 0202 setIcon(QIcon(QPixmap::fromImage(pm))); 0203 }