summaryrefslogtreecommitdiffstats
path: root/kio/kio/kfilemetainfo.h
blob: 0bc97df706b884f38662324be743acbb290d7d96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
/*
 *  This file is part of the KDE libraries
 *  Copyright (C) 2001-2002 Rolf Magnus <ramagnus@kde.org>
 *  Copyright (C) 2001-2002 Carsten Pfeiffer <pfeiffer@kde.org>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation version 2.0.
 *
 *  This library 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
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this library; see the file COPYING.LIB.  If not, write to
 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301, USA.
 */
#ifndef KILEMETAINFO_H
#define KILEMETAINFO_H

/* Hack for HPUX: Namespace pollution
   m_unit is a define in <sys/sysmacros.h> */
#define m_unit outouftheway_m_unit

#include <tqdict.h>
#include <tqvariant.h>
#include <tqobject.h>
#include <tqstring.h>
#include <kurl.h>

#undef m_unit

class QValidator;
class KFilePlugin;
class KFileMetaInfoGroup;

/**
 * @brief Represents the capabilities of a KFilePlugin for a given mimetype
 *
 * This class provides information about the capabilities that a
 * KFilePlugin for a given mimetype has. It includes a list of metainfo
 * groups and items together with their type, a prefix, suffix and some other
 * information about how to use, display or edit the items.
 *
 * @author Rolf Magnus
 * @author Carsten Pfeiffer
 */
class KIO_EXPORT KFileMimeTypeInfo
{
    // the plugin needs to be a friend because it puts the data into the object,
    // and it should be the only one allowed to do this.
    friend class KFilePlugin;
    friend class KFileMetaInfoProvider;

public:
    KFileMimeTypeInfo() {}

    /**
     * This enum is used to specify some attributes that an item can have,
     * which fit neither in the Hint nor in the Unit enum.
     */
    enum Attributes
    {
        Addable     =  1, ///< The item or group can be added by a user
        Removable   =  2, ///< It can be removed
        Modifiable  =  4, ///< The value can be edited (no meaning for a group)
        Cumulative =  8,  /**< If an application wants to display information
                               for more than one file, it may add up the values
                               for this item (e.g. play time of an mp3 file) */
        Cummulative = Cumulative, ///< @deprecated Use Cumulative instead
        Averaged    = 16, /**< Similar to Cumulative, but the average should
                               be calculated instead of the sum */
        MultiLine   = 32, /**< This attribute says that a string item is likely
                               to be more than one line long, so for editing, a
                               widget capable for multline text should be used
                               @since 3.1 */
        SqueezeText = 64  /**< If the text for this item is very long, it
                               should be squeezed to the size of the widget
                               where it's displayed
                               @since 3.1 */
    };

    /**
     * This enum is mainly for items that have a special meaning for some
     * applications.
     */
    enum Hint {
        NoHint      = 0, ///< No hint
        Name        = 1, ///< The name or title of the document
        Author      = 2, ///< The one who created the contents of it
        Description = 3, ///< Description Some information about the document
        Width       = 4, ///< The width in pixels
        Height      = 5, ///< The height in pixels
        Size        = 6, ///< The size in pixels (width and height)
        Bitrate     = 7, ///< For media files
        Length      = 8, ///< The length of the file, also for media files
        Hidden      = 9, ///< The item is usually not shown to the user
        Thumbnail   = 10 ///< The item is a thumbnail picture of the file

    };

    /**
     * This enum exists so that you can specify units for items, which you
     * can usually use for integer items, so an application knows how to
     * display it (e.g. a time in seconds in a hh:mm:ss form). You can either
     * use one of those units, or if you don't find one that fits, you can
     * add it yourself using a prefix and/or suffix.
     */
    enum Unit {
        NoUnit          = 0,  ///< None of the listed units
        Seconds         = 1,  ///< The item represents a time in seconds
        MilliSeconds    = 2,  ///< The item represents a time in milliseconds
        BitsPerSecond   = 3,  ///< A bit rate
        Pixels          = 4,  ///< For image dimensions and similar
        Inches          = 5,  ///< Sizes
        Centimeters     = 6,  ///< Sizes
        Bytes           = 7,  ///< Some data/file size in bytes
        FramesPerSecond = 8,  ///< A frame rate @since 3.1
        DotsPerInch     = 9,  ///< Resolution in DPI @since 3.1
        BitsPerPixel    = 10, ///< A bit depth @since 3.1
        Hertz           = 11, ///< Sample rates and similar @since 3.1
        KiloBytes       = 12, ///< Some data/file size in kilobytes @since 3.1
        Millimeters     = 13  ///< Sizes @since 3.3
    };


    class ItemInfo;

    /**
     *  @brief Information about a meta information group
     *
     *  This is the class for one group of items of a KFileMimeTypeInfo.
     *  It contains, among other things, the information about the group's name
     *  and a list of supported items.
     */
    class KIO_EXPORT GroupInfo
    {

    friend class KFilePlugin;
    friend class KFileMimeTypeInfo;
    public:
        /**
         * Use this method to get a list of keys in the specified group that
         * the plugin knows about. No variable keys.
         * For a group that doesn't support variable keys, all keys that this
         * group may have are returned. For a group that does support them, the
         * non-variable ones are returned. See KFileMetaInfo about variable
         * keys
         *
         * @return the list of keys supported for this mimetype
         **/
        TQStringList supportedKeys() const
        {
            return m_supportedKeys;
        }

        /**
         * Use this method to get the name of the group. This string  doesn't
         * depend on the user's locale settings
         *
         * @return the group name
         */
        const TQString& name() const
        {
            return m_name;
        }

        /**
         *  Use this method to get the string to display to the user as group
         *  name. This may be different to name() and it returns the
         *  name in the user's language
         *
         *  @return the translated group name
         */
        const TQString& translatedName() const
        {
            return m_translatedName;
        }

       /**
        *  A group object can contain several item objects (of which you can
        *  get the names with supportedKeys() . With this method, you can
        *  get one of those item objects. See ItemInfo
        *
        *  @return a pointer to the item info. Don't delete this object!
        */
        const ItemInfo * itemInfo( const TQString& key ) const;

       /**
        *  Get the attributes of this group (see Attributes)
        *
        *  @return the attributes
        */
        uint attributes() const
        {
            return m_attr;
        }

