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++) {
187 if (emitProgress >= 10) {
201 QString ext = path.right(3).toUpper();
203 if (ext !=
"SVG" && ext !=
"VGZ") {
208 img = QImage(canvasIconWidth, canvasIconHeight, QImage::Format_ARGB32_Premultiplied);
211 if (renderer.isValid()) {
222 if (img.width() > canvasIconWidth || img.height() > canvasIconHeight) {
223 if (img.width() / (float)canvasIconWidth > img.height() / (float)canvasIconHeight) {
224 int height = (int) (((
float)canvasIconWidth / img.width()) * img.height());
225 img = img.scaled(canvasIconWidth, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
227 int width = (int) (((
float)canvasIconHeight / img.height()) * img.width());
228 img = img.scaled(width, canvasIconHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
232 if (uniformIconSize && (img.width() != canvasIconWidth || img.height() != canvasIconHeight)) {
235 QImage paddedImage = QImage(canvasIconWidth, canvasIconHeight, QImage::Format_ARGB32_Premultiplied);
237 QPainter painter(&paddedImage);
238 painter.drawImage( (canvasIconWidth - img.width()) / 2, (canvasIconHeight - img.height()) / 2, img);
242 QPixmap pm = QPixmap::fromImage(img);
244 QListWidgetItem *item =
new QListWidgetItem(pm, fi.completeBaseName(), q);
245 item->setData(Qt::UserRole, *it);
246 item->setToolTip(fi.completeBaseName());
250 q->setUpdatesEnabled(
true);
252 QApplication::restoreOverrideCursor();
255 q->setResizeMode(QListWidget::Adjust);
262 return currentItem()->data(Qt::UserRole).toString();
267 d->m_bLoading =
false;
270 void KIconCanvas::KIconCanvasPrivate::_k_slotCurrentChanged(QListWidgetItem *item)
272 emit q->nameChanged((item != 0L) ? item->text() :
QString());
275 class KIconDialog::KIconDialogPrivate
280 m_bStrictIconSize =
true;
282 m_bLockCustomDir =
false;
286 ~KIconDialogPrivate() {}
293 void _k_slotContext(
int);
294 void _k_slotStartLoading(
int);
295 void _k_slotProgress(
int);
296 void _k_slotFinished();
297 void _k_slotAcceptIcons();
298 void _k_slotBrowse();
299 void _k_slotOtherIconClicked();
300 void _k_slotSystemIconClicked();
310 QRadioButton *mpSystemIcons, *mpOtherIcons;
311 QProgressBar *mpProgress;
318 bool m_bStrictIconSize, m_bLockUser, m_bLockCustomDir;
330 :
KDialog(parent), d(new KIconDialogPrivate(this))
333 setCaption(
i18n(
"Select Icon") );
335 setDefaultButton(
Ok );
342 :
KDialog(parent), d(new KIconDialogPrivate(this))
345 setCaption(
i18n(
"Select Icon") );
347 setDefaultButton(
Ok );
349 d->mpLoader = loader;
353 void KIconDialog::KIconDialogPrivate::init()
357 mFileList = KGlobal::dirs()->findAllResources(
"appicon", QLatin1String(
"*.png"));
360 q->setMainWidget(main);
362 QVBoxLayout *top =
new QVBoxLayout(main);
366 bgroup->setTitle(
i18n(
"Icon Source"));
368 QVBoxLayout *vbox =
new QVBoxLayout;
369 bgroup->setLayout( vbox );
370 top->addWidget(bgroup);
372 QGridLayout *grid =
new QGridLayout();
373 vbox->addLayout(grid);
375 mpSystemIcons =
new QRadioButton(
i18n(
"S&ystem icons:"), bgroup);
376 connect(mpSystemIcons, SIGNAL(clicked()), q, SLOT(_k_slotSystemIconClicked()));
377 grid->addWidget(mpSystemIcons, 1, 0);
379 mpCombo->setMaxVisibleItems(12);
380 connect(mpCombo, SIGNAL(activated(
int)), q, SLOT(_k_slotContext(
int)));
381 grid->addWidget(mpCombo, 1, 1);
382 mpOtherIcons =
new QRadioButton(
i18n(
"O&ther icons:"), bgroup);
383 connect(mpOtherIcons, SIGNAL(clicked()), q, SLOT(_k_slotOtherIconClicked()));
384 grid->addWidget(mpOtherIcons, 2, 0);
386 connect(mpBrowseBut, SIGNAL(clicked()), q, SLOT(_k_slotBrowse()));
387 grid->addWidget(mpBrowseBut, 2, 1);
392 QHBoxLayout *searchLayout =
new QHBoxLayout();
393 searchLayout->setMargin(0);
394 top->addLayout(searchLayout);
397 searchLayout->addWidget(searchLabel);
400 searchLayout->addWidget(searchLine);
401 searchLabel->setBuddy(searchLine);
403 QString wtstr =
i18n(
"Search interactively for icon names (e.g. folder).");
404 searchLabel->setWhatsThis(wtstr);
405 searchLine->setWhatsThis(wtstr);
409 connect(mpCanvas, SIGNAL(itemActivated(QListWidgetItem*)), q, SLOT(_k_slotAcceptIcons()));
410 top->addWidget(mpCanvas);
411 searchLine->setListWidget(mpCanvas);
415 opt.initFrom(mpCanvas);
416 int width = 4 * mpCanvas->gridSize().width() + 1;
417 width += mpCanvas->verticalScrollBar()->sizeHint().width();
418 width += 2 * mpCanvas->frameWidth();
419 if (mpCanvas->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, mpCanvas)) {
420 width += mpCanvas->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt, mpCanvas);
422 mpCanvas->setMinimumSize(width, 125);
424 mpProgress =
new QProgressBar(main);
425 top->addWidget(mpProgress);
426 connect(mpCanvas, SIGNAL(startLoading(
int)), q, SLOT(_k_slotStartLoading(
int)));
427 connect(mpCanvas, SIGNAL(progress(
int)), q, SLOT(_k_slotProgress(
int)));
428 connect(mpCanvas, SIGNAL(finished()), q, SLOT(_k_slotFinished()));
431 connect(q, SIGNAL(hidden()), mpCanvas, SLOT(stopLoading()));
433 static const char*
const context_text[] = {
460 int cnt =
sizeof( context_text ) /
sizeof( context_text[ 0 ] );
462 Q_ASSERT( cnt ==
sizeof( context_id ) /
sizeof( context_id[ 0 ] )
463 && cnt ==
sizeof( mContextMap ) /
sizeof( mContextMap[ 0 ] ));
464 for (
int i = 0; i < cnt; ++i) {
465 if (mpLoader->hasContext( context_id[ i ])) {
466 mpCombo->addItem(
i18n( context_text[ i ] ));
467 mContextMap[ mNumContext++ ] = context_id[ i ];
470 mpCombo->setFixedSize(mpCombo->sizeHint());
472 mpBrowseBut->setFixedWidth(mpCombo->width());
475 q->incrementInitialSize(
QSize(0,100));
476 connect(q, SIGNAL(okClicked()), q, SLOT(slotOk()));
485 void KIconDialog::KIconDialogPrivate::_k_slotAcceptIcons()
491 void KIconDialog::KIconDialogPrivate::showIcons()
495 if (mpSystemIcons->isChecked()) {
496 if (m_bStrictIconSize) {
497 filelist = mpLoader->queryIcons(mGroupOrSize, mContext);
499 filelist = mpLoader->queryIconsByContext(mGroupOrSize, mContext);
501 }
else if (!customLocation.isEmpty()) {
502 filelist = mpLoader->queryIconsByDir(customLocation);
504 filelist = mFileList;
508 QStringList::const_iterator it;
509 foreach (
const QString &it, filelist) {
510 iconlist.append(IconPath(it));
516 foreach (
const IconPath &
ip, iconlist) {
526 if (mGroupOrSize < -1) {
529 mpCanvas->setIconSize(
QSize(-mGroupOrSize, -mGroupOrSize));
533 mpCanvas->setIconSize(
QSize(groupSize, groupSize));
536 mpCanvas->loadFiles(filelist);
541 d->m_bStrictIconSize=b;
546 return d->m_bStrictIconSize;
555 d->mGroupOrSize = -size;
562 return (d->mGroupOrSize < 0) ? -d->mGroupOrSize : 0;
566 bool strictIconSize,
int iconSize,
bool user,
567 bool lockUser,
bool lockCustomDir )
570 d->m_bLockUser = lockUser;
571 d->m_bLockCustomDir = lockCustomDir;
579 d->mGroupOrSize = group;
585 d->mpSystemIcons->setChecked(!user);
586 d->mpSystemIcons->setEnabled(!lockUser || !user);
587 d->mpOtherIcons->setChecked(user);
588 d->mpOtherIcons->setEnabled(!lockUser || user);
589 d->mpCombo->setEnabled(!user);
590 d->mpBrowseBut->setEnabled(user && !lockCustomDir);
591 d->setContext(context);
597 for (
int i = 0; i < mNumContext; ++i) {
598 if( mContextMap[ i ] == context ) {
599 mpCombo->setCurrentIndex(i);
607 d->customLocation = location;
613 d->searchLine->setFocus();
615 if (exec() == Accepted) {
616 if (!d->custom.isEmpty()) {
621 if (name.isEmpty() || d->mpOtherIcons->isChecked()) {
626 return fi.completeBaseName();
636 d->searchLine->setFocus();
643 if (!d->custom.isEmpty()) {
646 name = d->mpCanvas->getCurrent();
647 if (!name.isEmpty() && d->mpSystemIcons->isChecked()) {
648 const QFileInfo fi(name);
649 name = fi.completeBaseName();
658 bool strictIconSize,
int iconSize,
bool user,
662 dlg.
setup(group, context, strictIconSize, iconSize, user);
663 if (!caption.isEmpty()) {
664 dlg.setCaption(caption);
670 void KIconDialog::KIconDialogPrivate::_k_slotBrowse()
676 KFileDialog dlg(emptyUrl,
i18n(
"*.png *.xpm *.svg *.svgz|Icon Files (*.png *.xpm *.svg *.svgz)"), q);
678 dlg.setCaption(
i18n(
"Open") );
682 dlg.setPreviewWidget( ip );
685 QString file = dlg.selectedFile();
689 if (mpSystemIcons->isChecked()) {
690 customLocation = QFileInfo(file).absolutePath();
696 void KIconDialog::KIconDialogPrivate::_k_slotSystemIconClicked()
698 mpBrowseBut->setEnabled(
false);
699 mpCombo->setEnabled(
true);
703 void KIconDialog::KIconDialogPrivate::_k_slotOtherIconClicked()
705 mpBrowseBut->setEnabled(!m_bLockCustomDir);
706 mpCombo->setEnabled(
false);
710 void KIconDialog::KIconDialogPrivate::_k_slotContext(
int id)
716 void KIconDialog::KIconDialogPrivate::_k_slotStartLoading(
int steps)
723 mpProgress->setValue(0);
728 void KIconDialog::KIconDialogPrivate::_k_slotProgress(
int p)
730 mpProgress->setValue(static_cast<int>(100.0 * (
double)p / (
double)mNumOfSteps));
733 void KIconDialog::KIconDialogPrivate::_k_slotFinished()
739 class KIconButton::KIconButtonPrivate
743 ~KIconButtonPrivate();
746 void _k_slotChangeIcon();
747 void _k_newIconName(
const QString&);
753 bool m_bStrictIconSize;
772 QPushButton::setIconSize(
QSize(48, 48));
776 :
QPushButton(parent), d(new KIconButtonPrivate(this, loader))
778 QPushButton::setIconSize(
QSize(48, 48));
784 m_bStrictIconSize =
false;
794 connect(q, SIGNAL(clicked()), q, SLOT(_k_slotChangeIcon()));
797 KIconButton::KIconButtonPrivate::~KIconButtonPrivate()
809 d->m_bStrictIconSize=b;
814 return d->m_bStrictIconSize;
819 if (d->buttonIconSize == -1) {
820 QPushButton::setIconSize(
QSize(size, size));
833 QPushButton::setIconSize(
QSize(size, size));
834 d->buttonIconSize = size;
839 return QPushButton::iconSize().height();
845 d->mContext = context;
856 connect(d->mpDialog, SIGNAL(newIconName(
QString)),
this, SLOT(_k_newIconName(
QString)));
860 d->mpDialog->setCustomLocation(QFileInfo(d->mpLoader->iconPath(d->mIcon, d->mGroup,
true) ).absolutePath());
866 QPushButton::setIcon(icon);
880 void KIconButton::KIconButtonPrivate::_k_slotChangeIcon()
885 connect(mpDialog, SIGNAL(newIconName(
QString)), q, SLOT(_k_newIconName(
QString)));
888 mpDialog->setup(mGroup, mContext, m_bStrictIconSize, iconSize, mbUser);
889 mpDialog->showDialog();
892 void KIconButton::KIconButtonPrivate::_k_newIconName(
const QString& name)
894 if (name.isEmpty()) {
898 q->setIcon(
KIcon(name));
902 mpDialog->setCustomLocation(QFileInfo(mpLoader->iconPath(mIcon, mGroup,
true)).absolutePath());
905 emit q->iconChanged(name);
908 #include "kicondialog.moc"