diff options
Diffstat (limited to 'kkbswitch/kbpickicondlg.cpp')
-rw-r--r-- | kkbswitch/kbpickicondlg.cpp | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/kkbswitch/kbpickicondlg.cpp b/kkbswitch/kbpickicondlg.cpp new file mode 100644 index 0000000..d745f7c --- /dev/null +++ b/kkbswitch/kbpickicondlg.cpp @@ -0,0 +1,203 @@ +/*************************************************************************** + 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 ¤tPath, const QPixmap ¤tPixmap, + 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 ¤tPath, + const QPixmap ¤tPixmap) +{ + 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); +} |