summaryrefslogtreecommitdiffstats
path: root/noatun/modules/metatag
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commite2de64d6f1beb9e492daf5b886e19933c1fa41dd (patch)
tree9047cf9e6b5c43878d5bf82660adae77ceee097a /noatun/modules/metatag
downloadtdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.tar.gz
tdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'noatun/modules/metatag')
-rw-r--r--noatun/modules/metatag/HANDLED_ITEMS21
-rw-r--r--noatun/modules/metatag/Makefile.am15
-rw-r--r--noatun/modules/metatag/edit.cpp312
-rw-r--r--noatun/modules/metatag/edit.h55
-rw-r--r--noatun/modules/metatag/metatag.cpp124
-rw-r--r--noatun/modules/metatag/metatag.h30
-rw-r--r--noatun/modules/metatag/metatag.plugin125
7 files changed, 682 insertions, 0 deletions
diff --git a/noatun/modules/metatag/HANDLED_ITEMS b/noatun/modules/metatag/HANDLED_ITEMS
new file mode 100644
index 00000000..3c369a9e
--- /dev/null
+++ b/noatun/modules/metatag/HANDLED_ITEMS
@@ -0,0 +1,21 @@
+ Here are the mappings between the items returned from KFileMetaInfo, and the
+properties Metatag sets based on those items. These properties may or may be
+set depending on the file's type and contents, and will not be set for
+non-local files or streams.
+
+|=============================================================================|
+| KFileMetaInfo Key | Noatun Property | Description |
+|===================|=================|=======================================|
+| Artist | author | Author |
+| Album | album | Album from which the file originates |
+| Bitrate | bitrate | Average bitrate (kilobits per second) |
+| Channels | channels | Number of audio channels |
+| Comment | comment | Free-form text comment |
+| Date | date | Date the file was released |
+| Genre | genre | Genre of file |
+| Location | location | Location of recording |
+| Organization | organization | |
+| Sample Rate | samplerate | File's audio sample rate (hertz) |
+| Title | title | Title of file |
+| Tracknumber | track | Track number of file on it's album |
+|=============================================================================|
diff --git a/noatun/modules/metatag/Makefile.am b/noatun/modules/metatag/Makefile.am
new file mode 100644
index 00000000..330e9f34
--- /dev/null
+++ b/noatun/modules/metatag/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES= -I$(top_srcdir)/noatun/library -I$(kde_includes)/arts $(all_includes)
+kde_module_LTLIBRARIES = noatun_metatag.la
+
+noatun_metatag_la_SOURCES = metatag.cpp edit.cpp
+
+noatun_metatag_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined
+noatun_metatag_la_LIBADD = $(LIB_KIO) $(top_builddir)/noatun/library/libnoatun.la \
+ $(top_builddir)/noatun/library/noatuntags/libnoatuntags.la
+
+noatun_metatag_la_METASOURCES = AUTO
+
+noinst_HEADERS = metatag.h edit.h
+
+noatun_modules_metatag_DATA = metatag.plugin
+noatun_modules_metatagdir = $(kde_datadir)/noatun
diff --git a/noatun/modules/metatag/edit.cpp b/noatun/modules/metatag/edit.cpp
new file mode 100644
index 00000000..d5ccb0c4
--- /dev/null
+++ b/noatun/modules/metatag/edit.cpp
@@ -0,0 +1,312 @@
+#include <klocale.h>
+#include <qlayout.h>
+#include <klineedit.h>
+#include <qlabel.h>
+#include <qptrlist.h>
+
+#include <kmimetype.h>
+#include <kicontheme.h>
+#include <qtooltip.h>
+#include <kstringvalidator.h>
+#include <qspinbox.h>
+#include <qhbox.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qcombobox.h>
+#include <qpushbutton.h>
+#include <kdialogbase.h>
+#include <kdebug.h>
+#include <kseparator.h>
+#include <kfilemetainfo.h>
+#include <qvalidator.h>
+
+#include "metatag.h"
+#include "edit.h"
+
+Editor::Editor()
+: KDialogBase((QWidget*)0L, 0, false, i18n("Tag Editor"), Ok | Cancel)
+{
+ mMainWidget = makeMainWidget();
+// mMainWidget->setMinimumWidth(325);
+
+ mGrid = new QGridLayout(mMainWidget, 1, 1, 0, spacingHint(), "Editor::mGrid");
+
+ mGrid->setColStretch(1, 1);
+ mGrid->setColStretch(2, 1);
+
+ QHBox *heading = new QHBox(mMainWidget, "Editor::heading");
+ heading->setSpacing(4);
+ mFileIcon = new QLabel(heading);
+ mFileIcon->setAlignment(AlignVCenter | AlignLeft);
+ mFile = new QLabel(heading);
+ mFile->setAlignment(AlignVCenter | AlignLeft);
+ heading->setStretchFactor(mFile, 2);
+ mGrid->addMultiCellWidget(heading, 0, 0, 0, 2);
+
+ KSeparator *sep = new KSeparator(KSeparator::HLine, mMainWidget);
+ mGrid->addMultiCellWidget(sep, 1, 1, 0, 2);
+
+ mControls.setAutoDelete(true);
+ mNextRow = 2;
+
+ connect(this, SIGNAL(closeClicked()), SLOT(delayedDestruct()));
+ connect(this, SIGNAL(okClicked()), SLOT(save()));
+
+ enableButtonSeparator(true);
+ setFixedHeight(sizeHint().height());
+}
+
+void Editor::open(const PlaylistItem & file)
+{
+ KFileMetaInfo file_meta_info(file.file(), file.mimetype());
+ KFileMetaInfoItem info_item;
+
+ item = file;
+ mDirty = false;
+
+ mFile->setText("<nobr><b>" + file.url().fileName(false) + "</b></nobr>");
+ QToolTip::add(mFile, file.url().prettyURL());
+ mFileIcon->
+ setPixmap(KMimeType::pixmapForURL(file.url(), 0, KIcon::Small));
+
+ if (file.url().isLocalFile()) {
+ QFileInfo file_info(file.file());
+ mFileWritable = file_info.isWritable();
+ }
+ else {
+ // KFileMetaInfo doesn't work on remote files
+ mFileWritable = false;
+ }
+
+ if ( !file_meta_info.isValid() ) // go ahead people, nothing to see here
+ return;
+
+ mControls.append(createControl(file_meta_info, i18n("&Title"), "Title", QVariant::String, false, mMainWidget));
+ mControls.append(createControl(file_meta_info, i18n("&Artist"), "Artist", QVariant::String, false, mMainWidget));
+ mControls.append(createControl(file_meta_info, i18n("A&lbum"), "Album", QVariant::String, false, mMainWidget));
+ mControls.append(createControl(file_meta_info, i18n("&Date"), "Date", QVariant::String, false, mMainWidget));
+ mControls.append(createControl(file_meta_info, i18n("T&rack"), "Tracknumber", QVariant::UInt, false, mMainWidget));
+ mControls.append(createControl(file_meta_info, i18n("&Genre"), "Genre", QVariant::String, false, mMainWidget));
+ mControls.append(createControl(file_meta_info, i18n("Co&mment"), "Comment", QVariant::String, false, mMainWidget));
+}
+
+void Editor::save()
+{
+ // Only write to disk if something actually changed
+ if (!mDirty)
+ {
+ delayedDestruct();
+ return;
+ }
+
+ KFileMetaInfo meta_info(item.file(), item.mimetype());
+ if ( !meta_info.isValid() )
+ {
+ delayedDestruct();
+ return;
+ }
+
+ for (MetaWidget *meta_widget = mControls.first(); meta_widget; meta_widget = mControls.next() )
+ saveControl(meta_info, *meta_widget);
+
+ meta_info.applyChanges();
+
+ emit(saved(item));
+ delayedDestruct();
+}
+
+void Editor::saveControl(KFileMetaInfo& meta_info, const MetaWidget &meta_widget) {
+ QVariant value;
+ const KFileMimeTypeInfo *info = KFileMetaInfoProvider::self()->mimeTypeInfo( meta_info.mimeType() );
+
+ if (!meta_widget.widget->isEnabled())
+ return;
+
+ if (meta_widget.widget->inherits("QSpinBox"))
+ value = static_cast<QSpinBox *>(meta_widget.widget)->value();
+ else if (meta_widget.widget->inherits("QComboBox"))
+ value = static_cast<QComboBox *>(meta_widget.widget)->currentText();
+ else if (meta_widget.widget->inherits("QLineEdit"))
+ value = static_cast<QLineEdit *>(meta_widget.widget)->text();
+
+ QString group = keyGroup(meta_info, meta_widget.key);
+
+ if (group.isNull()) {
+ kdWarning() << "Cannot find group for " << meta_widget.key << endl;
+ return;
+ }
+
+ if (info->groupInfo(group)->itemInfo(meta_widget.key)) {
+ if (info->groupInfo(group)->attributes() & KFileMimeTypeInfo::Addable) {
+ kdDebug(66666) << "Adding group " << group << endl;
+ if (!meta_info.addGroup(group))
+ kdWarning() << "Adding group \"" << group << "\" failed!" << endl;
+ }
+
+ if (info->groupInfo(group)->itemInfo(meta_widget.key)->attributes() & KFileMimeTypeInfo::Addable) {
+ kdDebug(66666) << "Adding key " << meta_widget.key << endl;
+ if (!meta_info.group(group).addItem(meta_widget.key).isValid())
+ kdWarning() << "Adding key \"" << meta_widget.key << "\" failed!" << endl;
+ }
+ }
+
+ if (value.cast(meta_info.item(meta_widget.key).type())) {
+ if (!meta_info.item(meta_widget.key).setValue(value))
+ kdWarning() << "setValue() failed on " << group << "/" << meta_widget.key << endl;
+ }
+ else
+ kdWarning() << "Cannot save " << meta_widget.key << " as required type." << endl;
+}
+
+MetaWidget* Editor::createControl(KFileMetaInfo& meta_info, const QString &label, const QString &key, QVariant::Type default_type, bool optional, QWidget *parent) {
+ QLabel *tmp_label = 0L;
+ KFileMetaInfoItem info_item = meta_info.item(key);
+ QVariant::Type type;
+ MetaWidget *meta_widget = 0L;
+ QValidator *validator = 0L;
+ QString groupName = keyGroup(meta_info, key);
+ bool known_key = ((!groupName.isNull()) && meta_info.group(groupName).contains(key));
+ bool addable = keyAddable(meta_info, key);
+ const KFileMimeTypeInfo *info = KFileMetaInfoProvider::self()->mimeTypeInfo( meta_info.mimeType() );
+
+ // This key isn't a real thing, and we can't even create it
+ if ((!info_item.isEditable()) && (!addable) && optional)
+ return 0;
+
+ if (!groupName.isNull()) {
+ type = info->groupInfo(groupName)->itemInfo(key)->type();
+ }
+ else {
+ type = default_type;
+ }
+
+ // Get the correct validator
+ if ( info && !groupName.isNull() )
+ validator = info->createValidator( groupName, key, parent );
+
+ // meta_widget is used for book-keeping internally
+ meta_widget = new MetaWidget;
+ meta_widget->key = key;
+
+ if ((type == QVariant::Int) || (type == QVariant::UInt)) {
+ // We're an int, make a spin box
+ QSpinBox *box = new QSpinBox(parent);
+
+ // Well, normally metatag doesn't care that much about suffixes
+ // and prefixes, but this is just too easy.
+ box->setPrefix(info_item.prefix());
+ box->setSuffix(info_item.suffix());
+ // Kinda a hack... display " " instead of "0" (think track numbers)
+ box->setSpecialValueText(" ");
+
+ // Do we have a validator?
+ if (validator) {
+ box->setValidator(validator);
+
+ // Is it an integer validator
+ if (validator->inherits("QIntValidator")) {
+ QIntValidator *int_validator = static_cast<QIntValidator *>(validator);
+
+ // FIXME: Why the -hell- doesn't QSpinBox::setValidator() do this??
+ box->setMinValue(int_validator->bottom());
+ box->setMaxValue(int_validator->top());
+ }
+ }
+
+ box->setValue(info_item.value().toInt());
+
+ connect(box, SIGNAL(valueChanged(int)), this, SLOT(modified()));
+ meta_widget->widget = box;
+ }
+ else {
+ // We're not an int, make a KLineEdit/QComboBox, depending on our validator
+ bool combo_box = false;
+
+ if (validator)
+ combo_box = validator->isA("KStringListValidator");
+
+ if (combo_box) {
+ QComboBox *combo = new QComboBox(parent);
+
+ combo->clear();
+ combo->insertStringList(static_cast<
+ KStringListValidator *
+ >(validator)->stringList());
+
+ combo->setCurrentText(info_item.value().toString());
+ connect(combo, SIGNAL(activated(int)), this, SLOT(modified()));
+
+ meta_widget->widget = combo;
+ }
+ else {
+ KLineEdit *edit;
+
+ edit = new KLineEdit(parent);
+ edit->setText(info_item.value().toString());
+ edit->setValidator(validator);
+ connect(edit, SIGNAL(textChanged(const QString &)), this, SLOT(modified()));
+
+ meta_widget->widget = edit;
+ }
+ }
+
+ if (known_key)
+ meta_widget->widget->setEnabled(info_item.isEditable() && mFileWritable);
+ else
+ meta_widget->widget->setEnabled(addable && mFileWritable);
+
+ mGrid->addMultiCellWidget(meta_widget->widget, mNextRow, mNextRow, 1, 2);
+
+ // Add our label. This is the easy part
+ tmp_label = new QLabel(meta_widget->widget, label + ":", parent);
+ mGrid->addWidget(tmp_label, mNextRow, 0);
+
+
+ mNextRow++;
+
+ return meta_widget;
+}
+
+QString Editor::keyGroup(const KFileMetaInfo& i, QString key) {
+ const KFileMimeTypeInfo *info = KFileMetaInfoProvider::self()->mimeTypeInfo( i.mimeType() );
+ QStringList groups = info->supportedGroups();
+
+ for (QStringList::Iterator it = groups.begin();it != groups.end();++it) {
+ if (info->groupInfo(*it)->itemInfo(key)) {
+ return *it;
+ }
+ }
+
+ return QString::null;
+}
+
+bool Editor::keyAddable(const KFileMetaInfo &i, QString key) {
+ const KFileMimeTypeInfo *info = KFileMetaInfoProvider::self()->mimeTypeInfo( i.mimeType() );
+ QStringList groups = info->supportedGroups();
+
+ kdDebug(66666) << "Testing if " << key << " is addable" << endl;
+ for (QStringList::Iterator it = groups.begin();it != groups.end();++it) {
+ if (info->groupInfo(*it)->supportsVariableKeys()) {
+ kdDebug(66666) << "Group " << *it << " supports variable keys" << endl;
+ return true;
+ }
+
+ if (info->groupInfo(*it)->itemInfo(key)) {
+ if (info->groupInfo(*it)->attributes() & KFileMimeTypeInfo::Addable) {
+ kdDebug(66666) << "Group " << *it << " is addable" << endl;
+ return true;
+ }
+
+ if (info->groupInfo(*it)->itemInfo(key)->attributes() & KFileMimeTypeInfo::Addable)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void Editor::modified() {
+ mDirty = true;
+}
+
+#include "edit.moc"
diff --git a/noatun/modules/metatag/edit.h b/noatun/modules/metatag/edit.h
new file mode 100644
index 00000000..d6b0ab9c
--- /dev/null
+++ b/noatun/modules/metatag/edit.h
@@ -0,0 +1,55 @@
+#ifndef EDITOR_H
+#define EDITOR_H
+
+#include <kdialogbase.h>
+#include <noatun/playlist.h>
+#include <qptrlist.h>
+#include <qvariant.h>
+
+class KFileMetaInfo;
+class KFileMetaInfoItem;
+class QGridLayout;
+
+struct MetaWidget {
+ QWidget *widget;
+ QString key;
+};
+
+class Editor:public KDialogBase {
+ Q_OBJECT
+ public:
+ Editor();
+
+ signals:
+ void saved(PlaylistItem &);
+
+ public slots:
+ void open(const PlaylistItem & i);
+
+ protected slots:
+ void save();
+ void modified();
+
+ protected:
+ bool keyAddable(const KFileMetaInfo &, QString);
+ QString keyGroup(const KFileMetaInfo &, QString);
+
+ void saveControl(KFileMetaInfo& meta_info, const MetaWidget&);
+ MetaWidget *createControl(KFileMetaInfo& meta_info, const QString &label, const QString &key, QVariant::Type default_type, bool optional, QWidget *parent);
+
+ QPtrList<MetaWidget> mControls;
+
+ QWidget *mMainWidget;
+ QGridLayout *mGrid;
+ int mNextRow;
+
+ bool mFileWritable;
+ bool mDirty;
+
+ QLabel *mFile;
+ QLabel *mFileIcon;
+ const char *filename;
+ PlaylistItem item;
+};
+
+#endif
diff --git a/noatun/modules/metatag/metatag.cpp b/noatun/modules/metatag/metatag.cpp
new file mode 100644
index 00000000..d0531092
--- /dev/null
+++ b/noatun/modules/metatag/metatag.cpp
@@ -0,0 +1,124 @@
+
+#include "metatag.h"
+#include "edit.h"
+
+#include <string.h>
+
+#include <noatun/app.h>
+#include <noatun/stdaction.h>
+
+#include <qfile.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qregexp.h>
+
+#include <klocale.h>
+#include <kaction.h>
+#include <kglobal.h>
+#include <klineedit.h>
+#include <kconfig.h>
+#include <kaction.h>
+#include <kiconloader.h>
+#include <kpopupmenu.h>
+#include <kfilemetainfo.h>
+
+extern "C"
+{
+ KDE_EXPORT Plugin *create_plugin()
+ {
+ return new MetaTagLoader;
+ }
+}
+
+MetaTagLoader::MetaTagLoader():Plugin()
+{
+ mAction = new KAction(i18n("&Tag Editor..."), "edit", 0, this, SLOT(editTag()), this, "edittag");
+ napp->pluginActionMenu()->insert(mAction);
+}
+
+MetaTagLoader::~MetaTagLoader()
+{
+ napp->pluginActionMenu()->remove(mAction);
+}
+
+void MetaTagLoader::editTag()
+{
+ PlaylistItem i = napp->player()->current();
+
+ if(!i)
+ return;
+
+ Editor *e = new Editor();
+ e->open(i);
+ e->show();
+
+ connect(e, SIGNAL(saved(PlaylistItem &)),
+ SLOT(update(PlaylistItem &)));
+}
+
+bool MetaTagLoader::update(PlaylistItem & item)
+{
+ KFileMetaInfo file_info(item.file(),item.mimetype());
+
+ // Ack, no file info :(
+ if ( !file_info.isValid() )
+ return false;
+
+ if(item.length() == -1) // no value set, set almost correct id3tag time
+ {
+ KFileMetaInfoItem length_item = file_info.item("Length");
+ if(length_item.isValid())
+ {
+ int numVal = length_item.value().toInt();
+ if (numVal != 0)
+ item.setLength(numVal * 1000);
+ }
+ }
+
+ // Yes, this is icky. It maps KFileMetaInfo property names to Noatun's
+ setProperty(file_info, item, "Title", "title");
+ setProperty(file_info, item, "Artist", "author");
+ setProperty(file_info, item, "Album", "album");
+ setProperty(file_info, item, "Genre", "genre");
+ setProperty(file_info, item, "Tracknumber", "track");
+ setProperty(file_info, item, "Date", "date");
+ setProperty(file_info, item, "Comment", "comment");
+ setProperty(file_info, item, "Location", "location");
+ setProperty(file_info, item, "Organization", "organization");
+
+ // Now map the audio properties over
+ setProperty(file_info, item, "Bitrate", "bitrate");
+ setProperty(file_info, item, "Sample Rate", "samplerate");
+ setProperty(file_info, item, "Channels", "channels");
+
+ return true;
+}
+
+bool MetaTagLoader::setProperty(KFileMetaInfo &info, PlaylistItem &item, const QString &key, const QString &property)
+{
+ KFileMetaInfoItem info_item = info.item(key);
+
+ if ( info_item.isValid() )
+ {
+ if (!info_item.value().toString().stripWhiteSpace().isEmpty())
+ {
+ // The item is valid and non-empty, add it
+ item.setProperty(property, info_item.value().toString());
+ }
+ else
+ {
+ // If the info_item is valid, but empty.
+ // This means we know for a fact that this
+ // property has no value. Blow it away.
+ item.clearProperty(property);
+ }
+ return true;
+ }
+
+ // The item isn't valid, so we don't know that it has
+ // no value. Don't remove the property, so we can work
+ // well with other tag readers, like Lucky
+ return false;
+}
+
+#include "metatag.moc"
diff --git a/noatun/modules/metatag/metatag.h b/noatun/modules/metatag/metatag.h
new file mode 100644
index 00000000..ff5c277f
--- /dev/null
+++ b/noatun/modules/metatag/metatag.h
@@ -0,0 +1,30 @@
+#ifndef NID3_H
+#define NID3_H
+
+#include <noatun/player.h>
+#include <noatun/plugin.h>
+#include <noatun/pref.h>
+#include <noatuntags/tags.h>
+
+#include <qobject.h>
+
+class KFileMetaInfo;
+class KAction;
+
+class MetaTagLoader:public QObject, public Tags, public Plugin {
+ Q_OBJECT
+ public:
+ MetaTagLoader();
+ ~MetaTagLoader();
+
+ public slots:
+ bool update(PlaylistItem & item);
+ void editTag();
+
+ private:
+ bool setProperty(KFileMetaInfo &info, PlaylistItem &item, const QString &key, const QString &property);
+ int menuID;
+ KAction *mAction;
+};
+
+#endif
diff --git a/noatun/modules/metatag/metatag.plugin b/noatun/modules/metatag/metatag.plugin
new file mode 100644
index 00000000..0e359350
--- /dev/null
+++ b/noatun/modules/metatag/metatag.plugin
@@ -0,0 +1,125 @@
+Filename=noatun_metatag.la
+Author=Ryan Cumming
+Site=http://noatun.derkarl.org/
+Email=bodnar42@phalynx.dhs.org
+Type=other
+License=Artistic
+Name=Tag Reader
+Name[af]=Etiket Leser
+Name[ar]=قارئ معلومات الرقعة
+Name[br]=Lenner al liketennoù
+Name[bs]=Čitač tagova
+Name[ca]=Lector de marques
+Name[cs]=Čtení tagů
+Name[cy]=Darllenydd Tag
+Name[da]=Mærkelæser
+Name[de]=Meta-Info-Leser
+Name[el]=Αναγνώστης ετικετών
+Name[eo]=Indiklegilo
+Name[es]=Lector de etiquetas
+Name[et]=Tagide lugeja
+Name[eu]=Etiketa irakurlea
+Name[fa]=خوانندۀ برچسب
+Name[fi]=Tagilukija
+Name[fr]=Lecteur de balise
+Name[ga]=Léitheoir Clibe
+Name[gl]=Lector de Etiquetas
+Name[he]=קורא תגיות
+Name[hi]=टैग रीडर
+Name[hr]=Čitač tag-ova
+Name[hu]=Azonosító-olvasó
+Name[is]=Tagabirtir
+Name[it]=Lettore tag
+Name[ja]=タグリーダー
+Name[kk]=Тегтерді оқу
+Name[km]=កម្មវិធី​អាន​ស្លាក
+Name[ko]=태그 리더
+Name[lt]=Etikečių skaityklė
+Name[lv]=Tagu Lasītājs
+Name[mk]=Читач на ознаки
+Name[nb]=Taggleser
+Name[nds]=Beteker-Kieker
+Name[ne]=ट्याग रिडर
+Name[nl]=Tag-lezer
+Name[nn]=Tagglesar
+Name[pa]=ਟੈਗ ਰੀਡਰ
+Name[pl]=Czytnik znaczników
+Name[pt]=Leitor de Marcas
+Name[pt_BR]=Leitor de símbolos
+Name[ro]=Cititor taguri
+Name[ru]=Чтение тегов
+Name[se]=Sárggislohkki
+Name[sk]=Čítačka tagov
+Name[sl]=Bralnik oznak
+Name[sr]=Читач ознака
+Name[sr@Latn]=Čitač oznaka
+Name[sv]=Taggläsare
+Name[ta]=ஒட்டு வாசிப்பாளர்
+Name[tg]=Хонандаи Борчасп
+Name[th]=โปรแกรมอ่านแท็ก
+Name[tr]=İm Okuyucu
+Name[uk]=Читач етикеток
+Name[ven]=Muvhali wa Tag
+Name[zh_CN]=标签读取程序
+Name[zh_HK]=標籤閱讀器
+Name[zh_TW]=標籤閱讀器
+Name[zu]=Umfundi we Tag
+Comment=Support for reading and writing to tags in media files
+Comment[af]=Ondersteun vir lees en om te skryf na etiket in media lêers
+Comment[ar]=دعم قراءة و كتابة الرقع في ملفات الوسائط
+Comment[bg]=Поддръжка на четене и запис на информацията в мултимедийни файловете
+Comment[bs]=Podrška za čitanje i pisanje tagova u multimedijalnim datotekama
+Comment[ca]=Suport per llegir i escriure etiquetes a fitxers multimèdia
+Comment[cs]=Podpora čtení a zápisu tagů v multimediálních souborech
+Comment[cy]=Cynhaliaeth ar gyfer darllen ac ysgrifennu i dagiau mewn ffeiliau cyfryngau
+Comment[da]=Understøttelse af læsning fra og skrivning til mærker i mediefiler
+Comment[de]=Lesen und Schreiben von Meta-Infos (Tags) in Media-Dateien
+Comment[el]=Υποστήριξη για ανάγνωση και εγγραφή στις ετικέτες των αρχείων μέσων
+Comment[eo]=Subteno por legado kaj skribado de indikoj en sonordosieroj
+Comment[es]=Soporte para lectura y escritura de etiquetas en archivos multimedia
+Comment[et]=Multimeediafailide tagide lugemise ja kirjutamise toetus
+Comment[eu]=Euskarri fitxategien etiketak irakurtzeko eta idazteko euskarria
+Comment[fa]=پشتیبانی برای خواندن و نوشتن در برچسبهای پرونده‌های رسانه
+Comment[fi]=Tuki mediatiedostojen tagien lukuun ja kirjoittamiseen
+Comment[fr]=Lecture et écriture des balises ID3 dans les fichiers multimedia
+Comment[gl]=Soporte para a lectura e escritura de etiquetas en ficheiros multimedia
+Comment[he]=תמיכה בקריאה וכתיבה של תגיות בקבצי מדיה
+Comment[hi]=मीडिया फ़ाइलों के टैग पढ़ने तथा लिखने का समर्थन
+Comment[hr]=Podrška za čitanje i pisanje dodatnih informacija (tag-ova) u medijske datoteke
+Comment[hu]=Támogatás médiafájlok azonosítóinak olvasásához és írásához
+Comment[is]=Stuðningur til að lesa og skrifa ID3 tög í MP3 skrám
+Comment[it]=Supporto per la lettura e la scrittura dei tag nei file multimediali
+Comment[ja]=メディアファイル内のタグの読み書きをサポート
+Comment[kk]=Медиа файлдарының тегтерін оқу-жазу құралы
+Comment[km]=ការ​គាំទ្រ​ដើម្បី​អាន និង​សរសេរ​ស្លាក​ក្នុង​ឯកសារ​មេឌៀ
+Comment[ko]=미디어 파일의 태그 읽고 쓰기 지원
+Comment[lt]=Palaiko etikečių skaitymą ir rašymą media bylose
+Comment[lv]=Tagu lasīšanas un rakstīšanas uzturēšana mēdiju failos
+Comment[mk]=Поддршка за читање и запишување на ознаките од мултимедијални датотеки
+Comment[ms]=Sokongan untuk baca dan tulis tag pada fail media
+Comment[nb]=Støtte for lesing og skriving til merkelapper i mediafiler
+Comment[nds]=Ünnerstütten för't Lesen un Schrieven vun Betekers binnen Mediendateien
+Comment[ne]=मिडिया फाइलको ट्यागमा लेख्न र पढ्नका लागि समर्थन
+Comment[nl]=Ondersteuning voor het lezen van en schrijven naar tags in mediabestanden
+Comment[nn]=Støtte for lesing og skriving av taggar i mediefiler
+Comment[pl]=Obsługa odczytu i zapisu znaczników w plikach medialnych
+Comment[pt]=O suporte de leitura/escrita de marcas em ficheiros multimédia
+Comment[pt_BR]=Suporte a leitura e gravação de símbolos em arquivos de mídia
+Comment[ro]=Suport pentru citirea şi scrierea tagurilor în fişiere multimedia
+Comment[ru]=Поддержка чтения и записи тегов в медиафайлах
+Comment[se]=Doarju sárggislohkama ja -čállima mediefiillain
+Comment[sk]=Podpora pre čítanie a zápis do tagov v multimediálnych súboroch
+Comment[sl]=Podpora branju in pisanju oznak za večpredstavnostne datoteke
+Comment[sr]=Подршка за читање и писање ID3 ознака у MP3 фајловима
+Comment[sr@Latn]=Podrška za čitanje i pisanje ID3 oznaka u MP3 fajlovima
+Comment[sv]=Stöd för att läsa och skriva taggar i mediafiler
+Comment[ta]=ஊடகக் கோப்புகளில் குறியொட்டுக்களை எழுத வாசிக்கப்பதற்கு ஆதரவு
+Comment[tg]=Пуштибонии хондан ва навиштани борчаспҳо дар файлҳои расона
+Comment[th]=รองรับการอ่านและเขียนแท็กในแฟ้มสื่อ
+Comment[tr]=Medya dosyalarındaki imleri okumak ve yazmak için destek
+Comment[uk]=Підтримка для читання та запису етикеток в медіафайлах
+Comment[ven]=Thikhedzo ya u vhala na u nwala u itela u tag kha dzifaela dza media
+Comment[zh_CN]=支持对媒体文件的标签进行读取和写入
+Comment[zh_HK]=讀取或寫入媒體檔案標籤的支援
+Comment[zh_TW]=支援讀取或寫入媒體檔案的標籤
+Comment[zu]=Inxaso yokufunda nokubhala amathegi kumafayela ezezindaba