Move keditfiletype to runtime since it's actually needed by KPropertiesDialog.

This also makes it possible to configure kde-wide file associations even without konqueror installed.
BUG: 179355

svn path=/trunk/KDE/kdebase/apps/; revision=942059
This commit is contained in:
David Faure 2009-03-20 22:09:13 +00:00
parent db9f4abf69
commit 6f0265a255
28 changed files with 0 additions and 3902 deletions

View file

@ -4,4 +4,3 @@ add_subdirectory( konq )
add_subdirectory( konqhtml )
add_subdirectory( performance )
add_subdirectory( kio )
add_subdirectory( filetypes )

View file

@ -1,41 +0,0 @@
add_subdirectory(tests)
set(libfiletypes_SRCS
filetypedetails.cpp
filegroupdetails.cpp
kservicelistwidget.cpp
typeslistitem.cpp
mimetypedata.cpp
mimetypewriter.cpp
newtypedlg.cpp
kserviceselectdlg.cpp
sharedmimeinfoversion.cpp
)
########### next target ###############
set(kcm_filetypes_SRCS filetypesview.cpp ${libfiletypes_SRCS})
kde4_add_plugin(kcm_filetypes ${kcm_filetypes_SRCS})
target_link_libraries(kcm_filetypes ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS})
install(TARGETS kcm_filetypes DESTINATION ${PLUGIN_INSTALL_DIR} )
########### next target ###############
set(keditfiletype_SRCS keditfiletype.cpp ${libfiletypes_SRCS})
kde4_add_executable(keditfiletype ${keditfiletype_SRCS})
target_link_libraries(keditfiletype ${KDE4_KIO_LIBS})
if (Q_WS_X11)
target_link_libraries(keditfiletype ${X11_X11_LIB})
endif (Q_WS_X11)
install(TARGETS keditfiletype ${INSTALL_TARGETS_DEFAULT_ARGS})
########### install files ###############
install( FILES filetypes.desktop DESTINATION ${SERVICES_INSTALL_DIR} )

View file

@ -1,2 +0,0 @@
#! /usr/bin/env bash
$XGETTEXT *.cpp -o $podir/filetypes.pot

View file

@ -1,71 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2000, 2007 David Faure <faure@kde.org>
Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "filegroupdetails.h"
#include "mimetypedata.h"
#include <QtGui/QLayout>
#include <QtGui/QRadioButton>
#include <QtGui/QButtonGroup>
#include <QtGui/QGroupBox>
#include <klocale.h>
FileGroupDetails::FileGroupDetails(QWidget *parent)
: QWidget( parent )
{
QVBoxLayout *secondLayout = new QVBoxLayout(this);
QGroupBox *autoEmbedBox = new QGroupBox( i18n("Left Click Action") );
m_autoEmbed = new QButtonGroup( autoEmbedBox );
secondLayout->addWidget( autoEmbedBox );
// The order of those two items is very important. If you change it, fix typeslistitem.cpp !
QRadioButton *r1 = new QRadioButton( i18n("Show file in embedded viewer"));
QRadioButton *r2 = new QRadioButton( i18n("Show file in separate viewer"));
QVBoxLayout *autoEmbedBoxLayout = new QVBoxLayout(autoEmbedBox);
autoEmbedBoxLayout->addWidget(r1);
autoEmbedBoxLayout->addWidget(r2);
m_autoEmbed->addButton(r1, 0);
m_autoEmbed->addButton(r2, 1);
connect(m_autoEmbed, SIGNAL( buttonClicked( int ) ), SLOT( slotAutoEmbedClicked( int ) ));
autoEmbedBox->setWhatsThis( i18n("Here you can configure what the Konqueror file manager"
" will do when you click on a file belonging to this group. Konqueror can display the file in"
" an embedded viewer or start up a separate application. You can change this setting for a"
" specific file type in the 'Embedding' tab of the file type configuration.") );
secondLayout->addStretch();
}
void FileGroupDetails::setMimeTypeData( MimeTypeData * mimeTypeData )
{
Q_ASSERT( mimeTypeData->isMeta() );
m_mimeTypeData = mimeTypeData;
m_autoEmbed->button( m_mimeTypeData->autoEmbed() )->setChecked( true );
}
void FileGroupDetails::slotAutoEmbedClicked(int button)
{
if ( !m_mimeTypeData )
return;
m_mimeTypeData->setAutoEmbed( (MimeTypeData::AutoEmbed)button );
emit changed(true);
}
#include "filegroupdetails.moc"

View file

@ -1,52 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2000, 2007 David Faure <faure@kde.org>
Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef FILEGROUPDETAILS_H
#define FILEGROUPDETAILS_H
#include <QtGui/QWidget>
class MimeTypeData;
class QButtonGroup;
/**
* This widget contains the details for a filetype group.
* Currently this only involves the embedding configuration.
*/
class FileGroupDetails : public QWidget
{
Q_OBJECT
public:
FileGroupDetails(QWidget *parent = 0);
void setMimeTypeData( MimeTypeData * mimeTypeData );
Q_SIGNALS:
void changed(bool);
protected Q_SLOTS:
void slotAutoEmbedClicked(int button);
private:
MimeTypeData * m_mimeTypeData;
// Embedding config
QButtonGroup *m_autoEmbed;
};
#endif

View file

@ -1,378 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2000, 2007 David Faure <faure@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
// Own
#include "filetypedetails.h"
#include "sharedmimeinfoversion.h"
// Qt
#include <QtGui/QBoxLayout>
#include <QtGui/QButtonGroup>
#include <QtGui/QCheckBox>
#include <QtGui/QLayout>
#include <QtGui/QListWidget>
#include <QtGui/QRadioButton>
#include <QLabel>
// KDE
#include <kconfig.h>
#include <kdebug.h>
#include <kicondialog.h>
#include <kinputdialog.h>
#include <klineedit.h>
#include <klocale.h>
#include <kpushbutton.h>
// Local
#include "kservicelistwidget.h"
#include "typeslistitem.h"
FileTypeDetails::FileTypeDetails( QWidget * parent )
: QWidget( parent ), m_mimeTypeData(0), m_item(0)
{
QVBoxLayout* topLayout = new QVBoxLayout(this);
m_mimeTypeLabel = new QLabel(this);
topLayout->addWidget(m_mimeTypeLabel, 0, Qt::AlignCenter);
m_tabWidget = new QTabWidget(this);
topLayout->addWidget(m_tabWidget);
QString wtstr;
// First tab - General
QWidget * firstWidget = new QWidget(m_tabWidget);
QVBoxLayout *firstLayout = new QVBoxLayout(firstWidget);
firstLayout->setMargin(KDialog::marginHint());
firstLayout->setSpacing(KDialog::spacingHint());
QHBoxLayout *hBox = new QHBoxLayout();
hBox->setSpacing(KDialog::spacingHint());
firstLayout->addLayout(hBox);
if (SharedMimeInfoVersion::supportsIcon()) {
iconButton = new KIconButton(firstWidget);
iconButton->setIconType(KIconLoader::Desktop, KIconLoader::MimeType);
connect(iconButton, SIGNAL(iconChanged(QString)), SLOT(updateIcon(QString)));
iconButton->setWhatsThis( i18n("This button displays the icon associated"
" with the selected file type. Click on it to choose a different icon.") );
iconButton->setFixedSize(70, 70);
iconLabel = 0;
hBox->addWidget(iconButton);
} else {
iconButton = 0;
iconLabel = new QLabel(firstWidget);
iconLabel->setWhatsThis( i18n("This is the icon associated with the selected file type. "
"Choosing a different icon requires shared-mime-info to be at least version 0.40.") );
iconLabel->setFixedSize(70, 70);
hBox->addWidget(iconLabel);
}
QGroupBox *gb = new QGroupBox(i18n("Filename Patterns"), firstWidget);
hBox->addWidget(gb);
hBox = new QHBoxLayout(gb);
hBox->setSpacing(KDialog::spacingHint());
extensionLB = new QListWidget(gb);
connect(extensionLB, SIGNAL(itemSelectionChanged()), SLOT(enableExtButtons()));
hBox->addWidget(extensionLB);
extensionLB->setFixedHeight(extensionLB->minimumSizeHint().height());
extensionLB->setWhatsThis( i18n("This box contains a list of patterns that can be"
" used to identify files of the selected type. For example, the pattern *.txt is"
" associated with the file type 'text/plain'; all files ending in '.txt' are recognized"
" as plain text files.") );
QVBoxLayout *vbox = new QVBoxLayout();
hBox->addLayout(vbox);
vbox->setSpacing(KDialog::spacingHint());
// vbox->setMargins(KDialog::spacingHint());
addExtButton = new KPushButton(i18n("Add..."), gb);
addExtButton->setIcon(KIcon("list-add"));
addExtButton->setEnabled(false);
connect(addExtButton, SIGNAL(clicked()),
this, SLOT(addExtension()));
vbox->addWidget(addExtButton);
addExtButton->setWhatsThis( i18n("Add a new pattern for the selected file type.") );
removeExtButton = new KPushButton(i18n("Remove"), gb);
removeExtButton->setIcon(KIcon("list-remove"));
removeExtButton->setEnabled(false);
connect(removeExtButton, SIGNAL(clicked()),
this, SLOT(removeExtension()));
vbox->addWidget(removeExtButton);
removeExtButton->setWhatsThis( i18n("Remove the selected filename pattern.") );
vbox->addStretch(1);
gb->setFixedHeight(gb->minimumSizeHint().height());
description = new KLineEdit(firstWidget);
description->setClearButtonShown(true);
connect(description, SIGNAL(textChanged(const QString &)),
SLOT(updateDescription(const QString &)));
QHBoxLayout *descriptionBox = new QHBoxLayout;
descriptionBox->addWidget(new QLabel(i18n("Description"),firstWidget));
descriptionBox->addWidget(description);
firstLayout->addLayout(descriptionBox);
wtstr = i18n("You can enter a short description for files of the selected"
" file type (e.g. 'HTML Page'). This description will be used by applications"
" like Konqueror to display directory content.");
description->setWhatsThis( wtstr );
serviceListWidget = new KServiceListWidget( KServiceListWidget::SERVICELIST_APPLICATIONS, firstWidget );
connect( serviceListWidget, SIGNAL(changed(bool)), this, SIGNAL(changed(bool)));
firstLayout->addWidget(serviceListWidget,5);
// Second tab - Embedding
QWidget * secondWidget = new QWidget(m_tabWidget);
QVBoxLayout *secondLayout = new QVBoxLayout(secondWidget);
secondLayout->setMargin(KDialog::marginHint());
secondLayout->setSpacing(KDialog::spacingHint());
m_autoEmbedBox = new QGroupBox( i18n("Left Click Action"), secondWidget );
secondLayout->setSpacing( KDialog::spacingHint() );
secondLayout->addWidget( m_autoEmbedBox );
m_autoEmbedBox->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
QRadioButton *embViewerRadio = new QRadioButton( i18n("Show file in embedded viewer") );
QRadioButton *sepViewerRadio = new QRadioButton( i18n("Show file in separate viewer") );
m_rbGroupSettings = new QRadioButton( QString("Use settings for '%1' group") );
m_chkAskSave = new QCheckBox( i18n("Ask whether to save to disk instead") );
connect(m_chkAskSave, SIGNAL( toggled(bool) ), SLOT( slotAskSaveToggled(bool) ));
m_autoEmbedGroup = new QButtonGroup(m_autoEmbedBox);
m_autoEmbedGroup->addButton(embViewerRadio, 0);
m_autoEmbedGroup->addButton(sepViewerRadio, 1);
m_autoEmbedGroup->addButton(m_rbGroupSettings, 2);
connect(m_autoEmbedGroup, SIGNAL( buttonClicked(int) ), SLOT( slotAutoEmbedClicked(int) ));
vbox = new QVBoxLayout(m_autoEmbedBox);
vbox->addWidget(embViewerRadio);
vbox->addWidget(sepViewerRadio);
vbox->addWidget(m_rbGroupSettings);
vbox->addWidget(m_chkAskSave);
m_autoEmbedBox->setWhatsThis( i18n("Here you can configure what the Konqueror file manager"
" will do when you click on a file of this type. Konqueror can display the file in"
" an embedded viewer or start up a separate application. If set to 'Use settings for G group',"
" Konqueror will behave according to the settings of the group G this type belongs to,"
" for instance 'image' if the current file type is image/png.") );
embedServiceListWidget = new KServiceListWidget( KServiceListWidget::SERVICELIST_SERVICES, secondWidget );
embedServiceListWidget->setMinimumHeight( serviceListWidget->sizeHint().height() );
connect( embedServiceListWidget, SIGNAL(changed(bool)), this, SIGNAL(changed(bool)));
secondLayout->addWidget(embedServiceListWidget);
m_tabWidget->addTab( firstWidget, i18n("&General") );
m_tabWidget->addTab( secondWidget, i18n("&Embedding") );
}
void FileTypeDetails::updateRemoveButton()
{
removeExtButton->setEnabled(extensionLB->count()>0);
}
void FileTypeDetails::updateIcon(const QString &icon)
{
if (!m_mimeTypeData)
return;
m_mimeTypeData->setUserSpecifiedIcon(icon);
if (m_item)
m_item->setIcon(icon);
emit changed(true);
}
void FileTypeDetails::updateDescription(const QString &desc)
{
if (!m_mimeTypeData)
return;
m_mimeTypeData->setComment(desc);
emit changed(true);
}
void FileTypeDetails::addExtension()
{
if ( !m_mimeTypeData )
return;
bool ok;
QString ext = KInputDialog::getText( i18n( "Add New Extension" ),
i18n( "Extension:" ), "*.", &ok, this );
if (ok) {
extensionLB->addItem(ext);
QStringList patt = m_mimeTypeData->patterns();
patt += ext;
m_mimeTypeData->setPatterns(patt);
updateRemoveButton();
emit changed(true);
}
}
void FileTypeDetails::removeExtension()
{
if (extensionLB->currentRow() == -1)
return;
if ( !m_mimeTypeData )
return;
QStringList patt = m_mimeTypeData->patterns();
patt.removeAll(extensionLB->currentItem()->text());
m_mimeTypeData->setPatterns(patt);
delete extensionLB->takeItem(extensionLB->currentRow());
updateRemoveButton();
emit changed(true);
}
void FileTypeDetails::slotAutoEmbedClicked( int button )
{
if ( !m_mimeTypeData || (button > 2))
return;
m_mimeTypeData->setAutoEmbed( (MimeTypeData::AutoEmbed) button );
updateAskSave();
emit changed(true);
}
void FileTypeDetails::updateAskSave()
{
if ( !m_mimeTypeData )
return;
MimeTypeData::AutoEmbed autoEmbed = m_mimeTypeData->autoEmbed();
if (m_mimeTypeData->isMeta() && autoEmbed == MimeTypeData::UseGroupSetting) {
// Resolve by looking at group (we could cache groups somewhere to avoid the re-parsing?)
autoEmbed = MimeTypeData(m_mimeTypeData->majorType()).autoEmbed();
}
const QString mimeType = m_mimeTypeData->name();
QString dontAskAgainName;
if (autoEmbed == MimeTypeData::Yes) // Embedded
dontAskAgainName = "askEmbedOrSave"+mimeType;
else
dontAskAgainName = "askSave"+mimeType;
KSharedConfig::Ptr config = KSharedConfig::openConfig("filetypesrc", KConfig::NoGlobals);
// default value
bool ask = config->group("Notification Messages").readEntry(dontAskAgainName, QString()).isEmpty();
// per-mimetype override if there's one
m_mimeTypeData->getAskSave(ask);
bool neverAsk = false;
if (autoEmbed == MimeTypeData::Yes) {
const KMimeType::Ptr mime = KMimeType::mimeType( mimeType );
if (mime) {
// SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC
// NOTE: Keep this function in sync with
// kdelibs/kparts/browserrun.cpp BrowserRun::askEmbedOrSave()
// Don't ask for:
// - html (even new tabs would ask, due to about:blank!)
// - dirs obviously (though not common over HTTP :),
// - images (reasoning: no need to save, most of the time, because fast to see)
// e.g. postscript is different, because takes longer to read, so
// it's more likely that the user might want to save it.
// - multipart/* ("server push", see kmultipart)
// - other strange 'internal' mimetypes like print/manager...
if ( mime->is( "text/html" ) ||
mime->is( "application/xml" ) ||
mime->is( "inode/directory" ) ||
mimeType.startsWith( "image" ) ||
mime->is( "multipart/x-mixed-replace" ) ||
mime->is( "multipart/replace" ) ||
mimeType.startsWith( "print" ) )
{
neverAsk = true;
}
}
}
m_chkAskSave->blockSignals(true);
m_chkAskSave->setChecked(ask && !neverAsk);
m_chkAskSave->setEnabled(!neverAsk);
m_chkAskSave->blockSignals(false);
}
void FileTypeDetails::slotAskSaveToggled(bool askSave)
{
if (!m_mimeTypeData)
return;
m_mimeTypeData->setAskSave(askSave);
emit changed(true);
}
void FileTypeDetails::setMimeTypeData( MimeTypeData * mimeTypeData, TypesListItem* item )
{
m_mimeTypeData = mimeTypeData;
m_item = item; // can be 0
Q_ASSERT(mimeTypeData);
m_mimeTypeLabel->setText(i18n("File type %1", mimeTypeData->name()));
if (iconButton)
iconButton->setIcon(mimeTypeData->icon());
else
iconLabel->setPixmap(DesktopIcon(mimeTypeData->icon()));
description->setText(mimeTypeData->comment());
m_rbGroupSettings->setText( i18n("Use settings for '%1' group", mimeTypeData->majorType() ) );
extensionLB->clear();
addExtButton->setEnabled(true);
removeExtButton->setEnabled(false);
serviceListWidget->setMimeTypeData( mimeTypeData );
embedServiceListWidget->setMimeTypeData( mimeTypeData );
m_autoEmbedGroup->button(mimeTypeData->autoEmbed())->setChecked(true);
m_rbGroupSettings->setEnabled( mimeTypeData->canUseGroupSetting() );
extensionLB->addItems(mimeTypeData->patterns());
updateAskSave();
}
void FileTypeDetails::enableExtButtons()
{
removeExtButton->setEnabled(true);
}
void FileTypeDetails::refresh()
{
if (!m_mimeTypeData)
return;
// Called when ksycoca has been updated -> refresh data, then widgets
m_mimeTypeData->refresh();
setMimeTypeData(m_mimeTypeData, m_item);
}
#include "filetypedetails.moc"

