/***************************************************************************
 *   Copyright (C) 2004-2006 by Pere Constans
 *   constans@molspaces.com
 *   cb2Bib version 0.6.1
 *   See LICENSE file that comes with this distribution
 ***************************************************************************/
#include "cb2bibconffri.h"
#include "cb2bibconf.h"
#include "cb2bib_par.h"
#include "citeidmakerlineedit.h"
#include "colorlistviewitem.h"

#include <qcolordialog.h>
#include <qlistview.h>
#include <qpushbutton.h>
#include <qtabwidget.h>


/*! \page c2bconf Configuring cb2Bib
 
- \ref c2bconf_files
- \ref c2bconf_fonts
- \ref c2bconf_input
- \ref c2bconf_network
- \ref c2bconf_output
- \ref c2bconf_pdfimport
<p>&nbsp;</p>
 
\section c2bconf_files Configuring Files
 
- <b>Journal Abbreviation List File</b> \n This file contains a list of journal
names equivalences: a capital-letter acronym, standard abbreviated form, and
full name of the journal. If an input journal name is recognized, cb2Bib will
use the standard abbreviated form for the <tt>journal</tt> bibkey. If your usual
journal were not within the distributed, default <tt>abbreviations.txt</tt>, you
could edit this file, or point to a personalized abbreviation file. <b>Note:</b>
Changes in the abbreviation file only take place after reestarting cb2Bib.
 
- <b>Regular Expression List File</b> \n The cb2Bib distribution includes the
file <tt>regexps.txt</tt> with a few set of rules for reference extraction. This
includes most of the scientific literature. Extracting from email alerts or
publisher abstract pages is a <em>volatile</em> task. Information does not
follow a standardized structure. Extraction pattern may then change as often as
the web design needs to. Besides, such extraction from the clipboard is system
dependent, in a way that produces different formatting of the text copies on
different systems. You can use your personalized <tt>regexps.txt</tt> file, for
testing, debugging -regular expressions are reloaded each time the automatic
recognition engine executes-, and fullfiling your particular extraction needs.
 
- <b>Bookmarks and Network Query Info File</b> \n The cb2Bib distribution
includes the file <tt>netqinf.txt</tt>, a bookmark file for journal querying.
Rules and cb2Bib syntax may change considerably in future realeases. Check the
file <tt>netqinf.txt</tt> for implementations details and customization.
 
- <b>Rename and Copy/Move article files to Directory</b> \n If selected, each
file 'drag and dropped' onto the cb2Bib main window is renamed to
<tt>citeID.pdf</tt> (or citeID.ps, citeID.dvi, etc.) and moved to the pointed
storage directory. If unselected, the file URL is written to the <tt>file</tt>
bibkeyword, without any renaming or moving of the file.
 
- <b>Copy or Move article files</b> \n Choose whether copy or move Network Files
'dropped' onto the cb2Bib main window. See also <b>Use External Network
Client</b>.
 
 
\section c2bconf_fonts Configuring Fonts
 
- <b>Font Selector</b> \n Selects the main window and editor font family and size.
 
- <b>Context Colors</b> \n Doubleclick on context color items to select syntax
highlighter font color. Besides syntax highlighting, and to ease manual
bibliographic extractions, cb2Bib has the following coloring convention. 'cb2Bib
unrelevant text' colors non-word, non-digit, and cb2Bib's internal tags. 'cb2Bib
relevant text' refers to the reference's year. 'cb2Bib highly relevant' attempts to
guess text sectioning, highlighting 'abstract', 'introduction', and 'keywords'.
 
 
\section c2bconf_input Configuring Input
 
- <b>Replace/Remove from input stream</b> \n If checked, input stream is
preprocessed by performing a customizable set of string substitutions/removals.
This option is mainly intended to remove image HTML <tt>alt</tt> tags. Although
not visible, <tt>alt</tt> tags reach the clipboard when selecting and copying
text. Author lists embellished with email icons may therefore contain
<tt>alt</tt> strings that would interfere with the author names processing. In
addition, this option is also appropriate to help translating special characters
to Unicode and LaTeX. Use it carefully, as to avoid unwanted or unsuspected
substitutions. See also \ref bibproc.
 
- <b>External Clipboard Preparsing Command</b> \n Preparses input stream through
an external, user-defined tool. Use the box bellow to specify its name and path.
cb2Bib executes the command <tt>tool_name tmp_inputfile tmp_outputfile</tt>. You
might consider a wrapper shell script to fullfill this particular syntax
requirement. Two examples, <tt>isi2bib</tt> and <tt>ris2bib</tt> are provided.
To test them, make sure the 
\htmlonly
<a href="http://www.scripps.edu/~cdputnam/software/bibutils/bibutils.html" 
target="_blank">BibUtils Package</a>
\endhtmlonly
is available on your machine. Otherwise, modify these scripts according to your
needs. See also \ref keyboard, \ref bibproc, and the examples \ref ex_isi_format
and \ref ex_ris.
 
- <b>Perform always, as part of an automatic extraction</b> \n Performs
preparsing each time the recognition engine is invoked. <b>Caution:</b> cb2Bib,
when not in disconnected mode, starts the recognition engine each time the
clipboard changes. Thus, it might send arbitrary data to the external parsing
tool. The tool might not be prepared to handle <b>'any data'</b> and might fall
into a sort of <b>'infinite loop'</b>. cb2Bib kills the external tool after a
reasonable waiting. But, if the tool is called through a wrapper script, killing
the script will not end the tool itself. Therefore, <b>check this box only when
needed</b>. If you write your own preparser, design it as to write no data to
output file whenever it can not process an input properly. When the preparser
produces no data, the cb2Bib sends instead the input stream to the recognition
engine. In this way, preparsing and normal cb2Bib functioning will work
harmoniously.
 
- <b>Do not show log output</b> \n If unchecked, the external process messages,
and the input and output streams are shown in a log window. Showing output logs
is usefull for debugging purposes.
 
 
\section c2bconf_network Configuring Network
 
- <b>Use External Network Client</b> \n cb2Bib manages local and network files
in an equivalent manner. Network file retrieving, however, requires sometimes
password and/or cookies administration. Opening and browsing retrieved files
requires also desktop specific commands. The KDE desktop incorporates
<tt>kfmclient</tt> utility. A command <tt>kfmclient (copy|move|exec) orig
[dest]</tt> permits copying, moving or opening files, taking care of
redirections, cookies or user browsing preferences. By checking this box, cb2Bib
will use the specified file manger client. External file managers should be used
whenever redirections or cookies are an issue. <b>Note:</b> Internal Network
file manager has been found to 'freeze' on some Windows platforms. Switch to an
appropriate external manager if experiencing problems.
 
- <b>Perform Network Queries after automatic reference extractions</b> \n
Network queries can be used to complete a partial reference extraction. For
instance, provided a reference 'J. Name, 25, 103' and an appropriate pattern to
extract it, cb2Bib will attempt to complete the reference automatically.
Currently, it should work out-of-the-box for PubMed, PNAS, and ACS publications.
See also the file <tt>netqinf.txt</tt>.
 
- <b>Download PDF article if available</b> \n If checked, cb2Bib downloads
article PDF files to the directory specified in <b>Rename and Copy/Move dropped PDF
article files to Directory</b>. See also the file <tt>netqinf.txt</tt> for
details.
 
- <b>Keep Query temporary files (Debug Only)</b> \n cb2Bib may use up to three
temporary files to perform a network query. If this box is checked, the
temporary files are not deleted. This facilitates the customization of the
information file <tt>netqinf.txt</tt>.
 
 
\section c2bconf_output Configuring Ouput
 
- <b>Author and Editor Name Format</b> \n Sets Authors and Editor names in
abbreviated or full form, if the latter is available.
 
- <b>Journal Name Format</b> \n Sets output journal names in abbreviated or
full form. Note that this feature only works if journal names are found in the
<tt>Journal Abbreviation List File</tt>.
 
 - <b>CiteID Pattern</b> \n Specifies the pattern for formating cite's ID.
Pattern editing and predefined placeholders popup menu are available upon mouse
rightclicks. Placeholders will be substituted by the actual cite field
values. See \ref citeid_placeholders for descriptions.
 
- <b>Convert entry strings to LaTeX</b> \n If checked, cb2Bib converts special,
Unicode characters to LaTeX commands. Most BibTeX import filters do not process
LaTeX escaped characters. Keeping this box unchecked can thus be appropriate
when using cb2Bib-BibTeX as a temporary media to transfer references to non
BibTeX reference managers and formats.
 
- <b>Postprocess 'month' entry as BibTeX</b> \n If checked, cb2Bib elaborates
the 'month' string on a BibTeX fashion. E.g., 'April 1' becomes '"1~" # apr'.
 
- <b>Try Heuristic Guess if recognition fails</b> \n If checked, and the
automatic recognition fails, cb2Bib tries to catch some of the fields of the
reference through an heuristic set of rules. See \ref heuristic_guess.
 
- <b>External BibTeX Postprocessing</b> \n Use this box to select a preferred
BibTeX postprocessing external tool. The name of the executable, the command
arguments and the output file extension are required fields. Arguments, any
number, are passed to the executable. For the sake of generality, it is required
to specify the <tt>\%finput</tt> and <tt>\%foutput</tt> placeholders. The first one
is later substituted by the current BibTeX filename. The second one is
substituted by the current filename with the specified output extension.
<b>Caution:</b> Be careful if using the same file extension for input and
output, e.g., using <tt>bib</tt> because you want to use a beautifier or a sorting
script. The cb2Bib has no control on external disk modifications. Moreover, if
the script fails, the input data might be lost. See also \ref keyboard.
 
\section c2bconf_pdfimport Configuring PDFImport
 
- <b>PDF to plain text converter</b> \n Selects the external
<tt>some_format_to_text</tt> tool that cb2Bib uses to convert sets of files
prior to reference extraction. cb2Bib executes the line command <tt>converter
[options] inputfile tmp_output.txt</tt>, where <tt>[options]</tt> are user
defined arguments. As a default, cb2Bib launches <tt>pdftotext</tt>, a PDF to
text utility found in many platforms. Default arguments are <tt>-f 1 -l 1</tt>
to extract only the first page from the PDF document.
 
- <b>Process next file once previous reference is saved</b> \n The cb2Bib
permits to supervise and eventually correct references prior to saving. Keep in
mind that PDF to text translations are sometimes poor: accented letters,
missprint characters, or 'forgotten' words and sentences are possible issues to
take care of. By checking this box PDFImport will process the next file in list
once the current reference is accepted and saved, without needing to go back and
forth from the main cb2Bib window to PDFImport.
 
 
<p>&nbsp;</p>
 
*/


cb2BibConf::cb2BibConf(QWidget* parent, const char* name, bool modal, WFlags fl)
        : cb2bibconfbase(parent,name, modal,fl)
{
    connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( Help() ));
    QSettings settings;
    settings.insertSearchPath( QSettings::Windows, WINDOWS_REGISTRY );

    // Files
    JAbFile->setText( QDir::convertSeparators(settings.readEntry( APP_KEY + "jabfl", APP_JABF )) );
    connect( AbDir, SIGNAL( clicked() ), this, SLOT( getJAF() ) );
    RegExpsFile->setText( QDir::convertSeparators(settings.readEntry( APP_KEY + "regexpfl", APP_REGEXPF )) );
    connect( REFDir, SIGNAL( clicked() ), this, SLOT( getREF() ) );
    NetQueryFile->setText( QDir::convertSeparators(settings.readEntry( APP_KEY + "netqinffl", APP_NETQIF )) );
    connect( NQFDir, SIGNAL( clicked() ), this, SLOT( getNQF() ) );

    MovePDF->setChecked( settings.readBoolEntry( APP_KEY + "movepdf", APP_MOVE_PDF ) );
    PDF_Dir->setText( QDir::convertSeparators(settings.readEntry( APP_KEY + "pdfdir", APP_PDFDIR )) );
    connect( PDFDir, SIGNAL( clicked() ), this, SLOT( getPDFDir() ) );

    CopyMove = settings.readEntry( APP_KEY + "copymovepdf", APP_COPYMOVE_PDF );
    if( CopyMove == "copy" )
        Copy->setChecked( TRUE );
    else if( CopyMove == "move" )
        Move->setChecked( TRUE );
    if( MovePDF->isChecked() )
        CopyMovePDF->setEnabled( TRUE );
    else
        CopyMovePDF->setEnabled( FALSE );
    connect( MovePDF, SIGNAL( toggled( bool ) ), CopyMovePDF, SLOT( setEnabled( bool ) ) );


    // Fonts
    m_font.setFamily( settings.readEntry( APP_KEY + "Font0", WINDOW_FF ) );
    m_font.setPointSize( settings.readNumEntry( APP_KEY + "FontSize0", WINDOW_FS ) );
    families = db.families();
    familycombo->insertStringList(families);
    QValueList<int> sizes = db.standardSizes();
    QValueList<int>::Iterator it = sizes.begin();
    while (it != sizes.end())
        psizecombo->insertItem(QString::number(*it++));
    FontSelection();
    connect( familycombo, SIGNAL( activated(const QString&) ), this, SLOT( comboFamilyChanged(const QString&) ));
    connect( psizecombo, SIGNAL( activated(const QString&) ), this, SLOT( comboSizeChanged(const QString&) ));

    ColorListViewItem *cli;
    pm = QPixmap( 30, 10 );
    cli = new ColorListViewItem( ColorList, "  BibTeX delimiters",
                                 c.bib_delimiter_color, "bib_delimiter_color" );
    pm.fill( c.bib_delimiter_color );
    cli->setPixmap( 0, pm );
    cli = new ColorListViewItem( ColorList, "  BibTeX reference field",
                                 c.bib_reference_field_color, "bib_reference_field_color" );
    pm.fill( c.bib_reference_field_color );
    cli->setPixmap( 0, pm );
    cli = new ColorListViewItem( ColorList, "  BibTeX reference type",
                                 c.bib_reference_type_color, "bib_reference_type_color" );
    pm.fill( c.bib_reference_type_color );
    cli->setPixmap( 0, pm );
    cli = new ColorListViewItem( ColorList, "  cb2Bib digits",
                                 c.cb2bib_digit_color, "cb2bib_digit_color" );
    pm.fill( c.cb2bib_digit_color );
    cli->setPixmap( 0, pm );
    cli = new ColorListViewItem( ColorList, "  cb2Bib highly relevant text",
                                 c.cb2bib_highly_relevant_color, "cb2bib_highly_relevant_color" );
    pm.fill( c.cb2bib_highly_relevant_color );
    cli->setPixmap( 0, pm );
    cli = new ColorListViewItem( ColorList, "  cb2Bib relevant text",
                                 c.cb2bib_relevant_color, "cb2bib_relevant_color" );
    pm.fill( c.cb2bib_relevant_color );
    cli->setPixmap( 0, pm );
    cli = new ColorListViewItem( ColorList, "  cb2Bib unrelevant text",
                                 c.cb2bib_unrelevant_color, "cb2bib_unrelevant_color" );
    pm.fill( c.cb2bib_unrelevant_color );
    cli->setPixmap( 0, pm );
    cli = new ColorListViewItem( ColorList, "  Comments",
                                 c.comment_color, "comment_color" );
    pm.fill( c.comment_color );
    cli->setPixmap( 0, pm );
    cli = new ColorListViewItem( ColorList, "  NetQInf command contents",
                                 c.netqinf_command_content_color, "netqinf_command_content_color" );
    pm.fill( c.netqinf_command_content_color );
    cli->setPixmap( 0, pm );
    cli = new ColorListViewItem( ColorList, "  NetQInf command keys",
                                 c.netqinf_command_key_color, "netqinf_command_key_color" );
    pm.fill( c.netqinf_command_key_color );
    cli->setPixmap( 0, pm );
    cli = new ColorListViewItem( ColorList, "  RegExp and NetQInf cb2Bib tags",
                                 c.cb2bib_tag_color, "cb2bib_tag_color" );
    pm.fill( c.cb2bib_tag_color );
    cli->setPixmap( 0, pm );
    connect( ColorList, SIGNAL( doubleClicked(QListViewItem*) ),
             this, SLOT( changeContextColor(QListViewItem*) ) );


    // Input
    replaceinput->setChecked( settings.readBoolEntry( APP_KEY + "replaceinput",
                              APP_FIND_REPLACE_INPUT ) );
    connect( replaceinput, SIGNAL( toggled(bool) ), this, SLOT( updateFindReplaceButtons() ) );
    updateFindReplaceButtons();
    QStringList replaceinputList = settings.readListEntry( APP_KEY + "replaceinputList" );
    if ( replaceinputList.isEmpty() )
        replaceinputList = QStringList::split( "^e", APP_FIND_REPLACE_LIST );
    QStringList::Iterator i = replaceinputList.begin();
    QListViewItem *fri;
    while( i != replaceinputList.end() )
    {
        QStringList spLine = QStringList::split( "|", *i, TRUE );
        fri = new QListViewItem( FindReplaceList, spLine[0], spLine[1], spLine[2] );
        ++i;
    }
    connect( FindReplaceList, SIGNAL(  selectionChanged() ), this, SLOT( updateFindReplaceButtons() ) );
    connect( FRNew, SIGNAL( clicked() ), this, SLOT( FindReplaceDialog_New() ) );
    connect( FREdit, SIGNAL( clicked() ), this, SLOT( FindReplaceDialog_Edit() ) );
    connect( FRDelete, SIGNAL( clicked() ), this, SLOT( FindReplaceDialog_Delete() ) );

    AutomaticPreparser->setChecked( settings.readBoolEntry( APP_KEY + "preparser_automatic", APP_PREPARSER_AUTOMATIC ) );
    ClipboardPPShowLog->setChecked( !settings.readBoolEntry( APP_KEY + "preparser_show_log", APP_PREPARSER_SHOW_LOG ) );
    ClipboardPPBin->setText( QDir::convertSeparators( settings.readEntry( APP_KEY + "preparser_bin", APP_PREPARSER_BIN )) );
    connect( ClipboardPPDir, SIGNAL( clicked() ), this, SLOT( getClipboardPPBin() ) );


    // Network
    bool m_fmclient = settings.readBoolEntry( APP_KEY + "fmclient", APP_FMCLIENT );
    fmclient->setChecked( m_fmclient );
    clientGroupBox->setEnabled( m_fmclient );
    fmclient_copy_bin->setText( QDir::convertSeparators( settings.readEntry( APP_KEY + "fmclient_copy_bin",
                                APP_FMCLIENT_COPY_BIN )) );
    fmclient_copy_arg->setText( settings.readEntry( APP_KEY + "fmclient_copy_arg",
                                APP_FMCLIENT_COPY_ARG ));
    fmclient_move_bin->setText( QDir::convertSeparators( settings.readEntry( APP_KEY + "fmclient_move_bin",
                                APP_FMCLIENT_MOVE_BIN )) );
    fmclient_move_arg->setText( settings.readEntry( APP_KEY + "fmclient_move_arg",
                                APP_FMCLIENT_MOVE_ARG ));
    fmclient_open_bin->setText( QDir::convertSeparators( settings.readEntry( APP_KEY + "fmclient_open_bin",
                                APP_FMCLIENT_OPEN_BIN )) );
    fmclient_open_arg->setText( settings.readEntry( APP_KEY + "fmclient_open_arg",
                                APP_FMCLIENT_OPEN_ARG ));

    tabWidget->setCurrentPage(settings.readNumEntry( APP_KEY + "currentpage", 0 ));

    connect( FMClientCopyDir, SIGNAL( clicked() ), this, SLOT( getFMClientCopyBin() ) );
    connect( FMClientMoveDir, SIGNAL( clicked() ), this, SLOT( getFMClientMoveBin() ) );
    connect( FMClientOpenDir, SIGNAL( clicked() ), this, SLOT( getFMClientOpenBin() ) );

    AutoNetQuery->setChecked( settings.readBoolEntry( APP_KEY + "autonetquery", APP_AUTO_NETQUERY ) );
    AutoPDFDownload->setChecked( settings.readBoolEntry( APP_KEY + "autopdfd", APP_AUTO_PDFD ) );
    KeepTmpNQFiles->setChecked( settings.readBoolEntry( APP_KEY + "keeptmpf", APP_KEEP_TMPF ) );


    // Output
    m_pp_month = settings.readBoolEntry( APP_KEY + "pp_month", APP_PP_MONTH );
    PPMonthBox->setChecked( m_pp_month );
    m_convert_entries_to_latex = settings.readBoolEntry( APP_KEY +
                                 "convert_entries_to_latex", APP_CONVERT_ENTRIES_TO_LATEX );
    convertEntriesToLaTeXBox->setChecked( m_convert_entries_to_latex );
    m_author_editor_name_full = settings.readBoolEntry( APP_KEY +
                                "author_editor_name_full", APP_AUTHOR_EDITOR_NAME_FULL );
    AENF_Abbreviated->setChecked( !m_author_editor_name_full );
    AENF_Full->setChecked( m_author_editor_name_full );
    m_journal_name_full = settings.readBoolEntry( APP_KEY +
                          "journal_name_full", APP_JOURNAL_NAME_FULL );
    JNF_Abbreviated->setChecked( !m_journal_name_full );
    JNF_Full->setChecked( m_journal_name_full );

    BibTeXPPBin->setText( QDir::convertSeparators( settings.readEntry( APP_KEY + "ppbibtexbin", APP_PPBIBTEX_BIN )) );
    PBibTeXPPArg->setText( settings.readEntry( APP_KEY + "ppbibtexarg", APP_PPBIBTEX_ARG ));
    PBibTeXPPExt->setText( settings.readEntry( APP_KEY + "ppbibtexext", APP_PPBIBTEX_EXT ));
    connect( BibTeXPPDir, SIGNAL( clicked() ), this, SLOT( getBibTeXPPBin() ) );

    HeuristicGuessBox->setChecked( settings.readBoolEntry( APP_KEY + "heuristic_guess", APP_HEURISTIC_GUESS ) );
    CiteIDPattern->setText( settings.readEntry( APP_KEY + "citeidpattern", APP_CITE_ID_PATTERN ) );


    // PDFImport
    PDF2TBin->setText( QDir::convertSeparators( settings.readEntry( APP_KEY + "pdf2txtbin", APP_PDF2TXT_BIN )) );
    PDF2TBinArg->setText( settings.readEntry( APP_KEY + "pdf2txtarg", APP_PDF2TXT_ARG ));
    m_automatic_pdfimport = settings.readBoolEntry( APP_KEY + "automatic_pdfimport", APP_PDF2TXT_AUTOMATIC );
    AutomaticProcess->setChecked( m_automatic_pdfimport );
    connect( PDF2TDir, SIGNAL( clicked() ), this, SLOT( getPDF2TBin() ) );
}

cb2BibConf::~cb2BibConf()
{}


void cb2BibConf::reject()
{
    QDialog::reject();
}

void cb2BibConf::accept()
{
    c.writeSettings();

    QSettings settings;
    settings.insertSearchPath( QSettings::Windows, WINDOWS_REGISTRY );
    settings.writeEntry( APP_KEY + "currentpage", tabWidget->currentPageIndex() );

    // Files
    if( !CopyMove.isEmpty() )
    {
        if( Copy->isChecked() )
            CopyMove = "copy";
        else
            CopyMove = "move";
    }
    settings.writeEntry( APP_KEY + "jabfl", JAbFile->text() );
    settings.writeEntry( APP_KEY + "regexpfl", RegExpsFile->text() );
    settings.writeEntry( APP_KEY + "netqinffl", NetQueryFile->text() );
    settings.writeEntry( APP_KEY + "copymovepdf", CopyMove );
    settings.writeEntry( APP_KEY + "movepdf", MovePDF->isChecked() );
    settings.writeEntry( APP_KEY + "pdfdir", PDF_Dir->text() );

    // Fonts
    settings.writeEntry( APP_KEY + "Font0", m_font.family() );
    settings.writeEntry( APP_KEY + "FontSize0", m_font.pointSize() );

    // Input
    settings.writeEntry( APP_KEY + "replaceinput", replaceinput->isChecked() );
    QStringList replaceinputList;
    QListViewItemIterator it( FindReplaceList );
    while ( it.current() )
    {
        QListViewItem *item = it.current();
        QString Line = QString("%1|%2|%3").arg(item->text(0))
                       .arg(item->text(1))
                       .arg(item->text(2));
        replaceinputList += Line;
        ++it;
    }
    settings.writeEntry( APP_KEY + "replaceinputList", replaceinputList );
    settings.writeEntry( APP_KEY + "preparser_automatic", AutomaticPreparser->isChecked() );
    settings.writeEntry( APP_KEY + "preparser_show_log", !ClipboardPPShowLog->isChecked() );
    settings.writeEntry( APP_KEY + "preparser_bin", ClipboardPPBin->text() );

    // Network
    settings.writeEntry( APP_KEY + "fmclient", fmclient->isChecked() );
    settings.writeEntry( APP_KEY + "fmclient_copy_bin", fmclient_copy_bin->text() );
    settings.writeEntry( APP_KEY + "fmclient_move_bin", fmclient_move_bin->text() );
    settings.writeEntry( APP_KEY + "fmclient_open_bin", fmclient_open_bin->text() );
    settings.writeEntry( APP_KEY + "fmclient_copy_arg", fmclient_copy_arg->text().simplifyWhiteSpace() );
    settings.writeEntry( APP_KEY + "fmclient_move_arg", fmclient_move_arg->text().simplifyWhiteSpace() );
    settings.writeEntry( APP_KEY + "fmclient_open_arg", fmclient_open_arg->text().simplifyWhiteSpace() );
    settings.writeEntry( APP_KEY + "autonetquery", AutoNetQuery->isChecked() );
    settings.writeEntry( APP_KEY + "autopdfd", AutoPDFDownload->isChecked() );
    settings.writeEntry( APP_KEY + "keeptmpf", KeepTmpNQFiles->isChecked() );

    // Output
    settings.writeEntry( APP_KEY + "pp_month", PPMonthBox->isChecked() );
    settings.writeEntry( APP_KEY + "convert_entries_to_latex", convertEntriesToLaTeXBox->isChecked() );
    settings.writeEntry( APP_KEY + "author_editor_name_full", AENF_Full->isChecked() );
    settings.writeEntry( APP_KEY + "journal_name_full", JNF_Full->isChecked() );
    settings.writeEntry( APP_KEY + "ppbibtexbin", BibTeXPPBin->text() );
    settings.writeEntry( APP_KEY + "ppbibtexarg", PBibTeXPPArg->text() );
    settings.writeEntry( APP_KEY + "ppbibtexext", PBibTeXPPExt->text() );
    settings.writeEntry( APP_KEY + "heuristic_guess", HeuristicGuessBox->isChecked() );
    settings.writeEntry( APP_KEY + "citeidpattern", CiteIDPattern->text() );

    // PDFImport
    settings.writeEntry( APP_KEY + "pdf2txtarg", PDF2TBinArg->text().simplifyWhiteSpace() );
    settings.writeEntry( APP_KEY + "pdf2txtbin", PDF2TBin->text() );
    settings.writeEntry( APP_KEY + "automatic_pdfimport", AutomaticProcess->isChecked() );

    QDialog::accept();
}

