/***************************************************************************
 *   Copyright (C) 2004-2015 by Pere Constans
 *   constans@molspaces.com
 *   cb2Bib version 1.9.2. Licensed under the GNU GPL version 3.
 *   See the LICENSE file that comes with this distribution.
 ***************************************************************************/
#include "c2bConfigure.h"

#include "c2b.h"
#include "c2bConfigureFR.h"
#include "c2bFileDialog.h"
#include "c2bSettings.h"
#include "c2bUtils.h"

#include <QColorDialog>
#include <QHeaderView>
#include <QStatusTipEvent>


/** \page c2bconf Configuration

- \ref c2bconf_annote
- \ref c2bconf_bibtex
- \ref c2bconf_clipboard
- \ref c2bconf_documents
- \ref c2bconf_files
- \ref c2bconf_fonts
- \ref c2bconf_network
- \ref c2bconf_shortcuts
- \ref c2bconf_utilities
<p>&nbsp;</p>

\section c2bconf_annote Configuring Annote

    - <b>Annote Cascading Style Sheet (CSS)</b> \n This file contains the style
    sheet to personalize the appearance of the HTML notes generated by the
    cb2Bib. The cb2Bib distribution includes the <tt>tex2html.css</tt> file as
    a CSS template.

    - <b>jsMath Directory</b> \n The mathematical notation in the text notes is
    displayed by
    \htmlonly
    <a href="http://www.math.union.edu/~dpvc/jsMath/" target="_blank">jsMath</a>.
    \endhtmlonly
    The jsMath is a Java Script library. Its location must be specified inside
    the HTML files in order to be known by the browser.

    - <b>Include CSS in HTML</b> \n Styles for the notes will be included, if
    checked, into the HTML file. In this way, all the information, text and
    layout, is contained in one single file.

    - <b>Use relative links</b> \n If checked, linked local files will be set
    relative to the current HTML document.

    - <b>Annote Viewer Fonts</b> \n Selects default and monospaced fonts for
    the Annote viewer. Changes in the fonts might need restarting the viewer
    unless using some of the latest QtWebKit libraries. The viewer is disabled
    if the cb2Bib was not compiled and linked against WebKit. Note also that
    fonts specified in the CSS prevail over this selection.


\section c2bconf_bibtex Configuring BibTeX

    - <b>CiteID Pattern</b> \n Specifies the pattern for formatting cite's ID.
    Predefined placeholders are available as a context menu, by right-clicking
    this edit line. Placeholders will be substituted by the actual reference
    field values. See \ref idplaceholders for descriptions.

    - <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>Number Separator</b> \n Sets number separator, e.g., ' - ' or ' -- '.
    Spaces count. It applies to <tt>pages</tt>, multiple <tt>volume</tt>,
    <tt>number</tt>, and <tt>year</tt> cases.

    - <b>Convert entry strings to LaTeX</b> \n If checked, cb2Bib converts
    special characters to LaTeX commands. Most BibTeX import filters do not
    process LaTeX escaped characters. Therefore, keeping this box unchecked can
    be appropriate when using cb2Bib as a temporary media to transfer
    references to non BibTeX reference managers.

    - <b>Set 'title' in double braces</b> \n If checked, it writes extra braces
    in title. This will keep capitalization as is, when processed by BibTeX.

    - <b>Postprocess 'month'</b> \n If checked, cb2Bib elaborates the 'month'
    string on a BibTeX fashion. E.g., 'April 1' becomes '"1~" # apr'. No
    processing is done if the input string is not written in English.

    - <b>Try Heuristic Guess if recognition fails</b> \n If checked, when
    automatic recognition fails, cb2Bib tries to catch some of the fields of
    the reference through an heuristic set of rules. See \ref heuristicguess.

    - <b>Check Repeated On Save</b> \n If checked, cb2Bib looks for existing
    references in the BibTeX directory similar to the one being saved. The
    search is based on exact cite ID match, or on reference contents, by
    considering title and author field values, or, if empty, booktitle and
    editor, and using the
    \htmlonly
    <a href="http://arxiv.org/abs/0705.0751v1" target="_blank">approximate string</a>
    \endhtmlonly
    search pattern. If similar references are found, the current reference is
    not saved, and the similar ones are displayed. Pressing the <b>save button
    one second time will proceed to actually saving the current reference</b>.
    Note that this feature is not applied in command line mode, when using
    <tt>cb2bib --txt2bib</tt> or <tt>cb2bib --doc2bib</tt>. See also \ref
    keyboard.

    - <b>External BibTeX Postprocessing</b> \n Use this box to select a 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. Therefore, if the script failed, the input
    data would possibly be lost. See also \ref keyboard.


\section c2bconf_clipboard Configuring Clipboard

    - <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 with email icons
    may 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://bibutils.refbase.org/"
    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</b> \n If unchecked, the external process messages,
    and the input and output streams are shown in a log window. Showing output
    logs is useful for debugging purposes.

    - <b>Add document metadata to Input Stream</b> \n When checked, if the
    document linked to a reference contains relevant metadata, then metadata
    will be added to the current clipboard contents. The metadata is included
    at the time of adding the document to the current reference, e. g., when
    dropping a file into the cb2Bib panel. If the document has BibTeX
    information, the cb2Bib will automatically set the corresponding fields. If
    it has not, but relevant bibliographic information is found, this data is
    only added to the clipboard panel. To insert it in the edit lines, activate
    the Heuristic Guess (Alt+G). The option <b>Prepend</b> or <b>Append</b> to
    the clipboard contents is provided for conveniently writing regular
    expressions considering metadata contents. File documents are linked to the
    references by the BibTeX tag 'file'. See also \ref metadata.


\section c2bconf_documents Configuring Documents

    - <b>Rename and Copy/Move document files to Directory</b> \n If selected,
    each file 'drag and dropped' onto the cb2Bib main window is renamed to
    <tt>DocumentID.pdf</tt> (or DocumentID.ps, DocumentID.dvi, etc.) and moved
    to the storage directory. If unselected, the file URL is written to the
    <tt>file</tt> BibTeX keyword, without any renaming or moving of the file.
    The actual copy/move action is scheduled and performed once the reference
    is accepted, e.g., once it is saved.

    - <b>Copy or Move document files</b> \n Choose whether copy or move Network
    Files dropped onto the cb2Bib main window. See also <b>Use External
    Network Client</b>.

    - <b>Set directory relative to the BibTeX File Directory</b> \n If checked,
    the document file is copied/moved to the current BibTeX file directory. If
    the Documents Directory box contains a <b>relative directory</b> it will be
    added to the file name. For example, if it contains <tt>articles</tt>,
    files will be copied to <tt>/current_bibtex_path/articles/</tt>. An
    absolute path in the Documents Directory box will be ignored in this
    context. Note that the file dialog returns here relative file addresses.
    Consequently, only the necessary portion of the full name, instead of the
    fullpath filename, is written to the BibTeX entry. File retrieving from
    within the cb2Bib browser will be relative to the BibTeX file absolute
    location.
    \n Use this option if you plan to store in a same or a related directory
    the BibTeX and document files. This option is appropriate for storing
    bibliographic collections in removal devices. Likewise, when the cb2Bib is
    launched in USB mode, by means of the command line switch '--conf', the
    alternate option is not available. See \ref relnotes084 and \ref
    export_entries.

    - <b>Insert BibTeX metadata to document files</b> \n If checked, the cb2Bib
    will write bibliographic metadata to the linked document, once the current
    reference is accepted and saved. See also \ref metadata.

    - <b>DocumentID Pattern</b> \n Specifies the pattern for formatting the
    document's filenames. Predefined placeholders are available as a context
    menu, by right-clicking this edit line. Placeholders will be substituted by
    the actual reference field values. See \ref idplaceholders for
    descriptions.

    - <b>ExifTool Metadata writer</b> \n The cb2Bib uses
    \htmlonly
    <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/" target="_blank">ExifTool</a>
    \endhtmlonly
    for writing bibliographic metadata to the attached documents. Select here
    the ExifTool path name. On Windows, remember renaming
    <tt>exiftool(-k).exe</tt> to <tt>exiftool.exe</tt> for command line use.
    See also \ref metadata_write.


\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> that contains bookmarks data, and
    server related information for bibliographic querying. Note that the cb2Bib
    treats bibliographic queries as generalized net bookmarks. This allows
    accessing almost any online bibliographic resource. Check this file for
    implementations details and customization.

    - <b>Browser Cascading Style Sheet (CSS)</b> \n This file contains the
    style sheet to configure the appearance of the bibliographic references
    when viewed in browser mode. The cb2Bib distribution includes the
    <tt>references.css</tt> and <tt>references-dark.css</tt> file as a CSS
    examples.

    - <b>Part Of Speech (POS) Lexicon</b> \n This box must contain the address
    to the cb2Bib distribution file <tt>lexicon.pos</tt>. This file contains a
    set of patterns and related POS information required to Index Documents, i.
    e., to extract keywords from documents for the c2bCiter module.

    - <b>Search In Files Cache Directory</b> \n Directory containing internal
    data for Search In Files functionality. If an existing directory is
    selected the cb2Bib will write all internal data on it. If otherwise, cache
    data will be written on the same directory from where BibTeX are searched.
    It might be, therefore, convenient to group all this files in a separate
    directory that does not need to be backup, and that can easily be deleted
    whenever desired.


\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_network Configuring Network

    - <b>Use External Network Client</b> \n The cb2Bib manages local and
    network files in an equivalent manner. Network file retrieving, however,
    requires sometimes password and/or cookies administration. The KDE desktop
    incorporates <tt>kfmclient</tt> utility. A command <tt>kfmclient
    (copy|move|exec) source [destination]</tt> permits copying or moving files,
    with <tt>kfmclient</tt> taking care of advanced browsing preferences. By
    checking this box, cb2Bib will use the specified file manger client.

    - <b>Use Proxy</b> \n If checked, the cb2Bib will access the network
    through a proxy host. Set the Host name, the Port, and the proxy Type. A
    login dialog will appear if the proxy requires authentication. Login data
    is not stored, it must be entered at each session.

    - <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. No query is performed if automatic reference extraction was
    tagged as BibTeX.

    - <b>Download document if available</b> \n If checked, cb2Bib downloads
    document files to the directory specified in <b>Rename and Copy/Move
    document files to Directory</b>. See also the file <tt>netqinf.txt</tt> for
    details. Download is scheduled and performed once the reference is
    accepted, e.g., once it is saved. Note that when document file is local,
    e.g., when PDFImport or switch <tt>--doc2bib</tt> is used, no document is
    downloaded.

    - <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 testing and
    customization of the information file <tt>netqinf.txt</tt>.


\section c2bconf_shortcuts Configuring Shortcuts

    - Customizes most key sequences for actions shortcuts. Concretely, cb2Bib
    specific actions are configurable, but not standard actions such as 'Open',
    'Exit', 'Copy', or 'Paste', which are already predefined to the standard,
    specific key sequences for each platform. Shortcuts are customizable for
    the cb2Bib main panel, editor, and reference list actions. Single-key
    shortcuts, i.e., for manual reference extraction and shortcuts in c2bCiter,
    are non-configurable, since they they closely map non-translatable BibTeX
    keywords.


\section c2bconf_utilities Configuring Utilities

    - <b>To plain text converter</b> \n Selects the external
    <tt>some_format_to_text</tt> tool that cb2Bib uses to convert document
    files prior to reference extraction and searching. 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>pdf2cb</tt>, a modified PDF to text utility found in the XPDF
    package. Modifications are available at xpdf/ directory in the cb2Bib
    sources. Default arguments are <tt>-q -f 1 -l 1</tt> to extract only the
    first, title page when used within PDFImport, and <tt>-q</tt>, to convert
    the complete document when used within Search in Files. Appropriate for
    PDFImport could also be a document metadata extractor. Often metadata
    contains structured information regarding document authors, title, and
    source. A simple shell script wrapper could be the following
    <tt>any2text_search</tt>:

    \verbatim
   #!/bin/csh
   # Convert documents to text according to filename extension
   # any2text_search input_fn.ext output_fn.txt
   set ext = $1:e
   if ( $ext == 'djvu' ) then
      /usr/bin/djvutxt "$1" "$2"
      if ($status) exit 1
   else if ( $ext == 'chm' ) then
      (/usr/local/bin/archmage -c text "$1" "$2") >& /dev/null
      if ($status) exit 1
   else
   # If using pdf2cb
      /path/to/pdf2cb -q "$1" "$2"
   # If using pdftotex
   #  /usr/bin/pdftotext -enc UTF-8 "$1" "$2"
      if ($status) exit 1
   endif
   \endverbatim

    <p>&nbsp;</p>
*/

