2010-03-10 16:38:26 -05:00
/***************************************************************************
* Copyright ( C ) 2009 *
* *
* 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 . *
* *
* This program 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 General Public License for more details . *
* *
* You should have received a copy of the GNU General Public License *
* along with this program ; if not , write to the *
* Free Software Foundation , Inc . , *
* 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA . *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <iostream>
# include <QStringList>
2010-03-22 15:46:58 -04:00
# include <QRegExp>
# include <QApplication>
# include <QMimeData>
# include <QClipboard>
2010-07-15 07:25:34 -04:00
# include <QDesktopServices>
# include <QMessageBox>
# include <QIcon>
# include <QObject>
2010-03-10 16:38:26 -05:00
# include "RetroShareLink.h"
2011-04-19 15:42:44 -04:00
# include "MainWindow.h"
# include "ForumsDialog.h"
# include "ChannelFeed.h"
2010-08-06 11:31:30 -04:00
# include "util/misc.h"
2010-09-28 16:33:34 -04:00
# include "common/PeerDefs.h"
2010-03-10 16:38:26 -05:00
2010-08-06 05:40:23 -04:00
# include <retroshare/rsfiles.h>
# include <retroshare/rspeers.h>
2011-04-19 15:42:44 -04:00
# include <retroshare/rsforums.h>
# include <retroshare/rschannels.h>
2010-07-15 07:25:34 -04:00
2011-02-09 16:44:49 -05:00
//#define DEBUG_RSLINK 1
2010-03-10 16:38:26 -05:00
2010-11-18 11:31:44 -05:00
# define HOST_FILE "file"
# define HOST_PERSON "person"
2011-04-19 15:42:44 -04:00
# define HOST_FORUM "forum"
# define HOST_CHANNEL "channel"
# define HOST_REGEXP "file|person|forum|channel"
2010-11-18 11:31:44 -05:00
# define FILE_NAME "name"
# define FILE_SIZE "size"
# define FILE_HASH "hash"
# define PERSON_NAME "name"
# define PERSON_HASH "hash"
2010-03-10 16:38:26 -05:00
2011-04-19 15:42:44 -04:00
# define FORUM_NAME "name"
# define FORUM_ID "id"
# define FORUM_MSGID "msgid"
# define CHANNEL_NAME "name"
# define CHANNEL_ID "id"
# define CHANNEL_MSGID "msgid"
2010-03-10 18:09:35 -05:00
RetroShareLink : : RetroShareLink ( const QUrl & url )
2010-03-10 16:38:26 -05:00
{
2010-11-18 11:31:44 -05:00
fromUrl ( url ) ;
2010-07-15 07:25:34 -04:00
}
RetroShareLink : : RetroShareLink ( const QString & url )
{
fromString ( url ) ;
}
void RetroShareLink : : fromString ( const QString & url )
{
2010-11-18 11:31:44 -05:00
clear ( ) ;
2010-07-15 07:25:34 -04:00
// parse
2010-03-10 16:38:26 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
std : : cerr < < " got new RS link \" " < < url . toStdString ( ) < < " \" " < < std : : endl ;
2010-03-10 16:38:26 -05:00
# endif
2010-11-18 11:31:44 -05:00
if ( ( url . startsWith ( QString ( RSLINK_SCHEME ) + " :// " + QString ( HOST_FILE ) ) & & url . count ( " | " ) = = 3 ) | |
( url . startsWith ( QString ( RSLINK_SCHEME ) + " :// " + QString ( HOST_PERSON ) ) & & url . count ( " | " ) = = 2 ) ) {
/* Old link, we try it */
QStringList list = url . split ( " | " ) ;
if ( list . size ( ) > = 1 ) {
if ( list . size ( ) = = 4 & & list [ 0 ] = = QString ( RSLINK_SCHEME ) + " :// " + QString ( HOST_FILE ) ) {
bool ok ;
2010-03-10 16:38:26 -05:00
2010-11-18 11:31:44 -05:00
_type = TYPE_FILE ;
_name = list [ 1 ] ;
_size = list [ 2 ] . toULongLong ( & ok ) ;
_hash = list [ 3 ] . left ( 40 ) ; // normally not necessary, but it's a security.
2010-03-10 16:38:26 -05:00
2010-11-18 11:31:44 -05:00
if ( ok ) {
2010-03-10 16:38:26 -05:00
# ifdef DEBUG_RSLINK
2010-11-18 11:31:44 -05:00
std : : cerr < < " New RetroShareLink forged: " < < std : : endl ;
std : : cerr < < " name = \" " < < _name . toStdString ( ) < < " \" " < < std : : endl ;
std : : cerr < < " hash = \" " < < _hash . toStdString ( ) < < " \" " < < std : : endl ;
std : : cerr < < " size = " < < _size < < std : : endl ;
2010-03-10 16:38:26 -05:00
# endif
2010-11-18 11:31:44 -05:00
check ( ) ;
return ;
}
} else if ( list . size ( ) = = 3 & & list [ 0 ] = = QString ( RSLINK_SCHEME ) + " :// " + QString ( HOST_PERSON ) ) {
_type = TYPE_PERSON ;
_name = list [ 1 ] ;
_hash = list [ 2 ] . left ( 40 ) ; // normally not necessary, but it's a security.
_size = 0 ;
2010-07-15 07:25:34 -04:00
check ( ) ;
return ;
}
2010-11-18 11:31:44 -05:00
// bad link
}
}
/* Now try QUrl */
2011-01-14 19:25:25 -05:00
fromUrl ( QUrl : : fromEncoded ( url . toAscii ( ) ) ) ;
2010-11-18 11:31:44 -05:00
}
void RetroShareLink : : fromUrl ( const QUrl & url )
{
clear ( ) ;
// parse
# ifdef DEBUG_RSLINK
std : : cerr < < " got new RS link \" " < < url . toString ( ) . toStdString ( ) < < " \" " < < std : : endl ;
# endif
if ( url . scheme ( ) ! = RSLINK_SCHEME ) {
/* No RetroShare-Link */
return ;
}
if ( url . host ( ) = = HOST_FILE ) {
bool ok ;
_type = TYPE_FILE ;
_name = url . queryItemValue ( FILE_NAME ) ;
_size = url . queryItemValue ( FILE_SIZE ) . toULongLong ( & ok ) ;
_hash = url . queryItemValue ( FILE_HASH ) . left ( 40 ) ; // normally not necessary, but it's a security.
if ( ok ) {
# ifdef DEBUG_RSLINK
std : : cerr < < " New RetroShareLink forged: " < < std : : endl ;
std : : cerr < < " name = \" " < < _name . toStdString ( ) < < " \" " < < std : : endl ;
std : : cerr < < " hash = \" " < < _hash . toStdString ( ) < < " \" " < < std : : endl ;
std : : cerr < < " size = " < < _size < < std : : endl ;
# endif
2010-07-15 07:25:34 -04:00
check ( ) ;
return ;
}
2010-11-18 11:31:44 -05:00
}
2010-07-15 07:25:34 -04:00
2010-11-18 11:31:44 -05:00
if ( url . host ( ) = = HOST_PERSON ) {
_type = TYPE_PERSON ;
_name = url . queryItemValue ( PERSON_NAME ) ;
_hash = url . queryItemValue ( PERSON_HASH ) . left ( 40 ) ; // normally not necessary, but it's a security.
_size = 0 ;
check ( ) ;
return ;
2010-07-15 07:25:34 -04:00
}
2010-03-10 16:38:26 -05:00
2011-04-19 15:42:44 -04:00
if ( url . host ( ) = = HOST_FORUM ) {
_type = TYPE_FORUM ;
_name = url . queryItemValue ( FORUM_NAME ) ;
_hash = url . queryItemValue ( FORUM_ID ) ;
_msgId = url . queryItemValue ( FORUM_MSGID ) ;
_size = 0 ;
check ( ) ;
return ;
}
if ( url . host ( ) = = HOST_CHANNEL ) {
_type = TYPE_CHANNEL ;
_name = url . queryItemValue ( CHANNEL_NAME ) ;
_hash = url . queryItemValue ( CHANNEL_ID ) ;
_msgId = url . queryItemValue ( CHANNEL_MSGID ) ;
_size = 0 ;
check ( ) ;
return ;
}
2010-11-18 11:31:44 -05:00
// bad link
2010-03-10 16:38:26 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
std : : cerr < < " Wrongly formed RS link. Can't process. " < < std : : endl ;
2010-03-10 16:38:26 -05:00
# endif
2010-11-18 11:31:44 -05:00
clear ( ) ;
2010-03-10 16:38:26 -05:00
}
2011-04-19 15:42:44 -04:00
// file
2010-03-10 16:38:26 -05:00
RetroShareLink : : RetroShareLink ( const QString & name , uint64_t size , const QString & hash )
2010-07-15 07:25:34 -04:00
: _name ( name ) , _size ( size ) , _hash ( hash )
2010-03-10 16:38:26 -05:00
{
2010-07-15 07:25:34 -04:00
_valid = false ;
_type = TYPE_FILE ;
check ( ) ;
2010-03-10 16:38:26 -05:00
}
2011-04-19 15:42:44 -04:00
// person
2010-07-15 07:25:34 -04:00
RetroShareLink : : RetroShareLink ( const QString & name , const QString & hash )
: _name ( name ) , _size ( 0 ) , _hash ( hash )
2010-03-10 16:38:26 -05:00
{
2010-07-15 07:25:34 -04:00
_valid = false ;
_type = TYPE_PERSON ;
check ( ) ;
}
2010-03-10 16:38:26 -05:00
2011-04-19 15:42:44 -04:00
// forum, channel
RetroShareLink : : RetroShareLink ( enumType type , const QString & name , const QString & id , const QString & msgId )
: _name ( name ) , _size ( 0 ) , _hash ( id ) , _msgId ( msgId )
{
_valid = false ;
_type = TYPE_UNKNOWN ;
switch ( type ) {
case TYPE_UNKNOWN :
case TYPE_FILE :
case TYPE_PERSON :
// wrong type
break ;
case TYPE_FORUM :
case TYPE_CHANNEL :
_type = type ;
break ;
}
check ( ) ;
}
2010-11-18 11:31:44 -05:00
void RetroShareLink : : clear ( )
{
_valid = false ;
_type = TYPE_UNKNOWN ;
_hash = " " ;
_size = 0 ;
_name = " " ;
}
2010-07-15 07:25:34 -04:00
void RetroShareLink : : check ( )
{
_valid = true ;
switch ( _type ) {
case TYPE_UNKNOWN :
_valid = false ;
break ;
case TYPE_FILE :
if ( _size > ( ( ( uint64_t ) 1 ) < < 40 ) ) // 1TB. Who has such large files?
_valid = false ;
if ( ! checkName ( _name ) )
_valid = false ;
if ( ! checkHash ( _hash ) )
_valid = false ;
break ;
case TYPE_PERSON :
if ( _size ! = 0 )
_valid = false ;
if ( _name . isEmpty ( ) )
_valid = false ;
2011-04-19 15:42:44 -04:00
if ( _hash . isEmpty ( ) )
_valid = false ;
break ;
case TYPE_FORUM :
if ( _size ! = 0 )
_valid = false ;
if ( _name . isEmpty ( ) )
_valid = false ;
if ( _hash . isEmpty ( ) )
_valid = false ;
break ;
case TYPE_CHANNEL :
if ( _size ! = 0 )
_valid = false ;
if ( _name . isEmpty ( ) )
_valid = false ;
2010-07-15 07:25:34 -04:00
if ( _hash . isEmpty ( ) )
_valid = false ;
break ;
}
if ( ! _valid ) // we should throw an exception instead of this crap, but drbob doesn't like exceptions. Why ???
{
_type = TYPE_UNKNOWN ;
_hash = " " ;
_name = " " ;
_size = 0 ;
}
2010-03-10 16:38:26 -05:00
}
2011-05-01 18:26:41 -04:00
QString RetroShareLink : : title ( ) const
{
if ( ! valid ( ) ) {
return " " ;
}
switch ( _type ) {
case TYPE_UNKNOWN :
break ;
case TYPE_FILE :
return QString ( " %1 (%2) " ).arg(hash()).arg(misc::friendlyUnit(size())) ;
case TYPE_PERSON :
case TYPE_FORUM :
case TYPE_CHANNEL :
break ;
}
return " " ;
}
2011-01-14 19:25:25 -05:00
QString RetroShareLink : : toString ( bool encoded /*= true*/ ) const
2010-03-10 16:38:26 -05:00
{
2010-07-15 07:25:34 -04:00
switch ( _type ) {
case TYPE_UNKNOWN :
break ;
case TYPE_FILE :
2010-11-18 11:31:44 -05:00
{
QUrl url ;
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_FILE ) ;
url . addQueryItem ( FILE_NAME , _name ) ;
url . addQueryItem ( FILE_SIZE , QString : : number ( _size ) ) ;
url . addQueryItem ( FILE_HASH , _hash ) ;
2011-01-14 19:25:25 -05:00
if ( encoded ) {
return url . toEncoded ( ) ;
}
2010-11-18 11:31:44 -05:00
return url . toString ( ) ;
}
2010-07-15 07:25:34 -04:00
case TYPE_PERSON :
2010-11-18 11:31:44 -05:00
{
QUrl url ;
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_PERSON ) ;
url . addQueryItem ( PERSON_NAME , _name ) ;
url . addQueryItem ( PERSON_HASH , _hash ) ;
2011-01-14 19:25:25 -05:00
if ( encoded ) {
return url . toEncoded ( ) ;
}
2011-04-19 15:42:44 -04:00
return url . toString ( ) ;
}
case TYPE_FORUM :
{
QUrl url ;
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_FORUM ) ;
url . addQueryItem ( FORUM_NAME , _name ) ;
url . addQueryItem ( FORUM_ID , _hash ) ;
if ( ! _msgId . isEmpty ( ) ) {
url . addQueryItem ( FORUM_MSGID , _msgId ) ;
}
if ( encoded ) {
return url . toEncoded ( ) ;
}
return url . toString ( ) ;
}
case TYPE_CHANNEL :
{
QUrl url ;
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_CHANNEL ) ;
url . addQueryItem ( CHANNEL_NAME , _name ) ;
url . addQueryItem ( CHANNEL_ID , _hash ) ;
if ( ! _msgId . isEmpty ( ) ) {
url . addQueryItem ( CHANNEL_MSGID , _msgId ) ;
}
if ( encoded ) {
return url . toEncoded ( ) ;
}
2010-11-18 11:31:44 -05:00
return url . toString ( ) ;
}
2010-07-15 07:25:34 -04:00
}
return " " ;
2010-03-10 16:38:26 -05:00
}
2010-07-15 07:25:34 -04:00
QString RetroShareLink : : niceName ( ) const
{
if ( type ( ) = = TYPE_PERSON ) {
2010-09-28 16:33:34 -04:00
return PeerDefs : : rsid ( name ( ) . toStdString ( ) , hash ( ) . toStdString ( ) ) ;
2010-07-15 07:25:34 -04:00
}
return name ( ) ;
}
2010-03-15 08:57:08 -04:00
QString RetroShareLink : : toHtml ( ) const
2010-03-22 15:46:58 -04:00
{
2011-05-01 18:26:41 -04:00
QString html = " <a href= \" " + toString ( true ) ;
QString linkTitle = title ( ) ;
if ( ! linkTitle . isEmpty ( ) ) {
html + = " title= \" " + linkTitle + " \" " ;
}
html + = " \" > " + niceName ( ) + " </a> " ;
return html ;
2010-03-22 15:46:58 -04:00
}
2010-07-15 07:25:34 -04:00
2010-03-22 15:46:58 -04:00
QString RetroShareLink : : toHtmlFull ( ) const
2010-03-15 08:57:08 -04:00
{
2011-01-14 19:25:25 -05:00
return QString ( " <a href= \" " ) + toString ( true ) + " \" > " + toString ( false ) + " </a> " ;
2010-03-15 08:57:08 -04:00
}
2010-03-10 16:38:26 -05:00
2010-08-06 11:31:30 -04:00
QString RetroShareLink : : toHtmlSize ( ) const
{
2011-01-14 19:25:25 -05:00
return QString ( " <a href= \" " ) + toString ( true ) + " \" > " + name ( ) + " </a> " + " " + " <font color= \" blue \" > " + " ( " + misc : : friendlyUnit ( _size ) + " ) " + " </font> " ;
2010-08-06 11:31:30 -04:00
}
2010-03-10 16:38:26 -05:00
bool RetroShareLink : : checkName ( const QString & name )
{
2010-07-15 07:25:34 -04:00
if ( name = = " " )
return false ;
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
for ( int i = 0 ; i < name . length ( ) ; + + i )
{
QChar : : Category cat ( name [ i ] . category ( ) ) ;
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
if ( cat = = QChar : : Separator_Line
| | cat = = QChar : : Other_NotAssigned
)
{
2010-03-10 16:38:26 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
std : : cerr < < " Unwanted category " < < cat < < " at place " < < i < < " in string \" " < < name . toStdString ( ) < < " \" " < < std : : endl ;
2010-03-10 16:38:26 -05:00
# endif
2010-07-15 07:25:34 -04:00
return false ;
}
}
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
return true ;
2010-03-10 16:38:26 -05:00
}
2010-03-10 18:09:35 -05:00
QUrl RetroShareLink : : toUrl ( ) const
{
2010-07-15 07:25:34 -04:00
return QUrl ( toString ( ) ) ;
2010-03-10 18:09:35 -05:00
}
2010-03-10 16:38:26 -05:00
bool RetroShareLink : : checkHash ( const QString & hash )
{
2010-07-15 07:25:34 -04:00
if ( hash . length ( ) ! = 40 )
return false ;
QByteArray qb ( hash . toAscii ( ) ) ;
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
for ( int i = 0 ; i < qb . length ( ) ; + + i )
{
unsigned char b ( qb [ i ] ) ;
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
if ( ! ( ( b > 47 & & b < 58 ) | | ( b > 96 & & b < 103 ) ) )
return false ;
}
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
return true ;
}
2010-03-10 16:38:26 -05:00
2010-09-24 17:01:13 -04:00
bool RetroShareLink : : process ( int flag )
2010-07-15 07:25:34 -04:00
{
if ( valid ( ) = = false ) {
std : : cerr < < " RetroShareLink::process invalid request " < < std : : endl ;
return false ;
}
switch ( type ( ) ) {
case TYPE_UNKNOWN :
break ;
case TYPE_FILE :
{
2011-02-09 16:44:49 -05:00
# ifdef DEBUG_RSLINK
2010-09-17 17:54:25 -04:00
std : : cerr < < " RetroShareLink::process FileRequest : fileName : " < < name ( ) . toUtf8 ( ) . constData ( ) < < " . fileHash : " < < hash ( ) . toStdString ( ) < < " . fileSize : " < < size ( ) < < std : : endl ;
2011-02-09 16:44:49 -05:00
# endif
2010-07-15 07:25:34 -04:00
2010-11-18 11:31:44 -05:00
// Get a list of available direct sources, in case the file is browsable only.
std : : list < std : : string > srcIds ;
FileInfo finfo ;
rsFiles - > FileDetails ( hash ( ) . toStdString ( ) , RS_FILE_HINTS_REMOTE , finfo ) ;
2010-09-24 17:01:13 -04:00
2010-11-18 11:31:44 -05:00
for ( std : : list < TransferInfo > : : const_iterator it ( finfo . peers . begin ( ) ) ; it ! = finfo . peers . end ( ) ; + + it )
{
2011-02-09 16:44:49 -05:00
# ifdef DEBUG_RSLINK
2010-11-18 11:31:44 -05:00
std : : cerr < < " adding peerid " < < ( * it ) . peerId < < std : : endl ;
2011-02-09 16:44:49 -05:00
# endif
2010-11-18 11:31:44 -05:00
srcIds . push_back ( ( * it ) . peerId ) ;
}
2010-07-15 07:25:34 -04:00
2010-11-18 11:31:44 -05:00
if ( rsFiles - > FileRequest ( name ( ) . toUtf8 ( ) . constData ( ) , hash ( ) . toStdString ( ) , size ( ) , " " , RS_FILE_HINTS_NETWORK_WIDE , srcIds ) ) {
2010-07-15 07:25:34 -04:00
if ( flag & RSLINK_PROCESS_NOTIFY_SUCCESS ) {
QMessageBox mb ( QObject : : tr ( " File Request Confirmation " ) , QObject : : tr ( " The file has been added to your download list. " ) , QMessageBox : : Information , QMessageBox : : Ok , 0 , 0 ) ;
mb . setWindowIcon ( QIcon ( QString : : fromUtf8 ( " :/images/rstray3.png " ) ) ) ;
mb . exec ( ) ;
}
return true ;
}
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
QMessageBox mb ( QObject : : tr ( " File Request canceled " ) , QObject : : tr ( " The file has not been added to your download list, because you already have it. " ) , QMessageBox : : Critical , QMessageBox : : Ok , 0 , 0 ) ;
mb . setWindowIcon ( QIcon ( QString : : fromUtf8 ( " :/images/rstray3.png " ) ) ) ;
mb . exec ( ) ;
}
return false ;
}
case TYPE_PERSON :
{
2011-02-09 16:44:49 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
std : : cerr < < " RetroShareLink::process FriendRequest : name : " < < name ( ) . toStdString ( ) < < " . id : " < < hash ( ) . toStdString ( ) < < std : : endl ;
2011-02-09 16:44:49 -05:00
# endif
2010-07-15 07:25:34 -04:00
RsPeerDetails detail ;
if ( rsPeers - > getPeerDetails ( hash ( ) . toStdString ( ) , detail ) ) {
if ( detail . gpg_id = = rsPeers - > getGPGOwnId ( ) ) {
// it's me, do nothing
return true ;
}
if ( detail . accept_connection ) {
// peer connection is already accepted
if ( flag & RSLINK_PROCESS_NOTIFY_SUCCESS ) {
QMessageBox mb ( QObject : : tr ( " Friend Request Confirmation " ) , QObject : : tr ( " The friend is already in your list. " ) , QMessageBox : : Information , QMessageBox : : Ok , 0 , 0 ) ;
mb . setWindowIcon ( QIcon ( QString : : fromUtf8 ( " :/images/rstray3.png " ) ) ) ;
mb . exec ( ) ;
}
return true ;
}
if ( rsPeers - > setAcceptToConnectGPGCertificate ( hash ( ) . toStdString ( ) , true ) ) {
if ( flag & RSLINK_PROCESS_NOTIFY_SUCCESS ) {
QMessageBox mb ( QObject : : tr ( " Friend Request Confirmation " ) , QObject : : tr ( " The friend has been added to your list. " ) , QMessageBox : : Information , QMessageBox : : Ok , 0 , 0 ) ;
mb . setWindowIcon ( QIcon ( QString : : fromUtf8 ( " :/images/rstray3.png " ) ) ) ;
mb . exec ( ) ;
}
return true ;
}
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
QMessageBox mb ( QObject : : tr ( " Friend Request canceled " ) , QObject : : tr ( " The friend could not be added to your list. " ) , QMessageBox : : Critical , QMessageBox : : Ok , 0 , 0 ) ;
mb . setWindowIcon ( QIcon ( QString : : fromUtf8 ( " :/images/rstray3.png " ) ) ) ;
mb . exec ( ) ;
}
return false ;
}
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
QMessageBox mb ( QObject : : tr ( " Friend Request canceled " ) , QObject : : tr ( " The friend could not be found. " ) , QMessageBox : : Critical , QMessageBox : : Ok , 0 , 0 ) ;
mb . setWindowIcon ( QIcon ( QString : : fromUtf8 ( " :/images/rstray3.png " ) ) ) ;
mb . exec ( ) ;
}
return false ;
}
2011-04-19 15:42:44 -04:00
case TYPE_FORUM :
{
# ifdef DEBUG_RSLINK
std : : cerr < < " RetroShareLink::process ForumRequest : name : " < < name ( ) . toStdString ( ) < < " . id : " < < hash ( ) . toStdString ( ) < < " . msgId : " < < msgId ( ) . toStdString ( ) < < std : : endl ;
# endif
ForumInfo fi ;
if ( ! rsForums - > getForumInfo ( id ( ) . toStdString ( ) , fi ) ) {
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
QMessageBox mb ( QObject : : tr ( " Forum Request canceled " ) , QObject : : tr ( " The forum \" %1 \" could not be found. " ) . arg ( name ( ) ) , QMessageBox : : Critical , QMessageBox : : Ok , 0 , 0 ) ;
mb . setWindowIcon ( QIcon ( QString : : fromUtf8 ( " :/images/rstray3.png " ) ) ) ;
mb . exec ( ) ;
}
return false ;
}
ForumMsgInfo msg ;
if ( ! msgId ( ) . isEmpty ( ) ) {
if ( ! rsForums - > getForumMessage ( fi . forumId , msgId ( ) . toStdString ( ) , msg ) ) {
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
QMessageBox mb ( QObject : : tr ( " Forum Request canceled " ) , QObject : : tr ( " The forum message in forum \" %1 \" could not be found. " ) . arg ( name ( ) ) , QMessageBox : : Critical , QMessageBox : : Ok , 0 , 0 ) ;
mb . setWindowIcon ( QIcon ( QString : : fromUtf8 ( " :/images/rstray3.png " ) ) ) ;
mb . exec ( ) ;
}
return false ;
}
}
MainWindow : : showWindow ( MainWindow : : Forums ) ;
ForumsDialog * forumsDialog = dynamic_cast < ForumsDialog * > ( MainWindow : : getPage ( MainWindow : : Forums ) ) ;
if ( ! forumsDialog ) {
return false ;
}
return forumsDialog - > navigate ( fi . forumId , msg . msgId ) ;
}
case TYPE_CHANNEL :
{
# ifdef DEBUG_RSLINK
std : : cerr < < " RetroShareLink::process ChannelRequest : name : " < < name ( ) . toStdString ( ) < < " . id : " < < hash ( ) . toStdString ( ) < < " . msgId : " < < msgId ( ) . toStdString ( ) < < std : : endl ;
# endif
ChannelInfo ci ;
if ( ! rsChannels - > getChannelInfo ( id ( ) . toStdString ( ) , ci ) ) {
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
QMessageBox mb ( QObject : : tr ( " Channel Request canceled " ) , QObject : : tr ( " The channel \" %1 \" could not be found. " ) . arg ( name ( ) ) , QMessageBox : : Critical , QMessageBox : : Ok , 0 , 0 ) ;
mb . setWindowIcon ( QIcon ( QString : : fromUtf8 ( " :/images/rstray3.png " ) ) ) ;
mb . exec ( ) ;
}
return false ;
}
ChannelMsgInfo msg ;
if ( ! msgId ( ) . isEmpty ( ) ) {
if ( ! rsChannels - > getChannelMessage ( ci . channelId , msgId ( ) . toStdString ( ) , msg ) ) {
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
QMessageBox mb ( QObject : : tr ( " Channel Request canceled " ) , QObject : : tr ( " The channel message in channel \" %1 \" could not be found. " ) . arg ( name ( ) ) , QMessageBox : : Critical , QMessageBox : : Ok , 0 , 0 ) ;
mb . setWindowIcon ( QIcon ( QString : : fromUtf8 ( " :/images/rstray3.png " ) ) ) ;
mb . exec ( ) ;
}
return false ;
}
}
MainWindow : : showWindow ( MainWindow : : Channels ) ;
ChannelFeed * channelFeed = dynamic_cast < ChannelFeed * > ( MainWindow : : getPage ( MainWindow : : Channels ) ) ;
if ( ! channelFeed ) {
return false ;
}
return channelFeed - > navigate ( ci . channelId , msg . msgId ) ;
}
2010-07-15 07:25:34 -04:00
}
std : : cerr < < " RetroShareLink::process unknown type: " < < type ( ) < < std : : endl ;
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
QMessageBox mb ( QObject : : tr ( " File Request Error " ) , QObject : : tr ( " The file link is malformed. " ) , QMessageBox : : Critical , QMessageBox : : Ok , 0 , 0 ) ;
mb . setWindowIcon ( QIcon ( QString : : fromUtf8 ( " :/images/rstray3.png " ) ) ) ;
mb . exec ( ) ;
}
return false ;
2010-03-10 16:38:26 -05:00
}
2010-03-22 15:46:58 -04:00
void RSLinkClipboard : : copyLinks ( const std : : vector < RetroShareLink > & links )
{
2010-07-15 07:25:34 -04:00
QString res ;
for ( uint32_t i = 0 ; i < links . size ( ) ; + + i )
res + = links [ i ] . toString ( ) + " \n " ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
QApplication : : clipboard ( ) - > setText ( res ) ;
2010-03-22 15:46:58 -04:00
}
2010-07-15 07:25:34 -04:00
void RSLinkClipboard : : pasteLinks ( std : : vector < RetroShareLink > & links )
2010-03-22 15:46:58 -04:00
{
2010-07-15 07:25:34 -04:00
return parseClipboard ( links ) ;
2010-03-22 15:46:58 -04:00
}
2010-07-15 07:25:34 -04:00
void RSLinkClipboard : : parseClipboard ( std : : vector < RetroShareLink > & links )
2010-03-22 15:46:58 -04:00
{
2010-07-15 07:25:34 -04:00
// parse clipboard for links.
//
links . clear ( ) ;
QString text = QApplication : : clipboard ( ) - > text ( ) ;
std : : cerr < < " Parsing clipboard: " < < text . toStdString ( ) < < std : : endl ;
2011-04-19 15:42:44 -04:00
QRegExp rx ( QString ( " retroshare://(%1) [ ^ \ r \ n ] + " ).arg(HOST_REGEXP)) ;
2010-07-15 07:25:34 -04:00
int pos = 0 ;
while ( ( pos = rx . indexIn ( text , pos ) ) ! = - 1 )
{
QString url ( text . mid ( pos , rx . matchedLength ( ) ) ) ;
RetroShareLink link ( url ) ;
if ( link . valid ( ) )
{
// check that the link is not already in the list:
bool already = false ;
for ( uint32_t i = 0 ; i < links . size ( ) ; + + i )
if ( links [ i ] = = link )
{
already = true ;
break ;
}
if ( ! already )
{
links . push_back ( link ) ;
2011-02-09 16:44:49 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
std : : cerr < < " captured link: " < < link . toString ( ) . toStdString ( ) < < std : : endl ;
2011-02-09 16:44:49 -05:00
# endif
2010-07-15 07:25:34 -04:00
}
}
2011-02-09 16:44:49 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
else
std : : cerr < < " invalid link " < < std : : endl ;
2011-02-09 16:44:49 -05:00
# endif
2010-07-15 07:25:34 -04:00
pos + = rx . matchedLength ( ) ;
}
2010-03-22 15:46:58 -04:00
}
QString RSLinkClipboard : : toString ( )
{
2010-07-15 07:25:34 -04:00
std : : vector < RetroShareLink > links ;
parseClipboard ( links ) ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
QString res ;
for ( uint32_t i = 0 ; i < links . size ( ) ; + + i )
res + = links [ i ] . toString ( ) + " \n " ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
return res ;
2010-03-22 15:46:58 -04:00
}
QString RSLinkClipboard : : toHtml ( )
{
2010-07-15 07:25:34 -04:00
std : : vector < RetroShareLink > links ;
parseClipboard ( links ) ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
QString res ;
for ( uint32_t i = 0 ; i < links . size ( ) ; + + i )
res + = links [ i ] . toHtml ( ) + " <br/> " ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
return res ;
2010-03-22 15:46:58 -04:00
}
2010-07-15 07:25:34 -04:00
2010-03-22 15:46:58 -04:00
QString RSLinkClipboard : : toHtmlFull ( )
{
2010-07-15 07:25:34 -04:00
std : : vector < RetroShareLink > links ;
parseClipboard ( links ) ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
QString res ;
for ( uint32_t i = 0 ; i < links . size ( ) ; + + i )
res + = links [ i ] . toHtmlFull ( ) + " <br/> " ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
return res ;
2010-03-22 15:46:58 -04:00
}
2010-07-15 07:25:34 -04:00
bool RSLinkClipboard : : empty ( RetroShareLink : : enumType type /*= RetroShareLink::TYPE_UNKNOWN*/ )
2010-03-22 15:46:58 -04:00
{
2010-07-15 07:25:34 -04:00
std : : vector < RetroShareLink > links ;
parseClipboard ( links ) ;
if ( type = = RetroShareLink : : TYPE_UNKNOWN ) {
return links . empty ( ) ;
}
for ( std : : vector < RetroShareLink > : : iterator link = links . begin ( ) ; link ! = links . end ( ) ; link + + ) {
if ( link - > type ( ) = = type ) {
return false ;
}
}
return true ;
2010-03-22 15:46:58 -04:00
}
2010-07-15 07:25:34 -04:00
/*static*/ int RSLinkClipboard : : process ( RetroShareLink : : enumType type /*= RetroShareLink::TYPE_UNKNOWN*/ , int flag /*= RSLINK_PROCESS_NOTIFY_ALL*/ )
{
std : : vector < RetroShareLink > links ;
pasteLinks ( links ) ;
int count = 0 ;
for ( uint32_t i = 0 ; i < links . size ( ) ; i + + ) {
if ( links [ i ] . valid ( ) & & ( type = = RetroShareLink : : TYPE_UNKNOWN | | links [ i ] . type ( ) = = type ) ) {
2010-09-24 17:01:13 -04:00
if ( links [ i ] . process ( flag ) ) {
2010-07-15 07:25:34 -04:00
count + + ;
}
}
}
return count ;
}