        /**
         * @return true if this group supports adding or removing arbitrary
         * keys, false if not.
         **/
        bool supportsVariableKeys() const
        {
            return m_variableItemInfo;
        }

        /**
         * If the group supports variable keys, you can query their item
         * info with this method. The main reason for this is that you can
         * get the type and attributes of variable keys.
         *
         *  @return a pointer to the item info. Don't delete this object!
         **/
        const ItemInfo* variableItemInfo( ) const
        {
            return m_variableItemInfo;
        }

        /** @internal */
        ~GroupInfo();
    private:
        /** @internal */
        GroupInfo( const TQString& name, const TQString& translatedName);

        /** @internal */
        KFileMimeTypeInfo::ItemInfo* addItemInfo( const TQString& key,
                                                  const TQString& translatedKey,
                                                  TQVariant::Type type);

        /** @internal */
        void addVariableInfo( TQVariant::Type type, uint attr );

        TQString         m_name;
        TQString         m_translatedName;
        TQStringList     m_supportedKeys;
        uint            m_attr;
        ItemInfo*       m_variableItemInfo;
        TQDict<ItemInfo> m_itemDict;

    };

    /**
     *  This is the class for one item of a KFileMimeTypeInfo.
     *  It contains every information about a KFileMetaInfoItem that this
     *  item has in common for each file of a specific mimetype.
     **/
    class KIO_EXPORT ItemInfo
    {
    friend class KFilePlugin;
    friend class GroupInfo;
    public:
        /** @internal */
        ItemInfo() {}     // ### should be private?

        /**
         *
         * This method returns a translated prefix to be displayed before the
         * value. Think e.g. of the $ in $30
         *
         * @return the prefix
         */
        const TQString& prefix() const
        {
            return m_prefix;
        }

        /**
         * This method returns a translated suffix to be displayed after the
         * value. Think of the kbps in 128kbps
         *
         * @return the prefix
         */
        const TQString& suffix() const
        {
            return m_suffix;
        }

        /**
         * The items for a file are stored as a TQVariant and this method
         * can be used to get the data type of this item.
         *
         * @return the TQVariant type
         */
        TQVariant::Type type() const
        {
            return m_type;
        }

        /**
         * Returns the name of the item.
         * @return the name of the item
         */
        const TQString& key() const
        {
            return m_key;
        }

        /**
         * Returns a string for the specified @p value, if possible. If not,
         * TQString::null is returned. This can be used by programs if they want
         * to display a sum or an average of some item for a list of files.
         *
         * @param value the value to convert
         * @param mangle if true, the string will already contain prefix and
         *               suffix
         * @return the converted string, or TQString::null if not possible
         * @since 3.1
         */
        TQString string( const TQVariant& value, bool mangle = true ) const;

        /**
         * Is this item the variable item?
         *
         * @return true if it is, false if not
         */
        bool isVariableItem() const
        {
            // every valid item is supposed to have a non-null key
            return key().isNull();
        }

        /**
         * Returns a translation of the key for displaying to the user. If the
         * plugin provides translation to the key, it's also in the user's
         * language.
         * @return the translated key
         */
        const TQString& translatedKey() const
        {
            return m_translatedKey;
        }

        /**
         * Return the attributes of the item. See
         * KFileMimeTypeInfo::Attributes.
         * @return the attributes
         */
        uint attributes() const
        {
            return m_attr;
        }

        /**
         * Return the hints for the item. See
         * KFileMimeTypeInfo::Hint
         * @return the hint
         */
        uint hint() const
        {
            return m_hint;
        }

        /**
         * Return the unit of the item. See
         * KFileMimeTypeInfo::Unit
         * @return the unit
         */
        uint unit() const
        {
            return m_unit;
        }

    private:
        /** @internal */
        ItemInfo(const TQString& key, const TQString& translatedKey,
                 TQVariant::Type type)
            : m_key(key), m_translatedKey(translatedKey),
              m_type(type),
              m_attr(0), m_unit(NoUnit), m_hint(NoHint),
              m_prefix(TQString::null), m_suffix(TQString::null)
        {}

        TQString           m_key;
        TQString           m_translatedKey;
        TQVariant::Type    m_type;
        uint              m_attr;
        uint              m_unit;
        uint              m_hint;
        TQString           m_prefix;
        TQString           m_suffix;
    };

    // ### could it be made private? Would this be BC?
    ~KFileMimeTypeInfo();

    /**
     * Creates a validator for this item. Make sure to supply a proper
     * @p parent argument or delete the validator yourself.
     *
     * @param group the group of the item
     * @param key the key of the item
     * @param parent the parent of the TQObject, or 0 for a parent-less object
     * @param name the name of the TQObject, can be 0
     * @return the validator. You are responsible for deleting it. 0 if
     *         creation failed
     */
    TQValidator * createValidator(const TQString& group, const TQString& key,
                                 TQObject *parent = 0, const char *name = 0) const;

    /**
     * Returns the list of all groups that the plugin for this mimetype
     * supports.
     *
     * @return the list of groups
     */
    TQStringList supportedGroups() const;

    /**
     * Same as the above function, but returns the strings to display to the
     * user.
     *
     * @return the list of groups
     */
    TQStringList translatedGroups() const;

    /**
     * This returns the list of groups in the preferred order that's specified
     * in the .desktop file.
     *
     * @return the list of groups
     */
    TQStringList preferredGroups() const
    {
        return m_preferredGroups;
    }

    /**
     * Returns the mimetype to which this info belongs.
     *
     * @return the mimetype of this info
     */
    TQString mimeType()  const {return m_mimeType;}

    /**
     * Get the group info for a specific group.
     *
     * @param group the group whose group info should be retrieved
     * @return a pointer to the info. 0 if it does not
     *         exist. Don't delete this object!
     */
    const GroupInfo * groupInfo( const TQString& group ) const;

    // always returning stringlists which the user has to iterate and use them
    // to look up the real items sounds strange to me. I think we should add
    // our own iterators some time (somewhere in the future ;)

    /**
     * Return a list of all supported keys without looking for a specific
     * group
     *
     * @return the list of keys
     */
    TQStringList supportedKeys() const;

    /**
     * Return a list of all supported keys in preference order
     *
     * @return the list of keys
     */
    TQStringList preferredKeys() const
    {
        return m_preferredKeys;
    }

    // ### shouldn't this be private? BC?
    GroupInfo * addGroupInfo( const TQString& name,
                              const TQString& translatedName);

    TQString         m_translatedName;
    TQStringList     m_supportedKeys;
    uint            m_attr;
    //        bool            m_supportsVariableKeys : 1;
    TQDict<ItemInfo> m_itemDict;

// ### this should be made private instead, but this would be BIC
protected:
    /** @internal */
    KFileMimeTypeInfo( const TQString& mimeType );

    TQDict<GroupInfo> m_groups;
    TQString     m_mimeType;
    TQStringList m_preferredKeys;   // same as KFileMetaInfoProvider::preferredKeys()
    TQStringList m_preferredGroups; // same as KFileMetaInfoProvider::preferredKeys()
};


/**
 * @brief A meta information item about a file
 *
 * This is one item of the meta information about a file (see
 * KFileMetaInfo).
 */
class KIO_EXPORT KFileMetaInfoItem
{
public:
    class Data;
    typedef KFileMimeTypeInfo::Hint Hint;
    typedef KFileMimeTypeInfo::Unit Unit;
    typedef KFileMimeTypeInfo::Attributes Attributes;

    /**
     * @internal
     * You usually don't need to use this constructor yourself. Let
     * KFileMetaInfo do it for you.
     **/
    // ### hmm, then it should be private
    KFileMetaInfoItem( const KFileMimeTypeInfo::ItemInfo* mti,
                       const TQString& key, const TQVariant& value);

    /**
     * Copy constructor
     **/
    KFileMetaInfoItem( const KFileMetaInfoItem & item );

    /**
     * The assignment operator, so you can do:
     * @code
     *    KFileMetaInfoItem item = info.item("Title");
     * @endcode
     *
     * This will create a shared copy of the object. The actual data
     * is automatically deleted if all copies go out of scope
     **/
    const KFileMetaInfoItem& operator= (const KFileMetaInfoItem & item );

    /**
     * Default constructor. This creates an "invalid" item
     */
    KFileMetaInfoItem();

    ~KFileMetaInfoItem();

    /**
     * Returns the key of the item.
     *
     * @return the key of this item
     */
    TQString key() const;

    /**
     * Returns a translation of the key for displaying to the user. If the
     * plugin provides translation to the key, it's also in the user's language
     *
     * @return the translated key
     */
    TQString translatedKey() const;

    /**
     * Returns the value of the item.
     *
     * @return the value of the item.
     */
    const TQVariant& value() const;

    /**
     * Returns a string containing the value, if possible. If not,
     * TQString::null is returned.
     *
     * @param mangle if true, the string will already contain prefix and
     * suffix
     * @return the value string, or TQString::null if not possible
     */
    TQString string( bool mangle = true ) const;

    /**
     * Changes the value of the item.
     *
     * @param value the new value
     * @return true if successful, false otherwise
     */
    bool setValue( const TQVariant& value );

    /**
     * Return the type of the item.
     *
     * @return the type of the item
     */
    TQVariant::Type type() const;

    /**
     * You can query if the application can edit the item and write it back to
     * the file with this method.
     *
     * @note This doesn't ensure that you have write access to the file and
     *       that enough space is available.
     *
     * @return true if the item's value can be changed, false if not
     */
    bool isEditable() const;

    /**
     * If you remove an item, it is only marked for removal for the file. On
     * the next KFileMetaInfo::applyChanges() , it will be removed from
     * the file. With this method, you can ask if the item is marked for
     * removal.
     *
     * @return true if the item was removed, false if not
     */
    bool isRemoved() const;

    /**
     * If you change an item, it is marked as "dirty". On the next
     * KFileMetaInfo::applyChanges() , the change will be written to the
     * file. With this method, you can ask if this item is dirty.
     *
     * @return true if the item contains changes that have not yet been written
     * back into the file. Removing or adding an item counts as such a change
     */
    bool isModified() const;

    /**
     * This method returns a translated prefix to be displayed before the
     * value. Think e.g. of the $ in $30
     *
     * @return the prefix
     */
    TQString prefix() const;

    /**
     * This method returns a translated suffix to be displayed after the
     * value. Think of the kbps in 128kbps
     *
     * @return the suffix
     */
    TQString suffix() const;

    /**
     * Returns the hint for this item. See KFileMimeTypeInfo::Hint.
     *
     * @return the hint
     **/
    uint hint() const;

    /**
     * Returns the unit for this item. See KFileMimeTypeInfo::Unit.
     *
     * @return the unit
     * @since 3.2
     **/
    uint unit() const;

    /**
     * Returns the attributes for this item. See
     * KFileMimeTypeInfo::Attributes.
     *
     * @return the attributes
     **/
    uint attributes() const;

    /**
     * Return true if the item is valid, i.e. if it contains data, false
     * if it's invalid (created with the default constructor and not been
     * assigned anything), or if KFileMetaInfoGroup::item() didn't find
     * your requested item).
     *
     * @return true if valid, false if invalid
     */
    bool isValid() const;

    KIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoItem& );
    KIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoGroup& );
    KIO_EXPORT friend TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoItem& );
    friend class KFileMetaInfoGroup;

protected:
    void setAdded();
    void setRemoved();

    void ref();
    void deref();

    Data *d;
};

/**
 * @brief A group of meta information items about a file
 *
 * This is one group of meta information items about a file (see
 * KFileMetaInfo).
 */
class KIO_EXPORT KFileMetaInfoGroup
{
  friend class KFilePlugin;
  friend class KFileMetaInfo;
  KIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoGroup& );
  KIO_EXPORT friend TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoGroup& );