c2bConfigure::c2bConfigure(QWidget* parentw) : QDialog(parentw)
{
    ui.setupUi(this);
    resize(QSize(1, 1)); // Set it at minimum size
    settings = c2bSettingsP;

    for (int i = 0; i < ui.contentsWidget->count(); ++i)
        ui.contentsWidget->item(i)->setStatusTip(tr("Configure %1").arg(ui.contentsWidget->item(i)->text()));
    connect(ui.contentsWidget, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
            this, SLOT(changePage(QListWidgetItem*, QListWidgetItem*)));
    ui.contentsWidget->setCurrentItem(ui.contentsWidget->item(settings->value("c2bConfigure/CurrentPage", 0).toInt()));
    ui.buttonBox->button(QDialogButtonBox::Apply)->setAutoDefault(false);
    ui.buttonBox->button(QDialogButtonBox::Cancel)->setAutoDefault(false);
    ui.buttonBox->button(QDialogButtonBox::Help)->setAutoDefault(false);
    connect(ui.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply()));
    connect(ui.buttonBox, SIGNAL(helpRequested()), this, SLOT(help()));
    populateFontCombos();

    // Annote
    ui.AnnoteCssFile->setText(settings->fileName("c2bAnnote/AnnoteCssFile"));
    connect(ui.AnnoteCssDir, SIGNAL(clicked()), this, SLOT(getAnnoteCssFile()));
    ui.jsMathDirectory->setText(settings->fileName("c2bAnnote/jsMathDirectory"));
    connect(ui.jsMathDir, SIGNAL(clicked()), this, SLOT(getjsMathDirectory()));
    ui.IncludeCSS->setChecked(settings->value("c2bAnnote/IncludeCSS").toBool());
    ui.UseRelativeLinks->setChecked(settings->value("c2bAnnote/UseRelativeLinks").toBool());
    fontSelection(settings->value("c2bAnnote/Font").value<QFont>(), ui.af_familycombo, ui.af_psizecombo);
    fontSelection(settings->value("c2bAnnote/FixedFont").value<QFont>(), ui.aff_familycombo, ui.aff_psizecombo);
