示例#1
0
void RecordNode::createNewDirectory()
{
    std::cout << "Creating new directory." << std::endl;

    rootFolder = File(dataDirectory.getFullPathName() + File::separator + generateDirectoryName());

    updateFileName(eventChannel);

    for (int i = 0; i < channelPointers.size(); i++)
    {
        updateFileName(channelPointers[i]);
    }

}
int TFileOpen::updateListBoxes()
{
  int Result;
  char Path[fsPathName+1];

  if (GetDlgItem(hWindow, id_FList))
  {
        strcpy(Path, pathName);
        Result = DlgDirList(hWindow, Path, id_FList, id_FPath, 0);
        if (Result)
                DlgDirList(hWindow, "*.*", id_DList, 0, 0x0C010);
  }
  else
  {
        strncpy(Path, pathName, getFileName(pathName) - pathName);
        strncat(Path, "*.*", fsPathName);
        Result = DlgDirList(hWindow, Path, id_DList, id_FPath, 0x0C010);
  }

  if (Result)
  {
        strncpy(fileSpec, getFileName(pathName), fsFileSpec);
        strcpy(pathName, fileSpec);
        updateFileName();
  }
  return Result;
}
示例#3
0
TestWizardPage::TestWizardPage(QWidget *parent) :
    QWizardPage(parent),
    m_sourceSuffix(QtWizard::sourceSuffix()),
    m_lowerCaseFileNames(QtWizard::lowerCaseFiles()),
    ui(new Ui::TestWizardPage),
    m_fileNameEdited(false),
    m_valid(false)
{
    setTitle(tr("Test Class Information"));
    ui->setupUi(this);
    ui->testSlotLineEdit->setText(QLatin1String("testCase1"));
    ui->testClassLineEdit->setLowerCaseFileName(m_lowerCaseFileNames);
    ui->qApplicationCheckBox->setChecked(TestWizardParameters::requiresQApplicationDefault);
    connect(ui->testClassLineEdit, SIGNAL(updateFileName(QString)),
            this, SLOT(slotClassNameEdited(QString)));
    connect(ui->fileLineEdit, SIGNAL(textEdited(QString)), \
                this, SLOT(slotFileNameEdited()));
    connect(ui->testClassLineEdit, SIGNAL(validChanged()),
            this, SLOT(slotUpdateValid()));
    connect(ui->testSlotLineEdit, SIGNAL(validChanged()),
            this, SLOT(slotUpdateValid()));
    connect(ui->fileLineEdit, SIGNAL(validChanged()),
            this, SLOT(slotUpdateValid()));

    setProperty(Utils::SHORT_TITLE_PROPERTY, tr("Details"));
}
示例#4
0
文件: RecordNode.cpp 项目: awidge/GUI
void RecordNode::createNewFiles()
{
    for (int i = 0; i < channelPointers.size(); i++)
    {
        updateFileName(channelPointers[i]);
    }
    
}
 void VideoCaptureDisplay::onInitialize()
 {
   updateFileName();
   updateFps();
   //updateStartCapture();
   start_capture_property_->setBool(false); // always false when starting up
   context_->queueRender();
 }
