1 /* This file is (c) 2013 Tvangeste <i.4m.l33t@yandex.ru>
2  * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
3 
4 #include <QDebug>
5 
6 #include "wordlist.hh"
7 
WordList(QWidget * parent)8 WordList::WordList( QWidget * parent ) : QListWidget( parent )
9 , listItemDelegate( itemDelegate() )
10 {
11   wordFinder = 0;
12   translateLine = 0;
13   setItemDelegate( &listItemDelegate );
14 }
15 
attachFinder(WordFinder * finder)16 void WordList::attachFinder( WordFinder * finder )
17 {
18   // qDebug() << "Attaching the word finder..." << finder;
19 
20   if ( wordFinder == finder )
21     return;
22 
23   if ( wordFinder )
24   {
25     disconnect( wordFinder, SIGNAL( updated() ),
26              this, SLOT( prefixMatchUpdated() ) );
27     disconnect( wordFinder, SIGNAL( finished() ),
28              this, SLOT( prefixMatchFinished() ) );
29   }
30 
31   wordFinder = finder;
32 
33   connect( wordFinder, SIGNAL( updated() ),
34            this, SLOT( prefixMatchUpdated() ) );
35   connect( wordFinder, SIGNAL( finished() ),
36            this, SLOT( prefixMatchFinished() ) );
37 }
38 
prefixMatchUpdated()39 void WordList::prefixMatchUpdated()
40 {
41   updateMatchResults( false );
42 }
43 
prefixMatchFinished()44 void WordList::prefixMatchFinished()
45 {
46   updateMatchResults( true );
47 }
48 
updateMatchResults(bool finished)49 void WordList::updateMatchResults( bool finished )
50 {
51   WordFinder::SearchResults const & results = wordFinder->getResults();
52 
53   setUpdatesEnabled( false );
54 
55   for( unsigned x = 0; x < results.size(); ++x )
56   {
57     QListWidgetItem * i = item( x );
58 
59     if ( !i )
60     {
61       i = new QListWidgetItem( results[ x ].first, this );
62       i->setToolTip( results[ x ].first );
63 
64       if ( results[ x ].second )
65       {
66         QFont f = i->font();
67         f.setItalic( true );
68         i->setFont( f );
69       }
70       addItem( i );
71     }
72     else
73     {
74       if ( i->text() != results[ x ].first )
75       {
76         i->setText( results[ x ].first );
77         i->setToolTip( results[ x ].first );
78       }
79 
80       QFont f = i->font();
81       if ( f.italic() != results[ x ].second )
82       {
83         f.setItalic( results[ x ].second );
84         i->setFont( f );
85       }
86     }
87 
88     i->setTextAlignment(Qt::AlignLeft);
89   }
90 
91   while ( count() > (int) results.size() )
92   {
93     // Chop off any extra items that were there
94     QListWidgetItem * i = takeItem( count() - 1 );
95 
96     if ( i )
97       delete i;
98     else
99       break;
100   }
101 
102   if ( count() )
103   {
104     scrollToItem( item( 0 ), QAbstractItemView::PositionAtTop );
105     setCurrentItem( 0, QItemSelectionModel::Clear );
106   }
107 
108   setUpdatesEnabled( true );
109 
110   if ( finished )
111   {
112     unsetCursor();
113 
114     refreshTranslateLine();
115 
116     if ( !wordFinder->getErrorString().isEmpty() )
117       emit statusBarMessage( tr( "WARNING: %1" ).arg( wordFinder->getErrorString() ),
118                              20000 , QPixmap( ":/icons/error.png" ) );
119   }
120 
121   if( !results.empty() && results.front().first.isRightToLeft() )
122     setLayoutDirection( Qt::RightToLeft );
123   else
124     setLayoutDirection( Qt::LeftToRight );
125 
126   emit contentChanged();
127 }
128 
refreshTranslateLine()129 void WordList::refreshTranslateLine()
130 {
131   if ( !translateLine )
132     return;
133 
134   // Visually mark the input line to mark if there's no results
135   bool setMark = wordFinder->getResults().empty() && !wordFinder->wasSearchUncertain();
136 
137   if ( translateLine->property( "noResults" ).toBool() != setMark )
138   {
139     translateLine->setProperty( "noResults", setMark );
140     translateLine->setStyleSheet( translateLine->styleSheet() );
141   }
142 
143 }
144 
resizeEvent(QResizeEvent * ev)145 void WordList::resizeEvent( QResizeEvent * ev )
146 {
147   // In some rare cases Qt start send QResizeEvent recursively
148   // up to full stack depletion (tested on Qt 4.8.5, 4.8.6).
149   // We use this trick to break such suicidal process.
150 
151   for( int x = 0; x < resizedSizes.size(); x++ )
152     if( resizedSizes.at( x ) == ev->size() )
153       return;
154 
155   resizedSizes.push_back( ev->size() );
156 
157   QListWidget::resizeEvent( ev );
158 
159   resizedSizes.pop_back();
160 }
161