#ifndef C2B_USE_WEBKIT
    ui.AnnoteViewerFont->setDisabled(true);
    ui.AnnoteViewerFixedFont->setDisabled(true);
#endif

    // BibTeX
    ui.CiteIdPattern->setText(settings->value("cb2Bib/CiteIdPattern").toString());
    ui.UseAbbreviatedNames->setChecked(!settings->value("cb2Bib/UseFullNames").toBool());
    ui.UseFullNames->setChecked(settings->value("cb2Bib/UseFullNames").toBool());
    ui.SetJournalsToAbbreviated->setChecked(!settings->value("cb2Bib/SetJournalsToFullname").toBool());
    ui.SetJournalsToFullname->setChecked(settings->value("cb2Bib/SetJournalsToFullname").toBool());
    ui.PageNumberSeparator->setText(settings->value("cb2Bib/PageNumberSeparator").toString());
    ui.ConvertReferenceToLaTeX->setChecked(settings->value("cb2Bib/ConvertReferenceToLaTeX").toBool());
    ui.UseDoubleBraces->setChecked(settings->value("cb2Bib/UseDoubleBraces").toBool());
    ui.PostprocessMonth->setChecked(settings->value("cb2Bib/PostprocessMonth").toBool());
    ui.DoHeuristicGuess->setChecked(settings->value("cb2Bib/DoHeuristicGuess").toBool());
    ui.CheckRepeatedOnSave->setChecked(settings->value("cb2Bib/CheckRepeatedOnSave").toBool());
    ui.PostprocessBibTeXBin->setText(settings->fileName("cb2Bib/PostprocessBibTeXBin"));
    ui.PostprocessBibTeXArg->setText(settings->value("cb2Bib/PostprocessBibTeXArg").toString());
    ui.PostprocessBibTeXExt->setText(settings->value("cb2Bib/PostprocessBibTeXExt").toString());
    connect(ui.PostprocessBibTeXDir, SIGNAL(clicked()), this, SLOT(getPostprocessBibTeXBin()));

    // Clipboard
    ui.FindReplaceInput->setChecked(settings->value("cb2Bib/FindReplaceInput").toBool());
    connect(ui.FindReplaceInput, SIGNAL(toggled(bool)), this, SLOT(updateFindReplaceInputButtons()));
    updateFindReplaceInputButtons();
    QStringList FindReplaceInputList(settings->value("cb2Bib/FindReplaceInputList").toStringList());
    QStringList::Iterator i = FindReplaceInputList.begin();
    while (i != FindReplaceInputList.end())
    {
        const QStringList spLine((*i).split('|'));
        new QTreeWidgetItem(ui.FindReplaceList, spLine);
        ++i;
    }
    connect(ui.FindReplaceList, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(FindReplaceDialog_Edit()));
    connect(ui.FindReplaceList, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(updateFindReplaceInputButtons()));
    connect(ui.FRNew, SIGNAL(clicked()), this, SLOT(FindReplaceDialog_New()));
    connect(ui.FREdit, SIGNAL(clicked()), this, SLOT(FindReplaceDialog_Edit()));
    connect(ui.FRDelete, SIGNAL(clicked()), this, SLOT(FindReplaceDialog_Delete()));
    ui.AddMetadata->setChecked(settings->value("cb2Bib/AddMetadata").toBool());
    const QString PreAppendMetadata(settings->value("cb2Bib/PreAppendMetadata").toString());
    if (PreAppendMetadata == "prepend")
        ui.Prepend->setChecked(true);
    else if (PreAppendMetadata == "append")
        ui.Append->setChecked(true);
    if (ui.AddMetadata->isChecked())
        ui.PreAppendMetadata->setEnabled(true);
    else
        ui.PreAppendMetadata->setEnabled(false);
    connect(ui.AddMetadata, SIGNAL(toggled(bool)), ui.PreAppendMetadata, SLOT(setEnabled(bool)));
    ui.PreparserAutomatic->setChecked(settings->value("cb2Bib/PreparserAutomatic").toBool());
    ui.PreparserShowLog->setChecked(!settings->value("cb2Bib/PreparserShowLog").toBool());
    ui.PreparserBin->setText(settings->fileName("cb2Bib/PreparserBin"));
    connect(ui.PreparserDir, SIGNAL(clicked()), this, SLOT(getPreparserBin()));

    // Documents
    ui.MovePdf->setChecked(settings->value("cb2Bib/MovePdf").toBool());
    ui.PdfDirectory->setText(settings->fileName("cb2Bib/PdfDirectory"));
    connect(ui.PdfDir, SIGNAL(clicked()), this, SLOT(getPdfDirectory()));
    const QString CopyMovePdf(settings->value("cb2Bib/CopyMovePdf").toString());
    if (CopyMovePdf == "copy")
        ui.Copy->setChecked(true);
    else if (CopyMovePdf == "move")
        ui.Move->setChecked(true);
    if (ui.MovePdf->isChecked())
    {
        ui.RenameCopyMovePdf->setEnabled(true);
        ui.DocumentIdPatternBox->setEnabled(true);
    }
    else
    {
        ui.RenameCopyMovePdf->setEnabled(false);
        ui.DocumentIdPatternBox->setEnabled(false);
    }
    connect(ui.MovePdf, SIGNAL(toggled(bool)), ui.RenameCopyMovePdf, SLOT(setEnabled(bool)));
    ui.RelativePdfDirectory->setChecked(settings->value("cb2Bib/RelativePdfDirectory").toBool());
    ui.RelativePdfDirectory->setDisabled(settings->isUsbConfiguredMode());
    ui.InsertMetadata->setChecked(settings->value("cb2Bib/InsertMetadata").toBool());
    ui.DocumentIdPattern->setDocumentIDEdit();
    ui.DocumentIdPattern->setText(settings->value("cb2Bib/DocumentIdPattern").toString());
    connect(ui.MovePdf, SIGNAL(toggled(bool)), ui.DocumentIdPatternBox, SLOT(setEnabled(bool)));
    ui.ExifToolBin->setText(settings->fileName("cb2Bib/ExifToolBin"));
    connect(ui.ExifToolDir, SIGNAL(clicked()), this, SLOT(getExifToolBin()));

    // Files
    ui.JournalFile->setText(settings->fileName("cb2Bib/JournalFile"));
    connect(ui.JournalDir, SIGNAL(clicked()), this, SLOT(getJournalFile()));
    ui.RegularExpressionFile->setText(settings->fileName("cb2Bib/RegularExpressionFile"));
    connect(ui.RegularExpressionDir, SIGNAL(clicked()), this, SLOT(getRegularExpressionFile()));
    ui.NetworkFile->setText(settings->fileName("cb2Bib/NetworkFile"));
    connect(ui.NetworkDir, SIGNAL(clicked()), this, SLOT(getNetworkFile()));
    ui.BrowserCssFile->setText(settings->fileName("cb2Bib/BrowserCssFile"));
    connect(ui.BrowserCssDir, SIGNAL(clicked()), this, SLOT(getBrowserCssFile()));
    ui.PosLexiconFile->setText(settings->fileName("cb2Bib/PosLexiconFile"));
    connect(ui.PosLexiconDir, SIGNAL(clicked()), this, SLOT(getPosLexiconFile()));
    ui.CacheDirectory->setText(settings->fileName("cb2Bib/CacheDirectory"));
    connect(ui.CacheDir, SIGNAL(clicked()), this, SLOT(getCacheDirectory()));

    // Fonts
    c2bMonoFont = settings->c2bMonoFont;
    ui.samplelineedit->setFont(c2bMonoFont);
    fontSelection(c2bMonoFont, ui.familycombo, ui.psizecombo);
    connect(ui.familycombo, SIGNAL(activated(const QString&)), this, SLOT(comboFamilyChanged(const QString&)));
    connect(ui.psizecombo, SIGNAL(activated(const QString&)), this, SLOT(comboSizeChanged(const QString&)));
    colors.loadColors(settings);
    QHashIterator<QString, QColor*> cit(colors.colorList);
    while (cit.hasNext())
    {
        cit.next();
        QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(cit.key()));
        item->setData(0, Qt::DecorationRole, *cit.value());
        item->setData(0, Qt::TextColorRole, *cit.value());
        ui.ColorList->insertTopLevelItem(0, item);
    }
    ui.ColorList->header()->setSortIndicatorShown(false);
    ui.ColorList->viewport()->setCursor(QCursor(static_cast<Qt::CursorShape>(Qt::PointingHandCursor)));
    ui.ColorList->sortItems(0, Qt::AscendingOrder);
    connect(ui.ColorList, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(changeContextColor(QTreeWidgetItem*)));
    connect(ui.ColorList, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(changeContextColor(QTreeWidgetItem*)));

    // Network
    ui.FmClient->setChecked(settings->value("cb2Bib/FmClient").toBool());
    ui.clientGroupBox->setEnabled(settings->value("cb2Bib/FmClient").toBool());
    ui.FmClientCopyBin->setText(settings->fileName("cb2Bib/FmClientCopyBin"));
    ui.FmClientCopyArg->setText(settings->value("cb2Bib/FmClientCopyArg").toString());
    ui.FmClientMoveBin->setText(settings->fileName("cb2Bib/FmClientMoveBin"));
    ui.FmClientMoveArg->setText(settings->value("cb2Bib/FmClientMoveArg").toString());
    connect(ui.FmClientCopyDir, SIGNAL(clicked()), this, SLOT(getFmClientCopyBin()));
    connect(ui.FmClientMoveDir, SIGNAL(clicked()), this, SLOT(getFmClientMoveBin()));
    ui.UseProxy->setChecked(settings->value("cb2Bib/UseProxy").toBool());
    ui.proxyGroupBox->setEnabled(settings->value("cb2Bib/UseProxy").toBool());
    ui.ProxyHostName->setText(settings->value("cb2Bib/ProxyHostName", QString()).toString());
    QValidator* proxyPortValidator = new QIntValidator(0, 999999, this);
    ui.ProxyPort->setValidator(proxyPortValidator);
    ui.ProxyPort->setText(settings->value("cb2Bib/ProxyPort").toString());
    ui.ProxyType->setCurrentIndex(settings->value("cb2Bib/ProxyType").toInt());
    ui.AutomaticQuery->setChecked(settings->value("cb2Bib/AutomaticQuery").toBool());
    ui.AutomaticPdfDownload->setChecked(settings->value("cb2Bib/AutomaticPdfDownload").toBool());
    ui.KeepTmpNQFiles->setChecked(settings->value("cb2Bib/KeepTmpNQFiles").toBool());

    // Shortcuts
    ui.cb2BibShortcuts->setShortcutNames("Shortcuts/cb2Bib/", settings->shortcutNames());
    connect(ui.cb2BibShortcuts, SIGNAL(statusMessage(const QString&)), this, SLOT(showMessage(const QString&)));
    ui.EditorShortcuts->setShortcutNames("Shortcuts/Editor/", settings->shortcutNames());
    connect(ui.EditorShortcuts, SIGNAL(statusMessage(const QString&)), this, SLOT(showMessage(const QString&)));

    // Utilities
    ui.PdfImportPdf2TextBin->setText(settings->fileName("c2bPdfImport/Pdf2TextBin"));
    ui.PdfImportPdf2TextArg->setText(settings->value("c2bPdfImport/Pdf2TextArg").toString());
    connect(ui.PdfImportPdf2TextDir, SIGNAL(clicked()), this, SLOT(getPdfImportPdf2TextBin()));
    ui.BibSearcherPdf2TextBin->setText(settings->fileName("c2bBibSearcher/Pdf2TextBin"));
    ui.BibSearcherPdf2TextArg->setText(settings->value("c2bBibSearcher/Pdf2TextArg").toString());
    connect(ui.BibSearcherPdf2TextDir, SIGNAL(clicked()), this, SLOT(getBibSearcherPdf2TextBin()));
}

