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.
basket/src/kicondialog.cpp

559 lines
15 KiB

/*
*
* This file is part of the KDE project, module tdefile.
* Copyright (C) 2006 Luke Sandell <lasandell@gmail.com>
* (C) 2002 Carsten Pfeiffer <pfeiffer@kde.org>
* (C) 2000 Geert Jansen <jansen@kde.org>
* (C) 2000 Kurt Granroth <granroth@kde.org>
* (C) 1997 Christoph Neerfeld <chris@kde.org>
*
* This is free software; it comes under the GNU Library General
* Public License, version 2. See the file "COPYING.LIB" for the
* exact licensing terms.
*/
#include "kicondialogui.h"
#include "kicondialog.h"
#include "kiconcanvas.h"
#include <config.h>
#include <kiconviewsearchline.h>
#include <kdebug.h>
#include <tdeapplication.h>
#include <tdelocale.h>
#include <tdeglobal.h>
#include <kstandarddirs.h>
#include <kiconloader.h>
#include <kprogress.h>
#include <kiconview.h>
#include <tdefiledialog.h>
#include <kimagefilepreview.h>
#include <kpushbutton.h>
#include <tdemessagebox.h>
#include <tqstring.h>
#include <tqstringlist.h>
#include <tqsortedlist.h>
#include <tqimage.h>
#include <tqpixmap.h>
#include <tqlabel.h>
#include <tqcombobox.h>
#include <tqtimer.h>
#include <tqbuttongroup.h>
#include <tqradiobutton.h>
#include <tqfileinfo.h>
#include <tqtoolbutton.h>
#include <tqwhatsthis.h>
#include <tqhbuttongroup.h>
#include <tqdragobject.h>
/* NOTE: Must be in the same order as listbox */
enum ExtendedContext
{
ALL = 0,
RECENT = 1,
// Action thru MimeType, subtract 1 to convert to TDEIcon::Context
OTHER = 7
};
class TDEIconDialog::TDEIconDialogPrivate
{
public:
TDEIconDialogPrivate() {
m_bStrictIconSize = true;
}
~TDEIconDialogPrivate() {}
bool m_bStrictIconSize;
TQString custom;
TQString customLocation;
int recentMax;
TQStringList recentList;
ExtendedContext extendedContext;
TDEIconDialogUI *ui; /* FIXME: KDE4 probably move this to the main class */
};
/*
* TDEIconDialog: Dialog for selecting icons. Both system and user
* specified icons can be chosen.
*/
TDEIconDialog::TDEIconDialog(TQWidget *parent, const char*)
: KDialogBase(parent, "IconDialog", true, i18n("Select Icon"), Ok|Cancel, Ok)
{
d = new TDEIconDialogPrivate;
mpLoader = TDEGlobal::iconLoader();
init();
resize(minimumSize());
}
TDEIconDialog::TDEIconDialog(TDEIconLoader *loader, TQWidget *parent,
const char *name)
: KDialogBase(parent, name, true, i18n("Select Icon"), Ok|Cancel, Ok)
{
d = new TDEIconDialogPrivate;
mpLoader = loader;
init();
}
void TDEIconDialog::init()
{
mGroupOrSize = TDEIcon::Desktop;
d->extendedContext = ALL;
mType = 0;
setCustomLocation(TQString()); // Initialize mFileList
// Read configuration
TDEConfig *config = TDEGlobal::config();
TDEConfigGroupSaver saver(config, "TDEIconDialog");
d->recentMax = config->readNumEntry("RecentMax", 10);
d->recentList = config->readPathListEntry("RecentIcons");
d->ui = new TDEIconDialogUI( this );
setMainWidget(d->ui);
d->ui->searchLine->setIconView(d->ui->iconCanvas);
d->ui->searchLine->setCaseSensitive(false);
// Hack standard Gui item, as KDevDesigner won't let us
d->ui->browseButton->setText(i18n("&Browse..."));
connect(d->ui->browseButton, TQT_SIGNAL(clicked()), TQT_SLOT(slotBrowse()));
connect(d->ui->listBox, TQT_SIGNAL(highlighted(int)), TQT_SLOT(slotContext(int)));
connect(d->ui->iconCanvas, TQT_SIGNAL(executed(TQIconViewItem *)), TQT_SLOT(slotOk()));
connect(d->ui->iconCanvas, TQT_SIGNAL(returnPressed(TQIconViewItem *)), TQT_SLOT(slotOk()));
connect(d->ui->iconCanvas, TQT_SIGNAL(startLoading(int)), TQT_SLOT(slotStartLoading(int)));
connect(d->ui->iconCanvas, TQT_SIGNAL(progress(int)), TQT_SLOT(slotProgress(int)));
connect(d->ui->iconCanvas, TQT_SIGNAL(finished()), TQT_SLOT(slotFinished()));
connect(this, TQT_SIGNAL(hidden()), d->ui->iconCanvas, TQT_SLOT(stopLoading()));
// NOTE: this must be consistent with the IconType enum (see above)
d->ui->listBox->insertItem(i18n("(All Icons)"));
d->ui->listBox->insertItem(i18n("(Recent)"));
d->ui->listBox->insertItem(i18n("Actions"));
d->ui->listBox->insertItem(i18n("Applications"));
d->ui->listBox->insertItem(i18n("Devices"));
d->ui->listBox->insertItem(i18n("Filesystem"));
d->ui->listBox->insertItem(i18n("File Types"));
d->ui->listBox->insertItem(i18n("Miscellaneous"));
}
TDEIconDialog::~TDEIconDialog()
{
// Write configuration
TDEConfig *config = TDEGlobal::config();
TDEConfigGroupSaver saver(config, "TDEIconDialog");
config->writeEntry("RecentMax", d->recentMax, true, true);
config->writePathEntry("RecentIcons", d->recentList, ',', true, true);
delete d;
}
void TDEIconDialog::slotAcceptIcons()
{
//FIXME: not used anymore
}
void TDEIconDialog::showIcons()
{
d->ui->iconCanvas->clear();
TQStringList filelist;
TDEIcon::Context context = static_cast<TDEIcon::Context>(d->extendedContext - 1);
switch (d->extendedContext)
{
case RECENT:
filelist = d->recentList;
break;
case OTHER:
filelist = mFileList;
break;
case ALL:
filelist = mFileList;
context = TDEIcon::Any;
// ** Fallthrough to next case **
default:
TQStringList list;
if (d->m_bStrictIconSize)
list=mpLoader->queryIcons(mGroupOrSize, context);
else
list=mpLoader->queryIconsByContext(mGroupOrSize, context);
// Remove path & extension
for ( TQStringList::iterator it = list.begin(); it != list.end(); ++it)
filelist.append(TQFileInfo(*it).baseName());
}
// Remove duplicate icons FIXME: TQt4 we can just use TQSet
filelist.sort();
TQString prev;
for ( TQStringList::iterator it = filelist.begin(); it != filelist.end(); )
{
if (*it == prev)
{
it = filelist.remove(it);
}
else
{
prev = *it;
++it;
}
}
d->ui->iconCanvas->setGroupOrSize(mGroupOrSize);
d->ui->iconCanvas->loadFiles(filelist);
}
void TDEIconDialog::setStrictIconSize(bool b)
{
d->m_bStrictIconSize=b;
}
bool TDEIconDialog::strictIconSize() const
{
return d->m_bStrictIconSize;
}
void TDEIconDialog::setIconSize( int size )
{
// see TDEIconLoader, if you think this is weird
if ( size == 0 )
mGroupOrSize = TDEIcon::Desktop; // default Group
else
mGroupOrSize = -size; // yes, TDEIconLoader::queryIconsByContext is weird
}
int TDEIconDialog::iconSize() const
{
// 0 or any other value ==> mGroupOrSize is a group, so we return 0
return (mGroupOrSize < 0) ? -mGroupOrSize : 0;
}
#ifndef KDE_NO_COMPAT
TQString TDEIconDialog::selectIcon(TDEIcon::Group group, TDEIcon::Context context, bool user)
{
setup( group, context, false, 0, user );
return openDialog();
}
#endif
void TDEIconDialog::setup(TDEIcon::Group group, TDEIcon::Context context,
bool strictIconSize, int iconSize, bool user )
{
setup(group, context, strictIconSize, iconSize, user, false, false);
}
void TDEIconDialog::setup(TDEIcon::Group group, TDEIcon::Context context,
bool strictIconSize, int iconSize, bool user,
bool lockContext, bool lockBrowse )
{
d->m_bStrictIconSize = strictIconSize;
d->ui->iconCanvas->setStrictIconSize(strictIconSize);
mGroupOrSize = (iconSize == 0) ? group : -iconSize;
mType = user;
d->extendedContext = static_cast<ExtendedContext>( ( context == TDEIcon::Any ) ? ALL : context + 1 );
// We cannot change layout because it is protected ;-(
// FIXME: TQt4 we will be able to inherit from both TQDialog and our GUI
d->ui->listBox->setEnabled(!lockContext);
d->ui->browseButton->setEnabled(!lockBrowse);
d->ui->listBox->setHidden(lockContext && lockBrowse);
d->ui->browseButton->setHidden(lockContext && lockBrowse);
d->ui->listBox->setCurrentItem(d->extendedContext);
}
const TQString & TDEIconDialog::customLocation( ) const
{
return d->customLocation;
}
void TDEIconDialog::setCustomLocation( const TQString& location )
{
d->customLocation = location;
if (location.isEmpty())
{
mFileList = TDEGlobal::dirs()->findAllResources("appicon", TQString::fromLatin1("*.png"));
} else {
mFileList = mpLoader->queryIconsByDir(location);
}
}
TQString TDEIconDialog::openDialog()
{
showIcons();
if ( exec() == Accepted )
{
if (!d->custom.isEmpty())
return d->custom;
else
return d->ui->iconCanvas->getCurrent();
}
else
{
return TQString();
}
}
void TDEIconDialog::showDialog()
{
d->custom = TQString();
// Make it so minimumSize returns correct value
d->ui->filterLabel->hide();
d->ui->searchLine->hide();
d->ui->progressBar->show();
setModal(false);
show();
// FIXME: this should be before show() but it doesn't work ;-(
resize(minimumSize());
showIcons();
}
void TDEIconDialog::slotOk()
{
TQString key = !d->custom.isEmpty() ? d->custom : d->ui->iconCanvas->getCurrent();
// Append to list of recent icons
if (!d->recentList.contains(key))
{
d->recentList.push_back(key);
// Limit recent list in size
while ( (int)d->recentList.size() > d->recentMax )
d->recentList.pop_front();
}
emit newIconName(key);
KDialogBase::slotOk();
}
TQString TDEIconDialog::getIcon(TDEIcon::Group group, TDEIcon::Context context,
bool strictIconSize, int iconSize, bool user,
TQWidget *parent, const TQString &caption)
{
TDEIconDialog dlg(parent, "icon dialog");
dlg.setup( group, context, strictIconSize, iconSize, user );
if (!caption.isNull())
dlg.setCaption(caption);
return dlg.openDialog();
}
void TDEIconDialog::slotBrowse()
{
// Create a file dialog to select a PNG, XPM or SVG file,
// with the image previewer shown.
// KFileDialog::getImageOpenURL doesn't allow svg.
KFileDialog dlg(TQString(), i18n("*.png *.xpm *.svg *.svgz|Icon Files (*.png *.xpm *.svg *.svgz)"),
this, "filedialog", true);
dlg.setOperationMode( KFileDialog::Opening );
dlg.setCaption( i18n("Open") );
dlg.setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly );
KImageFilePreview *ip = new KImageFilePreview( &dlg );
dlg.setPreviewWidget( ip );
dlg.exec();
TQString file = dlg.selectedFile();
if (!file.isEmpty())
{
d->custom = file;
if ( mType == 1 )
setCustomLocation(TQFileInfo( file ).dirPath( true ));
slotOk();
}
}
void TDEIconDialog::slotContext(int id)
{
d->extendedContext = static_cast<ExtendedContext>(id);
showIcons();
}
void TDEIconDialog::slotStartLoading(int steps)
{
if (steps < 10)
d->ui->progressBar->hide();
else
{
d->ui->progressBar->setTotalSteps(steps);
d->ui->progressBar->setProgress(0);
d->ui->progressBar->show();
d->ui->filterLabel->hide();
d->ui->searchLine->hide();
}
}
void TDEIconDialog::slotProgress(int p)
{
d->ui->progressBar->setProgress(p);
}
void TDEIconDialog::slotFinished()
{
d->ui->progressBar->hide();
d->ui->filterLabel->show();
d->ui->searchLine->show();
}
class TDEIconButton::TDEIconButtonPrivate
{
public:
TDEIconButtonPrivate() {
m_bStrictIconSize = false;
iconSize = 0; // let TDEIconLoader choose the default
}
~TDEIconButtonPrivate() {}
bool m_bStrictIconSize;
bool lockUser;
bool lockCustom;
int iconSize;
};
/*
* TDEIconButton: A "choose icon" pushbutton.
*/
TDEIconButton::TDEIconButton(TQWidget *parent, const char *name)
: TQPushButton(parent, name)
{
init( TDEGlobal::iconLoader() );
}
TDEIconButton::TDEIconButton(TDEIconLoader *loader,
TQWidget *parent, const char *name)
: TQPushButton(parent, name)
{
init( loader );
}
void TDEIconButton::init( TDEIconLoader *loader )
{
d = new TDEIconButtonPrivate;
mGroup = TDEIcon::Desktop;
mContext = TDEIcon::Application;
mbUser = false;
mpLoader = loader;
mpDialog = 0L;
connect(this, TQT_SIGNAL(clicked()), TQT_SLOT(slotChangeIcon()));
}
TDEIconButton::~TDEIconButton()
{
delete mpDialog;
delete d;
}
void TDEIconButton::setStrictIconSize(bool b)
{
d->m_bStrictIconSize=b;
}
bool TDEIconButton::strictIconSize() const
{
return d->m_bStrictIconSize;
}
void TDEIconButton::setIconSize( int size )
{
d->iconSize = size;
}
int TDEIconButton::iconSize() const
{
return d->iconSize;
}
void TDEIconButton::setIconType(TDEIcon::Group group, TDEIcon::Context context, bool user)
{
mGroup = group;
mContext = context;
mbUser = user;
d->lockUser = false;
d->lockCustom = false;
}
void TDEIconButton::setIconType(TDEIcon::Group group, TDEIcon::Context context, bool user, bool lockUser, bool lockCustom)
{
mGroup = group;
mContext = context;
mbUser = user;
d->lockUser = lockUser;
d->lockCustom = lockCustom;
}
void TDEIconButton::setIcon(const TQString& icon)
{
mIcon = icon;
setIconSet(mpLoader->loadIconSet(mIcon, mGroup, d->iconSize));
if (!mpDialog)
{
mpDialog = new TDEIconDialog(mpLoader, this);
connect(mpDialog, TQT_SIGNAL(newIconName(const TQString&)), TQT_SLOT(newIconName(const TQString&)));
}
}
const TQString & TDEIconButton::customLocation( ) const
{
return mpDialog ? mpDialog->customLocation() : TQString();
}
void TDEIconButton::setCustomLocation(const TQString &custom)
{
if (!mpDialog)
{
mpDialog = new TDEIconDialog(mpLoader, this);
connect(mpDialog, TQT_SIGNAL(newIconName(const TQString&)), TQT_SLOT(newIconName(const TQString&)));
}
mpDialog->setCustomLocation(custom);
}
void TDEIconButton::resetIcon()
{
mIcon = TQString();
setIconSet(TQIconSet());
}
void TDEIconButton::slotChangeIcon()
{
if (!mpDialog)
{
mpDialog = new TDEIconDialog(mpLoader, this);
connect(mpDialog, TQT_SIGNAL(newIconName(const TQString&)), TQT_SLOT(newIconName(const TQString&)));
}
mpDialog->setup( mGroup, mContext, d->m_bStrictIconSize, d->iconSize, mbUser, d->lockUser, d->lockCustom );
mpDialog->showDialog();
}
void TDEIconButton::newIconName(const TQString& name)
{
if (name.isEmpty())
return;
TQIconSet iconset = mpLoader->loadIconSet(name, mGroup, d->iconSize);
setIconSet(iconset);
mIcon = name;
emit iconChanged(name);
}
void TDEIconCanvas::virtual_hook( int id, void* data )
{ TDEIconView::virtual_hook( id, data ); }
void TDEIconDialog::virtual_hook( int id, void* data )
{ KDialogBase::virtual_hook( id, data ); }
#include "kicondialog.moc"