View file

@ -1,104 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2000, 2007 David Faure <faure@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef FILETYPEDETAILS_H
#define FILETYPEDETAILS_H
#include <QtGui/QTabWidget>
class KIconButton;
class MimeTypeData;
class TypesListItem;
class QLabel;
class QListWidget;
class QGroupBox;
class QButtonGroup;
class QCheckBox;
class QRadioButton;
class KLineEdit;
class KPushButton;
class KServiceListWidget;
/**
* This widget contains the right part of the file type configuration
* dialog, that shows the details for a file type.
* It is implemented as a separate class so that it can be used by
* the keditfiletype program to show the details of a single mimetype.
*/
class FileTypeDetails : public QWidget
{
Q_OBJECT
public:
FileTypeDetails(QWidget *parent = 0);
/**
* Set a non-gui "mimetype data" to work on,
* and optionally a gui "treeview item", to update its icon if set.
*/
void setMimeTypeData( MimeTypeData * mimeTypeData, TypesListItem* item = 0 );
/**
* Called when ksycoca has changed
*/
void refresh();
protected:
void updateRemoveButton();
void updateAskSave();
Q_SIGNALS:
void embedMajor(const QString &major, bool &embed); // To adjust whether major type is being embedded
void changed(bool);
protected Q_SLOTS:
void updateIcon(const QString &icon);
void updateDescription(const QString &desc);
void addExtension();
void removeExtension();
void enableExtButtons();
void slotAutoEmbedClicked(int button);
void slotAskSaveToggled(bool);
private:
MimeTypeData* m_mimeTypeData;
TypesListItem* m_item; // can be 0, in keditfiletype!
QLabel* m_mimeTypeLabel;
QTabWidget* m_tabWidget;
// First tab - General
KIconButton* iconButton;
QLabel* iconLabel; // if icon cannot be changed
QListWidget *extensionLB;
KPushButton *addExtButton, *removeExtButton;
KLineEdit *description;
KServiceListWidget *serviceListWidget;
// Second tab - Embedding
QGroupBox *m_autoEmbedBox;
QButtonGroup *m_autoEmbedGroup;
KServiceListWidget *embedServiceListWidget;
QRadioButton *m_rbOpenSeparate;
QCheckBox *m_chkAskSave;
QRadioButton *m_rbGroupSettings;
};
#endif

View file

@ -1,235 +0,0 @@
[Desktop Entry]
Icon=preferences-desktop-filetype-association
Type=Service
X-KDE-ServiceTypes=KCModule
Exec=kcmshell4 filetypes
X-DocPath=kcontrol/filetypes/index.html
X-KDE-Library=kcm_filetypes
X-KDE-ParentApp=kcontrol
X-KDE-System-Settings-Parent-Category=advanced-user-settings
Name=File Associations
Name[af]=Lêer Assosiasies
Name[ar]=ارتباطات الملفات
Name[as]=ি
Name[be]=Асацыяцыі файлаў
Name[be@latin]=Poviazi dla fajłaŭ
Name[bg]=Файлови асоциации
Name[bn]= ি
Name[bn_IN]=-ি ি
Name[br]=Kevreañ restroù
Name[ca]=Associacions de fitxers
Name[ca@valencia]=Associacions de fitxers
Name[cs]=Asociace souborů
Name[csb]=Pòwiązania lopków
Name[cy]=Cysylltiadau Ffeiliau
Name[da]=Filassociationer
Name[de]=Dateizuordnungen
Name[el]=Συσχετίσεις αρχείων
Name[eo]=Dosiera kunligaro
Name[es]=Asociaciones de archivo
Name[et]=Failide seosed
Name[eu]=Fitxategi elkarketak
Name[fa]=انجمنهای پرونده
Name[fi]=Tiedostosidokset
Name[fr]=Associations de fichiers
Name[fy]=Triemassosjaasjes
Name[ga]=Comhcheangail Chomhaid
Name[gl]=Asociacións de ficheiros
Name[gu]=
Name[he]=שיוכי קבצים
Name[hi]= ि
Name[hne]= ि
Name[hr]=Pridruživanja datoteka
Name[hsb]=Datajowe asociacije
Name[hu]=Fájltársítások
Name[is]=Skráavensl
Name[it]=Associazioni file
Name[ja]=
Name[ka]=
Name[kk]=Файл сәйкестіктері
Name[km]=
Name[kn]=
Name[ko]=
Name[ku]=Têkiliyên Pelan
Name[lt]=Failų sąsajos
Name[lv]=Failu asociācijas
Name[mai]= ि
Name[mk]=Асоцијации на датотеки
Name[ml]=
Name[mr]= ि
Name[nb]=Filtilknytninger
Name[nds]=Datei-Toornen
Name[ne]=
Name[nl]=Bestandsassociaties
Name[nn]=Filtilknytingar
Name[oc]=Associacions de fichièrs
Name[or]=
Name[pa]=
Name[pl]=Skojarzenia plików
Name[pt]=Associação de Ficheiros
Name[pt_BR]=Associações de arquivos
Name[ro]=Asociere fișiere
Name[ru]=Привязки файлов
Name[se]=Fiilačatnagasat
Name[si]=
Name[sk]=Asociácie súborov
Name[sl]=Datotečne povezave
Name[sr]=Придружења фајловима
Name[sr@latin]=Pridruženja fajlovima
Name[sv]=Filbindningar
Name[ta]=
Name[te]=
Name[tg]=Бастани файлҳо
Name[th]=
Name[tr]=Dosya İlişkileri
Name[uk]=Привязка файлів
Name[uz]=Fayl turi bilan\nbogʻliqlar
Name[uz@cyrillic]=Файл тури билан\nбоғлиқлар
Name[vi]=Tp tin tương ng
Name[wa]=Assoçnaedje di fitchîs
Name[x-test]=xxFile Associationsxx
Name[xh]=Uyelemaniso Lwefayile
Name[zh_CN]=
Name[zh_TW]=
Comment=Configure file associations
Comment[af]=Konfigureer lêer assosiasies
Comment[ar]=اضبط ارتباطات الملفات
Comment[as]=ি ি
Comment[be]=Настаўленні асацыяцыяў файлаў
Comment[be@latin]=Naładź poviazi dla fajłaŭ
Comment[bg]=Настройване и асоцииране на файлови типове с програми
Comment[bn]= ি ি
Comment[bn_IN]= ি ি
Comment[br]=Kefluniañ kevreañ restroù
Comment[ca]=Configura les associacions de fitxers
Comment[ca@valencia]=Configura les associacions de fitxers
Comment[cs]=Nastavit asociace souborů
Comment[csb]=Konfigùracëjô pòwiązaniów lopków
Comment[cy]=Ffurfweddu cysylltiadau ffeiliau
Comment[da]=Indstil filassociationer
Comment[de]=Dateizuordnungen vornehmen
Comment[el]=Ρύθμιση των συσχετίσεων αρχείων
Comment[eo]=Agordi la ligojn de programoj al dosiertipoj
Comment[es]=Configuración de asociaciones de archivos
Comment[et]=Failide seoste seadistamine
Comment[eu]=Fitxategi elkarketak konfiguratzen ditu
Comment[fa]=پیکربندی انجمنهای پرونده
Comment[fi]=Tiedostosidokset
Comment[fr]=Configuration des associations de fichiers
Comment[fy]=Hjir kinne jo de triemassosjaasjes ynstelle
Comment[ga]=Cumraigh comhcheangail chomhaid
Comment[gl]=Configurar as asociacións de ficheiros
Comment[gu]= િ
Comment[he]=שינוי הגדרות שיוכי הקבצים
Comment[hi]= ि ि
Comment[hne]= ि ि
Comment[hr]=Konfiguriranje pridruživanja datoteka
Comment[hsb]=Konfiguracija datajowych asociacijow
Comment[hu]=A fájlhozzárendelések módosítása
Comment[is]=Stilla skráavensl
Comment[it]=Configura associazioni dei file
Comment[ja]=
Comment[ka]=
Comment[kk]=Файл сәйкестіктерін баптау
Comment[km]=
Comment[kn]= ಿ
Comment[ko]=
Comment[ku]=Têkiliyên pelan ava bike
Comment[lt]=Konfigūruoti failų sąsajas
Comment[lv]=Konfigurēt failu asociācijas
Comment[mai]= ि ि
Comment[mk]=Конфигурирајте ги асоцијациите на датотеките
Comment[ml]= ി
Comment[mr]= ि
Comment[nb]=Tilpass filtilknytninger
Comment[nds]=Instellen, welk Dateitypen welk Programmen tohöört
Comment[ne]= ि
Comment[nl]=Hier kunt u de bestandsassociaties instellen
Comment[nn]=Set opp filassosiasjonar
Comment[or]= ି
Comment[pa]=
Comment[pl]=Konfiguracja skojarzeń plików
Comment[pt]=Configuração das associações de ficheiros
Comment[pt_BR]=Configurar associações de arquivos
Comment[ro]=Configurează asocierea fișierelor cu aplicații
Comment[ru]=Настройка привязки файлов
Comment[se]=Heivet fiilačatnagasaid
Comment[sk]=Nastavenie asociácií súborov
Comment[sl]=Nastavi datotečne povezave
Comment[sr]=Подешавање придружења фајловима
Comment[sr@latin]=Podešavanje pridruženja fajlovima
Comment[sv]=Anpassa filbindningar
Comment[ta]= ி
Comment[te]= ి
Comment[tg]=Танзимоти бастани файлҳо
Comment[th]=
Comment[tr]=Dosya ilişkilerini yapılandır
Comment[uk]=Налаштування привязки файлів
Comment[uz]=Fayl turi bilan bogʻliqlarni moslash
Comment[uz@cyrillic]=Файл тури билан боғлиқларни мослаш
Comment[vi]=Cu hình tp tin tương ng
Comment[wa]=Apontyî les assoçnaedjes di fitchîs
Comment[x-test]=xxConfigure file associationsxx
Comment[xh]=Qwalasela uloyamiso lwefayile
Comment[zh_CN]=
Comment[zh_TW]=
X-KDE-Keywords=Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern
X-KDE-Keywords[be]=Тыпы файлаў,асацыяцыі файлаў,сувязі файлаў,тыпы MIME,шаблоны файлаў,файлы,шаблон,Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern
X-KDE-Keywords[bg]=Keywords=файл, файлове, асоциация, асоциации, връзки, изпълнение, връзка, програма, тип на файл, тип, Filetypes, File Associations, Mime Types, File Patterns, Files, Pattern
X-KDE-Keywords[ca]=Tipus de fitxer,Associacions de fitxers,Tipus Mime,Patrons de fitxer,Fitxers,Patró
X-KDE-Keywords[cs]=Typy souborů,Asociace souborů,MIME typy,Vzory souborů,Soubory,Vzor
X-KDE-Keywords[csb]=ôrt lopków,pòwiązania lopków,ôrtë MIME,mùster lopków,lopczi,mùster
X-KDE-Keywords[cy]=Mathau o Ffeiliau,Cysylltiadau Ffeil,Mathau o Mime,Patrymau Ffeil,Ffeiliau,Patrwm
X-KDE-Keywords[da]=Filtyper,Filassociationer,Mimetyper,Filmønstre,Filer,mønstre
X-KDE-Keywords[de]=Dateitypen,Dateizuordnungen,MIME-Typen,Dateimuster,Filter,Muster,Dateien
X-KDE-Keywords[el]=Τύποι αρχείων,Συσχετίσεις αρχείων,Τύποι mime,Μοτίβα αρχείων,Αρχεία,Μοτίβο
X-KDE-Keywords[eo]=dosiertipoj,asocioj,MIME,dosieroj,ŝablonoj,dosieroj,MIME-tipoj
X-KDE-Keywords[es]=Tipos de fichero,Asociaciones de fichero,Tipos MIME,Patrones de fichero,Ficheros,Patrón
X-KDE-Keywords[et]=Failitüübid,Failide seosed,MIME tüübid,failimustrid,failid,mustrid
X-KDE-Keywords[eu]=Fitxategi motak,Fitxategi elkarketak,Mime motak, Fitxategi ereduak,Fitxategiak,Eredua
X-KDE-Keywords[fa]=انواع پرونده، انجمنهای پرونده، انواع مایم، الگوهای پرونده، پروندهها، الگو
X-KDE-Keywords[fi]=Tiedostotyypit,Tiedostosidokset,Mimetyypit,Tiedostokuviot,Tiedostot,Kuvio
X-KDE-Keywords[fr]=types de fichiers,associations de fichiers,types MIME,motifs de fichier,fichiers,motif,extension,extensions de fichiers,applications
X-KDE-Keywords[fy]=Triemtypen,Triemtaheaksels,Triemassosjaasjes,mime types,Triempatroanen,Taheaksels,Triemmen
X-KDE-Keywords[gl]=Tipos de ficheiro, Asociacións de ficheiro,Tipos Mime,Patróns de ficheiro,Ficheiros,Patrón
X-KDE-Keywords[he]=תבניות קבצים,קבצים,תבנית,סוגי קבצים,שיוכי קבצים,טיפוסי,Mime,Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern
X-KDE-Keywords[hr]=Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,Vrste datoteka,Pridruživanje datoteka,MIME vrste,Uzorci datoteka,datoteke,uzorci
X-KDE-Keywords[hu]=fájltípusok,fájlhozzárendelések,MIME-típusok,fájlminták,fájlok,minta
X-KDE-Keywords[is]=Skráartegund,Skráavensl,Samhengi skráa,skráarbindingar,Mime-tög,síur,skrár,mynstur
X-KDE-Keywords[it]=tipi di file,associazioni file,tipi MIME,MIME,pattern dei file,file,motivi dei file,schemi
X-KDE-Keywords[ja]=,,,,,
X-KDE-Keywords[km]= Mime
X-KDE-Keywords[ko]=Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern, , ,
X-KDE-Keywords[lt]=Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,Failų tipai,Failų sąsajos,Mime Tipai,Failų modeliai,Failo,Modeliai, failų sietys
X-KDE-Keywords[lv]=Failutipi,Failu Asociācijas,Maime Tipi,Failu Maskas,Faili,Maskas
X-KDE-Keywords[mk]=Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,Типови на датотеки,Асоцијации на датотеки,типови,Датотеки
X-KDE-Keywords[nb]=Filtyper,Filtilknytninger,Mime-typer,Filmønster,filer
X-KDE-Keywords[nds]=Dateitypen,Datei-Tohören,Mime Typen,Dateimuster,Datei,Muster
X-KDE-Keywords[ne]= , , , , ,
X-KDE-Keywords[nl]=bestandstypen,bestandsextensies,bestandsassociaties,mime types,bestandspatronen,extensies,bestanden
X-KDE-Keywords[nn]=filtypar,filtilknytingar,MIME-typar,filmønster,filer,mønster
X-KDE-Keywords[pa]=Filetypes,File Associations,Mime Types,File Patterns,,Pattern, ਿ,
X-KDE-Keywords[pl]=Typy plików,skojarzenia plików,typy MIME,wzorce plików,pliki,wzorzec
X-KDE-Keywords[pt]=Tipos de Ficheiros,Associações a Ficheiros,Tipos MIME,Padrões de Ficheiros,Ficheiros,Padrão
X-KDE-Keywords[pt_BR]=Tipos de Arquivo,Associações de Arquivo,Tipos MIME,Padrões de Arquivo,Arquivos,Padrão
X-KDE-Keywords[ro]=tipuri de fişiere,asocieri fişiere,tipuri MIME,modele de fişiere,fişiere
X-KDE-Keywords[se]=Fiilašlájat,Fiilačatnagasat,Mime-šlájat,Fiilaminsttar, fiillat,minsttar
X-KDE-Keywords[sl]=vrste datotek,vezi datotek,vzorci datotek,datoteke,vzorec
X-KDE-Keywords[sr]=Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,врсте фајлова,узорци фајлова,узорак,придружење,MIME типови
X-KDE-Keywords[sr@latin]=Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,vrste fajlova,uzorci fajlova,uzorak,pridruženje,MIME tipovi
X-KDE-Keywords[sv]=Filtyper,Filbindningar,Mime-typer,Filmönster,Filer,Mönster
X-KDE-Keywords[ta]= , , , ிி,,ிி
X-KDE-Keywords[th]=,, Mime,,,
X-KDE-Keywords[tr]=Dosya Türleri,Dosya İlişkileri,Mime Türleri,Dosya Kalıpları,Dosyalar
X-KDE-Keywords[uk]=типи файлів,асоціації файлів,типи MIME,MIME,шаблони файлів,файли,взірці,файли
X-KDE-Keywords[uz]=Файл турлари,Файл билан боғланган дастурлар,MIME турлари,Файл намуналари,Файллар,Намуна
X-KDE-Keywords[vi]=Kiu tp tin,Tp tin tương ng,Kiu MIME,Mu tp tin,Tp tin, Mu
X-KDE-Keywords[wa]=Sôres di fitchîs,assoçnaedjes di fitchîs,sôres MIME,patrons d' fitchîs,fitchîs,patrons
X-KDE-Keywords[x-test]=xxFiletypes,File Associations,Mime Types,File Patterns,Files,Patternxx
X-KDE-Keywords[xh]=Iindidi zefayile,Unxubelelaniso lwefayile,Iindidi zeMime,Imilinganiselo yefayile,Iifayile,Umlinganiselo
X-KDE-Keywords[zh_CN]=Filetypes,File Associations,Mime Types,File Patterns,Files,,,Mime ,,,
X-KDE-Keywords[zh_TW]=Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,,,MIME ,,,