public:
    class Data;
    /**
     * @internal
     * You usually don't need to use this constructor yourself. Let
     * KFileMetaInfo do it for you.
     **/
    // ### hmm, then it should be private
    KFileMetaInfoGroup( const TQString& name, const KFileMimeTypeInfo* info );

    /**
     * Copy constructor
     **/
    KFileMetaInfoGroup( const KFileMetaInfoGroup& original );

    /**
     * The assignment operator, so you can do:
     * @code
     *    KFileMetaInfoGroup group = info.group("Technical");
     * @endcode
     *
     * This will create a shared copy of the object. The actual data
     * is automatically deleted if all copies go out of scope
     **/
    const KFileMetaInfoGroup& operator= (const KFileMetaInfoGroup& info );

    /**
     * Default constructor. This creates an "invalid" item
     *
     * @since 3.1
     */
     KFileMetaInfoGroup();

    ~KFileMetaInfoGroup();

    /**
     * Returns true if the item is valid, i.e. if it contains data, false
     * if it's invalid (created with the default constructor and not been
     * assigned anything), or if KFileMetaInfoGroup::item() didn't find
     * your requested item).
     *
     * @return true if valid, false if invalid
     */
    bool isValid() const;

    /**
     * Returns false if the object contains data, true if it's empty. An
     * empty group is a group with no items (amazing, isn't it?).
     *
     * @return true if empty, false otherwise
     */
    bool isEmpty() const;

    /**
     * Returns true if an item as added or removed from the group.
     *
     * @return true if an item was added or removed from the group, otherwise
     * false.
     *
     * @since 3.1
     */
    bool isModified() const;

    /**
     * Operator for convenience. It does the same as item(),
     * but you cannot specify a group to search in
     */
    KFileMetaInfoItem operator[]( const TQString& key ) const
    { return item( key ); }

    /**
     * This method searches for the specified item.
     *
     * @param key the key of the item to search
     * @return the specified item if found, an invalid item, if not
     **/
    KFileMetaInfoItem item( const TQString& key ) const;

    /**
     * Returns the item with the given @p hint.
     *
     * @param hint the hint of the item
     * @return the item with the specified @p hint
     **/
    KFileMetaInfoItem item( uint hint ) const;

    /**
     * Convenience function. Returns the value of the specified key.
     * It does the same as item(key).value().
     *
     * @param key the key of the item to search
     * @return the value with the given key
     */
    const TQVariant value( const TQString& key ) const
    {
        const KFileMetaInfoItem &i = item( key );
        return i.value();
    }

    /**
     * Use this method to get a list of keys in the specified group that
     * the plugin knows about. No variable keys.
     * For a group that doesn't support variable keys, all keys that this
     * group may have are returned. For a group that does support them, the
     * non-variable ones are returned. See KFileMetaInfo about variable
     * keys
     *
     * @return the list of keys supported for this mimetype
    **/
    TQStringList supportedKeys() const;

    /**
     * Returns true if this group supports adding or removing arbitrary
     * keys, false if not.
     *
     * @return true is variable keys are supported, false otherwise
    **/
    bool supportsVariableKeys() const;

    /**
     * Checks whether an item with the given @p key exists.
     *
     * @return true if an item for this @p key exists.
     */
    bool contains( const TQString& key ) const;

    /**
     * Returns a list of all keys.
     *
     * @return a list of all keys in the order they were inserted.
     **/
    TQStringList keys() const;

    /**
     * Returns a list of all keys in preference order.
     *
     * @return a list of all keys in preference order.
     **/
    TQStringList preferredKeys() const;

   /**
    * @return the list of possible types that the value for the specified key
    *         can be. You can use this to determine the possible types for new
    *         keys before you add them.
    *
    **/
    // ### do we really want to support that?
    // let's not waste time on thinking about it. Let's just kick it for now
    // and add it in 4.0 if needed ;)
//    const TQMemArray<TQVariant::Type>& types( const TQString& key ) const;

   /**
    * Add an item to the info. This is only possible if the specified @p key
    * is in the supportedKeys list and not yet defined or if
    * the group supports variable keys.
    *
    * @param key the key of the item
    * @return the KFileMetaInfoItem for the given @p key
    **/
    KFileMetaInfoItem addItem( const TQString& key );

    /**
     * Remove this item from the meta info of the file. You cannot query
     * KFileMetaInfo for a removed object, but you can query for a list of
     * removed items with removedItems() if you need to.
     * If you re-add it, its value will be cleared.
     *
     * @param key the key of the removed item
     * @return true if successful, false otherwise
     */
    bool removeItem(const TQString& key);

    /**
     * Returns a list of all removed items.
     *
     * @return a list of all removed items
     */
    TQStringList removedItems();

    /**
     * The name of this group.
     *
     * @return the name of this group
     */
    TQString name() const;

    /**
     * The translated name of this group.
     *
     * @return the translated name of this group
     *
     * @since 3.2
     */
    TQString translatedName() const;

    /**
     * Returns the attributes of this item.
     *
     * @return the attributes
     */
    uint attributes() const;

protected:
      void setAdded();
      KFileMetaInfoItem appendItem( const TQString& key, const TQVariant& value);

      Data* d;
      void ref();
      void deref();

};


///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////


/**
 * @brief Meta Information about a file
 *
 * This is the class for objects that hold meta information about a file.
 * The information is kept in form of a system of key/value pairs. See also
 * KFileMetaInfoItem.
 * This information is retrieved from the file through a plugin system, and
 * this class is the main interface to it.
 * If you want to write your own plugin, have a look at KFilePlugin.
 * There are basically two different kinds of meta information: Fixed ones
 * that the plugin knows about (e.g. an mp3 id3v1 tag has a well defined
 * fixed list of fields), and variable keys that exist in mimetypes that
 * support their own key/value system (comments in png files are of this type).
 * Almost every file has fixed keys, but some also have variable keys.
 *
 * The groups and the What enum are not yet supported, but already added to
 * the interface so that adding support doesn't break compatibility.
 */
class KIO_EXPORT KFileMetaInfo
{
public:
    typedef KFileMimeTypeInfo::Hint Hint;
    typedef KFileMimeTypeInfo::Unit Unit;
    typedef KFileMimeTypeInfo::Attributes Attributes;
    class Data;

    /**
     * This is used to specify what a KFileMetaInfo object should read, so
     * you can specify if you want to read "expensive" items or not.
     */
    enum What
    {
      Fastest       = 0x1,  /**< do the fastest possible read and omit all items
                                 that might need a significantly longer time
                                 than the others */
      DontCare      = 0x2,  ///< let the plugin decide what to read

      TechnicalInfo = 0x4,  /**< extract technical details about the file, like
                                 e.g. play time, resolution or a compressioni
                                 type */
      ContentInfo   = 0x8,  /**< read information about the content of the file,
                                 like comments or id3 tags */
      ExtenedAttr   = 0x10, /**< read filesystem based extended attributes if
                                 they are supported for the filesystem */
      Thumbnail     = 0x20, /**< only read the file's thumbnail, if it contains
                                 one */
      Preferred     = 0x40,  ///< get at least the preferred items
      Everything    = 0xffff ///< read everything, even if it might take a while

    };

