diff options
Diffstat (limited to 'noatun/modules/metatag')
-rw-r--r-- | noatun/modules/metatag/HANDLED_ITEMS | 21 | ||||
-rw-r--r-- | noatun/modules/metatag/Makefile.am | 15 | ||||
-rw-r--r-- | noatun/modules/metatag/edit.cpp | 312 | ||||
-rw-r--r-- | noatun/modules/metatag/edit.h | 55 | ||||
-rw-r--r-- | noatun/modules/metatag/metatag.cpp | 124 | ||||
-rw-r--r-- | noatun/modules/metatag/metatag.h | 30 | ||||
-rw-r--r-- | noatun/modules/metatag/metatag.plugin | 125 |
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 |