View file

@ -1,445 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2000 - 2008 David Faure <faure@kde.org>
Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
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 ) version 3 or, at the discretion of KDE e.V. ( which shall
act as a proxy as in section 14 of the GPLv3 ), any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
// Own
#include "filetypesview.h"
#include "mimetypewriter.h"
// Qt
#include <QtGui/QLabel>
#include <QtGui/QLayout>
#include <QtCore/QTimer>
#include <QtGui/QBoxLayout>
#include <QFile>
#include <qdbusconnection.h>
#include <qdbusmessage.h>
// KDE
#include <kapplication.h>
#include <kbuildsycocaprogressdialog.h>
#include <kcursor.h>
#include <kdebug.h>
#include <klineedit.h>
#include <klocale.h>
#include <kpushbutton.h>
#include <kservicetypeprofile.h>
#include <ksycoca.h>
#include <kpluginfactory.h>
#include <kpluginloader.h>
// Local
#include "newtypedlg.h"
#include "filetypedetails.h"
#include "filegroupdetails.h"
K_PLUGIN_FACTORY(FileTypesViewFactory, registerPlugin<FileTypesView>();)
K_EXPORT_PLUGIN(FileTypesViewFactory("filetypes"))
FileTypesView::FileTypesView(QWidget *parent, const QVariantList &)
: KCModule(FileTypesViewFactory::componentData(), parent)
{
m_fileTypesConfig = KSharedConfig::openConfig("filetypesrc", KConfig::NoGlobals);
setQuickHelp( i18n("<p><h1>File Associations</h1>"
" This module allows you to choose which applications are associated"
" with a given type of file. File types are also referred to as MIME types"
" (MIME is an acronym which stands for \"Multipurpose Internet Mail"
" Extensions\").</p><p> A file association consists of the following:"
" <ul><li>Rules for determining the MIME-type of a file, for example"
" the filename pattern *.png, which means 'all files with names that end"
" in .png', is associated with the MIME type \"image/png\";</li>"
" <li>A short description of the MIME-type, for example the description"
" of the MIME type \"image/png\" is simply 'PNG image';</li>"
" <li>An icon to be used for displaying files of the given MIME-type,"
" so that you can easily identify the type of file in a file"
" manager or file-selection dialog (at least for the types you use often);</li>"
" <li>A list of the applications which can be used to open files of the"
" given MIME-type -- if more than one application can be used then the"
" list is ordered by priority.</li></ul>"
" You may be surprised to find that some MIME types have no associated"
" filename patterns; in these cases, KDE is able to determine the"
" MIME-type by directly examining the contents of the file.</p>"));
KServiceTypeProfile::setConfigurationMode();
setButtons(Help | Apply);
QString wtstr;
QHBoxLayout* l = new QHBoxLayout(this);
QVBoxLayout* leftLayout = new QVBoxLayout();
leftLayout->setSpacing(KDialog::spacingHint());
l->addLayout( leftLayout );
patternFilterLE = new KLineEdit(this);
patternFilterLE->setClearButtonShown(true);
patternFilterLE->setClickMessage( i18n("F&ind file type or filename pattern:").remove(':').remove('&')/*TODO remove colon*/ );
leftLayout->addWidget(patternFilterLE);
connect(patternFilterLE, SIGNAL(textChanged(const QString &)),
this, SLOT(slotFilter(const QString &)));
wtstr = i18n("Enter a part of a filename pattern, and only file types with a "
"matching file pattern will appear in the list. Alternatively, enter "
"a part of a file type name as it appears in the list.");
patternFilterLE->setWhatsThis( wtstr );
typesLV = new TypesListTreeWidget(this);
typesLV->setHeaderLabel(i18n("Known Types"));
leftLayout->addWidget(typesLV);
connect(typesLV, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
this, SLOT(updateDisplay(QTreeWidgetItem *)));
connect(typesLV, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
this, SLOT(slotDoubleClicked(QTreeWidgetItem *)));
typesLV->setWhatsThis( i18n("Here you can see a hierarchical list of"
" the file types which are known on your system. Click on the '+' sign"
" to expand a category, or the '-' sign to collapse it. Select a file type"
" (e.g. text/html for HTML files) to view/edit the information for that"
" file type using the controls on the right.") );
QHBoxLayout* btnsLay = new QHBoxLayout();
leftLayout->addLayout(btnsLay);
btnsLay->addStretch(1);
KPushButton *addTypeB = new KPushButton(i18n("Add..."), this);
addTypeB->setIcon(KIcon("list-add"));
connect(addTypeB, SIGNAL(clicked()), SLOT(addType()));
btnsLay->addWidget(addTypeB);
addTypeB->setWhatsThis( i18n("Click here to add a new file type.") );
m_removeTypeB = new KPushButton(i18n("&Remove"), this);
m_removeTypeB->setIcon(KIcon("list-remove"));
connect(m_removeTypeB, SIGNAL(clicked()), SLOT(removeType()));
btnsLay->addWidget(m_removeTypeB);
m_removeTypeB->setEnabled(false);
m_removeTypeB->setWhatsThis( i18n("Click here to remove the selected file type.") );
// For the right panel, prepare a widget stack
m_widgetStack = new QStackedWidget(this);
l->addWidget( m_widgetStack );
// File Type Details
m_details = new FileTypeDetails( m_widgetStack );
connect( m_details, SIGNAL( changed(bool) ),
this, SLOT( setDirty(bool) ) );
connect( m_details, SIGNAL( embedMajor(const QString &, bool &) ),
this, SLOT( slotEmbedMajor(const QString &, bool &)));
m_widgetStack->insertWidget( 1, m_details /*id*/ );
// File Group Details
m_groupDetails = new FileGroupDetails( m_widgetStack );
connect( m_groupDetails, SIGNAL( changed(bool) ),
this, SLOT( setDirty(bool) ) );
m_widgetStack->insertWidget( 2,m_groupDetails /*id*/ );
// Widget shown on startup
m_emptyWidget = new QLabel( i18n("Select a file type by name or by extension"), m_widgetStack);
m_emptyWidget->setAlignment( Qt::AlignCenter );
m_widgetStack->insertWidget( 3,m_emptyWidget );
m_widgetStack->setCurrentWidget( m_emptyWidget );
connect( KSycoca::self(), SIGNAL( databaseChanged() ), SLOT( slotDatabaseChanged() ) );
}
FileTypesView::~FileTypesView()
{
}
void FileTypesView::setDirty(bool state)
{
emit changed(state);
m_dirty = state;
}
// To order the mimetype list
static bool mimeTypeLessThan(const KMimeType::Ptr& m1, const KMimeType::Ptr& m2)
{
return m1->name() < m2->name();
}
// Note that this method loses any newly-added (and not saved yet) mimetypes.
// So this is really only for load().
void FileTypesView::readFileTypes()
{
typesLV->clear();
m_majorMap.clear();
m_itemList.clear();
KMimeType::List mimetypes = KMimeType::allMimeTypes();
qSort(mimetypes.begin(), mimetypes.end(), mimeTypeLessThan);
KMimeType::List::const_iterator it2(mimetypes.constBegin());
for (; it2 != mimetypes.constEnd(); ++it2) {
const QString mimetype = (*it2)->name();
const int index = mimetype.indexOf('/');
const QString maj = mimetype.left(index);
const QString min = mimetype.right(mimetype.length() - index+1);
TypesListItem* groupItem = m_majorMap.value(maj);
if ( !groupItem ) {
groupItem = new TypesListItem(typesLV, maj);
m_majorMap.insert(maj, groupItem);
}
TypesListItem *item = new TypesListItem(groupItem, (*it2));
m_itemList.append( item );
}
updateDisplay(0L);
}
void FileTypesView::slotEmbedMajor(const QString &major, bool &embed)
{
TypesListItem *groupItem = m_majorMap.value(major);
if (!groupItem)
return;
embed = (groupItem->mimeTypeData().autoEmbed() == MimeTypeData::Yes);
}
void FileTypesView::slotFilter(const QString & patternFilter)
{
for (int i = 0; i < typesLV->topLevelItemCount(); ++i) {
typesLV->topLevelItem(i)->setHidden(true);
}
// insert all items and their group that match the filter
Q_FOREACH(TypesListItem* it, m_itemList) {
const MimeTypeData& mimeTypeData = it->mimeTypeData();
if ( patternFilter.isEmpty() || mimeTypeData.matchesFilter(patternFilter) ) {
TypesListItem *group = m_majorMap.value( mimeTypeData.majorType() );
Q_ASSERT(group);
if (group) {
group->setHidden(false);
it->setHidden(false);
}
} else {
it->setHidden(true);
}
}
}
void FileTypesView::addType()
{
const QStringList allGroups = m_majorMap.keys();
NewTypeDialog dialog(allGroups, this);
if (dialog.exec()) {
QString newMimeType = dialog.group() + '/' + dialog.text();
QTreeWidgetItemIterator it(typesLV);
TypesListItem *group = m_majorMap.value(dialog.group());
if ( !group ) {
group = new TypesListItem(typesLV, dialog.group());
m_majorMap.insert(dialog.group(), group);
}
// find out if our group has been filtered out -> insert if necessary
QTreeWidgetItem *item = typesLV->topLevelItem(0);
bool insert = true;
while ( item ) {
if ( item == group ) {
insert = false;
break;
}
item = typesLV->itemBelow(item);
}
if ( insert )
typesLV->addTopLevelItem( group );
TypesListItem *tli = new TypesListItem(group, newMimeType);
m_itemList.append( tli );
group->setExpanded(true);
tli->setSelected(true);
setDirty(true);
}
}
void FileTypesView::removeType()
{
TypesListItem *current = (TypesListItem *) typesLV->currentItem();
if ( !current )
return;
const MimeTypeData& mimeTypeData = current->mimeTypeData();
// Can't delete groups
if ( mimeTypeData.isMeta() )
return;
// nor essential mimetypes
if ( mimeTypeData.isEssential() )
return;
QTreeWidgetItem *li = typesLV->itemAbove(current);
if (!li)
li = typesLV->itemBelow(current);
if (!li)
li = current->parent();
if (!mimeTypeData.isNew())
removedList.append(mimeTypeData.name());
current->parent()->takeChild(current->parent()->indexOfChild(current));
m_itemList.removeAll(current);
setDirty(true);
if ( li )
li->setSelected(true);
}
void FileTypesView::slotDoubleClicked(QTreeWidgetItem *item)
{
if ( !item ) return;
item->setExpanded( !item->isExpanded() );
}
void FileTypesView::updateDisplay(QTreeWidgetItem *item)
{
if (!item)
{
m_widgetStack->setCurrentWidget( m_emptyWidget );
m_removeTypeB->setEnabled(false);
return;
}
bool wasDirty = m_dirty;
TypesListItem *tlitem = (TypesListItem *) item;
MimeTypeData& mimeTypeData = tlitem->mimeTypeData();
if (mimeTypeData.isMeta()) // is a group
{
m_widgetStack->setCurrentWidget( m_groupDetails );
m_groupDetails->setMimeTypeData( &mimeTypeData );
m_removeTypeB->setEnabled(false);
}
else
{
m_widgetStack->setCurrentWidget( m_details );
m_details->setMimeTypeData( &mimeTypeData );
bool canRemove = !mimeTypeData.isEssential();
if (canRemove && !mimeTypeData.isNew()) {
// We can only remove mimetypes that we defined ourselves, not those from freedesktop.org
canRemove = MimeTypeWriter::hasDefinitionFile(mimeTypeData.name());
}
m_removeTypeB->setEnabled(canRemove);
}
// Updating the display indirectly called change(true)
if ( !wasDirty )
setDirty(false);
}
void FileTypesView::save()
{
bool needUpdateMimeDb = false;
bool didIt = false;
// first, remove those items which we are asked to remove.
Q_FOREACH(const QString& mime, removedList) {
MimeTypeWriter::removeOwnMimeType(mime);
didIt = true;
needUpdateMimeDb = true;
}
// now go through all entries and sync those which are dirty.
// don't use typesLV, it may be filtered
QMap<QString,TypesListItem*>::iterator it1 = m_majorMap.begin();
while ( it1 != m_majorMap.end() ) {
TypesListItem *tli = *it1;
if (tli->mimeTypeData().isDirty()) {
kDebug() << "Entry " << tli->name() << " is dirty. Saving.";
if (tli->mimeTypeData().sync())
needUpdateMimeDb = true;
didIt = true;
}
++it1;
}
Q_FOREACH(TypesListItem* tli, m_itemList) {
if (tli->mimeTypeData().isDirty()) {
kDebug() << "Entry " << tli->name() << " is dirty. Saving.";
if (tli->mimeTypeData().sync())
needUpdateMimeDb = true;
didIt = true;
}
}
m_fileTypesConfig->sync();
setDirty(false);
if (needUpdateMimeDb) {
MimeTypeWriter::runUpdateMimeDatabase();
}
if (didIt) {
KBuildSycocaProgressDialog::rebuildKSycoca(this);
// Trigger reparseConfiguration of filetypesrc in konqueror
QDBusMessage message =
QDBusMessage::createSignal("/KonqMain", "org.kde.Konqueror.Main", "reparseConfiguration");
QDBusConnection::sessionBus().send(message);
}
}
void FileTypesView::load()
{
setEnabled(false);
setCursor( Qt::WaitCursor );
readFileTypes();
unsetCursor();
setDirty(false);
setEnabled(true);
}
void FileTypesView::slotDatabaseChanged()
{
if ( KSycoca::self()->isChanged("xdgdata-mime") // changes in mimetype definitions
|| KSycoca::self()->isChanged("services") ) { // changes in .desktop files
m_details->refresh();
// ksycoca has new KMimeTypes objects for us, make sure to update
// our 'copies' to be in sync with it. Not important for OK, but
// important for Apply (how to differentiate those 2?).
// See BR 35071.
Q_FOREACH(TypesListItem* tli, m_itemList) {
tli->mimeTypeData().refresh();
}
}
}
void FileTypesView::defaults()
{
}
#include "filetypesview.moc"

