Logo Search packages:      
Sourcecode: valknut version File versions  Download package

dcfiletool.cpp

/***************************************************************************
                          dcfiletool.cpp  -  description
                             -------------------
    begin                : Die Mär 26 2002
    copyright            : (C) 2002 by Mathias Küster
    email                : mathen@users.berlios.de
 ***************************************************************************/

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

#include <stdlib.h>

#include <qstring.h>
#include <qfile.h>
#include <qmessagebox.h>
#include <qinputdialog.h>
#include <qdir.h>
#include <qregexp.h>
#include <qpopupmenu.h>
#include <qcursor.h>

#include <dclib/core/cdir.h>
#include <dclib/chttp.h>

#include <dcconfig.h>
#include <dctransferview.h>
#include <dcconnectionmanager.h>

#include "dcfiletool.h"

#include <dclib/dcos.h>

/** */
DCFileTool::DCFileTool()
{
      Init();
}

/** */
DCFileTool::~DCFileTool()
{
}

/** */
void DCFileTool::Init()
{
      m_nLastDownloadCase = -1;
      m_bCaseAllFiles     = FALSE;
}

/** */
bool DCFileTool::SelectFileSource( ulonglong size, QString & file, QString & localrootpath, QString & localpath )
{
      bool res = FALSE;
      QStringVector LocalFilesList;
      int id;

      g_pTransferView->GetLocalFilesList( LocalFilesList, size );

      if ( LocalFilesList.empty() )
      {
            return res;
      }

      // Add as an extra source
      QPopupMenu * m = new QPopupMenu;

      for ( int iter=0; iter<(int)LocalFilesList.size(); iter++ )
      {
            if ( LocalFilesList[iter].contains("\\") )
            {
                  m->insertItem( LocalFilesList[iter].section("\\",-1,-1), iter );
            }
            else
            {
                  m->insertItem( LocalFilesList[iter].section("/",-1,-1), iter );
            }
      }

      m->insertItem( tr("(choose an existing download to add to)"), 999);
      m->setItemEnabled(999,false);

      id = m->exec(QCursor::pos());

      delete m;

      if ( id != -1 )
      {
            QFileInfo fi(LocalFilesList[id]);

            file          = fi.fileName();
            localpath     = "";
            localrootpath = fi.dirPath();

            // now we must check if a localpath exist
            if ( localrootpath.find( g_pConfig->GetDownloadFolder().Data(), 0 ) == 0 )
            {
                  localpath     = localrootpath.mid( g_pConfig->GetDownloadFolder().Length(), localrootpath.length()-g_pConfig->GetDownloadFolder().Length() );
                  localrootpath = g_pConfig->GetDownloadFolder().Data();
            }

            res = TRUE;
      }

      return res;
}

/** */
bool DCFileTool::AddFileSource( CString nick, CString hubname, CString hubhost,
                        CString remotename, CString localname,
                        CString localpath, CString localrootpath,
                        eltMedium medium, ulonglong size, CString tth )
{
      bool res = FALSE;
      QString sourcefile = "",slocalrootpath,slocalpath;

      if ( SelectFileSource( size, sourcefile, slocalrootpath, slocalpath ) == FALSE )
      {
            return CheckFile( nick, hubname, hubhost,
                        remotename, localname,
                        localpath, localrootpath,
                        medium, size, tth );
      }

      if ( !sourcefile.isEmpty() )
      {
            // add transfer to the waitlist
            res = CheckFile( nick, hubname, hubhost,
                        remotename, sourcefile.ascii(),
                        slocalpath.ascii(), slocalrootpath.ascii(),
                        medium, size, tth, TRUE );

      }

      return res;
}

/** */
bool DCFileTool::CheckFile( CString nick, CString hubname, CString hubhost,
                        CString remotename, CString localname,
                        CString localpath, CString localrootpath,
                        eltMedium medium, ulonglong size, CString hash,
                        bool usermulti, eRepairType repair )
{
      CDir dir;
      CString s;
      QString name;
      ulonglong fsize, pos_s, pos_e;
      int filestate,i;
      bool multi = usermulti;

      // first we get the filestate from the downloadmanager
      filestate = g_pTransferView->DLM_QueueCheck( nick, hubname, hubhost,
                  remotename, localname,
                  localpath, localrootpath,
                  medium, size );

      if ( filestate == 1 )
      {
//          QMessageBox::information( this, tr("File download"),
//                tr("The same user/file is already in the queue !\n"));
            return FALSE;
      }
      else if ( (filestate == 2) && (multi == FALSE) )
      {
            switch( QMessageBox::warning( this, tr("File download"),
                  tr("A same file is already in the queue!"),
                    tr("Start a multi-download"),
                  tr("Cancel"), 0, 1 ) )
            {
                  case 0:
                        multi = TRUE;
                        break;
                  default:
                        return FALSE;
                        break;
            }
      }
      else if ( filestate == 3 )
      {
            QMessageBox::information( this, tr("File download"),
                  tr("File is already in the queue but not mark as a multi-download!\n"));
            return FALSE;
      }
      else if ( filestate == 4 )
      {
            QMessageBox::information( this, tr("File download"),
                  tr("File is already in the queue with a different size!\n"));
            return FALSE;
      }
      else if ( filestate == 0 )
      {
            if ( localrootpath != "" )
            {
                  name = localrootpath.Data();
            }
            else
            {
                  name = g_pConfig->GetDownloadFolder().Data();
            }

            if ( name == "" )
            {
                  return FALSE;
            }

            localpath = localpath.Replace(':',"");
            localname = localname.Replace(':',"");

            name = name + "/" + localpath.Data() + "/" + localname.Data();
            name = dir.SimplePath(name.ascii()).Data();

            QFile f(name);

            fsize = dir.getFileSize(name.ascii(),FALSE);

            // check already download
            if ( (size == fsize) && (fsize > 0) && !repair )
            {
                  QMessageBox::information( this, tr("File download"),
                        tr("File already downloaded!\n"));
                  return FALSE;
            }

            // check for partial download
            if ( fsize > 0 )
            {
                  if( repair )
                        {
                        // get desired byte range
                        QString buf;
                        char *b, *p;
                        bool ok = FALSE;

                        // There is probably a better way to get this info.  We assume 2352 sector size (ss)
                        // which is most common for BIN/CUE, but we might want to make two menu entries, one
                        // for 2352 and one for 2048 (ie. ISO).  The sector offset (so) is the number of bytes
                        // into the BIN file where sector zero is reported.  Fireburner for Linux reports
                        // from the beginning of the file, but other programs (like cdmage) report from the
                        // first data sector (skipping all header and directory information).  We assume zero.
                        int ss = 2352;
                        int so = 0;

                        if( repair == ertBYTES )
                              buf = QInputDialog::getText(
                                    tr("Repair File"),
                                    tr("Enter byte range (m-n)"),
                                    QLineEdit::Normal, QString::null, &ok, 0 );
                        else
                              buf = QInputDialog::getText(
                                    tr("Repair BIN Sectors"),
                                    tr("Enter sector range (m[-n])"),
                                    QLineEdit::Normal, QString::null, &ok, 0 );

                        if( !ok )
                              return FALSE;

                        b = (char*) buf.ascii();
                        s = b;
                        pos_s = s.asULL();

                        p = strchr( b, '-' );
                        if( p ) {
                              s = p+1;
                              pos_e = s.asULL();
                        }
                        else
                              {
                              if( repair == ertBYTES )
                                    return FALSE;
                              pos_e = 0;
                              }

                        if( repair == ertSECTORS )
                              {
                              if( !pos_e )
                                    pos_e = pos_s;
                              pos_s = so + pos_s * ss;
                              pos_e = so + (pos_e+1) * ss - 1;
                              }

                        if( pos_e > fsize )
                              pos_e = fsize;
                        if( pos_s > pos_e )
                              pos_s = pos_e;

                        multi = TRUE;
                        printf( "Starting download repair, %s, %lld-%lld\n", name.ascii(), pos_s, pos_e );
                        }
                  else
                  {
                        pos_e = 0;
                        switch( QMessageBox::warning( this, tr("File download"),
                              tr("File already exists!"),
                              tr("Resume"),
                              tr("Overwrite"),
                              tr("Cancel"), 0) )
                        {
                              case 0:
                                    pos_s = fsize;
                                    break;
                              case 1:
                                    f.remove();
                                    fsize = 0;
                                    pos_s = 0;
                                    break;
                              case 2:
                                    return FALSE;
                                    break;
                        }
                  }
            }

            if ( fsize == 0 )
            {
                  pos_s = 0;
                  pos_e = 0;

                  if ( size > (1024*1024) )
                  {
                        if ( (g_pConfig->GetDefaultDownloadMode() == 0) && (multi == FALSE) )
                        {
                              if ( m_bCaseAllFiles == FALSE )
                              {
                                    i = QMessageBox::warning( this, tr("File download"),
                                                        tr("You can start a multi-download!"),
                                                        QMessageBox::Yes | QMessageBox::Default,
                                                        QMessageBox::No | QMessageBox::Escape,
                                                        0 );

                                    if ( m_nLastDownloadCase == -1 )
                                    {
                                          switch ( QMessageBox::warning( this, tr("File download"),
                                                                   tr("Do you want to download all files in this mode?"),
                                                                   QMessageBox::Yes | QMessageBox::Default,
                                                                   QMessageBox::No | QMessageBox::Escape,
                                                                   0 ) )
                                          {
                                          case QMessageBox::Yes:
                                                m_bCaseAllFiles = TRUE;
                                                break;
                                          default:
                                                break;
                                          }
                                    }

                                    m_nLastDownloadCase = i;
                              }

                              switch( m_nLastDownloadCase )
                              {
                                    case QMessageBox::Yes:
                                          multi = TRUE;
                                                break;
                                    default:
                                          break;
                              }
                        }
                        else if ( (g_pConfig->GetDefaultDownloadMode() == 1) && (multi == FALSE) )
                        {
                              multi=FALSE;
                        }
                        else
                        {
                              multi=TRUE;
                        }
                  }
                  else
                  {
                        multi = FALSE;
                  }
            }
      }

      if ( g_pConnectionManager->IsHubOnline(hubname,hubhost) == ehsNONE )
      {
            /* Check if the user is connected to another hub that we are connected to.
             * I'm uncertain how it will react when multi==FALSE (thus that is not handled),
             * but as this concerns small files it is a bit annoying.
             */
            bool foundUser = FALSE;

            if ( multi == TRUE )
            {
                  CList<DCHubObject> HubList;
                  CString emptyString = CString("");
                  DCHubObject * CurrentHub = 0;
                  
                  /* Get hublist for the user, ie hubs that both us and them are
                   * connected to.
                   */
                  if( g_pConnectionManager->IsUserOnline(nick,emptyString,emptyString,&HubList) )
                  {
                        /* Add an item in the queue for each hub, mark the user as found */
                        while((CurrentHub =  HubList.Next(CurrentHub) ) != 0 )
                        {
                              foundUser = TRUE;
                              g_pTransferView->DLM_QueueAdd( nick, CurrentHub->m_sHubName, CurrentHub->m_sHubHost,
                                                remotename, localname,
                                                localpath, localrootpath,
                                                medium, size, pos_s, pos_e, hash, multi );
                        }
                  }
            }
            /* Usual behavior:
             * (no user found or option not enabled)
             */
            if(foundUser == FALSE)
            {
                  switch( QMessageBox::warning( this, tr("File download"),
                                    tr("Not connected to required hub!"),
                                    tr("Connect"),
                                    tr("Cancel"), 0, 0, 1 ) )
                  {
                        case 0:
                              g_pConnectionManager->Connect(hubname.Data(),hubhost.Data());
                              break;
                        case 1:
                              break;
                  }
            }
      }

      g_pTransferView->DLM_QueueAdd( nick, hubname, hubhost,
                        remotename, localname,
                        localpath, localrootpath,
                        medium, size, pos_s, pos_e, hash, multi );

      return TRUE;
}

Generated by  Doxygen 1.6.0   Back to index