~ubuntu-branches/ubuntu/karmic/kdepim/karmic-backports

« back to all changes in this revision

Viewing changes to akonadi/resources/shared/singlefileresource.h

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi, Alessandro Ghersi, Harald Sitter
  • Date: 2009-06-27 04:40:05 UTC
  • mfrom: (1.1.39 upstream)
  • Revision ID: james.westby@ubuntu.com-20090627044005-4y2vm9xz7rvmzi4p
Tags: 4:4.2.95svn20090701-0ubuntu1
[ Alessandro Ghersi ]
* New upstream release
  - Bump build-deps
* Remove akonadi-kde and libmaildir4 packages
  - remove akonadi-kde.install and libmaildir4.install
  - remove libmaildir4 from debian/rules
  - remove akonadi-kde and libmaildir4 from depends
  - remove akonadi-kde and libmaildir4 from installgen
* Update kdepim-dev.install
* Update kpilot.install
* Add akonadi-kde and libmaildir4 transitional packages

[ Harald Sitter ]
* KAddressbook replaces Kontact << 4.2.85 (LP: #378373)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (c) 2008 Bertjan Broeksema <b.broeksema@kdemail.net>
 
3
    Copyright (c) 2008 Volker Krause <vkrause@kde.org>
 
4
 
 
5
    This library is free software; you can redistribute it and/or modify it
 
6
    under the terms of the GNU Library General Public License as published by
 
7
    the Free Software Foundation; either version 2 of the License, or (at your
 
8
    option) any later version.
 
9
 
 
10
    This library is distributed in the hope that it will be useful, but WITHOUT
 
11
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
12
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
 
13
    License for more details.
 
14
 
 
15
    You should have received a copy of the GNU Library General Public License
 
16
    along with this library; see the file COPYING.LIB.  If not, write to the
 
17
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
18
    02110-1301, USA.
 
19
*/
 
20
 
 
21
#ifndef AKONADI_SINGLEFILERESOURCE_H
 
22
#define AKONADI_SINGLEFILERESOURCE_H
 
23
 
 
24
#include "singlefileresourcebase.h"
 
25
 
 
26
#include <akonadi/entitydisplayattribute.h>
 
27
 
 
28
#include <kio/job.h>
 
29
#include <KDirWatch>
 
30
#include <KLocale>
 
31
#include <KStandardDirs>
 
32
 
 
33
#include <QFile>
 
34
#include <QDir>
 
35
 
 
36
namespace Akonadi
 
37
{
 
38
 
 
39
/**
 
40
 * Base class for single file based resources.
 
41
 */
 
42
template <typename Settings>
 
43
class SingleFileResource : public SingleFileResourceBase
 
44
{
 
45
  public:
 
46
    SingleFileResource( const QString &id ) : SingleFileResourceBase( id )
 
47
    {
 
48
      // The resource needs network when the path refers to a non local file.
 
49
      setNeedsNetwork( !KUrl( Settings::self()->path() ).isLocalFile() );
 
50
    }
 
51
 
 
52
    /**
 
53
     * Indicate that there are pending changes.
 
54
     */
 
55
    void fileDirty()
 
56
    {
 
57
      if( !mDirtyTimer.isActive() ) {
 
58
        mDirtyTimer.setInterval( Settings::self()->autosaveInterval() * 60 * 1000 );
 
59
        mDirtyTimer.start();
 
60
      }
 
61
    }
 
62
 
 
63
    /**
 
64
     * Read changes from the backend file.
 
65
     */
 
66
    void readFile()
 
67
    {
 
68
      if ( KDirWatch::self()->contains( mCurrentUrl.path() ) )
 
69
        KDirWatch::self()->removeFile( mCurrentUrl.path() );
 
70
 
 
71
      const bool nameWasChanged = mCurrentUrl.fileName() != name() && !mCurrentUrl.isEmpty();
 
72
 
 
73
      if ( Settings::self()->path().isEmpty() ) {
 
74
        emit status( Broken, i18n( "No file selected." ) );
 
75
        return;
 
76
      }
 
77
 
 
78
      mCurrentUrl = KUrl( Settings::self()->path() );
 
79
 
 
80
      if ( mCurrentUrl.isLocalFile() )
 
81
      {
 
82
        if ( !nameWasChanged )
 
83
          setName( mCurrentUrl.fileName() );
 
84
 
 
85
        // check if the file does not exist yet, if so, create it
 
86
        if ( !QFile::exists( mCurrentUrl.path() ) ) {
 
87
          QFile f( mCurrentUrl.path() );
 
88
 
 
89
          // first create try to create the directory the file should be located in
 
90
          QDir dir = QFileInfo(f).dir();
 
91
          if ( ! dir.exists() ) {
 
92
            dir.mkpath( dir.path() );
 
93
          }
 
94
 
 
95
          if ( f.open( QIODevice::WriteOnly ) && f.resize( 0 ) ) {
 
96
            emit status( Idle, i18nc( "@info:status", "Ready" ) );
 
97
          } else {
 
98
            emit status( Broken, i18n( "Could not create file '%1'.", mCurrentUrl.prettyUrl() ) );
 
99
            mCurrentUrl.clear();
 
100
            return;
 
101
          }
 
102
        }
 
103
 
 
104
        if ( !readFromFile( mCurrentUrl.path() ) ) {
 
105
          mCurrentUrl = KUrl(); // reset so we don't accidentally overwrite the file
 
106
          return;
 
107
        }
 
108
 
 
109
        if ( Settings::self()->monitorFile() )
 
110
          KDirWatch::self()->addFile( mCurrentUrl.path() );
 
111
 
 
112
        emit status( Idle, i18nc( "@info:status", "Ready" ) );
 
113
        synchronize();
 
114
      }
 
115
      else
 
116
      {
 
117
        if ( mDownloadJob )
 
118
        {
 
119
          emit error( i18n( "Another download is still in progress." ) );
 
120
          return;
 
121
        }
 
122
 
 
123
        if ( mUploadJob )
 
124
        {
 
125
          emit error( i18n( "Another file upload is still in progress." ) );
 
126
          return;
 
127
        }
 
128
 
 
129
        KGlobal::ref();
 
130
 
 
131
        // NOTE: Test what happens with remotefile -> save, close before save is finished.
 
132
        mDownloadJob = KIO::file_copy( mCurrentUrl, KUrl( cacheFile() ), -1, KIO::Overwrite | KIO::DefaultFlags | KIO::HideProgressInfo );
 
133
        connect( mDownloadJob, SIGNAL( result( KJob * ) ),
 
134
                SLOT( slotDownloadJobResult( KJob * ) ) );
 
135
        connect( mDownloadJob, SIGNAL( percent( KJob *, unsigned long ) ),
 
136
                 SLOT( handleProgress( KJob *, unsigned long ) ) );
 
137
 
 
138
        emit status( Running, i18n( "Downloading remote file." ) );
 
139
      }
 
140
    }
 
141
 
 
142
    /**
 
143
     * Write changes to the backend file.
 
144
     */
 
145
    void writeFile()
 
146
    {
 
147
      if ( Settings::self()->readOnly() ) {
 
148
        emit error( i18n( "Trying to write to a read-only file: '%1'.", Settings::self()->path() ) );
 
149
        return;
 
150
      }
 
151
 
 
152
      mDirtyTimer.stop();
 
153
 
 
154
      // We don't use the Settings::self()->path() here as that might have changed
 
155
      // and in that case it would probably cause data lose.
 
156
      if ( mCurrentUrl.isEmpty() ) {
 
157
        emit status( Broken, i18n( "No file specified." ) );
 
158
        return;
 
159
      }
 
160
 
 
161
      if ( mCurrentUrl.isLocalFile() ) {
 
162
        KDirWatch::self()->stopScan();
 
163
        const bool writeResult = writeToFile( mCurrentUrl.path() );
 
164
        KDirWatch::self()->startScan();
 
165
        if ( !writeResult )
 
166
          return;
 
167
 
 
168
        emit status( Idle, i18nc( "@info:status", "Ready" ) );
 
169
      } else {
 
170
        // Check if there is a download or an upload in progress.
 
171
        if ( mDownloadJob ) {
 
172
          emit error( i18n( "A download is still in progress." ) );
 
173
          return;
 
174
        }
 
175
 
 
176
        if ( mUploadJob ) {
 
177
          emit error( i18n( "Another file upload is still in progress." ) );
 
178
          return;
 
179
        }
 
180
 
 
181
        // Write te items to the localy cached file.
 
182
        if ( !writeToFile( cacheFile() ) )
 
183
          return;
 
184
 
 
185
        KGlobal::ref();
 
186
        // Start a job to upload the localy cached file to the remote location.
 
187
        mUploadJob = KIO::file_copy( KUrl( cacheFile() ), mCurrentUrl, -1, KIO::Overwrite | KIO::DefaultFlags | KIO::HideProgressInfo );
 
188
        connect( mUploadJob, SIGNAL( result( KJob * ) ),
 
189
                SLOT( slotUploadJobResult( KJob * ) ) );
 
190
        connect( mUploadJob, SIGNAL( percent( KJob *, unsigned long ) ),
 
191
                 SLOT( handleProgress( KJob *, unsigned long ) ) );
 
192
 
 
193
        emit status( Running, i18n( "Uploading cached file to remote location." ) );
 
194
      }
 
195
    }
 
196
 
 
197
  protected:
 
198
    void retrieveCollections()
 
199
    {
 
200
      Collection c;
 
201
      c.setParent( Collection::root() );
 
202
      c.setRemoteId( Settings::self()->path() );
 
203
      c.setName( identifier() );
 
204
      QStringList mimeTypes;
 
205
      c.setContentMimeTypes( mSupportedMimetypes );
 
206
      if ( Settings::self()->readOnly() ) {
 
207
        c.setRights( Collection::CanChangeCollection );
 
208
      } else {
 
209
        Collection::Rights rights;
 
210
        rights |= Collection::CanChangeItem;
 
211
        rights |= Collection::CanCreateItem;
 
212
        rights |= Collection::CanDeleteItem;
 
213
        rights |= Collection::CanChangeCollection;
 
214
        c.setRights( rights );
 
215
      }
 
216
      EntityDisplayAttribute* attr = c.attribute<EntityDisplayAttribute>( Collection::AddIfMissing );
 
217
      attr->setDisplayName( name() );
 
218
      attr->setIconName( mCollectionIcon );
 
219
      Collection::List list;
 
220
      list << c;
 
221
      collectionsRetrieved( list );
 
222
    }
 
223
};
 
224
 
 
225
}
 
226
 
 
227
#endif