Krita Source Code Documentation
Loading...
Searching...
No Matches
KisResourceItemChooser.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2 SPDX-FileCopyrightText: 2002 Patrick Julien <freak@codepimps.org>
3 SPDX-FileCopyrightText: 2007 Jan Hambrecht <jaham@gmx.net>
4 SPDX-FileCopyrightText: 2007 Sven Langkamp <sven.langkamp@gmail.com>
5 SPDX-FileCopyrightText: 2011 Srikanth Tiyyagura <srikanth.tulasiram@gmail.com>
6 SPDX-FileCopyrightText: 2011 José Luis Vergara <pentalis@gmail.com>
7 SPDX-FileCopyrightText: 2013 Sascha Suelzer <s.suelzer@gmail.com>
8
9 SPDX-License-Identifier: LGPL-2.0-or-later
10*/
12
13#include <math.h>
14
15#include <QGridLayout>
16#include <QButtonGroup>
17#include <QHeaderView>
18#include <QAbstractProxyModel>
19#include <QLabel>
20#include <QScrollArea>
21#include <QScrollBar>
22#include <QImage>
23#include <QPixmap>
24#include <QPainter>
25#include <QSplitter>
26#include <QToolButton>
27#include <QWheelEvent>
28#include <QLineEdit>
29#include <QStandardPaths>
30
31#include "ksharedconfig.h"
32#include "kconfiggroup.h"
33#include <klocalizedstring.h>
34
35#include <KoIcon.h>
36#include <KoFileDialog.h>
37#include <KisKineticScroller.h>
38#include <KisMimeDatabase.h>
39#include "KisPopupButton.h"
40
41#include <KisResourceModel.h>
44
47#include "KisTagFilterWidget.h"
48#include "KisTagChooserWidget.h"
52
54
55
56class Q_DECL_HIDDEN KisResourceItemChooser::Private
57{
58public:
59 Private(QString _resourceType)
60 : resourceType(_resourceType)
61 {}
62
63 QString resourceType;
64
65 // Top/Bottom bar
66 KisTagFilterResourceProxyModel *tagFilterProxyModel {0};
68 KisPopupButton *viewModeButton {0};
69 KisStorageChooserWidget *storagePopupButton {0};
70
71 // Resources view
73 QSplitter *resourcesSplitter {0};
74
75 QScrollArea *previewScroller {0};
76 QLabel *previewLabel {0};
77
78 // Import and Export buttons
79 QFrame* importExportBtns {0};
80 QToolButton *importButton {0};
81 QToolButton *deleteButton {0};
82 QButtonGroup *buttonGroup {0}; // does not seem to do much, maybe replace with std::array
83
84 // Custom Buttons
86
87 bool usePreview {false};
88 bool tiledPreview {false};
89 bool grayscalePreview {false};
90 bool synced {false};
91 bool updatesBlocked {false};
92
94 Layout layout = Layout::NotSet;
96 bool isResponsive = false;
97 bool showViewModeBtn = true;
98 bool showStoragePopupBtn = true;
99
100 // Horizontal Layout Widgets
101 QSplitter* horzSplitter {0};
102 QFrame* left {0};
103 QFrame* right {0};
104
105 QFrame* right2Rows {0};
106 QHBoxLayout* top {0};
107 QHBoxLayout* bot {0};
108
109 QToolButton* scroll_left {0};
110 QToolButton* scroll_right {0};
111
113};
114
115KisResourceItemChooser::KisResourceItemChooser(const QString &resourceType, bool usePreview, QWidget *parent)
116 : QWidget(parent)
117 , d(new Private(resourceType))
118{
119 // Tag manager
120 d->tagFilterProxyModel = new KisTagFilterResourceProxyModel(resourceType, this);
121 d->tagFilterProxyModel->sort(Qt::DisplayRole);
122 d->tagManager = new KisResourceTaggingManager(resourceType, d->tagFilterProxyModel, this);
123
124 // Viewmode button
125 d->viewModeButton = new KisPopupButton(this);
126 d->viewModeButton->setToolTip(i18n("Display settings"));
127 d->viewModeButton->setVisible(false);
128 d->viewModeButton->setArrowVisible(false);
129 d->viewModeButton->setAutoRaise(true);
130
131 // Storage button
132 d->storagePopupButton = new KisStorageChooserWidget(resourceType, this);
133 d->storagePopupButton->setToolTip(i18n("Storage Resources"));
134 d->storagePopupButton->setAutoRaise(true);
135 d->storagePopupButton->setArrowVisible(false);
136
137 // Resource List View
138 d->view = new KisResourceItemListView(this);
139 d->view->setObjectName("ResourceItemview");
140 d->view->setStrictSelectionMode(true);
141
142 if (d->resourceType == ResourceType::Gradients) {
143 d->view->setFixedToolTipThumbnailSize(QSize(256, 64));
144 d->view->setToolTipShouldRenderCheckers(true);
145 }
146 else if (d->resourceType == ResourceType::PaintOpPresets) {
147 d->view->setFixedToolTipThumbnailSize(QSize(128, 128));
148 }
149 else if (d->resourceType == ResourceType::Patterns || d->resourceType == ResourceType::Palettes) {
150 d->view->setToolTipShouldRenderCheckers(false);
151 d->view->setFixedToolTipThumbnailSize(QSize(256, 256));
152 }
153
154 d->view->setItemDelegate(new KisResourceItemDelegate(this));
155 d->view->setSelectionMode(QAbstractItemView::SingleSelection);
156 d->view->viewport()->installEventFilter(this);
157 d->view->setModel(d->tagFilterProxyModel);
158
159 connect(d->tagFilterProxyModel, SIGNAL(afterFilterChanged()), this, SLOT(afterFilterChanged()));
160
161 connect(d->view, SIGNAL(currentResourceChanged(QModelIndex)), this, SLOT(activate(QModelIndex)));
162 connect(d->view, SIGNAL(currentResourceClicked(QModelIndex)), this, SLOT(clicked(QModelIndex)));
163 connect(d->view, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint)));
164 connect(d->view, SIGNAL(sigSizeChanged()), this, SLOT(updateView()));
165
166 // Splitter with resource views and preview scroller
167 d->resourcesSplitter = new QSplitter(this);
168 d->resourcesSplitter->addWidget(d->view);
169 d->resourcesSplitter->setStretchFactor(0, 1);
170
171 d->usePreview = usePreview;
172 if (d->usePreview) {
173 d->previewScroller = new QScrollArea(this);
174 d->previewScroller->setWidgetResizable(true);
175 d->previewScroller->setBackgroundRole(QPalette::Dark);
176 d->previewScroller->setVisible(true);
177 d->previewScroller->setAlignment(Qt::AlignCenter);
178 d->previewLabel = new QLabel(this);
179 d->previewScroller->setWidget(d->previewLabel);
180 d->resourcesSplitter->addWidget(d->previewScroller);
181
182 if (d->resourcesSplitter->count() == 2) {
183 d->resourcesSplitter->setSizes(QList<int>() << 280 << 160);
184 }
185
186 QScroller* scroller = KisKineticScroller::createPreconfiguredScroller(d->previewScroller);
187 if (scroller) {
188 connect(scroller, SIGNAL(stateChanged(QScroller::State)), this, SLOT(slotScrollerStateChanged(QScroller::State)));
189 }
190 }
191
192 // Import and Export buttons
193 d->importButton = new QToolButton(this);
194 d->importButton->setToolTip(i18nc("@info:tooltip", "Import resource"));
195 d->importButton->setAutoRaise(true);
196 d->importButton->setEnabled(true);
197
198 d->deleteButton = new QToolButton(this);
199 d->deleteButton->setToolTip(i18nc("@info:tooltip", "Delete resource"));
200 d->deleteButton->setEnabled(false);
201 d->deleteButton->setAutoRaise(true);
202
203 d->buttonGroup = new QButtonGroup(this);
204 d->buttonGroup->setExclusive(false);
205 d->buttonGroup->addButton(d->importButton, Button_Import);
206 d->buttonGroup->addButton(d->deleteButton, Button_Remove);
207 connect(d->buttonGroup, SIGNAL(idClicked(int)), this, SLOT(slotButtonClicked(int)));
208
209 d->importExportBtns = new QFrame(this);
210 QHBoxLayout* importExportLayout = new QHBoxLayout(d->importExportBtns);
211 importExportLayout->setAlignment(Qt::AlignmentFlag::AlignLeft);
212 importExportLayout->setContentsMargins(0, 0, 0, 0);
213 importExportLayout->addWidget(d->importButton);
214 importExportLayout->addWidget(d->deleteButton);
215
216 auto removePadding = [](QLayout* layout) {
217 layout->setContentsMargins(0, 0, 0, 0);
218 layout->setSpacing(0);
219 };
220
221 // Layout
222 QGridLayout* thisLayout = new QGridLayout(this);
223 thisLayout->setObjectName("ResourceChooser this");
224 removePadding(thisLayout);
225
226 // Horizontal Layout
227 {
228 // Splitter
229 d->horzSplitter = new QSplitter(this);
230 d->horzSplitter->setOrientation(Qt::Orientation::Horizontal);
231 connect(d->horzSplitter, SIGNAL(splitterMoved(int, int)), this, SLOT(slotSaveSplitterState()));
232
233 // Horizontal 1 row
234 d->left = new QFrame(this);
235 QSizePolicy newPolicy = d->left->sizePolicy();
236 newPolicy.setHorizontalStretch(2);
237 d->left->setSizePolicy(newPolicy);
238 QHBoxLayout* leftLayout = new QHBoxLayout(d->left);
239 leftLayout->setObjectName("ResourceChooser left");
240
241 d->right = new QFrame(this);
242 newPolicy = d->right->sizePolicy();
243 newPolicy.setHorizontalStretch(0);
244 d->right->setSizePolicy(newPolicy);
245 QHBoxLayout* rightLayout = new QHBoxLayout(d->right);
246 rightLayout->setObjectName("ResourceChooser right");
247
248 // Horizontal 2 rows
249 d->right2Rows = new QFrame(this);
250 newPolicy = d->right2Rows->sizePolicy();
251 newPolicy.setHorizontalStretch(0);
252 d->right2Rows->setSizePolicy(newPolicy);
253 QVBoxLayout* rightLayout2 = new QVBoxLayout(d->right2Rows);
254 rightLayout2->setObjectName("ResourceChooser right 2 rows");
255
256 d->top = new QHBoxLayout();
257 d->bot = new QHBoxLayout();
258 rightLayout2->addLayout(d->top);
259 rightLayout2->addLayout(d->bot);
260
261 // Common style
262 removePadding(leftLayout);
263 removePadding(rightLayout);
264 removePadding(rightLayout2);
265 removePadding(d->top);
266 removePadding(d->bot);
267
268 // Scroll buttons
269 d->scroll_left = new QToolButton(this);
270 d->scroll_left->setIcon(KisIconUtils::loadIcon("draw-arrow-back"));
271 connect(d->scroll_left, &QToolButton::clicked, this, &KisResourceItemChooser::scrollBackwards);
272 d->scroll_right = new QToolButton(this);
273 d->scroll_right->setIcon(KisIconUtils::loadIcon("draw-arrow-forward"));
274 connect(d->scroll_right, &QToolButton::clicked, this, &KisResourceItemChooser::scrollForwards);
275
276 // Hide
277 d->scroll_left->hide();
278 d->scroll_right->hide();
279 d->left->hide();
280 d->right->hide();
281 d->right2Rows->hide();
282 d->horzSplitter->hide();
283 }
284
285 // Other
286 updateView();
287
288 // Default Configuration
290 showViewModeBtn(false);
291 showTaggingBar(false);
294}
295
297{
298 disconnect();
299 delete d;
300}
301
303{
304 if (isResponsive) {
305
306 if (d->isResponsive == false) {
307 d->isResponsive = true;
309 }
310 else {
311 d->isResponsive = true;
312 }
313 }
314 else {
315 d->isResponsive = false;
316 }
317}
318
320{
321 d->requestedViewMode = newViewMode;
322 if (d->layout == Layout::NotSet || d->layout == Layout::Vertical) {
323 d->view->setListViewMode(newViewMode);
324 }
325}
326
328{
329 return d->tagFilterProxyModel;
330}
331
333{
334 if (button == Button_Import) {
335 QStringList mimeTypes = KisResourceLoaderRegistry::instance()->mimeTypes(d->resourceType);
336 KoFileDialog dialog(0, KoFileDialog::OpenFiles, "OpenDocument");
337 dialog.setMimeTypeFilters(mimeTypes);
338 dialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
339 dialog.setCaption(i18nc("@title:window", "Choose File to Add"));
340 Q_FOREACH(const QString &filename, dialog.filenames()) {
341 if (QFileInfo(filename).exists() && QFileInfo(filename).isReadable()) {
342
343 KoResourceSP previousResource = this->currentResource();
344 KoResourceSP newResource = KisResourceUserOperations::importResourceFileWithUserInput(this, "", d->resourceType, filename);
345
346 if (previousResource && newResource && !currentResource()) {
349 setCurrentResource(newResource);
350 } else if (currentResource() == newResource) {
355 const QModelIndex index = d->tagFilterProxyModel->indexForResource(newResource);
356 updatePreview(index);
357 }
358 }
359 }
360 tagFilterModel()->sort(Qt::DisplayRole);
361 }
362 else if (button == Button_Remove) {
363 QModelIndex index = d->view->currentIndex();
364 if (index.isValid()) {
365 d->tagFilterProxyModel->setResourceInactive(index);
366 }
367 int row = index.row();
368 int rowMin = --row;
369 row = qBound(0, rowMin, row);
370 setCurrentItem(row);
371 activate(d->tagFilterProxyModel->index(row, index.column()));
372 }
374}
375
377{
378 // assert(show == false);
379 if (show) {
380 d->importExportBtns->show();
381 }
382 else {
383 d->importExportBtns->hide();
384 }
385}
386
388{
389 d->tagManager->showTaggingBar(show);
390}
391
393{
394 d->view->setItemSize(QSize(d->view->gridSize().width(), rowHeight));
395}
396
398{
399 d->view->setItemSize(QSize(columnWidth, d->view->gridSize().height()));
400}
401
402void KisResourceItemChooser::setItemDelegate(QAbstractItemDelegate *delegate)
403{
404 d->view->setItemDelegate(delegate);
405}
406
408{
409 if (includeHidden || d->view->selectionModel()->isSelected(d->view->currentIndex())) {
410 return d->currentResource;
411 }
412
413 return nullptr;
414}
415
417{
418 // don't update if the change came from the same chooser
419 if (d->updatesBlocked) {
420 return;
421 }
422 QModelIndex index = d->tagFilterProxyModel->indexForResource(resource);
423 d->view->setCurrentIndex(index);
424
425 // The resource may currently be filtered out, but we want to be able
426 // to select it if the filter changes and includes the resource.
427 // Otherwise, activate() already took care of setting the current resource.
428 if (!index.isValid()) {
429 d->currentResource = resource;
430 }
431 updatePreview(index);
432}
433
435{
436 // don't update if the change came from the same chooser
437 if (d->updatesBlocked) {
438 return;
439 }
440
441 for (int row = 0; row < d->tagFilterProxyModel->rowCount(); row++) {
442 for (int col = 0; col < d->tagFilterProxyModel->columnCount(); col++) {
443 QModelIndex index = d->tagFilterProxyModel->index(row, col);
444 KoResourceSP resource = d->tagFilterProxyModel->resourceForIndex(index);
445
446 if (resource->name() == resourceName) {
447 d->view->setCurrentIndex(index);
448
449 // The resource may currently be filtered out, but we want to be able
450 // to select it if the filter changes and includes the resource.
451 // Otherwise, activate() already took care of setting the current resource.
452 if (!index.isValid()) {
453 d->currentResource = resource;
454 }
455 updatePreview(index);
456 }
457 }
458 }
459}
460
461void KisResourceItemChooser::setPreviewOrientation(Qt::Orientation orientation)
462{
463 d->resourcesSplitter->setOrientation(orientation);
464}
465
467{
468 d->tiledPreview = tiled;
469}
470
472{
473 d->grayscalePreview = grayscale;
474}
475
477{
478 QModelIndex index = d->view->model()->index(row, 0);
479 if (!index.isValid())
480 return;
481
482 d->view->setCurrentIndex(index);
483 if (index.isValid()) {
484 updatePreview(index);
485 }
486}
487
489{
490 QScrollBar* bar = d->view->horizontalScrollBar();
491 bar->setValue(bar->value() - d->view->gridSize().width());
492}
493
495{
496 QScrollBar* bar = d->view->horizontalScrollBar();
497 bar->setValue(bar->value() + d->view->gridSize().width());
498}
499
500void KisResourceItemChooser::activate(const QModelIndex &index)
501{
502 if (!index.isValid())
503 {
505 return;
506 }
507
508 KoResourceSP resource = resourceFromModelIndex(index);
509
510 if (resource && resource->valid()) {
511 if (resource != d->currentResource) {
512 d->currentResource = resource;
513 d->updatesBlocked = true;
514 Q_EMIT resourceSelected(resource);
515 d->updatesBlocked = false;
516 }
517 updatePreview(index);
519 }
520}
521
522void KisResourceItemChooser::clicked(const QModelIndex &index)
523{
524 Q_UNUSED(index);
525
526 KoResourceSP resource = currentResource();
527 if (resource) {
528 Q_EMIT resourceClicked(resource);
529 }
530}
531
533{
534 QAbstractButton *removeButton = d->buttonGroup->button(Button_Remove);
535 if (! removeButton)
536 return;
537
538 KoResourceSP resource = currentResource();
539 if (resource) {
540 removeButton->setEnabled(!resource->permanent());
541 return;
542 }
543 removeButton->setEnabled(false);
544}
545
546void KisResourceItemChooser::updatePreview(const QModelIndex &idx)
547{
548 if (!d->usePreview) return;
549
550 if (!idx.isValid()) {
551 d->previewLabel->setPixmap(QPixmap());
552 return;
553 }
554
555 QImage image = idx.data(Qt::UserRole + KisAbstractResourceModel::Thumbnail).value<QImage>();
556
557 if (image.format() != QImage::Format_RGB32 &&
558 image.format() != QImage::Format_ARGB32 &&
559 image.format() != QImage::Format_ARGB32_Premultiplied) {
560
561 image.convertTo(QImage::Format_ARGB32_Premultiplied);
562 }
563
564 if (d->tiledPreview) {
565 int width = d->previewScroller->width() * 4 * devicePixelRatioF();
566 int height = d->previewScroller->height() * 4 * devicePixelRatioF();
567 QImage img(width, height, image.format());
568 QPainter gc(&img);
569 gc.fillRect(img.rect(), Qt::white);
570 gc.setPen(Qt::NoPen);
571 gc.setBrush(QBrush(image));
572 gc.drawRect(img.rect());
573 image = img;
574 }
575
576 // Only convert to grayscale if it is rgb. Otherwise, it's gray already.
577 if (d->grayscalePreview && !image.isGrayscale()) {
578 QRgb *pixel = reinterpret_cast<QRgb *>(image.bits());
579 for (int row = 0; row < image.height(); ++row) {
580 for (int col = 0; col < image.width(); ++col) {
581 const QRgb currentPixel = pixel[row * image.width() + col];
582 const int red = qRed(currentPixel);
583 const int green = qGreen(currentPixel);
584 const int blue = qBlue(currentPixel);
585 const int grayValue = (red * 11 + green * 16 + blue * 5) / 32;
586 pixel[row * image.width() + col] = qRgb(grayValue, grayValue, grayValue);
587 }
588 }
589 }
590 image.setDevicePixelRatio(devicePixelRatioF());
591 d->previewLabel->setPixmap(QPixmap::fromImage(image));
592}
593
595{
596 if (!index.isValid()) {
597 return 0;
598 }
599 KoResourceSP r = d->tagFilterProxyModel->resourceForIndex(index);
600 return r;
601}
602
604{
605 return d->view->size();
606}
607
609{
610 return d->view;
611}
612
614{
615 d->tagManager->contextMenuRequested(currentResource(), pos);
616}
617
619{
620 d->storagePopupButton->setVisible(visible);
621 d->showStoragePopupBtn = visible;
622}
623
625{
626 d->viewModeButton->setVisible(visible);
627 d->showViewModeBtn = visible;
628}
629
631{
632 return d->viewModeButton;
633}
634
636{
637 if (d->synced == sync)
638 return;
639
640 d->synced = sync;
642 if (sync) {
643 connect(chooserSync, SIGNAL(baseLengthChanged(int)), SLOT(baseLengthChanged(int)));
644 baseLengthChanged(chooserSync->baseLength());
645 } else {
646 chooserSync->disconnect(this);
647 }
648}
649
651{
652 if (d->synced) {
653 d->view->setItemSize(QSize(length, length));
654 }
655}
656
658{
659 // Note: Item model reset events silently reset the view's selection model too.
660 // This currently only covers models resets as part of filter changes.
661 QModelIndex idx = d->tagFilterProxyModel->indexForResource(d->currentResource);
662
663 if (idx.isValid()) {
664 d->view->setCurrentIndex(idx);
665 }
666
668}
669
670bool KisResourceItemChooser::eventFilter(QObject *object, QEvent *event)
671{
672 if (d->synced && event->type() == QEvent::Wheel) {
674 QWheelEvent *qwheel = static_cast<QWheelEvent *>(event);
675 if (qwheel->modifiers() & Qt::ControlModifier) {
676
677 int degrees = qwheel->angleDelta().y() / 8;
678 int newBaseLength = chooserSync->baseLength() + degrees / 15 * 10;
679 chooserSync->setBaseLength(newBaseLength);
680 return true;
681 }
682 }
683 return QObject::eventFilter(object, event);
684}
685
686
687void KisResourceItemChooser::resizeEvent(QResizeEvent *event)
688{
689 QWidget::resizeEvent(event);
691 updateView();
692 updatePreview(d->view->currentIndex());
693}
694
696{
697 QWidget::showEvent(event);
698 updateView();
699 updatePreview(d->view->currentIndex());
700}
701
703{
704 d->horzSplitter->hide();
705 d->left->hide();
706 d->right->hide();
707 d->right2Rows->hide();
708 d->scroll_left->hide();
709 d->scroll_right->hide();
710
711 d->viewModeButton->hide();
712}
713
715{
716 if (d->layout == Layout::Vertical) {
717 return;
718 }
719
721
722 d->view->setListViewMode(d->requestedViewMode);
723 Q_EMIT listViewModeChanged(d->requestedViewMode);
724
725 // The horizontal layouts size the items based widget height not user configured base length
726 // so it needs to be restored when switching back to vertical layout
728 d->view->setItemSize(QSize(chooserSync->baseLength(), chooserSync->baseLength()));
729
730 QGridLayout* thisLayout = dynamic_cast<QGridLayout*>(layout());
731 thisLayout->addWidget(d->tagManager->tagChooserWidget(), 0, 0);
732 thisLayout->addWidget(d->viewModeButton, 0, 1);
733 thisLayout->addWidget(d->storagePopupButton, 0, 2);
734 thisLayout->addWidget(d->resourcesSplitter, 1, 0, 1, 3);
735 thisLayout->setRowStretch(1, 1);
736 thisLayout->addWidget(d->tagManager->tagFilterWidget(), 2, 0, 1, 3);
737 thisLayout->addWidget(d->importExportBtns, 3, 0, 1, 3);
738
739 d->viewModeButton->setVisible(d->showViewModeBtn);
740 d->storagePopupButton->setVisible(d->showStoragePopupBtn);
741
742 d->viewModeButton->setVisible(d->showViewModeBtn);
743 d->layout = Layout::Vertical;
744}
745
747{
748 if (d->isResponsive == false) {
749 return;
750 }
751 // Responsive Layout
752 else {
753 // Vertical
754 if (height() > 100) {
756 }
757 // Horizontal 2 rows
758 else if (height() > 60) {
759
760 if (d->layout == Layout::Horizontal2Rows) {
761 return;
762 }
763
765
766 d->view->setListViewMode(ListViewMode::IconStripHorizontal);
768
769 // Left
770 QLayout* leftLayout = d->left->layout();
771 leftLayout->addWidget(d->resourcesSplitter);
772
773 // Right Top
774 d->top->addWidget(d->scroll_left);
775 d->top->addWidget(d->scroll_right);
776 d->top->addWidget(d->tagManager->tagChooserWidget());
777 d->top->addWidget(d->importExportBtns);
778
779 // Right Bot
780 d->bot->addWidget(d->viewModeButton);
781 d->bot->addWidget(d->storagePopupButton);
782 d->bot->addWidget(d->tagManager->tagFilterWidget());
783
784 d->horzSplitter->addWidget(d->left);
785 d->horzSplitter->addWidget(d->right2Rows);
786
787 QGridLayout* thisLayout = dynamic_cast<QGridLayout*>(layout());
788 thisLayout->addWidget(d->horzSplitter, 0, 0);
789 thisLayout->setRowStretch(0, 2);
790 thisLayout->setColumnStretch(0, 2);
791 thisLayout->setRowStretch(1, 0);
792
793 d->viewModeButton->setVisible(false);
794 d->storagePopupButton->setVisible(d->showStoragePopupBtn);
795
796 const bool splitterRestored = d->restoreSplitterState(Layout::Horizontal2Rows);
797
798 d->horzSplitter->show();
799 d->left->show();
800 d->scroll_left->show();
801 d->scroll_right->show();
802 d->right2Rows->show();
803
804 d->layout = Layout::Horizontal2Rows;
805
806 if (!splitterRestored) {
808 }
809 }
810 // Horizontal 1 row
811 else {
812 if (d->layout == Layout::Horizontal1Row) {
813 return;
814 }
815
817
818 d->view->setListViewMode(ListViewMode::IconStripHorizontal);
820
821 QLayout* leftLayout = d->left->layout();
822 leftLayout->addWidget(d->resourcesSplitter);
823 leftLayout->addWidget(d->scroll_left);
824 leftLayout->addWidget(d->scroll_right);
825
826 QLayout* rightLayout = d->right->layout();
827 rightLayout->addWidget(d->tagManager->tagChooserWidget());
828 rightLayout->addWidget(d->viewModeButton);
829 rightLayout->addWidget(d->storagePopupButton);
830 rightLayout->addWidget(d->tagManager->tagFilterWidget());
831 rightLayout->addWidget(d->importExportBtns);
832
833 d->horzSplitter->addWidget(d->left);
834 d->horzSplitter->addWidget(d->right);
835
836 QGridLayout* thisLayout = dynamic_cast<QGridLayout*>(layout());
837 thisLayout->addWidget(d->horzSplitter, 0, 0);
838 thisLayout->setRowStretch(0, 2);
839 thisLayout->setColumnStretch(0, 2);
840 thisLayout->setRowStretch(1, 0);
841
842 d->viewModeButton->setVisible(false);
843 d->storagePopupButton->setVisible(d->showStoragePopupBtn);
844
845 const bool splitterRestored = d->restoreSplitterState(Layout::Horizontal1Row);
846
847 d->horzSplitter->show();
848 d->left->show();
849 d->scroll_left->show();
850 d->scroll_right->show();
851 d->right->show();
852
853 d->layout = Layout::Horizontal1Row;
854
855 if (!splitterRestored) {
857 }
858 }
859 }
860}
861
862bool KisResourceItemChooser::Private::restoreSplitterState(Layout layout)
863{
864 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(layout > Layout::Vertical, false);
865
866 KConfigGroup group = KSharedConfig::openConfig()->group(QString("KisResourceItemChooser_%1").arg(resourceType));
867
868 const QLatin1String key(
869 layout == Layout::Horizontal1Row ? "splitterState_1row" : "splitterState_2row");
870
871 bool splitterRestored = false;
872 QByteArray state = group.readEntry(key, QByteArray());
873 if (!state.isEmpty()) {
874 splitterRestored = horzSplitter->restoreState(state);
875 KIS_SAFE_ASSERT_RECOVER_NOOP(splitterRestored);
876 }
877
878 return splitterRestored;
879}
880
882{
883 if (d->layout > Layout::Vertical) {
884 KConfigGroup group = KSharedConfig::openConfig()->group(QString("KisResourceItemChooser_%1").arg(d->resourceType));
885 const QByteArray state = d->horzSplitter->saveState();
886
887 const QLatin1String key(
888 d->layout == Layout::Horizontal1Row ? "splitterState_1row" : "splitterState_2row");
889
890 group.writeEntry(key, state);
891 }
892}
893
895{
897 d->viewModeButton->setIcon(KisIconUtils::loadIcon("view-choose"));
898 d->importButton->setIcon(koIcon("document-import-16"));
899 d->deleteButton->setIcon(koIcon("edit-delete"));
900 d->storagePopupButton->setIcon(koIcon("bundle_archive"));
901 d->tagManager->tagChooserWidget()->updateIcons();
902}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void setPreviewOrientation(Qt::Orientation orientation)
determines whether the preview right or below the splitter
void setPreviewTiled(bool tiled)
determines whether the preview should tile the resource's image or not
void setCurrentResource(KoResourceSP resource)
Sets the item representing the resource as selected.
KisResourceItemChooser(const QString &resourceType, bool usePreview=false, QWidget *parent=0)
void contextMenuRequested(const QPoint &pos)
void updatePreview(const QModelIndex &idx)
void setListViewMode(ListViewMode viewMode)
bool eventFilter(QObject *object, QEvent *event) override
Allows zooming with Ctrl + Mouse Wheel.
void clicked(const QModelIndex &index)
bool restoreSplitterState(Layout layout)
void setColumnWidth(int columnWidth)
Sets the width of the view columns.
void slotScrollerStateChanged(QScroller::State state)
void listViewModeChanged(ListViewMode newViewMode)
Emitted when the view mode for the internal KisResourceItemListView changes.
QSize viewSize() const
View size for the resources view.
void setGrayscalePreview(bool grayscale)
shows the preview converted to grayscale
void resizeEvent(QResizeEvent *event) override
void setResponsiveness(bool isResponsive)
KisResourceItemListView * itemView() const
KoResourceSP resourceFromModelIndex(const QModelIndex &index) const
QList< QAbstractButton * > customButtons
void resourceSelected(KoResourceSP resource)
Emitted when a resource was selected.
void setRowHeight(int rowHeight)
Sets the height of the view rows.
void showEvent(QShowEvent *event) override
Private(QString _resourceType)
KisTagFilterResourceProxyModel * tagFilterModel() const
void activate(const QModelIndex &index)
void resourceClicked(KoResourceSP resource)
void setItemDelegate(QAbstractItemDelegate *delegate)
Sets a custom delegate for the view.
The resource item delegate for rendering the resource preview.
static KisResourceLoaderRegistry * instance()
QStringList mimeTypes(const QString &resourceType) const
The KisResourceTaggingManager class is a helper class for KisResourceItemChooser for tagChooser and t...
static KoResourceSP importResourceFileWithUserInput(QWidget *widgetParent, QString storageLocation, QString resourceType, QString resourceFilepath)
The KisTagFilterResourceProxyModel class filters the resources by tag or resource name.
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
unsigned int QRgb
#define koIcon(name)
Use these macros for icons without any issues.
Definition kis_icon.h:25
QString button(const QWheelEvent &ev)
QIcon loadIcon(const QString &name)
KRITAWIDGETUTILS_EXPORT QScroller * createPreconfiguredScroller(QAbstractScrollArea *target)
const QString Palettes
const QString Patterns
const QString Gradients
const QString PaintOpPresets
static KisResourceItemChooserSync * instance()