You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kkbswitch/kkbswitch/kbpickicondlg.cpp

204 lines
7.4 KiB

/***************************************************************************
kbpickicondlg.cpp - description
-------------------
begin : Sat Jul 21 2001
copyright : (C) 2001 by Leonid Zeitlin
email : lz@europe.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "kbpickicondlg.h"
#include <qvbox.h>
#include <qdir.h>
#include <qwhatsthis.h>
#include <qpushbutton.h>
#include <qimage.h>
#include <kdeversion.h>
#include <klocale.h>
#if KDE_VERSION_MAJOR >= 3
#include <kstandarddirs.h>
#else
#include <kstddirs.h>
#endif
#include <kglobal.h>
#include <kfiledialog.h>
#include <kmessagebox.h>
#include "kbconfig.h"
#include "pathlistboxitem.h"
KBPickIconDlg::KBPickIconDlg(const QString &currentPath, const QPixmap &currentPixmap,
QWidget *parent, const char *name )
: KDialogBase(parent, name, true /*modal*/, i18n("Pick an icon") /*caption*/, Ok | Cancel) {
QVBox *page = makeVBoxMainWidget();
lbIcons = new KListBox(page);
QObject::connect(lbIcons, SIGNAL(doubleClicked(QListBoxItem*)),
this, SLOT(slotOk()));
QObject::connect(lbIcons, SIGNAL(returnPressed(QListBoxItem*)),
this, SLOT(slotOk()));
QWhatsThis::add(lbIcons, i18n("Select one of the icons"));
QPushButton *btnBrowse = new QPushButton(i18n("&Browse..."), page);
QObject::connect(btnBrowse, SIGNAL(clicked()), this, SLOT(slotBrowseForIcon()));
QWhatsThis::add(btnBrowse, i18n("Browse for an image file to use as an icon"));
loadCountryFlags();
// I am told in Red Hat 9 standard KDE flag pixmaps are missing.
// Workaround: we have to simulate them by rescaling GKB's pixmaps
if (lbIcons->count() == 0) {
loadGkbCountryFlags();
}
lbIcons->sort();
showCurrentPath(currentPath, currentPixmap);
lbIcons->setFocus();
}
KBPickIconDlg::~KBPickIconDlg(){
}
/** Get the path name of the selected icon. Returns empty string if no icon selected */
QString KBPickIconDlg::getIconPath(){
QListBoxItem *item = lbIcons->selectedItem();
if (item)
return dynamic_cast<PathListBoxItem*>(item)->path;
else return QString::null; // should not happen
}
/** No descriptions */
const QPixmap* KBPickIconDlg::getIcon(){
if (lbIcons->currentItem() != -1)
return lbIcons->pixmap(lbIcons->currentItem());
else return NULL;
}
/** Browse for an arbitrary icon file */
void KBPickIconDlg::slotBrowseForIcon()
{
QString iconPath = KFileDialog::getOpenFileName(QString::null,
i18n("*.png *.jpg *.gif *.xpm|Icon files (*.png, *.jpg, *.gif, *.xpm)\n*.*|All files (*.*)"));
if (iconPath.isEmpty()) return;
QImage img;
if (img.load(iconPath)) {
double aspectRatio = img.width() / img.height();
QString message = QString::null;
bool too_big, too_wide, too_narrow;
too_narrow = aspectRatio < FLAG_ICON_WIDTH / FLAG_ICON_HEIGHT - 0.1;
too_wide = aspectRatio > FLAG_ICON_WIDTH / FLAG_ICON_HEIGHT + 0.1;
too_big = img.width() > FLAG_ICON_WIDTH * 2;
if (too_big || too_narrow || too_wide) {
message = i18n("The size of this image (%1 by %2) is not good.\n"
"Preferred size for the layout icons is %3 by %4.\n")
.arg(img.width()).arg(img.height()).arg(FLAG_ICON_WIDTH).arg(FLAG_ICON_HEIGHT);
if (too_big) {
QString msg_tail = "";
if (too_wide) msg_tail = i18n(" and also too wide");
else if (too_narrow) msg_tail += i18n(" and also too narrow");
message += i18n("This image is too big%1.").arg(msg_tail);
}
else if (too_wide) message += i18n("This image is too wide.");
else if (too_narrow) message += i18n("This image is too narrow.");
message += "\n";
message += i18n("KKBSwitch will scale it to appropriate size, but the result may not look very good.\n"
"Are you sure you want to use this image?");
if (KMessageBox::questionYesNo(this, message) != KMessageBox::Yes) return;
}
if (img.width() > FLAG_ICON_WIDTH + 3 || img.height() > FLAG_ICON_HEIGHT + 3)
img = img.smoothScale(FLAG_ICON_WIDTH, FLAG_ICON_HEIGHT);
QPixmap pix;
pix.convertFromImage(img);
PathListBoxItem *item = new PathListBoxItem(lbIcons, pix, QFileInfo(iconPath).fileName(),
iconPath);
lbIcons->setSelected(item, true);
lbIcons->centerCurrentItem();
}
else KMessageBox::error(this, i18n("Cannot read icon from file %1. "
"Either it is not an image file or it is corrupt.").arg(iconPath));
}
void KBPickIconDlg::loadCountryFlags()
{
QPixmap pix;
QDir dir;
QStringList locales;
QString path;
QStringList dirs = KGlobal::dirs()->findDirs("locale", "l10n");
for (QStringList::Iterator dirIter = dirs.begin(); dirIter != dirs.end(); dirIter++) {
dir.setPath(*dirIter);
locales = dir.entryList(QDir::Dirs, QDir::Name);
for (QStringList::Iterator iter = locales.begin(); iter != locales.end(); iter++) {
path = dir.path() + "/" + *iter + "/flag.png";
if (*iter != "." && *iter != ".." && pix.load(path)) {
KConfig config(dir.path() + "/" + *iter + "/entry.desktop", true, false,
"locale" /*doesn't really matter*/);
config.setGroup("KCM Locale");
new PathListBoxItem(lbIcons, pix, config.readEntry("Name"), path);
}
}
}
}
void KBPickIconDlg::loadGkbCountryFlags()
{
QDir dir;
QString path, code, name;
QPixmap pix;
QImage img;
dir.setPath("/usr/share/pixmaps/gkb");
const QFileInfoList *icons = dir.entryInfoList(QDir::Files, QDir::Name);
if (icons) {
QFileInfoListIterator iter(*icons);
QFileInfo *info;
for (; (info = iter.current()); ++iter) {
path = info->filePath();
code = info->baseName();
if (img.load(path)) {
KConfig config("l10n/" + code + "/entry.desktop", true, false, "locale");
config.setGroup("KCM Locale");
name = config.readEntry("Name");
if (!name.isNull()) {
pix.convertFromImage(img.smoothScale(FLAG_ICON_WIDTH, FLAG_ICON_HEIGHT));
new PathListBoxItem(lbIcons, pix, name, path);
}
}
}
}
}
void KBPickIconDlg::showCurrentPath(const QString &currentPath,
const QPixmap &currentPixmap)
{
PathListBoxItem *item = NULL;
bool itemFound = false;
for (unsigned i = 0; i < lbIcons->count(); i++) {
item = dynamic_cast<PathListBoxItem*>(lbIcons->item(i));
if (item->path == currentPath) {
itemFound = true;
break;
}
}
// why this strange manipulation of HScrollBarMode?
// Strangely, without it, if the selected item is the last in the listbox, it ends up
// being obscured by the horizontal scrollbar
lbIcons->setHScrollBarMode(QScrollView::AlwaysOn);
if (!itemFound) item = new PathListBoxItem(lbIcons, currentPixmap,
QFileInfo(currentPath).fileName(), currentPath);
lbIcons->updateScrollBars();
lbIcons->setSelected(item, true);
lbIcons->ensureCurrentVisible();
lbIcons->setHScrollBarMode(QScrollView::Auto);
}