    /**
     * The constructor.
     *
     * creating a KFileMetaInfo item through this will autoload the plugin
     * belonging to the mimetype and try to get meta information about
     * the specified file.
     *
     * If no info is available, you'll get an empty (not invalid) object.
     * You can test for it with the isEmpty() method.
     *
     *  @param path The file name. This must be the path to a local file.
     *  @param mimeType The name of the file's mimetype. If ommited, the
     *         mimetype is autodetected
     *  @param what one or more of the What enum values. It gives some
     *              hint to the plugin what information is desired. The plugin
     *              may still return more items.
     *
     * @note This version will @b only work for @b local (file:/) files.
     *
     **/
    KFileMetaInfo( const TQString& path,
                   const TQString& mimeType = TQString::null,
                   uint what = Fastest);

   /**
    * Another constructor
    *
    * Similar to the above, but takes a URL so that meta-data may be retrieved
    * over other protocols (ftp, etc.)
    *
    **/
    KFileMetaInfo( const KURL& url,
                   const TQString& mimeType = TQString::null,
                   uint what = Fastest);

    /**
     * Default constructor. This will create an invalid object (see
     * isValid().
     **/
    KFileMetaInfo();

    /**
     * Copy constructor. This creates a copy of the original object, but
     * that copy will point to the same data, so if you change the original,
     * the copy will be changed, too. After all, they are referring to the same
     * file.
     **/
    KFileMetaInfo( const KFileMetaInfo& original);

    ~KFileMetaInfo();

    /**
     * The assignment operator, so you can do e.g.:
     * @code
     *    KFileMetaInfo info;
     *    if (something) info = KFileMetaInfo("/the/file");
     * @endcode
     *
     * This will create a shared copy of the object. The actual data
     * is automatically deleted if all copies go out of scope.
     **/
    const KFileMetaInfo& operator= (const KFileMetaInfo& info );


    /**
     * Returns a list of all groups.
     *
     * @return the keys of the groups that the file has.
     */
    TQStringList groups() const;

    /**
     * Returns a list of all supported groups.
     *
     * @return the supported keys of the groups that the file has.
     */
    TQStringList supportedGroups() const;

    /**
     * Returns a list of the preferred groups.
     *
     * @return the keys of the preferred groups that the file has.
     */
    TQStringList preferredGroups() const;

    /**
     * Returns a list of all preferred keys.
     *
     * @return a list of all preferred keys.
     */
    TQStringList preferredKeys() const;

    /**
     * Returns a list of supported keys.
     *
     * @return a list of supported keys
     */
    TQStringList supportedKeys() const;

   /**
    * Returns the list of groups that you can add or remove from the file.
    *
    * @return the groups can be added or removed
    */
    TQStringList editableGroups() const;

    // I'd like to keep those for lookup without group, at least the hint
    // version
    /**
     * Returns the KFileMetaInfoItem with the given @p key.
     *
     * @param key the key of the item
     * @return the item. Invalid if there is no item with the given @p key.
     */
    KFileMetaInfoItem item(const TQString& key) const;
    /**
     * Returns the KFileMetaInfoItem with the given @p hint.
     *
     * @param hint the hint of the item
     * @return the item. Invalid if there is no item with the given @p hint.
     */
    KFileMetaInfoItem item(const KFileMetaInfoItem::Hint hint) const;

    /**
     * Saves the item with the given @p key.
     *
     * @param key the key of the item
     * @param preferredGroup the preferred group, or TQString::null
     * @param createGroup true to create the group if necessary
     * @return the saved item
     */
    KFileMetaInfoItem saveItem( const TQString& key,
                                const TQString& preferredGroup = TQString::null,
                                bool createGroup = true );

    /**
     * Returns the KFileMetaInfoGroup with the given @p key.
     *
     * @param key the key of the item
     * @return the group. Invalid if there is no group with the given @p key.
     */
    KFileMetaInfoGroup group(const TQString& key) const;

    /**
     * Returns the KFileMetaInfoGroup with the given @p key.
     *
     * @param key the key of the item
     * @return the group. Invalid if there is no group with the given @p key.
     */
    KFileMetaInfoGroup operator[] (const TQString& key) const
    {
        return group(key);
    }

   /**
    * Try to add the specified group. This will only succeed if it is
    * in the list of editableGroups().
    *
    * @note that all non-variable items that belong to this group are
    *  automatically added as empty item.
    *
    * @param name the name of the group to add
    * @return true if successful, false if not
    */
    bool addGroup( const TQString& name );

   /**
    * Remove the specified group. This will only succeed if it is
    * in the list of editableGroups(). Beware that this also
    * removes all the items in that group, so always ask the user
    * before removing it!
    *
    * @param name the name of the group to remove
    * @return true if successful, false if not
    */
    bool removeGroup( const TQString& name );

    /**
     * Returns a list of removed groups.
     *
     * @return a list of removed groups.
     */
    TQStringList removedGroups();

   /**
    * This method writes all pending changes of the meta info back to the file.
    * If any items are marked as removed, they are really removed from the
    * list. The info object as well as all items are updated.
    *
    * @return true if successful, false if not
    */
    bool applyChanges();

   /**
    * This method writes all pending changes of the meta info to the file @p path.
    * If any items are marked as removed, they are really removed from the
    * list. The info object as well as all items are updated.
    *
    * @return true if successful, false if not
    */
    bool applyChanges(const TQString& path);

   /**
     * Checks whether an item with the given @p key exists.
     *
     * @param key the key to check
     * @return whether an item for this @p key exists.
     */
    bool contains( const TQString& key ) const;

    /**
     * Checks whether a group with the given @p key exists.
     *
     * @param key the key to check
     * @return whether a group with this name exists.
     */
    bool containsGroup( const TQString& key ) const;

    /**
     * Returns the value with the given @p key.
     *
     * @param key the key to retrieve
     * @return the value. Invalid if it does not exist
     */
    const TQVariant value( const TQString& key ) const
    {
        return item(key).value();
    }


    /**
     * Returns true if the item is valid, i.e. if actually represents the info
     * about a file, false if the object is uninitialized.
     *
     * @return true if valid, false otherwise
     */
    bool isValid() const;

    /**
     * Returns false if the object contains data, true if it's empty. You'll
     * get an empty object if no plugin for the file could be found.
     *
     * @return true if empty, false otherwise
     */
    bool isEmpty() const;

    /**
     * Returns the mime type of file.
     *
     * @return the file's mime type
     */
    TQString mimeType() const;

    /**
     * Returns the path of file - or TQString::null if file is non-local
     *
     * @return the file's path - or TQString::null if file is non-local
     */
    TQString path() const;

    /**
     * Returns the url of file
     *
     * @return the file's url
     */
    KURL url() const;

    KIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfo& );
    KIO_EXPORT friend TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfo& );
    friend class KFilePlugin;

protected:
    KFileMetaInfoGroup appendGroup(const TQString& name);

   /**
     * @return a pointer to the plugin that belogs to this object's mimetype.
     *         It will be auto-loaded if it's currently not loaded
     **/
    KFilePlugin * const plugin() const;

    void ref();
    void deref();

    Data* d;

private:
    KFileMetaInfoItem findEditableItem( KFileMetaInfoGroup& group,
                                        const TQString& key );

    void init( const KURL& url,
               const TQString& mimeType = TQString::null,
               uint what = Fastest);
};

///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////


/**
 * @brief Base class for a meta information plugin
 *
 * Meta information plugins are used to extract useful information from files
 * of a given type. These plugins are used in Konqueror's file properties
 * dialog, for example.
 *
 * If you want to write your own plugin, you need to derive from this class.
 *
 * In the constructor of your class, you need to call addMimeTypeInfo() to tell
 * the KFile framework which mimetype(s) your plugin supports. For each
 * mimetype, use the addGroupInfo() and addItemInfo() methods to declare the
 * meta information items the plugin calculates and to group them accordingly.
 * For groups, use setAttributes() to customize your group (see
 * KFileMimeTypeInfo::Attributes). For items, use setAttributes() to define the
 * behaviour of the item; use setHint() to define the meaning of the item; use
 * setUnit() to define the Unit, such as KFileMimeTypeInfo::Seconds or
 * KFileMimeTypeInfo::KiloBytes. In short, the constructor defines the data
 * structure of the meta information supported by your plugin.
 *
 * Example:
 *  @code
 *  FooPlugin::FooPlugin(TQObject *parent, const char *name,
 *                       const TQStringList &args)
 *      : KFilePlugin(parent, name, args)
 *  {
 *      KFileMimeTypeInfo* info = addMimeTypeInfo( "application/x-foo" );
 *
 *      // our new group
 *      KFileMimeTypeInfo::GroupInfo* group = 0L;
 *      group = addGroupInfo(info, "FooInfo", i18n("Foo Information"));
 *
 *      KFileMimeTypeInfo::ItemInfo* item;
 *
 *      // our new items in the group
 *      item = addItemInfo(group, "Items", i18n("Items"), TQVariant::Int);
 *      item = addItemInfo(group, "Size", i18n("Size"), TQVariant::Int);
 *      setUnit(item, KFileMimeTypeInfo::KiloBytes);
 *
 *      // strings are possible, too:
 *      //addItemInfo(group, "Document Type", i18n("Document type"), TQVariant::String);
 *  }
 *  @endcode
 *
 * Some meta information items are likely to be available in several different
 * file formats, such as @c "Author", @c "Title" (for documents), and
 * @c "Length" (for multimedia files). Be sure to use the naming scheme from
 * existing plugins for your meta information items if possible. If, for
 * example, the meta information of a group of files is shown in a table view,
 * this will allow two files to share the same column (say "Length") even if
 * they are of a different file type.
 *
 * You must overwrite the readInfo() method. In this method you need to extract
 * the meta information of the given file. You can use a third-party library to
 * achieve this task. This might be the best way for binary files, since a
 * change in the file format is likely to be supported by subsequent releases
 * of that library. Alternatively, for text-based file formats, you can use
 * TQTextStream to parse the file. For simple file formats, TQRegExp can be of
 * great help, too.
 *
 * After you extracted the relevant information, use appendGroup() and
 * appendItem() to fill the meta information data structure (as defined in the
 * constructor) with values. Note that you can leave out groups or items
 * which are not appropriate for a particular file.
 *
 * Example:
 *  @code
 *  bool FooPlugin::readInfo( KFileMetaInfo& info, uint what)
 *  {
 *      int numItems = 0;
 *      int size = 0;
 *
 *      // do your calculations here, e.g. using a third-party
 *      // library or by writing an own parser using e.g. QTextStream
 *
 *      // calculate numItems and size ...
 *
 *      // note: use the same key strings as in the constructor
 *      KFileMetaInfoGroup group = appendGroup(info, "FooInfo");
 *
 *      appendItem(group, "Items", numItems);
 *      appendItem(group, "Size", size);
 *
 *      return true;
 *  }
 *  @endcode
 *
 * If you want to define mutable meta information items, you need to overwrite
 * the writeInfo() method. In this method, you can use third-party library
 * (appropriate mostly for binary files, see above) or TQTextStream to write the
 * information back to the file. If you use TQTextStream, be sure to write all
 * file contents back.
 *
 * For some items, it might be that not all possible values are allowed. You
 * can overwrite the createValidator() method to define constraints for a meta
 * information item. For example, the @c "Year" field for an MP3 file could
 * reject values outside the range 1500 - 2050 (at least for now). The
 * validator is used to check values before the writeInfo() method is called so
 * that writeInfo() is only provided correct values.
 *
 * In your plugin, you need to create a factory for the KFilePlugin
 *
 * Example:
 *  @code
 *  typedef KGenericFactory<FooPlugin> FooFactory;
 *  K_EXPORT_COMPONENT_FACTORY(kfile_foo, FooFactory("kfile_foo"));
 *  @endcode
 *
 * To make your plugin available within KDE, you also need to provide a
 * @c .desktop file which describes your plugin. The required fields in the
 * file are:
 *
 * - @c Type: must be @c "Service"
 * - @c Name: the name of the plugin
 * - @c ServiceTypes: must contain @c "KFilePlugin"
 * - @c X-KDE-Library: the name of the library containing the KFile plugin
 * - @c MimeType: the mimetype(s) which are supported by the plugin
 * - @c PreferredGroups: a comma-separated list of the most important groups.
 *   This list defines the order in which the meta information groups should be
 *   displayed
 * - @c PreferredItems: a comma-separated list of the most important items.
 *   This list defines the order in which the meta information items should be
 *   displayed
 *
 * Example:
 *  @code
 *  [Desktop Entry]
 *  Encoding=UTF-8
 *  Type=Service
 *  Name=Foo Info
 *  ServiceTypes=KFilePlugin
 *  X-KDE-Library=kfile_foo
 *  MimeType=application/x-foo
 *  PreferredGroups=FooInfo
 *  PreferredItems=Items,Size
 *  @endcode
 **/
class KIO_EXPORT KFilePlugin : public QObject
{
    Q_OBJECT

public:
    /**
     * Creates a new KFilePlugin instance. You need to implement a constructor
     * with the same argument list as this is required by KGenericFactory
     *
     * @param parent the parent of the TQObject, can be @c 0
     * @param name the name of the TQObject, can be @c 0
     * @param args currently ignored
     *
     * @see addMimeTypeInfo()
     * @see addGroupInfo()
     * @see addItemInfo()
     * @see TQObject()
     **/
    KFilePlugin( TQObject *parent, const char *name,
                 const TQStringList& args );

    /**
     * Destructor
     */
    virtual ~KFilePlugin();

    /**
     * Read the info from the file in this method and insert it into the
     * provided KFileMetaInfo object. You can get the path to the file with
     * KFileMetaInfo::path(). Use appendGroup() and appendItem() to fill
     * @p info with the extracted values
     *
     * @param info the information will be written here
     * @param what defines what to read, see KFileMetaInfo::What
     * @return @c true if successful, @c false if it failed
     *
     * @see writeInfo()
     **/
    virtual bool readInfo( KFileMetaInfo& info,
                           uint what = KFileMetaInfo::Fastest ) = 0;

    /**
     * Similar to the readInfo() but for writing the info back to the file.
     * If you don't have any writable keys, don't implement this method
     *
     * @param info the information that will be written
     * @return @c true if successful, @c false if it failed
     **/
    virtual bool writeInfo( const KFileMetaInfo& info ) const
    {
        Q_UNUSED(info);
        return true;
    }

    /**
     * This method should create an appropriate validator for the specified
     * item if it's editable or return a null pointer if not. If you don't have
     * any editable items, you don't need to implement this method.
     *
     * If you you don't need any validation, e.g. you accept any input, you can
     * simply return @c 0L, or not reimplement this method at all.
     *
     * @param mimeType the mime type
     * @param group the group name of the validator item
     * @param key the key name of the validator item
     * @param parent the TQObject parent, can be @c 0
     * @param name the name of the TQObject, can be @c 0
     **/
    virtual TQValidator* createValidator( const TQString& mimeType,
                                         const TQString& group,
                                         const TQString& key,
                                         TQObject* parent,
                                         const char* name) const
    {
        Q_UNUSED(mimeType); Q_UNUSED(group);Q_UNUSED(key);
        Q_UNUSED(parent);Q_UNUSED(name);
        return 0;
    }

protected:

    /**
     * Call this from within your constructor to tell the KFile framework what
     * mimetypes your plugin supports.
     *
     * @param mimeType a string containing the mimetype, e.g. @c "text/html"
     * @return a KFileMimeTypeInfo object, to be used with addGroupInfo()
     **/
    KFileMimeTypeInfo * addMimeTypeInfo( const TQString& mimeType );
    // ### do we need this, if it only calls the provider?
    // IMHO the Plugin shouldn't call its provider.
    // DF: yes we need this. A plugin can create more than one mimetypeinfo.
    // What sucks though, is to let plugins do that in their ctor.
    // Would be much simpler to have a virtual init method for that,
    // so that the provider can set up stuff with the plugin pointer first!

    /**
     * Creates a meta information group for KFileMimeTypeInfo object returned
     * by addMimeTypeInfo().
     *
     * @param info the object returned by addMimeTypeInfo()
     * @param key a unique string identifiing this group. For simplicity it is
     *        recommended to use the same string as for the translatedKey
     *        parameter
     * @param translatedKey the translated version of the key string for
     *        displaying in user interfaces. Use i18n() to translate the string
     * @return a GroupInfo object. Pass this object to addItemInfo to add meta
     *         information attributed to this group.
     *
     * @see setAttributes()
     * @see addItemInfo()
     **/
    KFileMimeTypeInfo::GroupInfo*  addGroupInfo(KFileMimeTypeInfo* info,
                      const TQString& key, const TQString& translatedKey) const;

    /**
     * Sets attributes of the GroupInfo object returned by addGroupInfo().
     *
     * @param gi the object returned by addGroupInfo()
     * @param attr the attributes for this group; these are values of type
     *        KFileMimeTypeInfo::Attributes, or'ed together
     **/
    void setAttributes(KFileMimeTypeInfo::GroupInfo* gi, uint attr) const;

    void addVariableInfo(KFileMimeTypeInfo::GroupInfo* gi, TQVariant::Type type,
                         uint attr) const;

    /**
     * Adds a meta information item to a GroupInfo object as returned by
     * addGroupInfo().
     *
     * @param gi the GroupInfo object to add a new item to
     * @param key a unique string to identify this item. For simplicity it is
     *        recommended to use the same string as for the translatedKey
     *        parameter
     * @param translatedKey the translated version of the key string for
     *        displaying in user interfaces. Use i18n() to translate the string
     * @param type the type of the meta information item, e.g. TQVariant::Int
     *        or TQVariant::String.
     * @return an ItemInfo object. Pass this object to setAttributes()
     **/
    KFileMimeTypeInfo::ItemInfo* addItemInfo(KFileMimeTypeInfo::GroupInfo* gi,
                                             const TQString& key,
                                             const TQString& translatedKey,
                                             TQVariant::Type type);

    /**
     * Sets some attributes for a meta information item. The attributes
     * describe if the item is mutable, how it should be computed for a list of
     * files, and how it should be displayed
     *
     * @param item the ItemInfo object as returned by addItemInfo()
     * @param attr the attributes for this item; these are values of type
     *        KFileMimeTypeInfo::Attributes, or'ed together
     **/
    void setAttributes(KFileMimeTypeInfo::ItemInfo* item, uint attr);

    /**
     * Defines the meaning of the meta information item. Some applications make
     * use of this information, so be sure to check KFileMimeTypeInfo::Hint to
     * see if an item's meaning is in the list.
     *
     * @param item the ItemInfo object as returned by addItemInfo()
     * @param hint the item's meaning. See KFileMimeTypeInfo::Hint for a list
     *        of available meanings
     **/
    void setHint(KFileMimeTypeInfo::ItemInfo* item, uint hint);

    /**
     * Sets the unit used in the meta information item. This unit is used to
     * format the value and to make large values human-readable. For example,
     * if the item's unit is KFileMimeTypeInfo::Seconds and the value is 276,
     * it will be displayed as 4:36.
     *
     * @param item the ItemInfo object as returned by addItemInfo()
     * @param unit the item's unit. See KFileMimeTypeInfo::Unit for a list of
     *        available units
     **/
    void setUnit(KFileMimeTypeInfo::ItemInfo* item, uint unit);

    /**
     * Sets a prefix string which is displayed before the item's value. Use
     * this string if no predefined unit fits the item's unit. Be sure to
     * translate the string with i18n()
     *
     * @param item the ItemInfo object as returned by addItemInfo()
     * @param prefix the prefix string to display
     **/
    void setPrefix(KFileMimeTypeInfo::ItemInfo* item, const TQString& prefix);

    /**
     * Sets a suffix string which is displayed before the item's value. Use
     * this string if no predefined unit fits the item's unit. Be sure to
     * translate the string with i18n()
     *
     * @param item the ItemInfo object as returned by addItemInfo()
     * @param suffix the suffix string to display
     **/
    void setSuffix(KFileMimeTypeInfo::ItemInfo* item, const TQString& suffix);

    /**
     * Call this method from within readInfo() to indicate that you wish to
     * fill meta information items of the group identified by @p key with
     * values.
     *
     * @param info the KFileMetaInfo object. Use the parameter of the
     *        readInfo() method
     * @param key the key string to identify the group. Use the string that you
     *        defined in your class' constructor
     * @return a KFileMetaInfoGroup object, to be used in appendItem()
     **/
    KFileMetaInfoGroup appendGroup(KFileMetaInfo& info, const TQString& key);

    /**
     * Call this method from within readInfo() to fill the meta information item
     * identified by @p key with a @p value
     *
     * @param group the KFileMetaInfoGroup object, as returned by appendGroup()
     * @param key the key string to identify the item.
     * @param value the value of the meta information item
     **/
    void appendItem(KFileMetaInfoGroup& group, const TQString& key, TQVariant value);

    TQStringList m_preferredKeys;
    TQStringList m_preferredGroups;

protected:
    /**
     * Helper method to allow binary compatible extensions when needing
     * "new virtual methods"
     *
     * @param id the identifier of the new "virtual" method
     * @param data any parameter data the new "virtual" method needs
     */
    virtual void virtual_hook( int id, void* data );
private:
    class KFilePluginPrivate;
    KFilePluginPrivate *d;
};

///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////


/**
 * @internal
 * Synchronous access to metadata of a local file. Usually, you don't want
 * to use this class for getting metainfo from a file. Use KFileMetaInfo
 *  directly. However, if you want to find out if a specific mimetype is
 *  supported and which groups and items are provided for it, you can ask
 *  the KFileMetainfoProvider for it.
 **/
class KIO_EXPORT KFileMetaInfoProvider: private QObject
{
    friend class KFilePlugin;

  Q_OBJECT
public:
    virtual ~KFileMetaInfoProvider();

    static KFileMetaInfoProvider * self();

    /**
     *  @return a pointer to the plugin that belongs to the specified mimetype,
     *  which means also load the plugin if it's not in memory
     */
    KFilePlugin * plugin( const TQString& mimeType ); // KDE4: merge with method below

    /**
     *  @return a pointer to the plugin that belongs to the specified mimetype,
     *  for the given protocol.
     *  This loads the plugin if it's not in memory yet.
     */
    KFilePlugin * plugin( const TQString& mimeType, const TQString& protocol );

    const KFileMimeTypeInfo * mimeTypeInfo( const TQString& mimeType ); // KDE4: merge with below
    const KFileMimeTypeInfo * mimeTypeInfo( const TQString& mimeType, const TQString& protocol );

    TQStringList preferredKeys( const TQString& mimeType ) const;
    TQStringList preferredGroups( const TQString& mimeType ) const;

    /// @since 3.1
    TQStringList supportedMimeTypes() const;

protected: // ## should be private, right?
    KFileMetaInfoProvider();

private:

    // Data structure:
    // Mimetype or Protocol -> { Plugin and MimeTypeInfo }
    // The {} struct is CachedPluginInfo
    struct CachedPluginInfo
    {
        CachedPluginInfo() : plugin( 0 ), mimeTypeInfo( 0 ), ownsPlugin( false ) {}
        CachedPluginInfo( KFilePlugin* p, KFileMimeTypeInfo* i, bool owns )
            : plugin( p ), mimeTypeInfo( i ), ownsPlugin( owns ) {}
        // auto-delete behavior
        ~CachedPluginInfo() {
            if ( ownsPlugin ) delete plugin;
            delete mimeTypeInfo;
        }

        // If plugin and mimeTypeInfo are 0, means that no plugin is available.
        KFilePlugin* plugin;
        KFileMimeTypeInfo* mimeTypeInfo;
        // The problem here is that plugin can be shared in multiple instances,
        // so the memory management isn't easy. KDE4 solution: use KSharedPtr?
        // For now we flag one copy of the KFilePlugin pointer as being "owned".
        bool ownsPlugin;
    };

    // The key is either a mimetype or a protocol. Those things don't look the same
    // so there's no need for two QDicts.
    TQDict<CachedPluginInfo> m_plugins;

    // This data is aggregated during the creation of a plugin,
    // before being moved to the appropriate CachedPluginInfo(s)
    // At any other time than during the loading of a plugin, this dict is EMPTY.
    // Same key as in m_plugins: mimetype or protocol
    TQDict<KFileMimeTypeInfo> m_pendingMimetypeInfos;

private:
    static KFileMetaInfoProvider * s_self;

    KFilePlugin* loadPlugin( const TQString& mimeType, const TQString& protocol );
    KFilePlugin* loadAndRegisterPlugin( const TQString& mimeType, const TQString& protocol );
    KFileMimeTypeInfo * addMimeTypeInfo( const TQString& mimeType );

    class KFileMetaInfoProviderPrivate;
    KFileMetaInfoProviderPrivate *d;

};

KIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoItem& );
KIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoItem& );

KIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoGroup& );
KIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoGroup& );

KIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfo& );
KIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfo& );


#endif // KILEMETAINFO_H