Commit 5ce4b067 authored by Pino Toscano's avatar Pino Toscano

Make okular able to copy the text selection to the clipboard (finally!).

svn path=/trunk/playground/graphics/okular/; revision=607496
parent f070c5cd
......@@ -431,6 +431,11 @@ void Page::setSourceReferences( const QLinkedList< SourceRefObjectRect * > refRe
m_rects << rect;
}
const RegularAreaRect * Page::textSelection() const
{
return m_textSelections;
}
void Page::addAnnotation( Annotation * annotation )
{
//uniqueName: okular-PAGENUM-ID
......
......@@ -159,9 +159,10 @@ class OKULAR_EXPORT Page : public QObject
Qt::CaseSensitivity caseSensitivity, const RegularAreaRect * lastRect=0) const;
/**
* Returns the text which is included by rectangular area @p rect or an empty string.
* Returns the page text (or part of it).
* @see TextPage::text()
*/
QString text( const RegularAreaRect * rect ) const;
QString text( const RegularAreaRect * rect = 0 ) const;
/**
* Returns the rectangular area of the given @p selection.
......@@ -230,6 +231,11 @@ class OKULAR_EXPORT Page : public QObject
*/
void setSourceReferences( const QLinkedList< SourceRefObjectRect * > rects );
/**
* Returns the current text selection.
*/
const RegularAreaRect * textSelection() const;
/**
* Adds a new @p annotation to the page.
*/
......
......@@ -421,22 +421,26 @@ RegularAreaRect* TextPage::Private::findTextInternalForward( int searchID, const
QString TextPage::text(const RegularAreaRect *area) const
{
if (!area || area->isNull())
if ( area && area->isNull() )
return QString();
QString ret = "";
TextEntity::List::ConstIterator it,end = d->m_words.end();
TextEntity * last=0;
for ( it = d->m_words.begin(); it != end; ++it )
TextEntity::List::ConstIterator it = d->m_words.begin(), itEnd = d->m_words.end();
QString ret;
if ( area )
{
// provide the string FIXME?: newline handling
if (area->intersects((*it)->transformedArea()))
for ( ; it != itEnd; ++it )
{
// kDebug()<< "[" << (*it)->area->left << "," << (*it)->area->top << "]x["<< (*it)->area->right << "," << (*it)->area->bottom << "]\n";
ret += (*it)->text();
last=*it;
if ( area->intersects( (*it)->transformedArea() ) )
{
ret += (*it)->text();
}
}
}
else
{
for ( ; it != itEnd; ++it )
ret += (*it)->text();
}
return ret;
}
......
......@@ -144,9 +144,12 @@ class TextPage
Qt::CaseSensitivity caseSensitivity, const RegularAreaRect *lastRect );
/**
* Returns the text which is included by rectangular area @p rect or an empty string.
* Returns:
* - a null string if @p rect is a valid pointer to a null area
* - the whole page text if @p rect is a null pointer
* - the text which is included by rectangular area @p rect otherwise
*/
QString text( const RegularAreaRect *rect ) const;
QString text( const RegularAreaRect *rect = 0 ) const;
/**
* Returns the rectangular area of the given @p selection.
......
......@@ -260,6 +260,8 @@ Part::Part(QWidget *parentWidget,
m_nextBookmark->setWhatsThis( i18n( "Go to the next bookmarked page" ) );
connect( m_nextBookmark, SIGNAL( triggered() ), this, SLOT( slotNextBookmark() ) );
m_copy = KStdAction::create( KStdAction::Copy, "edit_copy", m_pageView, SLOT( copyTextSelection() ), ac );
// Find and other actions
m_find = KStdAction::find( this, SLOT( slotFind() ), ac, "find" );
m_find->setEnabled( false );
......
......@@ -187,6 +187,7 @@ private:
KAction *m_historyNext;
KAction *m_prevBookmark;
KAction *m_nextBookmark;
KAction *m_copy;
KAction *m_find;
KAction *m_findNext;
KAction *m_saveAs;
......
......@@ -12,6 +12,8 @@
<Action name="file_export_as" group="file_print"/>
</Menu>
<Menu name="edit"><text>&amp;Edit</text>
<Action name="edit_copy"/>
<Separator/>
<Action name="find"/>
<Action name="find_next"/>
</Menu>
......
......@@ -518,6 +518,43 @@ void PageView::reparseConfig()
}
}
void PageView::copyTextSelection() const
{
if ( d->pagesWithTextSelection.isEmpty() )
return;
QString text;
QList< int > selpages = d->pagesWithTextSelection.toList();
qSort( selpages );
const Okular::Page * pg = 0;
if ( selpages.count() == 1 )
{
pg = d->document->page( selpages.first() );
text.append( pg->text( pg->textSelection() ) );
}
else
{
pg = d->document->page( selpages.first() );
text.append( pg->text( pg->textSelection() ) );
int end = selpages.count() - 1;
for( int i = 1; i < end; ++i )
{
pg = d->document->page( selpages.at( i ) );
text.append( pg->text() );
}
pg = d->document->page( selpages.last() );
text.append( pg->text( pg->textSelection() ) );
}
if ( !text.isEmpty() )
{
QClipboard *cb = QApplication::clipboard();
cb->setText( text, QClipboard::Clipboard );
if ( cb->supportsSelection() )
cb->setText( text, QClipboard::Selection );
}
}
//BEGIN DocumentObserver inherited methods
void PageView::notifySetup( const QVector< Okular::Page * > & pageSet, bool documentChanged )
{
......@@ -1742,12 +1779,23 @@ void PageView::contentsMouseReleaseEvent( QMouseEvent * e )
d->mouseTextSelecting = false;
// textSelectionClear();
}
else if ( !d->mousePressPos.isNull() )
else if ( !d->mousePressPos.isNull() && rightButton )
{
PageViewItem * pageItem = pickItemOnPoint( e->x(), e->y() );
const Okular::Page * page = pageItem ? pageItem->page() : 0;
if ( page )
KMenu menu( this );
QAction *textToClipboard = menu.addAction( KIcon( "editcopy" ), i18n( "Copy" ) );
if ( !d->document->isAllowed( Okular::Document::AllowCopy ) )
{
textToClipboard->setEnabled( false );
textToClipboard->setText( i18n("Copy forbidden by DRM") );
}
QAction *choice = menu.exec( e->globalPos() );
// check if the user really selected an action
if ( choice )
{
if ( choice == textToClipboard )
copyTextSelection();
}
}
break;
......
......@@ -97,6 +97,8 @@ Q_OBJECT
displayMessage( message, PageViewMessage::Warning, duration );
}
void copyTextSelection() const;
signals:
void urlDropped( const KUrl& );
void rightClick( const Okular::Page *, const QPoint & );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment