<commit_before>/*
    This file is part of kdepim.

    Copyright (c) 2004 Bo Thorsen <bo@sonofthor.dk>
    Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "kmailchanges.h"

#include <kapplication.h>
#include <klocale.h>
#include <kconfiggroup.h>
#include <kstandarddirs.h>
#include <kemailsettings.h>
#include <kpimidentities/identitymanager.h>
#include <kpimidentities/identity.h>
#include <kdebug.h>
#include <kstringhandler.h>
#include <krandom.h>
#include <kwallet.h>
using namespace KWallet;

static const char* s_folderContentsType[] = {
  I18N_NOOP( "Calendar" ),
  I18N_NOOP( "Contacts" ),
  I18N_NOOP( "Notes" ),
  I18N_NOOP( "Tasks" ),
  I18N_NOOP( "Journal" ) };

Wallet* CreateImapAccount::mWallet = 0;

CreateImapAccount::CreateImapAccount( const QString &accountName, const QString &title )
  : KConfigPropagator::Change( title ),
    mAccountName( accountName ), mPort( 993 ), mEnableSieve( false ), mEnableSavePassword( true ),
    mEncryption( None ), mAuthentication( NONE ), mAuthenticationSend( PLAIN ), mSmtpPort( 25 ),
    mExistingAccountId( -1 ), mExistingTransportId( -1 ),
    mCustomWriter( 0 )
{
}

CreateImapAccount::~CreateImapAccount()
{
  delete mCustomWriter;
}

void CreateImapAccount::setServer( const QString &s )
{
  mServer = s;
}

void CreateImapAccount::setUser( const QString &s )
{
  mUser = s;
}

void CreateImapAccount::setPassword( const QString &s )
{
  mPassword = s;
}

void CreateImapAccount::setRealName( const QString &s )
{
  mRealName = s;
}

void CreateImapAccount::setPort( int port )
{
  mPort = port;
}

void CreateImapAccount::setEmail( const QString &s )
{
  mEmail = s;
}

void CreateImapAccount::enableSieve( bool b )
{
  mEnableSieve = b;
}

void CreateImapAccount::setSieveVacationFileName( const QString& f )
{
  mSieveVacationFileName = f;
}

void CreateImapAccount::enableSavePassword( bool b )
{
  mEnableSavePassword = b;
}

void CreateImapAccount::setEncryption(
  CreateImapAccount::Encryption e )
{
  mEncryption = e;
}

void CreateImapAccount::setAuthentication(
  CreateImapAccount::Authentication a )
{
  mAuthentication = a;
}

void CreateImapAccount::setDefaultDomain(const QString &d)
{
  mDefaultDomain = d;
}

void CreateImapAccount::setAuthenticationSend(
  CreateImapAccount::Authentication a )
{
  mAuthenticationSend = a;
}

void CreateImapAccount::setSmtpPort( int port )
{
  mSmtpPort = port;
}

void CreateImapAccount::setExistingAccountId( int id )
{
  mExistingAccountId = id;
}

void CreateImapAccount::setExistingTransportId( int id )
{
  mExistingTransportId = id;
}

void CreateImapAccount::setCustomWriter(
  CreateImapAccount::CustomWriter *writer )
{
  mCustomWriter = writer;
}

CreateDisconnectedImapAccount::CreateDisconnectedImapAccount(const QString & accountName) :
    CreateImapAccount( accountName, i18n("Create Disconnected IMAP Account for KMail") ),
    mLocalSubscription( false ), mGroupwareType( GroupwareKolab )
{
}

void CreateDisconnectedImapAccount::apply()
{
  if ( mEmail.isEmpty() ) mEmail = mUser + '@' + mServer;

  KConfig c( "kmailrc" );
  KConfigGroup group = c.group( "General" );
  group.writeEntry( "Default domain", mDefaultDomain );
  int accountId;
  if ( mExistingAccountId < 0 ) {
    uint accCnt = group.readEntry( "accounts", 0 );
    accountId = accCnt + 1;
    group.writeEntry( "accounts", accountId );
  } else {
    accountId = mExistingAccountId;
  }
  int transportId;
  if ( mExistingTransportId < 0 ) {
    uint transCnt = group.readEntry( "transports", 0 );
    transportId = transCnt + 1;
    group.writeEntry( "transports", transportId );
  } else {
    transportId = mExistingTransportId;
  }

  group = c.group( QString("Account %1").arg( accountId ) );
  int uid;
  if ( mExistingAccountId < 0 ) {
    uid = KRandom::random();
    group.writeEntry( "Folder", uid );
  } else {
    uid = group.readEntry( "Folder",0 );
  }
  group.writeEntry( "Id", uid );
  group.writeEntry( "Type", "cachedimap");
  switch ( mAuthentication ) {
    case NONE:
      group.writeEntry( "auth", "*" );
      break;
    case PLAIN:
      group.writeEntry( "auth", "PLAIN" );
      break;
    case LOGIN:
      group.writeEntry( "auth", "LOGIN" );
      break;
    case NTLM_SPA:
      group.writeEntry( "auth", "NTLM" );
      break;
    case GSSAPI:
      group.writeEntry( "auth", "GSSAPI" );
      break;
    case DIGEST_MD5:
      group.writeEntry( "auth", "DIGEST-MD5" );
      break;
    case CRAM_MD5:
      group.writeEntry( "auth", "CRAM-MD5" );
      break;
  }
  group.writeEntry( "Name", mAccountName );
  group.writeEntry( "host", mServer );
  group.writeEntry( "port", mPort );

  group.writeEntry( "groupwareType", (int)mGroupwareType );

  // in case the user wants to get rid of some groupware folders
  group.writeEntry( "locally-subscribed-folders", mLocalSubscription );

  group.writeEntry( "login", mUser );

  group.writeEntry( "sieve-support", mEnableSieve ? "true" : "false" );
  if ( !mSieveVacationFileName.isEmpty() )
    group.writeEntry( "sieve-vacation-filename", mSieveVacationFileName );

  if ( mEncryption == SSL ) {
    group.writeEntry( "use-ssl", true );
  } else if ( mEncryption == TLS ) {
    group.writeEntry( "use-tls", true );
  }

  if ( mEnableSavePassword ) {
    if ( !writeToWallet( "account", accountId ) ) {
      group.writeEntry( "pass", KStringHandler::obscure( mPassword ) );
      group.writeEntry( "store-passwd", true );
    }
  }

  group = c.group( QString("Folder-%1").arg( uid ) );
  group.writeEntry( "isOpen", true );

  if ( mEnableSavePassword ) {
    group.writeEntry( "pass", KStringHandler::obscure( mPassword ) );
    group.writeEntry( "store-passwd", true );
  }

  KConfig transport( "mailtransports" );
  group = transport.group( QString("Transport %1").arg( transportId ) );
  group.writeEntry( "name", mAccountName );
  group.writeEntry( "host", mServer );
  group.writeEntry( "type", "smtp" );
  group.writeEntry( "port", mSmtpPort );
  if ( mEncryption == SSL ) {
    group.writeEntry( "encryption", "SSL" );
  } else if ( mEncryption == TLS ) {
    group.writeEntry( "encryption", "TLS" );
  }
  group.writeEntry( "auth", true );
  if ( mAuthenticationSend == PLAIN ) {
    group.writeEntry( "authtype", "PLAIN" );
  } else if ( mAuthenticationSend == LOGIN ) {
    group.writeEntry( "authtype", "LOGIN" );
  }
  group.writeEntry( "id", transportId );
  group.writeEntry( "user", mUser );
  if ( mEnableSavePassword ) {
    if ( !writeToWallet( "transport", transportId ) ) {
      group.writeEntry( "pass", KStringHandler::obscure( mPassword ) );
      group.writeEntry( "storepass", true );
    }
  }

  // Write email in "default kcontrol settings", used by IdentityManager
  // if it has to create a default identity.
  KEMailSettings es;
  es.setSetting( KEMailSettings::RealName, mRealName );
  es.setSetting( KEMailSettings::EmailAddress, mEmail );

  KPIMIdentities::IdentityManager identityManager;
  if ( !identityManager.allEmails().contains( mEmail ) ) {
    // Not sure how to name the identity. First one is "Default", next one mAccountName, but then...
    // let's use the server name after that.
    QString accountName = mAccountName;
    const QStringList identities = identityManager.identities();
    if ( identities.contains( accountName )  ) {
      accountName = mServer;
      int i = 2;
      // And if there's already one, number them
      while ( identities.contains( accountName )  ) {
        accountName = mServer + ' ' + QString::number( i++ );
      }
    }

    KPIMIdentities::Identity& identity = identityManager.newFromScratch( accountName );
    identity.setFullName( mRealName );
    identity.setEmailAddr( mEmail );
    identityManager.commit();
  }

  if ( mCustomWriter ) {
    mCustomWriter->writeFolder( c, uid );
    mCustomWriter->writeIds( accountId, transportId );
  }
}

CreateOnlineImapAccount::CreateOnlineImapAccount(const QString & accountName) :
    CreateImapAccount( accountName, i18n("Create Online IMAP Account for KMail") )
{
}

void CreateOnlineImapAccount::apply()
{
  KConfig c( "kmailrc" );
  KConfigGroup group = c.group( "General" );
  uint accCnt = group.readEntry( "accounts", 0 );
  group.writeEntry( "accounts", accCnt+1 );

  group = c.group( QString("Account %1").arg(accCnt+1) );
  int uid = KRandom::random();
  group.writeEntry( "Folder", uid );
  group.writeEntry( "Id", uid );
  group.writeEntry( "Type", "imap" );
  group.writeEntry( "auth", "*" );
  group.writeEntry( "Name", mAccountName );
  group.writeEntry( "host", mServer );

  group.writeEntry( "login", mUser );

  if ( mEnableSavePassword ) {
    if ( !writeToWallet( "account", accCnt+1 ) ) {
      group.writeEntry( "pass", KStringHandler::obscure( mPassword ) );
      group.writeEntry( "store-passwd", true );
    }
  }
  group.writeEntry( "port", "993" );

  if ( mEncryption == SSL ) {
    group.writeEntry( "use-ssl", true );
  } else if ( mEncryption == TLS ) {
    group.writeEntry( "use-tls", true );
  }

  if ( mAuthenticationSend == PLAIN ) {
    group.writeEntry( "authtype", "PLAIN" );
  } else if ( mAuthenticationSend == LOGIN ) {
    group.writeEntry( "authtype", "LOGIN" );
  }

  group.writeEntry( "sieve-support", mEnableSieve );

  // locally unsubscribe the default folders
  group.writeEntry( "locally-subscribed-folders", true );
  QString groupwareFolders = QString("/INBOX/%1/,/INBOX/%2/,/INBOX/%3/,/INBOX/%4/,/INBOX/%5/")
      .arg( i18n(s_folderContentsType[0]) ).arg( i18n(s_folderContentsType[1]) )
      .arg( i18n(s_folderContentsType[2]) ).arg( i18n(s_folderContentsType[3]) )
      .arg( i18n(s_folderContentsType[4]) );
  group.writeEntry( "locallyUnsubscribedFolders", groupwareFolders );

  group = c.group( QString("Folder-%1").arg( uid ) );
  group.writeEntry( "isOpen", true );
}

bool CreateImapAccount::writeToWallet(const QString & type, int id)
{
  if ( !Wallet::isEnabled() )
    return false;
  if ( !mWallet || !mWallet->isOpen() ) {
    delete mWallet;
    WId window = 0;
    if ( qApp->activeWindow() )
      window = qApp->activeWindow()->winId();
    mWallet = Wallet::openWallet( Wallet::NetworkWallet(), window );
    if ( !mWallet )
      return false;
  }
  QString folder, str_id;
  if ( type=="transport" ) {
    folder = "mailtransports";
    str_id = QString::number( id );
  } else {
    folder = "kmail";
    str_id = type + '-' + QString::number( id );
  }
  if ( !mWallet->hasFolder( folder ) )
    mWallet->createFolder( folder );
  mWallet->setFolder( folder );
  return mWallet->writePassword( str_id, mPassword );
}
<commit_msg>Backport r840318 by wstephens to the 4.1 branch:<commit_after>/*
    This file is part of kdepim.

    Copyright (c) 2004 Bo Thorsen <bo@sonofthor.dk>
    Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "kmailchanges.h"

#include <kapplication.h>
#include <klocale.h>
#include <kconfiggroup.h>
#include <kstandarddirs.h>
#include <kemailsettings.h>
#include <kpimidentities/identitymanager.h>
#include <kpimidentities/identity.h>
#include <kdebug.h>
#include <kstringhandler.h>
#include <krandom.h>
#include <kwallet.h>
using namespace KWallet;

static const char* s_folderContentsType[] = {
  I18N_NOOP( "Calendar" ),
  I18N_NOOP( "Contacts" ),
  I18N_NOOP( "Notes" ),
  I18N_NOOP( "Tasks" ),
  I18N_NOOP( "Journal" ) };

Wallet* CreateImapAccount::mWallet = 0;

CreateImapAccount::CreateImapAccount( const QString &accountName, const QString &title )
  : KConfigPropagator::Change( title ),
    mAccountName( accountName ), mPort( 993 ), mEnableSieve( false ), mEnableSavePassword( true ),
    mEncryption( None ), mAuthentication( NONE ), mAuthenticationSend( PLAIN ), mSmtpPort( 25 ),
    mExistingAccountId( -1 ), mExistingTransportId( -1 ),
    mCustomWriter( 0 )
{
}

CreateImapAccount::~CreateImapAccount()
{
  delete mCustomWriter;
}

void CreateImapAccount::setServer( const QString &s )
{
  mServer = s;
}

void CreateImapAccount::setUser( const QString &s )
{
  mUser = s;
}

void CreateImapAccount::setPassword( const QString &s )
{
  mPassword = s;
}

void CreateImapAccount::setRealName( const QString &s )
{
  mRealName = s;
}

void CreateImapAccount::setPort( int port )
{
  mPort = port;
}

void CreateImapAccount::setEmail( const QString &s )
{
  mEmail = s;
}

void CreateImapAccount::enableSieve( bool b )
{
  mEnableSieve = b;
}

void CreateImapAccount::setSieveVacationFileName( const QString& f )
{
  mSieveVacationFileName = f;
}

void CreateImapAccount::enableSavePassword( bool b )
{
  mEnableSavePassword = b;
}

void CreateImapAccount::setEncryption(
  CreateImapAccount::Encryption e )
{
  mEncryption = e;
}

void CreateImapAccount::setAuthentication(
  CreateImapAccount::Authentication a )
{
  mAuthentication = a;
}

void CreateImapAccount::setDefaultDomain(const QString &d)
{
  mDefaultDomain = d;
}

void CreateImapAccount::setAuthenticationSend(
  CreateImapAccount::Authentication a )
{
  mAuthenticationSend = a;
}

void CreateImapAccount::setSmtpPort( int port )
{
  mSmtpPort = port;
}

void CreateImapAccount::setExistingAccountId( int id )
{
  mExistingAccountId = id;
}

void CreateImapAccount::setExistingTransportId( int id )
{
  mExistingTransportId = id;
}

void CreateImapAccount::setCustomWriter(
  CreateImapAccount::CustomWriter *writer )
{
  mCustomWriter = writer;
}

CreateDisconnectedImapAccount::CreateDisconnectedImapAccount(const QString & accountName) :
    CreateImapAccount( accountName, i18n("Create Disconnected IMAP Account for KMail") ),
    mLocalSubscription( false ), mGroupwareType( GroupwareKolab )
{
}

void CreateDisconnectedImapAccount::apply()
{
  if ( mEmail.isEmpty() ) mEmail = mUser + '@' + mServer;

  KConfig c( "kmailrc" );
  KConfigGroup group = c.group( "General" );
  group.writeEntry( "Default domain", mDefaultDomain );
  int accountId;
  if ( mExistingAccountId < 0 ) {
    uint accCnt = group.readEntry( "accounts", 0 );
    accountId = accCnt + 1;
    group.writeEntry( "accounts", accountId );
  } else {
    accountId = mExistingAccountId;
  }
  int transportId;
  if ( mExistingTransportId < 0 ) {
    uint transCnt = group.readEntry( "transports", 0 );
    transportId = transCnt + 1;
    group.writeEntry( "transports", transportId );
  } else {
    transportId = mExistingTransportId;
  }

  group = c.group( QString("Account %1").arg( accountId ) );
  int uid;
  if ( mExistingAccountId < 0 ) {
    uid = KRandom::random();
    group.writeEntry( "Folder", uid );
  } else {
    uid = group.readEntry( "Folder",0 );
  }
  group.writeEntry( "Id", uid );
  group.writeEntry( "Type", "DImap");
  switch ( mAuthentication ) {
    case NONE:
      group.writeEntry( "auth", "*" );
      break;
    case PLAIN:
      group.writeEntry( "auth", "PLAIN" );
      break;
    case LOGIN:
      group.writeEntry( "auth", "LOGIN" );
      break;
    case NTLM_SPA:
      group.writeEntry( "auth", "NTLM" );
      break;
    case GSSAPI:
      group.writeEntry( "auth", "GSSAPI" );
      break;
    case DIGEST_MD5:
      group.writeEntry( "auth", "DIGEST-MD5" );
      break;
    case CRAM_MD5:
      group.writeEntry( "auth", "CRAM-MD5" );
      break;
  }
  group.writeEntry( "Name", mAccountName );
  group.writeEntry( "host", mServer );
  group.writeEntry( "port", mPort );

  group.writeEntry( "groupwareType", (int)mGroupwareType );

  // in case the user wants to get rid of some groupware folders
  group.writeEntry( "locally-subscribed-folders", mLocalSubscription );

  group.writeEntry( "login", mUser );

  group.writeEntry( "sieve-support", mEnableSieve ? "true" : "false" );
  if ( !mSieveVacationFileName.isEmpty() )
    group.writeEntry( "sieve-vacation-filename", mSieveVacationFileName );

  if ( mEncryption == SSL ) {
    group.writeEntry( "use-ssl", true );
  } else if ( mEncryption == TLS ) {
    group.writeEntry( "use-tls", true );
  }

  if ( mEnableSavePassword ) {
    if ( !writeToWallet( "account", accountId ) ) {
      group.writeEntry( "pass", KStringHandler::obscure( mPassword ) );
      group.writeEntry( "store-passwd", true );
    }
  }

  group = c.group( QString("Folder-%1").arg( uid ) );
  group.writeEntry( "isOpen", true );

  if ( mEnableSavePassword ) {
    group.writeEntry( "pass", KStringHandler::obscure( mPassword ) );
    group.writeEntry( "store-passwd", true );
  }

  group = c.group( QLatin1String( "AccountWizard" ) );
  group.writeEntry( QLatin1String( "ShowOnStartup" ), false );

  KConfig transport( "mailtransports" );
  group = transport.group( QString("Transport %1").arg( transportId ) );
  group.writeEntry( "name", mAccountName );
  group.writeEntry( "host", mServer );
  group.writeEntry( "type", "smtp" );
  group.writeEntry( "port", mSmtpPort );
  if ( mEncryption == SSL ) {
    group.writeEntry( "encryption", "SSL" );
  } else if ( mEncryption == TLS ) {
    group.writeEntry( "encryption", "TLS" );
  }
  group.writeEntry( "auth", true );
  if ( mAuthenticationSend == PLAIN ) {
    group.writeEntry( "authtype", "PLAIN" );
  } else if ( mAuthenticationSend == LOGIN ) {
    group.writeEntry( "authtype", "LOGIN" );
  }
  group.writeEntry( "id", transportId );
  group.writeEntry( "user", mUser );
  if ( mEnableSavePassword ) {
    if ( !writeToWallet( "transport", transportId ) ) {
      group.writeEntry( "pass", KStringHandler::obscure( mPassword ) );
      group.writeEntry( "storepass", true );
    }
  }

  // Write email in "default kcontrol settings", used by IdentityManager
  // if it has to create a default identity.
  KEMailSettings es;
  es.setSetting( KEMailSettings::RealName, mRealName );
  es.setSetting( KEMailSettings::EmailAddress, mEmail );

  KPIMIdentities::IdentityManager identityManager;
  if ( !identityManager.allEmails().contains( mEmail ) ) {
    // Not sure how to name the identity. First one is "Default", next one mAccountName, but then...
    // let's use the server name after that.
    QString accountName = mAccountName;
    const QStringList identities = identityManager.identities();
    if ( identities.contains( accountName )  ) {
      accountName = mServer;
      int i = 2;
      // And if there's already one, number them
      while ( identities.contains( accountName )  ) {
        accountName = mServer + ' ' + QString::number( i++ );
      }
    }

    KPIMIdentities::Identity& identity = identityManager.newFromScratch( accountName );
    identity.setFullName( mRealName );
    identity.setEmailAddr( mEmail );
    identityManager.commit();
  }

  if ( mCustomWriter ) {
    mCustomWriter->writeFolder( c, uid );
    mCustomWriter->writeIds( accountId, transportId );
  }
}

CreateOnlineImapAccount::CreateOnlineImapAccount(const QString & accountName) :
    CreateImapAccount( accountName, i18n("Create Online IMAP Account for KMail") )
{
}

void CreateOnlineImapAccount::apply()
{
  KConfig c( "kmailrc" );
  KConfigGroup group = c.group( "General" );
  uint accCnt = group.readEntry( "accounts", 0 );
  group.writeEntry( "accounts", accCnt+1 );

  group = c.group( QString("Account %1").arg(accCnt+1) );
  int uid = KRandom::random();
  group.writeEntry( "Folder", uid );
  group.writeEntry( "Id", uid );
  group.writeEntry( "Type", "Imap" );
  group.writeEntry( "auth", "*" );
  group.writeEntry( "Name", mAccountName );
  group.writeEntry( "host", mServer );

  group.writeEntry( "login", mUser );

  if ( mEnableSavePassword ) {
    if ( !writeToWallet( "account", accCnt+1 ) ) {
      group.writeEntry( "pass", KStringHandler::obscure( mPassword ) );
      group.writeEntry( "store-passwd", true );
    }
  }
  group.writeEntry( "port", "993" );

  if ( mEncryption == SSL ) {
    group.writeEntry( "use-ssl", true );
  } else if ( mEncryption == TLS ) {
    group.writeEntry( "use-tls", true );
  }

  if ( mAuthenticationSend == PLAIN ) {
    group.writeEntry( "authtype", "PLAIN" );
  } else if ( mAuthenticationSend == LOGIN ) {
    group.writeEntry( "authtype", "LOGIN" );
  }

  group.writeEntry( "sieve-support", mEnableSieve );

  // locally unsubscribe the default folders
  group.writeEntry( "locally-subscribed-folders", true );
  QString groupwareFolders = QString("/INBOX/%1/,/INBOX/%2/,/INBOX/%3/,/INBOX/%4/,/INBOX/%5/")
      .arg( i18n(s_folderContentsType[0]) ).arg( i18n(s_folderContentsType[1]) )
      .arg( i18n(s_folderContentsType[2]) ).arg( i18n(s_folderContentsType[3]) )
      .arg( i18n(s_folderContentsType[4]) );
  group.writeEntry( "locallyUnsubscribedFolders", groupwareFolders );

  group = c.group( QString("Folder-%1").arg( uid ) );
  group.writeEntry( "isOpen", true );

  group = c.group( QLatin1String( "AccountWizard" ) );
  group.writeEntry( QLatin1String( "ShowOnStartup" ), false );
}

bool CreateImapAccount::writeToWallet(const QString & type, int id)
{
  if ( !Wallet::isEnabled() )
    return false;
  if ( !mWallet || !mWallet->isOpen() ) {
    delete mWallet;
    WId window = 0;
    if ( qApp->activeWindow() )
      window = qApp->activeWindow()->winId();
    mWallet = Wallet::openWallet( Wallet::NetworkWallet(), window );
    if ( !mWallet )
      return false;
  }
  QString folder, str_id;
  if ( type=="transport" ) {
    folder = "mailtransports";
    str_id = QString::number( id );
  } else {
    folder = "kmail";
    str_id = type + '-' + QString::number( id );
  }
  if ( !mWallet->hasFolder( folder ) )
    mWallet->createFolder( folder );
  mWallet->setFolder( folder );
  return mWallet->writePassword( str_id, mPassword );
}
<|endoftext|>


<commit_before>//  Natron
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "AnimatedCheckBox.h"

#include <QStyle>
CLANG_DIAG_OFF(unused-private-field)
// /opt/local/include/QtGui/qmime.h:119:10: warning: private field 'type' is not used [-Wunused-private-field]
#include <QMouseEvent>
CLANG_DIAG_ON(unused-private-field)

void AnimatedCheckBox::setAnimation(int i)
{
    animation = i;
    style()->unpolish(this);
    style()->polish(this);
}

void AnimatedCheckBox::setReadOnly(bool readOnly)
{
    this->readOnly = readOnly;
    style()->unpolish(this);
    style()->polish(this);
    repaint();
}

void AnimatedCheckBox::setDirty(bool b)
{
    dirty = b;
    style()->unpolish(this);
    style()->polish(this);
    repaint();
}

void AnimatedCheckBox::mousePressEvent(QMouseEvent* e)
{
    if (readOnly && e->buttons().testFlag(Qt::LeftButton)) {
        return;
    } else {
        QCheckBox::mousePressEvent(e);
    }
}<commit_msg>AnimatedCheckBox: use GuiMacros.h<commit_after>//  Natron
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "AnimatedCheckBox.h"

#include <QStyle>
CLANG_DIAG_OFF(unused-private-field)
// /opt/local/include/QtGui/qmime.h:119:10: warning: private field 'type' is not used [-Wunused-private-field]
#include <QMouseEvent>
CLANG_DIAG_ON(unused-private-field)

#include "Gui/GuiMacros.h"

void
AnimatedCheckBox::setAnimation(int i)
{
    animation = i;
    style()->unpolish(this);
    style()->polish(this);
}

void
AnimatedCheckBox::setReadOnly(bool readOnly)
{
    this->readOnly = readOnly;
    style()->unpolish(this);
    style()->polish(this);
    repaint();
}

void
AnimatedCheckBox::setDirty(bool b)
{
    dirty = b;
    style()->unpolish(this);
    style()->polish(this);
    repaint();
}

void
AnimatedCheckBox::mousePressEvent(QMouseEvent* e)
{
    if (readOnly && buttonIsLeft(e)) {
        return;
    } else {
        QCheckBox::mousePressEvent(e);
    }
}<|endoftext|>


<commit_before>#include "MainWindow.hpp"
#include "Task.hpp"
#include "AddTask.hpp"
#include "Category.hpp"
#include "TaskGoogle.hpp"
#include "TaskSync.hpp"

#include <Layout.h>
#include <LayoutBuilder.h>
#include <LayoutItem.h>

#define CATEGORY_ALL_ICON "MIME_DATABASE"

MainWindow::MainWindow()
	: BWindow(BRect(50,50,600+50,400+50),"HaikuToDo",B_TITLED_WINDOW,0)
{
	#ifdef BUILD_SQLITE
	manager=new TaskSQL();
	#else
	manager=new TaskFS();
	#endif
	//DOING TESTS WITH GOOGLE TASKS
	sync=new TaskGoogle();
	//sync->Login();
	//SEND MESSAGE WHEN LOADED
	//END DOING TESTS
	BView* main=new BView(Bounds(),"Main View",B_FOLLOW_ALL_SIDES,B_WILL_DRAW);
	main->SetViewColor(220,220,220);
	//BGroupLayout* grid=new BGroupLayout(B_HORIZONTAL);
	BGridLayout* grid=new BGridLayout();
	main->SetLayout(grid);

	/* Categories View */
	BGridLayout* categoriesLayout=new BGridLayout();
	grid->AddItem(categoriesLayout,0,0);

	taskAdd=new BButton("Add task","Add task",new BMessage(TASK_ADD));
	categoriesLayout->AddView(taskAdd,1,1,2,1);

	categories=new BListView("Categories list",B_SINGLE_SELECTION_LIST);
	categories->SetSelectionMessage(new BMessage(CHANGE_CATEGORY));

	BScrollView* scrollCategories=new BScrollView("Scroll categories"
		,categories, 0, false, true);
	categoriesLayout->AddView(scrollCategories,1,3,6,5);

	googleTasks=new BButton("Google Tasks","Google Tasks",new BMessage(LOGIN_GTASKS));
	categoriesLayout->AddView(googleTasks,1,8,2,1);

	categories->AddItem(new Category("ALL",CATEGORY_ALL_ICON));
	manager->LoadCategories(categories);

	categoriesLayout->SetInsets(10.0f,10.0f,10.0f,10.0f);

	/* List View */
	BGridLayout* listLayout=new BGridLayout();
	grid->AddItem(listLayout,1,0);

	taskRemove=new BButton("Remove task","Remove task",new BMessage(TASK_REMOVE));
	listLayout->AddView(taskRemove,1,1,2,1);

	tasklist=new BListView("Tasks list",B_SINGLE_SELECTION_LIST);
	tasklist->SetSelectionMessage(new BMessage(ITEM_SELECTED));

	BScrollView* scrollTasks=new BScrollView("Scroll tasks", tasklist,0
		,false, true);
	listLayout->AddView(scrollTasks,1,3,6,5);
	listLayout->SetInsets(0.0f,10.0f,0.0f, 10.0f);

	/* Task View */
	BGroupLayout* taskLayout=new BGroupLayout(B_VERTICAL);
	grid->AddItem(taskLayout,2,0);

	taskTitle=new BStringView("Task title","No task selected");

	BFont font;
	taskTitle->GetFont(&font);
	font.SetSize(20.0f);
	taskTitle->SetFont(&font,B_FONT_SIZE | B_FONT_FLAGS);

	taskLayout->AddView(taskTitle);//,1,1,6,2);

	taskDescription=new BTextView("Task description");
	taskDescription->MakeEditable(false);
	taskDescription->SetViewColor(220,220,220);
	taskLayout->AddView(taskDescription);//,1,4//,5,3);

	taskCompleted=new BCheckBox("Task completed","Finished",new BMessage(COMPLETED_TASK));
	taskLayout->AddView(taskCompleted);//,1,8,5,1);

	taskLayout->SetInsets(10.0f,10.0f,10.0f,10.0f);

	grid->SetMaxColumnWidth(0,300.0f);
	grid->SetMaxColumnWidth(1,300.0f);
	grid->SetMinColumnWidth(2,300.0f);

	AddChild(main);

	manager->LoadTasks("ALL",tasklist);
}

MainWindow::~MainWindow()
{

}

bool
MainWindow::QuitRequested()
{
	be_app_messenger.SendMessage(B_QUIT_REQUESTED);
	return BWindow::QuitRequested();
}

void
MainWindow::MessageReceived(BMessage* msg)
{
	switch(msg->what)
	{
		case ITEM_SELECTED:
		{
			int32 taskSelection=tasklist->CurrentSelection();
			if(taskSelection>=0)
			{
				Task* item=dynamic_cast<Task*>(tasklist->ItemAt(taskSelection));
				SetTitle(item->Text());
				taskTitle->SetText(item->Text());
				taskDescription->SetText(item->GetDetails());
				taskCompleted->SetValue(item->GetCompleted());
			}
			break;
		}
		case COMPLETED_TASK:
		{
			//ASK FOR REMOVE TASK
			int32 taskSelection=tasklist->CurrentSelection();
			if(taskSelection>=0)
			{
				Task* item=dynamic_cast<Task*>(tasklist->ItemAt(taskSelection));
				manager->MarkAsComplete(item->Text(),item->GetDetails(),item->GetCategory());
				PostMessage(new BMessage(RELOAD));
			}
			break;
		}
		case TASK_ADD:
		{
			AddTask* add=new AddTask(manager);
			add->Show();

			break;
		}
		case SYNC_CATEGORIES:
		{
			BList* cats=sync->GetCategories();
			categories->AddList(cats);
			break;
		}
		case LOGIN_GTASKS:
		{
			std::cout << "Login one time" << std::endl;
			sync->Login();
			break;
		}
		case RELOAD:
		{
			std::cout << "Reload started" << std::endl;
			tasklist->MakeEmpty();
			int32 selection=categories->CurrentSelection();
			if(selection>=0)
			{
				Category* item=dynamic_cast<Category*>(categories->ItemAt(selection));
				if(strcmp(item->GetID(),"NULL")==0)
				{
					manager->LoadTasks(item->GetName(),tasklist);
				}else{
					tasklist->AddList(sync->GetTasks(item));
				}

			}else{
				manager->LoadTasks("ALL",tasklist);
			}
			break;
		}
		case RELOAD_CATEGORIES:
		{
			categories->MakeEmpty();
			categories->AddItem(new Category("ALL",CATEGORY_ALL_ICON));
			manager->LoadCategories(categories);
			break;
		}
		case TASK_REMOVE:
		{
			int32 taskSelection=tasklist->CurrentSelection();
			if(taskSelection>=0)
			{
				Task* item=dynamic_cast<Task*>(tasklist->ItemAt(taskSelection));
				manager->RemoveTask(item->Text(),item->GetDetails(),item->GetCategory());
				PostMessage(new BMessage(RELOAD));
			}
			break;
		}
		case CHANGE_CATEGORY:
		{
			PostMessage(new BMessage(RELOAD));
		}
		default:
			BWindow::MessageReceived(msg);
	}
}
<commit_msg>Task title works on HDPI screens<commit_after>#include "MainWindow.hpp"
#include "Task.hpp"
#include "AddTask.hpp"
#include "Category.hpp"
#include "TaskGoogle.hpp"
#include "TaskSync.hpp"

