[kde-doc-english] [kwave] /: saveblocks: format strings of second and later invocations of patterns were ignored

Thomas Eschenbacher Thomas.Eschenbacher at gmx.de
Tue Nov 3 19:21:56 UTC 2015


Git commit 2df3998ad91317e19b02ccaa48fe104eaa9bfba0 by Thomas Eschenbacher.
Committed on 03/11/2015 at 18:04.
Pushed by eschenbacher into branch 'master'.

saveblocks: format strings of second and later invocations of patterns were ignored

saveblocks: added pattern to include file info (file meta data)

M  +4    -1    CHANGES
M  +9    -0    doc/en/index.docbook
M  +273  -242  libkwave/FileInfo.cpp
M  +48   -5    libkwave/FileInfo.h
M  +60   -7    plugins/saveblocks/SaveBlocksPlugin.cpp

http://commits.kde.org/kwave/2df3998ad91317e19b02ccaa48fe104eaa9bfba0

diff --git a/CHANGES b/CHANGES
index 8994650..faaa5e5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -10,9 +10,12 @@
  * support for cmake > 3.3, fix for policy CMP0063
  * cmdline option "--nofork" no longer exists
  * bugfix: multiple issues in context of switching the GUI type in scripts
- * saveblocks: fixed issues with special characters in filenames and patterns
+ * bugfix: fixed issues in saveblocks saveblocks with special characters in
+   filenames and patterns, format strings of second and later invocations
+   of patterns were ignored
  * saveblocks: allow path separators in filename patterns to make it possible
    to create subdirectories
+ * saveblocks: added pattern to include file info (file meta data)
 
 0.9.0 [2015-05-25]
 
diff --git a/doc/en/index.docbook b/doc/en/index.docbook
index 2169727..07e1746 100644
--- a/doc/en/index.docbook
+++ b/doc/en/index.docbook
@@ -6986,6 +6986,15 @@
 						    without path and without extension.
 						</entry>
 					    </row>
+					    <row>
+						<entry>&no-i18n-tag;<command>[%fileinfo{<replaceable>keyword</replaceable>}]</command></entry>
+						<entry>
+						    Will be replaced with the content of a file information
+						    identified by <replaceable>keyword</replaceable>.
+						    See section <link linkend="file-info-list" endterm="file-info-list-title"/>
+						    for a list of all available keywords.
+						</entry>
+					    </row>
 					</tbody>
 				    </tgroup>
 				</informaltable>
diff --git a/libkwave/FileInfo.cpp b/libkwave/FileInfo.cpp
index 928c303..55fc747 100644
--- a/libkwave/FileInfo.cpp
+++ b/libkwave/FileInfo.cpp
@@ -22,240 +22,285 @@
 #include "libkwave/MetaDataList.h"
 #include "libkwave/String.h"
 