View file

@ -1,107 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2000 - 2008 David Faure <faure@kde.org>
Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
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 ) version 3 or, at the discretion of KDE e.V. ( which shall
act as a proxy as in section 14 of the GPLv3 ), any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef FILETYPESVIEW_H
#define FILETYPESVIEW_H
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtGui/QLabel>
#include <QtGui/QStackedWidget>
#include <KConfig>
#include <KSharedConfig>
#include <KCModule>
#include "typeslistitem.h"
class QLabel;
class QTreeWidget;
class QTreeWidgetItem;
class KPushButton;
class KLineEdit;
class FileTypeDetails;
class FileGroupDetails;
class QStackedWidget;
class FileTypesView : public KCModule
{
Q_OBJECT
public:
FileTypesView(QWidget *parent, const QVariantList &args);
~FileTypesView();
void load();
void save();
void defaults();
protected Q_SLOTS:
void addType();
void removeType();
void updateDisplay(QTreeWidgetItem *);
void slotDoubleClicked(QTreeWidgetItem *);
void slotFilter(const QString &patternFilter);
void setDirty(bool state);
void slotDatabaseChanged();
void slotEmbedMajor(const QString &major, bool &embed);
private:
void readFileTypes();
private:
QTreeWidget *typesLV;
KPushButton *m_removeTypeB;
QStackedWidget * m_widgetStack;
FileTypeDetails * m_details;
FileGroupDetails * m_groupDetails;
QLabel * m_emptyWidget;
KLineEdit *patternFilterLE;
QStringList removedList;
bool m_dirty;
QMap<QString,TypesListItem*> m_majorMap;
QList<TypesListItem *> m_itemList;
KSharedConfig::Ptr m_fileTypesConfig;
};
// helper class for loading the icon on request instead of preloading lots of probably
// unused icons which takes quite a lot of time
class TypesListTreeWidget : public QTreeWidget
{
Q_OBJECT
public:
TypesListTreeWidget(QWidget *parent)
: QTreeWidget(parent) {
}
protected:
void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
static_cast<TypesListItem *>(itemFromIndex(index))->loadIcon();
QTreeWidget::drawRow(painter, option, index);
}
};
#endif

View file

@ -1,199 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2000, 2007 David Faure <faure@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
// Own
#include "keditfiletype.h"
#include "mimetypewriter.h"
// Qt
#include <qdbusconnection.h>
#include <qdbusmessage.h>
#include <QtCore/QFile>
// KDE
#include <kapplication.h>
#include <kaboutdata.h>
#include <kbuildsycocaprogressdialog.h>
#include <kdebug.h>
#include <kcmdlineargs.h>
#include <ksycoca.h>
#include <kservicetypeprofile.h>
#include <kstandarddirs.h>
#include <klocale.h>
#include <kwindowsystem.h>
// Local
#include "filetypedetails.h"
#include "typeslistitem.h"
FileTypeDialog::FileTypeDialog( MimeTypeData* mime )
: KDialog( 0 ),
m_mimeTypeData(mime)
{
setButtons( Cancel | Apply | Ok );
showButtonSeparator( false );
init();
}
FileTypeDialog::~FileTypeDialog()
{
delete m_details;
}
void FileTypeDialog::init()
{
m_details = new FileTypeDetails( this );
m_details->setMimeTypeData( m_mimeTypeData );
// This code is very similar to kcdialog.cpp
setMainWidget( m_details );
connect(m_details, SIGNAL(changed(bool)), this, SLOT(clientChanged(bool)));
// TODO setHelp()
enableButton(Apply, false);
connect( KSycoca::self(), SIGNAL( databaseChanged() ), SLOT( slotDatabaseChanged() ) );
connect( this, SIGNAL( okClicked() ), SLOT( slotOk() ) );
connect( this, SIGNAL( applyClicked() ), SLOT( slotApply() ) );
}
void FileTypeDialog::save()
{
if (m_mimeTypeData->isDirty()) {
if (m_mimeTypeData->sync())
MimeTypeWriter::runUpdateMimeDatabase();
KBuildSycocaProgressDialog::rebuildKSycoca(this);
// Trigger reparseConfiguration of filetypesrc in konqueror
QDBusMessage message =
QDBusMessage::createSignal("/KonqMain", "org.kde.Konqueror.Main", "reparseConfiguration");
QDBusConnection::sessionBus().send(message);
}
}
void FileTypeDialog::slotOk()
{
save();
accept();
}
void FileTypeDialog::slotApply()
{
save();
}
void FileTypeDialog::clientChanged(bool state)
{
// enable/disable buttons
enableButton(User1, state);
enableButton(Apply, state);
}
void FileTypeDialog::slotDatabaseChanged()
{
if ( KSycoca::self()->isChanged("xdgdata-mime") // changes in mimetype definitions
|| KSycoca::self()->isChanged("services") ) { // changes in .desktop files
m_details->refresh();
}
}
#include "keditfiletype.moc"
int main(int argc, char ** argv)
{
KServiceTypeProfile::setConfigurationMode();
KAboutData aboutData( "keditfiletype", "filetypes", ki18n("KEditFileType"), "1.0",
ki18n("KDE file type editor - simplified version for editing a single file type"),
KAboutData::License_GPL,
ki18n("(c) 2000, KDE developers") );
aboutData.addAuthor(ki18n("Preston Brown"),KLocalizedString(), "pbrown@kde.org");
aboutData.addAuthor(ki18n("David Faure"),KLocalizedString(), "faure@kde.org");
aboutData.setProgramIconName("preferences-desktop-filetype-association");
KCmdLineArgs::init( argc, argv, &aboutData );
KCmdLineOptions options;
options.add("parent <winid>", ki18n("Makes the dialog transient for the window specified by winid"));
options.add("+mimetype", ki18n("File type to edit (e.g. text/html)"));
KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
KApplication app;
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
if (args->count() == 0)
KCmdLineArgs::usage();
QString arg = args->arg(0);
MimeTypeData* mimeTypeData = 0;
const bool createType = arg.startsWith('*');
if ( createType ) {
QString mimeString = "application/x-kdeuser%1";
QString mimeTypeName;
int inc = 0;
bool ok = false;
do {
++inc;
mimeTypeName = mimeString.arg(inc);
ok = !KMimeType::mimeType(mimeTypeName);
} while (!ok);
QStringList patterns;
if ( arg.length() > 2 )
patterns << arg.toLower() << arg.toUpper();
QString comment;
if ( arg.startsWith( "*." ) && arg.length() >= 3 ) {
const QString type = arg.mid( 3 ).prepend( arg[2].toUpper() );
comment = i18n( "%1 File", type );
}
mimeTypeData = new MimeTypeData(mimeTypeName, true); // new mimetype
mimeTypeData->setComment(comment);
mimeTypeData->setPatterns(patterns);
}
else {
const QString mimeTypeName = arg;
KMimeType::Ptr mime = KMimeType::mimeType(mimeTypeName, KMimeType::ResolveAliases);
if (!mime) {
kError() << "Mimetype" << mimeTypeName << "not found" ;
return 1;
}
mimeTypeData = new MimeTypeData(mime);
}
FileTypeDialog dlg( mimeTypeData );
if( args->isSet( "parent" )) {
bool ok;
long id = QString(args->getOption("parent")).toLong(&ok);
if (ok)
KWindowSystem::setMainWindow( &dlg, (WId)id );
}
args->clear();
if ( !createType )
dlg.setCaption( i18n("Edit File Type %1", mimeTypeData->name()) );
else {
dlg.setCaption( i18n("Create New File Type %1", mimeTypeData->name()) );
dlg.enableButton( KDialog::Apply, true );
}
dlg.show(); // non-modal
return app.exec();
}

View file

@ -1,53 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2000, 2007 David Faure <faure@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef __keditfiletype_h
#define __keditfiletype_h
#include <kdialog.h>
#include <kmimetype.h>
class MimeTypeData;
class FileTypeDetails;
// A dialog for ONE file type to be edited.
class FileTypeDialog : public KDialog
{
Q_OBJECT
public:
FileTypeDialog(MimeTypeData* mime);
~FileTypeDialog();
protected Q_SLOTS:
virtual void slotOk();
virtual void slotApply();
void clientChanged(bool state);
void slotDatabaseChanged();
protected:
void save();
private:
void init();
FileTypeDetails * m_details;
MimeTypeData* m_mimeTypeData;
};
#endif

View file

