summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/inputmethods.cpp533
-rw-r--r--core/launcher/inputmethods.h50
2 files changed, 431 insertions, 152 deletions
diff --git a/core/launcher/inputmethods.cpp b/core/launcher/inputmethods.cpp
index 09b9a83..f0d8294 100644
--- a/core/launcher/inputmethods.cpp
+++ b/core/launcher/inputmethods.cpp
@@ -1,321 +1,566 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#define QTOPIA_INTERNAL_LANGLIST 21#define QTOPIA_INTERNAL_LANGLIST
22#include "inputmethods.h" 22#include "inputmethods.h"
23 23
24#include <qpe/config.h> 24#include <qtopia/config.h>
25#include <qpe/qpeapplication.h> 25#include <qtopia/qpeapplication.h>
26#include <qpe/inputmethodinterface.h> 26#include <qtopia/inputmethodinterface.h>
27#include <qpe/qlibrary.h> 27#include <qtopia/global.h>
28#include <qpe/global.h>
29 28
30#include <qpopupmenu.h> 29#include <qpopupmenu.h>
31#include <qpushbutton.h> 30#include <qpushbutton.h>
32#include <qtoolbutton.h> 31#include <qtoolbutton.h>
32#include <qwidgetstack.h>
33#include <qwidget.h> 33#include <qwidget.h>
34#include <qlayout.h> 34#include <qlayout.h>
35#include <qtimer.h> 35#include <qtimer.h>
36#include <qdir.h> 36#include <qdir.h>
37#include <stdlib.h> 37#include <stdlib.h>
38#include <qtranslator.h> 38#include <qtranslator.h>
39#include <qtl.h>
39 40
40#ifdef Q_WS_QWS 41#ifdef Q_WS_QWS
41#include <qwindowsystem_qws.h> 42#include <qwindowsystem_qws.h>
42#include <qwsevent_qws.h> 43#include <qwsevent_qws.h>
44#include <qcopchannel_qws.h>
43#endif 45#endif
44 46
45#ifdef SINGLE_APP 47/* ### SingleFloppy if someone is interested? */
46#include "handwritingimpl.h" 48#if 0
47#include "keyboardimpl.h" 49#ifdef QT_NO_COMPONENT
48#include "pickboardimpl.h" 50#include "../plugins/inputmethods/handwriting/handwritingimpl.h"
51#include "../plugins/inputmethods/keyboard/keyboardimpl.h"
52#include "../3rdparty/plugins/inputmethods/pickboard/pickboardimpl.h"
53#endif
49#endif 54#endif
50
51 55
52/* XPM */ 56/* XPM */
53static const char * tri_xpm[]={ 57static const char * tri_xpm[]={
54"9 9 2 1", 58"9 9 2 1",
55"a c #000000", 59"a c #000000",
56". c None", 60". c None",
57".........", 61".........",
58".........", 62".........",
59".........", 63".........",
60"....a....", 64"....a....",
61"...aaa...", 65"...aaa...",
62"..aaaaa..", 66"..aaaaa..",
63".aaaaaaa.", 67".aaaaaaa.",
64".........", 68".........",
65"........."}; 69"........."};
66 70
67static const int inputWidgetStyle = QWidget::WStyle_Customize | 71static const int inputWidgetStyle = QWidget::WStyle_Customize |
68 QWidget::WStyle_Tool | 72 QWidget::WStyle_Tool |
69 QWidget::WStyle_StaysOnTop | 73 QWidget::WStyle_StaysOnTop |
70 QWidget::WGroupLeader; 74 QWidget::WGroupLeader;
71 75
72InputMethods::InputMethods( QWidget *parent ) : 76
73 QWidget( parent, "InputMethods", WStyle_Tool | WStyle_Customize ) 77int InputMethod::operator <(const InputMethod& o) const
78{
79 return name() < o.name();
80}
81int InputMethod::operator >(const InputMethod& o) const
82{
83 return name() > o.name();
84}
85int InputMethod::operator <=(const InputMethod& o) const
74{ 86{
75 method = NULL; 87 return name() <= o.name();
88}
89
90
91/*
92 Slightly hacky: We use WStyle_Tool as a flag to say "this widget
93 belongs to the IM system, so clicking it should not cause a reset".
94 */
95class IMToolButton : public QToolButton
96{
97public:
98 IMToolButton::IMToolButton( QWidget *parent ) : QToolButton( parent )
99 { setWFlags( WStyle_Tool ); }
100};
76 101
77 setBackgroundMode ( PaletteBackground );
78 102
103InputMethods::InputMethods( QWidget *parent ) :
104 QWidget( parent, "InputMethods", WStyle_Tool | WStyle_Customize ),
105 mkeyboard(0), imethod(0)
106{
107 setBackgroundMode( PaletteBackground );
79 QHBoxLayout *hbox = new QHBoxLayout( this ); 108 QHBoxLayout *hbox = new QHBoxLayout( this );
80 109
81 kbdButton = new QToolButton( this ); 110 kbdButton = new IMToolButton( this);
82 kbdButton->setFocusPolicy(NoFocus); 111 kbdButton->setFocusPolicy(NoFocus);
83 kbdButton->setToggleButton( TRUE ); 112 kbdButton->setToggleButton( TRUE );
84 kbdButton->setFixedHeight( 17 ); 113 if (parent->sizeHint().height() > 0)
114 kbdButton->setFixedHeight( parent->sizeHint().height() );
85 kbdButton->setFixedWidth( 32 ); 115 kbdButton->setFixedWidth( 32 );
86 kbdButton->setAutoRaise( TRUE ); 116 kbdButton->setAutoRaise( TRUE );
87 kbdButton->setUsesBigPixmap( TRUE ); 117 kbdButton->setUsesBigPixmap( TRUE );
88 hbox->addWidget( kbdButton ); 118 hbox->addWidget( kbdButton );
89 connect( kbdButton, SIGNAL(toggled(bool)), this, SLOT(showKbd(bool)) ); 119 connect( kbdButton, SIGNAL(toggled(bool)), this, SLOT(showKbd(bool)) );
90 120
91 kbdChoice = new QToolButton( this ); 121 kbdChoice = new IMToolButton( this );
92 kbdChoice->setFocusPolicy(NoFocus); 122 kbdChoice->setFocusPolicy(NoFocus);
93 kbdChoice->setPixmap( QPixmap( (const char **)tri_xpm ) ); 123 kbdChoice->setPixmap( QPixmap( (const char **)tri_xpm ) );
94 kbdChoice->setFixedHeight( 17 ); 124 if (parent->sizeHint().height() > 0)
95 kbdChoice->setFixedWidth( 12 ); 125 kbdChoice->setFixedHeight( parent->sizeHint().height() );
126 kbdChoice->setFixedWidth( 13 );
96 kbdChoice->setAutoRaise( TRUE ); 127 kbdChoice->setAutoRaise( TRUE );
97 hbox->addWidget( kbdChoice ); 128 hbox->addWidget( kbdChoice );
98 connect( kbdChoice, SIGNAL(clicked()), this, SLOT(chooseKbd()) ); 129 connect( kbdChoice, SIGNAL(clicked()), this, SLOT(chooseKbd()) );
99 130
100 connect( (QPEApplication*)qApp, SIGNAL(clientMoused()), 131 connect( (QPEApplication*)qApp, SIGNAL(clientMoused()),
101 this, SLOT(resetStates()) ); 132 this, SLOT(resetStates()) );
133
134
135 imButton = new QWidgetStack( this ); // later a widget stack
136 imButton->setFocusPolicy(NoFocus);
137 if (parent->sizeHint().height() > 0)
138 imButton->setFixedHeight( parent->sizeHint().height() );
139 hbox->addWidget(imButton);
140
141 imChoice = new QToolButton( this );
142 imChoice->setFocusPolicy(NoFocus);
143 imChoice->setPixmap( QPixmap( (const char **)tri_xpm ) );
144 if (parent->sizeHint().height() > 0)
145 imChoice->setFixedHeight( parent->sizeHint().height() );
146 imChoice->setFixedWidth( 13 );
147 imChoice->setAutoRaise( TRUE );
148 hbox->addWidget( imChoice );
149 connect( imChoice, SIGNAL(clicked()), this, SLOT(chooseIm()) );
102 150
103 loadInputMethods(); 151 loadInputMethods();
152
153 QCopChannel *channel = new QCopChannel( "QPE/IME", this );
154 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
155 this, SLOT(qcopReceive(const QCString&, const QByteArray&)) );
104} 156}
105 157
106InputMethods::~InputMethods() 158InputMethods::~InputMethods()
107{ 159{
108#ifndef SINGLE_APP 160 Config cfg("qpe");
109 QValueList<InputMethod>::Iterator mit; 161 cfg.setGroup("InputMethod");
110 for ( mit = inputMethodList.begin(); mit != inputMethodList.end(); ++mit ) { 162 if (imethod)
111 (void) (*mit).interface->release(); 163 cfg.writeEntry("im", imethod->name() );
112 (*mit).library->unload(); 164 if (mkeyboard)
113 delete (*mit).library; 165 cfg.writeEntry("current", mkeyboard->name() );
114 } 166
115#endif 167 unloadInputMethods();
116} 168}
117 169
118void InputMethods::hideInputMethod() 170void InputMethods::hideInputMethod()
119{ 171{
120 kbdButton->setOn( FALSE ); 172 kbdButton->setOn( FALSE );
121} 173}
122 174
123void InputMethods::showInputMethod() 175void InputMethods::showInputMethod()
124{ 176{
125 kbdButton->setOn( TRUE ); 177 kbdButton->setOn( TRUE );
126} 178}
127 179
128void InputMethods::showInputMethod(const QString& name) 180void InputMethods::showInputMethod(const QString& name)
129{ 181{
130 int i = 0; 182 int i = 0;
131 QValueList<InputMethod>::Iterator it; 183 QValueList<InputMethod>::Iterator it;
132 InputMethod *im = 0; 184 InputMethod *im = 0;
133 for ( it = inputMethodList.begin(); it != inputMethodList.end(); ++it, i++ ) { 185 for ( it = inputMethodList.begin(); it != inputMethodList.end(); ++it, i++ ) {
134 if ( (*it).interface->name() == name ) { 186 QString lname = (*it).libName.mid((*it).libName.findRev('/') + 1);
135 im = &(*it); 187 if ( (*it).name() == name || lname == name ) {
136 break; 188 im = &(*it);
137 } 189 break;
190 }
138 } 191 }
139 if ( im ) 192 if ( im )
140 chooseMethod(im); 193 chooseKeyboard(im);
141} 194}
142 195
143void InputMethods::resetStates() 196void InputMethods::resetStates()
144{ 197{
145 if ( method ) 198 if ( mkeyboard && !mkeyboard->newIM )
146 method->interface->resetState(); 199 mkeyboard->interface->resetState();
147} 200}
148 201
149QRect InputMethods::inputRect() const 202QRect InputMethods::inputRect() const
150{ 203{
151 if ( !method || !method->widget->isVisible() ) 204 if ( !mkeyboard || !mkeyboard->widget || !mkeyboard->widget->isVisible() )
152 return QRect(); 205 return QRect();
153 else 206 else
154 return method->widget->geometry(); 207 return mkeyboard->widget->geometry();
208}
209
210void InputMethods::unloadInputMethods()
211{
212 unloadMethod( inputMethodList );
213 unloadMethod( inputModifierList );
214 inputMethodList.clear();
215 inputModifierList.clear();
216
217}
218
219void InputMethods::unloadMethod( QValueList<InputMethod>& list ) {
220 QValueList<InputMethod>::Iterator it;
221
222 for (it = list.begin(); it != list.end(); ++it )
223 (*it).releaseInterface();
224
225}
226
227
228QStringList InputMethods::plugins()const {
229 QString path = QPEApplication::qpeDir() + "/plugins/inputmethods";
230 QDir dir( path, "lib*.so" );
231 return dir.entryList();
232}
233
234void InputMethods::installTranslator( const QString& type ) {
235 QStringList langs = Global::languageList();
236 QStringList::ConstIterator lit;
237 for ( lit= langs.begin(); lit!=langs.end(); ++lit) {
238 QString lang = *lit;
239 QTranslator * trans = new QTranslator(qApp);
240
241 QString tfn = QPEApplication::qpeDir()+"/i18n/"+lang+"/"+type+".qm";
242
243 if ( trans->load( tfn ))
244 qApp->installTranslator( trans );
245 else
246 delete trans;
247 }
248}
249
250void InputMethods::setPreferedHandlers() {
251 Config cfg("qpe");
252 cfg.setGroup("InputMethod");
253 QString current = cfg.readEntry("current");
254 QString im = cfg.readEntry("im");
255
256 QValueList<InputMethod>::Iterator it;
257 if (!inputModifierList.isEmpty() && !im.isEmpty() ) {
258 for (it = inputModifierList.begin(); it != inputModifierList.end(); ++it )
259 if ( (*it).name() == im ) {
260 imethod = &(*it); break;
261 }
262
263 }
264 if (!inputMethodList.isEmpty() && !current.isEmpty() ) {
265 for (it = inputMethodList.begin(); it != inputMethodList.end(); ++it )
266 if ( (*it).name() == current ) {
267 qWarning("preferred keyboard is %s", current.latin1() );
268 mkeyboard = &(*it);
269 kbdButton->setPixmap( *mkeyboard->icon() );
270 break;
271 }
272 }
273
155} 274}
156 275
157void InputMethods::loadInputMethods() 276void InputMethods::loadInputMethods()
158{ 277{
159#ifndef SINGLE_APP 278#ifndef QT_NO_COMPONENT
160 hideInputMethod(); 279 hideInputMethod();
161 method = 0; 280 mkeyboard = 0;
162 281
163 QValueList<InputMethod>::Iterator mit; 282 unloadInputMethods();
164 for ( mit = inputMethodList.begin(); mit != inputMethodList.end(); ++mit ) {
165 (*mit).interface->release();
166 (*mit).library->unload();
167 delete (*mit).library;
168 }
169 inputMethodList.clear();
170 283
171 QString path = QPEApplication::qpeDir() + "/plugins/inputmethods"; 284 QString path = QPEApplication::qpeDir() + "/plugins/inputmethods";
172 QDir dir( path, "lib*.so" ); 285 QStringList list = plugins();
173 QStringList list = dir.entryList();
174 QStringList::Iterator it; 286 QStringList::Iterator it;
175 for ( it = list.begin(); it != list.end(); ++it ) { 287 for ( it = list.begin(); it != list.end(); ++it ) {
176 InputMethodInterface *iface = 0; 288 InputMethodInterface *iface = 0;
177 QLibrary *lib = new QLibrary( path + "/" + *it ); 289 ExtInputMethodInterface *eface = 0;
178 if ( lib->queryInterface( IID_InputMethod, (QUnknownInterface**)&iface ) == QS_OK ) { 290 QLibrary *lib = new QLibrary( path + "/" + *it );
179 InputMethod input; 291
180 input.library = lib; 292 if ( lib->queryInterface( IID_InputMethod, (QUnknownInterface**)&iface ) == QS_OK ) {
181 input.interface = iface; 293 InputMethod input;
182 input.widget = input.interface->inputMethod( 0, inputWidgetStyle ); 294 input.newIM = FALSE;
183 input.interface->onKeyPress( this, SLOT(sendKey(ushort,ushort,ushort,bool,bool)) ); 295 input.library = lib;
184 inputMethodList.append( input ); 296 input.libName = *it;
185 297 input.interface = iface;
186 QString type = (*it).left( (*it).find(".") ); 298 input.widget = input.interface->inputMethod( 0, inputWidgetStyle );
187 QStringList langs = Global::languageList(); 299 input.interface->onKeyPress( this, SLOT(sendKey(ushort,ushort,ushort,bool,bool)) );
188 for (QStringList::ConstIterator lit = langs.begin(); lit!=langs.end(); ++lit) { 300 inputMethodList.append( input );
189 QString lang = *lit; 301 } else if ( lib->queryInterface( IID_ExtInputMethod, (QUnknownInterface**)&eface ) == QS_OK ) {
190 QTranslator * trans = new QTranslator(qApp); 302 InputMethod input;
191 QString tfn = QPEApplication::qpeDir()+"/i18n/"+lang+"/"+type+".qm"; 303 input.newIM = TRUE;
192 if ( trans->load( tfn )) 304 input.library = lib;
193 qApp->installTranslator( trans ); 305 input.libName = *it;
194 else 306 input.extInterface = eface;
195 delete trans; 307 input.widget = input.extInterface->keyboardWidget( 0, inputWidgetStyle );
196 } 308 // may be either a simple, or advanced.
197 } else { 309 if (input.widget) {
198 delete lib; 310 //qDebug("its a keyboard");
199 } 311 inputMethodList.append( input );
200 } 312 } else {
201#else 313 //qDebug("its a real im");
202 InputMethod input; 314 input.widget = input.extInterface->statusWidget( 0, 0 );
203 input.interface = new HandwritingImpl(); 315 if (input.widget) {
204 input.widget = input.interface->inputMethod( 0, inputWidgetStyle ); 316 //qDebug("blah");
205 input.interface->onKeyPress( this, SLOT(sendKey(ushort,ushort,ushort,bool,bool)) ); 317 inputModifierList.append( input );
206 inputMethodList.append( input ); 318 imButton->addWidget(input.widget, inputModifierList.count());
207 input.interface = new KeyboardImpl(); 319 }
208 input.widget = input.interface->inputMethod( 0, inputWidgetStyle ); 320 }
209 input.interface->onKeyPress( this, SLOT(sendKey(ushort,ushort,ushort,bool,bool)) ); 321 }else{
210 inputMethodList.append( input ); 322 delete lib;
211 input.interface = new PickboardImpl(); 323 lib = 0l;
212 input.widget = input.interface->inputMethod( 0, inputWidgetStyle );
213 input.interface->onKeyPress( this, SLOT(sendKey(ushort,ushort,ushort,bool,bool)) );
214 inputMethodList.append( input );
215#endif
216 if ( !inputMethodList.isEmpty() ) {
217 method = &inputMethodList[0];
218 Config cfg("qpe");
219 cfg.setGroup("InputMethod");
220 QString curMethod = cfg.readEntry("current","");
221 int i = 0;
222 QValueList<InputMethod>::Iterator it;
223 for ( it = inputMethodList.begin(); it != inputMethodList.end(); ++it, i++ ) {
224 if((*it).interface->name() == curMethod) {
225 method = &inputMethodList[i];
226 }
227 } 324 }
228 kbdButton->setPixmap( *method->interface->icon() ); 325 installTranslator( (*it).left( (*it).find(".") ) );
229 } 326 }
230 if ( !inputMethodList.isEmpty() ) 327 qHeapSort( inputMethodList );
231 kbdButton->show(); 328#endif /* killed BUILT in cause they would not compile */
329
330 QWSServer::setCurrentInputMethod( 0 );
331
332 /* set the prefered IM + handler */
333 setPreferedHandlers();
334 if ( !inputModifierList.isEmpty() ) {
335 if (!imethod)
336 imethod = &inputModifierList[0];
337 imButton->raiseWidget(imethod->widget);
338 QWSServer::setCurrentInputMethod( imethod->extInterface->inputMethod() );
339 } else {
340 imethod = 0;
341 }
342
343 // we need to update keyboards afterwards, as some of them may not be compatible with
344 // the current input method
345 updateKeyboards(imethod);
346
347 if ( !inputModifierList.isEmpty() )
348 imButton->show();
232 else 349 else
233 kbdButton->hide(); 350 imButton->hide();
234 if ( inputMethodList.count() > 1 ) 351
235 kbdChoice->show(); 352 if ( inputModifierList.count() > 1 )
353 imChoice->show();
236 else 354 else
237 kbdChoice->hide(); 355 imChoice->hide();
238} 356}
239 357
240void InputMethods::chooseKbd() 358void InputMethods::chooseKbd()
241{ 359{
242 QPopupMenu pop( this ); 360 QPopupMenu pop( this );
361 pop.setFocusPolicy( NoFocus ); //don't reset IM
362
363 QString imname;
364 if (imethod)
365 imname = imethod->libName.mid(imethod->libName.findRev('/') + 1);
243 366
244 int i = 0; 367 int i = 0;
368 int firstDepKbd = 0;
369
245 QValueList<InputMethod>::Iterator it; 370 QValueList<InputMethod>::Iterator it;
246 for ( it = inputMethodList.begin(); it != inputMethodList.end(); ++it, i++ ) { 371 for ( it = inputMethodList.begin(); it != inputMethodList.end(); ++it, i++ ) {
247 pop.insertItem( (*it).interface->name(), i ); 372 // add empty new items, all old items.
248 if ( method == &(*it) ) 373 if (!(*it).newIM || (*it).extInterface->compatible().count() == 0 ) {
249 pop.setItemChecked( i, TRUE ); 374 pop.insertItem( (*it).name(), i, firstDepKbd);
375 if ( mkeyboard == &(*it) )
376 pop.setItemChecked( i, TRUE );
377
378 firstDepKbd++;
379 } else if ( (*it).extInterface->compatible().contains(imname)) {
380 // check if we need to insert a sep.
381 if (firstDepKbd == i)
382 pop.insertSeparator();
383 pop.insertItem( (*it).name(), i, -1);
384 if ( mkeyboard == &(*it) )
385 pop.setItemChecked( i, TRUE );
386 }
250 } 387 }
251 388
252 QPoint pt = mapToGlobal(kbdChoice->geometry().topRight()); 389 QPoint pt = mapToGlobal(kbdChoice->geometry().topRight());
253 QSize s = pop.sizeHint(); 390 QSize s = pop.sizeHint();
254 pt.ry() -= s.height(); 391 pt.ry() -= s.height();
255 pt.rx() -= s.width(); 392 pt.rx() -= s.width();
256 i = pop.exec( pt ); 393 i = pop.exec( pt );
257 if ( i == -1 ) 394 if ( i == -1 )
258 return; 395 return;
259 InputMethod *im = &inputMethodList[i]; 396 InputMethod *im = &inputMethodList[i];
397 chooseKeyboard(im);
398}
399
400void InputMethods::chooseIm()
401{
402 QPopupMenu pop( this );
403
404 int i = 0;
405 QValueList<InputMethod>::Iterator it;
406 for ( it = inputModifierList.begin(); it != inputModifierList.end(); ++it, i++ ) {
407 pop.insertItem( (*it).name(), i );
408 if ( imethod == &(*it) )
409 pop.setItemChecked( i, TRUE );
410 }
411
412 QPoint pt = mapToGlobal(imChoice->geometry().topRight());
413 QSize s = pop.sizeHint();
414 pt.ry() -= s.height();
415 pt.rx() -= s.width();
416 i = pop.exec( pt );
417 if ( i == -1 )
418 return;
419 InputMethod *im = &inputModifierList[i];
420
260 chooseMethod(im); 421 chooseMethod(im);
261} 422}
262 423
424void InputMethods::chooseKeyboard(InputMethod* im)
425{
426 if ( im != mkeyboard ) {
427 if ( mkeyboard && mkeyboard->widget->isVisible() )
428 mkeyboard->widget->hide();
429 mkeyboard = im;
430 kbdButton->setPixmap( *mkeyboard->icon() );
431 }
432 if ( !kbdButton->isOn() )
433 kbdButton->setOn( TRUE );
434 else
435 showKbd( TRUE );
436}
437
438static bool keyboardCompatible(InputMethod *keyb, const QString &imname )
439{
440 if ( !keyb || !keyb->newIM || !keyb->extInterface->compatible().count() )
441 return TRUE;
442
443 if ( keyb->extInterface->compatible().contains(imname) )
444 return TRUE;
445
446 return FALSE;
447}
448
449// Updates the display of the soft keyboards available to the current input method
450void InputMethods::updateKeyboards(InputMethod *im )
451{
452 uint count;
453
454 if ( im ) {
455 QString imname = im->libName.mid(im->libName.findRev('/') + 1);
456
457 if ( mkeyboard && !keyboardCompatible(mkeyboard, imname) ) {
458 kbdButton->setOn( FALSE );
459 showKbd( FALSE );
460 mkeyboard = 0;
461 }
462
463 count = 0;
464
465 QValueList<InputMethod>::Iterator it;
466 for ( it = inputMethodList.begin(); it != inputMethodList.end(); ++it ) {
467 if ( keyboardCompatible( &(*it), imname ) ) {
468 if ( !mkeyboard ) {
469 mkeyboard = &(*it);
470 kbdButton->setPixmap( *mkeyboard->icon() );
471 }
472
473 count++;
474 }
475 }
476 } else {
477 count = inputMethodList.count();
478 if ( count && !mkeyboard ) {
479 mkeyboard = &inputMethodList[0];
480 kbdButton->setPixmap( *mkeyboard->icon() );
481 } else if (!count){
482 mkeyboard = 0; //might be redundant
483 }
484 }
485
486 if ( count > 1 )
487 kbdChoice->show();
488 else
489 kbdChoice->hide();
490
491 if ( count )
492 kbdButton->show();
493 else
494 kbdButton->hide();
495}
496
263void InputMethods::chooseMethod(InputMethod* im) 497void InputMethods::chooseMethod(InputMethod* im)
264{ 498{
265 if ( im != method ) { 499 if ( im != imethod ) {
266 if ( method && method->widget->isVisible() ) 500 updateKeyboards( im );
267 method->widget->hide(); 501
268 method = im;
269 Config cfg("qpe"); 502 Config cfg("qpe");
270 cfg.setGroup("InputMethod"); 503 cfg.setGroup("InputMethod");
271 cfg.writeEntry("current", method->interface->name()); 504 if (im )
272 kbdButton->setPixmap( *method->interface->icon() ); 505 cfg.writeEntry("im", im->name() );
506 if (mkeyboard)
507 cfg.writeEntry("current", mkeyboard->name() );
508
509 QWSServer::setCurrentInputMethod( 0 );
510 imethod = im;
511 if ( imethod && imethod->newIM )
512 QWSServer::setCurrentInputMethod( imethod->extInterface->inputMethod() );
513 else
514 QWSServer::setCurrentInputMethod( 0 );
515
516 if ( im )
517 imButton->raiseWidget(im->widget);
518 else
519 imButton->hide(); //### good UI? make sure it is shown again!
273 } 520 }
274 if ( !kbdButton->isOn() ) 521}
275 kbdButton->setOn( TRUE ); 522
276 else 523void InputMethods::qcopReceive( const QCString &msg, const QByteArray &data )
277 showKbd( TRUE ); 524{
525 if ( imethod && imethod->newIM )
526 imethod->extInterface->qcopReceive( msg, data );
278} 527}
279 528
280 529
281void InputMethods::showKbd( bool on ) 530void InputMethods::showKbd( bool on )
282{ 531{
283 if ( !method ) 532 if ( !mkeyboard )
284 return; 533 return;
285 534
286 if ( on ) { 535 if ( on ) {
287 method->interface->resetState(); 536 mkeyboard->resetState();
288 // HACK... Make the texteditor fit with all input methods 537 // HACK... Make the texteditor fit with all input methods
289 // Input methods should also never use more than about 40% of the screen 538 // Input methods should also never use more than about 40% of the screen
290 int height = QMIN( method->widget->sizeHint().height(), 134 ); 539 int height = QMIN( mkeyboard->widget->sizeHint().height(), 134 );
291 #ifdef QT_QWS_SIMPAD 540 mkeyboard->widget->resize( qApp->desktop()->width(), height );
292 method->widget->resize( qApp->desktop()->width() / 2, height ); // make it half the width on the SIMpad 541 mkeyboard->widget->move( 0, mapToGlobal( QPoint() ).y() - height );
293 #else 542 mkeyboard->widget->show();
294 method->widget->resize( qApp->desktop()->width(), height );
295 #endif
296 method->widget->move( 0, mapToGlobal( QPoint() ).y() - height );
297 method->widget->show();
298 } else { 543 } else {
299 method->widget->hide(); 544 mkeyboard->widget->hide();
300 } 545 }
301 546
302 emit inputToggled( on ); 547 emit inputToggled( on );
303} 548}
304 549
305bool InputMethods::shown() const 550bool InputMethods::shown() const
306{ 551{
307 return method && method->widget->isVisible(); 552 return mkeyboard && mkeyboard->widget->isVisible();
308} 553}
309 554
310QString InputMethods::currentShown() const 555QString InputMethods::currentShown() const
311{ 556{
312 return method && method->widget->isVisible() 557 return mkeyboard && mkeyboard->widget->isVisible()
313 ? method->interface->name() : QString::null; 558 ? mkeyboard->name() : QString::null;
314} 559}
315 560
316void InputMethods::sendKey( ushort unicode, ushort scancode, ushort mod, bool press, bool repeat ) 561void InputMethods::sendKey( ushort unicode, ushort scancode, ushort mod, bool press, bool repeat )
317{ 562{
318#if defined(Q_WS_QWS) 563#if defined(Q_WS_QWS)
319 QWSServer::sendKeyEvent( unicode, scancode, mod, press, repeat ); 564 QWSServer::sendKeyEvent( unicode, scancode, mod, press, repeat );
320#endif 565#endif
321} 566}
diff --git a/core/launcher/inputmethods.h b/core/launcher/inputmethods.h
index 286a818..93b69de 100644
--- a/core/launcher/inputmethods.h
+++ b/core/launcher/inputmethods.h
@@ -1,76 +1,110 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#ifndef __INPUT_METHODS_H__ 21#ifndef __INPUT_METHODS_H__
22#define __INPUT_METHODS_H__ 22#define __INPUT_METHODS_H__
23 23
24 24#include <qtopia/qlibrary.h>
25#include <qpe/inputmethodinterface.h> 25#include <qtopia/inputmethodinterface.h>
26 26
27#include <qwidget.h> 27#include <qwidget.h>
28#include <qvaluelist.h> 28#include <qvaluelist.h>
29 29
30class QToolButton; 30class QToolButton;
31class QLibrary; 31class QWidgetStack;
32 32
33struct InputMethod 33struct InputMethod
34{ 34{
35#ifndef QT_NO_COMPONENT 35#ifndef QT_NO_COMPONENT
36 QLibrary *library; 36 QLibrary *library;
37#endif 37#endif
38 QWidget *widget; 38 QWidget *widget;
39 InputMethodInterface *interface; 39 QString libName;
40 bool newIM;
41 union {
42 InputMethodInterface *interface;
43 ExtInputMethodInterface *extInterface;
44 };
45
46 inline void releaseInterface() {
47 newIM ? (void)extInterface->release() : (void)interface->release();
48 library->unload();
49 delete library; library = 0l;
50 }
51 inline QString name() const { return newIM ? extInterface->name() : interface->name(); }
52 inline QPixmap *icon() const { return newIM ? extInterface->icon() : interface->icon(); }
53 inline QUnknownInterface *iface() { return newIM ? (QUnknownInterface *)extInterface : (QUnknownInterface *)interface; }
54 inline void resetState() { if ( !newIM ) interface->resetState(); }
55
56 int operator <(const InputMethod& o) const;
57 int operator >(const InputMethod& o) const;
58 int operator <=(const InputMethod& o) const;
40}; 59};
41 60
42class InputMethods : public QWidget 61class InputMethods : public QWidget
43{ 62{
44 Q_OBJECT 63 Q_OBJECT
45public: 64public:
46 InputMethods( QWidget * ); 65 InputMethods( QWidget * );
47 ~InputMethods(); 66 ~InputMethods();
48 67
49 QRect inputRect() const; 68 QRect inputRect() const;
50 bool shown() const; 69 bool shown() const;
51 QString currentShown() const; // name of interface 70 QString currentShown() const; // name of interface
52 void showInputMethod(const QString& id); 71 void showInputMethod(const QString& id);
53 void showInputMethod(); 72 void showInputMethod();
54 void hideInputMethod(); 73 void hideInputMethod();
74 void unloadInputMethods();
55 void loadInputMethods(); 75 void loadInputMethods();
56 76
57signals: 77signals:
58 void inputToggled( bool on ); 78 void inputToggled( bool on );
59 79
60private slots: 80private slots:
61 void chooseKbd(); 81 void chooseKbd();
82 void chooseIm();
62 void showKbd( bool ); 83 void showKbd( bool );
63 void resetStates(); 84 void resetStates();
64 void sendKey( ushort unicode, ushort scancode, ushort modifiers, bool, bool ); 85 void sendKey( ushort unicode, ushort scancode, ushort modifiers, bool, bool );
86 void qcopReceive( const QCString &msg, const QByteArray &data );
65 87
66private: 88private:
89 void setPreferedHandlers();
90 /*static */QStringList plugins()const;
91 /*static */void installTranslator( const QString& );
92 void unloadMethod( QValueList<InputMethod>& );
67 void chooseMethod(InputMethod* im); 93 void chooseMethod(InputMethod* im);
94 void chooseKeyboard(InputMethod* im);
95 void updateKeyboards(InputMethod *im);
96
97private:
68 QToolButton *kbdButton; 98 QToolButton *kbdButton;
69 QToolButton *kbdChoice; 99 QToolButton *kbdChoice;
70 InputMethod *method; 100 QWidgetStack *imButton; // later will be widget stack
101 QToolButton *imChoice;
102 InputMethod *mkeyboard;
103 InputMethod *imethod;
71 QValueList<InputMethod> inputMethodList; 104 QValueList<InputMethod> inputMethodList;
105 QValueList<InputMethod> inputModifierList;
72}; 106};
73 107
74 108
75#endif // __INPUT_METHODS_H__ 109#endif // __INPUT_METHODS_H__
76 110