void MainWindow::setImg()
{
    if(!this->imgdir.dirExist || this->imgdir.fileList.length() == 0)
    {
        QPixmap empty;
        ui->imgLabel->setPixmap(empty);

        if(!this->imgdir.dirExist)
            ui->imgLabel->setText("Path is invalid, is not a directory?");
        else
            ui->imgLabel->setText("Couldn't find any image in the directory");
        return;
    }

    // in case index is outbounds, should not happen
    if(index > imgdir.fileList.count())
        return;

    QString temp = imgdir.dir.absoluteFilePath(imgdir.fileList.value(index));
    dbg << imgdir.fileList.value(index).toStdString().c_str() << std::endl;
    dbg << temp.toStdString().c_str() << std::endl;
    dbg << index << std::endl;
    QPixmap imgtemp;
    imgtemp.load(temp.toStdString().c_str());

    if(scaleImg)
    {
        if(imgtemp.height() > program_settings.retrive_as_int(MAX_HEIGHT_SETT))
            imgtemp = imgtemp.scaledToHeight(
                        program_settings.retrive_as_int(MAX_HEIGHT_SETT),
                        Qt::SmoothTransformation);
        if(imgtemp.width() > program_settings.retrive_as_int(MAX_WIDTH_SETT))
            imgtemp = imgtemp.scaledToWidth(
                        program_settings.retrive_as_int(MAX_WIDTH_SETT),
                        Qt::SmoothTransformation);

    }

    if(temp.endsWith(".gif",Qt::CaseInsensitive) ||
            temp.endsWith(".webm",Qt::CaseInsensitive)) // not yet support for webm
    {
        QMovie *movie = new QMovie(temp.toStdString().c_str());
        ui->imgLabel->setMovie(movie);
        movie->start();
        dbg << "movie" << std::endl;
    }else
    {
        ui->imgLabel->setPixmap(imgtemp);
    }

    adjustScrollArea();

    imgdir.saveIndex(imgdir.buildPath(
                         program_settings.retrive(DIR1_SETT),"i.txt").c_str(),
                         index);
   updateFileName();
   coutdebug();
}
示例#7
0
void SwapFile::fileSaved(const QString&)
{
  m_needSync = false;
  
  // remove old swap file (e.g. if a file A was "saved as" B)
  removeSwapFile();
  
  // set the name for the new swap file
  updateFileName();
}
void ImageSourceSeries::updateProperties() {
    currentImageIndex_.setReadOnly(fileList_.empty());

    if (fileList_.size() < static_cast<std::size_t>(currentImageIndex_.get()))
        currentImageIndex_.set(1);

    // clamp the number of files since setting the maximum to 0 will reset the min value to 0
    int numFiles = std::max(static_cast<const int>(fileList_.size()), 1);
    currentImageIndex_.setMaxValue(numFiles);
    updateFileName();
}
QgsDelimitedTextSourceSelect::QgsDelimitedTextSourceSelect( QWidget * parent, Qt::WFlags fl, bool embedded ):
    QDialog( parent, fl ),
    mFile( new QgsDelimitedTextFile() ),
    mExampleRowCount( 20 ),
    mBadRowCount( 0 ),
    mPluginKey( "/Plugin-DelimitedText" ),
    mLastFileType( "" )
{

  setupUi( this );

  QSettings settings;
  restoreGeometry( settings.value( mPluginKey + "/geometry" ).toByteArray() );

  if ( embedded )
  {
    buttonBox->button( QDialogButtonBox::Cancel )->hide();
    buttonBox->button( QDialogButtonBox::Ok )->hide();
  }

  cmbEncoding->clear();
  cmbEncoding->addItems( QgsVectorDataProvider::availableEncodings() );
  cmbEncoding->setCurrentIndex( cmbEncoding->findText( "UTF-8" ) );
  loadSettings();

  updateFieldsAndEnable();

  connect( txtFilePath, SIGNAL( textChanged( QString ) ), this, SLOT( updateFileName() ) );
  connect( txtLayerName, SIGNAL( textChanged( QString ) ), this, SLOT( enableAccept() ) );
  connect( cmbEncoding, SIGNAL( currentIndexChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );

  connect( delimiterCSV, SIGNAL( toggled( bool ) ), this, SLOT( updateFieldsAndEnable() ) );
  connect( delimiterChars, SIGNAL( toggled( bool ) ), this, SLOT( updateFieldsAndEnable() ) );
  connect( delimiterRegexp, SIGNAL( toggled( bool ) ), this, SLOT( updateFieldsAndEnable() ) );

  connect( cbxDelimComma, SIGNAL( stateChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );
  connect( cbxDelimSpace, SIGNAL( stateChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );
  connect( cbxDelimTab, SIGNAL( stateChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );
  connect( cbxDelimSemicolon, SIGNAL( stateChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );
  connect( cbxDelimColon, SIGNAL( stateChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );

  connect( txtDelimiterOther, SIGNAL( textChanged( QString ) ), this, SLOT( updateFieldsAndEnable() ) );
  connect( txtQuoteChars, SIGNAL( textChanged( QString ) ), this, SLOT( updateFieldsAndEnable() ) );
  connect( txtEscapeChars, SIGNAL( textChanged( QString ) ), this, SLOT( updateFieldsAndEnable() ) );
  connect( txtDelimiterRegexp, SIGNAL( textChanged( QString ) ), this, SLOT( updateFieldsAndEnable() ) );

  connect( rowCounter, SIGNAL( valueChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );
  connect( cbxUseHeader, SIGNAL( stateChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );
  connect( cbxSkipEmptyFields, SIGNAL( stateChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );
  connect( cbxTrimFields, SIGNAL( stateChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );

  connect( cbxPointIsComma, SIGNAL( toggled( bool ) ), this, SLOT( updateFieldsAndEnable() ) );
  connect( cbxXyDms, SIGNAL( toggled( bool ) ), this, SLOT( updateFieldsAndEnable() ) );
}
示例#10
0
void SwapFile::fileClosed ()
{
  // remove old swap file, file is now closed
  if (!shouldRecover()) {
    removeSwapFile();
  } else {
    m_document->setReadWrite(true);
  }

  // purge filename
  updateFileName();
}
void ClassNameValidatingLineEdit::handleChanged(const QString &t)
{
    if (isValid()) {
        // Suggest file names, strip namespaces
        QString fileName = d->m_lowerCaseFileName ? t.toLower() : t;
        if (d->m_namespacesEnabled) {
            const int namespaceIndex = fileName.lastIndexOf(d->m_namespaceDelimiter);
            if (namespaceIndex != -1)
                fileName.remove(0, namespaceIndex + d->m_namespaceDelimiter.size());
        }
        emit updateFileName(fileName);
    }
}
 VideoCaptureDisplay::VideoCaptureDisplay():
   Display(), capturing_(false), first_time_(true)
 {
   start_capture_property_ = new rviz::BoolProperty(
     "start capture", false, "start capture",
     this, SLOT(updateStartCapture()));
   file_name_property_ = new rviz::StringProperty(
     "filename", "output.avi",
     "filename", this, SLOT(updateFileName()));
   fps_property_ = new rviz::FloatProperty(
     "fps", 30.0,
     "fps", this, SLOT(updateFps()));
   fps_property_->setMin(0.1);
 }
示例#13
0
void RecordNode::addInputChannel(GenericProcessor* sourceNode, int chan)
{

    if (chan != getProcessorGraph()->midiChannelIndex)
    {

        int channelIndex = getNextChannel(false);

        setPlayConfigDetails(channelIndex+1,0,44100.0,128);

        channelPointers.add(sourceNode->channels[chan]);

        //   std::cout << channelIndex << std::endl;

        updateFileName(channelPointers[channelIndex]);



        //if (channelPointers[channelIndex]->isRecording)
        //	std::cout << "  This channel will be recorded." << std::endl;
        //else
        //	std::cout << "  This channel will NOT be recorded." << std::endl;

        //std::cout << "adding channel " << getNextChannel(false) << std::endl;

        //std::pair<int, Channel> newPair (getNextChannel(false), newChannel);

        //std::cout << "adding channel " << getNextChannel(false) << std::endl;

        //continuouschannelPointers.insert(newPair);


    }
    else
    {

        for (int n = 0; n < sourceNode->eventChannels.size(); n++)
        {

            eventChannelPointers.add(sourceNode->eventChannels[n]);

        }

    }

}
示例#14
0
void DesignDocument::loadDocument(QPlainTextEdit *edit)
{
    Q_CHECK_PTR(edit);

    connect(edit, SIGNAL(undoAvailable(bool)),
            this, SIGNAL(undoAvailable(bool)));
    connect(edit, SIGNAL(redoAvailable(bool)),
            this, SIGNAL(redoAvailable(bool)));
    connect(edit, SIGNAL(modificationChanged(bool)),
            this, SIGNAL(dirtyStateChanged(bool)));

    m_documentTextModifier.reset(new BaseTextEditModifier(dynamic_cast<TextEditor::BaseTextEditorWidget*>(plainTextEdit())));

    m_inFileComponentTextModifier.reset();

    updateFileName(QString(), fileName());

    m_subComponentManager->update(QUrl::fromLocalFile(fileName()), currentModel()->imports());

    m_documentLoaded = true;
}
示例#15
0
CodeEditor::CodeEditor(Toolchain* t, QString filename, QWidget* parent): QsciScintilla(parent)
{
    loading = false;
    highlighter = 0;
    
    connect(this, SIGNAL(textChanged()), this, SLOT(updateFileName()));
    connect(this, SIGNAL(linesChanged()), this, SLOT(updateLineNumberMarginWidth()));

    fileName = filename;
    // FIXME: Remove this; this just makes it so Ctrl-S doesn't ask for a filename.
    path = filename;
    toolchain = t;
    dirty = false;

    setHighlighter();
    setupEditor();
    setupMargins();
    setupSignals();

    readFile(filename);
}
示例#16
0
void JobListViewItem::updateText(const Job& job)
{
    const bool fileNameChanged(m_job.fileName() != job.fileName());
    m_job = job;

    setText(JobColumnID, QString::number(job.jobId()));
    if (JobListView* view = dynamic_cast<JobListView*>(treeWidget())) {
        setText(JobColumnClient, view->hostInfoManager()->nameForHost(job.client()));
        if (job.server())
            setText(JobColumnServer, view->hostInfoManager()->nameForHost(job.server()));
        else
            setText(JobColumnServer, QString());
    }
    setText(JobColumnState, job.stateAsString());
    setText(JobColumnReal, job.formattedRealTime());
    setText(JobColumnUser, job.formattedUserTime());
    setText(JobColumnFaults, QString::number(job.pageFaults()));
    setText(JobColumnSizeIn, job.formattedInputSize());
    setText(JobColumnSizeOut, job.formattedOutputSize());

    if (fileNameChanged)
        updateFileName();
}
示例#17
0
void SwapFile::fileLoaded(const QString&)
{
  // look for swap file
  if (!updateFileName())
    return;

  if (!m_swapfile.exists())
  {
    kDebug (13020) << "No swap file";
    return;
  }

  if (!QFileInfo(m_swapfile).isReadable())
  {
    kWarning( 13020 ) << "Can't open swap file (missing permissions)";
    return;
  }

  // sanity check
  QFile peekFile(fileName());
  if (peekFile.open(QIODevice::ReadOnly)) {
    QDataStream stream(&peekFile);
    if (!isValidSwapFile(stream, true)) {
      removeSwapFile();
      return;
    }
    peekFile.close();
  } else {
    kWarning( 13020 ) << "Can't open swap file:" << fileName();
    return;
  }

  // show swap file message
  m_document->setReadWrite(false);
  showSwapFileMessage();
}
示例#18
0
//Construct the base GUI, and connect the signals
void FileLineEdit::init(QString title, QFileDialog::FileMode mode)
{
    //Layout
    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->setSpacing(0);
    layout->setMargin(0);

    //Line edit
    _line = new QLineEdit();
    layout->addWidget(_line);
    CONNECT(_line, SIGNAL(textChanged(QString)), this, SLOT(updateFileName(QString)));

    //Button
    QPushButton *button = new QPushButton(tr("Select..."));
    //Reduce the button size so that it's not higher than the line edit, and not much larger than its text
    button->setMaximumHeight(_line->size().height()-5);
    button->setMaximumWidth(button->fontMetrics().boundingRect(button->text()).width()+15);
    layout->addWidget(button);
    CONNECT(button, SIGNAL(clicked()), this, SLOT(clicked()));

    //Create the file dialog and set its mode
    _fileDialog = new QFileDialog(this,title,QDir::homePath());
    _fileDialog->setFileMode(mode);
}
示例#19
0
bool Downloader::downloadFile(NetFile *netFile)
{
    BYTE  *buffer = new BYTE[readBufferSize];
    DWORD bytesRead;
    File  file;

    updateFileName(netFile);
    updateStatus(msg("Connecting..."));
    setMarquee(true, false);

    try
    {
        netFile->open(internet);
    }
    catch(exception &e)
    {
        setMarquee(false, stopOnError ? (netFile->size == FILE_SIZE_UNKNOWN) : false);
        updateStatus(msg(e.what()));
        storeError(msg(e.what()));
        delete[] buffer;
        return false;
    }

    if(!netFile->handle)
    {
        setMarquee(false, stopOnError ? (netFile->size == FILE_SIZE_UNKNOWN) : false);
        updateStatus(msg("Cannot connect"));
        storeError();
        delete[] buffer;
        return false;
    }

    if(!file.open(netFile->name))
    {
        setMarquee(false, stopOnError ? (netFile->size == FILE_SIZE_UNKNOWN) : false);
        tstring errstr = msg("Cannot create file") + _T(" ") + netFile->name;
        updateStatus(errstr);
        storeError(errstr);
        delete[] buffer;
        return false;
    }

    Timer progressTimer(100);
    Timer speedTimer(1000);

    updateStatus(msg("Downloading..."));

    if(!(netFile->size == FILE_SIZE_UNKNOWN))
        setMarquee(false, false);

    processMessages();

    while(true)
    {
        if(downloadCancelled)
        {
            file.close();
            netFile->close();
            delete[] buffer;
            return true;
        }

        if(!netFile->read(buffer, readBufferSize, &bytesRead))
        {
            setMarquee(false, netFile->size == FILE_SIZE_UNKNOWN);
            updateStatus(msg("Download failed"));
            storeError();
            file.close();
            netFile->close();
            delete[] buffer;
            return false;
        }

        if(bytesRead == 0)
            break;

        file.write(buffer, bytesRead);

        if(progressTimer.elapsed())
            updateProgress(netFile);

        if(speedTimer.elapsed())
            updateSpeed(netFile, &speedTimer);

        if(sizeTimeTimer.elapsed())
            updateSizeTime(netFile, &sizeTimeTimer);

        processMessages();
    }

    updateProgress(netFile);
    updateSpeed(netFile, &speedTimer);
    updateSizeTime(netFile, &sizeTimeTimer);
    updateStatus(msg("Download complete"));
    processMessages();

    file.close();
    netFile->close();
    netFile->downloaded = true;

    delete[] buffer;
    return true;
}
示例#20
0
bool Downloader::downloadFile(NetFile *netFile)
{
	BYTE  buffer[READ_BUFFER_SIZE];
	DWORD bytesRead;
	File  file;

	updateFileName(netFile);
	updateStatus(msg("Connecting..."));
	setMarquee(true, false);

	try
	{
		netFile->open(internet);
	}
	catch(exception &e)
	{
		setMarquee(false, netFile->size == FILE_SIZE_UNKNOWN);
		updateStatus(msg(e.what()));
		storeError(msg(e.what()));
		return false;
	}

	if(!netFile->handle)
	{
		setMarquee(false, netFile->size == FILE_SIZE_UNKNOWN);
		updateStatus(msg("Cannot connect"));
		storeError();
		return false;
	}

	file.open(netFile->name);

	Timer progressTimer(100);
	Timer speedTimer(1000);

	updateStatus(msg("Downloading..."));

	if(!(netFile->size == FILE_SIZE_UNKNOWN))
		setMarquee(false, false);

	while(true)
	{
		if(downloadCancelled)
		{
			file.close();
			netFile->close();
			return true;
		}

		if(!netFile->read(buffer, READ_BUFFER_SIZE, &bytesRead))
		{
			setMarquee(false, netFile->size == FILE_SIZE_UNKNOWN);
			updateStatus(msg("Download failed"));
			storeError();
			file.close();
			netFile->close();
			return false;
		}

		if(bytesRead == 0)
			break;

		file.write(buffer, bytesRead);

		if(progressTimer.elapsed())
			updateProgress(netFile);

		if(speedTimer.elapsed())
			updateSpeed(netFile, &speedTimer);

		if(sizeTimeTimer.elapsed())
			updateSizeTime(netFile, &sizeTimeTimer);
	}

	updateProgress(netFile);
	updateSpeed(netFile, &speedTimer);
	updateSizeTime(netFile, &sizeTimeTimer);
	updateStatus(msg("Download complete"));

	file.close();
	netFile->close();
	netFile->downloaded = true;

	return true;
}
int TFileOpen::doCommands(int Command, HWND hWndSource, UINT Notification)
{         
        switch(Command)
        {
                case id_FName:
                        if (Notification == EN_CHANGE)
                                EnableWindow(GetDlgItem(hWindow, IDOK),
                                        (WORD) SendMessage(hWndSource, WM_GETTEXTLENGTH, 0, 0));
                        return TRUE;

                case id_FList:
                        switch(Notification)
                        {
                                case LBN_DBLCLK:
                                        PostMessage(hWindow, WM_COMMAND, IDOK, 0);
					return TRUE;
				
                                case LBN_SELCHANGE:
                                        DlgDirSelect(hWindow, pathName, id_FList);
                                        updateFileName();
                                        return TRUE;

                                case LBN_KILLFOCUS:
                                        SendMessage(hWndSource, LB_SETCURSEL, -1, 0);
                                        return TRUE;
                        }
                case id_DList:
                        switch(Notification)
                        {
				case LBN_DBLCLK:
					updateListBoxes();
					return TRUE;
				case LBN_SELCHANGE:
					DlgDirSelect(hWindow, pathName, id_DList);
                                        strcat(pathName, fileSpec);
					updateFileName();
                                        return TRUE;
				case LBN_KILLFOCUS:
                                        SendMessage(hWndSource, LB_SETCURSEL, -1, 0);
                                        return TRUE;
                        }

                case id_Scribble:
                        strcat(strcpy(pathName,getFileFirst(pathName)), ScribbleExtension);
                        updateFileName();
                        return TRUE;
                case id_Graph:
                        strcat(strcpy(pathName,getFileFirst(pathName)), GraphExtension);
                        updateFileName();
                        return TRUE;
                case id_Text:
                        if (strcmp(getExtension(pathName),"."))
                        {
                                strcat(strcpy(pathName,getFileFirst(pathName)), ".TXT");
                                updateFileName();
                        }
                        return TRUE;
                default:
                        return TDialog::doCommands(Command, hWndSource, Notification);
        }
}
示例#22
0
DWORDLONG Downloader::getFileSizes(bool useComponents)
{
    if(ownMsgLoop)
        downloadCancelled = false;

    if(files.empty())
        return 0;

    updateStatus(msg("Initializing..."));
    processMessages();

    if(!openInternet())
    {
        storeError();
        return FILE_SIZE_UNKNOWN;
    }

    filesSize = 0;
    bool sizeUnknown = false;

    for(map<tstring, NetFile *>::iterator i = files.begin(); i != files.end(); i++)
    {
        updateStatus(msg("Getting file information..."));
        processMessages();

        NetFile *file = i->second;

        if(downloadCancelled)
            break;

        if(useComponents)
            if(!file->selected(components))
                continue;

        if(file->size == FILE_SIZE_UNKNOWN)
        {
            try
            {
                try
                {
                    updateFileName(file);
                    processMessages();
                    file->size = file->url.getSize(internet);
                }
                catch(HTTPError &e)
                {
                    updateStatus(msg(e.what()));
                    //TODO: if allowContinue==0 & error code == file not found - stop.
                }
                
                if(file->size == FILE_SIZE_UNKNOWN)
                    checkMirrors(i->first, false);
            }
            catch(FatalNetworkError &e)
            {
                updateStatus(msg(e.what()));
                storeError(msg(e.what()));
                closeInternet();
                return OPERATION_STOPPED;
            }
        }

        if(!(file->size == FILE_SIZE_UNKNOWN))
            filesSize += file->size;
        else
            sizeUnknown = true;
    }

    closeInternet();

    if(sizeUnknown && !filesSize)
        filesSize = FILE_SIZE_UNKNOWN; //TODO: if only part of files has unknown size - ???

#ifdef _DEBUG
    TRACE(_T("getFileSizes result:"));

    for(map<tstring, NetFile *>::iterator i = files.begin(); i != files.end(); i++)
    {
        NetFile *file = i->second;
        TRACE(_T("    %s: %s"), file->getShortName().c_str(), (file->size == FILE_SIZE_UNKNOWN) ? _T("Unknown") : itotstr((DWORD)file->size).c_str()); 
    }
#endif

    return filesSize;
}
示例#23
0
bool Downloader::scanFtpDir(FtpDir *ftpDir, tstring destsubdir)
{
    Url url(ftpDir->url);
    url.internetOptions = internetOptions;
    
    updateFileName(url.components.lpszUrlPath);
    
    if(!url.connect(internet))
    {
        storeError();
        return false;
    }
    
    if(!FtpSetCurrentDirectory(url.connection, url.components.lpszUrlPath))
    {
        storeError();
        return false;
    }
    
    list<tstring> dirs;
    WIN32_FIND_DATA fd;

    TRACE(_T("Scanning FTP dir %s:"), ftpDir->url.c_str());
    HINTERNET handle = FtpFindFirstFile(url.connection, ftpDir->mask.c_str(), &fd, NULL, NULL);

    if(handle)
    {
        TRACE(_T("    (%s) %s"), (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? _T("D") : _T("F"), fd.cFileName);
        updateFileName(tstring(fd.cFileName));

        if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            tstring dirname(fd.cFileName);

            if(!(dirname.compare(_T(".")) == 0) && !(dirname.compare(_T("..")) == 0))
                dirs.push_back(dirname);
        }
        else
        {
            tstring fileUrl  = addslash(ftpDir->url);
            tstring fileName = addbackslash(ftpDir->destdir);
            fileUrl  += tstring(fd.cFileName);
            fileName += addbackslash(destsubdir);
            fileName += tstring(fd.cFileName);
            
            addFile(fileUrl, fileName, ((DWORDLONG)fd.nFileSizeHigh << 32) | fd.nFileSizeLow, ftpDir->compstr);
        }

        while(InternetFindNextFile(handle, &fd))
        {
            TRACE(_T("    (%s) %s"), (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? _T("D") : _T("F"), fd.cFileName);
            updateFileName(tstring(fd.cFileName));

            if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                tstring dirname(fd.cFileName);

                if(!(dirname.compare(_T(".")) == 0) && !(dirname.compare(_T("..")) == 0))
                    dirs.push_back(dirname);
            }
            else
            {
                tstring fileUrl  = addslash(ftpDir->url);
                tstring fileName = addbackslash(ftpDir->destdir);
                fileUrl  += tstring(fd.cFileName);
                fileName += addbackslash(destsubdir);
                fileName += tstring(fd.cFileName);
                
                addFile(fileUrl, fileName, ((DWORDLONG)fd.nFileSizeHigh << 32) | fd.nFileSizeLow, ftpDir->compstr);
            }
        }
    }

    url.disconnect();

    if(ftpDir->recursive && !dirs.empty())
    {
        for(list<tstring>::iterator i = dirs.begin(); i != dirs.end(); i++)
        {
            tstring dir = *i;

            tstring urlstr = addslash(ftpDir->url);
            urlstr += dir;
            FtpDir fdir(urlstr, ftpDir->mask, ftpDir->destdir, ftpDir->recursive, ftpDir->compstr);
            
            if(preserveFtpDirs)
            {
                tstring destdir(addbackslash(ftpDir->destdir));
                destdir += addbackslash(destsubdir);
                destdir += dir;
                TRACE(_T("Creating directory %s"), destdir.c_str());
                _tmkdir(destdir.c_str());

                tstring subdir = addbackslash(destsubdir);
                subdir += dir;
                scanFtpDir(&fdir, subdir);
            }
            else
                scanFtpDir(&fdir);
        }
    }

    return true;
}