#include <Layout.h>
#include <LayoutBuilder.h>
#include <LayoutItem.h>

#define CATEGORY_ALL_ICON "MIME_DATABASE"

MainWindow::MainWindow()
	: BWindow(BRect(50,50,600+50,400+50),"HaikuToDo",B_TITLED_WINDOW,0)
{
	#ifdef BUILD_SQLITE
	manager=new TaskSQL();
	#else
	manager=new TaskFS();
	#endif
	//DOING TESTS WITH GOOGLE TASKS
	sync=new TaskGoogle();
	//sync->Login();
	//SEND MESSAGE WHEN LOADED
	//END DOING TESTS
	BView* main=new BView(Bounds(),"Main View",B_FOLLOW_ALL_SIDES,B_WILL_DRAW);
	main->SetViewColor(220,220,220);
	//BGroupLayout* grid=new BGroupLayout(B_HORIZONTAL);
	BGridLayout* grid=new BGridLayout();
	main->SetLayout(grid);

	/* Categories View */
	BGridLayout* categoriesLayout=new BGridLayout();
	grid->AddItem(categoriesLayout,0,0);

	taskAdd=new BButton("Add task","Add task",new BMessage(TASK_ADD));
	categoriesLayout->AddView(taskAdd,1,1,2,1);

	categories=new BListView("Categories list",B_SINGLE_SELECTION_LIST);
	categories->SetSelectionMessage(new BMessage(CHANGE_CATEGORY));

	BScrollView* scrollCategories=new BScrollView("Scroll categories"
		,categories, 0, false, true);
	categoriesLayout->AddView(scrollCategories,1,3,6,5);

	googleTasks=new BButton("Google Tasks","Google Tasks",new BMessage(LOGIN_GTASKS));
	categoriesLayout->AddView(googleTasks,1,8,2,1);

	categories->AddItem(new Category("ALL",CATEGORY_ALL_ICON));
	manager->LoadCategories(categories);

	categoriesLayout->SetInsets(10.0f,10.0f,10.0f,10.0f);

	/* List View */
	BGridLayout* listLayout=new BGridLayout();
	grid->AddItem(listLayout,1,0);

	taskRemove=new BButton("Remove task","Remove task",new BMessage(TASK_REMOVE));
	listLayout->AddView(taskRemove,1,1,2,1);

	tasklist=new BListView("Tasks list",B_SINGLE_SELECTION_LIST);
	tasklist->SetSelectionMessage(new BMessage(ITEM_SELECTED));

	BScrollView* scrollTasks=new BScrollView("Scroll tasks", tasklist,0
		,false, true);
	listLayout->AddView(scrollTasks,1,3,6,5);
	listLayout->SetInsets(0.0f,10.0f,0.0f, 10.0f);

	/* Task View */
	BGroupLayout* taskLayout=new BGroupLayout(B_VERTICAL);
	grid->AddItem(taskLayout,2,0);

	taskTitle=new BStringView("Task title","No task selected");

	BFont font;
	taskTitle->GetFont(&font);
	font.SetSize(font.Size()*1.7);
	taskTitle->SetFont(&font,B_FONT_SIZE | B_FONT_FLAGS);

	taskLayout->AddView(taskTitle);//,1,1,6,2);

	taskDescription=new BTextView("Task description");
	taskDescription->MakeEditable(false);
	taskDescription->SetViewColor(220,220,220);
	taskLayout->AddView(taskDescription);//,1,4//,5,3);

	taskCompleted=new BCheckBox("Task completed","Finished",new BMessage(COMPLETED_TASK));
	taskLayout->AddView(taskCompleted);//,1,8,5,1);

	taskLayout->SetInsets(10.0f,10.0f,10.0f,10.0f);

	grid->SetMaxColumnWidth(0,300.0f);
	grid->SetMaxColumnWidth(1,300.0f);
	grid->SetMinColumnWidth(2,300.0f);

	AddChild(main);

	manager->LoadTasks("ALL",tasklist);
}