c2bConfigure::~c2bConfigure()
{}


void c2bConfigure::setPage(int index)
{
    ui.contentsWidget->setCurrentItem(ui.contentsWidget->item(index));
}

void c2bConfigure::accept()
{
    apply();
    QDialog::accept();
}

void c2bConfigure::apply()
{
    settings->setValue("c2bConfigure/CurrentPage", ui.contentsWidget->row(ui.contentsWidget->currentItem()));

    // Annote
    settings->setFilename("c2bAnnote/AnnoteCssFile", ui.AnnoteCssFile->text());
    settings->setFilename("c2bAnnote/jsMathDirectory", ui.jsMathDirectory->text());
    settings->setValue("c2bAnnote/IncludeCSS", ui.IncludeCSS->isChecked());
    settings->setValue("c2bAnnote/UseRelativeLinks", ui.UseRelativeLinks->isChecked());
    settings->setValue("c2bAnnote/Font", selectedFont(ui.af_familycombo, ui.af_psizecombo));
    settings->setValue("c2bAnnote/FixedFont", selectedFont(ui.aff_familycombo, ui.aff_psizecombo));

    // BibTeX
    settings->setValue("cb2Bib/CiteIdPattern", ui.CiteIdPattern->text());
    settings->setValue("cb2Bib/UseFullNames", ui.UseFullNames->isChecked());
    settings->setValue("cb2Bib/SetJournalsToFullname", ui.SetJournalsToFullname->isChecked());
    settings->setValue("cb2Bib/PageNumberSeparator", ui.PageNumberSeparator->text());
    settings->setValue("cb2Bib/ConvertReferenceToLaTeX", ui.ConvertReferenceToLaTeX->isChecked());
    settings->setValue("cb2Bib/UseDoubleBraces", ui.UseDoubleBraces->isChecked());
    settings->setValue("cb2Bib/PostprocessMonth", ui.PostprocessMonth->isChecked());
    settings->setValue("cb2Bib/DoHeuristicGuess", ui.DoHeuristicGuess->isChecked());
    settings->setValue("cb2Bib/CheckRepeatedOnSave", ui.CheckRepeatedOnSave->isChecked());
    settings->setFilename("cb2Bib/PostprocessBibTeXBin", ui.PostprocessBibTeXBin->text());
    settings->setValue("cb2Bib/PostprocessBibTeXArg", ui.PostprocessBibTeXArg->text());
    settings->setValue("cb2Bib/PostprocessBibTeXExt", ui.PostprocessBibTeXExt->text());

    // Clipboard
    QStringList FindReplaceInputList;
    QTreeWidgetItemIterator it(ui.FindReplaceList);
    while (*it)
    {
        QTreeWidgetItem* item = *it;
        FindReplaceInputList.append(QString("%1|%2|%3").arg(item->text(0)).arg(item->text(1)).arg(item->text(2)));
        ++it;
    }
    if (FindReplaceInputList.isEmpty())
    {
        FindReplaceInputList = C2B_FIND_REPLACE_LIST.split("^e");
        settings->setValue("cb2Bib/FindReplaceInput", false);
    }
    else
        settings->setValue("cb2Bib/FindReplaceInput", ui.FindReplaceInput->isChecked());
    settings->setValue("cb2Bib/FindReplaceInputList", FindReplaceInputList);
    QString PreAppendMetadata;
    if (ui.Prepend->isChecked())
        PreAppendMetadata = "prepend";
    else
        PreAppendMetadata = "append";
    settings->setValue("cb2Bib/PreAppendMetadata", PreAppendMetadata);
    settings->setValue("cb2Bib/AddMetadata", ui.AddMetadata->isChecked());
    settings->setValue("cb2Bib/PreparserAutomatic", ui.PreparserAutomatic->isChecked());
    settings->setValue("cb2Bib/PreparserShowLog", !ui.PreparserShowLog->isChecked());
    settings->setFilename("cb2Bib/PreparserBin", ui.PreparserBin->text());

    // Documents
    QString CopyMovePdf;
    if (ui.Copy->isChecked())
        CopyMovePdf = "copy";
    else
        CopyMovePdf = "move";
    settings->setValue("cb2Bib/CopyMovePdf", CopyMovePdf);
    settings->setValue("cb2Bib/MovePdf", ui.MovePdf->isChecked());
    settings->setFilename("cb2Bib/PdfDirectory", ui.PdfDirectory->text());
    settings->setValue("cb2Bib/RelativePdfDirectory", ui.RelativePdfDirectory->isChecked());
    settings->setValue("cb2Bib/InsertMetadata", ui.InsertMetadata->isChecked());
    settings->setValue("cb2Bib/DocumentIdPattern", ui.DocumentIdPattern->text());
    settings->setFilename("cb2Bib/ExifToolBin", ui.ExifToolBin->text());

    // Files
    settings->setFilename("cb2Bib/JournalFile", ui.JournalFile->text());
    settings->setFilename("cb2Bib/RegularExpressionFile", ui.RegularExpressionFile->text());
    settings->setFilename("cb2Bib/NetworkFile", ui.NetworkFile->text());
    settings->setFilename("cb2Bib/BrowserCssFile", ui.BrowserCssFile->text());
    settings->setFilename("cb2Bib/PosLexiconFile", ui.PosLexiconFile->text());
    settings->setFilename("cb2Bib/CacheDirectory", ui.CacheDirectory->text());

    // Fonts
    settings->setValue("cb2Bib/MonoFont", c2bMonoFont);
    colors.saveColors(settings);

    // Network
    settings->setValue("cb2Bib/FmClient", ui.FmClient->isChecked());
    settings->setFilename("cb2Bib/FmClientCopyBin", ui.FmClientCopyBin->text());
    settings->setFilename("cb2Bib/FmClientMoveBin", ui.FmClientMoveBin->text());
    settings->setValue("cb2Bib/FmClientCopyArg", ui.FmClientCopyArg->text().simplified());
    settings->setValue("cb2Bib/FmClientMoveArg", ui.FmClientMoveArg->text().simplified());
    settings->setValue("cb2Bib/UseProxy", ui.UseProxy->isChecked());
    settings->setValue("cb2Bib/ProxyHostName", ui.ProxyHostName->text().trimmed());
    settings->setValue("cb2Bib/ProxyPort", ui.ProxyPort->text().trimmed());
    settings->setValue("cb2Bib/ProxyType", ui.ProxyType->currentIndex());
    settings->setValue("cb2Bib/AutomaticQuery", ui.AutomaticQuery->isChecked());
    settings->setValue("cb2Bib/AutomaticPdfDownload", ui.AutomaticPdfDownload->isChecked());
    settings->setValue("cb2Bib/KeepTmpNQFiles", ui.KeepTmpNQFiles->isChecked());

    // Shortcuts
    settings->setKeysequences(ui.cb2BibShortcuts->modifiedKeysequences());
    settings->setKeysequences(ui.EditorShortcuts->modifiedKeysequences());

    // Utilities
    settings->setValue("c2bPdfImport/Pdf2TextArg", ui.PdfImportPdf2TextArg->text().simplified());
    settings->setFilename("c2bPdfImport/Pdf2TextBin", ui.PdfImportPdf2TextBin->text());
    settings->setValue("c2bBibSearcher/Pdf2TextArg", ui.BibSearcherPdf2TextArg->text().simplified());
    settings->setFilename("c2bBibSearcher/Pdf2TextBin", ui.BibSearcherPdf2TextBin->text());

    // Notify settings
    settings->notify();
}

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

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

