1 | /* This file is part of the KDE libraries |
2 | Copyright (C) 2002,2003 Carsten Pfeiffer <pfeiffer@kde.org> |
3 | |
4 | library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Library General Public |
6 | License as published by the Free Software Foundation, version 2. |
7 | |
8 | This library is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
11 | Library General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU Library General Public License |
14 | along with this library; see the file COPYING.LIB. If not, write to |
15 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
16 | Boston, MA 02110-1301, USA. |
17 | */ |
18 | |
19 | #include "fileprops.h" |
20 | |
21 | #include <iostream> |
22 | |
23 | #include <QtCore/QFile> |
24 | |
25 | #include <kaboutdata.h> |
26 | #include <kapplication.h> |
27 | #include <kcmdlineargs.h> |
28 | #include <kfilemetainfo.h> |
29 | #include <klocale.h> |
30 | #include <kpropertiesdialog.h> |
31 | #include <kdebug.h> |
32 | |
33 | #define KFILEVERSION "0.2" |
34 | #define INDENT "\t" |
35 | |
36 | using namespace std; |
37 | |
38 | static QString beatifyValue( const QString& value ) |
39 | { |
40 | if ( value.isNull() ) |
41 | return QString("(no value for key available)" ); |
42 | else if ( value.isEmpty() ) |
43 | return QString("(empty)" ); |
44 | |
45 | return value; |
46 | } |
47 | |
48 | FileProps::FileProps( const QString& path ) |
49 | : m_dirty( false ) |
50 | { |
51 | m_info = new KFileMetaInfo(path, QString(), KFileMetaInfo::Everything); |
52 | } |
53 | |
54 | FileProps::~FileProps() |
55 | { |
56 | sync(); |
57 | delete m_info; |
58 | } |
59 | |
60 | bool FileProps::sync() |
61 | { |
62 | if ( !m_dirty ) |
63 | return true; |
64 | |
65 | return m_info->applyChanges(); |
66 | } |
67 | |
68 | bool FileProps::isValid() const |
69 | { |
70 | return m_info->isValid(); |
71 | } |
72 | |
73 | QStringList FileProps::supportedKeys() const |
74 | { |
75 | return QStringList(); |
76 | } |
77 | |
78 | QStringList FileProps::availableKeys() const |
79 | { |
80 | return m_info->keys(); |
81 | } |
82 | |
83 | QString FileProps::getValue( const QString& key ) const |
84 | { |
85 | return FileProps::createKeyValue( m_info->item(key) ); |
86 | } |
87 | |
88 | bool FileProps::setValue( const QString& key, const QString &value ) |
89 | { |
90 | bool ok = m_info->item(key).setValue( value ); |
91 | m_dirty |= ok; |
92 | return ok; |
93 | } |
94 | |
95 | QStringList FileProps::allValues() const |
96 | { |
97 | return FileProps::createKeyValueList( m_info->items().values() ); |
98 | } |
99 | |
100 | // static helper: |
101 | // creates strings like |
102 | // "group: translatedKey: value" |
103 | QString FileProps::createKeyValue( const KFileMetaInfoItem& item ) |
104 | { |
105 | static const int MAX_SPACE = 25; |
106 | |
107 | QString result("%1" ); |
108 | result = result.arg(item.name() + ':', -MAX_SPACE ); |
109 | result.append( beatifyValue( item.value().toString() ) ); |
110 | |
111 | return result; |
112 | } |
113 | |
114 | // static |
115 | QStringList FileProps::createKeyValueList( const KFileMetaInfoItemList& items ) |
116 | { |
117 | QStringList result; |
118 | KFileMetaInfoItemList::ConstIterator it = items.begin(); |
119 | |
120 | for ( ; it != items.end(); ++it ) |
121 | result.append( FileProps::createKeyValue( *it ) ); |
122 | |
123 | return result; |
124 | } |
125 | |
126 | /////////////////////////////////////////////////////////////////// |
127 | /////////////////////////////////////////////////////////////////// |
128 | |
129 | |
130 | |
131 | // kfile --mimetype --listsupported --listavailable --listwritable --getValue "key" --setValue "key=value" --allValues --dialog --quiet file [file...] |
132 | // "key" may be a list of keys, separated by commas |
133 | |
134 | // |
135 | // helper functions |
136 | // |
137 | |
138 | // Caller needs to delete the items in the list after use! |
139 | static KFileItemList fileItemList( const KCmdLineArgs *args ) |
140 | { |
141 | KFileItemList items; |
142 | for ( int i = 0; i < args->count(); i++ ) |
143 | items.append( KFileItem( KFileItem::Unknown, |
144 | KFileItem::Unknown, |
145 | args->url( i ) )); |
146 | return items; |
147 | } |
148 | |
149 | static void showPropertiesDialog( const KCmdLineArgs *args ) { |
150 | const KFileItemList items = fileItemList( args ); |
151 | KPropertiesDialog::showDialog( items, 0, true ); |
152 | } |
153 | /* |
154 | static void printMimeTypes( const KCmdLineArgs *args ) |
155 | { |
156 | for ( int i = 0; i < args->count(); i++ ) |
157 | { |
158 | KUrl url = args->url( i ); |
159 | KMimeType::Ptr mt = KMimeType::findByUrl( url ); |
160 | kDebug() << args->arg(i) << ": " << mt->comment().toLocal8Bit() << " (" |
161 | << mt->name().toLocal8Bit() << ")" << endl; |
162 | } |
163 | }*/ |
164 | |
165 | static void printList( const QStringList& list ) |
166 | { |
167 | QStringList::ConstIterator it = list.begin(); |
168 | for ( ; it != list.end(); ++it ) |
169 | kDebug() << (*it).toLocal8Bit(); |
170 | kDebug(); |
171 | } |
172 | |
173 | static void processMetaDataOptions( const QList<FileProps *> propList, |
174 | KCmdLineArgs *args ) |
175 | { |
176 | // kfile --mimetype --listsupported --listavailable --listwritable --getValue "key" --setValue "key=value" --allValues --dialog --quiet file [file...] |
177 | // "key" may be a list of keys, separated by commas |
178 | |
179 | QString line("-- -------------------------------------------------------" ); |
180 | foreach ( FileProps *props, propList ) |
181 | { |
182 | QString file = props->fileName() + ' '; |
183 | QString fileString = line; |
184 | fileString.replace( 3, file.length(), file ); |
185 | kDebug() << QFile::encodeName( fileString ); |
186 | |
187 | if ( args->isSet( "listsupported" ) ) |
188 | { |
189 | kDebug() << "=Supported Keys=" ; |
190 | printList( props->supportedKeys() ); |
191 | } |
192 | if ( args->isSet( "listavailable" ) ) |
193 | { |
194 | kDebug() << "=Available Keys=" ; |
195 | printList( props->availableKeys() ); |
196 | } |
197 | // if ( args->isSet( "listwritable" ) ) |
198 | // { |
199 | // kDebug() << "TODO :)"; |
200 | // } |
201 | if ( args->isSet( "getValue" ) ) |
202 | { |
203 | kDebug() << "=Value=" ; |
204 | QString key = args->getOption("getValue" ); |
205 | kDebug() << props->getValue( key ).toLocal8Bit(); |
206 | } |
207 | |
208 | if ( args->isSet( "setValue" ) ) |
209 | { |
210 | // separate key and value from the line "key=value" |
211 | QString cmd = args->getOption("setValue" ); |
212 | QString key = cmd.section( '=', 0, 0 ); |
213 | QString value = cmd.section( '=', 1 ); |
214 | |
215 | props->setValue(key, value); |
216 | } |
217 | |
218 | if ( args->isSet( "allValues" ) ) |
219 | { |
220 | kDebug() << "=All Values=" ; |
221 | printList( props->allValues() ); |
222 | } |
223 | } |
224 | |
225 | } |
226 | |
227 | int main( int argc, char **argv ) |
228 | { |
229 | KAboutData about( |
230 | "kfile" , 0, ki18n( "kfile" ), KFILEVERSION, |
231 | ki18n("A command-line tool to read and modify metadata of files." ), |
232 | KAboutData::License_LGPL, ki18n("(c) 2002, Carsten Pfeiffer" ), |
233 | ki18n(0 /*text*/), "http://devel-home.kde.org/~pfeiffer/" , |
234 | "pfeiffer@kde.org" ); |
235 | |
236 | about.addAuthor( ki18n("Carsten Pfeiffer" ), KLocalizedString(), "pfeiffer@kde.org" , |
237 | "http://devel-home.kde.org/~pfeiffer/" ); |
238 | |
239 | KCmdLineArgs::init( argc, argv, &about ); |
240 | |
241 | |
242 | KCmdLineOptions options; |
243 | |
244 | options.add("m" ); // short option for --mimetype |
245 | options.add("nomimetype" , ki18n("Do not print the mimetype of the given file(s)" )); |
246 | options.add("ls" ); // short option for --listsupported |
247 | options.add("listsupported" , ki18n("List all supported metadata keys." )); |
248 | options.add("la" ); // short option for --listavailable |
249 | options.add("listavailable" , ki18n("List all metadata keys which have a value in the given " |
250 | "file(s)." )); |
251 | options.add("q" ); // short option for --quiet |
252 | options.add("quiet" , ki18n("Do not print a warning when more than one file was given " |
253 | "and they do not all have the same mimetype." )); |
254 | options.add("av" ); // short option for --allValues |
255 | options.add("allValues" , ki18n("Prints all metadata values, available in the given " |
256 | "file(s)." )); |
257 | options.add("dialog" , ki18n("Opens a KDE properties dialog to allow viewing and " |
258 | "modifying of metadata of the given file(s)" )); |
259 | options.add("getValue <key>" , ki18n("Prints the value for 'key' of the given file(s). 'key' " |
260 | "may also be a comma-separated list of keys" )); |
261 | options.add("setValue <key=value>" , ki18n("Attempts to set the value 'value' for the metadata key " |
262 | "'key' for the given file(s)" )); |
263 | options.add("+[files]" , ki18n("The file (or a number of files) to operate on." )); |
264 | KCmdLineArgs::addCmdLineOptions( options ); |
265 | |
266 | KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); |
267 | bool useGUI = args->isSet( "dialog" ); |
268 | |
269 | KApplication app( useGUI ); |
270 | |
271 | QList<FileProps *> m_props; |
272 | |
273 | bool quiet = args->isSet( "quiet" ); |
274 | |
275 | int files = args->count(); |
276 | if ( files == 0 ) { |
277 | KCmdLineArgs::usageError( i18n("No files specified" ) ); // exit()s |
278 | } |
279 | |
280 | if ( args->isSet( "dialog" ) ) { |
281 | showPropertiesDialog( args ); |
282 | return 0; |
283 | } |
284 | |
285 | QString mimeType; |
286 | |
287 | for ( int i = 0; i < files; i++ ) { |
288 | //if ( args->isSet( "mimetype" ) ) |
289 | //printMimeTypes( args ); |
290 | |
291 | FileProps *props = new FileProps( args->url(i).path()); |
292 | if ( props->isValid() ) { |
293 | m_props.append( props ); |
294 | } else { |
295 | if ( !quiet ) { |
296 | kWarning() << args->arg(i) << ": " << |
297 | i18n("Cannot determine metadata" ).toLocal8Bit() << endl; |
298 | } |
299 | delete props; |
300 | } |
301 | } |
302 | |
303 | |
304 | processMetaDataOptions( m_props, args ); |
305 | |
306 | qDeleteAll(m_props); // force destruction/sync of props |
307 | |
308 | return 0; |
309 | } |
310 | |