MainWindow::~MainWindow()
{

}

bool
MainWindow::QuitRequested()
{
	be_app_messenger.SendMessage(B_QUIT_REQUESTED);
	return BWindow::QuitRequested();
}

void
MainWindow::MessageReceived(BMessage* msg)
{
	switch(msg->what)
	{
		case ITEM_SELECTED:
		{
			int32 taskSelection=tasklist->CurrentSelection();
			if(taskSelection>=0)
			{
				Task* item=dynamic_cast<Task*>(tasklist->ItemAt(taskSelection));
				SetTitle(item->Text());
				taskTitle->SetText(item->Text());
				taskDescription->SetText(item->GetDetails());
				taskCompleted->SetValue(item->GetCompleted());
			}
			break;
		}
		case COMPLETED_TASK:
		{
			//ASK FOR REMOVE TASK
			int32 taskSelection=tasklist->CurrentSelection();
			if(taskSelection>=0)
			{
				Task* item=dynamic_cast<Task*>(tasklist->ItemAt(taskSelection));
				manager->MarkAsComplete(item->Text(),item->GetDetails(),item->GetCategory());
				PostMessage(new BMessage(RELOAD));
			}
			break;
		}
		case TASK_ADD:
		{
			AddTask* add=new AddTask(manager);
			add->Show();

			break;
		}
		case SYNC_CATEGORIES:
		{
			BList* cats=sync->GetCategories();
			categories->AddList(cats);
			break;
		}
		case LOGIN_GTASKS:
		{
			std::cout << "Login one time" << std::endl;
			sync->Login();
			break;
		}
		case RELOAD:
		{
			std::cout << "Reload started" << std::endl;
			tasklist->MakeEmpty();
			int32 selection=categories->CurrentSelection();
			if(selection>=0)
			{
				Category* item=dynamic_cast<Category*>(categories->ItemAt(selection));
				if(strcmp(item->GetID(),"NULL")==0)
				{
					manager->LoadTasks(item->GetName(),tasklist);
				}else{
					tasklist->AddList(sync->GetTasks(item));
				}

			}else{
				manager->LoadTasks("ALL",tasklist);
			}
			break;
		}
		case RELOAD_CATEGORIES:
		{
			categories->MakeEmpty();
			categories->AddItem(new Category("ALL",CATEGORY_ALL_ICON));
			manager->LoadCategories(categories);
			break;
		}
		case TASK_REMOVE:
		{
			int32 taskSelection=tasklist->CurrentSelection();
			if(taskSelection>=0)
			{
				Task* item=dynamic_cast<Task*>(tasklist->ItemAt(taskSelection));
				manager->RemoveTask(item->Text(),item->GetDetails(),item->GetCategory());
				PostMessage(new BMessage(RELOAD));
			}
			break;
		}
		case CHANGE_CATEGORY:
		{
			PostMessage(new BMessage(RELOAD));
		}
		default:
			BWindow::MessageReceived(msg);
	}
}
<|endoftext|>


<commit_before>/*
 *  Util.cpp
 *  Part of the QUantitative Image Toolbox
 *
 *  Copyright (c) 2015 Tobias Wood.
 *
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 */

#include "Util.h"
#include <iostream>

using namespace std;