void cb2BibConf::comboFamilyChanged( const QString& family )
{
    samplelineedit->setFont( QFont( family, psizecombo->currentText().toInt() ) );
    m_font.setFamily( family );
}

void cb2BibConf::comboSizeChanged( const QString& pt )
{
    samplelineedit->setFont( QFont( familycombo->currentText(), pt.toInt() ) );
    m_font.setPointSize( pt.toInt() );
}

void cb2BibConf::FindReplaceDialog_Delete()
{
    QListViewItemIterator it( FindReplaceList );
    while ( it.current() )
    {
        QListViewItem *item = it.current();
        if ( item->isSelected() )
        {
            delete item;
            return;
        }
        ++it;
    }
}

void cb2BibConf::FindReplaceDialog_Edit()
{
    QListViewItemIterator it( FindReplaceList );
    while ( it.current() )
    {
        QListViewItem *item = it.current();
        if ( item->isSelected() )
        {
            cb2BibConfFRI* frD = new cb2BibConfFRI( item, this );
            frD->exec();
            delete frD;
            return;
        }
        ++it;
    }
}

void cb2BibConf::FindReplaceDialog_New()
{
    QListViewItem *fri = new QListViewItem( FindReplaceList, "", "", "" );
    fri->setVisible( FALSE );
    cb2BibConfFRI* frD = new cb2BibConfFRI( fri, this );
    if ( frD->exec() != QDialog::Accepted )
        delete fri;
    else
        fri->setVisible( TRUE );
    delete frD;
}

