~ubuntu-branches/ubuntu/raring/kbibtex/raring

« back to all changes in this revision

Viewing changes to src/entrywidget.cpp

  • Committer: Package Import Robot
  • Author(s): Michael Hanke
  • Date: 2011-07-18 09:29:48 UTC
  • mfrom: (1.1.6) (2.1.5 sid)
  • Revision ID: package-import@ubuntu.com-20110718092948-ksxjmg7kdfamolmg
Tags: 0.3-1
* First upstream release for KDE4 (Closes: #634255). A number of search
  engines are still missing, in comparison to the 0.2 series.
* Bumped Standards-Version to 3.9.2, no changes necessary.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
*   Copyright (C) 2004-2009 by Thomas Fischer                             *
3
 
*   fischer@unix-ag.uni-kl.de                                             *
4
 
*                                                                         *
5
 
*   This program is free software; you can redistribute it and/or modify  *
6
 
*   it under the terms of the GNU General Public License as published by  *
7
 
*   the Free Software Foundation; either version 2 of the License, or     *
8
 
*   (at your option) any later version.                                   *
9
 
*                                                                         *
10
 
*   This program is distributed in the hope that it will be useful,       *
11
 
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12
 
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13
 
*   GNU General Public License for more details.                          *
14
 
*                                                                         *
15
 
*   You should have received a copy of the GNU General Public License     *
16
 
*   along with this program; if not, write to the                         *
17
 
*   Free Software Foundation, Inc.,                                       *
18
 
*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19
 
***************************************************************************/
20
 
#include <qlayout.h>
21
 
#include <qcheckbox.h>
22
 
#include <qtooltip.h>
23
 
#include <qwhatsthis.h>
24
 
#include <qlistview.h>
25
 
#include <qlabel.h>
26
 
#include <qregexp.h>
27
 
#include <qpushbutton.h>
28
 
#include <qpopupmenu.h>
29
 
#include <qtabwidget.h>
30
 
#include <qcombobox.h>
31
 
#include <qtimer.h>
32
 
#include <qlineedit.h>
33
 
 
34
 
#include <klocale.h>
35
 
#include <kdebug.h>
36
 
#include <kiconloader.h>
37
 
#include <kmessagebox.h>
38
 
#include <kapplication.h>
39
 
#include <kconfig.h>
40
 
#include <kwin.h>
41
 
 
42
 
#include <entry.h>
43
 
#include <entryfield.h>
44
 
#include <file.h>
45
 
#include <settings.h>
46
 
#include <entrywidgettab.h>
47
 
#include <entrywidgettitle.h>
48
 
#include <entrywidgetauthor.h>
49
 
#include <entrywidgetkeyword.h>
50
 
#include <entrywidgetpublication.h>
51
 
#include <entrywidgetmisc.h>
52
 
#include <entrywidgetexternal.h>
53
 
#include <entrywidgetuserdefined.h>
54
 
#include <entrywidgetother.h>
55
 
#include <entrywidgetwarningsitem.h>
56
 
#include <fieldlistview.h>
57
 
#include <idsuggestions.h>
58
 
#include <webqueryarxiv.h>
59
 
#include "entrywidget.h"
60
 
 
61
 
namespace KBibTeX
62
 
{
63
 
    QDialog::DialogCode EntryWidget::execute( BibTeX::Entry *entry, BibTeX::File *bibtexfile, bool isReadOnly, bool isNew, QWidget *parent, const char *name )
64
 
    {
65
 
        EntryWidgetDialog *dlg = new EntryWidgetDialog( parent, name, TRUE, i18n( "Edit BibTeX Entry" ), KDialogBase::Ok | KDialogBase::Cancel );
66
 
        EntryWidget *entryWidget = new EntryWidget( entry, bibtexfile, isReadOnly, isNew, dlg, "entryWidget" );
67
 
        dlg->setMainWidget( entryWidget );
68
 
 
69
 
        QDialog::DialogCode result = ( QDialog::DialogCode ) dlg->exec();
70
 
 
71
 
        delete entryWidget;
72
 
        delete dlg;
73
 
 
74
 
        return result;
75
 
    }
76
 
 
77
 
    EntryWidget::EntryWidget( BibTeX::File *bibtexfile, bool isReadOnly, bool isNew, QDialog *parent, const char *name )
78
 
            : QWidget( parent, name ), m_originalEntry( NULL ), m_bibtexfile( bibtexfile ), m_isReadOnly( isReadOnly ), m_isNew( isNew ), m_lastPage( NULL ), m_dlgParent( parent ), m_wqa( new WebQueryArXiv( NULL ) )
79
 
    {
80
 
        setupGUI( parent, FALSE );
81
 
 
82
 
        Settings * settings = Settings::self();
83
 
        m_checkBoxEnableAll->setChecked( settings->editing_EnableAllFields );
84
 
        m_defaultIdSuggestionAvailable = settings->idSuggestions_default >= 0;
85
 
        m_pushButtonForceDefaultIdSuggestion->setEnabled( !m_isReadOnly && m_defaultIdSuggestionAvailable );
86
 
        m_pushButtonIdSuggestions->setEnabled( !m_isReadOnly );
87
 
 
88
 
        connect( m_wqa, SIGNAL( foundEntry( BibTeX::Entry*, bool ) ), this, SLOT( useExternalEntry( BibTeX::Entry*, bool ) ) );
89
 
        connect( m_wqa, SIGNAL( endSearch( WebQuery::Status ) ), this, SLOT( endExternalSearch( WebQuery::Status ) ) );
90
 
    }
91
 
 
92
 
    EntryWidget::EntryWidget( BibTeX::Entry *entry, BibTeX::File *bibtexfile, bool isReadOnly, bool isNew, QDialog *parent, const char *name )
93
 
            : QWidget( parent, name ), m_originalEntry( entry ), m_bibtexfile( bibtexfile ), m_isReadOnly( isReadOnly ), m_isNew( isNew ), m_lastPage( NULL ), m_dlgParent( parent ), m_wqa( new WebQueryArXiv( NULL ) )
94
 
    {
95
 
        setupGUI( parent );
96
 
 
97
 
        Settings * settings = Settings::self();
98
 
        m_checkBoxEnableAll->setChecked( settings->editing_EnableAllFields );
99
 
        m_defaultIdSuggestionAvailable = settings->idSuggestions_default >= 0;
100
 
        m_pushButtonForceDefaultIdSuggestion->setEnabled( !m_isReadOnly && m_defaultIdSuggestionAvailable );
101
 
        m_pushButtonIdSuggestions->setEnabled( !m_isReadOnly );
102
 
 
103
 
        reset();
104
 
 
105
 
        connect( m_wqa, SIGNAL( foundEntry( BibTeX::Entry*, bool ) ), this, SLOT( useExternalEntry( BibTeX::Entry*, bool ) ) );
106
 
        connect( m_wqa, SIGNAL( endSearch( WebQuery::Status ) ), this, SLOT( endExternalSearch( WebQuery::Status ) ) );
107
 
    }
108
 
 
109
 
    EntryWidget::~EntryWidget()
110
 
    {
111
 
        m_updateWarningsTimer->stop();
112
 
        delete m_updateWarningsTimer;
113
 
 
114
 
        delete m_wqa;
115
 
 
116
 
        KConfig * config = kapp->config();
117
 
        config->setGroup( "EntryWidget" );
118
 
        saveWindowSize( config );
119
 
    }
120
 
 
121
 
    void EntryWidget::showEvent( QShowEvent *showev )
122
 
    {
123
 
        QWidget::showEvent( showev );
124
 
        EntryWidgetTitle *ewt = dynamic_cast<EntryWidgetTitle*>( m_tabWidget->page( 0 ) );
125
 
        if ( ewt != NULL )
126
 
            ewt->m_fieldLineEditTitle->setFocus();
127
 
 
128
 
        KConfig * config = kapp->config();
129
 
        config->setGroup( "EntryWidget" );
130
 
        restoreWindowSize( config );
131
 
    }
132
 
 
133
 
    bool EntryWidget::queryClose()
134
 
    {
135
 
        bool isModified = m_lineEditID->isModified();
136
 
 
137
 
        for ( QValueList<KBibTeX::EntryWidgetTab*>::iterator it( m_internalEntryWidgets.begin() ); !isModified && it != m_internalEntryWidgets.end(); ++it )
138
 
            isModified = ( *it ) ->isModified();
139
 
        isModified |= m_sourcePage->isModified();
140
 
 
141
 
        KGuiItem discardBtn = KGuiItem( i18n( "Discard" ), "editshred" );
142
 
        return !isModified || KMessageBox::warningContinueCancel( this, i18n( "The current entry has been modified. Do you want do discard your changes?" ), i18n( "Discard changes" ), discardBtn ) == KMessageBox::Continue;
143
 
    }
144
 
 
145
 
    void EntryWidget::apply()
146
 
    {
147
 
        if ( !m_isReadOnly )
148
 
        {
149
 
            apply( m_originalEntry );
150
 
            m_originalEntry->setId( IdSuggestions::resolveConflict( m_bibtexfile, m_originalEntry->id(), m_originalEntry ) );
151
 
 
152
 
            Settings * settings = Settings::self();
153
 
            settings->addToCompletion( m_originalEntry );
154
 
        }
155
 
    }
156
 
 
157
 
    void EntryWidget::apply( BibTeX::Entry *entry )
158
 
    {
159
 
        internalApply( entry );
160
 
        if ( m_tabWidget->currentPage() == m_sourcePage )
161
 
            m_sourcePage->apply( entry );
162
 
        else
163
 
        {
164
 
            for ( QValueList<KBibTeX::EntryWidgetTab*>::iterator it( m_internalEntryWidgets.begin() ); it != m_internalEntryWidgets.end(); ++it )
165
 
                ( *it ) ->apply( entry );
166
 
        }
167
 
    }
168
 
 
169
 
    void EntryWidget::internalApply( BibTeX::Entry *entry )
170
 
    {
171
 
        BibTeX::Entry::EntryType entryType = BibTeX::Entry::entryTypeFromString( m_comboBoxEntryType->currentText() );
172
 
        if ( entryType == BibTeX::Entry::etUnknown )
173
 
            entry->setEntryTypeString( m_comboBoxEntryType->currentText() );
174
 
        else
175
 
            entry->setEntryType( entryType );
176
 
 
177
 
        entry->setId( m_lineEditID->text() );
178
 
    }
179
 
 
180
 
    void EntryWidget::reset()
181
 
    {
182
 
        reset( m_originalEntry );
183
 
    }
184
 
 
185
 
    void EntryWidget::reset( BibTeX::Entry *entry )
186
 
    {
187
 
        internalReset( entry );
188
 
        m_sourcePage->reset( entry );
189
 
        for ( QValueList<KBibTeX::EntryWidgetTab*>::iterator it( m_internalEntryWidgets.begin() ); it != m_internalEntryWidgets.end(); ++it )
190
 
            ( *it ) ->reset( entry );
191
 
 
192
 
        updateGUI();
193
 
    }
194
 
 
195
 
    void EntryWidget::internalReset( BibTeX::Entry *entry )
196
 
    {
197
 
        m_lineEditID->setText( entry->id() );
198
 
        Settings * settings = Settings::self();
199
 
        m_pushButtonForceDefaultIdSuggestion->setOn( m_defaultIdSuggestionAvailable && settings->idSuggestions_forceDefault && m_isNew );
200
 
        m_pushButtonForceDefaultIdSuggestion->setEnabled( !m_isReadOnly && m_defaultIdSuggestionAvailable );
201
 
 
202
 
        bool foundEntryType = FALSE;
203
 
        for ( int i = 0; !foundEntryType && i < m_comboBoxEntryType->count(); i++ )
204
 
            if (( BibTeX::Entry::EntryType ) i + BibTeX::Entry::etArticle == entry->entryType() )
205
 
            {
206
 
                m_comboBoxEntryType->setCurrentItem( i );
207
 
                foundEntryType = TRUE;
208
 
            }
209
 
        if ( !foundEntryType )
210
 
            m_comboBoxEntryType->setCurrentText( entry->entryTypeString() );
211
 
    }
212
 
 
213
 
    void EntryWidget::slotEnableAllFields( )
214
 
    {
215
 
        updateGUI();
216
 
    }
217
 
 
218
 
    void EntryWidget::slotForceDefaultIdSuggestion()
219
 
    {
220
 
        m_isNew = FALSE;
221
 
        m_lineEditID->setEnabled( !m_pushButtonForceDefaultIdSuggestion->isOn() );
222
 
        m_pushButtonIdSuggestions->setEnabled( !m_pushButtonForceDefaultIdSuggestion->isOn() && !m_isReadOnly );
223
 
        updateWarnings();
224
 
    }
225
 
 
226
 
    void EntryWidget::slotEntryTypeChanged( )
227
 
    {
228
 
        updateGUI();
229
 
    }
230
 
 
231
 
    void EntryWidget::slotCurrentPageChanged( QWidget* newPage )
232
 
    {
233
 
        BibTeX::Entry temporaryEntry;
234
 
 
235
 
        if ( newPage == m_sourcePage )
236
 
        {
237
 
            // switching to source tab
238
 
            m_updateWarningsTimer->stop();
239
 
            internalApply( &temporaryEntry );
240
 
            for ( QValueList<KBibTeX::EntryWidgetTab*>::iterator it( m_internalEntryWidgets.begin() ); it != m_internalEntryWidgets.end(); ++it )
241
 
                ( *it ) ->apply( &temporaryEntry );
242
 
            m_sourcePage->reset( &temporaryEntry );
243
 
 
244
 
            m_comboBoxEntryType->setEnabled( FALSE );
245
 
            m_lineEditID->setEnabled( FALSE );
246
 
            m_pushButtonIdSuggestions->setEnabled( FALSE );
247
 
            m_pushButtonForceDefaultIdSuggestion->setEnabled( FALSE );
248
 
        }
249
 
        else if ( m_lastPage == m_sourcePage )
250
 
        {
251
 
            // switching from source tab away
252
 
            bool doApply = true;
253
 
            bool doChange = true;
254
 
            if ( !m_sourcePage->containsValidText() )
255
 
            {
256
 
                if ( KMessageBox::warningYesNo( this, i18n( "The source code does not contain valid BibTeX code.\n\nRestore previous version or continue editing?" ), i18n( "Invalid BibTeX code" ), KGuiItem( i18n( "Restore" ) ), KGuiItem( i18n( "Edit" ) ) ) == KMessageBox::No )
257
 
                {
258
 
                    QString text = m_sourcePage->text();
259
 
                    m_tabWidget->showPage( m_sourcePage );
260
 
                    m_sourcePage->setText( text );
261
 
                    doChange = false;
262
 
                    newPage = m_sourcePage;
263
 
                }
264
 
                else
265
 
                    doApply = false;
266
 
            }
267
 
 
268
 
            if ( doChange )
269
 
            {
270
 
                if ( doApply )
271
 
                {
272
 
                    m_sourcePage->apply( &temporaryEntry );
273
 
                    internalReset( &temporaryEntry );
274
 
                    for ( QValueList<KBibTeX::EntryWidgetTab*>::iterator it( m_internalEntryWidgets.begin() ); it != m_internalEntryWidgets.end(); ++it )
275
 
                        ( *it ) ->reset( &temporaryEntry );
276
 
                    updateWarnings();
277
 
                }
278
 
 
279
 
                m_comboBoxEntryType->setEnabled( TRUE );
280
 
                m_lineEditID->setEnabled( !m_defaultIdSuggestionAvailable || !m_pushButtonForceDefaultIdSuggestion->isOn() );
281
 
                m_pushButtonIdSuggestions->setEnabled(( !m_defaultIdSuggestionAvailable || !m_pushButtonForceDefaultIdSuggestion->isOn() ) && !m_isReadOnly );
282
 
                m_pushButtonForceDefaultIdSuggestion->setEnabled( !m_isReadOnly && m_defaultIdSuggestionAvailable );
283
 
                if ( !m_isReadOnly )
284
 
                    m_updateWarningsTimer->start( 500 );
285
 
            }
286
 
        }
287
 
 
288
 
        m_lastPage = newPage;
289
 
    }
290
 
 
291
 
    void EntryWidget::warningsExecute( QListViewItem* item )
292
 
    {
293
 
        EntryWidgetWarningsItem * ewwi = dynamic_cast<KBibTeX::EntryWidgetWarningsItem*>( item );
294
 
        if ( ewwi != NULL && ewwi->widget() != NULL )
295
 
        {
296
 
            ewwi->widget() ->setFocus();
297
 
            // find and activate corresponding tab page
298
 
            QObject *parent = ewwi->widget();
299
 
            KBibTeX::EntryWidgetTab *ewt = dynamic_cast<KBibTeX::EntryWidgetTab*>( parent );
300
 
            while ( ewt == NULL && parent != NULL )
301
 
            {
302
 
                parent = parent->parent();
303
 
                ewt = dynamic_cast<KBibTeX::EntryWidgetTab*>( parent );
304
 
            }
305
 
            m_tabWidget->setCurrentPage( m_tabWidget-> indexOf( ewt ) );
306
 
        }
307
 
    }
308
 
 
309
 
    void EntryWidget::setupGUI( QWidget *parent, bool showWarnings )
310
 
    {
311
 
        QGridLayout * layout = new QGridLayout( this, 4, 6, 0, KDialog::spacingHint() );
312
 
 
313
 
        // in the top row on the left, put an entry type label and combobox
314
 
        QLabel *label = new QLabel( i18n( "E&ntry Type:" ), this );
315
 
        layout->addWidget( label, 0, 0 );
316
 
        m_comboBoxEntryType = new QComboBox( TRUE, this, "m_comboBoxEntryType" );
317
 
        label->setBuddy( m_comboBoxEntryType );
318
 
        m_comboBoxEntryType->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed );
319
 
        m_comboBoxEntryType->setEnabled( !m_isReadOnly );
320
 
        layout->addWidget( m_comboBoxEntryType, 0, 1 );
321
 
        setupEntryTypes();
322
 
 
323
 
        // in the top row on the left, put an identifier label and combobox
324
 
        label = new QLabel( i18n( "&Identifier" ), this );
325
 
        layout->addWidget( label, 0, 2 );
326
 
        m_lineEditID = new QLineEdit( this, "m_lineEditID" );
327
 
        label->setBuddy( m_lineEditID );
328
 
        m_lineEditID->setReadOnly( m_isReadOnly );
329
 
        m_lineEditID->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed );
330
 
        layout->addWidget( m_lineEditID, 0, 3 );
331
 
 
332
 
        m_pushButtonIdSuggestions = new QPushButton( QIconSet( BarIcon( "wizard" ) ), "", this, "m_pushButtonIdSuggestions" );
333
 
        m_menuIdSuggestions = new QPopupMenu( m_pushButtonIdSuggestions );
334
 
        connect( m_menuIdSuggestions, SIGNAL( activated( int ) ), this, SLOT( insertIdSuggestion( int ) ) );
335
 
        m_pushButtonIdSuggestions->setPopup( m_menuIdSuggestions );
336
 
        layout->addWidget( m_pushButtonIdSuggestions, 0, 4 );
337
 
 
338
 
        m_pushButtonForceDefaultIdSuggestion = new QPushButton( QIconSet( BarIcon( "favorites" ) ), "", this, "m_pushButtonForceDefaultIdSuggestion" );
339
 
        m_pushButtonForceDefaultIdSuggestion->setToggleButton( TRUE );
340
 
        layout->addWidget( m_pushButtonForceDefaultIdSuggestion, 0, 5 );
341
 
        QToolTip::add( m_pushButtonForceDefaultIdSuggestion, i18n( "Use the default id suggestion to set the entry id" ) );
342
 
        QWhatsThis::add( m_pushButtonForceDefaultIdSuggestion, i18n( "Use the default id suggestion to set the entry id.\nYou can edit and select the default id suggestion in the configuration dialog." ) );
343
 
 
344
 
        // central tab widget for all the tabs
345
 
        m_tabWidget = new QTabWidget( this );
346
 
        layout->addMultiCellWidget( m_tabWidget, 1, 1, 0, 5 );
347
 
        addTabWidgets();
348
 
 
349
 
        // a check box if the user want to edit all fields
350
 
        m_checkBoxEnableAll = new QCheckBox( i18n( "Enable all &fields for editing" ), this );
351
 
        layout->addMultiCellWidget( m_checkBoxEnableAll, 2, 2, 0, 4 );
352
 
 
353
 
        m_pushButtonRefetch = new QPushButton( KGlobal::iconLoader() ->loadIconSet( "reload", KIcon::Small ), i18n( "Refetch" ), this );
354
 
        layout->addWidget( m_pushButtonRefetch, 2, 5 );
355
 
        connect( m_pushButtonRefetch, SIGNAL( clicked() ), this, SLOT( refreshFromURL() ) );
356
 
 
357
 
        if ( showWarnings )
358
 
        {
359
 
            // list view for warnings, errors and suggestions
360
 
            m_listViewWarnings = new QListView( this );
361
 
            m_listViewWarnings->addColumn( i18n( "Message" ) );
362
 
            m_listViewWarnings->setAllColumnsShowFocus( true );
363
 
            layout->addMultiCellWidget( m_listViewWarnings, 3, 3, 0, 5 );
364
 
            connect( m_listViewWarnings, SIGNAL( doubleClicked( QListViewItem*, const QPoint&, int ) ), this, SLOT( warningsExecute( QListViewItem* ) ) );
365
 
        }
366
 
        else
367
 
            m_listViewWarnings = NULL;
368
 
 
369
 
        connect( m_checkBoxEnableAll, SIGNAL( toggled( bool ) ), this, SLOT( slotEnableAllFields( ) ) );
370
 
        connect( m_comboBoxEntryType, SIGNAL( activated( int ) ), this, SLOT( slotEntryTypeChanged( ) ) );
371
 
        connect( m_pushButtonForceDefaultIdSuggestion, SIGNAL( toggled( bool ) ), this, SLOT( slotForceDefaultIdSuggestion() ) );
372
 
        connect( m_comboBoxEntryType, SIGNAL( textChanged( const QString & ) ), this, SLOT( slotEntryTypeChanged() ) );
373
 
        connect( m_tabWidget, SIGNAL( currentChanged( QWidget* ) ), this, SLOT( slotCurrentPageChanged( QWidget* ) ) );
374
 
        connect( parent, SIGNAL( okClicked() ), this, SLOT( apply() ) );
375
 
        connect( m_menuIdSuggestions, SIGNAL( aboutToShow() ), this, SLOT( updateIdSuggestionsMenu() ) );
376
 
 
377
 
        m_updateWarningsTimer = new QTimer( this );
378
 
        connect( m_updateWarningsTimer, SIGNAL( timeout() ), this, SLOT( updateWarnings() ) );
379
 
        if ( !m_isReadOnly )
380
 
            m_updateWarningsTimer->start( 500 );
381
 
    }
