00001 #include <qprinter.h>
00002 #include <qpainter.h>
00003 #include <qlayout.h>
00004 #include <qlabel.h>
00005 #include <qlistview.h>
00006 #include <qcombobox.h>
00007 #include <qpushbutton.h>
00008 #include <qcheckbox.h>
00009
00010 #include <klocale.h>
00011 #include <kurlrequester.h>
00012 #include <kfiledialog.h>
00013 #include <kdebug.h>
00014 #include <kio/job.h>
00015 #include <kio/jobclasses.h>
00016 #include <kmessagebox.h>
00017
00018 #include <ksyncer.h>
00019 #include <calendarsyncee.h>
00020 #include <bookmarksyncee.h>
00021 #include <addressbooksyncee.h>
00022 #include <ksyncuikde.h>
00023
00024 #include "ksync.h"
00025
00026 #include "ksyncview.h"
00027 #include "ksyncview.moc"
00028
00029 class SynceeListItem : public QListViewItem {
00030 public:
00031 SynceeListItem(QListView *lv,KURL url) : QListViewItem(lv,url.url()),
00032 mUrl(url) {}
00033
00034 void setSyncee(KSyncee *syncee) { mSyncee = syncee; }
00035 KSyncee *syncee() { return mSyncee; }
00036
00037 KURL url() { return mUrl; }
00038
00039 private:
00040 KSyncee *mSyncee;
00041 KURL mUrl;
00042 };
00043
00044 KSyncView::KSyncView(QWidget *parent, const char *name) :
00045 QWidget(parent, name),
00046 mSyncer(0), mTarget(0), mLoadError(false)
00047 {
00048 mTmpFiles.setAutoDelete(true);
00049
00050 QLabel *typeLabel = new QLabel(i18n("Data type to be synced:"),this);
00051
00052 mTypeCombo = new QComboBox(this);
00053 mTypeCombo->insertItem(i18n("Calendar"),TypeCalendar);
00054 mTypeCombo->insertItem(i18n("Bookmarks"),TypeBookmarks);
00055 mTypeCombo->insertItem(i18n("Addressbook"),TypeAddressBook);
00056 mCurrentType = mTypeCombo->currentItem();
00057 connect(mTypeCombo,SIGNAL(activated(int)),SLOT(reloadSyncees()));
00058
00059 QPushButton *addButton = new QPushButton(i18n("Add Source..."),this);
00060 connect(addButton,SIGNAL(clicked()),SLOT(addSource()));
00061
00062 removeButton = new QPushButton(i18n("Remove Source"),this);
00063 connect(removeButton,SIGNAL(clicked()),SLOT(removeSource()));
00064
00065 showButton = new QPushButton(i18n("Show Source"),this);
00066 connect(showButton,SIGNAL(clicked()),SLOT(showSource()));
00067
00068 mSourceListView = new QListView(this);
00069 mSourceListView->addColumn(i18n("URL"));
00070
00071 connect(mSourceListView,SIGNAL(selectionChanged ()),this,SLOT(slotSelectionChanged()));
00072 mSyncBackCheck = new QCheckBox(i18n("Write synced data back to sources."),
00073 this);
00074 connect(mSyncBackCheck,SIGNAL(clicked()),SLOT(checkSyncBack()));
00075
00076 QLabel *targetLabel = new QLabel(i18n("Target: "),this);
00077 mTargetReq = new KURLRequester(this);
00078
00079 QPushButton *syncButton = new QPushButton(i18n("Sync"),this);
00080 connect(syncButton,SIGNAL(clicked()),SLOT(doSync()));
00081
00082 checkSyncBack();
00083
00084 QGridLayout *topLayout = new QGridLayout(this);
00085 topLayout->setMargin(8);
00086 topLayout->setSpacing(8);
00087 topLayout->addWidget(typeLabel,0,0);
00088 topLayout->addMultiCellWidget(mTypeCombo,0,0,1,2);
00089 topLayout->addMultiCellWidget(addButton,1,1,0,0);
00090 topLayout->addMultiCellWidget(removeButton,1,1,1,1);
00091 topLayout->addMultiCellWidget(showButton,1,1,2,2);
00092 topLayout->addMultiCellWidget(mSourceListView,2,2,0,2);
00093 topLayout->addMultiCellWidget(mSyncBackCheck,3,3,0,2);
00094 topLayout->addMultiCellWidget(targetLabel,4,4,0,0);
00095 topLayout->addMultiCellWidget(mTargetReq,4,4,1,2);
00096 topLayout->addMultiCellWidget(syncButton,5,5,0,2);
00097 slotSelectionChanged();
00098 }
00099
00100 KSyncView::~KSyncView()
00101 {
00102 }
00103
00104 void KSyncView::print(QPrinter *pPrinter)
00105 {
00106 QPainter printpainter;
00107 printpainter.begin(pPrinter);
00108
00109
00110
00111 printpainter.end();
00112 }
00113
00114 void KSyncView::addSource()
00115 {
00116 KURL url = KFileDialog::getOpenURL();
00117 if(!url.path().isEmpty())
00118 new SynceeListItem(mSourceListView,url);
00119 }
00120
00121 void KSyncView::removeSource()
00122 {
00123 QListViewItem *item = mSourceListView->selectedItem();
00124 if (item) delete item;
00125 }
00126
00127 void KSyncView::showSource()
00128 {
00129 QListViewItem *item = mSourceListView->selectedItem();
00130 if (!item) {
00131 kdDebug() << "No item selected" << endl;
00132 return;
00133 } else {
00134 kdDebug() << "** Source '" << item->text(0) << endl;
00135 KSyncee *syncee = createSyncee(item->text(0));
00136 KSyncEntry *entry = syncee->firstEntry();
00137 while(entry) {
00138 kdDebug() << "** '" << entry->name() << "'" << endl;
00139
00140 entry = syncee->nextEntry();
00141 }
00142 delete syncee;
00143 }
00144 }
00145
00146 void KSyncView::slotSelectionChanged()
00147 {
00148 bool state=(mSourceListView->currentItem()!=0);
00149 showButton->setEnabled(state);
00150 removeButton->setEnabled(state);
00151 }
00152
00153 void KSyncView::doSync()
00154 {
00155 delete mSyncer;
00156 mSyncer = new KSyncer(new KSyncUiKde(this));
00157
00158 mLoadCount = 0;
00159 mLoadError = false;
00160
00161 SynceeListItem *item = dynamic_cast<SynceeListItem *>(mSourceListView->firstChild());
00162 while(item) {
00163 KSyncee *syncee = createSyncee(item->url());
00164 item->setSyncee(syncee);
00165 mSyncer->addSyncee(syncee);
00166
00167 item = (SynceeListItem *)item->nextSibling();
00168 }
00169
00170 QString url = mTargetReq->url();
00171
00172 kdDebug() << "target url: " << url << endl;
00173 mTarget = createSyncee(KURL(url));
00174
00175 finishSync();
00176 }
00177
00178 KSyncee *KSyncView::createSyncee(const KURL &url)
00179 {
00180 kdDebug() << "KSyncView::createSyncee(): " << url.url() << endl;
00181
00182 KSyncee *syncee;
00183 switch (mTypeCombo->currentItem()) {
00184 case TypeBookmarks:
00185 syncee = new BookmarkSyncee();
00186 break;
00187 case TypeAddressBook:
00188 syncee = new AddressBookSyncee();
00189 break;
00190 case TypeCalendar:
00191 default:
00192 syncee = new CalendarSyncee();
00193 break;
00194 }
00195
00196 SynceeLoader *loader;
00197 if (url.isLocalFile()) {
00198 loader = new SynceeLoader(this,syncee,url.path());
00199 loader->loadSyncee();
00200 ++mLoadCount;
00201 delete loader;
00202 return syncee;
00203 } else {
00204 QString tmpFile = createTempFile();
00205
00206 loader = new SynceeLoader(this,syncee,tmpFile);
00207 KIO::FileCopyJob *j = KIO::file_copy(url,tmpFile,-1,true);
00208 connect(j,SIGNAL(result(KIO::Job *)),
00209 loader,SLOT(loadSyncee(KIO::Job *)));
00210 return syncee;
00211 }
00212 }
00213
00214 void KSyncView::synceeLoaded()
00215 {
00216 ++mLoadCount;
00217 finishSync();
00218 }
00219
00220 void KSyncView::finishSync()
00221 {
00222 kdDebug() << "KSyncView::finishSync()" << endl;
00223
00224 if (mLoadError) {
00225 kdDebug() << "KSyncView::finishSync(): load error" << endl;
00226 return;
00227 }
00228
00229 if (mLoadCount == mSourceListView->childCount() + 1) {
00230 mLoadCount = 0;
00231 if (mSyncBackCheck->isChecked()) {
00232 mSyncer->sync();
00233 SynceeListItem *item = dynamic_cast<SynceeListItem *>(mSourceListView->firstChild());
00234 KIO::FileCopyJob *j;
00235 while(item) {
00236 KURL from(item->syncee()->filename());
00237 KURL to(item->url());
00238 if (from != to) {
00239 kdDebug() << "Copy " << from.url() << " to " << to.url() << endl;
00240 j = KIO::file_copy(from,to,-1,true);
00241 connect(j,SIGNAL(result(KIO::Job *)),SLOT(jobFinished(KIO::Job *)));
00242 } else {
00243 checkFinish();
00244 }
00245
00246 item = (SynceeListItem *)item->nextSibling();
00247 }
00248 } else {
00249 mSyncer->syncAllToTarget(mTarget);
00250 mTarget->save();
00251 }
00252 } else {
00253 kdDebug() << "KSyncView::finishSync(): loadCount: " << mLoadCount << " childCount: "
00254 << mSourceListView->childCount() + 1 << endl;
00255 }
00256 }
00257
00258 void KSyncView::jobFinished(KIO::Job *job)
00259 {
00260 if (job->error()) {
00261 job->showErrorDialog(this);
00262 } else {
00263 checkFinish();
00264 }
00265 }
00266
00267 void KSyncView::checkFinish()
00268 {
00269 ++mLoadCount;
00270 if (mLoadCount == mSourceListView->childCount()) {
00271 KMessageBox::information(this,i18n("Sync finished"));
00272 mLoadCount = 0;
00273 }
00274 }
00275
00276 void KSyncView::synceeLoadError()
00277 {
00278 kdDebug() << "KSyncView::synceeLoadError()" << endl;
00279
00280 mLoadError = true;
00281
00282 KMessageBox::error(this,i18n("Can't load syncee."),i18n("Load Error"));
00283 }
00284
00285 void KSyncView::readConfig(KConfig *config)
00286 {
00287 int typeIndex = config->readNumEntry("SyncType",TypeCalendar);
00288 mTypeCombo->setCurrentItem(typeIndex);
00289 mCurrentType = typeIndex;
00290
00291 readTypeConfig(config);
00292 }
00293
00294 void KSyncView::readTypeConfig(KConfig *config)
00295 {
00296 QString typeString = mTypeCombo->text(mCurrentType);
00297
00298 QStringList sources = config->readListEntry("Sources_" + typeString);
00299
00300 mSourceListView->clear();
00301 QStringList::ConstIterator it = sources.begin();
00302 while(it != sources.end()) {
00303 new SynceeListItem (mSourceListView,KURL(*it));
00304 ++it;
00305 }
00306
00307 mTargetReq->setURL(config->readEntry("Target_" + typeString));
00308 }
00309
00310 void KSyncView::writeConfig(KConfig *config)
00311 {
00312 config->writeEntry("SyncType",mTypeCombo->currentItem());
00313
00314 writeTypeConfig(config);
00315 }
00316
00317 void KSyncView::writeTypeConfig(KConfig *config)
00318 {
00319 QStringList sources;
00320 QListViewItem *item = mSourceListView->firstChild();
00321 while(item) {
00322 sources.append(item->text(0));
00323 item = item->nextSibling();
00324 }
00325
00326 QString typeString = mTypeCombo->text(mCurrentType);
00327
00328 config->writeEntry("Sources_" + typeString,sources);
00329 config->writeEntry("Target_" + typeString,mTargetReq->url());
00330
00331 config->sync();
00332 }
00333
00334 void KSyncView::checkSyncBack()
00335 {
00336 if (mSyncBackCheck->isChecked()) {
00337 mTargetReq->setEnabled(false);
00338 } else {
00339 mTargetReq->setEnabled(true);
00340 }
00341 }
00342
00343 void KSyncView::reloadSyncees()
00344 {
00345 KConfig *config = kapp->config();
00346
00347 writeTypeConfig(config);
00348 mCurrentType = mTypeCombo->currentItem();
00349 readTypeConfig(config);
00350 }
00351
00352 QString KSyncView::createTempFile()
00353 {
00354 KTempFile *tmpFile = new KTempFile;
00355 mTmpFiles.append(tmpFile);
00356 tmpFile->setAutoDelete(true);
00357 return tmpFile->name();
00358 }