Diffstat (limited to 'inputmethods/handwriting/qimpensetup.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | inputmethods/handwriting/qimpensetup.cpp | 656 |
1 files changed, 656 insertions, 0 deletions
diff --git a/inputmethods/handwriting/qimpensetup.cpp b/inputmethods/handwriting/qimpensetup.cpp new file mode 100644 index 0000000..a6ae3a8 --- a/dev/null +++ b/inputmethods/handwriting/qimpensetup.cpp @@ -0,0 +1,656 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "qimpenwidget.h" +#include "qimpenprefbase.h" +#include "qimpensetup.h" + +#include <qpe/qpeapplication.h> +#include <qpe/config.h> + +#include <qcombobox.h> +#include <qlistbox.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qlayout.h> +#include <qpixmap.h> +#include <qbuttongroup.h> +#include <qslider.h> +#include <qtabwidget.h> +#include <qdir.h> +#include <qmessagebox.h> + + +/* XPM */ +static const char * const left_xpm[] = { +"16 16 2 1", +" c None", +". c #000000", +" ", +" ", +" ", +" . ", +" .. ", +" ... ", +" .... ", +" ..... ", +" ...... ", +" ..... ", +" .... ", +" ... ", +" .. ", +" . ", +" ", +" "}; + + +/* XPM */ +static const char * const right_xpm[] = { +"16 16 2 1", +" c None", +". c #000000", +" ", +" ", +" ", +" . ", +" .. ", +" ... ", +" .... ", +" ..... ", +" ...... ", +" ..... ", +" .... ", +" ... ", +" .. ", +" . ", +" ", +" "}; + + + +QIMPenSetup::QIMPenSetup( QIMPenProfile *p, QWidget *parent, + const char *name, bool modal, int WFlags ) + : QDialog( parent, name, modal, WFlags ), profileCombo(0), profile(p) +{ + setCaption( tr("Setup Handwriting Input") ); + + QVBoxLayout *vb = new QVBoxLayout( this ); + +#if 0 + profileList.setAutoDelete( true ); + QHBoxLayout *hb = new QHBoxLayout( vb ); + hb->setMargin( 6 ); + QLabel *l = new QLabel( tr("Character Profile:"), this ); + hb->addWidget( l ); + profileCombo = new QComboBox( this ); + connect( profileCombo, SIGNAL(activated(const QString &)), + this, SLOT(selectProfile(const QString &)) ); + hb->addWidget( profileCombo ); + loadProfiles(); +#else + profileList.append( profile ); +#endif + + QTabWidget *tw = new QTabWidget( this ); + vb->addWidget( tw ); + + pref = new QIMPenPrefBase( this ); + tw->addTab( pref, tr("Preferences") ); + + pref->inputStyle->setExclusive( TRUE ); + + style = profile->style() == QIMPenProfile::ToggleCases ? 1 : 0; + pref->inputStyle->setButton( style ); + connect( pref->inputStyle, SIGNAL(clicked(int)), + this, SLOT(styleClicked(int)) ); + pref->inputStyle->setEnabled( profile->canSelectStyle() ); + + multiTimeout = profile->multiStrokeTimeout(); + pref->multiStrokeSlider->setValue( multiTimeout ); + multiTimeoutChanged( multiTimeout ); + connect( pref->multiStrokeSlider, SIGNAL(valueChanged(int)), + this, SLOT(multiTimeoutChanged(int)) ); + + edit = new QIMPenEdit( p, tw ); + tw->addTab( edit, tr("Customize") ); +} + +void QIMPenSetup::loadProfiles() +{ + QString path = QPEApplication::qpeDir() + "etc/qimpen"; + QDir dir( path, "*.conf" ); + QStringList list = dir.entryList(); + QStringList::Iterator it; + for ( it = list.begin(); it != list.end(); ++it ) { + QIMPenProfile *p = new QIMPenProfile( path + "/" + *it ); + profileList.append( p ); + profileCombo->insertItem( p->name() ); + if ( p->name() == profile->name() ) { + profileCombo->setCurrentItem( profileCombo->count()-1 ); + profile = p; + } + } +} + +void QIMPenSetup::styleClicked( int id ) +{ + style = id; +} + +void QIMPenSetup::multiTimeoutChanged( int v ) +{ + multiTimeout = v; + pref->multiStrokeLabel->setText( tr("%1 ms").arg(v) ); +} + +void QIMPenSetup::selectProfile( const QString &p ) +{ + if ( p == profile->name() ) + return; + + profile->setStyle( style ? QIMPenProfile::ToggleCases : QIMPenProfile::BothCases ); + profile->setMultiStrokeTimeout( multiTimeout ); + + for ( int i = 0; i < (int)profileList.count(); i++ ) { + if ( profileList.at(i)->name() == p ) { + profile = profileList.at(i); + style = profile->style() == QIMPenProfile::ToggleCases ? 1 : 0; + pref->inputStyle->setButton( style ); + pref->inputStyle->setEnabled( profile->canSelectStyle() ); + multiTimeout = profile->multiStrokeTimeout(); + pref->multiStrokeSlider->setValue( multiTimeout ); + multiTimeoutChanged( multiTimeout ); + edit->setProfile( profile ); + break; + } + } +} + +void QIMPenSetup::accept() +{ + profile->setStyle( style ? QIMPenProfile::ToggleCases : QIMPenProfile::BothCases ); + profile->setMultiStrokeTimeout( multiTimeout ); + // Save current profile + if ( profileCombo ) { + Config config( "handwriting" ); + config.setGroup( "Settings" ); + config.writeEntry( "Profile", profileCombo->currentText() ); + } + // Save charsets + bool ok = TRUE; + for ( int i = 0; i < (int)profileList.count(); i++ ) { + QIMPenProfile *prof = profileList.at(i); + QIMPenCharSetIterator it(prof->charSets()); + for ( ; it.current(); ++it ) { + if ( !(it.current()->save( QIMPenCharSet::User )) ) { + ok = FALSE; + break; + } + } + } + if ( !ok ) { + if ( QMessageBox::critical( 0, tr( "Out of space" ), + tr("Unable to save information.\n" + "Free up some space\n" + "and try again.\n" + "\nQuit anyway?"), + QMessageBox::Yes|QMessageBox::Escape, + QMessageBox::No|QMessageBox::Default ) + != QMessageBox::No ) { + QDialog::accept(); + } + } else { + QDialog::accept(); + } +} + +//--------------------------------------------------------------------------- + +QIMPenInputCharDlg::QIMPenInputCharDlg( QWidget *parent, const char *name, + bool modal, int WFlags) + : QDialog( parent, name, modal, WFlags ) +{ + setCaption( tr("Enter new character") ); + uni = 0; + + QVBoxLayout *vb = new QVBoxLayout( this, 10 ); + + QHBoxLayout *hb = new QHBoxLayout(); + vb->addLayout( hb ); + + QLabel *label = new QLabel( "Character:", this ); + hb->addWidget( label ); + + QComboBox *cb = new QComboBox( TRUE, this ); + connect( cb, SIGNAL(activated(int)), SLOT(setSpecial(int)) ); + connect( cb, SIGNAL(textChanged(const QString &)), + SLOT(setCharacter(const QString &)) ); + addSpecial( cb ); + cb->setEditText( "" ); + hb->addWidget( cb ); + + hb = new QHBoxLayout(); + vb->addLayout( hb ); + + QPushButton *pb = new QPushButton( "OK", this ); + connect( pb, SIGNAL(clicked()), SLOT(accept())); + hb->addWidget( pb ); + pb = new QPushButton( "Cancel", this ); + connect( pb, SIGNAL(clicked()), SLOT(reject())); + hb->addWidget( pb ); + + cb->setFocus(); +} + +void QIMPenInputCharDlg::addSpecial( QComboBox *cb ) +{ + int i = 0; + while ( qimpen_specialKeys[i].code != Key_unknown ) { + cb->insertItem( qimpen_specialKeys[i].name ); + i++; + } +} + +void QIMPenInputCharDlg::setSpecial( int sp ) +{ + uni = qimpen_specialKeys[sp].code << 16; +} + +void QIMPenInputCharDlg::setCharacter( const QString &string ) +{ + uni = string[0].unicode(); +} + +//--------------------------------------------------------------------------- + +class CharListItem : public QListBoxText +{ +public: + CharListItem( const QString &text, uint c ) + : QListBoxText( text ) + { + _code = c; + } + + uint code() const { return _code; } + +protected: + uint _code; +}; + +/*! + \class QIMPenEdit qimpensetup.h + + Class to allow users to input totally useless character definitions + which could match any number of the default set. +*/ + +QIMPenEdit::QIMPenEdit( QIMPenProfile *p, QWidget *parent, + const char *name ) + : QWidget( parent, name ), profile(p) +{ + currentChar = 0; + currentCode = 0; + inputChar = new QIMPenChar(); + + QVBoxLayout *tvb = new QVBoxLayout( this, 5 ); + + QGridLayout *gl = new QGridLayout( tvb, 4, 2 ); + gl->setRowStretch( 1, 1 ); + gl->addRowSpacing( 2, 35 ); + gl->addRowSpacing( 3, 35 ); + + charSetCombo = new QComboBox( this ); + gl->addMultiCellWidget( charSetCombo, 0, 0, 0, 1 ); + connect( charSetCombo, SIGNAL(activated(int)), SLOT(selectCharSet(int))); + QIMPenCharSetIterator it( profile->charSets() ); + for ( ; it.current(); ++it ) { + charSetCombo->insertItem( it.current()->description() ); + } + + charList = new QListBox( this ); + charList->setMinimumHeight( charList->sizeHint().height() ); + connect( charList, SIGNAL(highlighted(int)), SLOT(selectChar(int)) ); + gl->addWidget( charList, 1, 0 ); + + pw = new QIMPenWidget( this ); + pw->setFixedHeight( 75 ); + gl->addMultiCellWidget( pw, 2, 3, 0, 0 ); + connect( pw, SIGNAL(stroke(QIMPenStroke *)), + SLOT(newStroke(QIMPenStroke *)) ); + + QVBoxLayout *vb = new QVBoxLayout(); + gl->addLayout( vb, 1, 1 ); + newBtn = new QPushButton( tr("New..."), this ); + connect( newBtn, SIGNAL(clicked()), SLOT(addNewChar()) ); + vb->addWidget( newBtn ); + + addBtn = new QPushButton( tr("Add"), this ); + connect( addBtn, SIGNAL(clicked()), SLOT(addChar()) ); + vb->addWidget( addBtn ); + + removeBtn = new QPushButton( tr("Remove"), this ); + connect( removeBtn, SIGNAL(clicked()), SLOT(removeChar()) ); + vb->addWidget( removeBtn ); + + QPushButton *pb = new QPushButton( tr("Default"), this ); + connect( pb, SIGNAL(clicked()), SLOT(defaultChars()) ); + vb->addWidget( pb ); + + QHBoxLayout *hb = new QHBoxLayout(); + gl->addLayout( hb, 2, 1 ); + prevBtn = new QPushButton( this ); + prevBtn->setPixmap( QPixmap( (const char **)left_xpm ) ); + connect( prevBtn, SIGNAL(clicked()), SLOT(prevChar())); + hb->addWidget( prevBtn ); + + nextBtn = new QPushButton( this ); + nextBtn->setPixmap( QPixmap( (const char **)right_xpm ) ); + connect( nextBtn, SIGNAL(clicked()), SLOT(nextChar())); + hb->addWidget( nextBtn ); + + pb = new QPushButton( tr("Clear"), this ); + connect( pb, SIGNAL(clicked()), SLOT(clearChar()) ); + gl->addWidget( pb, 3, 1 ); + + //-- +#if !defined(Q_WS_QWS) + hb = new QHBoxLayout( tvb ); + pb = new QPushButton( "OK", this ); + connect( pb, SIGNAL(clicked()), SLOT(accept()) ); + hb->addWidget( pb ); + + pb = new QPushButton( "Cancel", this ); + connect( pb, SIGNAL(clicked()), SLOT(reject()) ); + hb->addWidget( pb ); +#endif + selectCharSet( 0 ); + charList->setFocus(); + + resize( minimumSize() ); + enableButtons(); +} + +void QIMPenEdit::setProfile( QIMPenProfile *p ) +{ + profile = p; + charSetCombo->clear(); + QIMPenCharSetIterator it( profile->charSets() ); + for ( ; it.current(); ++it ) { + charSetCombo->insertItem( it.current()->description() ); + } + selectCharSet( 0 ); + charList->setFocus(); + enableButtons(); +} + +void QIMPenEdit::selectCharSet( QIMPenCharSet *c ) +{ + int i = 0; + QIMPenCharSetIterator it( profile->charSets() ); + for ( ; it.current(); ++it, i++ ) { + if ( it.current() == c ) { + charSetCombo->setCurrentItem( i ); + selectCharSet( i ); + } + } +} + + +/*! + Fill the character list box with the characters. Duplicates are not + inserted. +*/ +void QIMPenEdit::fillCharList() +{ + charList->clear(); + QIMPenCharIterator it( currentSet->characters() ); + CharListItem *li = 0; + for ( ; it.current(); ++it ) { + uint ch = it.current()->character(); + QString n = it.current()->name(); + if ( !n.isEmpty() ) + li = new CharListItem( n, ch ); + if ( li ) { + CharListItem *i = (CharListItem *)charList->findItem( li->text() ); + if ( !i || i->code() != ch ) { + charList->insertItem( li ); + } else { + delete li; + li = 0; + } + } + } + currentChar = 0; +} + +void QIMPenEdit::enableButtons() +{ + bool add = !inputChar->isEmpty(); + newBtn->setEnabled( add ); + addBtn->setEnabled( add ); + removeBtn->setEnabled( currentChar ); +} + +/*! + Find the previous character with the same code as the current one. + returns 0 if there is no previous character. +*/ +QIMPenChar *QIMPenEdit::findPrev() +{ + if ( !currentChar ) + return 0; + QIMPenCharIterator it( currentSet->characters() ); + bool found = FALSE; + for ( it.toLast(); it.current(); --it ) { + if ( !found && it.current() == currentChar ) + found = TRUE; + else if ( found && it.current()->character() == currentCode && + !it.current()->testFlag( QIMPenChar::Deleted ) ) { + return it.current(); + } + } + + return 0; +} + +/*! + Find the next character with the same code as the current one. + returns 0 if there is no next character. +*/ +QIMPenChar *QIMPenEdit::findNext() +{ + if ( !currentChar ) + return 0; + QIMPenCharIterator it( currentSet->characters() ); + bool found = FALSE; + for ( ; it.current(); ++it ) { + if ( !found && it.current() == currentChar ) + found = TRUE; + else if ( found && it.current()->character() == currentCode && + !it.current()->testFlag( QIMPenChar::Deleted ) ) { + return it.current(); + } + } + + return 0; +} + +void QIMPenEdit::setCurrentChar( QIMPenChar *pc ) +{ + currentChar = pc; + pw->showCharacter( currentChar ); + if ( currentChar ) { + prevBtn->setEnabled( findPrev() != 0 ); + nextBtn->setEnabled( findNext() != 0 ); + } +} + +void QIMPenEdit::prevChar() +{ + QIMPenChar *pc = findPrev(); + if ( pc ) + setCurrentChar( pc ); +} + +void QIMPenEdit::nextChar() +{ + QIMPenChar *pc = findNext(); + if ( pc ) + setCurrentChar( pc ); +} + +void QIMPenEdit::clearChar() +{ + inputChar->clear(); + pw->clear(); + enableButtons(); +} + +void QIMPenEdit::selectChar( int i ) +{ + currentChar = 0; + currentCode = ((CharListItem *)charList->item(i))->code(); + QIMPenCharIterator it(currentSet->characters() ); + for ( ; it.current(); ++it ) { + if ( it.current()->character() == currentCode && + !it.current()->testFlag( QIMPenChar::Deleted ) ) { + setCurrentChar( it.current() ); + break; + } + } + if ( !it.current() ) + setCurrentChar( 0 ); + inputChar->clear(); +} + +void QIMPenEdit::selectCharSet( int i ) +{ + if ( currentSet ) + pw->removeCharSet( 0 ); + currentSet = profile->charSets().at( i ); + fillCharList(); + pw->insertCharSet( currentSet ); + inputChar->clear(); + if ( charList->count() ) { + charList->setSelected( 0, TRUE ); + selectChar(0); + } +} + +void QIMPenEdit::addChar() +{ + if ( !inputChar->isEmpty() ) { + QIMPenChar *pc = new QIMPenChar( *inputChar ); + pc->setCharacter( currentCode ); + + // User characters override all matching system characters. + // Copy and mark deleted identical system characters. + QIMPenCharIterator it(currentSet->characters() ); + QIMPenChar *sc = 0; + while ( (sc = it.current()) != 0 ) { + ++it; + if ( sc->character() == currentCode && + sc->testFlag( QIMPenChar::System ) && + !sc->testFlag( QIMPenChar::Deleted ) ) { + QIMPenChar *cc = new QIMPenChar( *sc ); + cc->clearFlag( QIMPenChar::System ); + currentSet->addChar( cc ); + sc->setFlag( QIMPenChar::Deleted ); + } + } + + currentSet->addChar( pc ); + setCurrentChar( pc ); + inputChar->clear(); + } +} + +void QIMPenEdit::addNewChar() +{ + if ( !inputChar->isEmpty() ) { + QIMPenInputCharDlg dlg( 0, 0, TRUE ); + if ( dlg.exec() ) { + currentCode = dlg.unicode(); + addChar(); + fillCharList(); + for ( unsigned int i = 0; i < charList->count(); i++ ) { + CharListItem *li = (CharListItem *)charList->item(i); + if ( li->code() == dlg.unicode() ) { + charList->setSelected( i, TRUE ); + break; + } + } + } + } +} + +void QIMPenEdit::removeChar() +{ + if ( currentChar ) { + QIMPenChar *pc = findPrev(); + if ( !pc ) pc = findNext(); + if ( currentChar->testFlag( QIMPenChar::System ) ) + currentChar->setFlag( QIMPenChar::Deleted ); + else + currentSet->removeChar( currentChar ); + setCurrentChar( pc ); + } +} + +void QIMPenEdit::defaultChars() +{ + if ( currentCode ) { + currentChar = 0; + bool haveSystem = FALSE; + QIMPenCharIterator it(currentSet->characters() ); + for ( ; it.current(); ++it ) { + if ( it.current()->character() == currentCode && + it.current()->testFlag( QIMPenChar::System ) ) { + haveSystem = TRUE; + break; + } + } + if ( haveSystem ) { + it.toFirst(); + while ( it.current() ) { + QIMPenChar *pc = it.current(); + ++it; + if ( pc->character() == currentCode ) { + if ( pc->testFlag( QIMPenChar::System ) ) { + pc->clearFlag( QIMPenChar::Deleted ); + if ( !currentChar ) + currentChar = pc; + } else { + currentSet->removeChar( pc ); + } + } + } + setCurrentChar( currentChar ); + } + } +} + +void QIMPenEdit::newStroke( QIMPenStroke *st ) +{ + inputChar->addStroke( st ); + enableButtons(); +} + |