namespace QI {

const std::string &OutExt() {
	static char *env_ext = getenv("QUIT_EXT");
	static string ext;
	static bool checked = false;
	if (!checked) {
		static map<string, string> valid_ext{
			{"NIFTI", ".nii"},
			{"NIFTI_PAIR", ".img"},
			{"NIFTI_GZ", ".nii.gz"},
			{"NIFTI_PAIR_GZ", ".img.gz"},
		};
		if (!env_ext || (valid_ext.find(env_ext) == valid_ext.end())) {
			cerr << "Environment variable QUIT_EXT is not valid, defaulting to NIFTI_GZ" << endl;
			ext = valid_ext["NIFTI_GZ"];
		} else {
			ext = valid_ext[env_ext];
		}
		checked = true;
	}
	return ext;
}

time_t printStartTime() {
	time_t theTime = time(NULL);
	char timeStr[256];
	strftime(timeStr, 256, "%H:%M:%S", localtime(&theTime));
	cout << "Started at " << timeStr << endl;
	return theTime;
}

time_t printElapsedTime(const time_t &startTime) {
    time_t theTime = time(NULL);
    char timeStr[256];
    strftime(timeStr, 512, "%H:%M:%S", localtime(&theTime));
    double elapsed = difftime(theTime, startTime);
	cout << "Finished at " << timeStr << ". Elapsed time was " << elapsed << " s." << endl;
	return theTime;
}

void printElapsedClock(const clock_t &startClock, const int voxCount) {
	clock_t endClock = clock();
	float totalMilliseconds = (endClock - startClock) * (1.e3 / CLOCKS_PER_SEC);
	cout << "Total CPU time: " << totalMilliseconds << " ms" << endl;
	cout << "Average voxel CPU time: " << totalMilliseconds / voxCount << " ms" << endl;
}

void printLoopTime(const clock_t &loopStart, const int voxCount) {
	clock_t loopEnd = clock();
	if (voxCount > 0) {
		cout << voxCount << " unmasked voxels, CPU time per voxel was "
		     << ((loopEnd - loopStart) / ((float)voxCount * CLOCKS_PER_SEC)) << " s" << endl;
	} else {
		cout << " no voxels." << endl;
	}
}

mt19937_64::result_type RandomSeed() {
	static random_device rd;
	static mt19937_64 rng;
	static bool init = false;
	mutex seed_mtx;
	if (!init) {
		rng = mt19937_64(rd());
	}
	seed_mtx.lock();
	mt19937_64::result_type r = rng();
	seed_mtx.unlock();
	return r;
}

/*void writeResult(const ImageF::Pointer img,
                 const string path) {
	auto file = WriteImageF::New();
	file->SetFileName(path);
	file->SetInput(img);
	file->Update();
}*/

void writeResiduals(const VectorImageF::Pointer img,
                    const string prefix,
                    const bool allResids) {
	auto magFilter = itk::VectorMagnitudeImageFilter<VectorImageF, ImageF>::New();
	auto magFile = WriteImageF::New();
	magFilter->SetInput(img);
	magFile->SetInput(magFilter->GetOutput());
	magFile->SetFileName(prefix + "residual.nii");
	magFile->Update();
	if (allResids) {
		auto to4D = QI::VectorToTimeseriesF::New();
		auto allFile = QI::WriteTimeseriesF::New();
		to4D->SetInput(img);
		allFile->SetInput(to4D->GetOutput());
		allFile->SetFileName(prefix + "residuals.nii");
		allFile->Update();
	}
}

} // End namespace QUIT
<commit_msg>Removed un-templated writeResults function.<commit_after>/*
 *  Util.cpp
 *  Part of the QUantitative Image Toolbox
 *
 *  Copyright (c) 2015 Tobias Wood.
 *
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 */

#include "Util.h"
#include <iostream>

using namespace std;

namespace QI {

const std::string &OutExt() {
	static char *env_ext = getenv("QUIT_EXT");
	static string ext;
	static bool checked = false;
	if (!checked) {
		static map<string, string> valid_ext{
			{"NIFTI", ".nii"},
			{"NIFTI_PAIR", ".img"},
			{"NIFTI_GZ", ".nii.gz"},
			{"NIFTI_PAIR_GZ", ".img.gz"},
		};
		if (!env_ext || (valid_ext.find(env_ext) == valid_ext.end())) {
			cerr << "Environment variable QUIT_EXT is not valid, defaulting to NIFTI_GZ" << endl;
			ext = valid_ext["NIFTI_GZ"];
		} else {
			ext = valid_ext[env_ext];
		}
		checked = true;
	}
	return ext;
}

time_t printStartTime() {
	time_t theTime = time(NULL);
	char timeStr[256];
	strftime(timeStr, 256, "%H:%M:%S", localtime(&theTime));
	cout << "Started at " << timeStr << endl;
	return theTime;
}

time_t printElapsedTime(const time_t &startTime) {
    time_t theTime = time(NULL);
    char timeStr[256];
    strftime(timeStr, 512, "%H:%M:%S", localtime(&theTime));
    double elapsed = difftime(theTime, startTime);
	cout << "Finished at " << timeStr << ". Elapsed time was " << elapsed << " s." << endl;
	return theTime;
}

void printElapsedClock(const clock_t &startClock, const int voxCount) {
	clock_t endClock = clock();
	float totalMilliseconds = (endClock - startClock) * (1.e3 / CLOCKS_PER_SEC);
	cout << "Total CPU time: " << totalMilliseconds << " ms" << endl;
	cout << "Average voxel CPU time: " << totalMilliseconds / voxCount << " ms" << endl;
}

void printLoopTime(const clock_t &loopStart, const int voxCount) {
	clock_t loopEnd = clock();
	if (voxCount > 0) {
		cout << voxCount << " unmasked voxels, CPU time per voxel was "
		     << ((loopEnd - loopStart) / ((float)voxCount * CLOCKS_PER_SEC)) << " s" << endl;
	} else {
		cout << " no voxels." << endl;
	}
}

mt19937_64::result_type RandomSeed() {
	static random_device rd;
	static mt19937_64 rng;
	static bool init = false;
	mutex seed_mtx;
	if (!init) {
		rng = mt19937_64(rd());
	}
	seed_mtx.lock();
	mt19937_64::result_type r = rng();
	seed_mtx.unlock();
	return r;
}

void writeResiduals(const VectorImageF::Pointer img,
                    const string prefix,
                    const bool allResids) {
	auto magFilter = itk::VectorMagnitudeImageFilter<VectorImageF, ImageF>::New();
	auto magFile = WriteImageF::New();
	magFilter->SetInput(img);
	magFile->SetInput(magFilter->GetOutput());
	magFile->SetFileName(prefix + "residual.nii");
	magFile->Update();
	if (allResids) {
		auto to4D = QI::VectorToTimeseriesF::New();
		auto allFile = QI::WriteTimeseriesF::New();
		to4D->SetInput(img);
		allFile->SetInput(to4D->GetOutput());
		allFile->SetFileName(prefix + "residuals.nii");
		allFile->Update();
	}
}

} // End namespace QUIT
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: addxmltostorageoptions.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-11-11 08:46:14 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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 library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef GCC
#pragma hdrstop
#endif

//_________________________________________________________________________________________________________________
//  includes
//_________________________________________________________________________________________________________________

#include "addxmltostorageoptions.hxx"

#ifndef _UTL_CONFIGMGR_HXX_
#include <unotools/configmgr.hxx>
#endif
#ifndef _UTL_CONFIGITEM_HXX_
#include <unotools/configitem.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _TOOLS_STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif

#include <rtl/logfile.hxx>
#include "itemholder1.hxx"

//_________________________________________________________________________________________________________________
//  namespaces
//_________________________________________________________________________________________________________________

using namespace ::utl;
using namespace ::rtl;
using namespace ::osl;
using namespace ::com::sun::star::uno;

//*****************************************************************************************************************
//  initialize static member
//  DON'T DO IT IN YOUR HEADER!
//  see definition for further informations
//*****************************************************************************************************************
SvtAddXMLToStorageOptions_Impl* SvtAddXMLToStorageOptions::m_pDataContainer = 0;
sal_Int32 SvtAddXMLToStorageOptions::m_nRefCount = 0;

//_________________________________________________________________________________________________________________
//  private declarations!
//_________________________________________________________________________________________________________________

class SvtAddXMLToStorageOptions_Impl : public ConfigItem
{
    //-------------------------------------------------------------------------------------------------------------
    //  public methods
    //-------------------------------------------------------------------------------------------------------------

    public:

        //---------------------------------------------------------------------------------------------------------
        //  constructor / destructor
        //---------------------------------------------------------------------------------------------------------

         SvtAddXMLToStorageOptions_Impl();

        //---------------------------------------------------------------------------------------------------------
        //  overloaded methods of baseclass
        //---------------------------------------------------------------------------------------------------------

        //---------------------------------------------------------------------------------------------------------
        //  public interface
        //---------------------------------------------------------------------------------------------------------

        /*-****************************************************************************************************//**
            @short      access method to get internal values
            @descr      These method give us a chance to regulate acces to ouer internal values.
                        It's not used in the moment - but it's possible for the feature!

            @seealso    -

            @param      -
            @return     -

            @onerror    -
        *//*-*****************************************************************************************************/

        sal_Bool IsWriter_Add_XML_to_Storage() const    { return bAddXmlToStg_Writer; }
        sal_Bool IsCalc_Add_XML_to_Storage() const      { return bAddXmlToStg_Calc; }
        sal_Bool IsImpress_Add_XML_to_Storage() const   { return bAddXmlToStg_Impress; }
        sal_Bool IsDraw_Add_XML_to_Storage() const      { return bAddXmlToStg_Draw; }

    //-------------------------------------------------------------------------------------------------------------
    //  private methods
    //-------------------------------------------------------------------------------------------------------------

    private:

        /*-****************************************************************************************************//**
            @short      return list of key names of ouer configuration management which represent oue module tree
            @descr      These methods return a static const list of key names. We need it to get needed values from our
                        configuration management.

            @seealso    -

            @param      -
            @return     A list of needed configuration keys is returned.

            @onerror    -
        *//*-*****************************************************************************************************/

        static Sequence< OUString > GetPropertyNames();

    //-------------------------------------------------------------------------------------------------------------
    //  private member
    //-------------------------------------------------------------------------------------------------------------

    private:

        sal_Bool bAddXmlToStg_Writer,
                 bAddXmlToStg_Calc,
                 bAddXmlToStg_Impress,
                 bAddXmlToStg_Draw;
};

//_________________________________________________________________________________________________________________
//  definitions
//_________________________________________________________________________________________________________________

