1
// Copyright (C) 2004 Shintaro Matsuoka <shin@shoegazed.org>
2
// Copyright (C) 2006 Martin Aumueller <aumuell@reserv.at>
3
/***************************************************************************
4
 *                                                                         *
5
 *   This program is free software; you can redistribute it and/or modify  *
6
 *   it under the terms of the GNU General Public License as published by  *
7
 *   the Free Software Foundation; either version 2 of the License, or     *
8
 *   (at your option) any later version.                                   *
9
 *                                                                         *
10
 ***************************************************************************/
11
 
12
#ifndef AMAROK_QSTRINGX_H
13
#define AMAROK_QSTRINGX_H
14
15
#include <qglobal.h>
16
#include <QRegExp>
17
#include <QString>
18
#include <QStringList>
19
#include <qmap.h>
20
21
namespace Amarok
22
{
23
24
class QStringx : public QString
25
{
26
public:
27
    QStringx() {}
28
    QStringx( QChar ch ) : QString( ch ) {}
29
    QStringx( const QString& s ) : QString( s ) {}
30
    QStringx( const QByteArray& ba ) : QString( ba ) {}
31
    QStringx( const QChar* unicode, uint length ) : QString( unicode, length ) {}
32
    QStringx( const char* str ) : QString( str ) {}
33
    virtual ~QStringx() {}
34
35
    // the numbers following % obviously are not taken into account
36
    QString args( const QStringList& args ) const
37
    {
38
        const QStringList text = (*this).split( QRegExp( "%\\d+" ), QString::KeepEmptyParts );
39
40
        QList<QString>::ConstIterator itrText = text.constBegin();
41
        QList<QString>::ConstIterator itrArgs = args.constBegin();
42
        QList<QString>::ConstIterator endText = text.constEnd();
43
        QList<QString>::ConstIterator endArgs = args.constEnd();
44
        QString merged = (*itrText);
45
        ++itrText;
46
        while ( itrText != endText && itrArgs != endArgs )
47
        {
48
            merged += (*itrArgs) + (*itrText);
49
            ++itrText;
50
            ++itrArgs;
51
        }
52
53
        Q_ASSERT( itrText == text.end() && itrArgs == args.end() );
54
55
        return merged;
56
    }
57
58
    // %something gets replaced by the value corresponding to key "something" in args
59
    QString namedArgs( const QMap<QString, QString> &args, bool opt=false ) const
60
    {
61
        QRegExp rxArg( "%[a-zA-Z0-9]+" );
62
63
        QString result;
64
        int start = 0;
65
        for( int pos = rxArg.indexIn( *this );
66
                pos != -1;
67
                pos = rxArg.indexIn( *this, start ) )
68
        {
69
            int len = rxArg.matchedLength();
70
            QString p = rxArg.capturedTexts()[0].mid(1, len-1);
71
72
            result += mid( start, pos-start );
73
            if( !args[p].isEmpty() )
74
                result += args[p];
75
            else if( opt )
76
                return QString();
77
78
            start = pos + len;
79
        }
80
        result += mid( start );
81
82
        return result;
83
    }
84
85
    // %something gets replaced by the value corresponding to key "something" in args,
86
    // however, if key "something" is not available,
87
    // then replace everything within surrounding { } by an empty string
88
    QString namedOptArgs( const QMap<QString, QString> &args ) const
89
    {
90
        QRegExp rxOptArg( "\\{.*%[a-zA-Z0-9_]+.*\\}" );
91
        rxOptArg.setMinimal( true );
92
93
        QString result;
94
        int start = 0;
95
        for( int pos = rxOptArg.indexIn( *this );
96
                pos != -1;
97
                pos = rxOptArg.indexIn( *this, start ) )
98
        {
99
            int len = rxOptArg.matchedLength();
100
            QStringx opt = rxOptArg.capturedTexts()[0].mid(1, len-2);
101
102
            result += QStringx(mid( start, pos-start )).namedArgs( args );
103
            result += opt.namedArgs( args, true );
104
105
            start = pos + len;
106
        }
107
        result += QStringx( mid( start ) ).namedArgs( args );
108
109
        return result;
110
    }
111
};
112
113
} // namespace Amarok
114
115
#endif // AMAROK_QSTRINGX_H