fix tricky regression noticed by Vyacheslav Tokarev on Google Reader.
[kdelibs.git] / kio / kio / kmimetypechooser.cpp
blob2841b7bffe2aae543cdcb1837ae680c7c23bdd4a
1 /* This file is part of the KDE libraries
2 Copyright (C) 2001 - 2004 Anders Lund <anders@alweb.dk>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
19 #include "kmimetypechooser.h"
21 #include <kconfig.h>
22 #include <kiconloader.h>
23 #include <klocale.h>
24 #include <kmimetype.h>
25 #include <kshell.h>
26 #include <krun.h>
27 #include <ksycoca.h>
29 #include <QLabel>
30 #include <QLayout>
31 #include <QPushButton>
32 #include <QTreeWidget>
33 #include <kconfiggroup.h>
35 //BEGIN KMimeTypeChooserPrivate
36 class KMimeTypeChooserPrivate
38 public:
39 KMimeTypeChooserPrivate( KMimeTypeChooser *parent )
40 : q(parent),
41 mimeTypeTree(0),
42 btnEditMimeType(0)
46 void loadMimeTypes( const QStringList &selected = QStringList() );
48 void _k_editMimeType();
49 void _k_slotCurrentChanged(QTreeWidgetItem*);
50 void _k_slotSycocaDatabaseChanged(const QStringList&);
52 KMimeTypeChooser *q;
53 QTreeWidget *mimeTypeTree;
54 QPushButton *btnEditMimeType;
56 QString defaultgroup;
57 QStringList groups;
58 int visuals;
60 //END
62 //BEGIN KMimeTypeChooser
63 KMimeTypeChooser::KMimeTypeChooser( const QString &text,
64 const QStringList &selMimeTypes,
65 const QString &defaultGroup,
66 const QStringList &groupsToShow,
67 int visuals,
68 QWidget *parent )
69 : KVBox( parent ),
70 d(new KMimeTypeChooserPrivate(this))
72 d->defaultgroup = defaultGroup;
73 d->groups = groupsToShow;
74 d->visuals = visuals;
76 setSpacing( KDialog::spacingHint() );
78 if ( !text.isEmpty() )
80 new QLabel( text, this );
83 d->mimeTypeTree = new QTreeWidget( this );
84 QStringList headerLabels;
85 headerLabels.append( i18n("Mime Type") );
86 // d->mimeTypeTree->setColumnWidthMode( 0, QListView::Manual );
88 if ( visuals & Comments ) {
89 headerLabels.append( i18n("Comment") );
90 //d->mimeTypeTree->setColumnWidthMode( 1, Q3ListView::Manual );
92 if ( visuals & Patterns ) {
93 headerLabels.append( i18n("Patterns") );
96 // d->mimeTypeTree->setRootIsDecorated( true );
97 d->mimeTypeTree->setColumnCount(headerLabels.count());
98 d->mimeTypeTree->setHeaderLabels(headerLabels);
100 d->loadMimeTypes( selMimeTypes );
102 if (visuals & EditButton)
104 KHBox *btns = new KHBox( this );
105 ((QBoxLayout*)btns->layout())->addStretch(1);
106 d->btnEditMimeType = new QPushButton( i18n("&Edit..."), btns );
108 connect( d->btnEditMimeType, SIGNAL(clicked()), this, SLOT(_k_editMimeType()) );
109 d->btnEditMimeType->setEnabled( false );
110 connect( d->mimeTypeTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
111 this, SLOT(_k_editMimeType()));
112 connect( d->mimeTypeTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
113 this, SLOT(_k_slotCurrentChanged(QTreeWidgetItem*)) );
115 d->btnEditMimeType->setWhatsThis(i18n(
116 "Click this button to display the familiar KDE mime type editor.") );
120 KMimeTypeChooser::~KMimeTypeChooser()
122 delete d;
125 void KMimeTypeChooserPrivate::loadMimeTypes( const QStringList &_selectedMimeTypes )
127 QStringList selMimeTypes;
129 if ( !_selectedMimeTypes.isEmpty() )
130 selMimeTypes = _selectedMimeTypes;
131 else
132 selMimeTypes = q->mimeTypes();
134 mimeTypeTree->clear();
136 QMap<QString, QTreeWidgetItem*> groupItems;
137 const KMimeType::List mimetypes = KMimeType::allMimeTypes();
139 bool agroupisopen = false;
140 QTreeWidgetItem *idefault = 0; //open this, if all other fails
141 QTreeWidgetItem *firstChecked = 0; // make this one visible after the loop
143 foreach (const KMimeType::Ptr& mt, mimetypes)
145 const QString mimetype = mt->name();
146 const int index = mimetype.indexOf('/');
147 const QString maj = mimetype.left(index);
149 if ( !groups.isEmpty() && !groups.contains( maj ) )
150 continue;
152 QTreeWidgetItem *groupItem;
153 QMap<QString,QTreeWidgetItem*>::Iterator mit = groupItems.find( maj );
154 if ( mit == groupItems.end() )
156 groupItem = new QTreeWidgetItem( mimeTypeTree, QStringList(maj) );
157 groupItems.insert( maj, groupItem );
158 if ( maj == defaultgroup )
159 idefault = groupItem;
161 else
162 groupItem = mit.value();
164 const QString min = mimetype.mid(index+1);
165 QTreeWidgetItem *item = new QTreeWidgetItem( groupItem, QStringList(min) );
166 item->setIcon( 0, SmallIcon( mt->iconName() ) );
168 int cl = 1;
170 if ( visuals & KMimeTypeChooser::Comments )
172 item->setText( cl, mt->comment() );
173 cl++;
176 if ( visuals & KMimeTypeChooser::Patterns )
177 item->setText( cl, mt->patterns().join("; ") );
179 if ( selMimeTypes.contains(mimetype) ) {
180 item->setCheckState( 0, Qt::Checked );
181 groupItem->setExpanded( true );
182 agroupisopen = true;
183 if ( !firstChecked )
184 firstChecked = item;
185 } else {
186 item->setCheckState( 0, Qt::Unchecked );
190 if ( firstChecked )
191 mimeTypeTree->scrollToItem( firstChecked );
193 if ( !agroupisopen && idefault )
195 idefault->setExpanded( true );
196 mimeTypeTree->scrollToItem( idefault );
200 void KMimeTypeChooserPrivate::_k_editMimeType()
202 QTreeWidgetItem* item = mimeTypeTree->currentItem();
203 if ( !item || !item->parent() )
204 return;
205 QString mt = (item->parent())->text(0) + '/' + item->text(0);
206 // thanks to libkonq/konq_operations.cc
207 q->connect( KSycoca::self(), SIGNAL(databaseChanged(QStringList)),
208 q, SLOT(_k_slotSycocaDatabaseChanged(QStringList)) );
209 QString keditfiletype = QString::fromLatin1("keditfiletype");
210 KRun::runCommand( keditfiletype
211 #ifndef Q_OS_WIN
212 + " --parent " + QString::number( (ulong)q->topLevelWidget()->winId())
213 #endif
214 + ' ' + KShell::quoteArg(mt),
215 keditfiletype, keditfiletype /*unused*/, q->topLevelWidget());
218 void KMimeTypeChooserPrivate::_k_slotCurrentChanged(QTreeWidgetItem* item)
220 if ( btnEditMimeType )
221 btnEditMimeType->setEnabled( item->parent() );
224 void KMimeTypeChooserPrivate::_k_slotSycocaDatabaseChanged(const QStringList& changedResources)
226 if (changedResources.contains("xdgdata-mime"))
227 loadMimeTypes();
230 // recursive helper for mimeTypes()
231 static void getCheckedItems(QList<QTreeWidgetItem *> &lst, QTreeWidgetItem* parent)
233 for (int i = 0; i < parent->childCount(); ++i ) {
234 QTreeWidgetItem* item = parent->child(i);
235 if (item->checkState(0) == Qt::Checked)
236 lst.append(item);
237 getCheckedItems(lst, item);
241 static void getCheckedItems(QList<QTreeWidgetItem *>& lst, QTreeWidget* tree)
243 for (int i = 0; i < tree->topLevelItemCount(); ++i ) {
244 QTreeWidgetItem* topItem = tree->topLevelItem(i);
245 //if (topItem->checkState(0) == Qt::Checked)
246 // lst.append(topItem);
247 getCheckedItems(lst, topItem);
251 QStringList KMimeTypeChooser::mimeTypes() const
253 QStringList mimeList;
254 QList<QTreeWidgetItem *> checkedItems;
255 getCheckedItems(checkedItems, d->mimeTypeTree);
256 foreach(QTreeWidgetItem* item, checkedItems) {
257 mimeList.append( item->parent()->text(0) + '/' + item->text(0) );
259 return mimeList;
262 QStringList KMimeTypeChooser::patterns() const
264 QStringList patternList;
265 QList<QTreeWidgetItem *> checkedItems;
266 getCheckedItems(checkedItems, d->mimeTypeTree);
267 foreach(QTreeWidgetItem* item, checkedItems) {
268 KMimeType::Ptr p = KMimeType::mimeType( item->parent()->text(0) + '/' + item->text(0) );
269 Q_ASSERT(p);
270 patternList += p->patterns();
272 return patternList;
274 //END
276 //BEGIN KMimeTypeChooserDialog::Private
278 class KMimeTypeChooserDialog::Private
280 public:
281 Private( KMimeTypeChooserDialog *parent )
282 : q(parent)
286 void init();
288 KMimeTypeChooserDialog *q;
289 KMimeTypeChooser *m_chooser;
292 //END
294 //BEGIN KMimeTypeChooserDialog
295 KMimeTypeChooserDialog::KMimeTypeChooserDialog(
296 const QString &caption,
297 const QString& text,
298 const QStringList &selMimeTypes,
299 const QString &defaultGroup,
300 const QStringList &groupsToShow,
301 int visuals,
302 QWidget *parent )
303 : KDialog( parent ), d(new Private(this))
305 setCaption( caption );
306 d->init();
308 d->m_chooser = new KMimeTypeChooser( text, selMimeTypes,
309 defaultGroup, groupsToShow, visuals,
310 this );
311 setMainWidget(d->m_chooser);
314 KMimeTypeChooserDialog::KMimeTypeChooserDialog(
315 const QString &caption,
316 const QString& text,
317 const QStringList &selMimeTypes,
318 const QString &defaultGroup,
319 QWidget *parent )
320 : KDialog( parent ), d(new Private(this))
322 setCaption( caption );
323 d->init();
325 d->m_chooser = new KMimeTypeChooser( text, selMimeTypes,
326 defaultGroup, QStringList(),
327 KMimeTypeChooser::Comments|KMimeTypeChooser::Patterns|KMimeTypeChooser::EditButton,
328 this );
329 setMainWidget(d->m_chooser);
332 KMimeTypeChooser* KMimeTypeChooserDialog::chooser()
334 return d->m_chooser;
337 void KMimeTypeChooserDialog::Private::init()
339 q->setButtons( Cancel | Ok );
340 q->setModal( true );
341 q->setDefaultButton( Ok );
343 KConfigGroup group( KGlobal::config(), "KMimeTypeChooserDialog");
344 q->resize( group.readEntry("size", QSize(500,400)));
347 KMimeTypeChooserDialog::~KMimeTypeChooserDialog()
349 KConfigGroup group( KGlobal::config(), "KMimeTypeChooserDialog");
350 group.writeEntry("size", size());
352 delete d;
355 //END KMimeTypeChooserDialog
357 // kate: space-indent on; indent-width 2; replace-tabs on;
358 #include "kmimetypechooser.moc"