void cb2BibConf::updateFindReplaceButtons()
{
    if ( !replaceinput->isChecked() )
    {
        FindReplaceList->setEnabled( FALSE );
        FRNew->setEnabled( FALSE );
        FREdit->setEnabled( FALSE );
        FRDelete->setEnabled( FALSE );
        return;
    }
    else
    {
        FindReplaceList->setEnabled( TRUE );
        FRNew->setEnabled( TRUE );
    }
    if ( FindReplaceList->currentItem() == 0 )
    {
        FREdit->setEnabled( FALSE );
        FRDelete->setEnabled( FALSE );
        return;
    }
    if ( FindReplaceList->currentItem()->isSelected() )
    {
        FREdit->setEnabled( TRUE );
        FRDelete->setEnabled( TRUE );
    }
    else
    {
        FREdit->setEnabled( FALSE );
        FRDelete->setEnabled( FALSE );
    }
}

void cb2BibConf::getJAF()
{
    QString fn = JAbFile->text();
    QString new_fn = QFileDialog::getOpenFileName(
                         fn, "cb2Bib Journal Lists (*.txt);;All (*)",
                         this, "open file dialog",
                         "Select an existing filename (restart to apply changes)" );
    if( ! new_fn.isEmpty() )
        JAbFile->setText(new_fn);
}

void cb2BibConf::getREF()
{
    QString fn = RegExpsFile->text();
    QString new_fn = QFileDialog::getSaveFileName(
                         fn, "cb2Bib RegExp Lists (*.txt);;All (*)",
                         this, "save file dialog",
                         "Select a new or existing filename" );
    if( ! new_fn.isEmpty() )
        RegExpsFile->setText(new_fn);
}

void cb2BibConf::getNQF()
{
    QString fn = NetQueryFile->text();
    QString new_fn = QFileDialog::getSaveFileName(
                         fn, "cb2Bib Network Query Info (*.txt);;All (*)",
                         this, "save file dialog",
                         "Select a new or existing filename" );
    if( ! new_fn.isEmpty() )
        NetQueryFile->setText(new_fn);
}

void cb2BibConf::getFMClientCopyBin()
{
    QString fn = fmclient_copy_bin->text();
    QString new_fn = QFileDialog::getOpenFileName(
                         fn, "File Manager Client executable (*)",
                         this, "open file dialog",
                         "Select filename" );
    if( ! new_fn.isEmpty() )
        fmclient_copy_bin->setText(new_fn);
}

void cb2BibConf::getClipboardPPBin()
{
    QString fn = ClipboardPPBin->text();
    QString new_fn = QFileDialog::getOpenFileName(
                         fn, "External Parser executable (*)",
                         this, "open file dialog",
                         "Select filename" );
    if( ! new_fn.isEmpty() )
        ClipboardPPBin->setText(new_fn);
}

