mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 19:24:08 +00:00
Win-specific: Scan popup now work in GoldenDict article tabs
This commit is contained in:
parent
3abb74ad51
commit
3de1e09663
174
articleview.cc
174
articleview.cc
|
@ -21,7 +21,11 @@
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <mmsystem.h> // For PlaySound
|
#include <mmsystem.h> // For PlaySound
|
||||||
|
|
||||||
|
#include <QWebElement>
|
||||||
|
#include <QPainter>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
|
|
||||||
// Phonon headers are a mess. How to include them properly? Send patches if you
|
// Phonon headers are a mess. How to include them properly? Send patches if you
|
||||||
|
@ -1568,3 +1572,173 @@ void ArticleView::switchExpandOptionalParts()
|
||||||
emit setExpandMode( expandOptionalParts );
|
emit setExpandMode( expandOptionalParts );
|
||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
|
||||||
|
void ArticleView::readTag( const QString & from, QString & to, int & count )
|
||||||
|
{
|
||||||
|
QChar ch, prev_ch;
|
||||||
|
bool inQuote = false, inDoublequote = false;
|
||||||
|
|
||||||
|
to.append( ch = prev_ch = from[ count++ ] );
|
||||||
|
while( count < from.size() )
|
||||||
|
{
|
||||||
|
ch = from[ count ];
|
||||||
|
if( ch == '>' && !( inQuote || inDoublequote ) )
|
||||||
|
{
|
||||||
|
to.append( ch );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( ch == '\'' )
|
||||||
|
inQuote = !inQuote;
|
||||||
|
if( ch == '\"' )
|
||||||
|
inDoublequote = !inDoublequote;
|
||||||
|
to.append( prev_ch = ch );
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ArticleView::insertSpans( QString const & html )
|
||||||
|
{
|
||||||
|
QChar ch;
|
||||||
|
QString newContent;
|
||||||
|
bool inSpan = false, escaped = false;
|
||||||
|
|
||||||
|
/// Enclose every word in string (exclude tags) with <span></span>
|
||||||
|
|
||||||
|
for( int i = 0; i < html.size(); i++ )
|
||||||
|
{
|
||||||
|
ch = html[ i ];
|
||||||
|
if( ch == '&' )
|
||||||
|
{
|
||||||
|
escaped = true;
|
||||||
|
if( inSpan )
|
||||||
|
{
|
||||||
|
newContent.append( "</span>" );
|
||||||
|
inSpan = false;
|
||||||
|
}
|
||||||
|
newContent.append( ch );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ch == '<' ) // Skip tag
|
||||||
|
{
|
||||||
|
escaped = false;
|
||||||
|
if( inSpan )
|
||||||
|
{
|
||||||
|
newContent.append( "</span>" );
|
||||||
|
inSpan = false;
|
||||||
|
}
|
||||||
|
readTag( html, newContent, i );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( escaped )
|
||||||
|
{
|
||||||
|
if( ch == ';' )
|
||||||
|
escaped = false;
|
||||||
|
newContent.append( ch );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !inSpan && ( ch.isLetterOrNumber() || ch.isLowSurrogate() ) )
|
||||||
|
{
|
||||||
|
newContent.append( "<span>");
|
||||||
|
inSpan = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( inSpan && !( ch.isLetterOrNumber() || ch.isLowSurrogate() ) )
|
||||||
|
{
|
||||||
|
newContent.append( "</span>");
|
||||||
|
inSpan = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ch.isLowSurrogate() )
|
||||||
|
{
|
||||||
|
newContent.append( ch );
|
||||||
|
ch = html[ ++i ];
|
||||||
|
}
|
||||||
|
|
||||||
|
newContent.append( ch );
|
||||||
|
}
|
||||||
|
if( inSpan )
|
||||||
|
newContent.append( "</span>" );
|
||||||
|
return newContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ArticleView::checkElement( QWebElement & elem, QPoint const & pt )
|
||||||
|
{
|
||||||
|
/// Search for lower-level matching element
|
||||||
|
|
||||||
|
QWebElement parentElem = elem;
|
||||||
|
QWebElement childElem = elem.firstChild();
|
||||||
|
while( !childElem.isNull() )
|
||||||
|
{
|
||||||
|
if( childElem.geometry().contains( pt ) )
|
||||||
|
{
|
||||||
|
parentElem = childElem;
|
||||||
|
childElem = parentElem.firstChild();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
childElem = childElem.nextSibling();
|
||||||
|
}
|
||||||
|
|
||||||
|
return parentElem.toPlainText();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ArticleView::wordAtPoint( int x, int y )
|
||||||
|
{
|
||||||
|
QString word;
|
||||||
|
|
||||||
|
if( popupView )
|
||||||
|
return word;
|
||||||
|
|
||||||
|
QPoint pos = mapFromGlobal( QPoint( x, y ) );
|
||||||
|
QWebFrame *frame = ui.definition->page()->frameAt( pos );
|
||||||
|
if( !frame )
|
||||||
|
return word;
|
||||||
|
|
||||||
|
QPoint posWithScroll = pos + frame->scrollPosition();
|
||||||
|
|
||||||
|
/// Find target HTML element
|
||||||
|
|
||||||
|
QWebHitTestResult result = frame->hitTestContent( pos );
|
||||||
|
QWebElement baseElem = result.enclosingBlockElement();
|
||||||
|
|
||||||
|
if( baseElem.tagName().compare( "BODY" ) == 0 || /// Assume empty field position
|
||||||
|
baseElem.tagName().compare( "HTML" ) == 0 ||
|
||||||
|
baseElem.tagName().compare( "HEAD" ) == 0 )
|
||||||
|
return word;
|
||||||
|
|
||||||
|
/// Enclose every word be <span> </span>
|
||||||
|
|
||||||
|
QString content = baseElem.toInnerXml();
|
||||||
|
QString newContent = insertSpans( content );
|
||||||
|
|
||||||
|
/// Set new code and re-render it to fill geometry
|
||||||
|
|
||||||
|
QImage img( baseElem.geometry().width(), baseElem.geometry().height(), QImage::Format_Mono );
|
||||||
|
img.fill( 0 );
|
||||||
|
QPainter painter( & img );
|
||||||
|
|
||||||
|
baseElem.setInnerXml( newContent );
|
||||||
|
baseElem.render( &painter );
|
||||||
|
|
||||||
|
/// Search in all child elements and check it
|
||||||
|
|
||||||
|
QWebElementCollection elemCollection = baseElem.findAll( "*" );
|
||||||
|
foreach ( QWebElement elem, elemCollection )
|
||||||
|
{
|
||||||
|
if( elem.geometry().contains( posWithScroll ) )
|
||||||
|
word = checkElement( elem, posWithScroll );
|
||||||
|
if( !word.isEmpty() )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restore old content
|
||||||
|
baseElem.setInnerXml( content );
|
||||||
|
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -298,6 +298,19 @@ protected:
|
||||||
|
|
||||||
// We need this to hide the search bar when we're showed
|
// We need this to hide the search bar when we're showed
|
||||||
void showEvent( QShowEvent * );
|
void showEvent( QShowEvent * );
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
|
||||||
|
/// Search inside web page for word under cursor
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString insertSpans( QString const & html );
|
||||||
|
void readTag( QString const & from, QString & to, int & count );
|
||||||
|
QString checkElement( QWebElement & elem, const QPoint & pt );
|
||||||
|
public:
|
||||||
|
QString wordAtPoint( int x, int y );
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -25,6 +25,11 @@
|
||||||
#include "lionsupport.h"
|
#include "lionsupport.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#include "mouseover_win32/GDDataTranfer.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using std::set;
|
using std::set;
|
||||||
using std::wstring;
|
using std::wstring;
|
||||||
using std::map;
|
using std::map;
|
||||||
|
@ -527,6 +532,9 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
LionSupport::addFullscreen(this);
|
LionSupport::addFullscreen(this);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
gdAskMessage = RegisterWindowMessage( GD_MESSAGE_NAME );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::ctrlTabPressed()
|
void MainWindow::ctrlTabPressed()
|
||||||
|
@ -1021,6 +1029,9 @@ ArticleView * MainWindow::createNewTab( bool switchToIt,
|
||||||
|
|
||||||
view->setZoomFactor( cfg.preferences.zoomFactor );
|
view->setZoomFactor( cfg.preferences.zoomFactor );
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
view->installEventFilter( this );
|
||||||
|
#endif
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2950,3 +2961,28 @@ void MainWindow::switchExpandOptionalPartsMode()
|
||||||
if( view )
|
if( view )
|
||||||
view->switchExpandOptionalParts();
|
view->switchExpandOptionalParts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
|
||||||
|
bool MainWindow::winEvent( MSG * message, long * result )
|
||||||
|
{
|
||||||
|
if( message->message != gdAskMessage )
|
||||||
|
return false;
|
||||||
|
*result = 0;
|
||||||
|
ArticleView * view = getCurrentArticleView();
|
||||||
|
if( !view )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
LPGDDataStruct lpdata = ( LPGDDataStruct ) message->lParam;
|
||||||
|
|
||||||
|
QString str = view->wordAtPoint( lpdata->Pt.x, lpdata->Pt.y );
|
||||||
|
|
||||||
|
str.truncate( lpdata->dwMaxLength - 1 );
|
||||||
|
memset( lpdata->cwData, 0, lpdata->dwMaxLength * sizeof( WCHAR ) );
|
||||||
|
str.toWCharArray( lpdata->cwData );
|
||||||
|
|
||||||
|
*result = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -341,6 +341,13 @@ private slots:
|
||||||
signals:
|
signals:
|
||||||
/// Set optional parts expand mode for all tabs
|
/// Set optional parts expand mode for all tabs
|
||||||
void setExpandOptionalParts( bool expand );
|
void setExpandOptionalParts( bool expand );
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
/// For receiving message from scan libraries
|
||||||
|
protected:
|
||||||
|
unsigned gdAskMessage;
|
||||||
|
bool winEvent( MSG * message, long * result );
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue