37 #include <QImageReader> 
   38 #include <QMouseEvent> 
   39 #include <QApplication> 
   40 #include <QDesktopServices> 
   43 QgsImageDropTextEdit::QgsImageDropTextEdit( QWidget *parent )
 
   46   setTextInteractionFlags( Qt::TextEditorInteraction | Qt::LinksAccessibleByMouse );
 
   49 QgsImageDropTextEdit::~QgsImageDropTextEdit() = 
default;
 
   51 bool QgsImageDropTextEdit::canInsertFromMimeData( 
const QMimeData *source )
 const 
   53   if ( source->hasImage() || QTextEdit::canInsertFromMimeData( source ) )
 
   56   const QList<QUrl> urls = source->urls();
 
   58   files.reserve( urls.size() );
 
   59   for ( 
const QUrl &url : urls )
 
   61     QString fileName = url.toLocalFile();
 
   64     if ( !fileName.isEmpty() )
 
   71   for ( 
const QString &file : std::as_const( files ) )
 
   74     const QList<QByteArray> formats = QImageReader::supportedImageFormats();
 
   75     for ( 
const QByteArray &format : formats )
 
   77       if ( fi.suffix().compare( format, Qt::CaseInsensitive ) == 0 )
 
   88 void QgsImageDropTextEdit::insertFromMimeData( 
const QMimeData *source )
 
   90   if ( source->hasImage() )
 
   92     const QStringList formats = source->formats();
 
   94     for ( 
const QString &
string : formats )
 
   96       if ( 
string == QLatin1String( 
"image/bmp" ) )
 
   98         format = QStringLiteral( 
"BMP" );
 
  101       if ( 
string == QLatin1String( 
"image/jpeg" ) )
 
  103         format = QStringLiteral( 
"JPG" );
 
  106       if ( 
string == QLatin1String( 
"image/jpg" ) )
 
  108         format = QStringLiteral( 
"JPG" );
 
  111       if ( 
string == QLatin1String( 
"image/gif" ) )
 
  113         format = QStringLiteral( 
"GIF" );
 
  116       if ( 
string == QLatin1String( 
"image/png" ) )
 
  118         format = QStringLiteral( 
"PNG" );
 
  121       if ( 
string == QLatin1String( 
"image/pbm" ) )
 
  123         format = QStringLiteral( 
"PBM" );
 
  126       if ( 
string == QLatin1String( 
"image/pgm" ) )
 
  128         format = QStringLiteral( 
"PGM" );
 
  131       if ( 
string == QLatin1String( 
"image/ppm" ) )
 
  133         format = QStringLiteral( 
"PPM" );
 
  136       if ( 
string == QLatin1String( 
"image/tiff" ) )
 
  138         format = QStringLiteral( 
"TIFF" );
 
  141       if ( 
string == QLatin1String( 
"image/xbm" ) )
 
  143         format = QStringLiteral( 
"XBM" );
 
  146       if ( 
string == QLatin1String( 
"image/xpm" ) )
 
  148         format = QStringLiteral( 
"XPM" );
 
  152     if ( !format.isEmpty() )
 
  154       dropImage( qvariant_cast<QImage>( source->imageData() ), format );
 
  160     const QList<QUrl> urls = source->urls();
 
  162     files.reserve( urls.size() );
 
  163     for ( 
const QUrl &url : urls )
 
  165       if ( url.isLocalFile() )
 
  167         QString fileName = url.toLocalFile();
 
  170         if ( !fileName.isEmpty() )
 
  181     for ( 
const QString &file : std::as_const( files ) )
 
  183       const QFileInfo fi( file );
 
  184       const QList<QByteArray> formats = QImageReader::supportedImageFormats();
 
  185       bool isImage = 
false;
 
  186       for ( 
const QByteArray &format : formats )
 
  188         if ( fi.suffix().compare( format, Qt::CaseInsensitive ) == 0 )
 
  190           const QImage image( file );
 
  191           dropImage( image, format );
 
  198         dropLink( QUrl::fromLocalFile( file ) );
 
  201     if ( !files.empty() )
 
  205   QTextEdit::insertFromMimeData( source );
 
  208 void QgsImageDropTextEdit::mouseMoveEvent( QMouseEvent *e )
 
  210   QTextEdit::mouseMoveEvent( e );
 
  211   mActiveAnchor = anchorAt( e->pos() );
 
  212   if ( !mActiveAnchor.isEmpty() && !mCursorOverride )
 
  213     mCursorOverride = std::make_unique< QgsTemporaryCursorOverride >( Qt::PointingHandCursor );
 
  214   else if ( mActiveAnchor.isEmpty() && mCursorOverride )
 
  215     mCursorOverride.reset();
 
  218 void QgsImageDropTextEdit::mouseReleaseEvent( QMouseEvent *e )
 
  220   if ( e->button() == Qt::LeftButton && !mActiveAnchor.isEmpty() )
 
  222     QDesktopServices::openUrl( QUrl( mActiveAnchor ) );
 
  223     if ( mCursorOverride )
 
  224       mCursorOverride.reset();
 
  225     mActiveAnchor.clear();
 
  229     QTextEdit::mouseReleaseEvent( e );
 
  233 void QgsImageDropTextEdit::dropImage( 
const QImage &image, 
const QString &format )
 
  236   QBuffer buffer( &bytes );
 
  237   buffer.open( QIODevice::WriteOnly );
 
  238   image.save( &buffer, format.toLocal8Bit().data() );
 
  240   QByteArray base64 = bytes.toBase64();
 
  242   for ( 
int i = 0; i < base64.size(); i++ )
 
  244     base64l.append( base64[i] );
 
  247       base64l.append( 
"\n" );
 
  251   QTextCursor cursor = textCursor();
 
  252   QTextImageFormat imageFormat;
 
  253   imageFormat.setWidth( image.width() );
 
  254   imageFormat.setHeight( image.height() );
 
  255   imageFormat.setName( QStringLiteral( 
"data:image/%1;base64,%2" )
 
  256                        .arg( QStringLiteral( 
"%1.%2" ).arg( rand() ).arg( format ),
 
  259   cursor.insertImage( imageFormat );
 
  262 void QgsImageDropTextEdit::dropLink( 
const QUrl &url )
 
  264   QTextCursor cursor = textCursor();
 
  265   cursor.insertHtml( QStringLiteral( 
"<a href=\"%1\">%1</a>" ).arg( url.toString() ) );