void cb2BibConf::getFMClientMoveBin()
{
    QString fn = fmclient_move_bin->text();
    QString new_fn = QFileDialog::getOpenFileName(
                         fn, "File Manager Client executable (*)",
                         this, "open file dialog",
                         "Select filename" );
    if( ! new_fn.isEmpty() )
        fmclient_move_bin->setText(new_fn);
}

void cb2BibConf::getFMClientOpenBin()
{
    QString fn = fmclient_open_bin->text();
    QString new_fn = QFileDialog::getOpenFileName(
                         fn, "File Manager Client executable (*)",
                         this, "open file dialog",
                         "Select filename" );
    if( ! new_fn.isEmpty() )
        fmclient_open_bin->setText(new_fn);
}

void cb2BibConf::getBibTeXPPBin()
{
    QString fn = BibTeXPPBin->text();
    QString new_fn = QFileDialog::getOpenFileName(
                         fn, "BibTeX Postprocess executable (*)",
                         this, "open file dialog",
                         "Select filename" );
    if( ! new_fn.isEmpty() )
        BibTeXPPBin->setText(new_fn);
}

void cb2BibConf::getPDF2TBin()
{
    QString fn = PDF2TBin->text();
    QString new_fn = QFileDialog::getOpenFileName(
                         fn, "PDF to text converter executable (*)",
                         this, "open file dialog",
                         "Select filename" );
    if( ! new_fn.isEmpty() )
        PDF2TBin->setText(new_fn);
}

