~ubuntu-branches/ubuntu/oneiric/psi/oneiric

« back to all changes in this revision

Viewing changes to src/message.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2005-01-10 17:41:43 UTC
  • mfrom: (1.2.1 upstream) (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050110174143-ltocv5zapl6blf5d
Tags: 0.9.3-1
* New upstream release
* Cleaned up debian/rules (some things are done by upstream Makefiles now)
* Fixed some lintian warnings:
  - removed executable bit from some .png files
  - moved psi.desktop to /usr/share/applications
* Updated menu files

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/****************************************************************************
2
 
** message.cpp - messages and history
3
 
** Copyright (C) 2001, 2002  Justin Karneges
4
 
**
5
 
** This program is free software; you can redistribute it and/or
6
 
** modify it under the terms of the GNU General Public License
7
 
** as published by the Free Software Foundation; either version 2
8
 
** of the License, or (at your option) any later version.
9
 
**
10
 
** This program is distributed in the hope that it will be useful,
11
 
** but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
** GNU General Public License for more details.
14
 
**
15
 
** You should have received a copy of the GNU General Public License
16
 
** along with this program; if not, write to the Free Software
17
 
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 
**
19
 
****************************************************************************/
20
 
 
21
 
#include"message.h"
22
 
#include"common.h"
23
 
 
24
 
#include<qfile.h>
25
 
#include<qregexp.h>
26
 
#include"profiles.h"
27
 
#include<stdio.h>
28
 
 
29
 
 
30
 
Message::Message()
31
 
{
32
 
        unread = FALSE;
33
 
}
34
 
 
35
 
MessageHistory::MessageHistory(const QString &jid, int xmode)
36
 
{
37
 
        v_jid = cleanJid(jid);
38
 
 
39
 
        QString fname = getHistoryDir() + "/" + qstrlower(jidEncode(v_jid)) + ".history";
40
 
        pdb(DEBUG_MAINWIN, QString("MessageHistory: fname=[%1]\n").arg(fname.latin1()));
41
 
        f.setName(fname);
42
 
 
43
 
        mode = xmode;
44
 
        bool ok = 0;
45
 
        if(xmode == HISTORY_WRITE)
46
 
                ok = f.open(IO_WriteOnly | IO_Append);
47
 
        else if(xmode == HISTORY_READ)
48
 
                ok = f.open(IO_ReadOnly);
49
 
        else if(xmode == HISTORY_FLAG)
50
 
                ok = f.open(IO_ReadWrite);
51
 
 
52
 
        if(!ok) {
53
 
                pdb(DEBUG_MAINWIN, QString("Error opening message history.  Actions will be ignored. [mode=%1]\n").arg(xmode));
54
 
                mode = 0;
55
 
        }
56
 
 
57
 
        if(mode == HISTORY_READ || mode == HISTORY_FLAG)
58
 
                f.at(f.size()-2); // last byte should be a newline.  we want the byte before it.
59
 
}
60
 
 
61
 
MessageHistory::~MessageHistory()
62
 
{
63
 
        pdb(DEBUG_MAINWIN, "MessageHistory: closing.\n");
64
 
        if(mode)
65
 
                f.close();
66
 
}
67
 
 
68
 
void MessageHistory::stepForward()
69
 
{
70
 
        if(mode != HISTORY_FLAG && mode != HISTORY_READ)
71
 
                return;
72
 
 
73
 
        if(f.at() == 0)
74
 
                return;
75
 
 
76
 
        // go backwards till we find a newline (or the beginning of the file)
77
 
        while(f.at() > 0) {
78
 
                int x = f.getch();
79
 
                if(x == -1)
80
 
                        return;
81
 
                QChar c = x;
82
 
 
83
 
                if(c == '\n')
84
 
                        break;
85
 
                if(f.at() == 1) {
86
 
                        f.at(0);
87
 
                        break;
88
 
                }
89
 
                f.at(f.at()-2);
90
 
        }
91
 
 
92
 
        // skip past the newline
93
 
        int x = f.at() - 2;
94
 
        if(x < 0)
95
 
                x = 0;
96
 
        f.at(x);
97
 
}
98
 
 
99
 
void MessageHistory::stepBack()
100
 
{
101
 
        if(mode != HISTORY_FLAG && mode != HISTORY_READ)
102
 
                return;
103
 
 
104
 
        // at end?
105
 
        if(f.at() >= f.size()-2)
106
 
                return;
107
 
 
108
 
        // skip past the newline if we're not at the beginning
109
 
        if(f.at() > 0) {
110
 
                f.at(f.at() + 2);
111
 
        }
112
 
 
113
 
        // cursor should always be after the current message, so just read forward
114
 
        QTextStream t;
115
 
        t.setDevice(&f);
116
 
        t.setEncoding(QTextStream::UnicodeUTF8);
117
 
        t.readLine();
118
 
        t.unsetDevice();
119
 
 
120
 
        // we want the position before the newline
121
 
        f.at(f.at() - 2);
122
 
}
123
 
 
124
 
Message *MessageHistory::readCurrent()
125
 
{
126
 
        if(mode != HISTORY_READ && mode != HISTORY_FLAG)
127
 
                return 0;
128
 
 
129
 
        if(f.at() == 0)
130
 
                return 0;
131
 
 
132
 
        int at = f.at();
133
 
 
134
 
        // go backwards till we find a newline (or the beginning of the file)
135
 
        while(f.at() > 0) {
136
 
                int x = f.getch();
137
 
                if(x == -1) {
138
 
                        f.at(at);
139
 
                        return 0;
140
 
                }
141
 
                QChar c = x;
142
 
 
143
 
                if(c == '\n')
144
 
                        break;
145
 
                if(f.at() == 1) {
146
 
                        f.at(0);
147
 
                        break;
148
 
                }
149
 
                f.at(f.at()-2);
150
 
        }
151
 
 
152
 
        QTextStream t;
153
 
        t.setDevice(&f);
154
 
        t.setEncoding(QTextStream::UnicodeUTF8);
155
 
        QString line = t.readLine();
156
 
        t.unsetDevice();
157
 
 
158
 
        f.at(at);
159
 
 
160
 
        return parseLine(line);
161
 
}
162
 
 
163
 
Message *MessageHistory::parseLine(const QString &line)
164
 
{
165
 
        // -- read the line --
166
 
        QString sTime, sType, sOrigin, sFlags, sText, sSubj, sUrl, sUrlDesc;
167
 
        int x1, x2;
168
 
        x1 = line.find('|') + 1;
169
 
 
170
 
        x2 = line.find('|', x1);
171
 
        sTime = line.mid(x1, x2-x1);
172
 
        x1 = x2 + 1;
173
 
 
174
 
        x2 = line.find('|', x1);
175
 
        sType = line.mid(x1, x2-x1);
176
 
        x1 = x2 + 1;
177
 
 
178
 
        x2 = line.find('|', x1);
179
 
        sOrigin = line.mid(x1, x2-x1);
180
 
        x1 = x2 + 1;
181
 
 
182
 
        x2 = line.find('|', x1);
183
 
        sFlags = line.mid(x1, x2-x1);
184
 
        x1 = x2 + 1;
185
 
 
186
 
        // check for extra fields
187
 
        if(sFlags[1] != '-') {
188
 
                int subflags = hexChar2int(sFlags[1].latin1());
189
 
 
190
 
                // have subject?
191
 
                if(subflags & 1) {
192
 
                        x2 = line.find('|', x1);
193
 
                        sSubj = line.mid(x1, x2-x1);
194
 
                        x1 = x2 + 1;
195
 
                }
196
 
                // have url?
197
 
                if(subflags & 2) {
198
 
                        x2 = line.find('|', x1);
199
 
                        sUrl = line.mid(x1, x2-x1);
200
 
                        x1 = x2 + 1;
201
 
                        x2 = line.find('|', x1);
202
 
                        sUrlDesc = line.mid(x1, x2-x1);
203
 
                        x1 = x2 + 1;
204
 
                }
205
 
        }
206
 
 
207
 
        // body text is last
208
 
        sText = line.mid(x1);
209
 
 
210
 
        // -- read end --
211
 
 
212
 
 
213
 
        // populate the message class
214
 
        Message *msg = new Message;
215
 
        msg->timeStamp = QDateTime::fromString(sTime, Qt::ISODate);
216
 
        msg->type = sType.toInt();
217
 
        msg->originLocal = (sOrigin == "to") ? TRUE: FALSE;
218
 
        if(msg->originLocal)
219
 
                msg->to = v_jid;
220
 
        else
221
 
                msg->from = v_jid;
222
 
        if(sFlags[0] == 'N')
223
 
                msg->text = logdecode(sText);
224
 
        else
225
 
                msg->text = logdecode(QString::fromUtf8(sText));
226
 
        if(sFlags[2] == 'U')
227
 
                msg->unread = TRUE;
228
 
        msg->subject = logdecode(sSubj);
229
 
        msg->url = logdecode(sUrl);
230
 
        msg->url_desc = logdecode(sUrlDesc);
231
 
        msg->late = TRUE;
232
 
 
233
 
        return msg;
234
 
}
235
 
 
236
 
Message *MessageHistory::readEntry()
237
 
{
238
 
        Message *msg = readCurrent();
239
 
        stepForward();
240
 
        return msg;
241
 
}
242
 
 
243
 
void MessageHistory::writeEntry(const Message &msg)
244
 
{
245
 
        if(mode != HISTORY_WRITE)
246
 
                return;
247
 
 
248
 
        int subflags = 0;
249
 
        if(!msg.subject.isEmpty())
250
 
                subflags |= 1;
251
 
        if(!msg.url.isEmpty())
252
 
                subflags |= 2;
253
 
 
254
 
        QString sTime, sType, sOrigin, sFlags;
255
 
        sTime = msg.timeStamp.toString(Qt::ISODate);
256
 
        sType = sType.setNum(msg.type);
257
 
        sOrigin = msg.originLocal ? "to": "from";
258
 
        sFlags = "N---";
259
 
        if(subflags != 0)
260
 
                sFlags[1] = int2hexChar(subflags);
261
 
        if(msg.unread)
262
 
                sFlags[2] = 'U';
263
 
 
264
 
        //  | date | type | To/from | flags | text
265
 
        QString line = "|" + sTime + "|" + sType + "|" + sOrigin + "|" + sFlags + "|";
266
 
 
267
 
        if(subflags & 1) {
268
 
                line += logencode(msg.subject) + "|";
269
 
        }
270
 
        if(subflags & 2) {
271
 
                line += logencode(msg.url) + "|";
272
 
                line += logencode(msg.url_desc) + "|";
273
 
        }
274
 
 
275
 
        line += logencode(msg.text);
276
 
 
277
 
        pdb(DEBUG_MAINWIN, QString("MessageHistory::writeEntry: line=[%1]\n").arg(line.latin1()));
278
 
 
279
 
        QTextStream t;
280
 
        t.setDevice(&f);
281
 
        t.setEncoding(QTextStream::UnicodeUTF8);
282
 
        t << line << endl;
283
 
        t.unsetDevice();
284
 
        f.flush();
285
 
}
286
 
 
287
 
void MessageHistory::setFlagsCurrent(const QString &flags)
288
 
{
289
 
        if(mode != HISTORY_FLAG)
290
 
                return;
291
 
 
292
 
        if(flags.length() != 4)
293
 
                return;
294
 
 
295
 
        if(f.at() == 0)
296
 
                return;
297
 
 
298
 
        int at = f.at();
299
 
 
300
 
        // go backwards till we find a newline (or the beginning of the file)
301
 
        while(f.at() > 0) {
302
 
                int x = f.getch();
303
 
                if(x == -1) {
304
 
                        f.at(at);
305
 
                        return;
306
 
                }
307
 
                QChar c = x;
308
 
 
309
 
                if(c == '\n')
310
 
                        break;
311
 
                if(f.at() == 1) {
312
 
                        f.at(0);
313
 
                        break;
314
 
                }
315
 
                f.at(f.at()-2);
316
 
        }
317
 
 
318
 
        QTextStream t;
319
 
        t.setDevice(&f);
320
 
        t.setEncoding(QTextStream::UnicodeUTF8);
321
 
        QString line = t.readLine();
322
 
        t.unsetDevice();
323
 
 
324
 
        f.at(at);
325
 
 
326
 
        // find 4 pipes in a row
327
 
        int x1 = 0;
328
 
        int n;
329
 
        for(n = 0; n < 4; ++n) {
330
 
                x1 = line.find('|', x1);
331
 
                if(x1 == -1)
332
 
                        break;
333
 
                ++x1;
334
 
        }
335
 
        if(x1 == -1)
336
 
                return;
337
 
        QString oldflags = line.mid(x1, 4);
338
 
        QString newflags;
339
 
 
340
 
        for(n = 0; n < 4; ++n) {
341
 
                if(flags[n] == '*')
342
 
                        newflags[n] = oldflags[n];
343
 
                else
344
 
                        newflags[n] = flags[n];
345
 
        }
346
 
 
347
 
        line.replace(x1, 4, newflags);
348
 
 
349
 
        // save the updated entry
350
 
        at = f.at();
351
 
 
352
 
        // go backwards till we find a newline (or the beginning of the file)
353
 
        while(f.at() > 0) {
354
 
                int x = f.getch();
355
 
                if(x == -1) {
356
 
                        f.at(at);
357
 
                        return;
358
 
                }
359
 
                QChar c = x;
360
 
 
361
 
                if(c == '\n')
362
 
                        break;
363
 
                if(f.at() == 1) {
364
 
                        f.at(0);
365
 
                        break;
366
 
                }
367
 
                f.at(f.at()-2);
368
 
        }
369
 
 
370
 
        t.setDevice(&f);
371
 
        t.setEncoding(QTextStream::UnicodeUTF8);
372
 
        t << line << endl;
373
 
        t.unsetDevice();
374
 
 
375
 
        f.flush();
376
 
        f.at(at);
377
 
}