29 #include <QtGui/QApplication>
30 #include <QtGui/QGroupBox>
31 #include <QtGui/QLayout>
32 #include <QtGui/QLabel>
33 #include <QtCore/QTimer>
34 #include <QtGui/QRadioButton>
35 #include <QtCore/QFileInfo>
36 #include <QtGui/QProgressBar>
37 #include <QtGui/QPainter>
38 #include <QtGui/QScrollBar>
46 class KIconCanvasDelegate :
public QAbstractItemDelegate
49 KIconCanvasDelegate(
KIconCanvas *parent, QAbstractItemDelegate *defaultDelegate);
50 ~KIconCanvasDelegate() {};
51 void paint ( QPainter * painter,
const QStyleOptionViewItem & option,
const QModelIndex & index )
const;
52 QSize sizeHint (
const QStyleOptionViewItem & option,
const QModelIndex & index )
const;
55 QAbstractItemDelegate *m_defaultDelegate;
56 static const int HORIZONTAL_EDGE_PAD = 3;
59 KIconCanvasDelegate::KIconCanvasDelegate(
KIconCanvas *parent, QAbstractItemDelegate *defaultDelegate)
60 : QAbstractItemDelegate(parent)
62 m_iconCanvas = parent;
63 m_defaultDelegate = defaultDelegate;
66 void KIconCanvasDelegate::paint ( QPainter * painter,
const QStyleOptionViewItem & option,
const QModelIndex & index )
const
68 const int GRID_WIDTH = m_iconCanvas->gridSize().width();
69 QStyleOptionViewItem newOption = option;
71 newOption.rect.setX((option.rect.x() / GRID_WIDTH) * GRID_WIDTH + HORIZONTAL_EDGE_PAD);
72 newOption.rect.setWidth(GRID_WIDTH - 2 * HORIZONTAL_EDGE_PAD);
74 m_defaultDelegate->paint(painter, newOption, index);
77 QSize KIconCanvasDelegate::sizeHint (
const QStyleOptionViewItem & option,
const QModelIndex & index )
const
79 QSize size = m_defaultDelegate->sizeHint(option, index);
80 const int GRID_WIDTH = m_iconCanvas->gridSize().width();
81 size.setWidth(GRID_WIDTH - 2 * HORIZONTAL_EDGE_PAD);
85 class KIconCanvas::KIconCanvasPrivate
88 KIconCanvasPrivate(
KIconCanvas *qq) { q = qq; m_bLoading =
false; }
89 ~KIconCanvasPrivate() {}
94 KIconCanvasDelegate *mpDelegate;
97 void _k_slotLoadFiles();
98 void _k_slotCurrentChanged(QListWidgetItem *item);
104 class IconPath :
public QString
112 int n = lastIndexOf(
'/');
113 m_iconName = (n==-1) ? static_cast<QString>(*
this) : mid(n+1);
121 {
return m_iconName == ip.m_iconName; }
123 bool operator< (
const IconPath &ip)
const
124 {
return m_iconName < ip.m_iconName; }
133 :
KListWidget(parent), d(new KIconCanvasPrivate(this))
135 setViewMode(IconMode);
136 setUniformItemSizes(
true);
138 setIconSize(
QSize(60, 60));
139 d->mpTimer =
new QTimer(
this);
140 connect(d->mpTimer, SIGNAL(
timeout()),
this, SLOT(_k_slotLoadFiles()));
141 connect(
this, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
142 this, SLOT(_k_slotCurrentChanged(QListWidgetItem*)));
143 setGridSize(
QSize(100,80));
145 d->mpDelegate =
new KIconCanvasDelegate(
this, itemDelegate());
146 setItemDelegate(d->mpDelegate);
152 delete d->mpDelegate;
161 d->mpTimer->setSingleShot(
true);
162 d->mpTimer->start(10);
163 d->m_bLoading =
false;
166 void KIconCanvas::KIconCanvasPrivate::_k_slotLoadFiles()
168 q->setResizeMode(QListWidget::Fixed);
169 QApplication::setOverrideCursor(Qt::WaitCursor);
174 q->setUpdatesEnabled(
false);
177 const int canvasIconWidth = q->iconSize().width();
178 const int canvasIconHeight = q->iconSize().width();
179 const bool uniformIconSize = q->uniformItemSizes();
183 QStringList::ConstIterator it;
184 uint emitProgress = 10;
185 QStringList::ConstIterator
end(mFiles.constEnd());
186 for (it=mFiles.constBegin(), i=0; it!=
end; ++it, i++)
188 if ( emitProgress >= 10 ) {
202 QString ext = path.right(3).toUpper();
204 if (ext !=
"SVG" && ext !=
"VGZ")
209 img = QImage(canvasIconWidth, canvasIconHeight, QImage::Format_ARGB32_Premultiplied);
212 if (renderer.isValid()) {
221 if (img.width() > canvasIconWidth || img.height() > canvasIconHeight)
223 if (img.width() / (float)canvasIconWidth > img.height() / (float)canvasIconHeight)
225 int height = (int) (((
float)canvasIconWidth / img.width()) * img.height());
226 img = img.scaled(canvasIconWidth, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
229 int width = (int) (((
float)canvasIconHeight / img.height()) * img.width());
230 img = img.scaled(width, canvasIconHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
234 if (uniformIconSize && (img.width() != canvasIconWidth || img.height() != canvasIconHeight))
238 QImage paddedImage = QImage(canvasIconWidth, canvasIconHeight, QImage::Format_ARGB32_Premultiplied);
240 QPainter painter(&paddedImage);
241 painter.drawImage( (canvasIconWidth - img.width()) / 2, (canvasIconHeight - img.height()) / 2, img);
245 QPixmap pm = QPixmap::fromImage(img);
247 QListWidgetItem *item =
new QListWidgetItem(pm, fi.completeBaseName(), q);
248 item->setData(Qt::UserRole, *it);
249 item->setToolTip(fi.completeBaseName());
253 q->setUpdatesEnabled(
true);
255 QApplication::restoreOverrideCursor();
258 q->setResizeMode(QListWidget::Adjust);
265 return currentItem()->data(Qt::UserRole).toString();
270 d->m_bLoading =
false;
273 void KIconCanvas::KIconCanvasPrivate::_k_slotCurrentChanged(QListWidgetItem *item)
275 emit q->nameChanged((item != 0L) ? item->text() :
QString());
278 class KIconDialog::KIconDialogPrivate
283 m_bStrictIconSize =
true;
285 m_bLockCustomDir =
false;
289 ~KIconDialogPrivate() {}
296 void _k_slotContext(
int);
297 void _k_slotStartLoading(
int);
298 void _k_slotProgress(
int);
299 void _k_slotFinished();
300 void _k_slotAcceptIcons();
301 void _k_slotBrowse();
302 void _k_slotOtherIconClicked();
303 void _k_slotSystemIconClicked();
313 QRadioButton *mpSystemIcons, *mpOtherIcons;
314 QProgressBar *mpProgress;
321 bool m_bStrictIconSize, m_bLockUser, m_bLockCustomDir;
333 :
KDialog(parent), d(new KIconDialogPrivate(this))
345 :
KDialog(parent), d(new KIconDialogPrivate(this))
352 d->mpLoader = loader;
356 void KIconDialog::KIconDialogPrivate::init()
363 q->setMainWidget(main);
365 QVBoxLayout *top =
new QVBoxLayout(main);
369 bgroup->setTitle(
i18n(
"Icon Source"));
371 QVBoxLayout *vbox =
new QVBoxLayout;
372 bgroup->setLayout( vbox );
373 top->addWidget(bgroup);
375 QGridLayout *grid =
new QGridLayout();
376 vbox->addLayout(grid);
378 mpSystemIcons =
new QRadioButton(
i18n(
"S&ystem icons:"), bgroup);
379 connect(mpSystemIcons, SIGNAL(clicked()), q, SLOT(_k_slotSystemIconClicked()));
380 grid->addWidget(mpSystemIcons, 1, 0);
382 mpCombo->setMaxVisibleItems(12);
383 connect(mpCombo, SIGNAL(activated(
int)), q, SLOT(_k_slotContext(
int)));
384 grid->addWidget(mpCombo, 1, 1);
385 mpOtherIcons =
new QRadioButton(
i18n(
"O&ther icons:"), bgroup);
386 connect(mpOtherIcons, SIGNAL(clicked()), q, SLOT(_k_slotOtherIconClicked()));
387 grid->addWidget(mpOtherIcons, 2, 0);
389 connect(mpBrowseBut, SIGNAL(clicked()), q, SLOT(_k_slotBrowse()));
390 grid->addWidget(mpBrowseBut, 2, 1);
395 QHBoxLayout *searchLayout =
new QHBoxLayout();
396 searchLayout->setMargin(0);
397 top->addLayout(searchLayout);
400 searchLayout->addWidget(searchLabel);
403 searchLayout->addWidget(searchLine);
404 searchLabel->setBuddy(searchLine);
406 QString wtstr =
i18n(
"Search interactively for icon names (e.g. folder).");
407 searchLabel->setWhatsThis(wtstr);
408 searchLine->setWhatsThis(wtstr);
412 connect(mpCanvas, SIGNAL(itemActivated(QListWidgetItem*)), q, SLOT(_k_slotAcceptIcons()));
413 top->addWidget(mpCanvas);
414 searchLine->setListWidget(mpCanvas);
418 opt.initFrom(mpCanvas);
419 int width = 4 * mpCanvas->gridSize().width() + 1;
420 width += mpCanvas->verticalScrollBar()->sizeHint().width();
421 width += 2 * mpCanvas->frameWidth();
422 if (mpCanvas->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, mpCanvas)) {
423 width += mpCanvas->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt, mpCanvas);
425 mpCanvas->setMinimumSize(width, 125);
427 mpProgress =
new QProgressBar(main);
428 top->addWidget(mpProgress);
429 connect(mpCanvas, SIGNAL(startLoading(
int)), q, SLOT(_k_slotStartLoading(
int)));
430 connect(mpCanvas, SIGNAL(progress(
int)), q, SLOT(_k_slotProgress(
int)));
431 connect(mpCanvas, SIGNAL(finished()), q, SLOT(_k_slotFinished()));
434 connect(q, SIGNAL(hidden()), mpCanvas, SLOT(stopLoading()));
436 static const char*
const context_text[] = {
463 int cnt =
sizeof( context_text ) /
sizeof( context_text[ 0 ] );
465 Q_ASSERT( cnt ==
sizeof( context_id ) /
sizeof( context_id[ 0 ] )
466 && cnt ==
sizeof( mContextMap ) /
sizeof( mContextMap[ 0 ] ));
471 if( mpLoader->hasContext( context_id[ i ] ))
473 mpCombo->addItem(
i18n( context_text[ i ] ));
474 mContextMap[ mNumContext++ ] = context_id[ i ];
477 mpCombo->setFixedSize(mpCombo->sizeHint());
479 mpBrowseBut->setFixedWidth(mpCombo->width());
482 q->incrementInitialSize(
QSize(0,100));
483 connect(q, SIGNAL(okClicked()), q, SLOT(slotOk()));
492 void KIconDialog::KIconDialogPrivate::_k_slotAcceptIcons()
498 void KIconDialog::KIconDialogPrivate::showIcons()
502 if (mpSystemIcons->isChecked())
503 if (m_bStrictIconSize)
504 filelist=mpLoader->queryIcons(mGroupOrSize, mContext);
506 filelist=mpLoader->queryIconsByContext(mGroupOrSize, mContext);
507 else if (!customLocation.isNull()) {
508 filelist = mpLoader->queryIconsByDir(customLocation);
514 QStringList::const_iterator it;
515 foreach (
const QString &it, filelist) {
516 iconlist.append(IconPath(it));
522 foreach (
const IconPath &
ip, iconlist) {
532 if (mGroupOrSize < -1)
535 mpCanvas->setIconSize(
QSize(-mGroupOrSize, -mGroupOrSize));
541 mpCanvas->setIconSize(
QSize(groupSize, groupSize));
544 mpCanvas->loadFiles(filelist);
549 d->m_bStrictIconSize=b;
554 return d->m_bStrictIconSize;
563 d->mGroupOrSize = -size;
570 return (d->mGroupOrSize < 0) ? -d->mGroupOrSize : 0;
574 bool strictIconSize,
int iconSize,
bool user,
575 bool lockUser,
bool lockCustomDir )
578 d->m_bLockUser = lockUser;
579 d->m_bLockCustomDir = lockCustomDir;
591 d->mGroupOrSize = group;
599 d->mpSystemIcons->setChecked(!user);
600 d->mpSystemIcons->setEnabled(!lockUser || !user);
601 d->mpOtherIcons->setChecked(user);
602 d->mpOtherIcons->setEnabled(!lockUser || user);
603 d->mpCombo->setEnabled(!user);
604 d->mpBrowseBut->setEnabled(user && !lockCustomDir);
605 d->setContext(context);
614 if( mContextMap[ i ] == context )
616 mpCombo->setCurrentIndex( i );
623 d->customLocation = location;
629 d->searchLine->setFocus();
631 if ( exec() == Accepted )
633 if (!d->custom.isNull())
636 if (
name.isEmpty() || d->mpOtherIcons->isChecked()) {
640 return fi.completeBaseName();
649 d->searchLine->setFocus();
656 if (!d->custom.isNull())
662 name = d->mpCanvas->getCurrent();
663 if (!name.isEmpty() && d->mpSystemIcons->isChecked()) {
665 name = fi.baseName();
674 bool strictIconSize,
int iconSize,
bool user,
678 dlg.
setup( group, context, strictIconSize, iconSize, user );
679 if (!caption.isNull())
685 void KIconDialog::KIconDialogPrivate::_k_slotBrowse()
691 KFileDialog dlg(emptyUrl,
i18n(
"*.png *.xpm *.svg *.svgz|Icon Files (*.png *.xpm *.svg *.svgz)"), q);
693 dlg.setCaption(
i18n(
"Open") );
697 dlg.setPreviewWidget( ip );
700 QString file = dlg.selectedFile();
704 if (mpSystemIcons->isChecked()) {
705 customLocation = QFileInfo(file).absolutePath();
711 void KIconDialog::KIconDialogPrivate::_k_slotSystemIconClicked()
713 mpBrowseBut->setEnabled(
false);
714 mpCombo->setEnabled(
true);
718 void KIconDialog::KIconDialogPrivate::_k_slotOtherIconClicked()
720 mpBrowseBut->setEnabled(!m_bLockCustomDir);
721 mpCombo->setEnabled(
false);
725 void KIconDialog::KIconDialogPrivate::_k_slotContext(
int id)
731 void KIconDialog::KIconDialogPrivate::_k_slotStartLoading(
int steps)
738 mpProgress->setValue(0);
743 void KIconDialog::KIconDialogPrivate::_k_slotProgress(
int p)
745 mpProgress->setValue(static_cast<int>(100.0 * (
double)p / (
double)mNumOfSteps));
748 void KIconDialog::KIconDialogPrivate::_k_slotFinished()
754 class KIconButton::KIconButtonPrivate
758 ~KIconButtonPrivate();
761 void _k_slotChangeIcon();
762 void _k_newIconName(
const QString&);
768 bool m_bStrictIconSize;
787 QPushButton::setIconSize(
QSize(48, 48));
791 :
QPushButton(parent), d(new KIconButtonPrivate(this, loader))
793 QPushButton::setIconSize(
QSize(48, 48));
799 m_bStrictIconSize =
false;
809 connect(q, SIGNAL(clicked()), q, SLOT(_k_slotChangeIcon()));
812 KIconButton::KIconButtonPrivate::~KIconButtonPrivate()
824 d->m_bStrictIconSize=b;
829 return d->m_bStrictIconSize;
834 if (d->buttonIconSize == -1) {
835 QPushButton::setIconSize(
QSize(size, size));
848 QPushButton::setIconSize(
QSize(size, size));
849 d->buttonIconSize = size;
854 return QPushButton::iconSize().height();
860 d->mContext = context;
871 connect(d->mpDialog, SIGNAL(newIconName(
QString)),
this, SLOT(_k_newIconName(
QString)));
875 d->mpDialog->setCustomLocation(QFileInfo(d->mpLoader->iconPath(d->mIcon, d->mGroup,
true) ).absolutePath());
881 QPushButton::setIcon(icon);
895 void KIconButton::KIconButtonPrivate::_k_slotChangeIcon()
900 connect(mpDialog, SIGNAL(newIconName(
QString)), q, SLOT(_k_newIconName(
QString)));
903 mpDialog->setup(mGroup, mContext, m_bStrictIconSize, iconSize, mbUser);
904 mpDialog->showDialog();
907 void KIconButton::KIconButtonPrivate::_k_newIconName(
const QString& name)
912 q->setIcon(
KIcon(name));
916 mpDialog->setCustomLocation(QFileInfo(mpLoader->iconPath(mIcon, mGroup,
true)).absolutePath());
919 emit q->iconChanged(name);
922 #include "kicondialog.moc"