00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "kmimetypechooser.h"
00020
00021 #include <kconfig.h>
00022 #include <kiconloader.h>
00023 #include <klocale.h>
00024 #include <kmimetype.h>
00025 #include <kshell.h>
00026 #include <krun.h>
00027 #include <ksycoca.h>
00028
00029 #include <QLabel>
00030 #include <QLayout>
00031 #include <QPushButton>
00032 #include <QTreeWidget>
00033 #include <kconfiggroup.h>
00034
00035
00036 class KMimeTypeChooserPrivate
00037 {
00038 public:
00039 KMimeTypeChooserPrivate( KMimeTypeChooser *parent )
00040 : q(parent),
00041 mimeTypeTree(0),
00042 btnEditMimeType(0)
00043 {
00044 }
00045
00046 void loadMimeTypes( const QStringList &selected = QStringList() );
00047
00048 void _k_editMimeType();
00049 void _k_slotCurrentChanged(QTreeWidgetItem*);
00050 void _k_slotSycocaDatabaseChanged(const QStringList&);
00051
00052 KMimeTypeChooser *q;
00053 QTreeWidget *mimeTypeTree;
00054 QPushButton *btnEditMimeType;
00055
00056 QString defaultgroup;
00057 QStringList groups;
00058 int visuals;
00059 };
00060
00061
00062
00063 KMimeTypeChooser::KMimeTypeChooser( const QString &text,
00064 const QStringList &selMimeTypes,
00065 const QString &defaultGroup,
00066 const QStringList &groupsToShow,
00067 int visuals,
00068 QWidget *parent )
00069 : KVBox( parent ),
00070 d(new KMimeTypeChooserPrivate(this))
00071 {
00072 d->defaultgroup = defaultGroup;
00073 d->groups = groupsToShow;
00074 d->visuals = visuals;
00075 setSpacing(-1);
00076
00077 if ( !text.isEmpty() )
00078 {
00079 new QLabel( text, this );
00080 }
00081
00082 d->mimeTypeTree = new QTreeWidget( this );
00083 QStringList headerLabels;
00084 headerLabels.append( i18n("Mime Type") );
00085
00086
00087 if ( visuals & Comments ) {
00088 headerLabels.append( i18n("Comment") );
00089
00090 }
00091 if ( visuals & Patterns ) {
00092 headerLabels.append( i18n("Patterns") );
00093 }
00094
00095
00096 d->mimeTypeTree->setColumnCount(headerLabels.count());
00097 d->mimeTypeTree->setHeaderLabels(headerLabels);
00098
00099 d->loadMimeTypes( selMimeTypes );
00100
00101 if (visuals & EditButton)
00102 {
00103 KHBox *btns = new KHBox( this );
00104 ((QBoxLayout*)btns->layout())->addStretch(1);
00105 d->btnEditMimeType = new QPushButton( i18n("&Edit..."), btns );
00106
00107 connect( d->btnEditMimeType, SIGNAL(clicked()), this, SLOT(_k_editMimeType()) );
00108 d->btnEditMimeType->setEnabled( false );
00109 connect( d->mimeTypeTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
00110 this, SLOT(_k_editMimeType()));
00111 connect( d->mimeTypeTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
00112 this, SLOT(_k_slotCurrentChanged(QTreeWidgetItem*)) );
00113
00114 d->btnEditMimeType->setWhatsThis(i18n(
00115 "Click this button to display the familiar KDE mime type editor.") );
00116 }
00117 }
00118
00119 KMimeTypeChooser::~KMimeTypeChooser()
00120 {
00121 delete d;
00122 }
00123
00124 void KMimeTypeChooserPrivate::loadMimeTypes( const QStringList &_selectedMimeTypes )
00125 {
00126 QStringList selMimeTypes;
00127
00128 if ( !_selectedMimeTypes.isEmpty() )
00129 selMimeTypes = _selectedMimeTypes;
00130 else
00131 selMimeTypes = q->mimeTypes();
00132
00133 mimeTypeTree->clear();
00134
00135 QMap<QString, QTreeWidgetItem*> groupItems;
00136 const KMimeType::List mimetypes = KMimeType::allMimeTypes();
00137
00138 bool agroupisopen = false;
00139 QTreeWidgetItem *idefault = 0;
00140 QTreeWidgetItem *firstChecked = 0;
00141
00142 foreach (const KMimeType::Ptr& mt, mimetypes)
00143 {
00144 const QString mimetype = mt->name();
00145 const int index = mimetype.indexOf('/');
00146 const QString maj = mimetype.left(index);
00147
00148 if ( !groups.isEmpty() && !groups.contains( maj ) )
00149 continue;
00150
00151 QTreeWidgetItem *groupItem;
00152 QMap<QString,QTreeWidgetItem*>::Iterator mit = groupItems.find( maj );
00153 if ( mit == groupItems.end() )
00154 {
00155 groupItem = new QTreeWidgetItem( mimeTypeTree, QStringList(maj) );
00156 groupItems.insert( maj, groupItem );
00157 if ( maj == defaultgroup )
00158 idefault = groupItem;
00159 }
00160 else
00161 groupItem = mit.value();
00162
00163 const QString min = mimetype.mid(index+1);
00164 QTreeWidgetItem *item = new QTreeWidgetItem( groupItem, QStringList(min) );
00165 item->setIcon( 0, KIcon( mt->iconName() ) );
00166
00167 int cl = 1;
00168
00169 if ( visuals & KMimeTypeChooser::Comments )
00170 {
00171 item->setText( cl, mt->comment() );
00172 cl++;
00173 }
00174
00175 if ( visuals & KMimeTypeChooser::Patterns )
00176 item->setText( cl, mt->patterns().join("; ") );
00177
00178 if ( selMimeTypes.contains(mimetype) ) {
00179 item->setCheckState( 0, Qt::Checked );
00180 groupItem->setExpanded( true );
00181 agroupisopen = true;
00182 if ( !firstChecked )
00183 firstChecked = item;
00184 } else {
00185 item->setCheckState( 0, Qt::Unchecked );
00186 }
00187 }
00188
00189 if ( firstChecked )
00190 mimeTypeTree->scrollToItem( firstChecked );
00191
00192 if ( !agroupisopen && idefault )
00193 {
00194 idefault->setExpanded( true );
00195 mimeTypeTree->scrollToItem( idefault );
00196 }
00197 }
00198
00199 void KMimeTypeChooserPrivate::_k_editMimeType()
00200 {
00201 QTreeWidgetItem* item = mimeTypeTree->currentItem();
00202 if ( !item || !item->parent() )
00203 return;
00204 QString mt = (item->parent())->text(0) + '/' + item->text(0);
00205
00206 q->connect( KSycoca::self(), SIGNAL(databaseChanged(QStringList)),
00207 q, SLOT(_k_slotSycocaDatabaseChanged(QStringList)) );
00208 QString keditfiletype = QString::fromLatin1("keditfiletype");
00209 KRun::runCommand( keditfiletype
00210 #ifndef Q_OS_WIN
00211 + " --parent " + QString::number( (ulong)q->topLevelWidget()->winId())
00212 #endif
00213 + ' ' + KShell::quoteArg(mt),
00214 keditfiletype, keditfiletype , q->topLevelWidget());
00215 }
00216
00217 void KMimeTypeChooserPrivate::_k_slotCurrentChanged(QTreeWidgetItem* item)
00218 {
00219 if ( btnEditMimeType )
00220 btnEditMimeType->setEnabled( item->parent() );
00221 }
00222
00223 void KMimeTypeChooserPrivate::_k_slotSycocaDatabaseChanged(const QStringList& changedResources)
00224 {
00225 if (changedResources.contains("xdgdata-mime"))
00226 loadMimeTypes();
00227 }
00228
00229
00230 static void getCheckedItems(QList<QTreeWidgetItem *> &lst, QTreeWidgetItem* parent)
00231 {
00232 for (int i = 0; i < parent->childCount(); ++i ) {
00233 QTreeWidgetItem* item = parent->child(i);
00234 if (item->checkState(0) == Qt::Checked)
00235 lst.append(item);
00236 getCheckedItems(lst, item);
00237 }
00238 }
00239
00240 static void getCheckedItems(QList<QTreeWidgetItem *>& lst, QTreeWidget* tree)
00241 {
00242 for (int i = 0; i < tree->topLevelItemCount(); ++i ) {
00243 QTreeWidgetItem* topItem = tree->topLevelItem(i);
00244
00245
00246 getCheckedItems(lst, topItem);
00247 }
00248 }
00249
00250 QStringList KMimeTypeChooser::mimeTypes() const
00251 {
00252 QStringList mimeList;
00253 QList<QTreeWidgetItem *> checkedItems;
00254 getCheckedItems(checkedItems, d->mimeTypeTree);
00255 foreach(QTreeWidgetItem* item, checkedItems) {
00256 mimeList.append( item->parent()->text(0) + '/' + item->text(0) );
00257 }
00258 return mimeList;
00259 }
00260
00261 QStringList KMimeTypeChooser::patterns() const
00262 {
00263 QStringList patternList;
00264 QList<QTreeWidgetItem *> checkedItems;
00265 getCheckedItems(checkedItems, d->mimeTypeTree);
00266 foreach(QTreeWidgetItem* item, checkedItems) {
00267 KMimeType::Ptr p = KMimeType::mimeType( item->parent()->text(0) + '/' + item->text(0) );
00268 Q_ASSERT(p);
00269 patternList += p->patterns();
00270 }
00271 return patternList;
00272 }
00273
00274
00275
00276
00277 class KMimeTypeChooserDialog::Private
00278 {
00279 public:
00280 Private( KMimeTypeChooserDialog *parent )
00281 : q(parent)
00282 {
00283 }
00284
00285 void init();
00286
00287 KMimeTypeChooserDialog *q;
00288 KMimeTypeChooser *m_chooser;
00289 };
00290
00291
00292
00293
00294 KMimeTypeChooserDialog::KMimeTypeChooserDialog(
00295 const QString &caption,
00296 const QString& text,
00297 const QStringList &selMimeTypes,
00298 const QString &defaultGroup,
00299 const QStringList &groupsToShow,
00300 int visuals,
00301 QWidget *parent )
00302 : KDialog( parent ), d(new Private(this))
00303 {
00304 setCaption( caption );
00305 d->init();
00306
00307 d->m_chooser = new KMimeTypeChooser( text, selMimeTypes,
00308 defaultGroup, groupsToShow, visuals,
00309 this );
00310 setMainWidget(d->m_chooser);
00311 }
00312
00313 KMimeTypeChooserDialog::KMimeTypeChooserDialog(
00314 const QString &caption,
00315 const QString& text,
00316 const QStringList &selMimeTypes,
00317 const QString &defaultGroup,
00318 QWidget *parent )
00319 : KDialog( parent ), d(new Private(this))
00320 {
00321 setCaption( caption );
00322 d->init();
00323
00324 d->m_chooser = new KMimeTypeChooser( text, selMimeTypes,
00325 defaultGroup, QStringList(),
00326 KMimeTypeChooser::Comments|KMimeTypeChooser::Patterns|KMimeTypeChooser::EditButton,
00327 this );
00328 setMainWidget(d->m_chooser);
00329 }
00330
00331 KMimeTypeChooser* KMimeTypeChooserDialog::chooser()
00332 {
00333 return d->m_chooser;
00334 }
00335
00336 void KMimeTypeChooserDialog::Private::init()
00337 {
00338 q->setButtons( Cancel | Ok );
00339 q->setModal( true );
00340 q->setDefaultButton( Ok );
00341
00342 KConfigGroup group( KGlobal::config(), "KMimeTypeChooserDialog");
00343 q->resize( group.readEntry("size", QSize(500,400)));
00344 }
00345
00346 KMimeTypeChooserDialog::~KMimeTypeChooserDialog()
00347 {
00348 KConfigGroup group( KGlobal::config(), "KMimeTypeChooserDialog");
00349 group.writeEntry("size", size());
00350
00351 delete d;
00352 }
00353
00354
00355
00356
00357 #include "kmimetypechooser.moc"