//*****************************************************************************************************************
//  constructor
//*****************************************************************************************************************
SvtAddXMLToStorageOptions_Impl::SvtAddXMLToStorageOptions_Impl()
    // Init baseclasses first
    :   ConfigItem( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM(
                        "Office.Common/AddXMLToStorage"))),
    // Init member then.
    bAddXmlToStg_Writer( FALSE ),
    bAddXmlToStg_Calc( FALSE ),
    bAddXmlToStg_Impress( FALSE ),
    bAddXmlToStg_Draw( FALSE )
{
    // Use our static list of configuration keys to get his values.
    Sequence< OUString > seqNames = GetPropertyNames();
    Sequence< Any > seqValues = GetProperties( seqNames );

    // Copy values from list in right order to ouer internal member.
    sal_Int32 nPropertyCount = seqValues.getLength();
    const Any* pValue = seqValues.getConstArray();
    for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty, ++pValue )
        if( pValue->hasValue() )

            switch( nProperty )
            {
            case 0:
                *pValue >>= bAddXmlToStg_Writer;
                break;
            case 1:
                *pValue >>= bAddXmlToStg_Calc;
                break;
            case 2:
                *pValue >>= bAddXmlToStg_Impress;
                break;
            case 3:
                *pValue >>= bAddXmlToStg_Draw;
                break;
            }
}

//*****************************************************************************************************************
//  private method
//*****************************************************************************************************************
Sequence< OUString > SvtAddXMLToStorageOptions_Impl::GetPropertyNames()
{
    // Build static list of configuration key names.
    static const sal_Char* pProperties[] =
    {
        "Writer",
        "Calc",
        "Impress",
        "Draw"
    };

    const sal_uInt16 nCnt = sizeof(pProperties) / sizeof( pProperties[0] );
    Sequence<OUString> aNames( nCnt );
    OUString* pNames = aNames.getArray();
    for( sal_uInt16 n = 0; n < nCnt; ++n )
        pNames[ n ] = OUString::createFromAscii( pProperties[ n ] );
    return aNames;
}

//*****************************************************************************************************************
//  constructor
//*****************************************************************************************************************
SvtAddXMLToStorageOptions::SvtAddXMLToStorageOptions()
{
    // Global access, must be guarded (multithreading!).
    MutexGuard aGuard( GetOwnStaticMutex() );
    // Increase ouer refcount ...
    ++m_nRefCount;
    // ... and initialize ouer data container only if it not already exist!
    if( !m_pDataContainer )
    {
        RTL_LOGFILE_CONTEXT(aLog, "svtools (???) ::SvtAddXMLToStorageOptions_Impl::ctor()");
        m_pDataContainer = new SvtAddXMLToStorageOptions_Impl;

        ItemHolder1::holdConfigItem(E_ADDXMLTOSTORAGEOPTIONS);
   }
}

//*****************************************************************************************************************
//  destructor
//*****************************************************************************************************************
SvtAddXMLToStorageOptions::~SvtAddXMLToStorageOptions()
{
    // Global access, must be guarded (multithreading!)
    MutexGuard aGuard( GetOwnStaticMutex() );
    // Decrease ouer refcount.
    // If last instance was deleted ...
    // we must destroy ouer static data container!
    if( !--m_nRefCount )
        delete m_pDataContainer, m_pDataContainer = 0;
}

sal_Bool SvtAddXMLToStorageOptions::IsWriter_Add_XML_to_Storage() const
{
    MutexGuard aGuard( GetOwnStaticMutex() );
    return m_pDataContainer->IsWriter_Add_XML_to_Storage();
}
sal_Bool SvtAddXMLToStorageOptions::IsCalc_Add_XML_to_Storage() const
{
    MutexGuard aGuard( GetOwnStaticMutex() );
    return m_pDataContainer->IsCalc_Add_XML_to_Storage();
}
sal_Bool SvtAddXMLToStorageOptions::IsImpress_Add_XML_to_Storage() const
{
    MutexGuard aGuard( GetOwnStaticMutex() );
    return m_pDataContainer->IsImpress_Add_XML_to_Storage();
}
sal_Bool SvtAddXMLToStorageOptions::IsDraw_Add_XML_to_Storage() const
{
    MutexGuard aGuard( GetOwnStaticMutex() );
    return m_pDataContainer->IsDraw_Add_XML_to_Storage();
}

//*****************************************************************************************************************
//  private method
//*****************************************************************************************************************
Mutex& SvtAddXMLToStorageOptions::GetOwnStaticMutex()
{
    // Initialize static mutex only for one time!
    static Mutex* pMutex = NULL;
    // If these method first called (Mutex not already exist!) ...
    if( pMutex == NULL )
    {
        // ... we must create a new one. Protect follow code with the global mutex -
        // It must be - we create a static variable!
        MutexGuard aGuard( Mutex::getGlobalMutex() );
        // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
        if( pMutex == NULL )
        {
            // Create the new mutex and set it for return on static variable.
            static Mutex aMutex;
            pMutex = &aMutex;
        }
    }
    // Return new created or already existing mutex object.
    return *pMutex;
}
<commit_msg>INTEGRATION: CWS warnings01 (1.4.62); FILE MERGED 2006/01/25 19:37:51 sb 1.4.62.2: RESYNC: (1.4-1.5); FILE MERGED 2005/10/25 12:43:59 pl 1.4.62.1: #i55991# removed warnings for linux platform<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: addxmltostorageoptions.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 20:41:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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 library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef GCC
#pragma hdrstop
#endif

//_________________________________________________________________________________________________________________
//  includes
//_________________________________________________________________________________________________________________

#include "addxmltostorageoptions.hxx"

#ifndef _UTL_CONFIGMGR_HXX_
#include <unotools/configmgr.hxx>
#endif
#ifndef _UTL_CONFIGITEM_HXX_
#include <unotools/configitem.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _TOOLS_STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif

#include <rtl/logfile.hxx>
#include "itemholder1.hxx"

//_________________________________________________________________________________________________________________
//  namespaces
//_________________________________________________________________________________________________________________

using namespace ::utl;
using namespace ::rtl;
using namespace ::osl;
using namespace ::com::sun::star::uno;

//*****************************************************************************************************************
//  initialize static member
//  DON'T DO IT IN YOUR HEADER!
//  see definition for further informations
//*****************************************************************************************************************
SvtAddXMLToStorageOptions_Impl* SvtAddXMLToStorageOptions::m_pDataContainer = 0;
sal_Int32 SvtAddXMLToStorageOptions::m_nRefCount = 0;

//_________________________________________________________________________________________________________________
//  private declarations!
//_________________________________________________________________________________________________________________

class SvtAddXMLToStorageOptions_Impl : public ConfigItem
{
    //-------------------------------------------------------------------------------------------------------------
    //  public methods
    //-------------------------------------------------------------------------------------------------------------

    public:

        //---------------------------------------------------------------------------------------------------------
        //  constructor / destructor
        //---------------------------------------------------------------------------------------------------------

         SvtAddXMLToStorageOptions_Impl();

        //---------------------------------------------------------------------------------------------------------
        //  overloaded methods of baseclass
        //---------------------------------------------------------------------------------------------------------

        //---------------------------------------------------------------------------------------------------------
        //  public interface
        //---------------------------------------------------------------------------------------------------------

        /*-****************************************************************************************************//**
            @short      access method to get internal values
            @descr      These method give us a chance to regulate acces to ouer internal values.
                        It's not used in the moment - but it's possible for the feature!

            @seealso    -

            @param      -
            @return     -

            @onerror    -
        *//*-*****************************************************************************************************/

        sal_Bool IsWriter_Add_XML_to_Storage() const    { return bAddXmlToStg_Writer; }
        sal_Bool IsCalc_Add_XML_to_Storage() const      { return bAddXmlToStg_Calc; }
        sal_Bool IsImpress_Add_XML_to_Storage() const   { return bAddXmlToStg_Impress; }
        sal_Bool IsDraw_Add_XML_to_Storage() const      { return bAddXmlToStg_Draw; }

    //-------------------------------------------------------------------------------------------------------------
    //  private methods
    //-------------------------------------------------------------------------------------------------------------

    private:

        /*-****************************************************************************************************//**
            @short      return list of key names of ouer configuration management which represent oue module tree
            @descr      These methods return a static const list of key names. We need it to get needed values from our
                        configuration management.

            @seealso    -

            @param      -
            @return     A list of needed configuration keys is returned.

            @onerror    -
        *//*-*****************************************************************************************************/

        static Sequence< OUString > GetPropertyNames();

    //-------------------------------------------------------------------------------------------------------------
    //  private member
    //-------------------------------------------------------------------------------------------------------------

    private:

        sal_Bool bAddXmlToStg_Writer,
                 bAddXmlToStg_Calc,
                 bAddXmlToStg_Impress,
                 bAddXmlToStg_Draw;
};

//_________________________________________________________________________________________________________________
//  definitions
//_________________________________________________________________________________________________________________

//*****************************************************************************************************************
//  constructor
//*****************************************************************************************************************
SvtAddXMLToStorageOptions_Impl::SvtAddXMLToStorageOptions_Impl()
    // Init baseclasses first
    :   ConfigItem( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM(
                        "Office.Common/AddXMLToStorage"))),
    // Init member then.
    bAddXmlToStg_Writer( FALSE ),
    bAddXmlToStg_Calc( FALSE ),
    bAddXmlToStg_Impress( FALSE ),
    bAddXmlToStg_Draw( FALSE )
{
    // Use our static list of configuration keys to get his values.
    Sequence< OUString > seqNames = GetPropertyNames();
    Sequence< Any > seqValues = GetProperties( seqNames );

    // Copy values from list in right order to ouer internal member.
    sal_Int32 nPropertyCount = seqValues.getLength();
    const Any* pValue = seqValues.getConstArray();
    for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty, ++pValue )
        if( pValue->hasValue() )

            switch( nProperty )
            {
            case 0:
                *pValue >>= bAddXmlToStg_Writer;
                break;
            case 1:
                *pValue >>= bAddXmlToStg_Calc;
                break;
            case 2:
                *pValue >>= bAddXmlToStg_Impress;
                break;
            case 3:
                *pValue >>= bAddXmlToStg_Draw;
                break;
            }
}

//*****************************************************************************************************************
//  private method
//*****************************************************************************************************************
Sequence< OUString > SvtAddXMLToStorageOptions_Impl::GetPropertyNames()
{
    // Build static list of configuration key names.
    static const sal_Char* pProperties[] =
    {
        "Writer",
        "Calc",
        "Impress",
        "Draw"
    };

    const sal_uInt16 nCnt = sizeof(pProperties) / sizeof( pProperties[0] );
    Sequence<OUString> aNames( nCnt );
    OUString* pNames = aNames.getArray();
    for( sal_uInt16 n = 0; n < nCnt; ++n )
        pNames[ n ] = OUString::createFromAscii( pProperties[ n ] );
    return aNames;
}

