Пример #1
0
UnicodeString&
CalendarTimeZoneTest::dateToString(UDate d, UnicodeString& str,
                                   const TimeZone& tz)
{
    str.remove();
    DateFormat* format = getDateFormat();
    if (format == 0)
    {
        str += "DATE_FORMAT_FAILURE";
        return str;
    }
    TimeZone* save = format->getTimeZone().clone();
    format->setTimeZone(tz);
    format->format(d, str);
    format->adoptTimeZone(save);
    releaseDateFormat(format);
    return str;
}
Пример #2
0
DivePlannerWidget::DivePlannerWidget(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f)
{
	ui.setupUi(this);
	ui.dateEdit->setDisplayFormat(getDateFormat());
	ui.tableWidget->setTitle(tr("Dive planner points"));
	ui.tableWidget->setModel(plannerModel);
	plannerModel->setRecalc(true);
	ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::GAS, new AirTypesDelegate(this));
	ui.cylinderTableWidget->setTitle(tr("Available gases"));
	ui.cylinderTableWidget->setModel(CylindersModel::instance());
	QTableView *view = ui.cylinderTableWidget->view();
	view->setColumnHidden(CylindersModel::START, true);
	view->setColumnHidden(CylindersModel::END, true);
	view->setColumnHidden(CylindersModel::DEPTH, false);
	view->setItemDelegateForColumn(CylindersModel::TYPE, new TankInfoDelegate(this));
	connect(ui.cylinderTableWidget, SIGNAL(addButtonClicked()), plannerModel, SLOT(addCylinder_clicked()));
	connect(ui.tableWidget, SIGNAL(addButtonClicked()), plannerModel, SLOT(addStop()));

	connect(CylindersModel::instance(), SIGNAL(dataChanged(QModelIndex, QModelIndex)),
		GasSelectionModel::instance(), SLOT(repopulate()));
	connect(CylindersModel::instance(), SIGNAL(rowsInserted(QModelIndex, int, int)),
		GasSelectionModel::instance(), SLOT(repopulate()));
	connect(CylindersModel::instance(), SIGNAL(rowsRemoved(QModelIndex, int, int)),
		GasSelectionModel::instance(), SLOT(repopulate()));
	connect(CylindersModel::instance(), SIGNAL(dataChanged(QModelIndex, QModelIndex)),
		plannerModel, SIGNAL(cylinderModelEdited()));
	connect(CylindersModel::instance(), SIGNAL(rowsInserted(QModelIndex, int, int)),
		plannerModel, SIGNAL(cylinderModelEdited()));
	connect(CylindersModel::instance(), SIGNAL(rowsRemoved(QModelIndex, int, int)),
		plannerModel, SIGNAL(cylinderModelEdited()));
	connect(plannerModel, SIGNAL(calculatedPlanNotes()), MainWindow::instance(), SLOT(setPlanNotes()));


	ui.tableWidget->setBtnToolTip(tr("Add dive data point"));
	connect(ui.startTime, SIGNAL(timeChanged(QTime)), plannerModel, SLOT(setStartTime(QTime)));
	connect(ui.dateEdit, SIGNAL(dateChanged(QDate)), plannerModel, SLOT(setStartDate(QDate)));
	connect(ui.ATMPressure, SIGNAL(valueChanged(int)), this, SLOT(atmPressureChanged(int)));
	connect(ui.atmHeight, SIGNAL(valueChanged(int)), this, SLOT(heightChanged(int)));
	connect(ui.salinity, SIGNAL(valueChanged(double)), this, SLOT(salinityChanged(double)));
	connect(plannerModel, SIGNAL(startTimeChanged(QDateTime)), this, SLOT(setupStartTime(QDateTime)));

	// Creating (and canceling) the plan
	replanButton = ui.buttonBox->addButton(tr("Save new"), QDialogButtonBox::ActionRole);
	connect(replanButton, SIGNAL(clicked()), plannerModel, SLOT(saveDuplicatePlan()));
	connect(ui.buttonBox, SIGNAL(accepted()), plannerModel, SLOT(savePlan()));
	connect(ui.buttonBox, SIGNAL(rejected()), plannerModel, SLOT(cancelPlan()));
	QShortcut *closeKey = new QShortcut(QKeySequence(Qt::Key_Escape), this);
	connect(closeKey, SIGNAL(activated()), plannerModel, SLOT(cancelPlan()));

	// This makes shure the spinbox gets a setMinimum(0) on it so we can't have negative time or depth.
	ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::DEPTH, new SpinBoxDelegate(0, INT_MAX, 1, this));
	ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::RUNTIME, new SpinBoxDelegate(0, INT_MAX, 1, this));
	ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::DURATION, new SpinBoxDelegate(0, INT_MAX, 1, this));
	ui.tableWidget->view()->setItemDelegateForColumn(DivePlannerPointsModel::CCSETPOINT, new DoubleSpinBoxDelegate(0, 2, 0.1, this));

	/* set defaults. */
	ui.ATMPressure->setValue(1013);
	ui.atmHeight->setValue(0);

	setMinimumWidth(0);
	setMinimumHeight(0);
}
Пример #3
0
void LocalePreferences::saveValues() {
    int date = getDateFormat();
    int time = getTimeFormat();

    global.settings->beginGroup("Locale");
    global.settings->setValue("dateFormat", date);
    global.settings->setValue("timeFormat", time);
    global.settings->endGroup();

    datefmt = "MM/dd/yy";
    switch (date) {
    case MMddyy:
        datefmt = "MM/dd/yy";
        break;
    case MMddyyyy:
        datefmt = "MM/dd/yyyy";
        break;
    case Mddyyyy:
        datefmt = "M/dd/yyyy";
        break;
    case Mdyyyy:
        datefmt = "M/d/yyyy";
        break;
    case ddMMyy:
        datefmt = "dd/MM/yy";
        break;
    case dMyy:
        datefmt = "d/M/yy";
        break;
    case ddMMyyyy:
        datefmt = "dd/MM/yyyy";
        break;
    case dMyyyy:
        datefmt = "d/M/yyyy";
        break;
    case yyyyMMdd:
        datefmt = "yyyy-MM-dd";
        break;
    case yyMMdd:
        datefmt = "yy-MM-dd";
        break;
    }

    timefmt = "HH:mm:ss";
    switch (time) {
    case HHmmss:
        timefmt = "HH:mm:ss";
        break;
    case HHmmssa:
        timefmt = "HH:MM:SS a";
        break;
    case HHmm:
        timefmt = "HH:mm";
        break;
    case HHmma:
        timefmt = "HH:mm a";
        break;
    case hhmmss:
        timefmt = "hh:mm:ss";
        break;
    case hhmmssa:
        timefmt = "hh:mm:ss a";
        break;
    case hhmm:
        timefmt = "hh:mm";
        break;
    case hhmma:
        timefmt = "hh:mm a";
        break;
    case hmma:
        timefmt = "h:mm a";
        break;
    case hmmssa:
        timefmt = "h:mm:ss a";
        break;
    }
    global.dateFormat = datefmt;
    global.timeFormat = timefmt;
}
Пример #4
0
// ================
//    PUBLIC SLOTS
// ================
void DirWidget::LoadDir(QString dir, QList<LFileInfo> list){
  if(dir.isEmpty()){ return; } //nothing to do
  QTime time;
  if(DEBUG){time.start(); }
  qDebug() << "Load Dir:" << dir;
  QString lastdir = CDIR; //for some checks later
  QString lastbasedir = normalbasedir;
  CDIR = dir;
  if(CDIR.endsWith("/") && CDIR.length() > 1){ CDIR.chop(1); }
  CLIST = list; //save for later
  canmodify = QFileInfo(CDIR).isWritable();
  if(DEBUG){ qDebug() << "Clear UI:" <<time.elapsed(); }
  //Clear the status text
  if(!canmodify){ui->label_status->setText(tr("(Limited Access) ")); }
  else{ ui->label_status->setText(""); }
  //Hide the extra buttons for a moment
  ui->tool_goToPlayer->setVisible(false);
  ui->tool_goToImages->setVisible(false);
  ui->tool_new_dir->setVisible(canmodify);
  ui->tool_new_file->setVisible(canmodify);
  //Set the drag/drop info as appripriate
  if(canmodify){
    listWidget->setWhatsThis(CDIR);
    treeWidget->setWhatsThis(CDIR);
  }else{
    listWidget->setWhatsThis("");
    treeWidget->setWhatsThis("");
  }
  bool updateThumbs = (lastdir != CDIR);
  //Determine if this is an internal ZFS snapshot
  bool loadsnaps = false;
  if(DEBUG){ qDebug() << "Load Snap Info:" << time.elapsed(); }
  if( dir.contains(ZSNAPDIR) ){
    //This is a zfs snapshot - only update the saved paths necessary to rotate between snapshots/system
    snaprelpath = dir.section(ZSNAPDIR,1,1000).section("/",1,1000); //the relative path inside the snapshot
    if(snaprelpath.endsWith("/")){ snaprelpath.chop(1); }
    normalbasedir = dir.section(ZSNAPDIR,0,0)+"/"+snaprelpath; //Update the new base directory
    if(normalbasedir.endsWith("/")){ normalbasedir.chop(1); }
    line_dir->setText(normalbasedir);
    //See if this was a manual move to the directory, or an internal move
    QString tmp = dir.section(ZSNAPDIR,0,0);
    if(tmp != snapbasedir.section(ZSNAPDIR,0,0)){
      loadsnaps = true; //different snapshot loaded - need to update internally
    }
  }else{
    //This is a normal directory - prompt for snapshot information
    line_dir->setText(CDIR);
    normalbasedir = CDIR;
    if(!snapbasedir.isEmpty()){ watcher->removePath(snapbasedir); }
    snapbasedir.clear();
    loadsnaps = true;
  }
  if(loadsnaps){
    //kick this off while still loading the dir contents
    ui->group_snaps->setEnabled(false); //to prevent the snap updates to be automatically used
    ui->group_snaps->setVisible(false);
    ui->slider_snap->setRange(1,1);
    emit findSnaps(ID, normalbasedir);
  }

  if(DEBUG){ qDebug() << "Update History:" <<time.elapsed(); }
  //Now update the history for this browser
  //qDebug() << "History:" << history << normalbasedir << lastbasedir;
  if(!history.isEmpty() && history.last() == normalbasedir && lastbasedir!=normalbasedir ){
    //We went back one - remove this from the history
    history.takeLast();
    ui->actionBack->setEnabled(!history.isEmpty());
    //qDebug() << " - Duplicate: removed item";
  }else if(lastbasedir!=normalbasedir){ //not a refresh or internal snapshot change
    //qDebug() << " - New History Item:" << normalbasedir;
    history << normalbasedir;
    ui->actionBack->setEnabled(history.length()>1);
  }
  if(DEBUG){ qDebug() << "Update Watcher:" << time.elapsed(); }
  //Clear the current watcher
  if(!watcher->directories().isEmpty()){ watcher->removePaths(watcher->directories()); }
  if(!watcher->files().isEmpty()){ watcher->removePaths(watcher->files()); }
  watcher->addPath(CDIR);
  // add sessionsettings to watcher so date_format can be update based on user settings
  watcher->addPath(sessionsettings_config_file);
  ui->actionStopLoad->setVisible(true);
  stopload = false;
  //Clear the display widget (if a new directory)
    if(DEBUG){ qDebug() << "Clear Browser Widget:" << time.elapsed(); }
  double scrollpercent = -1;
  if(updateThumbs){ needThumbs.clear(); }
  if(lastbasedir != normalbasedir){
    if(showDetails){ treeWidget->clear(); }
    else{ listWidget->clear(); }
    QApplication::processEvents(); //make sure it is cleared right away
  }else{
    //Need to be smarter about which items need to be removed
    // - compare the old/new lists and remove any items not in the new listing (new items taken care of below)
    QStringList newfiles; //just the filenames
    for(int i=0; i<CLIST.length(); i++){ newfiles << CLIST[i].fileName(); }
    if(showDetails){
      for(int i=0; i<treeWidget->topLevelItemCount(); i++){
        if( !newfiles.contains(treeWidget->topLevelItem(i)->whatsThis(0).section("/",-1)) ){
	  if(!updateThumbs){ needThumbs.removeAll( treeWidget->topLevelItem(i)->whatsThis(0).section("::::",1,50)); }
	  delete treeWidget->takeTopLevelItem(i); 
	  i--;
	}
      }
      QApplication::processEvents(); //make sure the scrollbar is up to date after removals
      scrollpercent = treeWidget->verticalScrollBar()->value()/( (double) treeWidget->verticalScrollBar()->maximum());
    }else{
      for(int i=0; i<listWidget->count(); i++){
        if( !newfiles.contains(listWidget->item(i)->text()) ){
	  if(!updateThumbs){ needThumbs.removeAll( listWidget->item(i)->whatsThis().section("::::",1,50)); }
	  delete listWidget->takeItem(i); 
	  i--;
	}
      }
      QApplication::processEvents(); //make sure the scrollbar is up to date after removals
      scrollpercent = listWidget->horizontalScrollBar()->value()/( (double) listWidget->horizontalScrollBar()->maximum());
    }
  } //end check for CDIR reload
  //Now fill the display widget
  bool hasimages, hasmultimedia;
  hasimages = hasmultimedia = false;
  int numdirs = 0;
  qint64 filebytes = 0;
  //Setup the timer to see when we should process events
  /*QTimer updatetime;
    updatetime.setInterval(1000); //1 second updates
    updatetime.setSingleShot(true);
    updatetime.start();*/
  QTime updatetime = QTime::currentTime().addMSecs(500);
  if(DEBUG){ qDebug() << "Start Loop over items:" << time.elapsed(); }
  for(int i=0; i<list.length(); i++){
    if(stopload){ ui->actionStopLoad->setVisible(false); return; } //stop right now
    if(!hasimages && list[i].isImage()){ hasimages = true;  ui->tool_goToImages->setVisible(true); }
    else if(!hasmultimedia && list[i].isAVFile()){ hasmultimedia = true;  ui->tool_goToPlayer->setVisible(true); }
    //Update statistics
    if(list[i].isDir()){ numdirs++; }
    else{ filebytes += list[i].size(); }
    watcher->addPath(list[i].absoluteFilePath());
    if(showDetails){
      //Now create all the individual items for the details tree
      CQTreeWidgetItem *it;
      bool addnew = false;
	//See if an item already exists for this file
	QList<QTreeWidgetItem*> items = treeWidget->findItems(list[i].fileName(),Qt::MatchExactly,0); //NOTE: This requires column 0 to be the name
	if(items.isEmpty()){
        it = new CQTreeWidgetItem();
	    addnew = true;
	}else{
        // Safe downcasting because CQTreeWidgetItem only redefines the virtual function bool opearot<. Not new methos added.
        it = static_cast<CQTreeWidgetItem *> (items.first());
	}
	//Now update the entry contents
	it->setWhatsThis(0, QString(canmodify ? "cut": "copy")+"::::"+list[i].absoluteFilePath());
      for(int t=0; t<listDetails.length(); t++){
        switch(listDetails[t]){
	  case NAME:
	    it->setText(t,list[i].fileName());
	    it->setStatusTip(t, list[i].fileName());
	      //Since the icon/image is based on the filename - only update this for a new item
	      // (This is the slowest part of the routine)
	      if(list[i].isImage()&& (addnew || updateThumbs)){
	        if(showThumbs){ 
		  it->setIcon(t, LXDG::findIcon("fileview-preview","image-x-generic") );
		  needThumbs << list[i].fileName();	
		}else{ it->setIcon(t, LXDG::findIcon(list[i].iconfile(),"image-x-generic") ); }
	      }else if(addnew){
	        it->setIcon(t, LXDG::findIcon(list[i].iconfile(),"unknown") );
	      }
	    break;
	  case SIZE:
	    if(!list[i].isDir()){
	      it->setText(t, LUtils::BytesToDisplaySize(list[i].size()) );
	    }
	    break;
	  case TYPE:
	    it->setText(t, list[i].mimetype());
	    break;
      case DATEMOD:
        {
          QStringList datetime_format = getDateFormat();
          // Save datetime in WhatThis value. Lately will be used by CQTreeWidgetItem for sorting by date
          it->setWhatsThis(t, list[i].lastModified().toString("yyyyMMddhhmmsszzz"));
          // Default configurition. Fallback to Qt::DefaultLocaleShortDate for formats
          if(datetime_format.at(0).isEmpty() && datetime_format.at(1).isEmpty())
            it->setText(t, list[i].lastModified().toString(Qt::DefaultLocaleShortDate) );
          // Date is setted but time not. Time goes to default
          else if(!datetime_format.at(0).isEmpty() && datetime_format.at(1).isEmpty())
            it->setText(t, list[i].lastModified().date().toString(datetime_format.at(0)) + " " + list[i].lastModified().time().toString(Qt::DefaultLocaleShortDate));
          // Time is setted but date not. Date goes to default
          else if(datetime_format.at(0).isEmpty() && !datetime_format.at(1).isEmpty())
            it->setText(t, list[i].lastModified().date().toString(Qt::DefaultLocaleShortDate) + " " + list[i].lastModified().time().toString(datetime_format.at(1)));
          // Both time and date setted.
          else
            it->setText(t, list[i].lastModified().date().toString(datetime_format.at(0)) + " " + list[i].lastModified().time().toString(datetime_format.at(1)));
          break;
        }
      case DATECREATE:
        {
          QStringList datetime_format = getDateFormat();
          it->setWhatsThis(DATECREATE, list[i].lastModified().toString("yyyyMMddhhmmsszzz"));
          if(datetime_format.at(0).isEmpty() && datetime_format.at(1).isEmpty())
            it->setText(t, list[i].lastModified().toString(Qt::DefaultLocaleShortDate) );
          else if(!datetime_format.at(0).isEmpty() && datetime_format.at(1).isEmpty())
            it->setText(t, list[i].lastModified().date().toString(datetime_format.at(0)) + " " + list[i].lastModified().time().toString(Qt::DefaultLocaleShortDate));
          else if(datetime_format.at(0).isEmpty() && !datetime_format.at(1).isEmpty())
            it->setText(t, list[i].lastModified().date().toString(Qt::DefaultLocaleShortDate) + " " + list[i].lastModified().time().toString(datetime_format.at(1)));
          else
            it->setText(t, list[i].lastModified().date().toString(datetime_format.at(0)) + " " + list[i].lastModified().time().toString(datetime_format.at(1)));
          break;
        }
	}
      }
      if(addnew){ treeWidget->addTopLevelItem(it); }
      if(tmpSel.contains(list[i].absoluteFilePath())){ it->setSelected(true); }
      if(lastdir == CDIR+"/"+list[i].fileName()){ 
	treeWidget->setCurrentItem(it);
	treeWidget->scrollToItem(it);
      }
    }else{
	//Create all the individual items for the basic list
	QListWidgetItem *it;
	  //See if there is an existing item to re-use
	  bool addnew = false;
	  QList<QListWidgetItem*> items = listWidget->findItems(list[i].fileName(), Qt::MatchExactly);
	  if(items.isEmpty()){
	    it = new QListWidgetItem();
	    addnew = true;
	  }else{ it = items.first(); }

	  it->setWhatsThis( QString(canmodify ? "cut": "copy")+"::::"+list[i].absoluteFilePath()); //used for drag and drop
	  it->setText(list[i].fileName());
	  it->setStatusTip(list[i].fileName());
	    //Since the icon/image is based on the filename - only update this for a new items (non-thumbnail)
	    // (This is the slowest part of the routine)
	    if(list[i].isImage() && (addnew || updateThumbs) ){
	      if(showThumbs){ 
		it->setIcon(LXDG::findIcon("fileview-preview","image-x-generic") );
		needThumbs << list[i].fileName();	
	      }else{ it->setIcon(LXDG::findIcon(list[i].iconfile(),"image-x-generic") ); }
	    }else if(addnew){
	      it->setIcon(LXDG::findIcon(list[i].iconfile(),"unknown") );
	    }
	listWidget->addItem(it);
	if(tmpSel.contains(list[i].absoluteFilePath())){ it->setSelected(true); }
	if(lastdir == CDIR+"/"+list[i].fileName()){ 
	  listWidget->setCurrentItem(it);
	  listWidget->scrollToItem(it);
	}
    }
    if(QTime::currentTime() > updatetime){ QApplication::processEvents(); updatetime = QTime::currentTime().addMSecs(500); }//keep the UI snappy while loading a directory
    if(DEBUG){ qDebug() << " - item finished:" << i << time.elapsed(); }
  }
  tmpSel.clear();
  if(DEBUG){ qDebug() << "Done with item loop:" << time.elapsed() << list.length(); }
  ui->actionStopLoad->setVisible(false);
  //Another check to ensure the current item is visible (or return to the same scroll position)
  if(stopload){ return; } //stop right now
  if(scrollpercent<0){
    if(showDetails){
      for(int t=0; t<treeWidget->columnCount(); t++){treeWidget->resizeColumnToContents(t); }
      if(treeWidget->currentItem()!=0){ treeWidget->scrollToItem(treeWidget->currentItem()); }
    }else{
      if(listWidget->currentItem()!=0){ listWidget->scrollToItem(listWidget->currentItem()); }
    }
  }else{
    if(showDetails){
      treeWidget->verticalScrollBar()->setValue( qRound(treeWidget->verticalScrollBar()->maximum()*scrollpercent) );
    }else{
      listWidget->horizontalScrollBar()->setValue( qRound(listWidget->horizontalScrollBar()->maximum()*scrollpercent) );
    }
  }

  
  if(stopload){ return; } //stop right now
  if(DEBUG){ qDebug() << "Assemble Status Message:" << time.elapsed(); }
  //Assemble any status message
  QString stats = QString(tr("Capacity: %1")).arg(LOS::FileSystemCapacity(CDIR));
  if(list.length()>0){
    stats.prepend("\t");
    if(numdirs < list.length()){
      //Has Files
      stats.prepend( QString(tr("Files: %1 (%2)")).arg(QString::number(list.length()-numdirs), LUtils::BytesToDisplaySize(filebytes)) );
    }
    if(numdirs > 0){
      //Has Dirs
      if(numdirs<list.length()){ stats.prepend(" / "); }//has files output already
      stats.prepend( QString(tr("Dirs: %1")).arg(QString::number(numdirs)) );
    }
    
  }
  if(stopload){ return; } //stop right now  
  if(!canmodify){ stats.prepend(tr("(Limited Access) ")); }
  ui->label_status->setText( stats.simplified() );
  if(DEBUG){ qDebug() << "DONE:" << time.elapsed(); }
  if(showThumbs){ thumbThread = QtConcurrent::run(this, &DirWidget::startLoadThumbs); }
}
Пример #5
0
/*
 * This method is used by the CKMailDeliverySystem to actually send
 * the passed message out the delivery channel. In order to include
 * all possibilities that might take place, we include the flag for
 * asking for a read receipt, and including private recipients. In
 * the case of SMTP delivery, we use the CKSMTPConnection to connect
 * to the server (again), exchange greetings, send the 'boilerplate'
 * information (from, to, header), and then send the message body.
 * After successful completion, we send the message and close the
 * connection, and return success. If anything fails we throw an
 * exception through the AKExceptionHandler and return false.
 */
bool CKSMTPDelivery::deliver( const CKMailMessage & aMsg,
							  bool aReadReceipt,
							  const CKStringList & aPvtRecipients )
{
	bool		error = false;

	// first, make sure we're ready to deliver the message
	if (!error) {
		try {
			if (!readyToDeliverMessages()) {
				error = true;
				std::ostringstream	msg;
				msg << "CKSMTPDelivery::deliverMessage(const CKMailMessage &, "
					"bool, const CKStringList &) - there was an "
					"error while trying to check the connection to the SMTP "
					"server on " << mHostname << ". Please make sure it's "
					"there and available.";
				throw CKException(__FILE__, __LINE__, msg.str());
			}
		} catch (CKException & e) {
			error = true;
			std::ostringstream	msg;
			msg << "CKSMTPDelivery::deliverMessage(const CKMailMessage &, "
				"bool, const CKStringList &) - there was an "
				"error while trying to verify the connection to the SMTP server "
				"on " << mHostname << ". Please make sure it's there and "
				"available.";
			throw CKException(__FILE__, __LINE__, msg.str());
		}
	}

	// let's connect to the host, if we aren't already connected
	if (!error) {
		if (!mHostConnection.isConnected()) {
			if (!mHostConnection.connectToHost(mHostname)) {
				error = true;
				std::ostringstream	msg;
				msg << "CKSMTPDelivery::deliverMessage(const CKMailMessage &, "
					"bool, const CKStringList &) - there was an "
					"error while trying to connect to the SMTP server on " <<
					mHostname << ". Please make sure it's there and available.";
				throw CKException(__FILE__, __LINE__, msg.str());
			}
		}
	}

	// now we need to send the sender's address for this message
	if (!error) {
		if (!mHostConnection.senderAddress(mFromEMailAddress)) {
			error = true;
			std::ostringstream	msg;
			msg << "CKSMTPDelivery::deliverMessage(const CKMailMessage &, "
				"bool, const CKStringList &) - there was an "
				"error while trying to set the sender's email address with the "
				"SMTP server on " << mHostname << ". Please make sure it's "
				"there and available.";
			throw CKException(__FILE__, __LINE__, msg.str());
		}
	}

	/*
	 * Now we need to send the recipient address list for
	 * this message and at the same time, build up the mail
	 * header component that is a list of all the public
	 * recipients.
	 */
	CKString		publicRecipientList = "To:";
	if (!error) {
		CKStringNode		*i = NULL;
		for (i = aMsg.getRecipients()->getHead(); i != NULL; i = i->getNext()) {
			if (!mHostConnection.recipientAddress(*i)) {
				error = true;
				std::ostringstream	msg;
				msg << "CKSMTPDelivery::deliverMessage(const CKMailMessage &, "
					"bool, const CKStringList &) - while trying to "
					"add the public recipient '" << (*i) << "' to the list for this message "
					"an error occurred. Please check into it as soon as possible.";
				throw CKException(__FILE__, __LINE__, msg.str());
			} else {
				// add this guy to the list of public recipients
				publicRecipientList.append(" ").append(*i).append("\r\n");
			}
		}
	}

	/*
	 * Now we need to send the *private* recipient address
	 * list for this message. Note we don't add these to the
	 * publicRecipientList.
	 */
	if (!error) {
		CKStringNode		*i = NULL;
		for (i = aPvtRecipients.getHead(); i != NULL; i = i->getNext()) {
			if (!mHostConnection.recipientAddress(*i)) {
				error = true;
				std::ostringstream	msg;
				msg << "CKSMTPDelivery::deliverMessage(const CKMailMessage &, "
					"bool, const CKStringList &) - while trying to "
					"add the private recipient '" << (*i) << "' to the list for this message "
					"an error occurred. Please check into it as soon as possible.";
				throw CKException(__FILE__, __LINE__, msg.str());
			}
		}
	}

	/*
	 * Now we need to start the message body, create and send
	 * the message header, send the message, and close the
	 * message body. Since these are somewhat related, they
	 * are treated as a somewhat single unit.
	 */
	// Start the message body with the SMTP server
	if (!error) {
		if (!mHostConnection.startMessageBody()) {
			// Couldn't start the message header
			error = true;
			std::ostringstream	msg;
			msg << "CKSMTPDelivery::deliverMessage(const CKMailMessage &, "
				"bool, const CKStringList &) - while trying to "
				"start the message body for this message an error occurred at the "
				"SMTP server. Please check into it as soon as possible.";
			throw CKException(__FILE__, __LINE__, msg.str());
		}
	}
	// Now format and send the message header to the SMTP server
	if (!error) {
		/*
		 * Format the message header (complex, but necessary)
		 * Print message header according to RFC 822:
		 * Return-path, Received, Date, From, Subject, Sender, To, cc
		 */
		CKString msgHeader;

		// First, indicate if it's a MIME message
		if (aMsg.isMIME()) {
			msgHeader.append("MIME-Version: 1.0\r\n");
		}

		// Next, put up the return path
		msgHeader.append("Return-Path: ").append(mFromEMailAddress).append("\r\n");
		msgHeader.append("X-Sender: ").append(mFromEMailAddress).append("\r\n");
		msgHeader.append("X-Mailer: CKit Mailer\r\n");

		// Indicate the client's date and time
		msgHeader.append("Date: ").append(getDateFormat()).append("\r\n");

		/*
		 * Now add the simple 'from', 'subject', and 'to'
		 * (built up already from the recipient list.)
		 */
		msgHeader.append("From: ").append(mFromEMailAddress).append("\r\n");
		msgHeader.append("Subject: ").append(aMsg.getSubject()).append("\r\n");
		msgHeader.append(publicRecipientList);

		/**
		 * Now try to send this header to the SMTP server
		 */
		// Try to send the message body
		if (!mHostConnection.addToMessageBody(msgHeader)) {
			// Couldn't send the message header
			error = true;
			std::ostringstream	msg;
			msg << "CKSMTPDelivery::deliverMessage(const CKMailMessage &, "
				"bool, const CKStringList &) - while trying to "
				"add the message header to this message an error occurred. "
				"Please check into it as soon as possible.";
			throw CKException(__FILE__, __LINE__, msg.str());
		}
	}
	// Now send the message body to the SMTP server
	if (!error) {
		// Try to send the message body
		if (!mHostConnection.addToMessageBody(aMsg.getMessageBody())) {
			// Couldn't send the message body
			error = true;
			std::ostringstream	msg;
			msg << "CKSMTPDelivery::deliverMessage(const CKMailMessage &, "
				"bool, const CKStringList &) - while trying to "
				"add the message body to this message an error occurred. "
				"Please check into it as soon as possible.";
			throw CKException(__FILE__, __LINE__, msg.str());
		}
	}
	// Now close out the message with the SMTP server
	if (!error) {
		if (!mHostConnection.closeMessageBody()) {
			// Couldn't end the message section
			error = true;
			std::ostringstream	msg;
			msg << "CKSMTPDelivery::deliverMessage(const CKMailMessage &, "
				"bool, const CKStringList &) - while trying to "
				"end the message section to this message an error occurred. "
				"Please check into it as soon as possible.";
			throw CKException(__FILE__, __LINE__, msg.str());
		}
	}

	// Now we need to close the connection to the server
	if (mHostConnection.isConnected()) {
		if (!mHostConnection.quit()) {
			error = true;
			std::ostringstream	msg;
			msg << "CKSMTPDelivery::deliverMessage(const CKMailMessage &, "
				"bool, const CKStringList &) - while trying to "
				"close the connection to the SMTP server and send the message "
				"on it's way, an error occurred. Please check into it as soon "
				"as possible.";
			throw CKException(__FILE__, __LINE__, msg.str());
		}
	}

	// Return the success of this entire process...
	return !error;
}