@ -1,435 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
Copyright (C) 2003 David Faure <faure@kde.org>
Copyright (C) 2002 Daniel Molkentin <molkentin@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
// Own
#include "kservicelistwidget.h"
// std
#include <unistd.h>
// Qt
#include <QtGui/QLayout>
#include <QtGui/QHBoxLayout>
// KDE
#include <kapplication.h>
#include <kdebug.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <knotification.h>
#include <kopenwithdialog.h>
#include <kpropertiesdialog.h>
#include <kpushbutton.h>
#include <kstandarddirs.h>
// Local
#include "kserviceselectdlg.h"
#include "mimetypedata.h"
KServiceListItem::KServiceListItem( const KService::Ptr& pService, int kind )
: QListWidgetItem(), storageId(pService->storageId()), desktopPath(pService->entryPath())
{
if ( kind == KServiceListWidget::SERVICELIST_APPLICATIONS )
setText( pService->name() );
else
setText( i18n( "%1 (%2)", pService->name(), pService->desktopEntryName() ) );
if (!pService->isApplication())
localPath = KStandardDirs::locateLocal("services", desktopPath);
else
localPath = pService->locateLocal();
}
bool KServiceListItem::isImmutable() const
{
return !KStandardDirs::checkAccess(localPath, W_OK);
}
KServiceListWidget::KServiceListWidget(int kind, QWidget *parent)
: QGroupBox( kind == SERVICELIST_APPLICATIONS ? i18n("Application Preference Order")
: i18n("Services Preference Order"), parent ),
m_kind( kind ), m_mimeTypeData( 0L )
{
QHBoxLayout *lay= new QHBoxLayout(this);
lay->setMargin(KDialog::marginHint());
lay->setSpacing(KDialog::spacingHint());
servicesLB = new QListWidget(this);
connect(servicesLB, SIGNAL(itemSelectionChanged()), SLOT(enableMoveButtons()));
lay->addWidget(servicesLB);
connect( servicesLB, SIGNAL( itemDoubleClicked(QListWidgetItem*)), this, SLOT( editService()));
QString wtstr =
(kind == SERVICELIST_APPLICATIONS ?
i18n("This is a list of applications associated with files of the selected"
" file type. This list is shown in Konqueror's context menus when you select"
" \"Open With...\". If more than one application is associated with this file type,"
" then the list is ordered by priority with the uppermost item taking precedence"
" over the others.") :
i18n("This is a list of services associated with files of the selected"
" file type. This list is shown in Konqueror's context menus when you select"
" a \"Preview with...\" option. If more than one service is associated with this file type,"
" then the list is ordered by priority with the uppermost item taking precedence"
" over the others."));
setWhatsThis( wtstr );
servicesLB->setWhatsThis( wtstr );
QVBoxLayout *btnsLay= new QVBoxLayout();
lay->addLayout(btnsLay);
servUpButton = new KPushButton(i18n("Move &Up"), this);
servUpButton->setIcon(KIcon("arrow-up"));
servUpButton->setEnabled(false);
connect(servUpButton, SIGNAL(clicked()), SLOT(promoteService()));
btnsLay->addWidget(servUpButton);
servUpButton->setWhatsThis( kind == SERVICELIST_APPLICATIONS ?
i18n("Assigns a higher priority to the selected\n"
"application, moving it up in the list. Note: This\n"
"only affects the selected application if the file type is\n"
"associated with more than one application.") :
i18n("Assigns a higher priority to the selected\n"
"service, moving it up in the list."));
servDownButton = new KPushButton(i18n("Move &Down"), this);
servDownButton->setIcon(KIcon("arrow-down"));
servDownButton->setEnabled(false);
connect(servDownButton, SIGNAL(clicked()), SLOT(demoteService()));
btnsLay->addWidget(servDownButton);
servDownButton->setWhatsThis( kind == SERVICELIST_APPLICATIONS ?
i18n("Assigns a lower priority to the selected\n"
"application, moving it down in the list. Note: This \n"
"only affects the selected application if the file type is\n"
"associated with more than one application."):
i18n("Assigns a lower priority to the selected\n"
"service, moving it down in the list."));
servNewButton = new KPushButton(i18n("Add..."), this);
servNewButton->setIcon(KIcon("list-add"));
servNewButton->setEnabled(false);
connect(servNewButton, SIGNAL(clicked()), SLOT(addService()));
btnsLay->addWidget(servNewButton);
servNewButton->setWhatsThis( i18n( "Add a new application for this file type." ) );
servEditButton = new KPushButton(i18n("Edit..."), this);
servEditButton->setIcon(KIcon("edit-rename"));
servEditButton->setEnabled(false);
connect(servEditButton, SIGNAL(clicked()), SLOT(editService()));
btnsLay->addWidget(servEditButton);
servEditButton->setWhatsThis( i18n( "Edit command line of the selected application." ) );
servRemoveButton = new KPushButton(i18n("Remove"), this);
servRemoveButton->setIcon(KIcon("list-remove"));
servRemoveButton->setEnabled(false);
connect(servRemoveButton, SIGNAL(clicked()), SLOT(removeService()));
btnsLay->addWidget(servRemoveButton);
servRemoveButton->setWhatsThis( i18n( "Remove the selected application from the list." ) );
btnsLay->addStretch(1);
}
void KServiceListWidget::setMimeTypeData( MimeTypeData * mimeTypeData )
{
m_mimeTypeData = mimeTypeData;
if ( servNewButton )
servNewButton->setEnabled(true);
// will need a selection
servUpButton->setEnabled(false);
servDownButton->setEnabled(false);
servicesLB->clear();
servicesLB->setEnabled(false);
if (m_mimeTypeData) {
const QStringList services = ( m_kind == SERVICELIST_APPLICATIONS )
? m_mimeTypeData->appServices()
: m_mimeTypeData->embedServices();
if (services.isEmpty()) {
if (m_kind == SERVICELIST_APPLICATIONS)
servicesLB->addItem(i18nc("No applications associated with this file type", "None"));
else
servicesLB->addItem(i18nc("No components associated with this file type", "None"));
} else {
Q_FOREACH(const QString& service, services) {
KService::Ptr pService = KService::serviceByStorageId(service);
if (pService)
servicesLB->addItem( new KServiceListItem(pService, m_kind) );
}
servicesLB->setEnabled(true);
}
}
if (servRemoveButton)
servRemoveButton->setEnabled(servicesLB->currentRow() > -1);
if (servEditButton)
servEditButton->setEnabled(servicesLB->currentRow() > -1);
}
void KServiceListWidget::promoteService()
{
if (!servicesLB->isEnabled()) {
KNotification::beep();
return;
}
int selIndex = servicesLB->currentRow();
if (selIndex == 0) {
KNotification::beep();
return;
}
QListWidgetItem *selItem = servicesLB->item(selIndex);
servicesLB->takeItem(selIndex);
servicesLB->insertItem(selIndex-1,selItem);
servicesLB->setCurrentRow(selIndex - 1);
updatePreferredServices();
emit changed(true);
}
void KServiceListWidget::demoteService()
{
if (!servicesLB->isEnabled()) {
KNotification::beep();
return;
}
int selIndex = servicesLB->currentRow();
if (selIndex == servicesLB->count() - 1) {
KNotification::beep();
return;
}
QListWidgetItem *selItem = servicesLB->item(selIndex);
servicesLB->takeItem(selIndex);
servicesLB->insertItem(selIndex + 1, selItem);
servicesLB->setCurrentRow(selIndex + 1);
updatePreferredServices();
emit changed(true);
}
void KServiceListWidget::addService()
{
if (!m_mimeTypeData)
return;
KService::Ptr service;
if ( m_kind == SERVICELIST_APPLICATIONS )
{
KOpenWithDialog dlg(m_mimeTypeData->name(), QString(), this);
dlg.setSaveNewApplications(true);
if (dlg.exec() != QDialog::Accepted)
return;
service = dlg.service();
Q_ASSERT(service);
if (!service)
return; // Don't crash if KOpenWith wasn't able to create service.
}
else
{
KServiceSelectDlg dlg(m_mimeTypeData->name(), QString(), this);
if (dlg.exec() != QDialog::Accepted)
return;
service = dlg.service();
Q_ASSERT(service);
if (!service)
return;
}
// Did the list simply show "None"?
const bool hadDummyEntry = ( m_kind == SERVICELIST_APPLICATIONS )
? m_mimeTypeData->appServices().isEmpty()
: m_mimeTypeData->embedServices().isEmpty();
if (hadDummyEntry) {
delete servicesLB->takeItem(0); // Remove the "None" item.
servicesLB->setEnabled(true);
} else {
// check if it is a duplicate entry
for (int index = 0; index < servicesLB->count(); index++) {
if (static_cast<KServiceListItem*>( servicesLB->item(index) )->desktopPath
== service->entryPath()) {
// ##### shouldn't we make the existing entry the default one?
return;
}
}
}
servicesLB->insertItem(0, new KServiceListItem(service, m_kind));
servicesLB->setCurrentItem(0);
updatePreferredServices();
emit changed(true);
}
void KServiceListWidget::editService()
{
if (!m_mimeTypeData)
return;
const int selected = servicesLB->currentRow();
if (selected < 0)
return;
// Only edit applications, not services as
// they don't have any parameters
if (m_kind != SERVICELIST_APPLICATIONS)
return;
// Just like popping up an add dialog except that we
// pass the current command line as a default
KServiceListItem *selItem = (KServiceListItem*)servicesLB->item(selected);
const QString desktopPath = selItem->desktopPath;
KService::Ptr service = KService::serviceByDesktopPath(desktopPath);
if (!service)
return;
QString path = service->entryPath();
// If the path to the desktop file is relative, try to get the full
// path from KStandardDirs.
path = KStandardDirs::locate("apps", path); // TODO use xdgdata-apps instead?
KFileItem item(KUrl(path), "application/x-desktop", KFileItem::Unknown);
KPropertiesDialog dlg(item, this);
if (dlg.exec() != QDialog::Accepted)
return;
// Note that at this point, ksycoca has been updated,
// and setMimeTypeData has been called again, so all the items have been recreated.
// Reload service
service = KService::serviceByDesktopPath(desktopPath);
if (!service)
return;
// Remove the old one...
delete servicesLB->takeItem(selected);
// ...check that it's not a duplicate entry...
bool addIt = true;
for (int index = 0; index < servicesLB->count(); index++) {
if (static_cast<KServiceListItem*>(servicesLB->item(index))->desktopPath
== service->entryPath()) {
addIt = false;
break;
}
}
// ...and add it in the same place as the old one:
if (addIt) {
servicesLB->insertItem(selected, new KServiceListItem(service, m_kind));
servicesLB->setCurrentRow(selected);
}
updatePreferredServices();
emit changed(true);
}
void KServiceListWidget::removeService()
{
if (!m_mimeTypeData) return;
int selected = servicesLB->currentRow();
if ( selected >= 0 ) {
// Check if service is associated with this mimetype or with one of its parents
KServiceListItem *serviceItem = static_cast<KServiceListItem *>(servicesLB->item(selected));
if (serviceItem->isImmutable())
{
KMessageBox::sorry(this, i18n("You are not authorized to remove this service."));
}
else
{
delete servicesLB->takeItem( selected );
updatePreferredServices();
emit changed(true);
}
}
// Update buttons and service list again (e.g. to re-add "None")
setMimeTypeData(m_mimeTypeData);
}
void KServiceListWidget::updatePreferredServices()
{
if (!m_mimeTypeData)
return;
QStringList sl;
unsigned int count = servicesLB->count();
for (unsigned int i = 0; i < count; i++) {
KServiceListItem *sli = (KServiceListItem *) servicesLB->item(i);
sl.append( sli->storageId );
}
if ( m_kind == SERVICELIST_APPLICATIONS )
m_mimeTypeData->setAppServices(sl);
else
m_mimeTypeData->setEmbedServices(sl);
}
void KServiceListWidget::enableMoveButtons()
{
int idx = servicesLB->currentRow();
if (servicesLB->model()->rowCount() <= 1)
{
servUpButton->setEnabled(false);
servDownButton->setEnabled(false);
}
else if ( idx == (servicesLB->model()->rowCount() - 1) )
{
servUpButton->setEnabled(true);
servDownButton->setEnabled(false);
}
else if (idx == 0)
{
servUpButton->setEnabled(false);
servDownButton->setEnabled(true);
}
else
{
servUpButton->setEnabled(true);
servDownButton->setEnabled(true);
}
if ( servRemoveButton )
servRemoveButton->setEnabled(true);
if ( servEditButton )
servEditButton->setEnabled( m_kind == SERVICELIST_APPLICATIONS );
}
#include "kservicelistwidget.moc"

View file

@ -1,79 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
Copyright (C) 2003 David Faure <faure@kde.org>
Copyright (C) 2002 Daniel Molkentin <molkentin@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published
by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef _KSERVICELISTWIDGET_H
#define _KSERVICELISTWIDGET_H
#include <QGroupBox>
#include <QtGui/QListWidget>
#include <kservice.h>
class MimeTypeData;
class KPushButton;
class KService;
class KServiceListItem : public QListWidgetItem
{
public:
KServiceListItem( const KService::Ptr& pService, int kind );
bool isImmutable() const;
QString storageId;
QString desktopPath;
QString localPath;
};
/**
* This widget holds a list of services, with 5 buttons to manage it.
* It's a separate class so that it can be used by both tabs of the
* module, once for applications and once for services.
* The "kind" is determined by the argument given to the constructor.
*/
class KServiceListWidget : public QGroupBox
{
Q_OBJECT
public:
enum { SERVICELIST_APPLICATIONS, SERVICELIST_SERVICES };
explicit KServiceListWidget(int kind, QWidget *parent = 0);
void setMimeTypeData( MimeTypeData * item );
Q_SIGNALS:
void changed(bool);
protected Q_SLOTS:
void promoteService();
void demoteService();
void addService();
void editService();
void removeService();
void enableMoveButtons();
protected:
void updatePreferredServices();
private:
int m_kind;
QListWidget *servicesLB;
KPushButton *servUpButton, *servDownButton;
KPushButton *servNewButton, *servEditButton, *servRemoveButton;
MimeTypeData *m_mimeTypeData;
};
#endif

View file

@ -1,74 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2000 David Faure <faure@kde.org>
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "kserviceselectdlg.h"
#include "kserviceselectdlg.moc"
#include "kservicelistwidget.h"
#include <klocale.h>
#include <kvbox.h>
#include <QtGui/QLabel>
KServiceSelectDlg::KServiceSelectDlg( const QString& /*serviceType*/, const QString& /*value*/, QWidget *parent )
: KDialog( parent )
{
setObjectName( "serviceSelectDlg" );
setModal( true );
setCaption( i18n( "Add Service" ) );
setButtons( Ok | Cancel );
KVBox *vbox = new KVBox ( this );
vbox->setSpacing( KDialog::spacingHint() );
new QLabel( i18n( "Select service:" ), vbox );
m_listbox=new KListWidget( vbox );
// Can't make a KTrader query since we don't have a servicetype to give,
// we want all services that are not applications.......
// So we have to do it the slow way
// ### Why can't we query for KParts/ReadOnlyPart as the servicetype? Should work fine!
const KService::List allServices = KService::allServices();
KService::List::const_iterator it(allServices.constBegin());
for ( ; it != allServices.constEnd() ; ++it )
if ( (*it)->hasServiceType( "KParts/ReadOnlyPart" ) )
{
m_listbox->addItem( new KServiceListItem( (*it), KServiceListWidget::SERVICELIST_SERVICES ) );
}
m_listbox->model()->sort(0);
m_listbox->setMinimumHeight(350);
m_listbox->setMinimumWidth(300);
connect(m_listbox,SIGNAL(itemDoubleClicked(QListWidgetItem*)),SLOT(slotOk()));
connect( this, SIGNAL(okClicked()), this, SLOT(slotOk()) );
setMainWidget(vbox);
}
KServiceSelectDlg::~KServiceSelectDlg()
{
}
void KServiceSelectDlg::slotOk()
{
accept();
}
KService::Ptr KServiceSelectDlg::service()
{
int selIndex = m_listbox->currentRow();
KServiceListItem *selItem = static_cast<KServiceListItem *>(m_listbox->item(selIndex));
return KService::serviceByDesktopPath( selItem->desktopPath );
}

View file

@ -1,50 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2000 David Faure <faure@kde.org>
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __kserviceselectdlg_h
#define __kserviceselectdlg_h
#include <kdialog.h>
#include <kservice.h>
#include <klistwidget.h>
class KServiceSelectDlg : public KDialog
{
Q_OBJECT
public:
/**
* Create a dialog to select a service (not application) for a given service type.
*
* @param serviceType the service type we want to choose a service for.
* @param value is the initial service to select (not implemented currently)
* @param parent parent widget
*/
explicit KServiceSelectDlg( const QString& serviceType,
const QString& value = QString(),
QWidget *parent = 0L );
~KServiceSelectDlg();
/**
* @return the chosen service
*/
KService::Ptr service();
protected slots:
void slotOk();
private:
KListWidget * m_listbox;
};
#endif

View file

@ -1,470 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
Copyright (C) 2003, 2007 David Faure <faure@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "mimetypedata.h"
#include "sharedmimeinfoversion.h"
#include <kprotocolmanager.h>
#include "mimetypewriter.h"
#include <kdebug.h>
#include <kservice.h>
#include <ksharedconfig.h>
#include <kconfiggroup.h>
#include <kmimetypetrader.h>
MimeTypeData::MimeTypeData(const QString& major)
: m_askSave(AskSaveDefault),
m_bNewItem(false),
m_bFullInit(true),
m_isGroup(true),
m_appServicesModified(false),
m_embedServicesModified(false),
m_major(major)
{
m_autoEmbed = readAutoEmbed();
}
MimeTypeData::MimeTypeData(const KMimeType::Ptr mime)
: m_mimetype(mime),
m_askSave(AskSaveDefault), // TODO: the code for initializing this is missing. FileTypeDetails initializes the checkbox instead...
m_bNewItem(false),
m_bFullInit(false),
m_isGroup(false),
m_appServicesModified(false),
m_embedServicesModified(false)
{
const QString mimeName = m_mimetype->name();
const int index = mimeName.indexOf('/');
if (index != -1) {
m_major = mimeName.left(index);
m_minor = mimeName.mid(index+1);
} else {
m_major = mimeName;
}
initFromKMimeType();
}
MimeTypeData::MimeTypeData(const QString& mimeName, bool)
: m_mimetype(0),
m_askSave(AskSaveDefault),
m_bNewItem(true),
m_bFullInit(false),
m_isGroup(false),
m_appServicesModified(false),
m_embedServicesModified(false)
{
const int index = mimeName.indexOf('/');
if (index != -1) {
m_major = mimeName.left(index);
m_minor = mimeName.mid(index+1);
} else {
m_major = mimeName;
}
m_autoEmbed = UseGroupSetting;
// all the rest is empty by default
}
void MimeTypeData::initFromKMimeType()
{
m_comment = m_mimetype->comment();
m_userSpecifiedIcon = m_mimetype->userSpecifiedIconName();
setPatterns(m_mimetype->patterns());
m_autoEmbed = readAutoEmbed();
}
MimeTypeData::AutoEmbed MimeTypeData::readAutoEmbed() const
{
const KSharedConfig::Ptr config = KSharedConfig::openConfig("filetypesrc", KConfig::NoGlobals);
const QString key = QString("embed-") + name();
const KConfigGroup group(config, "EmbedSettings");
if (m_isGroup) {
// embedding is false by default except for image/* and inode/* (hardcoded in konq)
const bool defaultValue = ( m_major == "image" || m_major == "inode" );
return group.readEntry(key, defaultValue) ? Yes : No;
} else {
if (group.hasKey(key))
return group.readEntry(key, false) ? Yes : No;
// TODO if ( !mimetype->property( "X-KDE-LocalProtocol" ).toString().isEmpty() )
// TODO return MimeTypeData::Yes; // embed by default for zip, tar etc.
return MimeTypeData::UseGroupSetting;
}
}
void MimeTypeData::writeAutoEmbed()
{
KSharedConfig::Ptr config = KSharedConfig::openConfig("filetypesrc", KConfig::NoGlobals);
if (!config->isConfigWritable(true))
return;
const QString key = QString("embed-") + name();
KConfigGroup group(config, "EmbedSettings");
if (m_isGroup) {
group.writeEntry(key, m_autoEmbed == Yes);
} else {
if (m_autoEmbed == UseGroupSetting)
group.deleteEntry(key);
else
group.writeEntry(key, m_autoEmbed == Yes);
}
}
bool MimeTypeData::isEssential() const
{
// Keep in sync with KMimeType::checkEssentialMimeTypes
const QString n = name();
if ( n == "application/octet-stream" )
return true;
if ( n == "inode/directory" )
return true;
if ( n == "inode/blockdevice" )
return true;
if ( n == "inode/chardevice" )
return true;
if ( n == "inode/socket" )
return true;
if ( n == "inode/fifo" )
return true;
if ( n == "application/x-shellscript" )
return true;
if ( n == "application/x-executable" )
return true;
if ( n == "application/x-desktop" )
return true;
return false;
}
void MimeTypeData::setUserSpecifiedIcon(const QString& icon)
{
m_userSpecifiedIcon = icon;
}
QStringList MimeTypeData::getAppOffers() const
{
QStringList services;
const KService::List offerList =
KMimeTypeTrader::self()->query(name(), "Application");
KService::List::const_iterator it(offerList.begin());
for (; it != offerList.constEnd(); ++it) {
if ((*it)->allowAsDefault())
services.append((*it)->storageId());
}
return services;
}
QStringList MimeTypeData::getPartOffers() const
{
QStringList services;
const KService::List partOfferList =
KMimeTypeTrader::self()->query(name(), "KParts/ReadOnlyPart");
for ( KService::List::const_iterator it = partOfferList.begin(); it != partOfferList.constEnd(); ++it)
services.append((*it)->storageId());
return services;
}
void MimeTypeData::getMyServiceOffers() const
{
m_appServices = getAppOffers();
m_embedServices = getPartOffers();
m_bFullInit = true;
}
QStringList MimeTypeData::appServices() const
{
if (!m_bFullInit) {
getMyServiceOffers();
}
return m_appServices;
}
QStringList MimeTypeData::embedServices() const
{
if (!m_bFullInit) {
getMyServiceOffers();
}
return m_embedServices;
}
bool MimeTypeData::isMimeTypeDirty() const
{
Q_ASSERT(!m_isGroup);
if (m_bNewItem)
return true;
if (m_mimetype->comment() != m_comment) {
kDebug() << "Mimetype Comment Dirty: old=" << m_mimetype->comment() << "m_comment=" << m_comment;
return true;
}
if (m_mimetype->userSpecifiedIconName() != m_userSpecifiedIcon) {
kDebug() << "Mimetype Icon Dirty: old=" << m_mimetype->iconName() << "m_userSpecifiedIcon=" << m_userSpecifiedIcon;
return true;
}
QStringList storedPatterns = m_mimetype->patterns();
storedPatterns.sort(); // see ctor
if ( storedPatterns != m_patterns) {
kDebug() << "Mimetype Patterns Dirty: old=" << storedPatterns
<< "m_patterns=" << m_patterns;
return true;
}
if (readAutoEmbed() != m_autoEmbed)
return true;
return false;
}
bool MimeTypeData::isDirty() const
{
if ( m_bNewItem ) {
kDebug() << "New item, need to save it";
return true;
}
if ( !m_isGroup ) {
if (m_appServicesModified || m_embedServicesModified)
return true;
if (isMimeTypeDirty())
return true;
}
else // is a group
{
if (readAutoEmbed() != m_autoEmbed)
return true;
}
if (m_askSave != AskSaveDefault)
return true;
// nothing seems to have changed, it's not dirty.
return false;
}
bool MimeTypeData::sync()
{
if (m_isGroup) {
writeAutoEmbed();
return false;
}
if (m_askSave != AskSaveDefault) {
KSharedConfig::Ptr config = KSharedConfig::openConfig("filetypesrc", KConfig::NoGlobals);
if (!config->isConfigWritable(true))
return false;
KConfigGroup cg = config->group("Notification Messages");
if (m_askSave == AskSaveYes) {
// Ask
cg.deleteEntry("askSave"+name());
cg.deleteEntry("askEmbedOrSave"+name());
} else {
// Do not ask, open
cg.writeEntry("askSave"+name(), "no" );
cg.writeEntry("askEmbedOrSave"+name(), "no" );
}
}
writeAutoEmbed();
bool needUpdateMimeDb = false;
if (isMimeTypeDirty()) {
MimeTypeWriter mimeTypeWriter(name());
mimeTypeWriter.setComment(m_comment);
if (SharedMimeInfoVersion::supportsIcon()) {
// Very important: don't write <icon> if shared-mime-info doesn't support it,
// it would abort on it!
if (!m_userSpecifiedIcon.isEmpty()) {
mimeTypeWriter.setIconName(m_userSpecifiedIcon);
}
}
mimeTypeWriter.setPatterns(m_patterns);
if (!mimeTypeWriter.write())
return false;
needUpdateMimeDb = true;
}
syncServices();
return needUpdateMimeDb;
}
void MimeTypeData::syncServices()
{
if (!m_bFullInit)
return;
KSharedConfig::Ptr profile = KSharedConfig::openConfig("mimeapps.list", KConfig::NoGlobals, "xdgdata-apps");
if (!profile->isConfigWritable(true)) // warn user if mimeapps.list is root-owned (#155126/#94504)
return;
const QStringList oldAppServices = getAppOffers();
if (oldAppServices != m_appServices) {
// Save preferred services
KConfigGroup addedApps(profile, "Added Associations");
saveServices(addedApps, m_appServices);
KConfigGroup removedApps(profile, "Removed Associations");
saveRemovedServices(removedApps, m_appServices, oldAppServices);
}
const QStringList oldPartServices = getPartOffers();
if (oldPartServices != m_embedServices) {
// Handle removed services
KConfigGroup addedParts(profile, "Added KDE Service Associations");
saveServices(addedParts, m_embedServices);
KConfigGroup removedParts(profile, "Removed KDE Service Associations");
saveRemovedServices(removedParts, m_embedServices, oldPartServices);
}
m_appServicesModified = false;
m_embedServicesModified = false;
}
static QStringList collectStorageIds(const QStringList& services)
{
QStringList serviceList;
QStringList::const_iterator it(services.begin());
for (int i = services.count(); it != services.end(); ++it, i--) {
KService::Ptr pService = KService::serviceByStorageId(*it);
if (!pService) {
kWarning() << "service with storage id" << *it << "not found";
continue; // Where did that one go?
}
serviceList.append(pService->storageId());
}
return serviceList;
}
void MimeTypeData::saveRemovedServices(KConfigGroup & config, const QStringList& services, const QStringList& oldServices)
{
QStringList removedServiceList = config.readXdgListEntry(name());
Q_FOREACH(const QString& service, services) {
// If removedServiceList.contains(service), then it was previously removed but has been added back
removedServiceList.removeAll(service);
}
Q_FOREACH(const QString& oldService, oldServices) {
if (!services.contains(oldService)) {
// The service was in m_appServices (or m_embedServices) but has been removed
removedServiceList.append(oldService);
}
}
if (removedServiceList.isEmpty())
config.deleteEntry(name());
else
config.writeXdgListEntry(name(), removedServiceList);
}
void MimeTypeData::saveServices(KConfigGroup & config, const QStringList& services)
{
if (services.isEmpty())
config.deleteEntry(name());
else
config.writeXdgListEntry(name(), collectStorageIds(services));
}
void MimeTypeData::refresh()
{
if (m_isGroup)
return;
//kDebug() << "MimeTypeData refresh" << name();
m_mimetype = KMimeType::mimeType( name() );
if (m_mimetype) {
if (m_bNewItem) {
kDebug() << "OK, created" << name();
m_bNewItem = false; // if this was a new mimetype, we just created it
}
if (!isMimeTypeDirty()) {
// Update from ksycoca, in case something was changed from out of this kcm
// (e.g. using KOpenWithDialog, or keditfiletype + kcmshell filetypes)
initFromKMimeType();
}
if (!m_appServicesModified && !m_embedServicesModified) {
m_bFullInit = false; // refresh services too
}
}
}
void MimeTypeData::getAskSave(bool &_askSave)
{
if (m_askSave == AskSaveYes)
_askSave = true;
if (m_askSave == AskSaveNo)
_askSave = false;
}
void MimeTypeData::setAskSave(bool _askSave)
{
m_askSave = _askSave ? AskSaveYes : AskSaveNo;
}
bool MimeTypeData::canUseGroupSetting() const
{
// "Use group settings" isn't available for zip, tar etc.; those have a builtin default...
if (!m_mimetype) // e.g. new mimetype
return true;
const bool hasLocalProtocolRedirect = !KProtocolManager::protocolForArchiveMimetype(name()).isEmpty();
return !hasLocalProtocolRedirect;
}
void MimeTypeData::setPatterns(const QStringList &p)
{
m_patterns = p;
// Sort them, since update-mime-database doesn't respect order (order of globs file != order of xml),
// and this code says things like if (m_mimetype->patterns() == m_patterns).
// We could also sort in KMimeType::setPatterns but this would just slow down the
// normal use case (anything else than this KCM) for no good reason.
m_patterns.sort();
}
bool MimeTypeData::matchesFilter(const QString& filter) const
{
if (name().contains(filter, Qt::CaseInsensitive))
return true;
if (m_comment.contains(filter, Qt::CaseInsensitive))
return true;
if (!m_patterns.filter(filter, Qt::CaseInsensitive).isEmpty())
return true;
return false;
}
void MimeTypeData::setAppServices(const QStringList &dsl)
{
m_appServices = dsl;
m_appServicesModified = true;
}
void MimeTypeData::setEmbedServices(const QStringList &dsl)
{
m_embedServices = dsl;
m_embedServicesModified = true;
}
QString MimeTypeData::icon() const
{
if (!m_userSpecifiedIcon.isEmpty())
return m_userSpecifiedIcon;
if (m_mimetype)
return m_mimetype->iconName();
return QString();
}

View file

