summaryrefslogtreecommitdiffstats
path: root/kpilot/lib/syncAction.h
blob: 4643e7c6ef88ff3a4275eb6af3ac28339df497c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
#ifndef _KPILOT_SYNCACTION_H
#define _KPILOT_SYNCACTION_H
/* KPilot
**
** Copyright (C) 1998-2001 by Dan Pilone
** Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
** Copyright (C) 2006 Adriaan de Groot <groot@kde.org>
**
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/

#include <time.h>

#include <pi-dlp.h>

#include <tqobject.h>
#include <tqstring.h>
#include <tqstringlist.h>

#include "kpilotlink.h"

/** @file
* SyncAction
*/

class QTimer;
class KPilotUser;
class SyncAction;

class KDE_EXPORT SyncAction : public QObject
{
Q_OBJECT

public:
	SyncAction(KPilotLink *p,
		const char *name=0L);
	SyncAction(KPilotLink *p,
		TQWidget *visibleparent,
		const char *name=0L);
	~SyncAction();

	typedef enum { Error=-1 } Status;

	/** A syncaction has a status, which can be expressed as an
	*   integer. Subclasses are expected to define their own status
	*   values as needed.
	*/
	int status() const
	{
		return fActionStatus;
	}
	/** Return a human-readable representation of the status. */
	virtual TQString statusString() const;

protected:
	/**
	* This function starts the actual processing done
	* by the conduit. It should return false if the
	* processing cannot be initiated, f.ex. because
	* some parameters were not set or a needed library
	* is missing. This will be reported to the user.
	* It should return true if processing is started
	* normally. If processing starts normally, it is
	* the _conduit's_ responsibility to eventually
	* emit syncDone(); if processing does not start
	* normally (ie. exec() returns false) then the
	* environment will deal with syncDone().
	*/
	virtual bool exec() = 0;

public slots:
	/**
	* This just calls exec() and deals with the
	* return code.
	*/
	void execConduit();

signals:
	void syncDone(SyncAction *);
	void logMessage(const TQString &);
	void logError(const TQString &);
	void logProgress(const TQString &,int);

protected slots:
	/** This slot emits syncDone(), and does nothing else. This
	*   is safe, since the method returns immediately after the
	*   emit -- even if syncDone() causes the SyncAction to be deleted.
	*/
	void delayedDoneSlot();

protected:
	/**
	* It might not be safe to emit syncDone() from exec().
	* So instead, call delayDone() to wait for the main event
	* loop to return if you manage to do all processing
	* immediately.
	*
	* delayDone() returns true, so that return delayDone();
	* is a sensible final statement in exec().
	*/
	bool delayDone();

public:
	/** Public API for adding a sync log entry, see the implementation
	*   in KPilotLink::addSyncLogEntry().
	* @param e   Message to add to the sync log
	* @param log If @c true, also add the entry to the log in KPilot
	* @note Having messages appear on the handheld but not in KPilot
	*       should be a @em very rare occurrence.
	*/
	void addSyncLogEntry(const TQString &e,bool log=true)
	{
		if (deviceLink())
		{
			deviceLink()->addSyncLogEntry(e,log);
		}
	}
	/** Public API for adding a message to the log in KPilot.
	*   Adds @p msg to the synclog maintained on the PC.
	*/
	void addLogMessage( const TQString &msg )
	{
		emit logMessage( msg );
	}
	/** Log an error message in KPilot (the PC side of things). */
	void addLogError( const TQString &msg )
	{
		emit logError( msg );
	}
	/** Log progress in KPilot (the PC side of things). */
	void addLogProgress( const TQString &msg, int prog )
	{
		emit logProgress( msg, prog );
	}
protected:
	/** Connection to the device. @todo make private. */
	KPilotLink *fHandle;
	int fActionStatus;

	/** Returns a pointer to the connection to the device. */
	inline KPilotLink *deviceLink() const
	{
		return fHandle;
	}

	/** Returns the file descriptor for the device link -- that is,
	* the raw handle to the OS's connection to the device. Use with care.
	* May return -1 if there is no device.
	*/
	int pilotSocket() const
	{
		return deviceLink() ? deviceLink()->pilotSocket() : -1 ;
	}

	/** Tells the handheld device that someone is talking to it now.
	* Useful (repeatedly) to inform the user of what is going on.
	* May return < 0 on error (or if there is no device attached).
	*/
	int openConduit()
	{
		return deviceLink() ? deviceLink()->openConduit() : -1;
	}
public:
	/**
	* This class encapsulates the different sync modes that
	* can be used, and enforces a little discipline in changing
	* the mode and messing around in general. It replaces a
	* simple enum by not much more, but it makes things like
	* local test backups less likely to happen.
	*
	* Note that this could all be packed into a bitfield (5 bits needed)
	* but that makes for messy code in the end.
	*/
	class SyncMode
	{
	public:
		/** Available modes for the sync. */
		enum Mode {
			eHotSync=1,
			eFullSync=2,
			eCopyPCToHH=3,
			eCopyHHToPC=4,
			eBackup=5,
			eRestore=6
		} ;

		/** Create a mode with the given Mode @p m and
		* the mix-ins @p test and @p local, which
		* determine whether the sync should actually change
		* anything at all (test mode) and whether the HH is
		* to be simulated by local databases.
		*/
		SyncMode(Mode m, bool test=false, bool local=false);

