-rw-r--r-- | kaddressbook/kabcore.cpp | 460 |
1 files changed, 456 insertions, 4 deletions
diff --git a/kaddressbook/kabcore.cpp b/kaddressbook/kabcore.cpp index 32dd43a..49c3b19 100644 --- a/kaddressbook/kabcore.cpp +++ b/kaddressbook/kabcore.cpp @@ -23,24 +23,25 @@ /* Enhanced Version of the file for platform independent KDE tools. Copyright (c) 2004 Ulf Schenk $Id$ */ #include "kabcore.h" #include <stdaddressbook.h> #include <klocale.h> +#include <kfiledialog.h> #ifndef KAB_EMBEDDED #include <qclipboard.h> #include <qdir.h> #include <qfile.h> #include <qapplicaton.h> #include <qlayout.h> #include <qregexp.h> #include <qvbox.h> #include <kabc/addresseelist.h> #include <kabc/errorhandler.h> #include <kabc/resource.h> @@ -133,41 +134,47 @@ $Id$ #include "details/detailsviewcontainer.h" #include "kabprefs.h" #include "xxportmanager.h" #include "incsearchwidget.h" #include "jumpbuttonbar.h" #include "extensionmanager.h" #include "addresseeconfig.h" #include <kcmultidialog.h> #ifdef _WIN32_ #include "kaimportoldialog.h" +#else +#include <unistd.h> #endif +// sync includes +#include <libkdepim/ksyncprofile.h> + bool pasteWithNewUid = true; #ifdef KAB_EMBEDDED KABCore::KABCore( KAddressBookMain *client, bool readWrite, QWidget *parent, const char *name ) : QWidget( parent, name ), mGUIClient( client ), mViewManager( 0 ), mExtensionManager( 0 ),mConfigureDialog( 0 ),/*US mLdapSearchDialog( 0 ),*/ mReadWrite( readWrite ), mModified( false ), mMainWindow(client) #else //KAB_EMBEDDED KABCore::KABCore( KXMLGUIClient *client, bool readWrite, QWidget *parent, const char *name ) : QWidget( parent, name ), mGUIClient( client ), mViewManager( 0 ), mExtensionManager( 0 ), mConfigureDialog( 0 ), mLdapSearchDialog( 0 ), mReadWrite( readWrite ), mModified( false ) #endif //KAB_EMBEDDED { + mBlockSaveFlag = false; mExtensionBarSplitter = 0; mIsPart = !parent->inherits( "KAddressBookMain" ); mAddressBook = KABC::StdAddressBook::self(); KABC::StdAddressBook::setAutomaticSave( false ); #ifndef KAB_EMBEDDED mAddressBook->setErrorHandler( new KABC::GUIErrorHandler ); #endif //KAB_EMBEDDED connect( mAddressBook, SIGNAL( addressBookChanged( AddressBook * ) ), SLOT( addressBookChanged() ) ); @@ -1052,44 +1059,48 @@ void KABCore::executeContact( const QString &uid /*US = QString::null*/ ) editContact( uid ); } else { setDetailsVisible( true ); mActionDetails->setChecked(true); } } void KABCore::save() { + if (mBlockSaveFlag) + return; + mBlockSaveFlag = true; if ( !mModified ) return; QString text = i18n( "There was an error while attempting to save\n the " "address book. Please check that some \nother application is " "not using it. " ); statusMessage(i18n("Saving addressbook ... ")); #ifndef KAB_EMBEDDED KABC::StdAddressBook *b = dynamic_cast<KABC::StdAddressBook*>( mAddressBook ); if ( !b || !b->save() ) { KMessageBox::error( this, text, i18n( "Unable to Save" ) ); } #else //KAB_EMBEDDED KABC::StdAddressBook *b = (KABC::StdAddressBook*)( mAddressBook ); if ( !b || !b->save() ) { QMessageBox::critical( this, i18n( "Unable to Save" ), text, i18n("Ok")); } #endif //KAB_EMBEDDED statusMessage(i18n("Addressbook saved!")); setModified( false ); + mBlockSaveFlag = false; } void KABCore::statusMessage(QString mess , int time ) { //topLevelWidget()->setCaption( mess ); // pending setting timer to revome message } void KABCore::undo() { UndoStack::instance()->undo(); // Refresh the view @@ -1427,25 +1438,25 @@ void KABCore::initGUI() topLayout->setStretchFactor( mJumpButtonBar, 1 ); mXXPortManager = new XXPortManager( this, this ); #else //KAB_EMBEDDED //US initialize viewMenu before settingup viewmanager. // Viewmanager needs this menu to plugin submenues. viewMenu = new QPopupMenu( this ); settingsMenu = new QPopupMenu( this ); //filterMenu = new QPopupMenu( this ); ImportMenu = new QPopupMenu( this ); ExportMenu = new QPopupMenu( this ); - + syncMenu = new QPopupMenu( this ); changeMenu= new QPopupMenu( this ); //US since we have no splitter for the embedded system, setup // a layout with two frames. One left and one right. QBoxLayout *topLayout; // = new QHBoxLayout( this ); // QBoxLayout *topLayout = (QBoxLayout*)layout(); // QWidget *mainBox = new QWidget( this ); // QBoxLayout * mainBoxLayout = new QHBoxLayout(mainBox); @@ -1745,42 +1756,44 @@ void KABCore::addActionsManually() KToolBar* tb = mMainWindow->toolBar(); #ifdef DESKTOP_VERSION QMenuBar* mb = mMainWindow->menuBar(); //US setup menubar. //Disable the following block if you do not want to have a menubar. mb->insertItem( "&File", fileMenu ); mb->insertItem( "&Edit", editMenu ); mb->insertItem( "&View", viewMenu ); mb->insertItem( "&Settings", settingsMenu ); + mb->insertItem( i18n("Synchronize"), syncMenu ); mb->insertItem( "&Change selected", changeMenu ); mb->insertItem( "&Help", helpMenu ); mIncSearchWidget = new IncSearchWidget( tb ); // tb->insertWidget(-1, 0, mIncSearchWidget); #else //US setup toolbar QPEMenuBar *menuBarTB = new QPEMenuBar( tb ); QPopupMenu *popupBarTB = new QPopupMenu( this ); menuBarTB->insertItem( "ME", popupBarTB); tb->insertWidget(-1, 0, menuBarTB); mIncSearchWidget = new IncSearchWidget( tb ); tb->enableMoving(false); popupBarTB->insertItem( "&File", fileMenu ); popupBarTB->insertItem( "&Edit", editMenu ); popupBarTB->insertItem( "&View", viewMenu ); popupBarTB->insertItem( "&Settings", settingsMenu ); + popupBarTB->insertItem( i18n("Synchronize"), syncMenu ); mViewManager->getFilterAction()->plug ( popupBarTB); popupBarTB->insertItem( "&Change selected", changeMenu ); popupBarTB->insertItem( "&Help", helpMenu ); if (QApplication::desktop()->width() > 320 ) { // mViewManager->getFilterAction()->plug ( tb); } #endif // mActionQuit->plug ( mMainWindow->toolBar()); //US Now connect the actions with the menue entries. @@ -1874,24 +1887,28 @@ void KABCore::addActionsManually() /*US mIncSearchWidget = new IncSearchWidget( tb ); connect( mIncSearchWidget, SIGNAL( doSearch( const QString& ) ), SLOT( incrementalSearch( const QString& ) ) ); mJumpButtonBar = new JumpButtonBar( this, this ); //US topLayout->addWidget( mJumpButtonBar ); this->layout()->add( mJumpButtonBar ); */ #endif //KAB_EMBEDDED + + connect ( syncMenu, SIGNAL( activated ( int ) ), this, SLOT (slotSyncMenu( int ) ) ); + fillSyncMenu(); + } void KABCore::showLicence() { KApplication::showLicence(); } void KABCore::removeVoice() { if ( KMessageBox::questionYesNo( this, i18n("After importing, phone numbers\nmay have two or more types.\n(E.g. work+voice)\nThese numbers are shown as \"other\".\nClick Yes to remove the voice type\nfrom numbers with more than one type.\n\nRemove voice type?") ) == KMessageBox::No ) return; KABC::Addressee::List list = mViewManager->selectedAddressees(); KABC::Addressee::List::Iterator it; for ( it = list.begin(); it != list.end(); ++it ) { @@ -2075,17 +2092,452 @@ void KABCore::requestForDetails(const QString& sourceChannel, const QString& ses mActionDetails->setChecked(true); } } } void KABCore::faq() { KApplication::showFile( "KA/Pi FAQ", "kdepim/kaddressbook/kapiFAQ.txt" ); } +void KABCore::fillSyncMenu() +{ + if ( syncMenu->count() ) + syncMenu->clear(); + syncMenu->insertItem( i18n("Configure..."), 0 ); + syncMenu->insertSeparator(); + syncMenu->insertItem( i18n("Multiple sync"), 1 ); + syncMenu->insertSeparator(); + KConfig config ( locateLocal( "config","ksyncprofilesrc" ) ); + config.setGroup("General"); + QStringList prof = config.readListEntry("SyncProfileNames"); + KABPrefs::instance()->mLocalMachineName = config.readEntry("LocalMachineName","undefined"); + if ( prof.count() < 3 ) { + prof.clear(); + prof << i18n("Sharp_DTM"); + prof << i18n("Local_file"); + prof << i18n("Last_file"); + KSyncProfile* temp = new KSyncProfile (); + temp->setName( prof[0] ); + temp->writeConfig(&config); + temp->setName( prof[1] ); + temp->writeConfig(&config); + temp->setName( prof[2] ); + temp->writeConfig(&config); + config.setGroup("General"); + config.writeEntry("SyncProfileNames",prof); + config.writeEntry("ExternSyncProfiles","Sharp_DTM"); + config.sync(); + delete temp; + } + KABPrefs::instance()->mExternSyncProfiles = config.readListEntry("ExternSyncProfiles"); + KABPrefs::instance()->mSyncProfileNames = prof; + int i; + for ( i = 0; i < prof.count(); ++i ) { + + syncMenu->insertItem( prof[i], 1000+i ); + if ( i == 2 ) + syncMenu->insertSeparator(); + } + QDir app_dir; + if ( !app_dir.exists(QDir::homeDirPath()+"/Applications/dtm" ) ) { + syncMenu->setItemEnabled( false , 1000 ); + } + //probaly useless + //mView->setupExternSyncProfiles(); +} +void KABCore::slotSyncMenu( int action ) +{ + //qDebug("syncaction %d ", action); + if ( action == 0 ) { + + // seems to be a Qt2 event handling bug + // syncmenu.clear causes a segfault at first time + // when we call it after the main event loop, it is ok + // same behaviour when calling OM/Pi via QCOP for the first time + QTimer::singleShot ( 1, this, SLOT ( confSync() ) ); + //confSync(); + return; + } + if ( action == 1 ) { + multiSync( true ); + return; + } -#ifndef KAB_EMBEDDED -#include "kabcore.moc" -#endif //KAB_EMBEDDED + if (mBlockSaveFlag) + return; + mBlockSaveFlag = true; + mCurrentSyncProfile = action - 1000 ; + mCurrentSyncDevice = KABPrefs::instance()->mSyncProfileNames[mCurrentSyncProfile] ; + mCurrentSyncName = KABPrefs::instance()->mLocalMachineName ; + KConfig config ( locateLocal( "config","ksyncprofilesrc" ) ); + KSyncProfile* temp = new KSyncProfile (); + temp->setName(KABPrefs::instance()->mSyncProfileNames[mCurrentSyncProfile]); + temp->readConfig(&config); + KABPrefs::instance()->mAskForPreferences = temp->getAskForPreferences(); + KABPrefs::instance()->mSyncAlgoPrefs = temp->getSyncPrefs(); + KABPrefs::instance()->mWriteBackFile = temp->getWriteBackFile(); + KABPrefs::instance()->mWriteBackExistingOnly = temp->getWriteBackExisting(); + KABPrefs::instance()->mWriteBackInFuture = 0; + if ( temp->getWriteBackFuture() ) + KABPrefs::instance()->mWriteBackInFuture = temp->getWriteBackFutureWeeks( ); + KABPrefs::instance()->mShowSyncSummary = temp->getShowSummaryAfterSync(); + if ( action == 1000 ) { + syncSharp(); + + } else if ( action == 1001 ) { + syncLocalFile(); + + } else if ( action == 1002 ) { + quickSyncLocalFile(); + + } else if ( action >= 1003 ) { + if ( temp->getIsLocalFileSync() ) { + if ( syncWithFile( temp->getRemoteFileName( ), false ) ) + KABPrefs::instance()->mLastSyncedLocalFile = temp->getRemoteFileName(); + } else { + if ( temp->getIsPhoneSync() ) { + KABPrefs::instance()->mPhoneDevice = temp->getPhoneDevice( ) ; + KABPrefs::instance()->mPhoneConnection = temp->getPhoneConnection( ); + KABPrefs::instance()->mPhoneModel = temp->getPhoneModel( ); + syncPhone(); + } else + syncRemote( temp ); + + } + } + delete temp; + mBlockSaveFlag = false; +} + +void KABCore::syncLocalFile() +{ + + QString fn =KABPrefs::instance()->mLastSyncedLocalFile; + + fn =KFileDialog:: getOpenFileName( fn, i18n("Sync filename(*.ics/*.vcs)"), this ); + if ( fn == "" ) + return; + if ( syncWithFile( fn, false ) ) { + qDebug("syncLocalFile() successful "); + } + +} +bool KABCore::syncWithFile( QString fn , bool quick ) +{ + bool ret = false; + QFileInfo info; + info.setFile( fn ); + QString mess; + bool loadbup = true; + if ( !info. exists() ) { + mess = i18n( "Sync file \n...%1\ndoes not exist!\nNothing synced!\n").arg(fn.right( 30) ); + int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"), + mess ); + return ret; + } + int result = 0; + if ( !quick ) { + mess = i18n("Sync with file \n...%1\nfrom:\n%2\n").arg(fn.right( 25)).arg(KGlobal::locale()->formatDateTime(info.lastModified (), true, false )); + result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"), + mess, + i18n("Sync"), i18n("Cancel"), 0, + 0, 1 ); + if ( result ) + return false; + } + if ( KABPrefs::instance()->mAskForPreferences ) + edit_sync_options(); + if ( result == 0 ) { + //qDebug("Now sycing ... "); + if ( ret = syncAB( fn, KABPrefs::instance()->mSyncAlgoPrefs ) ) + setCaption( i18n("Synchronization successful") ); + else + setCaption( i18n("Sync cancelled or failed. Nothing synced.") ); + if ( ! quick ) + KABPrefs::instance()->mLastSyncedLocalFile = fn; + setModified(); + } + return ret; +} +void KABCore::quickSyncLocalFile() +{ + + if ( syncWithFile( KABPrefs::instance()->mLastSyncedLocalFile, false ) ) { + qDebug("quick syncLocalFile() successful "); + + } +} +void KABCore::multiSync( bool askforPrefs ) +{ + if (mBlockSaveFlag) + return; + mBlockSaveFlag = true; + QString question = i18n("Do you really want\nto multiple sync\nwith all checked profiles?\nSyncing takes some\ntime - all profiles\nare synced twice!"); + if ( QMessageBox::information( this, i18n("KO/Pi Sync"), + question, + i18n("Yes"), i18n("No"), + 0, 0 ) != 0 ) { + mBlockSaveFlag = false; + setCaption(i18n("Aborted! Nothing synced!")); + return; + } + mCurrentSyncDevice = i18n("Multiple profiles") ; + KABPrefs::instance()->mSyncAlgoPrefs = KABPrefs::instance()->mRingSyncAlgoPrefs; + if ( askforPrefs ) { + edit_sync_options(); + KABPrefs::instance()->mRingSyncAlgoPrefs = KABPrefs::instance()->mSyncAlgoPrefs; + } + setCaption(i18n("Multiple sync started.") ); + qApp->processEvents(); + int num = ringSync() ; + if ( num > 1 ) + ringSync(); + mBlockSaveFlag = false; + if ( num ) + save(); + if ( num ) + setCaption(i18n("%1 profiles synced. Multiple sync completed!").arg(num) ); + else + setCaption(i18n("Nothing synced! No profiles defined for multisync!")); + return; +} +int KABCore::ringSync() +{ + int syncedProfiles = 0; + int i; + QTime timer; + KConfig config ( locateLocal( "config","ksyncprofilesrc" ) ); + QStringList syncProfileNames = KABPrefs::instance()->mSyncProfileNames; + KSyncProfile* temp = new KSyncProfile (); + KABPrefs::instance()->mAskForPreferences = false; + for ( i = 0; i < syncProfileNames.count(); ++i ) { + mCurrentSyncProfile = i; + temp->setName(syncProfileNames[mCurrentSyncProfile]); + temp->readConfig(&config); + if ( temp->getIncludeInRingSync() && ( i < 1 || i > 2 )) { + setCaption(i18n("Profile ")+syncProfileNames[mCurrentSyncProfile]+ i18n(" is synced ... ")); + ++syncedProfiles; + // KABPrefs::instance()->mAskForPreferences = temp->getAskForPreferences(); + KABPrefs::instance()->mWriteBackFile = temp->getWriteBackFile(); + KABPrefs::instance()->mWriteBackExistingOnly = temp->getWriteBackExisting(); + KABPrefs::instance()->mWriteBackInFuture = 0; + if ( temp->getWriteBackFuture() ) + KABPrefs::instance()->mWriteBackInFuture = temp->getWriteBackFutureWeeks( ); + KABPrefs::instance()->mShowSyncSummary = false; + mCurrentSyncDevice = syncProfileNames[i] ; + mCurrentSyncName = KABPrefs::instance()->mLocalMachineName; + if ( i == 0 ) { + syncSharp(); + } else { + if ( temp->getIsLocalFileSync() ) { + if ( syncWithFile( temp->getRemoteFileName( ), true ) ) + KABPrefs::instance()->mLastSyncedLocalFile = temp->getRemoteFileName(); + } else { + if ( temp->getIsPhoneSync() ) { + KABPrefs::instance()->mPhoneDevice = temp->getPhoneDevice( ) ; + KABPrefs::instance()->mPhoneConnection = temp->getPhoneConnection( ); + KABPrefs::instance()->mPhoneModel = temp->getPhoneModel( ); + syncPhone(); + } else + syncRemote( temp, false ); + + } + } + timer.start(); + setCaption(i18n("Multiple sync in progress ... please wait!") ); + while ( timer.elapsed () < 2000 ) { + qApp->processEvents(); +#ifndef _WIN32_ + sleep (1); +#endif + } + + } + + } + delete temp; + return syncedProfiles; +} + +void KABCore::syncRemote( KSyncProfile* prof, bool ask) +{ + QString question; + if ( ask ) { + question = i18n("Do you really want\nto remote sync\nwith profile \n")+ prof->getName()+" ?\n"; + if ( QMessageBox::information( this, i18n("KO/Pi Sync"), + question, + i18n("Yes"), i18n("No"), + 0, 0 ) != 0 ) + return; + } + QString command = prof->getPreSyncCommand(); + int fi; + if ( (fi = command.find("$PWD$")) > 0 ) { + QString pwd = getPassword(); + command = command.left( fi )+ pwd + command.mid( fi+5 ); + + } + int maxlen = 30; + if ( QApplication::desktop()->width() > 320 ) + maxlen += 25; + setCaption ( i18n( "Copy remote file to local machine..." ) ); + int fileSize = 0; + int result = system ( command ); + // 0 : okay + // 256: no such file or dir + // + qDebug("KO: Remote copy result(0 = okay): %d ",result ); + if ( result != 0 ) { + int len = maxlen; + while ( len < command.length() ) { + command.insert( len , "\n" ); + len += maxlen +2; + } + question = i18n("Sorry, the copy command failed!\nCommand was:\n%1\n \nTry command on console to get more\ndetailed info about the reason.\n").arg (command) ; + QMessageBox::information( this, i18n("KO/Pi Sync - ERROR"), + question, + i18n("Okay!")) ; + setCaption ("KO/Pi"); + return; + } + setCaption ( i18n( "Copying succeed." ) ); + //qDebug(" file **%s** ",prof->getLocalTempFile().latin1() ); + if ( syncWithFile( prof->getLocalTempFile(), true ) ) { +// Event* e = mView->getLastSyncEvent(); +// e->setReadOnly( false ); +// e->setLocation( KOPrefs::instance()->mSyncProfileNames[mCurrentSyncProfile]); +// e->setReadOnly( true ); + if ( KABPrefs::instance()->mWriteBackFile ) { + command = prof->getPostSyncCommand(); + int fi; + if ( (fi = command.find("$PWD$")) > 0 ) { + QString pwd = getPassword(); + command = command.left( fi )+ pwd + command.mid( fi+5 ); + + } + setCaption ( i18n( "Writing back file ..." ) ); + result = system ( command ); + qDebug("KO: Writing back file result: %d ", result); + if ( result != 0 ) { + setCaption ( i18n( "Writing back file result: " )+QString::number( result ) ); + return; + } else { + setCaption ( i18n( "Syncronization sucessfully completed" ) ); + } + } + } + return; +} +#include <qpushbutton.h> +#include <qradiobutton.h> +#include <qbuttongroup.h> +void KABCore::edit_sync_options() +{ + //mDialogManager->showSyncOptions(); + //KABPrefs::instance()->mSyncAlgoPrefs + QDialog dia( this, "dia", true ); + dia.setCaption( i18n("Device: " ) +mCurrentSyncDevice ); + QButtonGroup gr ( 1, Qt::Horizontal, i18n("Sync preferences"), &dia); + QVBoxLayout lay ( &dia ); + lay.setSpacing( 2 ); + lay.setMargin( 3 ); + lay.addWidget(&gr); + QRadioButton loc ( i18n("Take local entry on conflict"), &gr ); + QRadioButton rem ( i18n("Take remote entry on conflict"), &gr ); + QRadioButton newest( i18n("Take newest entry on conflict"), &gr ); + QRadioButton ask( i18n("Ask for every entry on conflict"), &gr ); + QRadioButton f_loc( i18n("Force: Take local entry always"), &gr ); + QRadioButton f_rem( i18n("Force: Take remote entry always"), &gr ); + //QRadioButton both( i18n("Take both on conflict"), &gr ); + QPushButton pb ( "OK", &dia); + lay.addWidget( &pb ); + connect(&pb, SIGNAL( clicked() ), &dia, SLOT ( accept() ) ); + switch ( KABPrefs::instance()->mSyncAlgoPrefs ) { + case 0: + loc.setChecked( true); + break; + case 1: + rem.setChecked( true ); + break; + case 2: + newest.setChecked( true); + break; + case 3: + ask.setChecked( true); + break; + case 4: + f_loc.setChecked( true); + break; + case 5: + f_rem.setChecked( true); + break; + case 6: + // both.setChecked( true); + break; + default: + break; + } + if ( dia.exec() ) { + KABPrefs::instance()->mSyncAlgoPrefs = rem.isChecked()*1+newest.isChecked()*2+ ask.isChecked()*3+ f_loc.isChecked()*4+ f_rem.isChecked()*5;//+ both.isChecked()*6 ; + } + + +} +QString KABCore::getPassword( ) +{ + QString retfile = ""; + QDialog dia ( this, "input-dialog", true ); + QLineEdit lab ( &dia ); + lab.setEchoMode( QLineEdit::Password ); + QVBoxLayout lay( &dia ); + lay.setMargin(7); + lay.setSpacing(7); + lay.addWidget( &lab); + dia.setFixedSize( 230,50 ); + dia.setCaption( i18n("Enter password") ); + QPushButton pb ( "OK", &dia); + lay.addWidget( &pb ); + connect(&pb, SIGNAL( clicked() ), &dia, SLOT ( accept() ) ); + dia.show(); + int res = dia.exec(); + if ( res ) + retfile = lab.text(); + dia.hide(); + qApp->processEvents(); + return retfile; + +} + +bool KABCore::syncAB(QString filename, int mode) +{ + +} + + +void KABCore::confSync() +{ + //mView->confSync(); + qDebug("pending KABCore::confSync() "); + fillSyncMenu(); +} +void KABCore::syncSharp() +{ + if ( mModified ) + save(); + qDebug("pending syncSharp() "); + //mView->syncSharp(); + mModified = true ; + +} +void KABCore::syncPhone() +{ + if ( mModified ) + save(); + qDebug("pending syncPhone(); "); + //mView->syncPhone(); + setModified(); + +} |