void c2bConfigure::FindReplaceDialog_Delete()
{
    QTreeWidgetItem* item = ui.FindReplaceList->currentItem();
    delete item;
    item = ui.FindReplaceList->currentItem();
    if (item)
        item->setSelected(true);
    updateFindReplaceInputButtons();
}

void c2bConfigure::FindReplaceDialog_Edit()
{
    QTreeWidgetItem* item = ui.FindReplaceList->currentItem();
    if (item)
    {
        c2bConfigureFR* frD = new c2bConfigureFR(item, this);
        frD->exec();
        delete frD;
    }
}

void c2bConfigure::FindReplaceDialog_New()
{
    QStringList newlist;
    newlist << QString() << QString() << QString();
    QTreeWidgetItem* fri = new QTreeWidgetItem(ui.FindReplaceList, newlist);
    c2bConfigureFR* frD = new c2bConfigureFR(fri, this);
    if (frD->exec() != QDialog::Accepted)
        delete fri;
    delete frD;
}

void c2bConfigure::updateFindReplaceInputButtons()
{
    if (!ui.FindReplaceInput->isChecked())
    {
        ui.FindReplaceList->setEnabled(false);
        ui.FRNew->setEnabled(false);
        ui.FREdit->setEnabled(false);
        ui.FRDelete->setEnabled(false);
        return;
    }
    else
    {
        ui.FindReplaceList->setEnabled(true);
        ui.FRNew->setEnabled(true);
        if (ui.FindReplaceList->topLevelItemCount() > 0)
        {
            ui.FREdit->setEnabled(true);
            ui.FRDelete->setEnabled(true);
        }
        else
        {
            ui.FREdit->setEnabled(false);
            ui.FRDelete->setEnabled(false);
        }
    }
}