		/** Create a mode by parsing the string list. This
		* is used mostly by the conduit proxies, which use
		* a string list to pass aparameters to the shared
		* library loader.
		*/
		SyncMode(const TQStringList &l);

		/** Returns the kind of sync; this is just incomplete
		* information, since a test hot sync is very different from
		* a non-test one. */
		Mode mode() const
		{
			return fMode;
		}

		/** Sets a mode from an integer @p mode, if possible.
		* If the @p mode is illegal, return false and set the
		* mode to Hot Sync. As a side effect, options test and local
		* are reset to false.
		*/
		bool setMode(int);

		/** Sets a mode from a @p mode, if possible. This leaves
		* the options unchanged, so as to reward properly-typed programming.
		*/
		bool setMode(Mode m);

		/** Sets options. Returns false if the combination of mode
		* and the options is impossible. */
		bool setOptions(bool test, bool local)
		{
			fTest=test;
			fLocal=local;
			return true;
		}

		/** Shorthand to test for a specific mode enum. This disregards
		*   the mixings local and test.
		*/
		bool operator ==(const Mode &m) const
		{
			return mode() == m;
		}
		/** Longhand comparison. Compares two modes for the same
		*   mode enum and mixins local and test.
		*/
		bool operator ==(const SyncMode &m) const
		{
			return ( mode() == m.mode() ) &&
				( isTest() == m.isTest() ) &&
				( isLocal() == m.isLocal() );
		} ;

		/** Accessor for the test part of the mode. Test syncs should
		*   never actually modify data anywhere.
		*/
		bool isTest() const
		{
			return fTest;
		}

		/** Accessor for the local part of the mode. Local syncs use a
		*   local database instead of one on the device link.
		*/
		bool isLocal() const
		{
			return fLocal;
		}

		bool isFullSync() const
		{
			return	( fMode==eFullSync  ) ||
				( fMode==eCopyPCToHH) ||
				( fMode==eCopyHHToPC) ;
		} ;
		bool isFirstSync() const
		{
			return ( fMode==eCopyHHToPC ) || ( fMode==eCopyPCToHH ) ;
		};

		/** Classify every mode as either a sync (two-way) or copy (one-way) mode. */
		bool isSync() const
		{
			return ( fMode==eFullSync ) ||
				( fMode == eHotSync );
		} ;

		/** Classify every mode as either a sync (two-way) or copy (one-way) mode. */
		bool isCopy() const
		{
			return ( fMode==eBackup ) ||
				( fMode==eRestore ) ||
				( fMode==eCopyPCToHH ) ||
				( fMode==eCopyHHToPC );
		} ;

		/**
		* Returns a standard name for each of the sync modes.
		*/
		static TQString name(Mode);

		/**
		* Returns a (human readable) name for this particular mode,
		* including extra information about test and local mode.
		*/
		TQString name() const;

		/**
		* Returns a TQStringList that, when passed to the constructor
		* of SyncMode, will re-create it. Used to pass modes into
		* shared library factories.
		*/
		TQStringList list() const;

	private:
		Mode fMode;
		bool fTest;
		bool fLocal;
	};


	enum ConflictResolution
	{
		eUseGlobalSetting=-1,
		eAskUser=0,
		eDoNothing,
		eHHOverrides,
		ePCOverrides,
		ePreviousSyncOverrides,
		eDuplicate,
		eDelete,
		eCROffset=-1
	};

	/**
	 * This MUST stay in sync with the combobox in
	 * kpilotConfigDialog_backup.ui.  If it does not, you need to
	 * either change this enum or the combobox.
	 */
	enum BackupFrequency
	{
		eEveryHotSync=0,
		eOnRequestOnly
	};

protected:
	/**
	* Call startTickle() some time before showing a dialog to the
	* user (we're assuming a local event loop here) so that while
	* the dialog is up and the user is thinking, the pilot stays
	* awake. Afterwards, call stopTickle().
	*
	* The parameter to startTickle indicates the timeout, in
	* seconds, before signal timeout is emitted. You can connect
	* to that, again, to take down the user interface part if the
	* user isn't reacting.
	*/
	void startTickle(unsigned count=0);
	void stopTickle();
signals:
	void timeout();




protected:
	TQWidget *fParent;

	/**
	* Ask a yes-no question of the user. This has a timeout so that
	* you don't wait forever for inattentive users. It's much like
	* KMessageBox::questionYesNo(), but with this extra timeout-on-
	* no-answer feature. Returns a KDialogBase::ButtonCode value - Yes,No or
	* Cancel on timeout. If there is a key set and the user indicates not to ask again,
	* the selected answer (Yes or No) is remembered for future reference.
	*
	* @p caption Message Box caption, uses "Question" if null.
	* @p key     Key for the "Don't ask again" code.
	* @p timeout Timeout, in seconds.
	*/
	int questionYesNo(const TQString &question ,
		const TQString &caption = TQString::null,
		const TQString &key = TQString::null,
		unsigned timeout = 20,
		const TQString &yes = TQString::null,
		const TQString &no = TQString::null );
	int questionYesNoCancel(const TQString &question ,
		const TQString &caption = TQString::null,
		const TQString &key = TQString::null,
		unsigned timeout = 20,
		const TQString &yes = TQString::null,
		const TQString &no = TQString::null ) ;
};


#endif