@ -1,128 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
Copyright (C) 2003, 2007 David Faure <faure@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef MIMETYPEDATA_H
#define MIMETYPEDATA_H
#include <kmimetype.h>
/**
* This is a non-gui (data) class, that represents a mimetype.
* It is a KMimeType::Ptr plus the changes we made to it.
*/
class MimeTypeData
{
public:
// Constructor used for groups
MimeTypeData(const QString& major);
// Real constructor, used for an existing mimetype.
MimeTypeData(const KMimeType::Ptr mime);
// Real constructor, used for a new mimetype.
MimeTypeData(const QString& mimeName, bool /*unused, just to distinguish from the other QString ctor*/);
QString name() const { return m_isGroup ? m_major : m_major + '/' + m_minor; }
QString majorType() const { return m_major; }
QString minorType() const { return m_minor; }
void setMinor(const QString& m) { m_minor = m; }
QString comment() const { return m_comment; }
void setComment(const QString& c) { m_comment = c; }
/**
* Returns true if "this" is a group
*/
bool isMeta() const { return m_isGroup; }
/**
* Returns true if the type is essential, i.e. can't be deleted
* (see KMimeType::checkEssentialMimeTypes)
*/
bool isEssential() const;
QString icon() const;
void setUserSpecifiedIcon(const QString& icon);
QStringList patterns() const { return m_patterns; }
void setPatterns(const QStringList &p);
QStringList appServices() const;
void setAppServices(const QStringList &dsl);
QStringList embedServices() const;
void setEmbedServices(const QStringList &dsl);
enum AutoEmbed { Yes = 0, No = 1, UseGroupSetting = 2 };
AutoEmbed autoEmbed() const { return m_autoEmbed; }
void setAutoEmbed( AutoEmbed a ) { m_autoEmbed = a; }
const KMimeType::Ptr& mimeType() const { return m_mimetype; }
bool canUseGroupSetting() const;
void getAskSave(bool &);
void setAskSave(bool);
/**
* Returns true if the mimetype data has any unsaved changes.
*/
bool isDirty() const;
/**
* Save changes to disk.
* Does not check isDirty(), so the common idiom is if (data.isDirty()) { needUpdate = data.sync(); }
* Returns true if update-mime-database needs to be run afterwards
*/
bool sync();
/**
* Update m_mimetype from ksycoca when Apply is pressed
*/
void refresh();
/**
* Return true if this is a new mimetype, i.e. one that is not yet in ksycoca
*/
bool isNew() const { return m_bNewItem; }
/**
* Helper method for the filtering in the listview
*/
bool matchesFilter(const QString& filter) const;
private:
void initFromKMimeType();
AutoEmbed readAutoEmbed() const;
void writeAutoEmbed();
bool isMimeTypeDirty() const; // whether the mimetype definition file needs saving
QStringList getAppOffers() const;
QStringList getPartOffers() const;
void getMyServiceOffers() const;
void syncServices();
void saveServices(KConfigGroup & config, const QStringList& services);
void saveRemovedServices(KConfigGroup & config, const QStringList& services, const QStringList& oldServices);
KMimeType::Ptr m_mimetype; // 0 if this is data for a mimetype group (m_isGroup==true)
enum AskSave { AskSaveYes = 0, AskSaveNo = 1, AskSaveDefault = 2 };
AskSave m_askSave:3;
AutoEmbed m_autoEmbed:3;
bool m_bNewItem:1;
mutable bool m_bFullInit:1; // lazy init of m_appServices and m_embedServices
bool m_isGroup:1;
bool m_appServicesModified:1;
bool m_embedServicesModified:1;
QString m_major, m_minor, m_comment, m_userSpecifiedIcon;
QStringList m_patterns;
mutable QStringList m_appServices;
mutable QStringList m_embedServices;
};
#endif /* MIMETYPEDATA_H */

View file

@ -1,179 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2007, 2008 David Faure <faure@kde.org>
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 ) version 3 or, at the discretion of KDE e.V. ( which shall
act as a proxy as in section 14 of the GPLv3 ), any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "mimetypewriter.h"
#include <kmimetype.h>
#include <kdebug.h>
#include <kdeversion.h>
#include <kprocess.h>
#include <kstandarddirs.h>
#include <QXmlStreamWriter>
#include <QFile>
/// WARNING: this code is duplicated between apps/nsplugins and runtime/filetypes
static bool sharedMimeInfoSupportsIcon()
{
return KMimeType::sharedMimeInfoVersion() >= KDE_MAKE_VERSION(0, 40, 0);
}
class MimeTypeWriterPrivate
{
public:
QString localFilePath() const;
QString m_mimeType;
QString m_comment;
QString m_iconName;
QStringList m_patterns;
QString m_marker;
};
MimeTypeWriter::MimeTypeWriter(const QString& mimeType)
: d(new MimeTypeWriterPrivate)
{
d->m_mimeType = mimeType;
Q_ASSERT(!mimeType.isEmpty());
}
MimeTypeWriter::~MimeTypeWriter()
{
delete d;
}
void MimeTypeWriter::setComment(const QString& comment)
{
d->m_comment = comment;
}
void MimeTypeWriter::setPatterns(const QStringList& patterns)
{
d->m_patterns = patterns;
}
void MimeTypeWriter::setIconName(const QString& iconName)
{
d->m_iconName = iconName;
}
void MimeTypeWriter::setMarker(const QString& marker)
{
d->m_marker = marker;
}
bool MimeTypeWriter::write()
{
const QString packageFileName = d->localFilePath();
kDebug() << "writing" << packageFileName;
QFile packageFile(packageFileName);
if (!packageFile.open(QIODevice::WriteOnly)) {
kError() << "Couldn't open" << packageFileName << "for writing";
return false;
}
QXmlStreamWriter writer(&packageFile);
writer.setAutoFormatting(true);
writer.writeStartDocument();
if (!d->m_marker.isEmpty()) {
writer.writeComment(d->m_marker);
}
const QString nsUri = "http://www.freedesktop.org/standards/shared-mime-info";
writer.writeDefaultNamespace(nsUri);
writer.writeStartElement("mime-info");
writer.writeStartElement(nsUri, "mime-type");
writer.writeAttribute("type", d->m_mimeType);
if (!d->m_comment.isEmpty()) {
writer.writeStartElement(nsUri, "comment");
writer.writeCharacters(d->m_comment);
writer.writeEndElement(); // comment
}
if (!d->m_iconName.isEmpty()) {
// User-specified icon name
if (sharedMimeInfoSupportsIcon()) {
writer.writeStartElement(nsUri, "icon");
writer.writeAttribute("name", d->m_iconName);
writer.writeEndElement(); // icon
}
}
foreach(const QString& pattern, d->m_patterns) {
writer.writeStartElement(nsUri, "glob");
writer.writeAttribute("pattern", pattern);
writer.writeEndElement(); // glob
}
writer.writeEndElement(); // mime-info
writer.writeEndElement(); // mime-type
writer.writeEndDocument();
return true;
}
void MimeTypeWriter::runUpdateMimeDatabase()
{
const QString localPackageDir = KStandardDirs::locateLocal("xdgdata-mime", QString());
Q_ASSERT(!localPackageDir.isEmpty());
KProcess proc;
proc << "update-mime-database";
proc << localPackageDir;
const int exitCode = proc.execute();
if (exitCode) {
kWarning() << proc.program() << "exited with error code" << exitCode;
}
}
QString MimeTypeWriterPrivate::localFilePath() const
{
// XDG shared mime: we must write into a <kdehome>/share/mime/packages/ file...
// To simplify our job, let's use one "input" file per mimetype, in the user's dir.
// (this writes into $HOME/.local/share/mime by default)
//
// We could also use Override.xml, says the spec, but then we'd need to merge with other mimetypes,
// and in ~/.local we don't really expect other packages to be installed anyway...
QString baseName = m_mimeType;
baseName.replace('/', '-');
return KStandardDirs::locateLocal( "xdgdata-mime", "packages/" + baseName + ".xml" );
}
static QString existingDefinitionFile(const QString& mimeType)
{
QString baseName = mimeType;
baseName.replace('/', '-');
return KGlobal::dirs()->findResource( "xdgdata-mime", "packages/" + baseName + ".xml" );
}
bool MimeTypeWriter::hasDefinitionFile(const QString& mimeType)
{
return !existingDefinitionFile(mimeType).isEmpty();
}
void MimeTypeWriter::removeOwnMimeType(const QString& mimeType)
{
const QString file = existingDefinitionFile(mimeType);
Q_ASSERT(!file.isEmpty());
QFile::remove(file);
// We must also remove the generated XML file, update-mime-database doesn't do that, for unknown media types
QString xmlFile = KGlobal::dirs()->findResource( "xdgdata-mime", mimeType + ".xml" );
QFile::remove(xmlFile);
}
/// WARNING: this code is duplicated between apps/nsplugins and runtime/filetypes

View file

@ -1,102 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2007, 2008 David Faure <faure@kde.org>
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 ) version 3 or, at the discretion of KDE e.V. ( which shall
act as a proxy as in section 14 of the GPLv3 ), any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef MIMETYPEWRITER_H
#define MIMETYPEWRITER_H
class QStringList;
class QString;
class MimeTypeWriterPrivate;
/// WARNING: this code is duplicated between apps/nsplugins and runtime/filetypes
/**
* MimeTypeWriter writes out the definition of a mimetype
* in a XDG shared-mime-info compliant way.
*/
class MimeTypeWriter
{
public:
MimeTypeWriter(const QString& mimeType);
~MimeTypeWriter();
/**
* Sets the comment describing this mimetype.
* It is strongly recommended to call this.
*/
void setComment(const QString& comment);
/**
* Define the patterns associated with this mimetype,
* like "*.png"
*/
void setPatterns(const QStringList& patterns);
/**
* Optional: set a user-specified icon name for this mimetype.
* Otherwise the icon name is based on the mimetype name.
*/
void setIconName(const QString& iconName);
/**
* Sets a string that will be written out as an XML comment
* in the XML definition file, to make it possible to recognize
* this file later on. Used by nspluginscan.
*/
void setMarker(const QString& marker);
/**
* Write out the mimetype definition file
* Returns true on success
*/
bool write();
/**
* Returns true if a mimetype definition file already exists
* for the given mimetype.
*
* NOTE: this is not the same as testing whether the
* mimetype is defined in general (for instance by freedesktop.org.xml)
* you should use KMimeType::mimeType() for that.
* This method is only for mimetypes generated by MimeTypeWriter.
*/
static bool hasDefinitionFile(const QString& mimeType);
/**
* Remove mimetype created by MimeTypeWriter.
* Assumes hasDefinitionFile(mimeType).
* Remember to call runUpdateMimeDatabase afterwards!
*/
static void removeOwnMimeType(const QString& mimeType);
/**
* Call this once after writing as many mimetypes as you want,
* to let update-mime-database process the new mimetype xml files.
*/
static void runUpdateMimeDatabase();
private:
MimeTypeWriterPrivate* const d;
};
/// WARNING: this code is duplicated between apps/nsplugins and runtime/filetypes
#endif /* MIMETYPEWRITER_H */

View file

@ -1,82 +0,0 @@
/* This file is part of the KDE project
Copyright 2000 Kurt Granroth <granroth@kde.org>
2008 David Faure <faure@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
// Own
#include "newtypedlg.h"
// Qt
#include <QtGui/QBoxLayout>
#include <QtGui/QComboBox>
#include <QtGui/QFrame>
#include <QtGui/QFormLayout>
#include <QtGui/QLabel>
#include <QtGui/QLayout>
// KDE
#include <klineedit.h>
#include <klocale.h>
NewTypeDialog::NewTypeDialog(const QStringList &groups, QWidget *parent)
: KDialog( parent )
{
setModal( true );
setCaption( i18n( "Create New File Type" ) );
setButtons( Ok | Cancel );
showButtonSeparator( true );
QWidget* main = mainWidget();
QFormLayout *formLayout = new QFormLayout(main);
QLabel *l = new QLabel(i18n("Group:"), main);
m_groupCombo = new QComboBox(main);
m_groupCombo->setEditable(true);
m_groupCombo->addItems(groups);
formLayout->addRow(l, m_groupCombo);
m_groupCombo->setWhatsThis( i18n("Select the category under which"
" the new file type should be added.") );
// Line 1: mimetype name
l = new QLabel(i18n("Type name:"), main);
m_typeEd = new KLineEdit(main);
formLayout->addRow(l, m_typeEd);
m_typeEd->setWhatsThis(i18n("Type the name of the file type. For instance, if you selected 'image' as category and you type 'custom' here, the file type 'image/custom' will be created."));
m_typeEd->setFocus();
// Set a minimum width so that caption is not half-hidden
setMinimumWidth(300);
}
QString NewTypeDialog::group() const
{
return m_groupCombo->currentText();
}
QString NewTypeDialog::text() const
{
return m_typeEd->text();
}

View file

@ -1,46 +0,0 @@
/* This file is part of the KDE project
Copyright 2000 Kurt Granroth <granroth@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef _NEWTYPEDLG_H
#define _NEWTYPEDLG_H
#include <kdialog.h>
class QStringList;
class KLineEdit;
class QComboBox;
/**
* A dialog for creating a new file type, with
* - a combobox for choosing the group
* - a line-edit for entering the name of the file type
* The rest (description, patterns, icon, apps) can be set later in the filetypesview anyway.
*/
class NewTypeDialog : public KDialog
{
public:
explicit NewTypeDialog(const QStringList &groups, QWidget *parent);
QString group() const;
QString text() const;
private:
KLineEdit *m_typeEd;
QComboBox *m_groupCombo;
};
#endif

View file

@ -1,28 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2009 David Faure <faure@kde.org>
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 ) version 3 or, at the discretion of KDE e.V. ( which shall
act as a proxy as in section 14 of the GPLv3 ), any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "sharedmimeinfoversion.h"
#include <kmimetype.h>
#include <kdeversion.h>
bool SharedMimeInfoVersion::supportsIcon()
{
return KMimeType::sharedMimeInfoVersion() >= KDE_MAKE_VERSION(0, 40, 0);
}

View file

@ -1,30 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2009 David Faure <faure@kde.org>
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 ) version 3 or, at the discretion of KDE e.V. ( which shall
act as a proxy as in section 14 of the GPLv3 ), any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef SHAREDMIMEINFOVERSION_H
#define SHAREDMIMEINFOVERSION_H
namespace SharedMimeInfoVersion
{
bool supportsIcon();
}
#endif /* SHAREDMIMEINFOVERSION_H */

View file

@ -1,13 +0,0 @@
set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} )
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. ${KDE4_INCLUDES} )
########### filetypestest ###############
kde4_add_unit_test(filetypestest TEST
filetypestest.cpp
../mimetypedata.cpp
../mimetypewriter.cpp
../sharedmimeinfoversion.cpp
)
target_link_libraries(filetypestest ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBRARY} ${KDE4_KDEUI_LIBRARIES}
${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTTEST_LIBRARY})

View file