void c2bConfigure::getAnnoteCssFile()
{
    const QString fn(ui.AnnoteCssFile->text());
    const QString new_fn(c2bFileDialog::getOpenFilename(this, tr("Select CSS filename"),
                         fn, tr("Cascading Style Sheets (*.css);;All (*)")));
    if (!new_fn.isEmpty())
        ui.AnnoteCssFile->setText(new_fn);
}

void c2bConfigure::getjsMathDirectory()
{
    const QString new_dir(c2bFileDialog::getExistingDirectory(this, tr("Select jsMath directory"), ui.jsMathDirectory->text()));
    if (!new_dir.isEmpty())
        ui.jsMathDirectory->setText(new_dir);
}

void c2bConfigure::getJournalFile()
{
    const QString fn(ui.JournalFile->text());
    const QString new_fn(c2bFileDialog::getOpenFilename(this, tr("Select a filename (Restart to apply changes)"),
                         fn, tr("cb2Bib Journal Lists (*.txt);;All (*)")));
    if (!new_fn.isEmpty())
        ui.JournalFile->setText(new_fn);
}

void c2bConfigure::getRegularExpressionFile()
{
    const QString fn(ui.RegularExpressionFile->text());
    const QString new_fn(c2bFileDialog::getFilename(this, QString(), fn, tr("cb2Bib RegExp Lists (*.txt);;All (*)")));
    if (!new_fn.isEmpty())
        ui.RegularExpressionFile->setText(new_fn);
}