//*****************************************************************************************************************
//  constructor
//*****************************************************************************************************************
SvtAddXMLToStorageOptions::SvtAddXMLToStorageOptions()
{
    // Global access, must be guarded (multithreading!).
    MutexGuard aGuard( GetOwnStaticMutex() );
    // Increase ouer refcount ...
    ++m_nRefCount;
    // ... and initialize ouer data container only if it not already exist!
    if( !m_pDataContainer )
    {
        RTL_LOGFILE_CONTEXT(aLog, "svtools ( ??? ) ::SvtAddXMLToStorageOptions_Impl::ctor()");
        m_pDataContainer = new SvtAddXMLToStorageOptions_Impl;

        ItemHolder1::holdConfigItem(E_ADDXMLTOSTORAGEOPTIONS);
   }
}

//*****************************************************************************************************************
//  destructor
//*****************************************************************************************************************
SvtAddXMLToStorageOptions::~SvtAddXMLToStorageOptions()
{
    // Global access, must be guarded (multithreading!)
    MutexGuard aGuard( GetOwnStaticMutex() );
    // Decrease ouer refcount.
    // If last instance was deleted ...
    // we must destroy ouer static data container!
    if( !--m_nRefCount )
        delete m_pDataContainer, m_pDataContainer = 0;
}

sal_Bool SvtAddXMLToStorageOptions::IsWriter_Add_XML_to_Storage() const
{
    MutexGuard aGuard( GetOwnStaticMutex() );
    return m_pDataContainer->IsWriter_Add_XML_to_Storage();
}
sal_Bool SvtAddXMLToStorageOptions::IsCalc_Add_XML_to_Storage() const
{
    MutexGuard aGuard( GetOwnStaticMutex() );
    return m_pDataContainer->IsCalc_Add_XML_to_Storage();
}
sal_Bool SvtAddXMLToStorageOptions::IsImpress_Add_XML_to_Storage() const
{
    MutexGuard aGuard( GetOwnStaticMutex() );
    return m_pDataContainer->IsImpress_Add_XML_to_Storage();
}
sal_Bool SvtAddXMLToStorageOptions::IsDraw_Add_XML_to_Storage() const
{
    MutexGuard aGuard( GetOwnStaticMutex() );
    return m_pDataContainer->IsDraw_Add_XML_to_Storage();
}

//*****************************************************************************************************************
//  private method
//*****************************************************************************************************************
Mutex& SvtAddXMLToStorageOptions::GetOwnStaticMutex()
{
    // Initialize static mutex only for one time!
    static Mutex* pMutex = NULL;
    // If these method first called (Mutex not already exist!) ...
    if( pMutex == NULL )
    {
        // ... we must create a new one. Protect follow code with the global mutex -
        // It must be - we create a static variable!
        MutexGuard aGuard( Mutex::getGlobalMutex() );
        // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
        if( pMutex == NULL )
        {
            // Create the new mutex and set it for return on static variable.
            static Mutex aMutex;
            pMutex = &aMutex;
        }
    }
    // Return new created or already existing mutex object.
    return *pMutex;
}
<|endoftext|>


<commit_before>/***********************************************************************************************************************
**
** Copyright (c) 2011, 2013 ETH Zurich
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
** following conditions are met:
**
**    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
**      disclaimer.
**    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
**      following disclaimer in the documentation and/or other materials provided with the distribution.
**    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
**      derived from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
***********************************************************************************************************************/

#include "SystemClipboard.h"
#include "FilePersistenceException.h"

#include "ModelBase/src/model/Model.h"
#include "ModelBase/src/nodes/Reference.h"
#include "ModelBase/src/persistence/PersistedNode.h"
#include "ModelBase/src/persistence/PersistedValue.h"

using namespace Model;

namespace FilePersistence {

static const QString CLIPBOARD_TAG = "clipboard";
const QString SystemClipboard::NULL_STRING = "____NULL____";

SystemClipboard::SystemClipboard() :
	xml(nullptr), numNodes_(0)
{
	readClipboard();
}

SystemClipboard::~SystemClipboard()
{
	SAFE_DELETE(xml);
}

// Methods from Persistent Store
void SystemClipboard::saveModel(::Model::Model* model, const QString &name)
{
	if (model->root())
	{
		SAFE_DELETE(xml);
		xml = new XMLModel();

		xml->beginSaveChildNode(CLIPBOARD_TAG);
		saveNode(model->root(), name, false);
		xml->endSaveChildNode();

		QApplication::clipboard()->setText(xml->documentText());

		SAFE_DELETE(xml);
		numNodes_ = 0;
	}
}

void SystemClipboard::saveStringValue(const QString &value)
{
	xml->saveStringValue(value);
}

void SystemClipboard::saveIntValue(int value)
{
	xml->saveIntValue(value);
}

void SystemClipboard::saveDoubleValue(double value)
{
	xml->saveDoubleValue(value);
}

void SystemClipboard::saveReferenceValue(const QString &name, const Node*)
{
	QString nameString = name.isNull() ? NULL_STRING : name;
	xml->saveStringValue(nameString);
}

void SystemClipboard::saveNode(const Node *node, const QString &name, bool)
{
	xml->beginSaveChildNode(node->typeName());
	xml->setName(name);
	xml->setPartialHint(false);

	node->save(*this);

	if ( !node->isFullyLoaded() )
	{
		// Persist sub nodes which have not been loaded. Each subnode has a unique name. If a node was previously
		// persisted and was not saved so far, we will read it back from the persistent store and store it again.

		// Get a list of sub nodes which have already been persisted.
		QStringList persistedChildren = xml->getChildrenNames();

		PersistedNode* persisted = node->model()->store()->loadCompleteNodeSubtree(node->model()->name(), node);

		if (!persisted) throw FilePersistenceException("Could not load node subtree from old persistent store.");
		PersistedValue< QList<PersistedNode*> >* composite = dynamic_cast<PersistedValue< QList<PersistedNode*> >* > (persisted);
		if (!composite) throw FilePersistenceException("Partial loading of Value-type nodes (string, int, double) is not supported.");

		for(int i = 0; i<composite->value().size(); ++i)
		{
			if (!persistedChildren.contains(composite->value()[i]->name())) saveNodeFromOldStore(composite->value()[i]);
		}

		SAFE_DELETE(persisted);
	}

	xml->endSaveChildNode();
}

void SystemClipboard::saveNodeFromOldStore(PersistedNode* node)
{
	xml->beginSaveChildNode( node->type() );
	xml->setName(node->name());
	xml->setPartialHint( false );

	PersistedValue< QString >* string =  dynamic_cast< PersistedValue< QString >* > (node);
	if (string) xml->saveStringValue(string->value());
	else
	{
		PersistedValue< int >* integer =  dynamic_cast< PersistedValue< int >* > (node);
		if (integer) xml->saveIntValue( integer->value() );
		else
		{
			PersistedValue< double >* dbl =  dynamic_cast< PersistedValue< double >* > (node);
			if (dbl) xml->saveDoubleValue(dbl->value());
			else
			{
				PersistedValue< QList<PersistedNode*> >* composite =  dynamic_cast< PersistedValue< QList<PersistedNode*> >* > (node);
				if (composite)
				{
					for (int i = 0; i< composite->value().size(); ++i) saveNodeFromOldStore(composite->value()[i]);
				}
				else throw FilePersistenceException("Unknown PersistedNode type.");
			}
		}
	}

	xml->endSaveChildNode();
}

Node* SystemClipboard::loadModel(::Model::Model*, const QString &)
{
	throw FilePersistenceException("The clipboard does not support the loadModel() method.");
}

QList<LoadedNode> SystemClipboard::loadAllSubNodes(Node*)
{
	QList<LoadedNode> result;

	if ( xml->hasChildren() )
	{
		xml->goToFirstChild();
		while ( true )
		{
			LoadedNode ln = loadNode(nullptr);
			result.append(ln);
			if ( xml->hasNext() ) xml->loadNext();
			else break;
		}
		xml->goToParent();
	}

	return result;
}

Node* SystemClipboard::loadSubNode(Node* parent, const QString& name)
{
	if (!xml->hasChild(name)) return nullptr;

	xml->beginLoadChildNode(name);
	LoadedNode ln = loadNode(parent);
	xml->endLoadChildNode();

	return ln.node;
}

LoadedNode SystemClipboard::loadNode(Node* parent)
{
	LoadedNode node;
	node.name = xml->getName();
	node.node = Node::createNewNode(xml->getType(), parent, *this, false);

	return node;
}

QString SystemClipboard::currentNodeType() const
{
	return xml->getType();
}

QList<LoadedNode> SystemClipboard::loadPartialNode(Node*)
{
	throw FilePersistenceException("The loadPartialNode(...) method is not supported in the SystemClipboard store. This might indicate that an object only partially loaded itself, ignoring the provided partial hint.");
}

PersistedNode* SystemClipboard::loadCompleteNodeSubtree(const QString&, const Node*)
{
	throw FilePersistenceException("The loadCompleteNodeSubtree(...) method is not supported in the SystemClipboard store. This might indicate that an object only partially loaded itself, ignoring the provided partial hint.");
}

int SystemClipboard::loadIntValue()
{
	return xml->loadIntValue();
}

QString SystemClipboard::loadStringValue()
{
	return xml->loadStringValue();
}

double SystemClipboard::loadDoubleValue()
{
	return xml->loadDoubleValue();
}

QString SystemClipboard::loadReferenceValue(Reference*)
{
	QString name = xml->loadStringValue();
	if (name == NULL_STRING) name = QString();

	return name;
}

// Methods from ClipboardStore
void SystemClipboard::putNode(const Node* node)
{
	QList<const Node*> nodes;
	nodes.append(node);
	putNodes(nodes);
}

void SystemClipboard::putNodes(const QList<const Node*>& nodes)
{
	if (nodes.size() > 0)
	{
		SAFE_DELETE(xml);
		xml = new XMLModel();
		xml->beginSaveChildNode(CLIPBOARD_TAG);

		for(int i = 0; i<nodes.size(); ++i)
		{
			xml->beginSaveChildNode(nodes[i]->typeName());
			xml->setName(QString::number(i));
			xml->setPartialHint(false);

			nodes[i]->save(*this);

			xml->endSaveChildNode();
		}

		xml->endSaveChildNode();
		QApplication::clipboard()->setText(xml->documentText());

		SAFE_DELETE(xml);
		numNodes_ = 0;
	}
}

bool SystemClipboard::readClipboard()
{
	numNodes_ = 0;
	SAFE_DELETE(xml);

	bool clipboardContainsEnvisionData = false;
	if (!QApplication::clipboard()->text().isEmpty())
	{
		bool oldAssertOnThrow = FilePersistenceException::assertOnThrow();
		FilePersistenceException::assertOnThrow() = false;
		try
		{
			xml = new XMLModel();
			xml->setDocumentText(QApplication::clipboard()->text());
			xml->goToRoot();
			numNodes_ = xml->getChildrenNames().size();
			xml->goToFirstChild();
			clipboardContainsEnvisionData = true;
		}
		catch (FilePersistenceException&)
		{
			SAFE_DELETE(xml);
			clipboardContainsEnvisionData = false;
		}
		FilePersistenceException::assertOnThrow() = oldAssertOnThrow;
	}

	return clipboardContainsEnvisionData && numNodes_ > 0;
}

int SystemClipboard::numNodes() const
{
	return numNodes_;
}

bool SystemClipboard::hasNext() const
{
	return xml->hasNext();
}

void SystemClipboard::next()
{
	if (xml->hasNext()) xml->loadNext();
	else throw FilePersistenceException("Could not find next clipboard element.");
}

Node* SystemClipboard::create(::Model::Model*, Node* parent)
{
	Node* node = Node::createNewNode(xml->getType(), parent, *this, false);
	return node;
}

}
<commit_msg>Fix a bug with copy-pasting resolved references<commit_after>/***********************************************************************************************************************
**
** Copyright (c) 2011, 2013 ETH Zurich
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
** following conditions are met:
**
**    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
**      disclaimer.
**    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
**      following disclaimer in the documentation and/or other materials provided with the distribution.
**    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
**      derived from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
***********************************************************************************************************************/