-/** FileInfo flag: for internal usage only, do not show to the user */
-#define FP_INTERNAL     0x0001
-
-/** FileInfo flag: readonly, cannot be modified by the user */
-#define FP_READONLY     0x0002
-
-/** FileInfo flag: available for the GUI, but not for loading/saving */
-#define FP_NO_LOAD_SAVE 0x0004
-
 /** prefix of all property names */
 #define FILE_INFO_PROPERTY_PREFIX _("FILE_INFO: ")
 
 /***************************************************************************/
 void Kwave::FileInfo::PropertyTypesMap::fill()
 {
-    append(Kwave::INF_UNKNOWN, FP_INTERNAL | FP_NO_LOAD_SAVE,
-           QString(), QString());
-
-    append(Kwave::INF_ALBUM, 0,
-        _(I18N_NOOP("Album")),
-        _(I18N_NOOP("Name of the album if the source is an album\n"
-             "that consist of more medias.")));
-    append(Kwave::INF_ANNOTATION, 0,
-        _(I18N_NOOP("Annotation")),
-        _(I18N_NOOP(
-             "Provides general comments about the file or the subject of\n"
-             "the file. If the comment is several sentences long, end\n"
-             "each sentence with a period. Do not include newline\n"
-             "characters!")));
-    append(Kwave::INF_ARCHIVAL, 0,
-        _(I18N_NOOP("Archival location")),
-        _(I18N_NOOP("Indicates where the subject of the file is archived.")));
-    append(Kwave::INF_AUTHOR, 0,
-        _(I18N_NOOP("Author")),
-        _(I18N_NOOP("Identifies the name of the author of the original\n"
-             "subject of the file."
-             "\nExample: 'van Beethoven, Ludwig'")));
-    append(Kwave::INF_BITRATE_LOWER, FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Lower Bitrate")),
-        _(I18N_NOOP("Specifies the lower limit in a VBR bitstream.")));
-    append(Kwave::INF_BITRATE_MODE, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Bitrate Mode")),
-        _(I18N_NOOP("Bitrate Mode (ABR, VBR, CBR, etc...)")));
-    append(Kwave::INF_BITRATE_NOMINAL, FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Bitrate")),
-        _(I18N_NOOP(
-             "Nominal bitrate of the audio stream in bits per second")));
-    append(Kwave::INF_BITRATE_UPPER, FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Upper Bitrate")),
-        _(I18N_NOOP("Specifies the upper limit in a VBR bitstream.")));
-    append(Kwave::INF_BITS_PER_SAMPLE, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Bits per Sample")),
-        _(I18N_NOOP("Specifies the number of bits per sample.")));
-    append(Kwave::INF_CD, 0,
-        _(I18N_NOOP("CD")),
-        _(I18N_NOOP(
-             "Number of the CD, if the source is an album of more CDROMs")));
-    append(Kwave::INF_CDS, 0,
-        _(I18N_NOOP("CDS")),
-        _(I18N_NOOP(
-             "Number of CDs, if the source is an album of more CDROMs")));
-    append(Kwave::INF_COMMISSIONED, 0,
-        _(I18N_NOOP("Commissioned")),
-        _(I18N_NOOP("Lists the name of the person or organization\n"
-             "that commissioned the subject of the file.")));
-    append(Kwave::INF_COMMENTS, 0,
-        _(I18N_NOOP("Comments")),
-        _(I18N_NOOP(
-             "Provides general comments about the file or the subject of\n"
-             "the file. If the comment is several sentences long, end\n"
-             "each sentence with a period. Do not include newline\n"
-             "characters!")));
-    append(Kwave::INF_COMPRESSION, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Compression")),
-        _(I18N_NOOP("Sets a mode for compressing the audio\n"
-             "data to reduce disk space.")));
-    append(Kwave::INF_CONTACT, 0,
-        _(I18N_NOOP("Contact")),
-        _(I18N_NOOP("Contact information for the creators or distributors of\n"
-             "the track. This could be a URL, an email address, the\n"
-             "physical address of the producing label.")));
-    append(Kwave::INF_COPYRIGHT, 0,
-        _(I18N_NOOP("Copyright")),
-        _(I18N_NOOP("Records the copyright information for the file. "
-	     "If there are\n"
-	     "multiple copyrights, separate them by a semicolon followed\n"
-             "by a space.\n"
-             "Example: 'Copyright Linux community 2002'")));
-    append(Kwave::INF_COPYRIGHTED, 0,
-        _(I18N_NOOP("Copyrighted")),
-        _(I18N_NOOP("Indicates whether the file is protected by "
-                  "copyright or not.")));
-    append(Kwave::INF_CREATION_DATE, 0,
-        _(I18N_NOOP("Date")),
-        _(I18N_NOOP("Specifies the date the subject of the file was created.\n"
-             "Example: '2001-12-24'")));
-    append(Kwave::INF_ENGINEER, 0,
-        _(I18N_NOOP("Engineer")),
-        _(I18N_NOOP("Shows the name of the engineer who worked on the file.\n"
-             "If there are multiple engineers, separate the names by\n"
-             "a semicolon and a blank.")));
-    append(Kwave::INF_ESTIMATED_LENGTH, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Estimated Length")),
-        _(I18N_NOOP("Estimated length of the file in samples")));
-    append(Kwave::INF_FILENAME, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Filename")),
-        _(I18N_NOOP("Name of the opened file")));
-    append(Kwave::INF_FILESIZE, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("File Size")),
-        _(I18N_NOOP("Size of the file in bytes")));
-    append(Kwave::INF_GENRE, 0,
-        _(I18N_NOOP("Genre")),
-        _(I18N_NOOP("Describes the genre or style of the original work.\n"
-             "Examples: 'classic', 'pop'")));
-    append(Kwave::INF_ISRC, FP_READONLY,
-        _(I18N_NOOP("ISRC")),
-        _(I18N_NOOP("ISRC number for the track; see the ISRC intro page\n"
-             "for more information on ISRC numbers.\n"
-             "http://www.ifpi.org/site-content/online/isrc_intro.html")));
-    append(Kwave::INF_KEYWORDS, 0,
-        _(I18N_NOOP("Keywords")),
-        _(I18N_NOOP("Provides a list of keywords that refer to the\n"
-             "file or subject of the file.")));
-    append(Kwave::INF_LABELS, FP_INTERNAL,
-        _(I18N_NOOP("Labels")),
-        _(I18N_NOOP("The list of labels/markers.")));
-    append(Kwave::INF_LENGTH, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Length")),
-        _(I18N_NOOP("Length of the file in samples.")));
-    append(Kwave::INF_LICENSE, 0,
-        _(I18N_NOOP("License")),
-        _(I18N_NOOP("License information, e.g., 'All Rights Reserved',\n"
-             "'Any Use Permitted', an URL to a license or the\n"
-             "EFF Open Audio License ('distributed under the\n"
-             "terms of the Open Audio License.\n"
-             "See http://www.eff.org/IP/Open_licenses/eff_oal.html\n"
-             "for details'), etc.")));
-    append(Kwave::INF_MEDIUM, 0,
-        _(I18N_NOOP("Medium")),
-        _(I18N_NOOP("Describes the original subject of the file,\n"
-             "where it was first recorded.\n"
-             "Example: 'orchestra'")));
-    append(Kwave::INF_MIMETYPE, FP_READONLY | FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Mime Type")),
-        _(I18N_NOOP("Mime type of the file format")));
-    append(Kwave::INF_MPEG_EMPHASIS, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Emphasis")),
-        _(I18N_NOOP("Audio emphasis mode")));
-    append(Kwave::INF_MPEG_LAYER, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Layer")),
-        _(I18N_NOOP("MPEG Layer, I, II or III")));
-    append(Kwave::INF_MPEG_MODEEXT, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Mode Extension")),
-        _(I18N_NOOP("MPEG Mode Extension (only if Joint Stereo)")));
-    append(Kwave::INF_MPEG_VERSION, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Version")),
-        _(I18N_NOOP("MPEG Version, 1, 2 or 2.5")));
-    append(Kwave::INF_NAME, 0,
-        _(I18N_NOOP("Name")),
-        _(I18N_NOOP("Stores the title of the subject of the file.\n"
-             "Example: \"Symphony No.6, Op.68 'Pastoral'\"")));
-    append(Kwave::INF_OPUS_FRAME_LEN, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Opus Frame Length")),
-        _(I18N_NOOP("Opus Frame Length in ms (supported values are "
-                    "2.5, 5, 10, 20, 40, or 60 ms)")));
-    append(Kwave::INF_ORGANIZATION, 0,
-        _(I18N_NOOP("Organization")),
-        _(I18N_NOOP("Name of the organization producing the track\n"
-             "(i.e. the 'record label')")));
-    append(Kwave::INF_ORIGINAL, FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Original")),
-        _(I18N_NOOP("Indicates whether the file is an original or a copy")));
-    append(Kwave::INF_PERFORMER, 0,
-        _(I18N_NOOP("Performer")),
-        _(I18N_NOOP("The artist(s) who performed the work. In classical\n"
-             "music this would be the conductor, orchestra, soloists.\n"
-             "In an audio book it would be the actor who did the reading.")));
-    append(Kwave::INF_PRIVATE, 0,
-        _(I18N_NOOP("Private")),
-        _(I18N_NOOP("Indicates whether the subject is private")));
-    append(Kwave::INF_PRODUCT, 0,
-        _(I18N_NOOP("Product")),
-        _(I18N_NOOP("Specifies the name or the title the\n"
-             "file was originally intended for.\n"
-             "Example: 'Linux audio collection'")));
-    append(Kwave::INF_SAMPLE_FORMAT, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Sample Format")),
-        _(I18N_NOOP("Format used for storing the digitized audio samples.\n"
-             "Example: '32-bit IEEE floating-point'")));
-    append(Kwave::INF_SAMPLE_RATE, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Sample Rate")),
-        _(I18N_NOOP("Number of samples per second\n")));
-    append(Kwave::INF_SOFTWARE, 0,
-        _(I18N_NOOP("Software")),
-        _(I18N_NOOP("Identifies the name of the software package\n"
-             "used to create the file.\n"
-             "Example: 'Kwave v0.6.4-1'")));
-    append(Kwave::INF_SOURCE, 0,
-        _(I18N_NOOP("Source")),
-        _(I18N_NOOP("Identifies the name of the person or organization\n"
-             "who supplied the original subject of the file.\n"
-             "Example: 'Chaotic Sound Research'")));
-    append(Kwave::INF_SOURCE_FORM, 0,
-        _(I18N_NOOP("Source form")),
-        _(I18N_NOOP("Identifies the original form of\n"
-             "the material that was digitized.\n"
-             "Examples: 'Record/Vinyl/90RPM', 'Audio DAT', "
-             "'tape/CrO2/60min'")));
-    append(Kwave::INF_SUBJECT, 0,
-        _(I18N_NOOP("Subject")),
-        _(I18N_NOOP("Describes the subject of the file.\n"
-             "Example: 'Bird voices at early morning'")));
-    append(Kwave::INF_TECHNICAN, 0,
-        _(I18N_NOOP("Technician")),
-        _(I18N_NOOP(
-             "Identifies the technician who digitized the subject file.\n"
-             "Example: 'Torvalds, Linus'")));
-    append(Kwave::INF_TRACK, 0,
-        _(I18N_NOOP("Track")),
-        _(I18N_NOOP("Track of the CD if the source was a CDROM.")));
-    append(Kwave::INF_TRACKS, 0,
-        _(I18N_NOOP("Tracks")),
-        _(I18N_NOOP("Number of tracks of the CD if the source was a CDROM.")));
-    append(Kwave::INF_CHANNELS, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Channels")),
-        _(I18N_NOOP("Specifies the number of channels of the signal.")));
-    append(Kwave::INF_VBR_QUALITY, FP_INTERNAL | FP_NO_LOAD_SAVE,
-        _(I18N_NOOP("Base Quality")),
-        _(I18N_NOOP("Base quality of the compression in VBR mode")));
-    append(Kwave::INF_VERSION, 0,
-        _(I18N_NOOP("Version")),
-        _(I18N_NOOP("May be used to differentiate multiple versions\n"
-             "of the same track title in a single collection.\n"
-             "(e.g. remix info)")));
+    append(Kwave::INF_UNKNOWN,
+	FP_INTERNAL | FP_NO_LOAD_SAVE,
+	QString(), QString());
+
+    append(Kwave::INF_ALBUM,
+	FP_NONE,
+	_(I18N_NOOP("Album")),
+	_(I18N_NOOP("Name of the album if the source is an album\n"
+	    "that consist of more medias.")));
+    append(Kwave::INF_ANNOTATION,
+	FP_NONE,
+	_(I18N_NOOP("Annotation")),
+	_(I18N_NOOP(
+	    "Provides general comments about the file or the subject of\n"
+	    "the file. If the comment is several sentences long, end\n"
+	    "each sentence with a period. Do not include newline\n"
+	    "characters!")));
+    append(Kwave::INF_ARCHIVAL,
+	FP_NONE,
+	_(I18N_NOOP("Archival location")),
+	_(I18N_NOOP("Indicates where the subject of the file is archived.")));
+    append(Kwave::INF_AUTHOR,
+	FP_NONE,
+	_(I18N_NOOP("Author")),
+	_(I18N_NOOP("Identifies the name of the author of the original\n"
+	    "subject of the file."
+	    "\nExample: 'van Beethoven, Ludwig'")));
+    append(Kwave::INF_BITRATE_LOWER,
+	FP_NO_LOAD_SAVE | FP_FORMAT_NUMERIC,
+	_(I18N_NOOP("Lower Bitrate")),
+	_(I18N_NOOP("Specifies the lower limit in a VBR bitstream.")));
+    append(Kwave::INF_BITRATE_MODE,
+	FP_INTERNAL | FP_NO_LOAD_SAVE | FP_FORMAT_NUMERIC,
+	_(I18N_NOOP("Bitrate Mode")),
+	_(I18N_NOOP("Bitrate Mode (ABR, VBR, CBR, etc...)")));
+    append(Kwave::INF_BITRATE_NOMINAL,
+	FP_NO_LOAD_SAVE | FP_FORMAT_NUMERIC,
+	_(I18N_NOOP("Bitrate")),
+	_(I18N_NOOP(
+	    "Nominal bitrate of the audio stream in bits per second")));
+    append(Kwave::INF_BITRATE_UPPER,
+	FP_NO_LOAD_SAVE | FP_FORMAT_NUMERIC,
+	_(I18N_NOOP("Upper Bitrate")),
+	_(I18N_NOOP("Specifies the upper limit in a VBR bitstream.")));
+    append(Kwave::INF_BITS_PER_SAMPLE,
+	FP_INTERNAL | FP_NO_LOAD_SAVE | FP_FORMAT_NUMERIC,
+	_(I18N_NOOP("Bits per Sample")),
+	_(I18N_NOOP("Specifies the number of bits per sample.")));
+    append(Kwave::INF_CD,
+	FP_FORMAT_NUMERIC,
+	_(I18N_NOOP("CD")),
+	_(I18N_NOOP(
+	    "Number of the CD, if the source is an album of more CDROMs")));
+    append(Kwave::INF_CDS,
+	FP_FORMAT_NUMERIC,
+	_(I18N_NOOP("CDS")),
+	_(I18N_NOOP(
+	    "Number of CDs, if the source is an album of more CDROMs")));
+    append(Kwave::INF_COMMISSIONED,
+	FP_NONE,
+	_(I18N_NOOP("Commissioned")),
+	_(I18N_NOOP("Lists the name of the person or organization\n"
+	    "that commissioned the subject of the file.")));
+    append(Kwave::INF_COMMENTS,
+	FP_NONE,
+	_(I18N_NOOP("Comments")),
+	_(I18N_NOOP(
+	    "Provides general comments about the file or the subject of\n"
+	    "the file. If the comment is several sentences long, end\n"
+	    "each sentence with a period. Do not include newline\n"
+	    "characters!")));
+    append(Kwave::INF_COMPRESSION,
+	FP_INTERNAL | FP_NO_LOAD_SAVE,
+	_(I18N_NOOP("Compression")),
+	_(I18N_NOOP("Sets a mode for compressing the audio\n"
+	    "data to reduce disk space.")));
+    append(Kwave::INF_CONTACT,
+	FP_NONE,
+	_(I18N_NOOP("Contact")),
+	_(I18N_NOOP("Contact information for the creators or distributors of\n"
+	    "the track. This could be a URL, an email address, the\n"
+	    "physical address of the producing label.")));
+    append(Kwave::INF_COPYRIGHT,
+	FP_NONE,
+	_(I18N_NOOP("Copyright")),
+	_(I18N_NOOP("Records the copyright information for the file. "
+	    "If there are\n"
+	    "multiple copyrights, separate them by a semicolon followed\n"
+	    "by a space.\n"
+	    "Example: 'Copyright Linux community 2002'")));
+    append(Kwave::INF_COPYRIGHTED,
+	FP_NONE,
+	_(I18N_NOOP("Copyrighted")),
+	_(I18N_NOOP("Indicates whether the file is protected by "
+		"copyright or not.")));
+    append(Kwave::INF_CREATION_DATE,
+	FP_NONE,
+	_(I18N_NOOP("Date")),
+	_(I18N_NOOP("Specifies the date the subject of the file was created.\n"
+	    "Example: '2001-12-24'")));
+    append(Kwave::INF_ENGINEER,
+	FP_NONE,
+	_(I18N_NOOP("Engineer")),
+	_(I18N_NOOP("Shows the name of the engineer who worked on the file.\n"
+	    "If there are multiple engineers, separate the names by\n"
+	    "a semicolon and a blank.")));
+    append(Kwave::INF_ESTIMATED_LENGTH,
+	FP_INTERNAL | FP_NO_LOAD_SAVE | FP_FORMAT_NUMERIC,
+	_(I18N_NOOP("Estimated Length")),
+	_(I18N_NOOP("Estimated length of the file in samples")));
+    append(Kwave::INF_FILENAME,
+	FP_INTERNAL | FP_NO_LOAD_SAVE,
+	_(I18N_NOOP("Filename")),
+	_(I18N_NOOP("Name of the opened file")));
+    append(Kwave::INF_FILESIZE,
+	FP_INTERNAL | FP_NO_LOAD_SAVE | FP_FORMAT_NUMERIC,
+	_(I18N_NOOP("File Size")),
+	_(I18N_NOOP("Size of the file in bytes")));
+    append(Kwave::INF_GENRE,
+	FP_NONE,
+	_(I18N_NOOP("Genre")),
+	_(I18N_NOOP("Describes the genre or style of the original work.\n"
+	    "Examples: 'classic', 'pop'")));
+    append(Kwave::INF_ISRC,
+	FP_READONLY,
+	_(I18N_NOOP("ISRC")),
+	_(I18N_NOOP("ISRC number for the track; see the ISRC intro page\n"
+	    "for more information on ISRC numbers.\n"
+	    "http://www.ifpi.org/site-content/online/isrc_intro.html")));
+    append(Kwave::INF_KEYWORDS,
+	FP_NONE,
+	_(I18N_NOOP("Keywords")),
+	_(I18N_NOOP("Provides a list of keywords that refer to the\n"
+	    "file or subject of the file.")));
+    append(Kwave::INF_LABELS,
+	FP_INTERNAL,
+	_(I18N_NOOP("Labels")),
+	_(I18N_NOOP("The list of labels/markers.")));
+    append(Kwave::INF_LENGTH,
+	FP_INTERNAL | FP_NO_LOAD_SAVE | FP_FORMAT_NUMERIC,
+	_(I18N_NOOP("Length")),
+	_(I18N_NOOP("Length of the file in samples.")));
+    append(Kwave::INF_LICENSE,
+	FP_NONE,
+	_(I18N_NOOP("License")),
+	_(I18N_NOOP("License information, e.g., 'All Rights Reserved',\n"
+	    "'Any Use Permitted', an URL to a license or the\n"
+	    "EFF Open Audio License ('distributed under the\n"
+	    "terms of the Open Audio License.\n"
+	    "See http://www.eff.org/IP/Open_licenses/eff_oal.html\n"
+	    "for details'), etc.")));
+    append(Kwave::INF_MEDIUM,
+	FP_NONE,
+	_(I18N_NOOP("Medium")),
+	_(I18N_NOOP("Describes the original subject of the file,\n"
+	    "where it was first recorded.\n"
+	    "Example: 'orchestra'")));
+    append(Kwave::INF_MIMETYPE,
+	FP_READONLY | FP_INTERNAL | FP_NO_LOAD_SAVE,
+	_(I18N_NOOP("Mime Type")),
+	_(I18N_NOOP("Mime type of the file format")));
+    append(Kwave::INF_MPEG_EMPHASIS,
+	FP_INTERNAL | FP_NO_LOAD_SAVE,
+	_(I18N_NOOP("Emphasis")),
+	_(I18N_NOOP("Audio emphasis mode")));
+    append(Kwave::INF_MPEG_LAYER,
+	FP_INTERNAL | FP_NO_LOAD_SAVE,
+	_(I18N_NOOP("Layer")),
+	_(I18N_NOOP("MPEG Layer, I, II or III")));
+    append(Kwave::INF_MPEG_MODEEXT,
+	FP_INTERNAL | FP_NO_LOAD_SAVE,
+	_(I18N_NOOP("Mode Extension")),
+	_(I18N_NOOP("MPEG Mode Extension (only if Joint Stereo)")));
+    append(Kwave::INF_MPEG_VERSION,
+	FP_INTERNAL | FP_NO_LOAD_SAVE,
+	_(I18N_NOOP("Version")),
+	_(I18N_NOOP("MPEG Version, 1, 2 or 2.5")));
+    append(Kwave::INF_NAME,
+	FP_NONE,
+	_(I18N_NOOP("Name")),
+	_(I18N_NOOP("Stores the title of the subject of the file.\n"
+	    "Example: \"Symphony No.6, Op.68 'Pastoral'\"")));
+    append(Kwave::INF_OPUS_FRAME_LEN,
+	FP_INTERNAL | FP_NO_LOAD_SAVE | FP_FORMAT_NUMERIC,
+	_(I18N_NOOP("Opus Frame Length")),
+	_(I18N_NOOP("Opus Frame Length in ms (supported values are "
+	            "2.5, 5, 10, 20, 40, or 60 ms)")));
+    append(Kwave::INF_ORGANIZATION,
+	FP_NONE,
+	_(I18N_NOOP("Organization")),
+	_(I18N_NOOP("Name of the organization producing the track\n"
+	    "(i.e. the 'record label')")));
+    append(Kwave::INF_ORIGINAL,
+	FP_NO_LOAD_SAVE,
+	_(I18N_NOOP("Original")),
+	_(I18N_NOOP("Indicates whether the file is an original or a copy")));
+    append(Kwave::INF_PERFORMER,
+	FP_NONE,
+	_(I18N_NOOP("Performer")),
+	_(I18N_NOOP("The artist(s) who performed the work. In classical\n"
+	    "music this would be the conductor, orchestra, soloists.\n"
+	    "In an audio book it would be the actor who did the reading.")));
+    append(Kwave::INF_PRIVATE,
+	FP_NONE,
+	_(I18N_NOOP("Private")),
+	_(I18N_NOOP("Indicates whether the subject is private")));
+    append(Kwave::INF_PRODUCT,
+	FP_NONE,
+	_(I18N_NOOP("Product")),
+	_(I18N_NOOP("Specifies the name or the title the\n"
+	    "file was originally intended for.\n"
+	    "Example: 'Linux audio collection'")));
+    append(Kwave::INF_SAMPLE_FORMAT,
+	FP_INTERNAL | FP_NO_LOAD_SAVE,
+	_(I18N_NOOP("Sample Format")),
+	_(I18N_NOOP("Format used for storing the digitized audio samples.\n"
+	    "Example: '32-bit IEEE floating-point'")));
+    append(Kwave::INF_SAMPLE_RATE,
+	FP_INTERNAL | FP_NO_LOAD_SAVE | FP_FORMAT_NUMERIC,
+	_(I18N_NOOP("Sample Rate")),
+	_(I18N_NOOP("Number of samples per second\n")));
+    append(Kwave::INF_SOFTWARE,
+	FP_NONE,
+	_(I18N_NOOP("Software")),
+	_(I18N_NOOP("Identifies the name of the software package\n"
+	    "used to create the file.\n"
+	    "Example: 'Kwave v0.6.4-1'")));
+    append(Kwave::INF_SOURCE,
+	FP_NONE,
+	_(I18N_NOOP("Source")),
+	_(I18N_NOOP("Identifies the name of the person or organization\n"
+	    "who supplied the original subject of the file.\n"
+	    "Example: 'Chaotic Sound Research'")));
+    append(Kwave::INF_SOURCE_FORM,
+	FP_NONE,
+	_(I18N_NOOP("Source form")),
+	_(I18N_NOOP("Identifies the original form of\n"
+	    "the material that was digitized.\n"
+	    "Examples: 'Record/Vinyl/90RPM', 'Audio DAT', "
+	    "'tape/CrO2/60min'")));
+    append(Kwave::INF_SUBJECT,
+	FP_NONE,
+	_(I18N_NOOP("Subject")),
+	_(I18N_NOOP("Describes the subject of the file.\n"
+	    "Example: 'Bird voices at early morning'")));
+    append(Kwave::INF_TECHNICAN,
+	FP_NONE,
+	_(I18N_NOOP("Technician")),
+	_(I18N_NOOP(
+	    "Identifies the technician who digitized the subject file.\n"
+	    "Example: 'Torvalds, Linus'")));
+    append(Kwave::INF_TRACK,
+	FP_FORMAT_NUMERIC,
+	_(I18N_NOOP("Track")),
+	_(I18N_NOOP("Track of the CD if the source was a CDROM.")));
+    append(Kwave::INF_TRACKS,
+	FP_FORMAT_NUMERIC,
+	_(I18N_NOOP("Tracks")),
+	_(I18N_NOOP("Number of tracks of the CD if the source was a CDROM.")));
+    append(Kwave::INF_CHANNELS,
+	FP_INTERNAL | FP_NO_LOAD_SAVE | FP_FORMAT_NUMERIC,
+	_(I18N_NOOP("Channels")),
+	_(I18N_NOOP("Specifies the number of channels of the signal.")));
+    append(Kwave::INF_VBR_QUALITY,
+	FP_INTERNAL | FP_NO_LOAD_SAVE,
+	_(I18N_NOOP("Base Quality")),
+	_(I18N_NOOP("Base quality of the compression in VBR mode")));
+    append(Kwave::INF_VERSION,
+	FP_NONE,
+	_(I18N_NOOP("Version")),
+	_(I18N_NOOP("May be used to differentiate multiple versions\n"
+	    "of the same track title in a single collection.\n"
+	    "(e.g. remix info)")));
 
     // please do not simply extend here, sort in alphabetically instead...
 