void c2bConfigure::getNetworkFile()
{
    const QString fn(ui.NetworkFile->text());
    const QString new_fn(c2bFileDialog::getFilename(this, QString(), fn, tr("cb2Bib Network Query Info (*.txt);;All (*)")));
    if (!new_fn.isEmpty())
        ui.NetworkFile->setText(new_fn);
}

void c2bConfigure::getBrowserCssFile()
{
    const QString fn(ui.BrowserCssFile->text());
    const QString new_fn(c2bFileDialog::getOpenFilename(this, tr("Select a filename (Restart browser to apply changes)"),
                         fn, tr("Cascading Style Sheets (*.css);;All (*)")));
    if (!new_fn.isEmpty())
        ui.BrowserCssFile->setText(new_fn);
}

void c2bConfigure::getFmClientCopyBin()
{
    const QString fn(ui.FmClientCopyBin->text());
    const QString new_fn(c2bFileDialog::getOpenFilename(this, QString(), fn, tr("File Manager Client executable (*)")));
    if (!new_fn.isEmpty())
        ui.FmClientCopyBin->setText(new_fn);
}

void c2bConfigure::getPreparserBin()
{
    const QString fn(ui.PreparserBin->text());
    const QString new_fn(c2bFileDialog::getOpenFilename(this, QString(), fn, tr("External Parser executable (*)")));
    if (!new_fn.isEmpty())
        ui.PreparserBin->setText(new_fn);
}