#include "SystemClipboard.h"
#include "FilePersistenceException.h"

#include "ModelBase/src/model/Model.h"
#include "ModelBase/src/nodes/Reference.h"
#include "ModelBase/src/persistence/PersistedNode.h"
#include "ModelBase/src/persistence/PersistedValue.h"

using namespace Model;

namespace FilePersistence {

static const QString CLIPBOARD_TAG = "clipboard";
const QString SystemClipboard::NULL_STRING = "____NULL____";

SystemClipboard::SystemClipboard() :
	xml(nullptr), numNodes_(0)
{
	readClipboard();
}

SystemClipboard::~SystemClipboard()
{
	SAFE_DELETE(xml);
}

// Methods from Persistent Store
void SystemClipboard::saveModel(::Model::Model* model, const QString &name)
{
	if (model->root())
	{
		SAFE_DELETE(xml);
		xml = new XMLModel();

		xml->beginSaveChildNode(CLIPBOARD_TAG);
		saveNode(model->root(), name, false);
		xml->endSaveChildNode();

		QApplication::clipboard()->setText(xml->documentText());

		SAFE_DELETE(xml);
		numNodes_ = 0;
	}
}

void SystemClipboard::saveStringValue(const QString &value)
{
	xml->saveStringValue(value);
}

void SystemClipboard::saveIntValue(int value)
{
	xml->saveIntValue(value);
}

void SystemClipboard::saveDoubleValue(double value)
{
	xml->saveDoubleValue(value);
}

void SystemClipboard::saveReferenceValue(const QString &name, const Node* target)
{
	QString nameString = name.isNull() ? (target && target->definesSymbol() ? target->symbolName() : NULL_STRING) : name;
	xml->saveStringValue(nameString);
}

void SystemClipboard::saveNode(const Node *node, const QString &name, bool)
{
	xml->beginSaveChildNode(node->typeName());
	xml->setName(name);
	xml->setPartialHint(false);

	node->save(*this);

	if ( !node->isFullyLoaded() )
	{
		// Persist sub nodes which have not been loaded. Each subnode has a unique name. If a node was previously
		// persisted and was not saved so far, we will read it back from the persistent store and store it again.

		// Get a list of sub nodes which have already been persisted.
		QStringList persistedChildren = xml->getChildrenNames();

		PersistedNode* persisted = node->model()->store()->loadCompleteNodeSubtree(node->model()->name(), node);

		if (!persisted) throw FilePersistenceException("Could not load node subtree from old persistent store.");
		PersistedValue< QList<PersistedNode*> >* composite = dynamic_cast<PersistedValue< QList<PersistedNode*> >* > (persisted);
		if (!composite) throw FilePersistenceException("Partial loading of Value-type nodes (string, int, double) is not supported.");

		for(int i = 0; i<composite->value().size(); ++i)
		{
			if (!persistedChildren.contains(composite->value()[i]->name())) saveNodeFromOldStore(composite->value()[i]);
		}

		SAFE_DELETE(persisted);
	}

	xml->endSaveChildNode();
}

void SystemClipboard::saveNodeFromOldStore(PersistedNode* node)
{
	xml->beginSaveChildNode( node->type() );
	xml->setName(node->name());
	xml->setPartialHint( false );

	PersistedValue< QString >* string =  dynamic_cast< PersistedValue< QString >* > (node);
	if (string) xml->saveStringValue(string->value());
	else
	{
		PersistedValue< int >* integer =  dynamic_cast< PersistedValue< int >* > (node);
		if (integer) xml->saveIntValue( integer->value() );
		else
		{
			PersistedValue< double >* dbl =  dynamic_cast< PersistedValue< double >* > (node);
			if (dbl) xml->saveDoubleValue(dbl->value());
			else
			{
				PersistedValue< QList<PersistedNode*> >* composite =  dynamic_cast< PersistedValue< QList<PersistedNode*> >* > (node);
				if (composite)
				{
					for (int i = 0; i< composite->value().size(); ++i) saveNodeFromOldStore(composite->value()[i]);
				}
				else throw FilePersistenceException("Unknown PersistedNode type.");
			}
		}
	}

	xml->endSaveChildNode();
}

Node* SystemClipboard::loadModel(::Model::Model*, const QString &)
{
	throw FilePersistenceException("The clipboard does not support the loadModel() method.");
}

QList<LoadedNode> SystemClipboard::loadAllSubNodes(Node*)
{
	QList<LoadedNode> result;

	if ( xml->hasChildren() )
	{
		xml->goToFirstChild();
		while ( true )
		{
			LoadedNode ln = loadNode(nullptr);
			result.append(ln);
			if ( xml->hasNext() ) xml->loadNext();
			else break;
		}
		xml->goToParent();
	}

	return result;
}

Node* SystemClipboard::loadSubNode(Node* parent, const QString& name)
{
	if (!xml->hasChild(name)) return nullptr;

	xml->beginLoadChildNode(name);
	LoadedNode ln = loadNode(parent);
	xml->endLoadChildNode();

	return ln.node;
}

LoadedNode SystemClipboard::loadNode(Node* parent)
{
	LoadedNode node;
	node.name = xml->getName();
	node.node = Node::createNewNode(xml->getType(), parent, *this, false);

	return node;
}

QString SystemClipboard::currentNodeType() const
{
	return xml->getType();
}

QList<LoadedNode> SystemClipboard::loadPartialNode(Node*)
{
	throw FilePersistenceException("The loadPartialNode(...) method is not supported in the SystemClipboard store. This might indicate that an object only partially loaded itself, ignoring the provided partial hint.");
}

PersistedNode* SystemClipboard::loadCompleteNodeSubtree(const QString&, const Node*)
{
	throw FilePersistenceException("The loadCompleteNodeSubtree(...) method is not supported in the SystemClipboard store. This might indicate that an object only partially loaded itself, ignoring the provided partial hint.");
}

int SystemClipboard::loadIntValue()
{
	return xml->loadIntValue();
}

QString SystemClipboard::loadStringValue()
{
	return xml->loadStringValue();
}

double SystemClipboard::loadDoubleValue()
{
	return xml->loadDoubleValue();
}

QString SystemClipboard::loadReferenceValue(Reference*)
{
	QString name = xml->loadStringValue();
	if (name == NULL_STRING) name = QString();

	return name;
}

// Methods from ClipboardStore
void SystemClipboard::putNode(const Node* node)
{
	QList<const Node*> nodes;
	nodes.append(node);
	putNodes(nodes);
}

void SystemClipboard::putNodes(const QList<const Node*>& nodes)
{
	if (nodes.size() > 0)
	{
		SAFE_DELETE(xml);
		xml = new XMLModel();
		xml->beginSaveChildNode(CLIPBOARD_TAG);

		for(int i = 0; i<nodes.size(); ++i)
		{
			xml->beginSaveChildNode(nodes[i]->typeName());
			xml->setName(QString::number(i));
			xml->setPartialHint(false);

			nodes[i]->save(*this);

			xml->endSaveChildNode();
		}

		xml->endSaveChildNode();
		QApplication::clipboard()->setText(xml->documentText());

		SAFE_DELETE(xml);
		numNodes_ = 0;
	}
}

bool SystemClipboard::readClipboard()
{
	numNodes_ = 0;
	SAFE_DELETE(xml);

	bool clipboardContainsEnvisionData = false;
	if (!QApplication::clipboard()->text().isEmpty())
	{
		bool oldAssertOnThrow = FilePersistenceException::assertOnThrow();
		FilePersistenceException::assertOnThrow() = false;
		try
		{
			xml = new XMLModel();
			xml->setDocumentText(QApplication::clipboard()->text());
			xml->goToRoot();
			numNodes_ = xml->getChildrenNames().size();
			xml->goToFirstChild();
			clipboardContainsEnvisionData = true;
		}
		catch (FilePersistenceException&)
		{
			SAFE_DELETE(xml);
			clipboardContainsEnvisionData = false;
		}
		FilePersistenceException::assertOnThrow() = oldAssertOnThrow;
	}

	return clipboardContainsEnvisionData && numNodes_ > 0;
}

int SystemClipboard::numNodes() const
{
	return numNodes_;
}

bool SystemClipboard::hasNext() const
{
	return xml->hasNext();
}

void SystemClipboard::next()
{
	if (xml->hasNext()) xml->loadNext();
	else throw FilePersistenceException("Could not find next clipboard element.");
}

Node* SystemClipboard::create(::Model::Model*, Node* parent)
{
	Node* node = Node::createNewNode(xml->getType(), parent, *this, false);
	return node;
}

}
<|endoftext|>


<commit_before><commit_msg>Strcpy fix.<commit_after><|endoftext|>