382
 
 
383
 
    void EntryWidget::addTabWidgets()
384
 
    {
385
 
        addTabWidget( new KBibTeX::EntryWidgetTitle( m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetTitle" ), i18n( "Title" ) );
386
 
        addTabWidget( new KBibTeX::EntryWidgetAuthor( m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetAuthor" ), i18n( "Author/Editor" ) );
387
 
        addTabWidget( new KBibTeX::EntryWidgetPublication( m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetPublication" ), i18n( "Publication" ) );
388
 
        addTabWidget( new KBibTeX::EntryWidgetMisc( m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetMisc" ), i18n( "Misc" ) );
389
 
        addTabWidget( new KBibTeX::EntryWidgetKeyword( m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetKeyword" ), i18n( "Keywords" ) );
390
 
        addTabWidget( new KBibTeX::EntryWidgetExternal( m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetExternal" ), i18n( "External" ) );
391
 
        addTabWidget( new KBibTeX::EntryWidgetUserDefined( m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetUserDefined" ), i18n( "User Defined" ) );
392
 
        addTabWidget( new KBibTeX::EntryWidgetOther( m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetOther" ), i18n( "Other Fields" ) );
393
 
 
394
 
        m_sourcePage = new KBibTeX::EntryWidgetSource( m_bibtexfile, m_isReadOnly, m_tabWidget, "EntryWidgetSource" );
395
 
        m_tabWidget->insertTab( m_sourcePage, i18n( "Source" ) );
396
 
    }
397
 
 
398
 
    void EntryWidget::addTabWidget( EntryWidgetTab *widget, const QString& title )
399
 
    {
400
 
        m_tabWidget->insertTab( widget, title );
401
 
        m_internalEntryWidgets.append( widget );
402
 
    }
403
 
 
404
 
    void EntryWidget::setupEntryTypes()
405
 
    {
406
 
        int i = ( int ) BibTeX::Entry::etArticle;
407
 
        BibTeX::Entry::EntryType entryType = ( BibTeX::Entry::EntryType ) i;
408
 
        while ( entryType != BibTeX::Entry::etUnknown )
409
 
        {
410
 
            QString currentString = BibTeX::Entry::entryTypeToString( entryType );
411
 
            m_comboBoxEntryType->insertItem( currentString );
412
 
            entryType = ( BibTeX::Entry::EntryType ) ++i;
413
 
        }
414
 
    }
415
 
 
416
 
    void EntryWidget::updateGUI()
417
 
    {
418
 
        BibTeX::Entry::EntryType entryType = BibTeX::Entry::entryTypeFromString( m_comboBoxEntryType->currentText() );
419
 
        for ( QValueList<KBibTeX::EntryWidgetTab*>::iterator it( m_internalEntryWidgets.begin() ); it != m_internalEntryWidgets.end(); ++it )
420
 
            ( *it ) ->updateGUI( entryType, m_checkBoxEnableAll->isChecked() );
421
 
        updateWarnings( );
422
 
    }
423
 
 
424
 
    void EntryWidget::updateWarnings()
425
 
    {
426
 
        if ( m_listViewWarnings == NULL )
427
 
            return;
428
 
 
429
 
        m_listViewWarnings->clear();
430
 
 
431
 
        int p = 0;
432
 
        if ( m_defaultIdSuggestionAvailable && m_pushButtonForceDefaultIdSuggestion->isOn() )
433
 
        {
434
 
            BibTeX::Entry temporaryEntry;
435
 
            apply( &temporaryEntry );
436
 
            QString id = IdSuggestions::createDefaultSuggestion( m_bibtexfile, &temporaryEntry );
437
 
            if ( id.isNull() || id.isEmpty() )
438
 
                new KBibTeX::EntryWidgetWarningsItem( KBibTeX::EntryWidgetWarningsItem::wlWarning, i18n( "Please supply more fields to use the default id" ), m_pushButtonForceDefaultIdSuggestion, m_listViewWarnings );
439
 
            else
440
 
            {
441
 
                new KBibTeX::EntryWidgetWarningsItem( KBibTeX::EntryWidgetWarningsItem::wlInformation, QString( i18n( "Using '%1' as entry id" ) ).arg( id ), m_pushButtonForceDefaultIdSuggestion, m_listViewWarnings );
442
 
                m_lineEditID->setText( id );
443
 
            }
444
 
        }
445
 
        else if ( m_lineEditID->text().isEmpty() )
446
 
            new KBibTeX::EntryWidgetWarningsItem( KBibTeX::EntryWidgetWarningsItem::wlError, i18n( "An entry has to have an identifier" ), m_lineEditID, m_listViewWarnings );
447
 
        else if (( p = m_lineEditID->text().find( Settings::noIdChars ) ) > 0 )
448
 
            new KBibTeX::EntryWidgetWarningsItem( KBibTeX::EntryWidgetWarningsItem::wlError, QString( i18n( "The identifier contains invalid characters at position %1" ) ).arg( p + 1 ), m_lineEditID, m_listViewWarnings );
449
 
 
450
 
        BibTeX::Entry::EntryType entryType = BibTeX::Entry::entryTypeFromString( m_comboBoxEntryType->currentText() );
451
 
        for ( QValueList<KBibTeX::EntryWidgetTab*>::iterator it( m_internalEntryWidgets.begin() ); it != m_internalEntryWidgets.end(); ++it )
452
 
            ( *it ) ->updateWarnings( entryType, m_listViewWarnings );
453
 
 
454
 
        QString text = m_lineEditID->text();
455
 
        for ( unsigned int i = 0; i < text.length(); i++ )
456
 
            if ( text.at( i ).unicode() > 127 )
457
 
            {
458
 
                new KBibTeX::EntryWidgetWarningsItem( KBibTeX::EntryWidgetWarningsItem::wlWarning, QString( i18n( "The identifier contains non-ascii characters, first one is '%1'" ) ).arg( text.at( i ) ), m_lineEditID, m_listViewWarnings );
459
 
                break;
460
 
            }
461
 
 
462
 
        BibTeX::Entry temporaryEntry;
463
 
        /** fetch data from GUI elements */
464
 
        for ( QValueList<KBibTeX::EntryWidgetTab*>::iterator it( m_internalEntryWidgets.begin() ); it != m_internalEntryWidgets.end(); ++it )
465
 
            ( *it ) ->apply( &temporaryEntry );
466
 
        internalApply( &temporaryEntry );
467
 
 
468
 
        /** check if entry with same id already exists */
469
 
        QString id = temporaryEntry.id();
470
 
        if ( m_bibtexfile != NULL && !id.isEmpty() )
471
 
        {
472
 
            BibTeX::Entry *nameMatched = dynamic_cast<BibTeX::Entry*>( m_bibtexfile->containsKey( id ) );
473
 
            if ( nameMatched != NULL && nameMatched != m_originalEntry )
474
 
                new KBibTeX::EntryWidgetWarningsItem( KBibTeX::EntryWidgetWarningsItem::wlError, QString( i18n( "This BibTeX file already contains an entry with id '%1'." ) ).arg( id ), m_lineEditID, m_listViewWarnings );
475
 
        }
476
 
 
477
 
        BibTeX::Entry *crossRefEntry = NULL;
478
 
        QString crossRefText = "";
479
 
        BibTeX::EntryField *crossRef = temporaryEntry.getField( BibTeX::EntryField::ftCrossRef );
480
 
        if ( crossRef != NULL && m_bibtexfile != NULL )
481
 
        {
482
 
            crossRefText = crossRef->value()->text();
483
 
            crossRefEntry = dynamic_cast<BibTeX::Entry*>( m_bibtexfile->containsKey( crossRefText ) );
484
 
        }
485
 
 
486
 
        switch ( temporaryEntry.entryType() )
487
 
        {
488
 
        case BibTeX::Entry::etProceedings:
489
 
            if ( temporaryEntry.getField( BibTeX::EntryField::ftEditor ) == NULL && temporaryEntry.getField( BibTeX::EntryField::ftOrganization ) == NULL && temporaryEntry.getField( BibTeX::EntryField::ftKey ) == NULL )
490
 
            {
491
 
                new KBibTeX::EntryWidgetWarningsItem( KBibTeX::EntryWidgetWarningsItem::wlWarning, i18n( "Require either 'Editor', 'Organization', or 'Key'" ), NULL, m_listViewWarnings );
492
 
            }
493
 
            break;
494
 
        case BibTeX::Entry::etInProceedings:
495
 
        {
496
 
            if ( crossRefEntry != NULL )
497
 
            {
498
 
                if ( crossRefEntry->getField( BibTeX::EntryField::ftEditor ) == NULL && crossRefEntry->getField( BibTeX::EntryField::ftKey ) == NULL && crossRefEntry->getField( BibTeX::EntryField::ftBookTitle ) == NULL )
499
 
                {
500
 
                    new KBibTeX::EntryWidgetWarningsItem( KBibTeX::EntryWidgetWarningsItem::wlWarning, QString( i18n( "Cross referenced entry '%1' must contain either 'Editor', 'Key', or 'Book Title'" ) ).arg( crossRefText ), NULL, m_listViewWarnings );
501
 
                }
502
 
            }
503
 
        }
504
 
        break;
505
 
        case BibTeX::Entry::etInBook:
506
 
        {
507
 
            if ( crossRefEntry != NULL )
508
 
            {
509
 
                if ( crossRefEntry->getField( BibTeX::EntryField::ftVolume ) == NULL )
510
 
                    new KBibTeX::EntryWidgetWarningsItem( KBibTeX::EntryWidgetWarningsItem::wlWarning, QString( i18n( "Cross referenced entry '%1' must contain 'Volume'" ) ).arg( crossRefText ), NULL, m_listViewWarnings );
511
 
                if ( crossRefEntry->getField( BibTeX::EntryField::ftEditor ) == NULL && crossRefEntry->getField( BibTeX::EntryField::ftKey ) == NULL && crossRefEntry->getField( BibTeX::EntryField::ftSeries ) == NULL )
512
 
                {
513
 
                    new KBibTeX::EntryWidgetWarningsItem( KBibTeX::EntryWidgetWarningsItem::wlWarning, QString( i18n( "Cross referenced entry '%1' must contain either 'Editor', 'Key', or 'Series'" ) ).arg( crossRefText ), NULL, m_listViewWarnings );
514
 
                }
515
 
            }
516
 
        }
517
 
        break;
518
 
        default:
519
 
        {
520
 
// nothing
521
 
        }
522
 
        }
523
 
    }
524
 
 
525
 
    void EntryWidget::updateIdSuggestionsMenu()
526
 
    {
527
 
        BibTeX::Entry temporaryEntry;
528
 
        m_menuIdSuggestions->clear();
529
 
        m_idToSuggestion.clear();
530
 
 
531
 
        apply( &temporaryEntry );
532
 
        QStringList suggestions = IdSuggestions::createSuggestions( m_bibtexfile, &temporaryEntry );
533
 
        for ( QStringList::ConstIterator it = suggestions.begin(); it != suggestions.end(); ++it )
534
 
            m_idToSuggestion.insert( m_menuIdSuggestions->insertItem( *it ), *it );
535
 
 
536
 
        if ( m_idToSuggestion.count() == 0 )
537
 
            m_menuIdSuggestions->setItemEnabled( m_menuIdSuggestions->insertItem( i18n( "No suggestions available" ) ), FALSE );
538
 
    }
539
 
 
540
 
    void EntryWidget::insertIdSuggestion( int id )
541
 
    {
542
 
        m_lineEditID->setText( m_idToSuggestion[id] );
543
 
    }
544
 
 
545
 
    /* This function was taken form KMainWindow of KDE 3.5 and modified to fit KBibTeX */
546
 
    void EntryWidget::saveWindowSize( KConfig *config ) const
547
 
    {
548
 
        int scnum = QApplication::desktop()->screenNumber( parentWidget() );
549
 
        QRect desk = QApplication::desktop()->screenGeometry( scnum );
550
 
        int w, h;
551
 
#if defined Q_WS_X11
552
 
        // save maximalization as desktop size + 1 in that direction
553
 
        KWin::WindowInfo info = KWin::windowInfo( m_dlgParent->winId(), NET::WMState );
554
 
        w = info.state() & NET::MaxHoriz ? desk.width() + 1 : m_dlgParent->width();
555
 
        h = info.state() & NET::MaxVert ? desk.height() + 1 : m_dlgParent->height();
556
 
#else
557
 
        if ( isMaximized() )
558
 
        {
559
 
            w = desk.width() + 1;
560
 
            h = desk.height() + 1;
561
 
        }
562
 
        //TODO: add "Maximized" property instead "+1" hack
563
 
#endif
564
 
        QRect size( desk.width(), w, desk.height(), h );
565
 
        bool defaultSize = false;//( size == d->defaultWindowSize );
566
 
        QString widthString = QString::fromLatin1( "Width %1" ).arg( desk.width() );
567
 
        QString heightString = QString::fromLatin1( "Height %1" ).arg( desk.height() );
568
 
        if ( !config->hasDefault( widthString ) && defaultSize )
569
 
            config->revertToDefault( widthString );
570
 
        else
571
 
            config->writeEntry( widthString, w );
572
 
 
573
 
        if ( !config->hasDefault( heightString ) && defaultSize )
574
 
            config->revertToDefault( heightString );
575
 
        else
576
 
            config->writeEntry( heightString, h );
577
 
    }
578
 
 
579
 
    /* This function was taken form KMainWindow of KDE 3.5 and modified to fit KBibTeX */
580
 
    void EntryWidget::restoreWindowSize( KConfig *config )
581
 
    {
582
 
        // restore the size
583
 
        int scnum = QApplication::desktop()->screenNumber( parentWidget() );
584
 
        QRect desk = QApplication::desktop()->screenGeometry( scnum );
585
 
//         if ( d->defaultWindowSize.isNull() ) // only once
586
 
//             d->defaultWindowSize = QRect( desk.width(), width(), desk.height(), height() ); // store default values
587
 
        QSize size( config->readNumEntry( QString::fromLatin1( "Width %1" ).arg( desk.width() ), 0 ),
588
 
                    config->readNumEntry( QString::fromLatin1( "Height %1" ).arg( desk.height() ), 0 ) );
589
 
        if ( size.isEmpty() )
590
 
        {
591
 
            // try the KDE 2.0 way
592
 
            size = QSize( config->readNumEntry( QString::fromLatin1( "Width" ), 0 ),
593
 
                          config->readNumEntry( QString::fromLatin1( "Height" ), 0 ) );
594
 
            if ( !size.isEmpty() )
595
 
            {
596
 
                // make sure the other resolutions don't get old settings
597
 
                config->writeEntry( QString::fromLatin1( "Width" ), 0 );
598
 
                config->writeEntry( QString::fromLatin1( "Height" ), 0 );
599
 
            }
600
 
        }
601
 
        if ( !size.isEmpty() )
602
 
        {
603
 
#ifdef Q_WS_X11
604
 
            int state = ( size.width() > desk.width() ? NET::MaxHoriz : 0 )
605
 
                        | ( size.height() > desk.height() ? NET::MaxVert : 0 );
606
 
            if (( state & NET::Max ) == NET::Max )
607
 
                ; // no resize
608
 
            else if (( state & NET::MaxHoriz ) == NET::MaxHoriz )
609
 
                m_dlgParent->resize( width(), size.height() );
610
 
            else if (( state & NET::MaxVert ) == NET::MaxVert )
611
 
                m_dlgParent->resize( size.width(), height() );
612
 
            else
613
 
                m_dlgParent->resize( size );
614
 
            // QWidget::showMaximized() is both insufficient and broken
615
 
            KWin::setState( m_dlgParent->winId(), state );
616
 
#else
617
 
            if ( size.width() > desk.width() || size.height() > desk.height() )
618
 
                m_dlgParent->setWindowState( WindowMaximized );
619
 
            else
620
 
                m_dlgParent->resize( size );
621
 
#endif
622
 
        }
623
 
    }
624
 
 
625
 
    void EntryWidget::refreshFromURL()
626
 
    {
627
 
        BibTeX::Entry *entry = new BibTeX::Entry();
628
 
        apply( entry );
629
 
        m_oldId = entry->id();
630
 
        BibTeX::EntryField * field = entry->getField( BibTeX::EntryField::ftURL );
631
 
        KURL url = field != NULL ? KURL( field->value()->text().lower() ) : KURL();
632
 
 
633
 
        if ( url.isValid() && url.prettyURL().contains( "arxiv.org/abs/" ) )
634
 
        {
635
 
            m_pushButtonRefetch->setEnabled( false );
636
 
            qDebug( "Refetching from url %s", url.prettyURL().latin1() );
637
 
            m_wqa->fetchFromAbstract( url );
638
 
        }
639
 
        else
640
 
        {
641
 
            KMessageBox::information( this, i18n( "Currently only refetching from ArXiv sources is supported.\n\nThis requires that the URL field points to an \"abstract\" page (i.e. the URL contains \"arxiv.org/abs/\")." ), i18n( "Refetching entry" ) );
642
 
            m_pushButtonRefetch->setEnabled( true );
643
 
        }
644
 
    }
645
 
 
646
 
    void EntryWidget::useExternalEntry( BibTeX::Entry* entry, bool )
647
 
    {
648
 
        if ( entry != NULL )
649
 
        {
650
 
            BibTeX::Entry *oldEntry = new BibTeX::Entry();
651
 
            apply( oldEntry );
652
 
 
653
 
            entry->setId( m_oldId );
654
 
            for ( BibTeX::Entry::EntryFields::ConstIterator it = oldEntry->begin(); it != oldEntry->end(); ++it )
655
 
            {
656
 
                BibTeX::EntryField *oldField = *it;
657
 
                BibTeX::EntryField *field = entry->getField( oldField->fieldTypeName() );
658
 
                if ( field == NULL )
659
 
                {
660
 
                    field = new BibTeX::EntryField( oldField->fieldTypeName() );
661
 
                    entry->addField( field );
662
 
                    field->setValue( new BibTeX::Value( oldField->value() ) );
663
 
                }
664
 
            }
665
 
            reset( entry );
666
 
        }
667
 
        else
668
 
            KMessageBox::error( this, i18n( "Fetching updated bibliographic data failed." ), i18n( "Refetching entry" ) );
669
 
    }
670
 
 
671
 
    void EntryWidget::endExternalSearch( WebQuery::Status )
672
 
    {
673
 
        m_pushButtonRefetch->setEnabled( true );
674
 
    }
675
 
 
676
 
}
677
 
#include "entrywidget.moc"