void c2bConfigure::getFmClientMoveBin()
{
    const QString fn(ui.FmClientMoveBin->text());
    const QString new_fn(c2bFileDialog::getOpenFilename(this, QString(), fn, tr("File Manager Client executable (*)")));
    if (!new_fn.isEmpty())
        ui.FmClientMoveBin->setText(new_fn);
}

void c2bConfigure::getPostprocessBibTeXBin()
{
    const QString fn(ui.PostprocessBibTeXBin->text());
    const QString new_fn(c2bFileDialog::getOpenFilename(this, QString(), fn, tr("BibTeX Postprocess executable (*)")));
    if (!new_fn.isEmpty())
        ui.PostprocessBibTeXBin->setText(new_fn);
}

void c2bConfigure::getPdfImportPdf2TextBin()
{
    const QString fn(ui.PdfImportPdf2TextBin->text());
    const QString new_fn(c2bFileDialog::getOpenFilename(this, QString(), fn, tr("PDF to text converter (*)")));
    if (!new_fn.isEmpty())
        ui.PdfImportPdf2TextBin->setText(new_fn);
}

void c2bConfigure::getBibSearcherPdf2TextBin()
{
    const QString fn(ui.BibSearcherPdf2TextBin->text());
    const QString new_fn(c2bFileDialog::getOpenFilename(this, QString(), fn, tr("PDF to text converter (*)")));
    if (!new_fn.isEmpty())
        ui.BibSearcherPdf2TextBin->setText(new_fn);
}

void c2bConfigure::getExifToolBin()
{
    const QString fn(ui.ExifToolBin->text());
    const QString new_fn(c2bFileDialog::getOpenFilename(this, QString(), fn, tr("ExifTool (*)")));
    if (!new_fn.isEmpty())
        ui.ExifToolBin->setText(new_fn);
}

void c2bConfigure::getPosLexiconFile()
{
    const QString fn(ui.PosLexiconFile->text());
    const QString new_fn(c2bFileDialog::getFilename(this, QString(), fn, tr("cb2Bib Part Of Speech Lexicon (*.pos);;All (*)")));
    if (!new_fn.isEmpty())
        ui.PosLexiconFile->setText(new_fn);
}

void c2bConfigure::getCacheDirectory()
{
    const QString new_dir(c2bFileDialog::getExistingDirectory(this, tr("Select a cache directory"), ui.CacheDirectory->text()));
    if (!new_dir.isEmpty())
        ui.CacheDirectory->setText(new_dir);
}

void c2bConfigure::getPdfDirectory()
{
    const QString dir(c2bUtils::documentAbsoluteName(ui.RelativePdfDirectory->isChecked(), settings->fileName("cb2Bib/BibTeXFile"),
                      ui.PdfDirectory->text(), QString()));
    QString new_dir(c2bFileDialog::getExistingDirectory(this, tr("Select documents directory"), dir));
    if (!new_dir.isEmpty())
    {
        new_dir = c2bUtils::documentDirName(ui.RelativePdfDirectory->isChecked(), settings->fileName("cb2Bib/BibTeXFile"), new_dir);
        ui.PdfDirectory->setText(new_dir);
    }
}

void c2bConfigure::populateFontCombos()
{
    QFontDatabase db;
    QList<int> sizes = db.standardSizes();
    QList<int>::Iterator it = sizes.begin();
    while (it != sizes.end())
    {
        ui.psizecombo->insertItem(0, QString::number(*it));
        ui.af_psizecombo->insertItem(0, QString::number(*it));
        ui.aff_psizecombo->insertItem(0, QString::number(*it));
        it++;
    }
}

void c2bConfigure::fontSelection(const QFont& f, QFontComboBox* fc, QComboBox* sc)
{
    fc->setCurrentFont(f);
    const int p_font_size(f.pointSize());
    int i(0);
    while (i < sc->count())
    {
        if (sc->itemText(i) == QString::number(p_font_size))
        {
            sc->setCurrentIndex(i);
            break;
        }
        i++;
    }
}

QFont c2bConfigure::selectedFont(QFontComboBox* fc, QComboBox* sc) const
{
    QFont f = fc->currentFont();
    f.setPointSize(sc->currentText().toInt());
    return f;
}

void c2bConfigure::changeContextColor(QTreeWidgetItem* item)
{
    QColor newColor = QColorDialog::getColor(item->textColor(0), this);
    if (newColor.isValid())
    {
        item->setData(0, Qt::TextColorRole, newColor);
        item->setData(0, Qt::DecorationRole, newColor);
        colors.updateColor(newColor, item->text(0));
    }
}

void c2bConfigure::changePage(QListWidgetItem* current, QListWidgetItem* previous)
{
    if (!current)
        current = previous;
    setWindowTitle(tr("Configure %1 - cb2Bib").arg(current->text()));
    ui.pagesWidget->setCurrentIndex(ui.contentsWidget->row(current));
}

void c2bConfigure::showMessage(const QString& ms)
{
    ui.statusBar->showMessage(ms, C2B_MESSAGE_TIME);
}

bool c2bConfigure::event(QEvent* qevent)
{
    if (qevent->type() == QEvent::StatusTip)
    {
        ui.statusBar->showMessage(static_cast<QStatusTipEvent*>(qevent)->tip());
        return true;
    }
    else
        return QDialog::event(qevent);
}

void c2bConfigure::help()
{
    c2bUtils::displayHelp("http://www.molspaces.com/d_cb2bib-c2bconf.php#c2bconf_" +
                          ui.contentsWidget->currentItem()->text().toLower());
}