@ -1,369 +0,0 @@
/* This file is part of the KDE project
Copyright 2007 David Faure <faure@kde.org>
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 ) version 3 or, at the discretion of KDE e.V. ( which shall
act as a proxy as in section 14 of the GPLv3 ), any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Boston, MA 02110-1301, USA.
*/
#include <kprocess.h>
#include <kservice.h>
#include <qtest_kde.h>
#include <kconfiggroup.h>
#include <kdebug.h>
#include <kdesktopfile.h>
#include <kstandarddirs.h>
#include <ksycoca.h>
#include <mimetypedata.h>
#include <mimetypewriter.h>
class FileTypesTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase()
{
m_mimeTypeCreatedSuccessfully = false;
const QString kdehome = QDir::home().canonicalPath() + "/.kde-unit-test";
// We need a place where we can hack a mimeapps.list without harm, so not ~/.local
::setenv("XDG_DATA_HOME", QFile::encodeName(kdehome) + "/xdg/local", 1);
QStringList appsDirs = KGlobal::dirs()->resourceDirs("xdgdata-apps");
//kDebug() << appsDirs;
m_localApps = kdehome + "/xdg/local/applications/";
QCOMPARE(appsDirs.first(), m_localApps);
QCOMPARE(KGlobal::dirs()->resourceDirs("xdgdata-mime").first(), kdehome + "/xdg/local/mime/");
QFile::remove(m_localApps + "mimeapps.list");
// Create fake applications for some tests below.
bool mustUpdateKSycoca = false;
fakeApplication = "fakeapplication.desktop";
if (createDesktopFile(m_localApps + fakeApplication))
mustUpdateKSycoca = true;
fakeApplication2 = "fakeapplication2.desktop";
if (createDesktopFile(m_localApps + fakeApplication2))
mustUpdateKSycoca = true;
// Cleanup after testMimeTypePatterns if it failed mid-way
const QString packageFileName = KStandardDirs::locateLocal( "xdgdata-mime", "packages/text-plain.xml" );
if (!packageFileName.isEmpty()) {
QFile::remove(packageFileName);
MimeTypeWriter::runUpdateMimeDatabase();
mustUpdateKSycoca = true;
}
QFile::remove(KStandardDirs::locateLocal("config", "filetypesrc"));
if ( mustUpdateKSycoca ) {
// Update ksycoca in ~/.kde-unit-test after creating the above
runKBuildSycoca();
}
KService::Ptr fakeApplicationService = KService::serviceByStorageId(fakeApplication);
QVERIFY(fakeApplicationService);
}
void testMimeTypeGroupAutoEmbed()
{
MimeTypeData data("text");
QCOMPARE(data.majorType(), QString("text"));
QCOMPARE(data.name(), QString("text"));
QVERIFY(data.isMeta());
QCOMPARE(data.autoEmbed(), MimeTypeData::No); // text doesn't autoembed by default
QVERIFY(!data.isDirty());
data.setAutoEmbed(MimeTypeData::Yes);
QCOMPARE(data.autoEmbed(), MimeTypeData::Yes);
QVERIFY(data.isDirty());
QVERIFY(!data.sync()); // save to disk. Should succeed, but return false (no need to run update-mime-database)
QVERIFY(!data.isDirty());
// Check what's on disk by creating another MimeTypeData instance
MimeTypeData data2("text");
QCOMPARE(data2.autoEmbed(), MimeTypeData::Yes);
QVERIFY(!data2.isDirty());
data2.setAutoEmbed(MimeTypeData::No); // revert to default, for next time
QVERIFY(data2.isDirty());
QVERIFY(!data2.sync());
QVERIFY(!data2.isDirty());
// TODO test askSave after cleaning up the code
}
void testMimeTypeAutoEmbed()
{
MimeTypeData data(KMimeType::mimeType("text/plain"));
QCOMPARE(data.majorType(), QString("text"));
QCOMPARE(data.minorType(), QString("plain"));
QCOMPARE(data.name(), QString("text/plain"));
QVERIFY(!data.isMeta());
QCOMPARE(data.autoEmbed(), MimeTypeData::UseGroupSetting);
QVERIFY(!data.isDirty());
data.setAutoEmbed(MimeTypeData::Yes);
QCOMPARE(data.autoEmbed(), MimeTypeData::Yes);
QVERIFY(data.isDirty());
QVERIFY(!data.sync()); // save to disk. Should succeed, but return false (no need to run update-mime-database)
QVERIFY(!data.isDirty());
// Check what's on disk by creating another MimeTypeData instance
MimeTypeData data2(KMimeType::mimeType("text/plain"));
QCOMPARE(data2.autoEmbed(), MimeTypeData::Yes);
QVERIFY(!data2.isDirty());
data2.setAutoEmbed(MimeTypeData::UseGroupSetting); // revert to default, for next time
QVERIFY(data2.isDirty());
QVERIFY(!data2.sync());
QVERIFY(!data2.isDirty());
}
void testMimeTypePatterns()
{
MimeTypeData data(KMimeType::mimeType("text/plain"));
QCOMPARE(data.name(), QString("text/plain"));
QCOMPARE(data.majorType(), QString("text"));
QCOMPARE(data.minorType(), QString("plain"));
QVERIFY(!data.isMeta());
QStringList patterns = data.patterns();
QVERIFY(patterns.contains("*.txt"));
QVERIFY(!patterns.contains("*.toto"));
const QStringList origPatterns = patterns;
patterns.append("*.toto"); // yes, a french guy wrote this, as you can see
patterns.sort(); // for future comparisons
QVERIFY(!data.isDirty());
data.setPatterns(patterns);
QVERIFY(data.isDirty());
bool needUpdateMimeDb = data.sync();
QVERIFY(needUpdateMimeDb);
MimeTypeWriter::runUpdateMimeDatabase();
runKBuildSycoca();
QCOMPARE(data.patterns(), patterns);
data.refresh(); // reload from ksycoca
QCOMPARE(data.patterns(), patterns);
QVERIFY(!data.isDirty());
// Check what's in ksycoca
QStringList newPatterns = KMimeType::mimeType("text/plain")->patterns();
newPatterns.sort();
QCOMPARE(newPatterns, patterns);
// Remove custom file
const QString packageFileName = KStandardDirs::locateLocal( "xdgdata-mime", "packages/text-plain.xml" );
QVERIFY(!packageFileName.isEmpty());
QFile::remove(packageFileName);
MimeTypeWriter::runUpdateMimeDatabase();
runKBuildSycoca();
// Check what's in ksycoca
newPatterns = KMimeType::mimeType("text/plain")->patterns();
newPatterns.sort();
QCOMPARE(newPatterns, origPatterns);
}
void testAddService()
{
const char* mimeTypeName = "application/vnd.oasis.opendocument.text";
MimeTypeData data(KMimeType::mimeType(mimeTypeName));
QStringList appServices = data.appServices();
//kDebug() << appServices;
const QString oldPreferredApp = appServices.first();
QVERIFY(!appServices.contains(fakeApplication)); // already there? hmm can't really test then
QVERIFY(!data.isDirty());
appServices.prepend(fakeApplication);
data.setAppServices(appServices);
QVERIFY(data.isDirty());
QVERIFY(!data.sync()); // success, but no need to run update-mime-database
runKBuildSycoca();
QVERIFY(!data.isDirty());
// Check what's in ksycoca
checkMimeTypeServices(mimeTypeName, appServices);
// Check what's in mimeapps.list
checkAddedAssociationsContains(mimeTypeName, fakeApplication);
// Now test removing (in the same test, since it's inter-dependent)
QVERIFY(appServices.removeAll(fakeApplication) > 0);
data.setAppServices(appServices);
QVERIFY(data.isDirty());
QVERIFY(!data.sync()); // success, but no need to run update-mime-database
runKBuildSycoca();
// Check what's in ksycoca
checkMimeTypeServices(mimeTypeName, appServices);
// Check what's in mimeapps.list
checkRemovedAssociationsContains(mimeTypeName, fakeApplication);
}
void testRemoveTwice()
{
// Remove fakeApplication from image/png
const char* mimeTypeName = "image/png";
MimeTypeData data(KMimeType::mimeType(mimeTypeName));
QStringList appServices = data.appServices();
kDebug() << "initial list for" << mimeTypeName << appServices;
QVERIFY(appServices.removeAll(fakeApplication) > 0);
data.setAppServices(appServices);
QVERIFY(!data.sync()); // success, but no need to run update-mime-database
runKBuildSycoca();
// Check what's in ksycoca
checkMimeTypeServices(mimeTypeName, appServices);
// Check what's in mimeapps.list
checkRemovedAssociationsContains(mimeTypeName, fakeApplication);
// Remove fakeApplication2 from image/png; must keep the previous entry in "Removed Associations"
kDebug() << "Removing fakeApplication2";
QVERIFY(appServices.removeAll(fakeApplication2) > 0);
data.setAppServices(appServices);
QVERIFY(!data.sync()); // success, but no need to run update-mime-database
runKBuildSycoca();
// Check what's in ksycoca
checkMimeTypeServices(mimeTypeName, appServices);
// Check what's in mimeapps.list
checkRemovedAssociationsContains(mimeTypeName, fakeApplication);
// Check what's in mimeapps.list
checkRemovedAssociationsContains(mimeTypeName, fakeApplication2);
// And now re-add fakeApplication2...
kDebug() << "Re-adding fakeApplication2";
appServices.prepend(fakeApplication2);
data.setAppServices(appServices);
QVERIFY(!data.sync()); // success, but no need to run update-mime-database
runKBuildSycoca();
// Check what's in ksycoca
checkMimeTypeServices(mimeTypeName, appServices);
// Check what's in mimeapps.list
checkRemovedAssociationsContains(mimeTypeName, fakeApplication);
checkRemovedAssociationsDoesNotContain(mimeTypeName, fakeApplication2);
}
void testCreateMimeType()
{
const QString mimeTypeName = "fake/unit-test-fake-mimetype";
// Clean up after previous runs if necessary
if (MimeTypeWriter::hasDefinitionFile(mimeTypeName))
MimeTypeWriter::removeOwnMimeType(mimeTypeName);
MimeTypeData data(mimeTypeName, true);
data.setComment("Fake MimeType");
QStringList patterns = QStringList() << "*.pkg.tar.gz";
data.setPatterns(patterns);
QVERIFY(data.isDirty());
QVERIFY(data.sync());
MimeTypeWriter::runUpdateMimeDatabase();
runKBuildSycoca();
KMimeType::Ptr mime = KMimeType::mimeType(mimeTypeName);
QVERIFY(mime);
QCOMPARE(mime->comment(), QString("Fake MimeType"));
QCOMPARE(mime->patterns(), patterns); // must sort them if more than one
// Testcase for the shaman.xml bug
QCOMPARE(KMimeType::findByPath("/whatever/foo.pkg.tar.gz")->name(), QString("fake/unit-test-fake-mimetype"));
m_mimeTypeCreatedSuccessfully = true;
}
void testDeleteMimeType()
{
if (!m_mimeTypeCreatedSuccessfully)
QSKIP("This test relies on testCreateMimeType", SkipAll);
const QString mimeTypeName = "fake/unit-test-fake-mimetype";
QVERIFY(MimeTypeWriter::hasDefinitionFile(mimeTypeName));
MimeTypeWriter::removeOwnMimeType(mimeTypeName);
MimeTypeWriter::runUpdateMimeDatabase();
runKBuildSycoca();
KMimeType::Ptr mime = KMimeType::mimeType(mimeTypeName);
QVERIFY(!mime);
}
void cleanupTestCase()
{
// If we remove it, then every run of the unit test has to run kbuildsycoca... slow.
//QFile::remove(KStandardDirs::locateLocal("xdgdata-apps", "fakeapplication.desktop"));
}
private: // helper methods
void checkAddedAssociationsContains(const QString& mimeTypeName, const QString& application)
{
const KConfig config(m_localApps + "mimeapps.list", KConfig::NoGlobals);
const KConfigGroup group(&config, "Added Associations");
const QStringList addedEntries = group.readXdgListEntry(mimeTypeName);
if (!addedEntries.contains(application)) {
kWarning() << addedEntries << "does not contain" << application;
QVERIFY(addedEntries.contains(application));
}
}
void checkRemovedAssociationsContains(const QString& mimeTypeName, const QString& application)
{
const KConfig config(m_localApps + "mimeapps.list", KConfig::NoGlobals);
const KConfigGroup group(&config, "Removed Associations");
const QStringList removedEntries = group.readXdgListEntry(mimeTypeName);
if (!removedEntries.contains(application)) {
kWarning() << removedEntries << "does not contain" << application;
QVERIFY(removedEntries.contains(application));
}
}
void checkRemovedAssociationsDoesNotContain(const QString& mimeTypeName, const QString& application)
{
const KConfig config(m_localApps + "mimeapps.list", KConfig::NoGlobals);
const KConfigGroup group(&config, "Removed Associations");
const QStringList removedEntries = group.readXdgListEntry(mimeTypeName);
if (removedEntries.contains(application)) {
kWarning() << removedEntries << "contains" << application;
QVERIFY(!removedEntries.contains(application));
}
}
void runKBuildSycoca()
{
// Wait for notifyDatabaseChanged DBus signal
// (The real KCM code simply does the refresh in a slot, asynchronously)
QEventLoop loop;
QObject::connect(KSycoca::self(), SIGNAL(databaseChanged()), &loop, SLOT(quit()));
KProcess proc;
proc << KStandardDirs::findExe(KBUILDSYCOCA_EXENAME);
proc.setOutputChannelMode(KProcess::MergedChannels); // silence kbuildsycoca output
proc.execute();
loop.exec();
}
bool createDesktopFile(const QString& path)
{
if (!QFile::exists(path)) {
KDesktopFile file(path);
KConfigGroup group = file.desktopGroup();
group.writeEntry("Name", "FakeApplication");
group.writeEntry("Type", "Application");
group.writeEntry("Exec", "ls");
group.writeEntry("MimeType", "image/png");
return true;
}
return false;
}
void checkMimeTypeServices(const QString& mimeTypeName, const QStringList& expectedServices)
{
MimeTypeData data2(KMimeType::mimeType(mimeTypeName));
if (data2.appServices() != expectedServices)
kDebug() << "got" << data2.appServices() << "expected" << expectedServices;
QCOMPARE(data2.appServices(), expectedServices);
}
QString fakeApplication; // storage id of the fake application
QString fakeApplication2; // storage id of the fake application2
QString m_localApps;
bool m_mimeTypeCreatedSuccessfully;
};
QTEST_KDEMAIN( FileTypesTest, NoGUI )
#include "filetypestest.moc"

View file

@ -1,67 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
Copyright (C) 2003, 2007 David Faure <faure@kde.org>
Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
// Own
#include "typeslistitem.h"
// KDE
#include <kdebug.h>
#include <kicon.h>
TypesListItem::TypesListItem(QTreeWidget *parent, const QString & major)
: QTreeWidgetItem(parent),
m_mimetypeData(major)
{
setText(0, major);
}
TypesListItem::TypesListItem(TypesListItem *parent, KMimeType::Ptr mimetype)
: QTreeWidgetItem(parent),
m_mimetypeData(mimetype)
{
setText(0, m_mimetypeData.minorType());
}
TypesListItem::TypesListItem(TypesListItem *parent, const QString& newMimetype)
: QTreeWidgetItem(parent),
m_mimetypeData(newMimetype, true)
{
setText(0, m_mimetypeData.minorType());
}
TypesListItem::~TypesListItem()
{
}
void TypesListItem::setIcon( const QString& icon )
{
m_mimetypeData.setUserSpecifiedIcon(icon);
loadIcon(true);
}
void TypesListItem::loadIcon(bool forceReload)
{
if ((!m_mimetypeData.icon().isEmpty() && icon(0).isNull()) || forceReload) {
QTreeWidgetItem::setIcon(0, KIcon(m_mimetypeData.icon()));
}
}

View file

@ -1,62 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
Copyright (C) 2003 David Faure <faure@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License version 2 or at your option version 3 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef TYPESLISTITEM_H
#define TYPESLISTITEM_H
#include "mimetypedata.h"
#include <QtGui/QTreeWidgetItem>
#include <kmimetype.h>
// TODO different subclasses for mimetypes and groups?
class TypesListItem : public QTreeWidgetItem
{
public:
/**
* Create a filetype group
*/
TypesListItem(QTreeWidget *parent, const QString &major);
/**
* Create a filetype item inside a group, for an existing mimetype
*/
TypesListItem(TypesListItem *parent, KMimeType::Ptr mimetype);
/**
* Create a filetype item inside a group, for a new mimetype
*/
TypesListItem(TypesListItem *parent, const QString& newMimetype);
~TypesListItem();
void setIcon( const QString& icon );
QString name() const { return m_mimetypeData.name(); }
const MimeTypeData& mimeTypeData() const { return m_mimetypeData; }
MimeTypeData& mimeTypeData() { return m_mimetypeData; }
void loadIcon(bool forceReload = false);
private:
MimeTypeData m_mimetypeData;
};
#endif