@@ -335,20 +380,6 @@ QVariant Kwave::FileInfo::get(Kwave::FileProperty key) const
 }
 
 /***************************************************************************/
-bool Kwave::FileInfo::isInternal(Kwave::FileProperty key) const
-{
-    int flags = m_property_map.data(key);
-    return (flags & FP_INTERNAL);
-}
-
-/***************************************************************************/
-bool Kwave::FileInfo::canLoadSave(Kwave::FileProperty key) const
-{
-    int flags = m_property_map.data(key);
-    return !(flags & FP_NO_LOAD_SAVE);
-}
-
-/***************************************************************************/
 QList<Kwave::FileProperty> Kwave::FileInfo::allKnownProperties() const
 {
     return m_property_map.all();
diff --git a/libkwave/FileInfo.h b/libkwave/FileInfo.h
index ff3dd70..ac7a499 100644
--- a/libkwave/FileInfo.h
+++ b/libkwave/FileInfo.h
@@ -21,6 +21,7 @@
 #include "config.h"
 
 #include <QtGlobal>
+#include <QFlags>
 #include <QList>
 #include <QMap>
 #include <QString>
@@ -112,6 +113,29 @@ namespace Kwave
     class Q_DECL_EXPORT FileInfo: public Kwave::MetaData
     {
     public:
+	/**
+	 * @enum Flags
+	 * flags additional meta information about file info entries
+	 */
+	typedef enum {
+	    /** no flags */
+	    FP_NONE           = 0,
+
+	    /** for internal usage only, do not show to the user */
+	    FP_INTERNAL       = 1,
+
+	    /** readonly, cannot be modified by the user */
+	    FP_READONLY       = 2,
+
+	    /** available for the GUI, but not for loading/saving */
+	    FP_NO_LOAD_SAVE   = 4,
+
+	    /** represents a numeric value, otherwise handled as a string */
+	    FP_FORMAT_NUMERIC = 8
+
+	} Flag;
+
+	Q_DECLARE_FLAGS(Flags, Flag)
 
 	/** Default constructor, creates an empty file info object */
 	FileInfo();
@@ -176,15 +200,26 @@ namespace Kwave
 	QVariant get(FileProperty key) const;
 
 	/**
+	 * returns the flags of a property (meta data)
+	 */
+	inline Flags flags(FileProperty key) const {
+	    return m_property_map.data(key);
+	}
+
+	/**
 	 * Returns true if a property is only internal.
 	 */
-	bool isInternal(FileProperty key) const;
+	inline bool isInternal(FileProperty key) const {
+	    return (flags(key) & FP_INTERNAL);
+	}
 
 	/**
 	 * Returns true if a property is intended to be saved into or
 	 * loaded from a file.
 	 */
-	bool canLoadSave(FileProperty key) const;
+	inline bool canLoadSave(FileProperty key) const {
+	    return !(flags(key) & FP_NO_LOAD_SAVE);
+	}
 
 	/**
 	 * Returns the name of a property.
@@ -200,6 +235,13 @@ namespace Kwave
 	    return m_property_map.description(key, false);
 	}
 
+	/**
+	 * Returns a file property key from a property name
+	 */
+	inline FileProperty fromName(const QString &name) const {
+	    return m_property_map.findFromName(name);
+	}
+
 	/** Returns a list with all properties */
 	const QMap<FileProperty, QVariant> properties() const;
 
@@ -214,12 +256,12 @@ namespace Kwave
 	/**
 	 * Pre-filled map with property names and descriptions
 	 */
-	class PropertyTypesMap: public Kwave::TypesMap<FileProperty, int>
+	class PropertyTypesMap: public Kwave::TypesMap<FileProperty, Flags>
 	{
 	public:
 	    /** constructor */
 	    explicit PropertyTypesMap()
-		:Kwave::TypesMap<FileProperty, int>()
+		:Kwave::TypesMap<FileProperty, Flags>()
 	    {
 		fill();
 	    }
@@ -235,9 +277,10 @@ namespace Kwave
 	PropertyTypesMap m_property_map;
 
     };
-
 }
 
+Q_DECLARE_OPERATORS_FOR_FLAGS(Kwave::FileInfo::Flags)
+
 #endif /* FILE_INFO_H */
 
 //***************************************************************************
diff --git a/plugins/saveblocks/SaveBlocksPlugin.cpp b/plugins/saveblocks/SaveBlocksPlugin.cpp
index 298896f..2d0453c 100644
--- a/plugins/saveblocks/SaveBlocksPlugin.cpp
+++ b/plugins/saveblocks/SaveBlocksPlugin.cpp
@@ -434,11 +434,14 @@ QString Kwave::SaveBlocksPlugin::createFileName(const QString &base,
     QString nr;
 
     // format the "index" parameter
-    QRegExp rx_nr(_("(\\\\\\[%\\d*nr\\\\\\])"), Qt::CaseInsensitive);
+    QRegExp rx_nr(_("(\\\\\\[%(\\d*)nr\\\\\\])"), Qt::CaseInsensitive);
     while (rx_nr.indexIn(p) >= 0) {
 	QString format = rx_nr.cap(1);
-	format = format.mid(2, format.length() - 6) + _("u");
-	p.replace(rx_nr, nr.sprintf(format.toLatin1(), index));
+	format = format.mid(2, format.length() - 6);
+	QString ex = _("(\\\\\\[") + format + _("nr\\\\\\])");
+	QRegExp rx(ex, Qt::CaseInsensitive);
+	format += _("u");
+	p.replace(rx, nr.sprintf(format.toLatin1(), index));
     }
 
     // format the "count" parameter
@@ -446,8 +449,11 @@ QString Kwave::SaveBlocksPlugin::createFileName(const QString &base,
     while (rx_count.indexIn(p) >= 0) {
 	if (count >= 0) {
 	    QString format = rx_count.cap(1);
-	    format = format.mid(2, format.length() - 9) + _("u");
-	    p.replace(rx_count, nr.sprintf(format.toLatin1(), count));
+	    format = format.mid(2, format.length() - 9);
+	    QString ex = _("(\\\\\\[") + format + _("count\\\\\\])");
+	    QRegExp rx(ex, Qt::CaseInsensitive);
+	    format += _("u");
+	    p.replace(rx, nr.sprintf(format.toLatin1(), count));
 	} else {
 	    p.replace(rx_count, _("(\\d+)"));
 	}
@@ -458,8 +464,11 @@ QString Kwave::SaveBlocksPlugin::createFileName(const QString &base,
     while (rx_total.indexIn(p) >= 0) {
 	if (total >= 0) {
 	    QString format = rx_total.cap(1);
-	    format = format.mid(2, format.length() - 9) + _("u");
-	    p.replace(rx_total, nr.sprintf(format.toLatin1(), total));
+	    format = format.mid(2, format.length() - 9);
+	    QString ex = _("(\\\\\\[") + format + _("total\\\\\\])");
+	    QRegExp rx(ex, Qt::CaseInsensitive);
+	    format += _("u");
+	    p.replace(rx, nr.sprintf(format.toLatin1(), total));
 	} else {
 	    p.replace(rx_total, _("(\\d+)"));
 	}
@@ -471,6 +480,50 @@ QString Kwave::SaveBlocksPlugin::createFileName(const QString &base,
 	p.replace(rx_filename, QRegExp::escape(base));
     }
 
+    // support for file info
+    QRegExp rx_fileinfo(
+	_("\\\\\\[%(\\d*)fileinfo\\\\\\{([A-Z,a-z]+)\\\\\\}\\\\\\]"),
+	Qt::CaseInsensitive
+    );
+    Kwave::FileInfo info(signalManager().metaData());
+    while (rx_fileinfo.indexIn(p) >= 0) {
+	const QString format = rx_fileinfo.cap(1);
+	const QString id     = rx_fileinfo.cap(2);
+	QString value;
+	FileProperty property = info.fromName(id);
+	if (property != Kwave::INF_UNKNOWN) {
+	    QVariant val = info.get(property);
+	    if (!val.isNull()) {
+		// we have a property value
+		value = val.toString();
+
+		// check for format (desired minimum string length)
+		bool ok  = false;
+		int  len = format.toUInt(&ok);
+		if ((len > 0) && ok) {
+		    Kwave::FileInfo::Flags flags = info.flags(property);
+		    if (flags & Kwave::FileInfo::FP_FORMAT_NUMERIC) {
+			// numeric format, pad with leading zeros or spaces
+			QString pad = (format.startsWith(QLatin1Char('0'))) ?
+			    _("0") : _(" ");
+			while (value.length() < len)
+			    value = pad + value;
+		    } else {
+			// string format, pad with trailing spaces
+			while (value.length() < len)
+			    value = value + _(" ");
+		    }
+		}
+		value = Kwave::Parser::escape(value);
+	    }
+	}
+
+	QString ex(_("(\\\\\\[%") + format + _("fileinfo\\\\\\{") + id +
+	           _("\\\\\\}\\\\\\])"));
+	QRegExp rx(ex, Qt::CaseInsensitive);
+	p.replace(rx, value);
+    }
+
     if (ext.length()) p += _(".") + ext;
 
     // sanitize the filename/path, make sure that there are no spaces



More information about the kde-doc-english mailing list