logViewExport.cpp 8.27 KB
Newer Older
1
/***************************************************************************
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 *   KSystemLog, a system log viewer tool                                  *
 *   Copyright (C) 2007 by Nicolas Ternisien                               *
 *   nicolas.ternisien@gmail.com                                           *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
 ***************************************************************************/

#include "logViewExport.h"

24
#include <QApplication>
25
#include <QClipboard>
Ragnar Thomsen's avatar
Ragnar Thomsen committed
26
#include <QFileDialog>
Laurent Montel's avatar
Laurent Montel committed
27
28
#include <QPrintDialog>
#include <QPrinter>
Andrei Kozlov's avatar
Andrei Kozlov committed
29
#include <QDesktopServices>
Andrei Kozlov's avatar
Andrei Kozlov committed
30
#include <QUrlQuery>
31

Laurent Montel's avatar
Laurent Montel committed
32
#include <KLocalizedString>
33
#include <KMessageBox>
Laurent Montel's avatar
Laurent Montel committed
34
#include <QPrintPreviewDialog>
35
36
37
38

#include "logging.h"

#include "logLine.h"
Laurent Montel's avatar
Laurent Montel committed
39
40
#include "logViewWidget.h"
#include "logViewWidgetItem.h"
41
42
43

#include "levelPrintPage.h"

44
LogViewExport::LogViewExport(QWidget *parent, LogViewWidget *logViewWidget)
Laurent Montel's avatar
Laurent Montel committed
45
46
    : mParent(parent)
    , mLogViewWidget(logViewWidget)
47
{
48
49
}

50
51
LogViewExport::~LogViewExport()
{
52
53
}

54
55
56
57
58
59
60
61
62
void LogViewExport::sendMail()
{
    logDebug() << "Exporting to mail...";

    QString body(i18n("Here are my logs:\n"));

    body += i18n("---------------------------------------\n");

    int i = 0;
Laurent Montel's avatar
Laurent Montel committed
63
    QTreeWidgetItemIterator it(mLogViewWidget, QTreeWidgetItemIterator::Selected);
64
    while (*it) {
Laurent Montel's avatar
Laurent Montel committed
65
        auto item = static_cast<LogViewWidgetItem *>(*it);
66
67
68
69
70
71
72
73
74
75
76
77

        body += item->logLine()->exportToText();
        body += QLatin1Char('\n');

        ++it;
        ++i;
    }

    body += i18n("---------------------------------------\n");

    // Too much lines selected
    if (i > 1000) {
Laurent Montel's avatar
Laurent Montel committed
78
        KMessageBox::sorry(mParent, i18n("You have selected too many lines. Please only select important log lines."), i18n("Too Many Lines Selected"));
79
80
81
        return;
    }

Andrei Kozlov's avatar
Andrei Kozlov committed
82
83
84
85
86
87
    const QUrlQuery urlQuery = {{QStringLiteral("subject"), i18n("Log Lines of my problem")}, {QStringLiteral("body"), body}};
    QUrl url;
    url.setScheme(QStringLiteral("mailto"));
    url.setQuery(urlQuery);

    QDesktopServices::openUrl(url);
88
89
}

Laurent Montel's avatar
Laurent Montel committed
90
void LogViewExport::print(QPrinter *printer)
91
92
93
94
95
{
    // create a painter to paint on the printer object
    QPainter painter;

    // start painting
Laurent Montel's avatar
Laurent Montel committed
96
    painter.begin(printer);
97
98
99

    QPen originalPen(painter.pen());

100
101
    QPaintDevice *painterDevice = painter.device();
    int dpiy = painterDevice->logicalDpiY();
Laurent Montel's avatar
Laurent Montel committed
102
    const int margin = (int)((2 / 2.54) * dpiy); // 2 cm margins
Laurent Montel's avatar
Laurent Montel committed
103
    QRect printView(margin, margin, painterDevice->width() - 2 * margin, painterDevice->height() - 2 * margin);
104
105
106
107
108

    int page = 1;

    int movement = 0;

Laurent Montel's avatar
Laurent Montel committed
109
    QTreeWidgetItemIterator it(mLogViewWidget, QTreeWidgetItemIterator::Selected);
110
    while (*it) {
Laurent Montel's avatar
Laurent Montel committed
111
        auto item = static_cast<LogViewWidgetItem *>(*it);
Laurent Montel's avatar
Laurent Montel committed
112
        const QString body = item->logLine()->exportToText();
113
114
        painter.setPen(originalPen);
        painter.drawText(printView, Qt::AlignLeft | Qt::TextWordWrap, body);
Laurent Montel's avatar
Laurent Montel committed
115
116
117
        const int fontHeight = painter.fontMetrics().height();
        const int lines = painter.fontMetrics().boundingRect(body).width() / printView.width() + 1;
        const int moveBy = (fontHeight + 2) * lines;
118
        painter.translate(0, moveBy);
Laurent Montel's avatar
Laurent Montel committed
119
        movement += moveBy;
120
121
        if (movement + margin >= printView.height()) {
            painter.setPen(originalPen);
Laurent Montel's avatar
Laurent Montel committed
122
            printPageNumber(painter, printView, movement, page, margin);
Laurent Montel's avatar
Laurent Montel committed
123
            printer->newPage();
124
125
126
127
128
129
130
131
            page++;
            movement = 0;
        }
        ++it;
    }

    // stop painting, this will automatically send the print data to the printer
    painter.end();
132
133
}

Laurent Montel's avatar
Laurent Montel committed
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
void LogViewExport::printSelection()
{
    logDebug() << "Printing selection...";

    QPrinter printer;

    // do some printer initialization
    printer.setFullPage(true);

    /*
     LevelPrintPage* dialogPage = new LevelPrintPage(parent);
     printer.addDialogPage(dialogPage);
     */

    // initialize the printer using the print dialog
Laurent Montel's avatar
Laurent Montel committed
149
    auto printDialog = new QPrintDialog(&printer, mParent);
Laurent Montel's avatar
Laurent Montel committed
150
151
152
153
154
    if (!printDialog->exec()) {
        delete printDialog;
        return;
    }
    delete printDialog;
Laurent Montel's avatar
Laurent Montel committed
155
    print(&printer);
Laurent Montel's avatar
Laurent Montel committed
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
}

void LogViewExport::printPreview()
{
    logDebug() << "Printing selection...";

    auto dialog = new QPrintPreviewDialog(mParent);
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->resize(800, 750);

    connect(dialog, &QPrintPreviewDialog::paintRequested, this, [=](QPrinter *printing) {
        print(printing);
    });

    dialog->open();
}

Laurent Montel's avatar
Laurent Montel committed
173
void LogViewExport::printPageNumber(QPainter &painter, QRect &printView, int movement, int page, int margin)
174
175
{
    logDebug() << "Printing page number...";
176

177
    painter.translate(0, -movement);
Laurent Montel's avatar
Laurent Montel committed
178
    printView.moveTo(QPoint(margin, printView.height() * page + margin));
179
    painter.translate(0, -printView.height());
180
    painter.drawText(printView.right() - painter.fontMetrics().boundingRect(QString::number(page)).width(),
Laurent Montel's avatar
Laurent Montel committed
181
182
                     printView.bottom() + painter.fontMetrics().ascent() + 5,
                     QString::number(page));
183
184
}

185
186
187
void LogViewExport::copyToClipboard()
{
    logDebug() << "Copying to clipboard...";
188

189
190
    int nbCopied = 0;
    QString text;
191

Laurent Montel's avatar
Laurent Montel committed
192
    QTreeWidgetItemIterator it(mLogViewWidget, QTreeWidgetItemIterator::Selected);
193
    while (*it) {
Laurent Montel's avatar
Laurent Montel committed
194
        auto item = static_cast<LogViewWidgetItem *>(*it);
195

196
197
198
        // Copy the item content to the text string
        text.append(item->logLine()->exportToText());
        text.append(QLatin1Char('\n'));
199

200
        ++it;
201
202
        nbCopied++;
    }
203

204
205
    // Copy text value only if it is not empty
    if (nbCopied == 0) {
Laurent Montel's avatar
Laurent Montel committed
206
        Q_EMIT statusBarChanged(i18n("No items selected. Nothing copied to clipboard."));
207
208
209
210
    } else {
        // Copy both to clipboard and X11-selection
        QApplication::clipboard()->setText(text, QClipboard::Clipboard);
        QApplication::clipboard()->setText(text, QClipboard::Selection);
211

Laurent Montel's avatar
Laurent Montel committed
212
        Q_EMIT statusBarChanged(i18np("1 log line copied to clipboard.", "%1 log lines copied to clipboard.", nbCopied));
213
    }
214

215
    logDebug() << "Copied " << nbCopied << " log lines";
216
217
}

218
219
220
void LogViewExport::fileSave()
{
    logDebug() << "Saving to a file...";
221

Laurent Montel's avatar
Laurent Montel committed
222
    QTreeWidgetItemIterator it(mLogViewWidget, QTreeWidgetItemIterator::Selected);
223

224
    // No item selected
Laurent Montel's avatar
Laurent Montel committed
225
    if (!(*it)) {
Laurent Montel's avatar
Laurent Montel committed
226
        Q_EMIT statusBarChanged(i18n("No items selected. Please select items to be able to save them."));
227
228
        return;
    }
229

Laurent Montel's avatar
Laurent Montel committed
230
    const QString filename = QFileDialog::getSaveFileName(mParent, i18n("Save selected log entries to..."), QString());
Laurent Montel's avatar
Laurent Montel committed
231
    if (filename.isEmpty()) {
232
233
        return;
    }
234

Laurent Montel's avatar
Laurent Montel committed
235
    auto ioDev = new QFile(filename);
236

237
238
    if (ioDev->open(QIODevice::WriteOnly)) {
        QTextStream stream(ioDev);
239

240
        int nbCopied = 0;
241

242
        while (*it) {
Laurent Montel's avatar
Laurent Montel committed
243
            auto item = static_cast<LogViewWidgetItem *>(*it);
244

245
246
            // Copy the item content to the stream
            stream << item->logLine()->exportToText() << '\n';
247

248
            // Retrieve the next item
249
            ++it;
250
251
            nbCopied++;
        }
252

253
        ioDev->close();
254

255
        delete ioDev;
256

Laurent Montel's avatar
Laurent Montel committed
257
        Q_EMIT statusBarChanged(i18np("1 log line saved to '%2'.", "%1 log lines saved to '%2'.", nbCopied, filename));
258
    } else {
Laurent Montel's avatar
Laurent Montel committed
259
        const QString message(i18n("Unable to save file '%1': Permission Denied.", filename));
Laurent Montel's avatar
Laurent Montel committed
260
        KMessageBox::error(mParent, message, i18n("Unable to save file."));
261
    }
262
}