void cb2BibConf::getPDFDir()
{
    QString dir = PDF_Dir->text();
    if( dir.isEmpty() )
        dir = QDir::homeDirPath();
    QString new_dir = QFileDialog::getExistingDirectory(
                          dir, this,
                          "get existing directory",
                          "Choose PDF article files directory",
                          TRUE );
    if( ! new_dir.isEmpty() )
        PDF_Dir->setText(new_dir);
}

void cb2BibConf::FontSelection()
{
    //  Procedure from qtconfig
    QStringList::Iterator sit = families.begin();
    int i = 0, possible = -1;
    while (sit != families.end())
    {
        if (*sit == m_font.family())
            break;
        if ((*sit).contains(m_font.family()))
            possible = i;
        i++;
        sit++;
    }
    if (sit == families.end())
        i = possible;
    if (i == -1) // no clue about the current font
        i = 0;
    familycombo->setCurrentItem(i);
    i = 0;
    while (i < psizecombo->count())
    {
        if (psizecombo->text(i) == QString::number(m_font.pointSize()))
        {
            psizecombo->setCurrentItem(i);
            break;
        }
        i++;
    }
    samplelineedit->setFont( m_font );
}

void cb2BibConf::changeContextColor(QListViewItem* item)
{
    if( item )
    {
        ColorListViewItem* citem = (ColorListViewItem*) item;
        QColor newColor = QColorDialog::getColor( citem->textColor(), this );
        if( newColor.isValid() )
        {
            citem->setTextColor( newColor );
            pm.fill( newColor );
            citem->setPixmap( 0, pm );
            c.updateColor( newColor, citem->textColorName() );
        }
    }
}

void cb2BibConf::Help()
{
    emit helpRequested( "http://www.molspaces.com/d_cb2bib-c2bconf.php" );
}
