You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kbibtex/src/documentwidget.cpp

1741 lines
71 KiB

11 years ago
/***************************************************************************
* Copyright (C) 2004-2009 by Thomas Fischer *
* fischer@unix-ag.uni-kl.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. *
* *
* 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 <cmath>
#include <tqlayout.h>
#include <tqfile.h>
#include <tqdragobject.h>
#include <tqregexp.h>
#include <tqsplitter.h>
#include <tqurl.h>
#include <tqtextedit.h>
#include <tqprogressdialog.h>
#include <tqbuffer.h>
#include <tqtooltip.h>
#include <tqapplication.h>
#include <tqpushbutton.h>
#include <tqfileinfo.h>
11 years ago
#include <kdebug.h>
#include <tdelocale.h>
#include <tdetempfile.h>
#include <tdeglobalsettings.h>
11 years ago
#include <kurl.h>
#include <kinputdialog.h>
#include <tdepopupmenu.h>
11 years ago
#include <kiconloader.h>
#include <tdeio/netaccess.h>
11 years ago
#include <kstandarddirs.h>
#include <tdemessagebox.h>
#include <tdeapplication.h>
11 years ago
#include <klineedit.h>
#include <kdebug.h>
#include <ktextedit.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "searchbar.h"
#include "sidebar.h"
#include "documentlistview.h"
#include "documentlistviewitem.h"
#include "documentsourceview.h"
#include "macrowidget.h"
#include "preamblewidget.h"
#include "commentwidget.h"
#include "entrywidget.h"
#include "fileimporterbibtex.h"
#include "fileimporterbibutils.h"
#include "fileimporterris.h"
#include "fileexporterbibtex.h"
#include "fileexporterbibutils.h"
#include "fileexporterris.h"
#include "fileexporterxml.h"
#include "fileexporterrtf.h"
#include "fileexporterdocbook5.h"
#include "fileexporterpdf.h"
#include "fileexporterps.h"
#include "fileexporterxslt.h"
#include "fileimporterexternal.h"
#include "fileexporterexternal.h"
#include "xsltransform.h"
#include "entry.h"
#include "entryfield.h"
#include "comment.h"
#include "macro.h"
#include "preamble.h"
#include "settings.h"
#include "webquery.h"
#include "mergeelements.h"
#include "idsuggestions.h"
11 years ago
#include "documentwidget.h"
namespace KBibTeX
{
DocumentWidget::DocumentWidget( bool isReadOnly, TQWidget *parent, const char *name )
: TQTabWidget( parent, name ), m_lineEditNewKeyword( NULL ), m_isReadOnly( isReadOnly ), m_filename( TQString::null ), m_progressDialog( NULL ), m_newElementCounter( 1 ), m_editMode( emList ), m_viewDocumentActionMenu( NULL ), m_assignKeywordsActionMenu( NULL ), m_searchWebsitesActionMenu( NULL ), m_actionEditCut( NULL ), m_actionEditCopy( NULL ), m_actionEditCopyRef( NULL ), m_actionEditPaste( NULL ), m_actionEditSelectAll( NULL ), m_actionEditFind( NULL ), m_actionEditFindNext( NULL ), m_dirWatch( this )
11 years ago
{
m_bibtexfile = new BibTeX::File();
setupGUI();
m_listViewElements->setBibTeXFile( m_bibtexfile );
m_sourceView->setBibTeXFile( m_bibtexfile );
}
DocumentWidget::~DocumentWidget()
{
delete m_bibtexfile;
}
void DocumentWidget::setupGUI()
{
setAcceptDrops( TRUE );
setFocusPolicy( TQWidget::ClickFocus );
11 years ago
// List view tab widget ===============================
m_container = new TQWidget( this );
TQVBoxLayout *layout = new TQVBoxLayout( m_container, 0, 0 );
11 years ago
addTab( m_container, i18n( "L&ist view" ) );
m_searchBar = new SearchBar( m_container );
layout->addWidget( m_searchBar );
m_horSplitter = new TQSplitter( TQt::Horizontal, m_container );
11 years ago
layout->addWidget( m_horSplitter );
m_horSplitter->setSizePolicy( TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding );
11 years ago
m_sideBar = new SideBar( m_isReadOnly, m_horSplitter );
m_vertSplitter = new TQSplitter( TQt::Vertical, m_horSplitter );
m_vertSplitter->setSizePolicy( TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding );
11 years ago
m_listViewElements = new DocumentListView( this, m_isReadOnly, m_vertSplitter );
m_preview = new KTextEdit( m_vertSplitter );
m_preview->setReadOnly( TRUE );
m_preview->setAlignment( TQt::AlignTop && TQt::AlignLeft );
11 years ago
// Source view tab widget =============================
m_sourceView = new DocumentSourceView( this, m_isReadOnly, this , "source_view" );
addTab( m_sourceView, i18n( "So&urce view" ) );
m_sourceView->setFont( TDEGlobalSettings::fixedFont() );
11 years ago
// Setup actions
connect( m_searchBar, SIGNAL( onlineSearch() ), this, SLOT( onlineSearch() ) );
connect( m_searchBar, SIGNAL( doSearch( const TQString&, BibTeX::Element::FilterType, BibTeX::EntryField::FieldType ) ), m_listViewElements, SLOT( filter( const TQString&, BibTeX::Element::FilterType, BibTeX::EntryField::FieldType ) ) );
11 years ago
connect( m_listViewElements, SIGNAL( executed( DocumentListViewItem* ) ), this, SLOT( executeElement( DocumentListViewItem* ) ) );
connect( m_listViewElements, SIGNAL( selectionChanged() ), this, SLOT( slotSelectionChanged() ) );
connect( m_listViewElements, SIGNAL( currentChanged( TQListViewItem* ) ), this, SLOT( slotPreviewElement( TQListViewItem* ) ) );
connect( m_listViewElements, SIGNAL( clicked( TQListViewItem* ) ), this, SLOT( slotPreviewElement( TQListViewItem* ) ) );
connect( this, SIGNAL( currentChanged( TQWidget * ) ), this, SLOT( slotTabChanged( TQWidget* ) ) );
11 years ago
connect( m_sourceView, SIGNAL( modified() ), this, SLOT( slotModified() ) );
connect( m_listViewElements, SIGNAL( modified() ), this, SLOT( slotModified() ) );
connect( m_sideBar, SIGNAL( valueRenamed() ), this, SLOT( slotModified() ) );
connect( m_sideBar, SIGNAL( valueRenamed() ), this, SLOT( refreshBibTeXFile() ) );
connect( m_sideBar, SIGNAL( selected( const TQString&, BibTeX::Element::FilterType, BibTeX::EntryField::FieldType ) ), m_searchBar, SLOT( setSearch( const TQString&, BibTeX::Element::FilterType, BibTeX::EntryField::FieldType ) ) );
connect( &m_dirWatch, SIGNAL( dirty( const TQString& ) ), this, SLOT( slotFileGotDirty( const TQString & ) ) );
11 years ago
}
bool DocumentWidget::open( const TQString &fileName, bool mergeOnly )
11 years ago
{
bool result = FALSE;
if ( !mergeOnly )
m_dirWatch.removeFile( m_filename );
BibTeX::FileImporter *importer = fileImporterFactory( fileName );
if ( importer != NULL )
{
TQFile file( fileName );
11 years ago
if ( file.open( IO_ReadOnly ) )
{
result = open( &file, mergeOnly, TQString( i18n( "<qt>Loading file <b>%1</b></qt>" ) ).arg( fileName ), importer );
11 years ago
if ( result )
{
m_bibtexfile->fileName = fileName;
m_filename = fileName;
}
file.close();
}
else
kdDebug() << "Cannot open file " << fileName << endl;
delete importer;
}
if ( !mergeOnly )
m_dirWatch.addFile( m_filename );
return result;
}
bool DocumentWidget::open( TQIODevice *iodevice, bool mergeOnly, const TQString &label, BibTeX::FileImporter *importer )
11 years ago
{
bool result = FALSE;
setEnabled( FALSE );
bool usingDefaultImporter = importer == NULL;
if ( usingDefaultImporter )
{
Settings * settings = Settings::self( NULL );
importer = new BibTeX::FileImporterBibTeX( settings->editing_FirstNameFirst, settings->fileIO_Encoding );
}
startProgress( label, importer );
BibTeX::File *newFile = importer->load( iodevice );
endProgress( importer );
if ( usingDefaultImporter )
delete importer;
if ( newFile != NULL )
{
if ( mergeOnly )
{
for ( TQValueList<BibTeX::Element*>::ConstIterator eit = newFile->constBegin(); eit != newFile->constEnd(); ++eit )
11 years ago
m_bibtexfile->appendElement(( *eit )->clone() );
if ( KMessageBox::questionYesNo( this, i18n( "Do you want to search for duplicates in the merged document?" ), i18n( "Find duplicates?" ), KGuiItem( i18n( "Find Duplicates" ) ) ) == KMessageBox::Yes )
{
MergeElements *me = new MergeElements( this );
me->mergeDuplicates( m_bibtexfile );
delete me;
}
delete newFile;
}
else
{
delete m_bibtexfile;
m_bibtexfile = newFile;
}
if ( currentPage() == m_sourceView )
m_sourceView->setBibTeXFile( m_bibtexfile );
else if ( currentPage() == m_container )
m_listViewElements->setBibTeXFile( m_bibtexfile );
Settings * settings = Settings::self( m_bibtexfile );
settings->addToCompletion( m_bibtexfile );
m_sideBar->refreshLists( m_bibtexfile );
result = TRUE;
}
else
{
kdDebug() << "Could not load bibliography file from io device" << endl;
result = FALSE;
}
setEnabled( TRUE );
return result;
}
bool DocumentWidget::save( const TQString &fileName, TQStringList *errorLog )
11 years ago
{
bool result = FALSE;
m_dirWatch.removeFile( m_filename );
Settings * settings = Settings::self( NULL );
BibTeX::File::FileFormat format = BibTeX::File::formatUndefined;
if ( fileName.endsWith( ".rtf", FALSE ) )
format = BibTeX::File::formatRTF;
else if ( fileName.endsWith( ".pdf", FALSE ) )
format = BibTeX::File::formatPDF;
else if ( fileName.endsWith( ".bib", FALSE ) )
format = BibTeX::File::formatBibTeX;
else if ( settings->external_xml2bibAvailable && settings->external_end2xmlAvailable && ( fileName.endsWith( ".ref", FALSE ) || fileName.endsWith( ".refer", FALSE ) || fileName.endsWith( ".txt", FALSE ) || fileName.endsWith( ".rfr", FALSE ) ) )
format = BibTeX::File::formatEndNote;
else if ( settings->external_xml2bibAvailable && settings->external_end2xmlAvailable && ( fileName.endsWith( ".isi", FALSE ) || fileName.endsWith( ".cgi", FALSE ) ) )
format = BibTeX::File::formatISI;
else if ( fileName.endsWith( ".ris", FALSE ) )
format = BibTeX::File::formatRIS;
else if ( fileName.endsWith( ".ps", FALSE ) )
format = BibTeX::File::formatPS;
else if ( fileName.endsWith( ".xml", FALSE ) )
{
TQStringList options = TQStringList::split( '|', ( settings->external_xml2bibAvailable && settings->external_end2xmlAvailable ? "DocBook5|MODS|internal XML" : "DocBook5|internal XML" ) );
11 years ago
bool ok = false;
TQString answer = KInputDialog::getItem( i18n( "Choose file format" ), TQString( i18n( "Choose file format of file '%1':" ) ).arg( fileName ), options, 0, false, &ok, this );
11 years ago
if ( ok && !answer.isNull() && answer == "DocBook5" )
format = BibTeX::File::formatDocBook5;
else if ( ok && !answer.isNull() && answer == "MODS" )
format = BibTeX::File::formatMODS;
else if ( ok && !answer.isNull() && answer == "internal XML" )
format = BibTeX::File::formatXML;
}
else if ( fileName.endsWith( ".html", FALSE ) || fileName.endsWith( ".xhtml", FALSE ) || fileName.endsWith( ".htm", FALSE ) )
format = BibTeX::File::formatHTML;
if ( format != BibTeX::File::formatUndefined )
{
TQString usedFileName = fileName;
TQFileInfo fi( fileName );
if ( !fi.readLink().isNull() && KMessageBox::questionYesNo( this, TQString( i18n( "The selected filename \"%1\" is a symbolic link pointing to \"%2\".\nReplace the link with a new file or overwrite the existing file the link points to?" ) ).arg( usedFileName ).arg( Settings::resolveLink( fileName, fi.readLink() ) ), i18n( "Symbolic Link" ), KGuiItem( i18n( "Replace link" ) ), KGuiItem( i18n( "Overwrite file the link points to" ) ) ) == KMessageBox::No )
11 years ago
usedFileName = Settings::resolveLink( fileName, fi.readLink() );
TQFile file( usedFileName );
11 years ago
if ( file.open( IO_WriteOnly ) )
{
result = save( &file, format, TQString( i18n( "<qt>Writing file <b>%1</b></qt>" ) ).arg( fileName ), errorLog );
11 years ago
if ( result )
{
m_bibtexfile->fileName = fileName;
m_filename = fileName;
}
file.close();
}
else
kdDebug() << "Cannot write to file " << fileName << endl;
}
else
kdDebug() << "Unknown file format to save to (filename is " << fileName << ")" << endl;
m_dirWatch.addFile( m_filename );
return result;
}
bool DocumentWidget::save( TQIODevice *iodevice, BibTeX::File::FileFormat format, const TQString &label, TQStringList *errorLog )
11 years ago
{
Settings * settings = Settings::self( m_bibtexfile );
bool result = FALSE;
setEnabled( FALSE );
updateFromGUI();
BibTeX::XSLTransform *transform = NULL;
BibTeX::FileExporter * exporter = NULL;
switch ( format )
{
case BibTeX::File::formatBibTeX:
{
BibTeX::FileExporterBibTeX * bibtexExporter = new BibTeX::FileExporterBibTeX();
bibtexExporter->setStringDelimiter( settings->fileIO_BibtexStringOpenDelimiter, settings->fileIO_BibtexStringCloseDelimiter );
bibtexExporter->setKeywordCasing( settings->fileIO_KeywordCasing );
bibtexExporter->setEncoding( settings->fileIO_Encoding );
bibtexExporter->setEnclosingCurlyBrackets( settings->fileIO_EnclosingCurlyBrackets );
exporter = bibtexExporter;
}
break;
case BibTeX::File::formatRIS:
if ( settings->external_xml2bibAvailable && settings->external_end2xmlAvailable && settings->fileIO_useBibUtils )
exporter = new BibTeX::FileExporterBibUtils( BibTeX::File::formatRIS );
else
exporter = new BibTeX::FileExporterRIS( );
break;
case BibTeX::File::formatEndNote:
case BibTeX::File::formatEndNoteXML:
case BibTeX::File::formatMODS:
case BibTeX::File::formatISI:
if ( settings->external_xml2bibAvailable && settings->external_end2xmlAvailable )
exporter = new BibTeX::FileExporterBibUtils( format );
break;
case BibTeX::File::formatXML:
exporter = new BibTeX::FileExporterXML();
break;
case BibTeX::File::formatHTML:
switch ( settings->fileIO_ExporterHTML )
{
case BibTeX::FileExporterExternal::exporterNone:
case BibTeX::FileExporterExternal::exporterXSLT:
{
TDEStandardDirs * kstd = TDEGlobal::dirs();
TQString resPath = kstd->findResource( "data", "kbibtexpart/xslt/html.xsl" );
11 years ago
if ( resPath != NULL )
transform = new BibTeX::XSLTransform( resPath );
if ( transform != NULL )
exporter = new BibTeX::FileExporterXSLT( transform );
else
{
kdDebug() << "XSLT for HTML export is not available" << endl;
}
}
break;
default:
{
exporter = new BibTeX::FileExporterExternal( settings->fileIO_ExporterHTML, BibTeX::File::formatHTML );
}
}
break;
case BibTeX::File::formatRTF:
{
if ( !settings->external_latex2rtfAvailable )
{
TQString msg = i18n( "To export a BibTeX document to the Rich Text Format (RTF) KBibTeX requires the program 'latex2rtf'." ) ;
11 years ago
KMessageBox::information( this, msg );
errorLog->append( msg );
}
else
{
BibTeX::FileExporterRTF *rtfExporter = new BibTeX::FileExporterRTF();
rtfExporter->setLaTeXLanguage( settings->fileIO_ExportLanguage );
rtfExporter->setLaTeXBibliographyStyle( settings->fileIO_ExportBibliographyStyle );
exporter = rtfExporter;
}
}
break;
case BibTeX::File::formatDocBook5:
{
if ( settings->fileIO_bib2db5ClassPath == TQString::null )
11 years ago
{
TQString msg = i18n( "To export a BibTeX document to the DocBook5 format KBibTeX requires the program 'bib2db5'." ) ;
11 years ago
KMessageBox::information( this, msg );
errorLog->append( msg );
}
else
{
BibTeX::FileExporterDocBook5 *db5Exporter = new BibTeX::FileExporterDocBook5( settings->fileIO_bib2db5ClassPath );
exporter = db5Exporter;
}
}
break;
case BibTeX::File::formatPDF:
{
if ( settings->fileIO_EmbedFiles && !Settings::kpsewhich( "embedfile.sty" ) )
{
KMessageBox::sorry( this, i18n( "Embedding files into the PDF file is enabled, but the required file 'embedfile.sty' was not found. Embedding files will be disabled." ), i18n( "Embedding files disabled" ) );
settings->fileIO_EmbedFiles = FALSE;
}
BibTeX::FileExporterPDF *pdfExporter = new BibTeX::FileExporterPDF( settings->fileIO_EmbedFiles );
pdfExporter->setLaTeXLanguage( settings->fileIO_ExportLanguage );
pdfExporter->setLaTeXBibliographyStyle( settings->fileIO_ExportBibliographyStyle );
TQStringList searchPaths;
for ( TQStringList::Iterator it = settings->editing_DocumentSearchPaths.begin(); it != settings->editing_DocumentSearchPaths.end(); ++it )
11 years ago
searchPaths.append( *it );
if ( m_bibtexfile->fileName != TQString::null )
11 years ago
searchPaths.append( KURL( m_bibtexfile->fileName ).directory( FALSE, FALSE ) );
pdfExporter->setDocumentSearchPaths( searchPaths );
exporter = pdfExporter;
}
break;
case BibTeX::File::formatPS:
{
BibTeX::FileExporterPS *psExporter = new BibTeX::FileExporterPS();
psExporter->setLaTeXLanguage( settings->fileIO_ExportLanguage );
psExporter->setLaTeXBibliographyStyle( settings->fileIO_ExportBibliographyStyle );
exporter = psExporter;
}
break;
default:
kdDebug() << "Unsupported export format selected" << endl;
}
if ( exporter != NULL )
{
startProgress( label, exporter );
result = exporter->save( iodevice, m_bibtexfile, errorLog );
endProgress( exporter );
if ( transform != NULL )
delete transform;
delete exporter;
}
setEnabled( TRUE );
return result;
}
bool DocumentWidget::newElement( const TQString& elementType )
11 years ago
{
Settings * settings = Settings::self( m_bibtexfile );
if ( m_editMode == emList )
{
if ( elementType.lower() == "macro" )
{
TQString name = TQString( i18n( "May only contain ASCII characters, in case of doubt keep English form", "NewMacro%1" ) ).arg( m_newElementCounter++ );
11 years ago
BibTeX::Macro *macro = new BibTeX::Macro( name );
if ( MacroWidget::execute( macro, m_isReadOnly ) == TQDialog::Accepted )
11 years ago
{
new DocumentListViewItem( m_bibtexfile, macro, m_listViewElements );
m_bibtexfile->appendElement( macro );
settings->addToCompletion( macro );
m_sideBar->refreshLists( m_bibtexfile );
return TRUE;
}
else
{
delete macro;
return FALSE;
}
}
else if ( elementType.lower() == "comment" )
{
BibTeX::Comment * comment = new BibTeX::Comment( i18n( "Put your comment here..." ) );
if ( CommentWidget::execute( comment, m_isReadOnly ) == TQDialog::Accepted )
11 years ago
{
new DocumentListViewItem( m_bibtexfile, comment, m_listViewElements );
m_bibtexfile->appendElement( comment );
return TRUE;
}
else
{
delete comment;
return FALSE;
}
}
else if ( elementType.lower() == "preamble" )
{
BibTeX::Preamble * preamble = new BibTeX::Preamble( );
if ( PreambleWidget::execute( preamble, m_isReadOnly ) == TQDialog::Accepted )
11 years ago
{
new DocumentListViewItem( m_bibtexfile, preamble, m_listViewElements );
m_bibtexfile->appendElement( preamble );
return TRUE;
}
else
{
delete preamble;
return FALSE;
}
}
else
{
TQString name = nextNewEntry();
11 years ago
BibTeX::Entry *entry = new BibTeX::Entry( elementType, name );
m_dirWatch.stopScan();
if ( EntryWidget::execute( entry, m_bibtexfile, m_isReadOnly, TRUE ) == TQDialog::Accepted )
11 years ago
{
new DocumentListViewItem( m_bibtexfile, entry, m_listViewElements );
m_bibtexfile->appendElement( entry );
settings->addToCompletion( entry );
m_sideBar->refreshLists( m_bibtexfile );
m_dirWatch.startScan();
return TRUE;
}
else
{
delete entry;
m_dirWatch.startScan();
return FALSE;
}
}
}
else if ( m_editMode == emSource )
{
if ( elementType.lower() == "macro" )
{
TQString name = TQString( i18n( "May only contain ASCII characters, in case of doubt keep English form", "NewString%1" ) ).arg( m_newElementCounter++ );
m_sourceView->insertLines( TQString( "@string{ %1 = \"%2\" }" ).arg( name ).arg( i18n( "No text yet" ) ) );
11 years ago
}
else if ( elementType.lower() == "comment" )
{
m_sourceView->insertLines( i18n( "@comment{ Put your comment here... }" ) );
}
else if ( elementType.lower() == "preamble" )
{
m_sourceView->insertLines( i18n( "@preamble{\"Put your preamble here using double quotes...\"}" ), 0 );
}
else
{
TQString name = nextNewEntry();
11 years ago
BibTeX::Entry *entry = new BibTeX::Entry( elementType, name );
for ( int t = 0; t < 2; t++ )
for ( int i = ( int ) BibTeX::EntryField::ftAbstract; i <= ( int ) BibTeX::EntryField::ftYear; i++ )
{
BibTeX::EntryField::FieldType fieldType = ( BibTeX::EntryField::FieldType ) i;
BibTeX::Entry::FieldRequireStatus fieldRequireStatus = BibTeX::Entry::getRequireStatus( entry->entryType(), fieldType );
if (( t == 0 && fieldRequireStatus == BibTeX::Entry::frsRequired ) || ( t == 1 && fieldRequireStatus == BibTeX::Entry::frsOptional ) )
{
BibTeX::Value * value = new BibTeX::Value();
value->items.append( new BibTeX::PlainText( fieldRequireStatus == BibTeX::Entry::frsRequired ? i18n( "REQUIRED" ) : i18n( "optional" ) ) );
BibTeX::EntryField *field = new BibTeX::EntryField( fieldType );
field->setValue( value );
entry->addField( field );
}
}
BibTeX::FileExporter * exporter = new BibTeX::FileExporterBibTeX( );
TQBuffer buffer;
11 years ago
buffer.open( IO_WriteOnly );
bool result = exporter->save( &buffer, entry );
buffer.close();
if ( result )
{
buffer.open( IO_ReadOnly );
TQTextStream textStream( &buffer );
textStream.setEncoding( TQTextStream::UnicodeUTF8 );
TQString text = textStream.read();
11 years ago
buffer.close();
TQStringList lines = TQStringList::split( '\n', text );
for ( TQStringList::Iterator it = lines.begin(); it != lines.end(); ++it )
11 years ago
m_sourceView->insertLines( *it );
}
delete exporter;
}
return TRUE;
}
return FALSE;
}
void DocumentWidget::updateViews()
{
m_listViewElements->updateVisiblity();
}
void DocumentWidget::showStatistics()
{
int n = m_bibtexfile->count();
KMessageBox::information( this, i18n( "This BibTeX file contains 1 element.", "This BibTeX file contains %n elements.", n ), i18n( "File Statistics" ) );
}
void DocumentWidget::refreshBibTeXFile()
{
if ( currentPage() == m_sourceView )
m_sourceView->setBibTeXFile( m_bibtexfile );
else if ( currentPage() == m_container )
m_listViewElements->setBibTeXFile( m_bibtexfile );
}
void DocumentWidget::setFactory( KXMLGUIFactory *factory, KXMLGUIClient *client )
{
m_searchBar->setFactory( factory, client );
m_listViewElements->setFactory( factory, client );
m_sourceView->setFactory( factory, client );
m_viewDocumentActionMenu = dynamic_cast<TDEActionMenu*>( client->action( "view_document" ) );
11 years ago
if ( m_viewDocumentActionMenu != NULL )
connect( m_viewDocumentActionMenu->popupMenu(), SIGNAL( activated( int ) ), this, SLOT( slotViewDocument( int ) ) );
m_assignKeywordsActionMenu = dynamic_cast<TDEActionMenu*>( client->action( "assign_keywords" ) );
11 years ago
if ( m_assignKeywordsActionMenu != NULL )
connect( m_assignKeywordsActionMenu->popupMenu(), SIGNAL( activated( int ) ), this, SLOT( slotAssignKeywords( int ) ) );
m_actionEditCut = client->action( "edit_cut" );
m_actionEditCopy = client->action( "edit_copy" );
m_actionEditCopyRef = client->action( "edit_copyref" );
m_actionEditPaste = client->action( "edit_paste" );
m_actionEditSelectAll = client->action( "edit_select_all" );
m_actionEditFind = client->action( "edit_find" );
m_actionEditFindNext = client->action( "edit_find_next" );
m_listViewElements->setViewShowColumnsMenu( dynamic_cast<TDEActionMenu*>( client->action( "view_showcolumns" ) ) );
m_searchWebsitesActionMenu = dynamic_cast<TDEActionMenu*>( client->action( "search_document_online" ) );
11 years ago
}
void DocumentWidget::updateViewDocumentMenu( )
{
if ( m_viewDocumentActionMenu == NULL )
{
kdDebug() << "FIXME: m_viewDocumentActionMenu is not set" << endl;
return;
}
TDEPopupMenu * popup = m_viewDocumentActionMenu->popupMenu();
11 years ago
popup->clear();
m_viewDocumentActionMenuURLs.clear();
BibTeX::Element * currentElement = NULL;
TQListViewItem * item = m_listViewElements->selectedItem();
11 years ago
if ( item == NULL )
item = m_listViewElements->currentItem();
DocumentListViewItem * dlvi = dynamic_cast<DocumentListViewItem*>( item );
if ( dlvi )
currentElement = dlvi->element();
BibTeX::Entry *entry = NULL;
if ( currentElement != NULL )
entry = dynamic_cast<BibTeX::Entry*>( currentElement );
m_viewDocumentActionMenu->setEnabled( FALSE );
if ( entry != NULL )
{
KURL::List documentURLs = getEntryURLs( entry );
if ( !documentURLs.isEmpty() )
{
for ( KURL::List::Iterator i = documentURLs.begin(); i != documentURLs.end(); ++i )
{
TQString prettyURL = ( *i ).prettyURL();
11 years ago
if ( prettyURL.endsWith( ".pdf", FALSE ) || prettyURL.find( "/pdf/" ) > 0 )
popup->insertItem( SmallIcon( "application-pdf" ), prettyURL );
11 years ago
else if ( prettyURL.endsWith( ".ps", FALSE ) )
popup->insertItem( SmallIcon( "application-postscript" ), prettyURL );
11 years ago
else if ( prettyURL.endsWith( ".html", FALSE ) || prettyURL.startsWith( "http://", FALSE ) )
popup->insertItem( SmallIcon( "text-html" ), prettyURL );
11 years ago
else
popup->insertItem( prettyURL );
m_viewDocumentActionMenuURLs.append( prettyURL );
}
m_viewDocumentActionMenu->setEnabled( TRUE );
}
}
}
void DocumentWidget::updateAssignKeywords()
{
if ( m_assignKeywordsActionMenu == NULL )
{
kdDebug() << "FIXME: m_assignKeywordsActionMenu is not set" << endl;
return;
}
TDEPopupMenu * popup = m_assignKeywordsActionMenu->popupMenu();
11 years ago
popup->clear();
m_assignKeywordsActionMenuURLs.clear();
TQStringList entryKeywords;
TQStringList fileKeywords;
11 years ago
/**
* Fetch keywords from selected entries into entryKeywords list
*/
TQValueList<BibTeX::Entry*> entryList;
for ( TQListViewItemIterator it( m_listViewElements, TQListViewItemIterator::Selected ); it.current(); ++it )
11 years ago
{
BibTeX::Element * currentElement = NULL;
DocumentListViewItem * dlvi = dynamic_cast<DocumentListViewItem*>( it.current() );
if ( dlvi && (( currentElement = dlvi->element() ) != NULL ) )
{
BibTeX::Entry *entry = dynamic_cast<BibTeX::Entry*>( currentElement );
if ( entry != NULL )
entryList << entry;
}
}
for ( TQValueList<BibTeX::Entry*>::Iterator it = entryList.begin(); it != entryList.end(); ++it )
11 years ago
{
BibTeX::Entry *entry = *it;
BibTeX::EntryField *field = NULL;
BibTeX::Value *valueKeywords = NULL;
if (( field = entry->getField( BibTeX::EntryField::ftKeywords ) ) != NULL && ( valueKeywords = field->value() ) != NULL )
for ( TQValueList<BibTeX::ValueItem*>::ConstIterator it = valueKeywords->items.begin();it != valueKeywords->items.end();++it )
11 years ago
{
BibTeX::KeywordContainer *container = dynamic_cast<BibTeX::KeywordContainer*>( *it );
if ( container != NULL )
for ( TQValueList<BibTeX::Keyword*>::ConstIterator kit = container->keywords.begin();kit != container->keywords.end();++kit )
11 years ago
entryKeywords.append(( *kit )->text() );
}
}
/**
* Fetch all keywords from current file into fileKeywords
*/
for ( TQValueList<BibTeX::Element*>::ConstIterator eit = m_bibtexfile->constBegin(); eit != m_bibtexfile->constEnd(); ++eit )
11 years ago
{
BibTeX::Entry *entry = dynamic_cast<BibTeX::Entry*>( *eit );
BibTeX::EntryField *field = NULL;
BibTeX::Value *value = NULL;
if ( entry != NULL && (( field = entry->getField( BibTeX::EntryField::ftKeywords ) ) != NULL ) && (( value = field->value() ) != NULL ) )
{
for ( TQValueList<BibTeX::ValueItem*>::ConstIterator vit = value->items.constBegin(); vit != value->items.constEnd();++vit )
11 years ago
{
BibTeX::KeywordContainer *container = dynamic_cast<BibTeX::KeywordContainer *>( *vit );
for ( TQValueList<BibTeX::Keyword*>::ConstIterator kit = container->keywords.constBegin(); kit != container->keywords.constEnd();++kit )
11 years ago
{
TQString text = ( *kit )->text();
11 years ago
if ( !fileKeywords.contains( text ) )
fileKeywords.append( text );
}
}
}
}
/**
* Merge keyword lists
*/
Settings * settings = Settings::self( m_bibtexfile );
TQStringList allKeywords = TQStringList( fileKeywords );
for ( TQStringList::Iterator it = settings->keyword_GlobalList.begin(); it != settings->keyword_GlobalList.end(); ++it )
11 years ago
if ( !allKeywords.contains( *it ) )
allKeywords.append( *it );
allKeywords.sort();
/**
* Build menu
*/
bool popupEmpty = FALSE;
if ( allKeywords.isEmpty() )
popupEmpty = TRUE;
else if ( allKeywords.count() < 24 )
{
for ( TQStringList::Iterator it = allKeywords.begin(); it != allKeywords.end(); ++it )
11 years ago
{
int i = popup->insertItem( *it );
popup->setItemChecked( i, entryKeywords.contains( *it ) );
m_assignKeywordsActionMenuURLs[i] = *it;
}
}
else
{
int maxCountPerSubMenu = ( int )sqrt( allKeywords.count() ) + 1;
int countPerSubMenu = 0;
TDEPopupMenu *subMenu = new TDEPopupMenu( popup );
11 years ago
connect( subMenu, SIGNAL( activated( int ) ), this, SLOT( slotAssignKeywords( int ) ) );
TQString startWord, endWord;
for ( TQStringList::Iterator it = allKeywords.begin(); it != allKeywords.end(); ++it )
11 years ago
{
if ( countPerSubMenu == 0 )
startWord = *it;
endWord = *it;
int i = subMenu->insertItem( *it );
subMenu->setItemChecked( i, entryKeywords.contains( *it ) );
m_assignKeywordsActionMenuURLs[i] = *it;
++countPerSubMenu;
if ( countPerSubMenu >= maxCountPerSubMenu )
{
popup->insertItem( TQString( i18n( "%1 ... %2" ) ).arg( startWord ).arg( endWord ), subMenu );
subMenu = new TDEPopupMenu( popup );
11 years ago
connect( subMenu, SIGNAL( activated( int ) ), this, SLOT( slotAssignKeywords( int ) ) );
countPerSubMenu = 0;
}
}
if ( countPerSubMenu > 0 )
{
popup->insertItem( TQString( i18n( "%1 ... %2" ) ).arg( startWord ).arg( endWord ), subMenu );
11 years ago
}
else
delete subMenu;
}
if ( !popupEmpty )
popup->insertSeparator();
TQWidget *container = new TQWidget( popup );
container->setBackgroundColor( TDEGlobalSettings::baseColor() );
TQHBoxLayout *layout = new TQHBoxLayout( container, 1, 1 );
TQLabel *label = new TQLabel( i18n( "New keyword:" ), container );
label->setBackgroundColor( TDEGlobalSettings::baseColor() );
11 years ago
layout->addWidget( label );
m_lineEditNewKeyword = new KLineEdit( container );
layout->addWidget( m_lineEditNewKeyword );
container->setFocusProxy( m_lineEditNewKeyword );
container->setFocusPolicy( TQWidget::ClickFocus );
11 years ago
popup->insertItem( container );
connect( m_lineEditNewKeyword, SIGNAL( returnPressed() ), this, SLOT( slotAddKeyword() ) );
}
void DocumentWidget::deferredInitialization()
{
restoreState();
m_listViewElements->deferredInitialization();
}
void DocumentWidget::saveState()
{
Settings * settings = Settings::self( m_bibtexfile );
settings->editing_HorSplitterSizes = m_horSplitter->sizes();
settings->editing_VertSplitterSizes = m_vertSplitter->sizes();
}
void DocumentWidget::restoreState()
{
m_listViewElements->restoreState();
m_searchBar->restoreState();
m_sideBar->restoreState();
Settings * settings = Settings::self( m_bibtexfile );
m_horSplitter->setSizes( settings->editing_HorSplitterSizes );
m_vertSplitter->setSizes( settings->editing_VertSplitterSizes );
if ( m_searchWebsitesActionMenu != NULL )
{
TDEPopupMenu * popup = m_searchWebsitesActionMenu->popupMenu();
11 years ago
popup->clear();
int i = 0;
for ( TQValueList<Settings::SearchURL*>::ConstIterator it = settings->searchURLs.begin(); it != settings->searchURLs.end(); ++it )
11 years ago
popup->insertItem(( *it ) ->description, ++i );
}
if ( settings->editing_UseSpecialFont )
m_preview->setFont( settings->editing_SpecialFont );
else
m_preview->setFont( TDEGlobalSettings::generalFont() );
11 years ago
}
void DocumentWidget::executeElement( DocumentListViewItem* item )
{
Settings * settings = Settings::self( m_bibtexfile );
bool openingDocumentOK = FALSE;
if ( settings->editing_MainListDoubleClickAction == 1 )
{
BibTeX::Entry *entry = dynamic_cast<BibTeX::Entry*>( item->element() );
if ( entry != NULL )
{
/** prefer local urls over remote urls, so first check for file:// and use other protocols only if no file:// was found */
TQString protocol = "file";
11 years ago
KURL::List urls = getEntryURLs( entry );
KURL selected = KURL();
while ( !selected.isValid() && protocol != TQString::null )
11 years ago
{
for ( KURL::List::Iterator it = urls.begin(); !selected.isValid() && it != urls.end(); ++it )
{
KURL url = *it;
if ( url.isValid() && ( !url.isLocalFile() || TQFile::exists( url.path() ) ) && url.protocol().startsWith( protocol ) )
11 years ago
selected = url;
}
/** little trick setting protocol prefix in the first round to "file://", then to "", and setting to null to quit the loop */
if ( !protocol.isEmpty() ) protocol = "";
else protocol = TQString::null;
11 years ago
}
if ( selected.isValid() )
openingDocumentOK = Settings::openUrl( selected, this );
}
}
if ( !openingDocumentOK )
editElement( item );
}
bool DocumentWidget::editElement()
{
bool result = false;
TQListViewItem * item = m_listViewElements->selectedItem();
11 years ago
if ( item == NULL )
item = m_listViewElements->currentItem();
DocumentListViewItem * dlvi = dynamic_cast<DocumentListViewItem*>( item );
if ( dlvi )
result = editElement( dlvi );
return result;
}
bool DocumentWidget::editElement( DocumentListViewItem*item )
{
BibTeX::Element * element = item->element();
bool result = editElement( element );
if ( result )
{
item->updateItem();
slotPreviewElement( item );
}
return result;
}
bool DocumentWidget::editElement( BibTeX::Element*element )
{
m_dirWatch.stopScan();
bool result = editElementDialog( element );
m_dirWatch.startScan( );
Settings * settings = Settings::self( m_bibtexfile );
settings->addToCompletion( element );
m_sideBar->refreshLists( m_bibtexfile );
return result;
}
bool DocumentWidget::editElementDialog( BibTeX::Element *element )
{
TQDialog::DialogCode dialogResult = TQDialog::Rejected;
11 years ago
BibTeX::Entry * entry = dynamic_cast<BibTeX::Entry*>( element );
if ( entry )
dialogResult = KBibTeX::EntryWidget::execute( entry, m_bibtexfile, m_isReadOnly, FALSE );
else
{
BibTeX::Comment * comment = dynamic_cast<BibTeX::Comment*>( element );
if ( comment )
dialogResult = KBibTeX::CommentWidget::execute( comment, m_isReadOnly );
else
{
BibTeX::Macro* macro = dynamic_cast<BibTeX::Macro*>( element );
if ( macro )
dialogResult = KBibTeX::MacroWidget::execute( macro, m_isReadOnly );
else
{
BibTeX::Preamble* preamble = dynamic_cast<BibTeX::Preamble*>( element );
if ( preamble )
dialogResult = KBibTeX::PreambleWidget::execute( preamble, m_isReadOnly );
}
}
}
if ( dialogResult == TQDialog::Accepted )
11 years ago
slotModified();
return dialogResult == TQDialog::Accepted;
11 years ago
}
void DocumentWidget::deleteElements()
{
if ( !m_isReadOnly )
{
if ( m_editMode == emList )
{
m_listViewElements->deleteSelected();
slotModified();
}
}
}
void DocumentWidget::sendSelectedToLyx()
{
if ( m_editMode == emList )
{
TQValueList<BibTeX::Element*> elements = m_listViewElements->selectedItems();
TQString genericMsg = i18n( "\n\nEither LyX is not running or has not been correctly configured to send references to." );
TQString title = i18n( "Error communicating with LyX" );
11 years ago
Settings * settings = Settings::self( m_bibtexfile );
TQString lyxPipeFilename = settings->detectLyXInPipe();
11 years ago
kdDebug() << "sendSelectedToLyx: lyxPipeFilename= " << lyxPipeFilename << endl;
if ( lyxPipeFilename.isNull() )
KMessageBox::error( this, i18n( "Cannot determine how to send references to LyX." ).append( genericMsg ), title );
else
{
TQFile pipe( lyxPipeFilename );
11 years ago
if ( !pipe.exists() )
KMessageBox::error( this, i18n( "The inpipe as configured in LyX does not exist." ).append( genericMsg ), title );
else
{
if ( !pipe.open( IO_WriteOnly ) )
KMessageBox::error( this, i18n( "Cannot open the inpipe as configured in LyX." ).append( genericMsg ), title );
else
{
TQStringList refsToSend;
for ( TQValueList<BibTeX::Element*>::Iterator it = elements.begin(); it != elements.end(); ++it )
11 years ago
{
BibTeX::Entry *entry = dynamic_cast<BibTeX::Entry*>( *it );
if ( entry != NULL ) refsToSend.append( entry->id() );
}
TQTextStream * writer = new TQTextStream( &pipe );
TQString msg = "LYXCMD:kbibtex:citation-insert:" + refsToSend.join( "," );
11 years ago
*writer << msg << endl;
delete writer;
pipe.close();
}
}
}
}
}
void DocumentWidget::cutElements()
{
if ( !m_isReadOnly )
{
if ( m_editMode == emList )
{
m_listViewElements->cut();
}
else if ( m_editMode == emSource )
{
m_sourceView->cut();
}
slotModified();
}
}
void DocumentWidget::copyElements()
{
if ( m_editMode == emList )
{
m_listViewElements->copy();
}
else if ( m_editMode == emSource )
{
m_sourceView->copy();
}
}
void DocumentWidget::copyRefElements()
{
if ( m_editMode == emList )
{
m_listViewElements->copyReferences();
}
else if ( m_editMode == emSource )
{
// TODO: Get selected text, parse text into BibTeX::File and join list of entries' ids
}
}
void DocumentWidget::pasteElements()
{
if ( !m_isReadOnly )
{
if ( m_editMode == emList )
{
if ( m_listViewElements->paste() )
slotModified();
}
else if ( m_editMode == emSource )
{
if ( m_sourceView->paste() )
slotModified();
}
}
}
void DocumentWidget::selectAll()
{
if ( m_editMode == emList )
m_listViewElements->selectAll();
else if ( m_editMode == emSource )
m_sourceView->selectAll();
}
void DocumentWidget::setReadOnly( bool isReadOnly )
{
m_isReadOnly = isReadOnly;
m_listViewElements->setReadOnly( m_isReadOnly );
m_sourceView->setReadOnly( m_isReadOnly );
m_sideBar->setReadOnly( m_isReadOnly );
}
void DocumentWidget::configureEditor()
{
m_sourceView->configureEditor();
}
void DocumentWidget::undoEditor()
{
m_sourceView->undo();
}
void DocumentWidget::find()
{
if ( m_editMode == emSource )
m_sourceView->find();
}
void DocumentWidget::findNext()
{
if ( m_editMode == emSource )
m_sourceView->findNext();
}
void DocumentWidget::slotShowProgress( int current, int total )
{
if ( m_progressDialog != NULL )
{
m_progressDialog->setProgress( current, total );
tqApp->processEvents();
11 years ago
}
}
void DocumentWidget::startProgress( const TQString & label, TQObject * progressFrom )
11 years ago
{
m_progressDialog = new TQProgressDialog( this );
11 years ago
m_progressDialog->setLabelText( label );
connect( progressFrom, SIGNAL( progress( int, int ) ), this, SLOT( slotShowProgress( int, int ) ) );
connect( m_progressDialog, SIGNAL( canceled() ), progressFrom, SLOT( cancel( ) ) );
TQApplication::setOverrideCursor( TQt::waitCursor );
11 years ago
}
void DocumentWidget::endProgress( TQObject * progressFrom )
11 years ago
{
disconnect( progressFrom, SIGNAL( progress( int, int ) ), this, SLOT( slotShowProgress( int, int ) ) );
disconnect( m_progressDialog, SIGNAL( canceled() ), progressFrom, SLOT( cancel( ) ) );
delete m_progressDialog;
m_progressDialog = NULL;
TQApplication::restoreOverrideCursor();
11 years ago
}
void DocumentWidget::searchWebsites( const TQString& searchURL, bool includeAuthor )
11 years ago
{
DocumentListViewItem * item = dynamic_cast<DocumentListViewItem*>( m_listViewElements->selectedItem() );
if ( item == NULL )
item = dynamic_cast<DocumentListViewItem*>( m_listViewElements->currentItem() );
if ( item != NULL )
searchWebsites( item->element(), searchURL, includeAuthor );
}
void DocumentWidget::searchWebsites( BibTeX::Element * element, const TQString& searchURL, bool includeAuthor )
11 years ago
{
TQString queryString = TQString::null;
11 years ago
BibTeX::Entry* entry = dynamic_cast<BibTeX::Entry*>( element );
if ( entry != NULL )
{
BibTeX::EntryField * field = entry->getField( BibTeX::EntryField::ftTitle );
if ( field && field->value() )
queryString = field->value() ->text();
if ( includeAuthor )
{
field = entry->getField( BibTeX::EntryField::ftAuthor );
if ( field && field->value() )
{
BibTeX::PersonContainer *personContainer = dynamic_cast<BibTeX::PersonContainer*>( field->value()->items.first() );
if ( personContainer != NULL )
{
TQValueList<BibTeX::Person*> list = personContainer->persons;
for ( TQValueList<BibTeX::Person*>::ConstIterator it = list.begin(); it != list.end(); ++it )
11 years ago
queryString = queryString.append( " " ).append(( *it )->lastName() );
}
}
}
}
else
{
BibTeX::Comment * comment = dynamic_cast<BibTeX::Comment*>( element );
if ( comment != NULL )
queryString = comment->text();
else
{
BibTeX::Macro * macro = dynamic_cast<BibTeX::Macro*>( element );
if ( macro != NULL && macro->value() )
queryString = macro->value() ->text();
else
kdDebug() << "Not yet supported" << endl;
}
}
if ( queryString != TQString::null )
11 years ago
{
queryString = queryString.stripWhiteSpace().replace( '$', "" ).replace( "%", "%25" ).replace( "+", "%2B" ).replace( " ", "%20" ).replace( "#", "%23" ).replace( "&", "%26" ).replace( "?", "%3F" ).replace( '{', "" ).replace( '}', "" );
KURL url( TQString( searchURL ).arg( queryString ) );
11 years ago
Settings::openUrl( url, this );
}
}
void DocumentWidget::onlineSearch()
{
if ( !m_isReadOnly )
{
BibTeX::FileExporter * exporter = new BibTeX::FileExporterBibTeX( );
TQValueList<BibTeX::Entry*> list;
if ( WebQueryWizard::execute( this, list ) == TQDialog::Accepted )
11 years ago
{
Settings * settings = Settings::self( m_bibtexfile );
for ( TQValueList<BibTeX::Entry*>::Iterator it = list.begin(); it != list.end(); ++it )
11 years ago
{
( *it )->setId( IdSuggestions::resolveConflict( m_bibtexfile, ( *it )->id() ) );
if ( m_editMode == emList )
m_listViewElements->insertItem( new BibTeX::Entry( *it ) );
else
{
TQBuffer buffer;
11 years ago
buffer.open( IO_WriteOnly );
bool result = exporter->save( &buffer, *it );
buffer.close();
if ( result )
{
buffer.open( IO_ReadOnly );
TQTextStream textStream( &buffer );
textStream.setEncoding( TQTextStream::UnicodeUTF8 );
TQString text = textStream.read();
11 years ago
buffer.close();
TQStringList lines = TQStringList::split( '\n', text );
for ( TQStringList::Iterator it = lines.begin(); it != lines.end(); ++it )
11 years ago
m_sourceView->insertLines( *it );
m_sourceView->insertLines( "" );
}
}
settings->addToCompletion( *it );
}
slotModified();
}
delete exporter;
}
}
void DocumentWidget::findDuplicates()
{
MergeElements *me = new MergeElements( this );
if ( me->mergeDuplicates( m_bibtexfile ) == TQDialog::Accepted )
11 years ago
{
refreshBibTeXFile();
slotModified();
}
delete me;
}
void DocumentWidget::updateFromGUI()
{
BibTeX::File * file = NULL;
if ( currentPage() == m_sourceView )
file = m_sourceView->getBibTeXFile();
else if ( currentPage() == m_container )
file = m_listViewElements->getBibTeXFile();
if ( file != NULL && file != m_bibtexfile )
{
delete m_bibtexfile;
m_bibtexfile = file;
}
}
TQString DocumentWidget::nextNewEntry()
11 years ago
{
TQString name = TQString( i18n( "May only contain ASCII characters, in case of doubt keep English form", "NewEntry%1" ) ).arg( m_newElementCounter++ );
11 years ago
while ( m_bibtexfile->containsKey( name ) != NULL )
{
++m_newElementCounter;
name = TQString( i18n( "May only contain ASCII characters, in case of doubt keep English form", "NewEntry%1" ) ).arg( m_newElementCounter++ );
11 years ago
}
return name;
}
KURL::List DocumentWidget::getEntryURLs( BibTeX::Entry *entry )
{
TQStringList urls = entry->urls();
11 years ago
KURL::List result;
for ( TQStringList::Iterator it = urls.begin(); it != urls.end(); ++it )
11 years ago
{
KURL url = Settings::locateFile( *it, m_bibtexfile->fileName, this );
if ( url.isValid() )
result.append( url );
}
return result;
}
void DocumentWidget::slotSelectionChanged()
{
int numSelected = 0;
TQListViewItemIterator it( m_listViewElements, TQListViewItemIterator::Selected );
11 years ago
while ( it.current() && numSelected < 3 )
{
numSelected++;
it++;
}
emit listViewSelectionChanged( numSelected );
}
BibTeX::FileImporter *DocumentWidget::fileImporterFactory( const TQString &fileName )
11 years ago
{
Settings * settings = Settings::self( NULL );
BibTeX::FileImporter * importer = NULL;
BibTeX::File::FileFormat format = BibTeX::File::formatUndefined;
if ( fileName.endsWith( ".bib", FALSE ) )
format = BibTeX::File::formatBibTeX;
else if ( settings->external_xml2bibAvailable && settings->external_end2xmlAvailable && ( fileName.endsWith( ".ref", FALSE ) || fileName.endsWith( ".refer", FALSE ) || fileName.endsWith( ".txt", FALSE ) || fileName.endsWith( ".rfr", FALSE ) ) )
format = BibTeX::File::formatEndNote;
else if ( settings->external_xml2bibAvailable && settings->external_end2xmlAvailable && ( fileName.endsWith( ".isi", FALSE ) || fileName.endsWith( ".cgi", FALSE ) ) )
format = BibTeX::File::formatISI;
else if ( fileName.endsWith( ".ris", FALSE ) )
format = BibTeX::File::formatRIS;
else if ( fileName.endsWith( ".xml", FALSE ) )
{
TQStringList options = TQStringList::split( '|', ( settings->external_xml2bibAvailable && settings->external_end2xmlAvailable ? "MODS|EndNote XML|internal XML" : "internal XML" ) );
11 years ago
bool ok = false;
TQString answer = KInputDialog::getItem( i18n( "Choose file format" ), TQString( i18n( "Choose file format of file '%1':" ) ).arg( fileName ), options, 0, false, &ok, this );
11 years ago
if ( ok && !answer.isNull() && answer == "DocBook5" )
format = BibTeX::File::formatDocBook5;
else if ( ok && !answer.isNull() && answer == "MODS" )
format = BibTeX::File::formatMODS;
else if ( ok && !answer.isNull() && answer == "EndNote XML" )
format = BibTeX::File::formatEndNoteXML;
else if ( ok && !answer.isNull() && answer == "internal XML" )
format = BibTeX::File::formatXML;
}
else
{
TQStringList options = TQStringList::split( '|', ( settings->external_xml2bibAvailable && settings->external_end2xmlAvailable ? "BibTeX|EndNote|ISI|RIS" : "BibTeX|RIS" ) );
11 years ago
bool ok = false;
TQString answer = KInputDialog::getItem( i18n( "Choose file format" ), TQString( i18n( "Choose file format of file '%1':" ) ).arg( fileName ), options, 0, false, &ok, this );
11 years ago
if ( ok && !answer.isNull() && answer == "BibTeX" )
format = BibTeX::File::formatBibTeX;
else if ( ok && !answer.isNull() && answer == "EndNote" )
format = BibTeX::File::formatEndNote;
else if ( ok && !answer.isNull() && answer == "ISI" )
format = BibTeX::File::formatISI;
else if ( ok && !answer.isNull() && answer == "RIS" )
format = BibTeX::File::formatRIS;
}
if ( format != BibTeX::File::formatUndefined )
{
Settings * settings = Settings::self( NULL );
switch ( format )
{
case BibTeX::File::formatBibTeX:
{
Settings * settings = Settings::self( NULL );
importer = new BibTeX::FileImporterBibTeX( settings->editing_FirstNameFirst, settings->fileIO_Encoding );
}
break;
case BibTeX::File::formatRIS:
{
if ( settings->external_xml2bibAvailable && settings->external_end2xmlAvailable && settings->fileIO_useBibUtils )
importer = new BibTeX::FileImporterBibUtils( BibTeX::File::formatRIS );
else
importer = new BibTeX::FileImporterRIS( );
break;
}
case BibTeX::File::formatEndNote:
case BibTeX::File::formatEndNoteXML:
case BibTeX::File::formatISI:
case BibTeX::File::formatMODS:
if ( settings->external_xml2bibAvailable && settings->external_end2xmlAvailable )
importer = new BibTeX::FileImporterBibUtils( format );
break;
default:
{
KMessageBox::sorry( this, TQString( i18n( "The file '%1' does not contain a known type of bibliography." ) ).arg( fileName ), i18n( "Unknown file format" ) );
11 years ago
}
}
}
return importer;
}
void DocumentWidget::slotPreviewElement( TQListViewItem * item )
11 years ago
{
if ( item == NULL )
item = m_listViewElements->selectedItem();
if ( item == NULL )
item = m_listViewElements->currentItem();
if ( item != NULL )
{
DocumentListViewItem * dlvi = dynamic_cast<DocumentListViewItem*>( item );
if ( dlvi != NULL && m_listViewElements->isEnabled() )
{
BibTeX::Element *currentElement = dlvi->element()->clone();
BibTeX::Entry *entry = dynamic_cast<BibTeX::Entry*>( currentElement );
if ( entry != NULL )
m_bibtexfile->completeReferencedFields( entry );
TDEStandardDirs * kstd = TDEGlobal::dirs();
11 years ago
BibTeX::XSLTransform *transform = new BibTeX::XSLTransform( kstd->findResource( "data", "kbibtexpart/xslt/html.xsl" ) );
if ( transform != NULL )
{
BibTeX::FileExporterXSLT * exporter = new BibTeX::FileExporterXSLT( transform );
TQBuffer buffer;
11 years ago
buffer.open( IO_WriteOnly );
bool result = exporter->save( &buffer, currentElement );
buffer.close();
if ( result )
{
buffer.open( IO_ReadOnly );
TQTextStream htmlTS( &buffer );
htmlTS.setEncoding( TQTextStream::UnicodeUTF8 );
TQString htmlText = htmlTS.read();
11 years ago
buffer.close();
TQString text = htmlText.remove( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ).append( "</qt>" ).prepend( "<qt>" ).replace( TQRegExp( "\\\\emph\\{([^}]+)\\}" ), "<em>\\1</em>" ).replace( TQRegExp( "\\\\[A-Za-z0-9]+" ), "" ).replace( '{', "" ).replace( '}', "" );
11 years ago
m_preview->setText( text );
}
else
{
int i = ( int ) BibTeX::EntryField::ftTitle - ( int ) BibTeX::EntryField::ftAbstract + 2;
m_preview->setText( m_listViewElements->currentItem()->text( i ) );
}
delete exporter;
delete transform;
}
else
m_preview->setText( i18n( "No preview available" ) );
delete currentElement;
}
}
}
void DocumentWidget::slotTabChanged( TQWidget *tab )
11 years ago
{
setEnabled( FALSE );
TQApplication::setOverrideCursor( TQt::waitCursor );
11 years ago
BibTeX::File *bibTeXFile = NULL;
if ( m_editMode == emSource )
bibTeXFile = m_sourceView->getBibTeXFile();
else if ( m_editMode == emList )
bibTeXFile = m_listViewElements->getBibTeXFile();
if ( tab == m_sourceView && m_editMode != emSource )
{
// switching from list view to source view
if ( bibTeXFile != NULL )
{
// check whether the selected widget has changed the bibtex file
if ( bibTeXFile != m_bibtexfile )
{
delete m_bibtexfile;
m_bibtexfile = bibTeXFile;
}
m_sourceView->setBibTeXFile( m_bibtexfile );
}
m_editMode = emSource;
if ( m_actionEditCut && m_actionEditCopy && m_actionEditPaste )
{
m_actionEditCut->setEnabled( TRUE );
m_actionEditCopy->setEnabled( TRUE );
m_actionEditPaste->setEnabled( TRUE );
}
}
else if ( tab == m_container && m_editMode != emList )
{
// switching from source view to list view
if ( bibTeXFile != NULL )
{
// check whether the selected widget has changed the bibtex file
if ( bibTeXFile != m_bibtexfile )
{
delete m_bibtexfile;
m_bibtexfile = bibTeXFile;
Settings * settings = Settings::self( m_bibtexfile );
settings->addToCompletion( m_bibtexfile );
m_sideBar->refreshLists( m_bibtexfile );
}
m_listViewElements->setBibTeXFile( m_bibtexfile );
emit listViewSelectionChanged( 0 );
}
m_editMode = emList;
}
setEnabled( TRUE );
if ( tab == m_sourceView )
m_sourceView->setFocus();
else if ( tab == m_container )
m_listViewElements->setFocus();
if ( m_actionEditFind && m_actionEditFindNext )
{
m_actionEditFind->setEnabled( m_editMode == emSource );
m_actionEditFindNext->setEnabled( m_editMode == emSource );
}
if ( m_actionEditCopyRef )
m_actionEditCopyRef->setEnabled( m_editMode == emList );
TQApplication::restoreOverrideCursor();
11 years ago
emit undoChanged( m_editMode == emSource );
}
void DocumentWidget::slotModified()
{
if ( isEnabled() )
{
m_sideBar->refreshLists( m_bibtexfile );
emit modified( );
}
}
void DocumentWidget::slotFileGotDirty( const TQString& path )
11 years ago
{
if ( path == m_filename )
{
m_dirWatch.removeFile( m_filename );
TQTimer::singleShot( 100, this, SLOT( slotRefreshDirtyFile( ) ) );
11 years ago
}
}
void DocumentWidget::slotRefreshDirtyFile()
{
if ( KMessageBox::questionYesNo( this, TQString( i18n( "File '%1' has been modified. Reload file to import changes or ignore changes?" ) ).arg( m_filename ), i18n( "Reload file?" ), KGuiItem( i18n( "Reload" ), "reload" ), KGuiItem( i18n( "Ignore" ), "ignore" ) ) == KMessageBox::Yes )
11 years ago
open( m_filename, FALSE );
else
m_dirWatch.addFile( m_filename );
}
void DocumentWidget::slotViewDocument( int id )
{
Settings::openUrl( m_viewDocumentActionMenuURLs[ m_viewDocumentActionMenu->popupMenu() ->indexOf( id )], this );
}
void DocumentWidget::slotViewFirstDocument()
{
for ( TQStringList::Iterator it = m_viewDocumentActionMenuURLs.begin(); it != m_viewDocumentActionMenuURLs.end(); ++it )
11 years ago
if (( *it ).endsWith( ".pdf" ) || ( *it ).endsWith( ".ps" ) || ( *it ).endsWith( ".djv" ) )
{
Settings::openUrl( *it, this );
break;
}
}
void DocumentWidget::slotViewFirstDocumentsOnlineRef()
{
for ( TQStringList::Iterator it = m_viewDocumentActionMenuURLs.begin(); it != m_viewDocumentActionMenuURLs.end(); ++it )
11 years ago
if (( *it ).contains( "dx.doi.org" ) )
{
Settings::openUrl( *it, this );
break;
}
}
void DocumentWidget::slotAssignKeywords( int id )
{
TQValueList<BibTeX::Entry*> entryList;
11 years ago
TQListViewItem * item = m_listViewElements->selectedItem();
11 years ago
if ( item == NULL )
item = m_listViewElements->currentItem();
for ( TQListViewItemIterator it( m_listViewElements, TQListViewItemIterator::Selected ); it.current(); ++it )
11 years ago
{
BibTeX::Element * currentElement = NULL;
DocumentListViewItem * dlvi = dynamic_cast<DocumentListViewItem*>( it.current() );
if ( dlvi && (( currentElement = dlvi->element() ) != NULL ) )
{
BibTeX::Entry *entry = dynamic_cast<BibTeX::Entry*>( currentElement );
if ( entry != NULL )
entryList << entry;
}
}
for ( TQValueList<BibTeX::Entry*>::Iterator it = entryList.begin(); it != entryList.end(); ++it )
11 years ago
{
BibTeX::Entry *entry = *it;
BibTeX::EntryField *field = NULL;
BibTeX::KeywordContainer *keywordContainer = NULL;
if (( field = entry->getField( BibTeX::EntryField::ftKeywords ) ) == NULL )
{
entry->addField( field = new BibTeX::EntryField( BibTeX::EntryField::ftKeywords ) );
}
BibTeX::Value *value = field->value();
if ( !value->items.isEmpty() )
keywordContainer = dynamic_cast<BibTeX::KeywordContainer*>( value->items.first() );
if ( keywordContainer == NULL )
value->items.append( keywordContainer = new BibTeX::KeywordContainer() );
if ( m_assignKeywordsActionMenu->popupMenu() ->isItemChecked( id ) )
keywordContainer->remove( m_assignKeywordsActionMenuURLs[ id ] );
else
keywordContainer->append( m_assignKeywordsActionMenuURLs[ id ] );
slotModified();
}
}
void DocumentWidget::slotAddKeyword()
{
TQString newKeyword = m_lineEditNewKeyword->text();
11 years ago
TQValueList<BibTeX::Entry*> entryList;
for ( TQListViewItemIterator it( m_listViewElements, TQListViewItemIterator::Selected ); it.current(); ++it )
11 years ago
{
BibTeX::Element * currentElement = NULL;
DocumentListViewItem * dlvi = dynamic_cast<DocumentListViewItem*>( it.current() );
if ( dlvi && (( currentElement = dlvi->element() ) != NULL ) )
{
BibTeX::Entry *entry = dynamic_cast<BibTeX::Entry*>( currentElement );
if ( entry != NULL )
entryList << entry;
}
}
for ( TQValueList<BibTeX::Entry*>::Iterator it = entryList.begin(); it != entryList.end(); ++it )
11 years ago
{
BibTeX::Entry *entry = *it;
BibTeX::EntryField *field = entry->getField( BibTeX::EntryField::ftKeywords );
if ( field == NULL )
{
field = new BibTeX::EntryField( BibTeX::EntryField::ftKeywords );
entry->addField( field );
}
BibTeX::Value *value = field->value();
BibTeX::KeywordContainer *keywordContainer = NULL;
if ( !value->items.isEmpty() )
keywordContainer = dynamic_cast<BibTeX::KeywordContainer*>( value->items.first() );
if ( keywordContainer == NULL )
value->items.append( keywordContainer = new BibTeX::KeywordContainer() );
keywordContainer->append( newKeyword );
}
if ( !entryList.isEmpty() )
{
if ( m_lineEditNewKeyword->isVisible() &&
m_lineEditNewKeyword->parentWidget() &&
m_lineEditNewKeyword->parentWidget()->parentWidget() &&
m_lineEditNewKeyword->parentWidget()->parentWidget()->inherits( "TQPopupMenu" ) )
11 years ago
m_lineEditNewKeyword->parentWidget()->parentWidget()->close();
slotModified();
}
}
void DocumentWidget::slotNormalizeIds()
{
Settings * settings = Settings::self();
TQMap<BibTeX::Entry*, TQString> entryToNewId;
TQMap<BibTeX::Entry*, DocumentListViewItem*> entryToItem;
TQStringList msgList;
11 years ago
if ( settings->idSuggestions_default < 0 )
{
KMessageBox::sorry( this, i18n( "You must set a default id suggestion in the settings dialog." ) );
return;
}
for ( TQListViewItemIterator it( m_listViewElements, TQListViewItemIterator::Selected ); it.current(); ++it )
11 years ago
{
BibTeX::Element * currentElement = NULL;
DocumentListViewItem * dlvi = dynamic_cast<DocumentListViewItem*>( it.current() );
if ( dlvi && (( currentElement = dlvi->element() ) != NULL ) )
{
BibTeX::Entry *entry = dynamic_cast<BibTeX::Entry*>( currentElement );
if ( entry != NULL )
{
TQString newEntryId = IdSuggestions::createDefaultSuggestion( m_bibtexfile, entry );
11 years ago
entryToNewId[entry] = newEntryId;
entryToItem[entry] = dlvi;
msgList << "Replacing id of entry \"" + entry->id() + "\" with new id \"" + newEntryId + "\"";
}
}
}
if ( entryToNewId.isEmpty() )
KMessageBox::information( this, i18n( "No entries were selected." ) );
else if ( KMessageBox::questionYesNoList( this, i18n( "The following changes will be applied to the currently selected elements.\nConflicts with duplicate entry ids will be resolved when applying the new ids." ), msgList, i18n( "Normalize Entry Ids" ), KGuiItem( i18n( "Replace Entry Ids" ), "system-run" ), KGuiItem( i18n( "Cancel" ), "cancel" ) ) == KMessageBox::Yes )
11 years ago
{
TQApplication::setOverrideCursor( TQt::waitCursor );
TQMap<BibTeX::Entry*, DocumentListViewItem*>::Iterator itItem = entryToItem.begin();
for ( TQMap<BibTeX::Entry*, TQString>::Iterator it = entryToNewId.begin(); it != entryToNewId.end(); ++it, ++itItem )
11 years ago
{
BibTeX::Entry *entry = it.key();
TQString newEntryId = it.data();
11 years ago
newEntryId = IdSuggestions::resolveConflict( m_bibtexfile, newEntryId, entry );
tqDebug( "Replacing id of entry \"%s\" with new id \"%s\"", entry->id().latin1(), newEntryId.latin1() );
11 years ago
entry->setId( newEntryId );
itItem.data()->updateItem();
}
slotModified();
m_sideBar->refreshLists( m_bibtexfile );
TQApplication::restoreOverrideCursor();
11 years ago
}
}
KDirWatch &DocumentWidget::dirWatch()
{
return m_dirWatch;
}
}
#include "documentwidget.moc"