6cf194e by Ariya Hidayat at 2008-11-03 1
/****************************************************************************
2
**
efeeab5 by David Boddie at 2009-04-03 3
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
** Contact: Qt Software Information (qt-info@nokia.com)
6cf194e by Ariya Hidayat at 2008-11-03 5
**
efeeab5 by David Boddie at 2009-04-03 6
** This file is part of the Graphics Dojo project on Qt Labs.
6cf194e by Ariya Hidayat at 2008-11-03 7
**
8
** This file may be used under the terms of the GNU General Public
efeeab5 by David Boddie at 2009-04-03 9
** License version 2.0 or 3.0 as published by the Free Software Foundation
6cf194e by Ariya Hidayat at 2008-11-03 10
** and appearing in the file LICENSE.GPL included in the packaging of
11
** this file.  Please review the following information to ensure GNU
12
** General Public Licensing requirements will be met:
efeeab5 by David Boddie at 2009-04-03 13
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
14
** http://www.gnu.org/copyleft/gpl.html.
6cf194e by Ariya Hidayat at 2008-11-03 15
**
16
** If you are unsure which license is appropriate for your use, please
efeeab5 by David Boddie at 2009-04-03 17
** contact the sales department at qt-sales@nokia.com.
6cf194e by Ariya Hidayat at 2008-11-03 18
**
19
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
20
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21
**
22
****************************************************************************/
23
24
#include <iostream>
25
26
#include <QtGui>
27
#include <QtWebKit>
28
29
class WebSnap : public QObject
30
{
31
    Q_OBJECT
32
33
public:
34
    WebSnap();
35
    QSize targetSize() const;
36
    void setTargetSize(const QSize &s);
37
    QImage image() const;
38
    void load(const QUrl &url, const QString &outputFileName);
39
40
signals:
41
    void finished();
42
43
private slots:
44
    void saveResult(bool ok);
45
46
private:
47
    QWebPage m_page;
48
    QString m_fileName;
49
    QSize m_targetSize;
50
    QImage m_image;
51
};
52
53
WebSnap::WebSnap(): QObject()
54
{
55
    m_targetSize = QSize(400, 300);
56
    connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(saveResult(bool)));
57
}
58
59
void WebSnap::setTargetSize(const QSize &s)
60
{
61
    m_targetSize = s;
62
}
63
64
QSize WebSnap::targetSize() const
65
{
66
    return m_targetSize;
67
}
68
69
QImage WebSnap::image() const
70
{
71
    return m_image;
72
}
73
74
void WebSnap::load(const QUrl &url, const QString &outputFileName)
75
{
76
    m_fileName = outputFileName;
77
    m_image = QImage();
78
    m_page.mainFrame()->load(url);
79
}
80
81
void WebSnap::saveResult(bool ok)
82
{
83
    // crude error-checking
84
    if (!ok) {
85
        std::cerr << "Failed loading " << qPrintable(m_page.mainFrame()->url().toString()) << std::endl;
86
        emit finished();
87
        return;
88
    }
89
90
    // find proper size, we stick to sensible aspect ratio
91
    QSize size = m_page.mainFrame()->contentsSize();
92
    size.setHeight(size.width() * m_targetSize.height() / m_targetSize.width());
93
94
    // create the target surface
95
    m_image = QImage(size, QImage::Format_ARGB32_Premultiplied);
96
    m_image.fill(Qt::transparent);
97
98
    // render and rescale
99
    QPainter p(&m_image);
100
    m_page.setViewportSize(m_page.mainFrame()->contentsSize());
101
    m_page.mainFrame()->render(&p);
102
    p.end();
103
    m_image = m_image.scaled(m_targetSize, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
104
105
    if (!m_fileName.isEmpty()) {
106
        if (m_image.save(m_fileName, "png"))
107
            std::cout << "Result saved to " << qPrintable(m_fileName) << std::endl;
108
        else
109
            std::cout << "Failed to save to " << qPrintable(m_fileName) << std::endl;
110
    }
111
112
    emit finished();
113
}
114
115
// shamelessly copied from Qt Demo Browser
116
static QUrl guessUrlFromString(const QString &string)
117
{
118
    QString urlStr = string.trimmed();
119
    QRegExp test(QLatin1String("^[a-zA-Z]+\\:.*"));
120
121
    // Check if it looks like a qualified URL. Try parsing it and see.
122
    bool hasSchema = test.exactMatch(urlStr);
123
    if (hasSchema) {
124
        QUrl url(urlStr, QUrl::TolerantMode);
125
        if (url.isValid())
126
            return url;
127
    }
128
129
    // Might be a file.
130
    if (QFile::exists(urlStr))
131
        return QUrl::fromLocalFile(urlStr);
132
133
    // Might be a shorturl - try to detect the schema.
134
    if (!hasSchema) {
135
        int dotIndex = urlStr.indexOf(QLatin1Char('.'));
136
        if (dotIndex != -1) {
137
            QString prefix = urlStr.left(dotIndex).toLower();
138
            QString schema = (prefix == QLatin1String("ftp")) ? prefix : QLatin1String("http");
139
            QUrl url(schema + QLatin1String("://") + urlStr, QUrl::TolerantMode);
140
            if (url.isValid())
141
                return url;
142
        }
143
    }
144
145
    // Fall back to QUrl's own tolerant parser.
146
    return QUrl(string, QUrl::TolerantMode);
147
}
148
149
#include "websnap.moc"
150
151
int main(int argc, char * argv[])
152
{
153
    if ((argc < 2) || (argc == 4)) {
154
        std::cout << "Create a thumbnail preview of a web page" << std::endl << std::endl;
155
        std::cout << "  websnap url [outputfile [width height]]" << std::endl << std::endl;
156
        std::cout << "Examples: " << std::endl;
157
        std::cout << "  websnap www.trolltech.com" << std::endl;
158
        std::cout << "  websnap www.nokia.com" << std::endl;
159
        std::cout << "  websnap www.google.com google.png 400 300" << std::endl;
160
        std::cout << std::endl;
161
        return 0;
162
    }
163
164
    QString fileName;
165
166
    QUrl url = guessUrlFromString(QString::fromLatin1(argv[1]));
167
    if (argc >= 3) {
168
        fileName = QString::fromLatin1(argv[2]);
169
    } else {
170
        fileName = QFileInfo(url.path()).completeBaseName();
171
        if (fileName.isEmpty())
172
            fileName = "result";
173
        fileName += ".png";
174
    }
175
176
    QApplication a(argc, argv);
177
    WebSnap websnap;
178
    QObject::connect(&websnap, SIGNAL(finished()), QApplication::instance(), SLOT(quit()));
179
180
    if (argc == 5) {
181
        int w = QString::fromLatin1(argv[3]).toInt();
182
        int h = QString::fromLatin1(argv[4]).toInt();
183
        websnap.setTargetSize(QSize(w, h));
184
        if (!websnap.targetSize().isValid() || w <= 0 || h <= 0) {
185
            std::cerr << "Please specify a valid target size !" << std::endl;
186
            return 0;
187
        }
188
    }
189
190
    websnap.load(url, fileName);
191
    return a.exec();
192
}
193