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
300
302{
303 if (isResponsive) {
304
305 if (d->isResponsive == false) {
306 d->isResponsive = true;
308 }
309 else {
310 d->isResponsive = true;
311 }
312 }
313 else {
314 d->isResponsive = false;
315 }
316}
317
319{
320 d->requestedViewMode = newViewMode;
321 if (d->layout == Layout::NotSet || d->layout == Layout::Vertical) {
322 d->view->setListViewMode(newViewMode);
323 }
324}
325
327{
328 return d->tagFilterProxyModel;
329}
330
332{
333 if (button == Button_Import) {
334 QStringList mimeTypes = KisResourceLoaderRegistry::instance()->mimeTypes(d->resourceType);
335 KoFileDialog dialog(0, KoFileDialog::OpenFiles, "OpenDocument");
336 dialog.setMimeTypeFilters(mimeTypes);
337 dialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
338 dialog.setCaption(i18nc("@title:window", "Choose File to Add"));
339 Q_FOREACH(const QString &filename, dialog.filenames()) {
340 if (QFileInfo(filename).exists() && QFileInfo(filename).isReadable()) {
341
342 KoResourceSP previousResource = this->currentResource();
343 KoResourceSP newResource = KisResourceUserOperations::importResourceFileWithUserInput(this, "", d->resourceType, filename);
344
345 if (previousResource && newResource && !currentResource()) {
348 setCurrentResource(newResource);
349 } else if (currentResource() == newResource) {
354 const QModelIndex index = d->tagFilterProxyModel->indexForResource(newResource);
355 updatePreview(index);
356 }
357 }
358 }
359 tagFilterModel()->sort(Qt::DisplayRole);
360 }
361 else if (button == Button_Remove) {
362 QModelIndex index = d->view->currentIndex();
363 if (index.isValid()) {
364 d->tagFilterProxyModel->setResourceInactive(index);
365 }
366 int row = index.row();
367 int rowMin = --row;
368 row = qBound(0, rowMin, row);
369 setCurrentItem(row);
370 activate(d->tagFilterProxyModel->index(row, index.column()));
371 }
373}
374
376{
377 // assert(show == false);
378 if (show) {
379 d->importExportBtns->show();
380 }
381 else {
382 d->importExportBtns->hide();
383 }
384}
385
387{
388 d->tagManager->showTaggingBar(show);
389}
390
392{
393 d->view->setItemSize(QSize(d->view->gridSize().width(), rowHeight));
394}
395
397{
398 d->view->setItemSize(QSize(columnWidth, d->view->gridSize().height()));
399}
400
401void KisResourceItemChooser::setItemDelegate(QAbstractItemDelegate *delegate)
402{
403 d->view->setItemDelegate(delegate);
404}
405
407{
408 if (includeHidden || d->view->selectionModel()->isSelected(d->view->currentIndex())) {
409 return d->currentResource;
410 }
411
412 return nullptr;
413}
414
416{
417 // don't update if the change came from the same chooser
418 if (d->updatesBlocked) {
419 return;
420 }
421 QModelIndex index = d->tagFilterProxyModel->indexForResource(resource);
422 d->view->setCurrentIndex(index);
423
424 // The resource may currently be filtered out, but we want to be able
425 // to select it if the filter changes and includes the resource.
426 // Otherwise, activate() already took care of setting the current resource.
427 if (!index.isValid()) {
428 d->currentResource = resource;
429 }
430 updatePreview(index);
431}
432
434{
435 // don't update if the change came from the same chooser
436 if (d->updatesBlocked) {
437 return;
438 }
439
440 for (int row = 0; row < d->tagFilterProxyModel->rowCount(); row++) {
441 for (int col = 0; col < d->tagFilterProxyModel->columnCount(); col++) {
442 QModelIndex index = d->tagFilterProxyModel->index(row, col);
443 KoResourceSP resource = d->tagFilterProxyModel->resourceForIndex(index);
444
445 if (resource->name() == resourceName) {
446 d->view->setCurrentIndex(index);
447
448 // The resource may currently be filtered out, but we want to be able
449 // to select it if the filter changes and includes the resource.
450 // Otherwise, activate() already took care of setting the current resource.
451 if (!index.isValid()) {
452 d->currentResource = resource;
453 }
454 updatePreview(index);
455 }
456 }
457 }
458}
459
460void KisResourceItemChooser::setPreviewOrientation(Qt::Orientation orientation)
461{
462 d->resourcesSplitter->setOrientation(orientation);
463}
464
466{
467 d->tiledPreview = tiled;
468}
469
471{
472 d->grayscalePreview = grayscale;
473}
474
476{
477 QModelIndex index = d->view->model()->index(row, 0);
478 if (!index.isValid())
479 return;
480
481 d->view->setCurrentIndex(index);
482 if (index.isValid()) {
483 updatePreview(index);
484 }
485}
486
488{
489 QScrollBar* bar = d->view->horizontalScrollBar();
490 bar->setValue(bar->value() - d->view->gridSize().width());
491}
492
494{
495 QScrollBar* bar = d->view->horizontalScrollBar();
496 bar->setValue(bar->value() + d->view->gridSize().width());
497}
498
499void KisResourceItemChooser::activate(const QModelIndex &index)
500{
501 if (!index.isValid())
502 {
504 return;
505 }
506
507 KoResourceSP resource = resourceFromModelIndex(index);
508
509 if (resource && resource->valid()) {
510 if (resource != d->currentResource) {
511 d->currentResource = resource;
512 d->updatesBlocked = true;
513 Q_EMIT resourceSelected(resource);
514 d->updatesBlocked = false;
515 }
516 updatePreview(index);
518 }
519}
520
521void KisResourceItemChooser::clicked(const QModelIndex &index)
522{
523 Q_UNUSED(index);
524
525 KoResourceSP resource = currentResource();
526 if (resource) {
527 Q_EMIT resourceClicked(resource);
528 }
529}
530
532{
533 QAbstractButton *removeButton = d->buttonGroup->button(Button_Remove);
534 if (! removeButton)
535 return;
536
537 KoResourceSP resource = currentResource();
538 if (resource) {
539 removeButton->setEnabled(!resource->permanent());
540 return;
541 }
542 removeButton->setEnabled(false);
543}
544
545void KisResourceItemChooser::updatePreview(const QModelIndex &idx)
546{
547 if (!d->usePreview) return;
548
549 if (!idx.isValid()) {
550 d->previewLabel->setPixmap(QPixmap());
551 return;
552 }
553
554 QImage image = idx.data(Qt::UserRole + KisAbstractResourceModel::Thumbnail).value<QImage>();
555
556 if (image.format() != QImage::Format_RGB32 &&
557 image.format() != QImage::Format_ARGB32 &&
558 image.format() != QImage::Format_ARGB32_Premultiplied) {
559
560 image.convertTo(QImage::Format_ARGB32_Premultiplied);
561 }
562
563 if (d->tiledPreview) {
564 int width = d->previewScroller->width() * 4 * devicePixelRatioF();
565 int height = d->previewScroller->height() * 4 * devicePixelRatioF();
566 QImage img(width, height, image.format());
567 QPainter gc(&img);
568 gc.fillRect(img.rect(), Qt::white);
569 gc.setPen(Qt::NoPen);
570 gc.setBrush(QBrush(image));
571 gc.drawRect(img.rect());
572 image = img;
573 }
574
575 // Only convert to grayscale if it is rgb. Otherwise, it's gray already.
576 if (d->grayscalePreview && !image.isGrayscale()) {
577 QRgb *pixel = reinterpret_cast<QRgb *>(image.bits());
578 for (int row = 0; row < image.height(); ++row) {
579 for (int col = 0; col < image.width(); ++col) {
580 const QRgb currentPixel = pixel[row * image.width() + col];
581 const int red = qRed(currentPixel);
582 const int green = qGreen(currentPixel);
583 const int blue = qBlue(currentPixel);
584 const int grayValue = (red * 11 + green * 16 + blue * 5) / 32;
585 pixel[row * image.width() + col] = qRgb(grayValue, grayValue, grayValue);
586 }
587 }
588 }
589 image.setDevicePixelRatio(devicePixelRatioF());
590 d->previewLabel->setPixmap(QPixmap::fromImage(image));
591}
592
594{
595 if (!index.isValid()) {
596 return 0;
597 }
598 KoResourceSP r = d->tagFilterProxyModel->resourceForIndex(index);
599 return r;
600}
601
603{
604 return d->view->size();
605}
606
608{
609 return d->view;
610}
611
613{
614 d->tagManager->contextMenuRequested(currentResource(), pos);
615}
616
618{
619 d->storagePopupButton->setVisible(visible);
620 d->showStoragePopupBtn = visible;
621}
622
624{
625 d->viewModeButton->setVisible(visible);
626 d->showViewModeBtn = visible;
627}
628
630{
631 return d->viewModeButton;
632}
633
635{
636 if (d->synced == sync)
637 return;
638
639 d->synced = sync;
641 if (sync) {
642 connect(chooserSync, SIGNAL(baseLengthChanged(int)), SLOT(baseLengthChanged(int)));
643 baseLengthChanged(chooserSync->baseLength());
644 } else {
645 chooserSync->disconnect(this);
646 }
647}
648
650{
651 if (d->synced) {
652 d->view->setItemSize(QSize(length, length));
653 }
654}
655
657{
658 // Note: Item model reset events silently reset the view's selection model too.
659 // This currently only covers models resets as part of filter changes.
660 QModelIndex idx = d->tagFilterProxyModel->indexForResource(d->currentResource);
661
662 if (idx.isValid()) {
663 d->view->setCurrentIndex(idx);
664 }
665
667}
668
669bool KisResourceItemChooser::eventFilter(QObject *object, QEvent *event)
670{
671 if (d->synced && event->type() == QEvent::Wheel) {
673 QWheelEvent *qwheel = static_cast<QWheelEvent *>(event);
674 if (qwheel->modifiers() & Qt::ControlModifier) {
675
676 int degrees = qwheel->angleDelta().y() / 8;
677 int newBaseLength = chooserSync->baseLength() + degrees / 15 * 10;
678 chooserSync->setBaseLength(newBaseLength);
679 return true;
680 }
681 }
682 return QObject::eventFilter(object, event);
683}
684
685
686void KisResourceItemChooser::resizeEvent(QResizeEvent *event)
687{
688 QWidget::resizeEvent(event);
690 updateView();
691 updatePreview(d->view->currentIndex());
692}
693
695{
696 QWidget::showEvent(event);
697 updateView();
698 updatePreview(d->view->currentIndex());
699}
700
702{
703 d->horzSplitter->hide();
704 d->left->hide();
705 d->right->hide();
706 d->right2Rows->hide();
707 d->scroll_left->hide();
708 d->scroll_right->hide();
709
710 d->viewModeButton->hide();
711}
712
714{
715 if (d->layout == Layout::Vertical) {
716 return;
717 }
718
720
721 d->view->setListViewMode(d->requestedViewMode);
722 Q_EMIT listViewModeChanged(d->requestedViewMode);
723
724 // The horizontal layouts size the items based widget height not user configured base length
725 // so it needs to be restored when switching back to vertical layout
727 d->view->setItemSize(QSize(chooserSync->baseLength(), chooserSync->baseLength()));
728
729 QGridLayout* thisLayout = dynamic_cast<QGridLayout*>(layout());
730 thisLayout->addWidget(d->tagManager->tagChooserWidget(), 0, 0);
731 thisLayout->addWidget(d->viewModeButton, 0, 1);
732 thisLayout->addWidget(d->storagePopupButton, 0, 2);
733 thisLayout->addWidget(d->resourcesSplitter, 1, 0, 1, 3);
734 thisLayout->setRowStretch(1, 1);
735 thisLayout->addWidget(d->tagManager->tagFilterWidget(), 2, 0, 1, 3);
736 thisLayout->addWidget(d->importExportBtns, 3, 0, 1, 3);
737
738 d->viewModeButton->setVisible(d->showViewModeBtn);
739 d->storagePopupButton->setVisible(d->showStoragePopupBtn);
740
741 d->viewModeButton->setVisible(d->showViewModeBtn);
742 d->layout = Layout::Vertical;
743}
744
746{
747 if (d->isResponsive == false) {
748 return;
749 }
750 // Responsive Layout
751 else {
752 // Vertical
753 if (height() > 100) {
755 }
756 // Horizontal 2 rows
757 else if (height() > 60) {
758
759 if (d->layout == Layout::Horizontal2Rows) {
760 return;
761 }
762
764
765 d->view->setListViewMode(ListViewMode::IconStripHorizontal);
767
768 // Left
769 QLayout* leftLayout = d->left->layout();
770 leftLayout->addWidget(d->resourcesSplitter);
771
772 // Right Top
773 d->top->addWidget(d->scroll_left);
774 d->top->addWidget(d->scroll_right);
775 d->top->addWidget(d->tagManager->tagChooserWidget());
776 d->top->addWidget(d->importExportBtns);
777
778 // Right Bot
779 d->bot->addWidget(d->viewModeButton);
780 d->bot->addWidget(d->storagePopupButton);
781 d->bot->addWidget(d->tagManager->tagFilterWidget());
782
783 d->horzSplitter->addWidget(d->left);
784 d->horzSplitter->addWidget(d->right2Rows);
785
786 QGridLayout* thisLayout = dynamic_cast<QGridLayout*>(layout());
787 thisLayout->addWidget(d->horzSplitter, 0, 0);
788 thisLayout->setRowStretch(0, 2);
789 thisLayout->setColumnStretch(0, 2);
790 thisLayout->setRowStretch(1, 0);
791
792 d->viewModeButton->setVisible(false);
793 d->storagePopupButton->setVisible(d->showStoragePopupBtn);
794
795 const bool splitterRestored = d->restoreSplitterState(Layout::Horizontal2Rows);
796
797 d->horzSplitter->show();
798 d->left->show();
799 d->scroll_left->show();
800 d->scroll_right->show();
801 d->right2Rows->show();
802
803 d->layout = Layout::Horizontal2Rows;
804
805 if (!splitterRestored) {
807 }
808 }
809 // Horizontal 1 row
810 else {
811 if (d->layout == Layout::Horizontal1Row) {
812 return;
813 }
814
816
817 d->view->setListViewMode(ListViewMode::IconStripHorizontal);
819
820 QLayout* leftLayout = d->left->layout();
821 leftLayout->addWidget(d->resourcesSplitter);
822 leftLayout->addWidget(d->scroll_left);
823 leftLayout->addWidget(d->scroll_right);
824
825 QLayout* rightLayout = d->right->layout();
826 rightLayout->addWidget(d->tagManager->tagChooserWidget());
827 rightLayout->addWidget(d->viewModeButton);
828 rightLayout->addWidget(d->storagePopupButton);
829 rightLayout->addWidget(d->tagManager->tagFilterWidget());
830 rightLayout->addWidget(d->importExportBtns);
831
832 d->horzSplitter->addWidget(d->left);
833 d->horzSplitter->addWidget(d->right);
834
835 QGridLayout* thisLayout = dynamic_cast<QGridLayout*>(layout());
836 thisLayout->addWidget(d->horzSplitter, 0, 0);
837 thisLayout->setRowStretch(0, 2);
838 thisLayout->setColumnStretch(0, 2);
839 thisLayout->setRowStretch(1, 0);
840
841 d->viewModeButton->setVisible(false);
842 d->storagePopupButton->setVisible(d->showStoragePopupBtn);
843
844 const bool splitterRestored = d->restoreSplitterState(Layout::Horizontal1Row);
845
846 d->horzSplitter->show();
847 d->left->show();
848 d->scroll_left->show();
849 d->scroll_right->show();
850 d->right->show();
851
852 d->layout = Layout::Horizontal1Row;
853
854 if (!splitterRestored) {
856 }
857 }
858 }
859}
860
861bool KisResourceItemChooser::Private::restoreSplitterState(Layout layout)
862{
863 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(layout > Layout::Vertical, false);
864
865 KConfigGroup group = KSharedConfig::openConfig()->group(QString("KisResourceItemChooser_%1").arg(resourceType));
866
867 const QLatin1String key(
868 layout == Layout::Horizontal1Row ? "splitterState_1row" : "splitterState_2row");
869
870 bool splitterRestored = false;
871 QByteArray state = group.readEntry(key, QByteArray());
872 if (!state.isEmpty()) {
873 splitterRestored = horzSplitter->restoreState(state);
874 KIS_SAFE_ASSERT_RECOVER_NOOP(splitterRestored);
875 }
876
877 return splitterRestored;
878}
879
881{
882 if (d->layout > Layout::Vertical) {
883 KConfigGroup group = KSharedConfig::openConfig()->group(QString("KisResourceItemChooser_%1").arg(d->resourceType));
884 const QByteArray state = d->horzSplitter->saveState();
885
886 const QLatin1String key(
887 d->layout == Layout::Horizontal1Row ? "splitterState_1row" : "splitterState_2row");
888
889 group.writeEntry(key, state);
890 }
891}
892
894{
896 d->viewModeButton->setIcon(KisIconUtils::loadIcon("view-choose"));
897 d->importButton->setIcon(koIcon("document-import-16"));
898 d->deleteButton->setIcon(koIcon("edit-delete"));
899 d->storagePopupButton->setIcon(koIcon("bundle_archive"));
900 d->tagManager->tagChooserWidget()->updateIcons();
901}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
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()