-rw-r--r-- | libopie2/qt3/opieui/ocombobox.cpp | 20 | ||||
-rw-r--r-- | libopie2/qt3/opieui/ocompletionbox.cpp | 10 | ||||
-rw-r--r-- | libopie2/qt3/opieui/ojanuswidget.cpp | 10 | ||||
-rw-r--r-- | libopie2/qt3/opieui/olineedit.cpp | 24 |
4 files changed, 32 insertions, 32 deletions
diff --git a/libopie2/qt3/opieui/ocombobox.cpp b/libopie2/qt3/opieui/ocombobox.cpp index 8dbda8f..bd330e0 100644 --- a/libopie2/qt3/opieui/ocombobox.cpp +++ b/libopie2/qt3/opieui/ocombobox.cpp @@ -1,669 +1,669 @@ /* This file Copyright (C) 2003 Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> is part of the Copyright (C) 2000 Carsten Pfeiffer <pfeiffer@kde.org> Opie Project Copyright (C) 2000 Dawit Alemayehu <adawit@kde.org> =. Originally part of the KDE Project .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* QT */ #include <qclipboard.h> #include <qlistbox.h> #include <qpopupmenu.h> /* OPIE */ #include <opie2/ocompletionbox.h> #include <opie2/olineedit.h> #include <opie2/opixmapprovider.h> #include <opie2/ocombobox.h> /*====================================================================================== * OComboBoxPrivate *======================================================================================*/ class OComboBox::OComboBoxPrivate { public: OComboBoxPrivate() { olineEdit = 0L; } ~OComboBoxPrivate() { } OLineEdit *olineEdit; }; /*====================================================================================== * OComboBox *======================================================================================*/ OComboBox::OComboBox( QWidget *parent, const char *name ) : QComboBox( parent, name ) { init(); } OComboBox::OComboBox( bool rw, QWidget *parent, const char *name ) : QComboBox( rw, parent, name ) { init(); if ( rw ) { OLineEdit *edit = new OLineEdit( this, "combo lineedit" ); setLineEdit( edit ); } } OComboBox::~OComboBox() { delete d; } void OComboBox::init() { d = new OComboBoxPrivate; // Permanently set some parameters in the parent object. QComboBox::setAutoCompletion( false ); // Initialize enable popup menu to false. // Below it will be enabled if the widget // is editable. m_bEnableMenu = false; m_trapReturnKey = false; // Enable context menu by default if widget // is editable. setContextMenuEnabled( true ); // for wheelscrolling installEventFilter( this ); if ( lineEdit() ) lineEdit()->installEventFilter( this ); } bool OComboBox::contains( const QString& _text ) const { if ( _text.isEmpty() ) return false; for (int i = 0; i < count(); i++ ) { if ( text(i) == _text ) return true; } return false; } void OComboBox::setAutoCompletion( bool autocomplete ) { if ( d->olineEdit ) { if ( autocomplete ) { d->olineEdit->setCompletionMode( OGlobalSettings::CompletionAuto ); setCompletionMode( OGlobalSettings::CompletionAuto ); } else { d->olineEdit->setCompletionMode( OGlobalSettings::completionMode() ); setCompletionMode( OGlobalSettings::completionMode() ); } } } void OComboBox::setContextMenuEnabled( bool showMenu ) { if( d->olineEdit ) { d->olineEdit->setContextMenuEnabled( showMenu ); m_bEnableMenu = showMenu; } } /* void OComboBox::setURLDropsEnabled( bool enable ) { if ( d->olineEdit ) d->olineEdit->setURLDropsEnabled( enable ); } bool OComboBox::isURLDropsEnabled() const { return d->olineEdit && d->olineEdit->isURLDropsEnabled(); } */ void OComboBox::setCompletedText( const QString& text, bool marked ) { if ( d->olineEdit ) d->olineEdit->setCompletedText( text, marked ); } void OComboBox::setCompletedText( const QString& text ) { if ( d->olineEdit ) d->olineEdit->setCompletedText( text ); } void OComboBox::makeCompletion( const QString& text ) { if( d->olineEdit ) d->olineEdit->makeCompletion( text ); else // read-only combo completion { if( text.isNull() || !listBox() ) return; int index = listBox()->index( listBox()->findItem( text ) ); if( index >= 0 ) { setCurrentItem( index ); } } } void OComboBox::rotateText( OCompletionBase::KeyBindingType type ) { if ( d->olineEdit ) d->olineEdit->rotateText( type ); } bool OComboBox::eventFilter( QObject* o, QEvent* ev ) { QLineEdit *edit = lineEdit(); int type = ev->type(); if ( o == edit ) { //OCursor::autoHideEventFilter( edit, ev ); if ( type == QEvent::KeyPress ) { QKeyEvent *e = static_cast<QKeyEvent *>( ev ); if ( e->key() == Key_Return || e->key() == Key_Enter) { // On Return pressed event, emit both // returnPressed(const QString&) and returnPressed() signals emit returnPressed(); emit returnPressed( currentText() ); if ( d->olineEdit && d->olineEdit->completionBox(false) && d->olineEdit->completionBox()->isVisible() ) d->olineEdit->completionBox()->hide(); return m_trapReturnKey; } } } // wheel-scrolling changes the current item if ( type == QEvent::Wheel ) { if ( !listBox() || listBox()->isHidden() ) { QWheelEvent *e = static_cast<QWheelEvent*>( ev ); static const int WHEEL_DELTA = 120; int skipItems = e->delta() / WHEEL_DELTA; if ( e->state() & ControlButton ) // fast skipping skipItems *= 10; int newItem = currentItem() - skipItems; if ( newItem < 0 ) newItem = 0; else if ( newItem >= count() ) newItem = count() -1; setCurrentItem( newItem ); if ( !text( newItem ).isNull() ) emit activated( text( newItem ) ); emit activated( newItem ); e->accept(); return true; } } return QComboBox::eventFilter( o, ev ); } void OComboBox::setTrapReturnKey( bool grab ) { m_trapReturnKey = grab; } bool OComboBox::trapReturnKey() const { return m_trapReturnKey; } /* void OComboBox::setEditURL( const OURL& url ) { QComboBox::setEditText( url.prettyURL() ); } void OComboBox::insertURL( const OURL& url, int index ) { QComboBox::insertItem( url.prettyURL(), index ); } void OComboBox::insertURL( const QPixmap& pixmap, const OURL& url, int index ) { QComboBox::insertItem( pixmap, url.prettyURL(), index ); } void OComboBox::changeURL( const OURL& url, int index ) { QComboBox::changeItem( url.prettyURL(), index ); } void OComboBox::changeURL( const QPixmap& pixmap, const OURL& url, int index ) { QComboBox::changeItem( pixmap, url.prettyURL(), index ); } */ void OComboBox::setCompletedItems( const QStringList& items ) { if ( d->olineEdit ) d->olineEdit->setCompletedItems( items ); } OCompletionBox * OComboBox::completionBox( bool create ) { if ( d->olineEdit ) return d->olineEdit->completionBox( create ); return 0; } // QWidget::create() turns off mouse-Tracking which would break auto-hiding void OComboBox::create( WId id, bool initializeWindow, bool destroyOldWindow ) { QComboBox::create( id, initializeWindow, destroyOldWindow ); //OCursor::setAutoHideCursor( lineEdit(), true, true ); } void OComboBox::setLineEdit( OLineEdit *edit ) { #if QT_VERSION > 290 QComboBox::setLineEdit( edit ); if ( !edit->inherits( "OLineEdit" ) ) d->olineEdit = 0; else d->olineEdit = static_cast<OLineEdit*>( edit ); setDelegate( d->olineEdit ); // forward some signals. We only emit returnPressed() ourselves. if ( d->olineEdit ) { - connect( d->olineEdit, SIGNAL( completion( const QString& )), - SIGNAL( completion( const QString& )) ); - connect( d->olineEdit, SIGNAL( substringCompletion( const QString& )), - SIGNAL( substringCompletion( const QString& )) ); + connect( d->olineEdit, SIGNAL( completion(const QString&)), + SIGNAL( completion(const QString&)) ); + connect( d->olineEdit, SIGNAL( substringCompletion(const QString&)), + SIGNAL( substringCompletion(const QString&)) ); connect( d->olineEdit, - SIGNAL( textRotation( OCompletionBase::KeyBindingType )), - SIGNAL( textRotation( OCompletionBase::KeyBindingType )) ); + SIGNAL( textRotation(OCompletionBase::KeyBindingType)), + SIGNAL( textRotation(OCompletionBase::KeyBindingType)) ); connect( d->olineEdit, - SIGNAL( completionModeChanged( OGlobalSettings::Completion )), - SIGNAL( completionModeChanged( OGlobalSettings::Completion))); + SIGNAL( completionModeChanged(OGlobalSettings::Completion)), + SIGNAL( completionModeChanged(OGlobalSettings::Completion))); connect( d->olineEdit, - SIGNAL( aboutToShowContextMenu( QPopupMenu * )), - SIGNAL( aboutToShowContextMenu( QPopupMenu * )) ); + SIGNAL( aboutToShowContextMenu(QPopupMenu*)), + SIGNAL( aboutToShowContextMenu(QPopupMenu*)) ); } #else #warning OComboBox is not fully functional with Qt2 #endif } // Temporary functions until QT3 appears. - Seth Chaiklin 20 may 2001 void OComboBox::deleteWordForward() { lineEdit()->cursorWordForward(TRUE); #if QT_VERSION > 290 if ( lineEdit()->hasSelectedText() ) #else if ( lineEdit()->hasMarkedText() ) #endif { lineEdit()->del(); } } void OComboBox::deleteWordBack() { lineEdit()->cursorWordBackward(TRUE); #if QT_VERSION > 290 if ( lineEdit()->hasSelectedText() ) #else if ( lineEdit()->hasMarkedText() ) #endif { lineEdit()->del(); } } void OComboBox::setCurrentItem( const QString& item, bool insert, int index ) { int sel = -1; for (int i = 0; i < count(); ++i) if (text(i) == item) { sel = i; break; } if (sel == -1 && insert) { insertItem(item, index); if (index >= 0) sel = index; else sel = count() - 1; } setCurrentItem(sel); } void OComboBox::setCurrentItem(int index) { QComboBox::setCurrentItem(index); } /*====================================================================================== * OHistoryCombo *======================================================================================*/ // we are always read-write OHistoryCombo::OHistoryCombo( QWidget *parent, const char *name ) : OComboBox( true, parent, name ) { init( true ); // using completion } // we are always read-write OHistoryCombo::OHistoryCombo( bool useCompletion, QWidget *parent, const char *name ) : OComboBox( true, parent, name ) { init( useCompletion ); } void OHistoryCombo::init( bool useCompletion ) { if ( useCompletion ) completionObject()->setOrder( OCompletion::Weighted ); setInsertionPolicy( NoInsertion ); myIterateIndex = -1; myRotated = false; myPixProvider = 0L; connect( this, SIGNAL(aboutToShowContextMenu(QPopupMenu*)), SLOT(addContextMenuItems(QPopupMenu*)) ); connect( this, SIGNAL( activated(int) ), SLOT( slotReset() )); connect( this, SIGNAL( returnPressed(const QString&) ), SLOT(slotReset())); } OHistoryCombo::~OHistoryCombo() { delete myPixProvider; } void OHistoryCombo::setHistoryItems( QStringList items, bool setCompletionList ) { OComboBox::clear(); // limit to maxCount() while ( (int) items.count() > maxCount() && !items.isEmpty() ) items.remove( items.begin() ); insertItems( items ); if ( setCompletionList && useCompletion() ) { // we don't have any weighting information here ;( OCompletion *comp = completionObject(); comp->setOrder( OCompletion::Insertion ); comp->setItems( items ); comp->setOrder( OCompletion::Weighted ); } clearEdit(); } QStringList OHistoryCombo::historyItems() const { QStringList list; for ( int i = 0; i < count(); i++ ) list.append( text( i ) ); return list; } void OHistoryCombo::clearHistory() { OComboBox::clear(); if ( useCompletion() ) completionObject()->clear(); } void OHistoryCombo::addContextMenuItems( QPopupMenu* menu ) { if ( menu &&!lineEdit()->text().isEmpty()) { menu->insertSeparator(); menu->insertItem( tr("Empty Contents"), this, SLOT( slotClear())); } } void OHistoryCombo::addToHistory( const QString& item ) { if ( item.isEmpty() || (count() > 0 && item == text(0) )) return; // remove all existing items before adding if ( !duplicatesEnabled() ) { for ( int i = 0; i < count(); i++ ) { if ( text( i ) == item ) removeItem( i ); } } // now add the item if ( myPixProvider ) //insertItem( myPixProvider->pixmapFor(item, KIcon::SizeSmall), item, 0); insertItem( myPixProvider->pixmapFor(item, 16), item, 0); else insertItem( item, 0 ); int last; QString rmItem; bool useComp = useCompletion(); while ( count() > maxCount() && count() > 0 ) { // remove the last item, as long as we are longer than maxCount() // remove the removed item from the completionObject if it isn't // anymore available at all in the combobox. last = count() - 1; rmItem = text( last ); removeItem( last ); if ( useComp && !contains( rmItem ) ) completionObject()->removeItem( rmItem ); } if ( useComp ) completionObject()->addItem( item ); } bool OHistoryCombo::removeFromHistory( const QString& item ) { if ( item.isEmpty() ) return false; bool removed = false; QString temp = currentText(); for ( int i = 0; i < count(); i++ ) { while ( item == text( i ) ) { removed = true; removeItem( i ); } } if ( removed && useCompletion() ) completionObject()->removeItem( item ); setEditText( temp ); return removed; } void OHistoryCombo::keyPressEvent( QKeyEvent *e ) { // save the current text in the lineedit if ( myIterateIndex == -1 ) myText = currentText(); // going up in the history, rotating when reaching QListBox::count() //if ( OStdAccel::isEqual( e, OStdAccel::rotateUp() ) ) { if ( e->key() == Qt::Key_Up ) { myIterateIndex++; // skip duplicates/empty items while ( myIterateIndex < count()-1 && (currentText() == text( myIterateIndex ) || text( myIterateIndex ).isEmpty()) ) myIterateIndex++; if ( myIterateIndex >= count() ) { myRotated = true; myIterateIndex = -1; // if the typed text is the same as the first item, skip the first if ( myText == text(0) ) myIterateIndex = 0; setEditText( myText ); } else setEditText( text( myIterateIndex )); } // going down in the history, no rotation possible. Last item will be // the text that was in the lineedit before Up was called. //else if ( OStdAccel::isEqual( e, OStdAccel::rotateDown() ) ) { else if ( e->key() == Qt::Key_Down ) { myIterateIndex--; // skip duplicates/empty items while ( myIterateIndex >= 0 && (currentText() == text( myIterateIndex ) || text( myIterateIndex ).isEmpty()) ) myIterateIndex--; if ( myIterateIndex < 0 ) { if ( myRotated && myIterateIndex == -2 ) { myRotated = false; myIterateIndex = count() - 1; setEditText( text(myIterateIndex) ); } else { // bottom of history if ( myIterateIndex == -2 ) { qDebug( "ONotifyClient is not implemented yet." ); //ONotifyClient::event( ONotifyClient::notification, // i18n("No further item in the history.")); } myIterateIndex = -1; if ( currentText() != myText ) setEditText( myText ); } } else setEditText( text( myIterateIndex )); } else OComboBox::keyPressEvent( e ); } void OHistoryCombo::slotReset() { myIterateIndex = -1; myRotated = false; } void OHistoryCombo::setPixmapProvider( OPixmapProvider *prov ) { if ( myPixProvider == prov ) return; delete myPixProvider; myPixProvider = prov; // re-insert all the items with/without pixmap // I would prefer to use changeItem(), but that doesn't honour the pixmap // when using an editable combobox (what we do) if ( count() > 0 ) { QStringList items( historyItems() ); clear(); insertItems( items ); } } void OHistoryCombo::insertItems( const QStringList& items ) { QStringList::ConstIterator it = items.begin(); QString item; while ( it != items.end() ) { item = *it; if ( !item.isEmpty() ) { // only insert non-empty items if ( myPixProvider ) // insertItem( myPixProvider->pixmapFor(item, OIcon::SizeSmall), item ); insertItem( myPixProvider->pixmapFor(item, 16), item ); else insertItem( item ); } ++it; } } void OHistoryCombo::slotClear() { clearHistory(); emit cleared(); } diff --git a/libopie2/qt3/opieui/ocompletionbox.cpp b/libopie2/qt3/opieui/ocompletionbox.cpp index b594b8e..b36123e 100644 --- a/libopie2/qt3/opieui/ocompletionbox.cpp +++ b/libopie2/qt3/opieui/ocompletionbox.cpp @@ -1,408 +1,408 @@ /* This file Copyright (C) 2003 Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> is part of the Copyright (C) 2000,2001 Carsten Pfeiffer <pfeiffer@kde.org> Opie Project Copyright (C) 2000 Stefan Schimanski <1Stein@gmx.de> Copyright (C) 2000,2001 Dawit Alemayehu <adawit@kde.org> =. .=l. Originally part of the KDE Project .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <qapplication.h> #include <qevent.h> #include <qstyle.h> #include <opie2/ocompletionbox.h> #define OListBox QListBox class OCompletionBox::OCompletionBoxPrivate { public: QWidget *m_parent; // necessary to set the focus back QString cancelText; bool tabHandling; bool down_workaround; }; OCompletionBox::OCompletionBox( QWidget *parent, const char *name ) :OListBox( parent, name, WType_Popup ) { d = new OCompletionBoxPrivate; d->m_parent = parent; d->tabHandling = true; d->down_workaround = false; setColumnMode( 1 ); setLineWidth( 1 ); setFrameStyle( QFrame::Box | QFrame::Plain ); if ( parent ) setFocusProxy( parent ); else setFocusPolicy( NoFocus ); setVScrollBarMode( Auto ); setHScrollBarMode( AlwaysOff ); - connect( this, SIGNAL( doubleClicked( QListBoxItem * )), - SLOT( slotActivated( QListBoxItem * )) ); + connect( this, SIGNAL( doubleClicked(QListBoxItem*)), + SLOT( slotActivated(QListBoxItem*)) ); // grmbl, just QListBox workarounds :[ Thanks Volker. - connect( this, SIGNAL( currentChanged( QListBoxItem * )), + connect( this, SIGNAL( currentChanged(QListBoxItem*)), SLOT( slotCurrentChanged() )); - connect( this, SIGNAL( clicked( QListBoxItem * )), - SLOT( slotItemClicked( QListBoxItem * )) ); + connect( this, SIGNAL( clicked(QListBoxItem*)), + SLOT( slotItemClicked(QListBoxItem*)) ); } OCompletionBox::~OCompletionBox() { d->m_parent = 0L; delete d; } QStringList OCompletionBox::items() const { QStringList list; for ( uint i = 0; i < count(); i++ ) { list.append( text( i ) ); } return list; } void OCompletionBox::slotActivated( QListBoxItem *item ) { if ( !item ) return; hide(); emit activated( item->text() ); } bool OCompletionBox::eventFilter( QObject *o, QEvent *e ) { int type = e->type(); if ( o == d->m_parent ) { if ( isVisible() ) { if ( type == QEvent::KeyPress ) { QKeyEvent *ev = static_cast<QKeyEvent *>( e ); switch ( ev->key() ) { case Key_BackTab: if ( d->tabHandling ) { up(); ev->accept(); return true; } break; case Key_Tab: if ( d->tabHandling ) { down(); // Only on TAB!! ev->accept(); return true; } break; case Key_Down: down(); ev->accept(); return true; case Key_Up: up(); ev->accept(); return true; case Key_Prior: pageUp(); ev->accept(); return true; case Key_Next: pageDown(); ev->accept(); return true; case Key_Escape: cancelled(); ev->accept(); return true; case Key_Enter: case Key_Return: if ( ev->state() & ShiftButton ) { hide(); ev->accept(); // Consume the Enter event return true; } break; default: break; } } else if ( type == QEvent::AccelOverride ) { // Override any acceleartors that match // the key sequences we use here... QKeyEvent *ev = static_cast<QKeyEvent *>( e ); switch ( ev->key() ) { case Key_Tab: case Key_BackTab: case Key_Down: case Key_Up: case Key_Prior: case Key_Next: case Key_Escape: case Key_Enter: case Key_Return: ev->accept(); return true; break; default: break; } } // parent loses focus or gets a click -> we hide else if ( type == QEvent::FocusOut || type == QEvent::Resize || type == QEvent::Close || type == QEvent::Hide || type == QEvent::Move ) { hide(); } else if ( type == QEvent::Move ) move( d->m_parent->mapToGlobal(QPoint(0, d->m_parent->height()))); else if ( type == QEvent::Resize ) resize( sizeHint() ); } } // any mouse-click on something else than "this" makes us hide else if ( type == QEvent::MouseButtonPress ) { QMouseEvent *ev = static_cast<QMouseEvent *>( e ); if ( !rect().contains( ev->pos() )) // this widget hide(); } return OListBox::eventFilter( o, e ); } void OCompletionBox::popup() { if ( count() == 0 ) hide(); else { ensureCurrentVisible(); bool block = signalsBlocked(); blockSignals( true ); setCurrentItem( 0 ); blockSignals( block ); clearSelection(); if ( !isVisible() ) show(); else if ( size().height() < sizeHint().height() ) resize( sizeHint() ); } } void OCompletionBox::show() { resize( sizeHint() ); if ( d->m_parent ) { //QDesktopWidget *screen = QApplication::desktop(); QWidget *screen = QApplication::desktop(); QPoint orig = d->m_parent->mapToGlobal( QPoint(0, d->m_parent->height()) ); int x = orig.x(); int y = orig.y(); if ( x + width() > screen->width() ) x = screen->width() - width(); if (y + height() > screen->height() ) y = y - height() - d->m_parent->height(); move( x, y); qApp->installEventFilter( this ); } // ### we shouldn't need to call this, but without this, the scrollbars // are pretty b0rked. //triggerUpdate( true ); OListBox::show(); } void OCompletionBox::hide() { if ( d->m_parent ) qApp->removeEventFilter( this ); d->cancelText = QString::null; OListBox::hide(); } QSize OCompletionBox::sizeHint() const { int ih = itemHeight(); int h = QMIN( 15 * ih, (int) count() * ih ) +1; h = QMAX( h, OListBox::minimumSizeHint().height() ); int w = (d->m_parent) ? d->m_parent->width() : OListBox::minimumSizeHint().width(); w = QMAX( OListBox::minimumSizeHint().width(), w ); return QSize( w, h ); } void OCompletionBox::down() { int i = currentItem(); if ( i == 0 && d->down_workaround ) { d->down_workaround = false; setCurrentItem( 0 ); setSelected( 0, true ); emit highlighted( currentText() ); } else if ( i < (int) count() - 1 ) setCurrentItem( i + 1 ); } void OCompletionBox::up() { if ( currentItem() > 0 ) setCurrentItem( currentItem() - 1 ); } void OCompletionBox::pageDown() { int i = currentItem() + numItemsVisible(); i = i > (int)count() - 1 ? (int)count() - 1 : i; setCurrentItem( i ); } void OCompletionBox::pageUp() { int i = currentItem() - numItemsVisible(); i = i < 0 ? 0 : i; setCurrentItem( i ); } void OCompletionBox::home() { setCurrentItem( 0 ); } void OCompletionBox::end() { setCurrentItem( count() -1 ); } void OCompletionBox::setTabHandling( bool enable ) { d->tabHandling = enable; } bool OCompletionBox::isTabHandling() const { return d->tabHandling; } void OCompletionBox::setCancelledText( const QString& text ) { d->cancelText = text; } QString OCompletionBox::cancelledText() const { return d->cancelText; } void OCompletionBox::cancelled() { if ( !d->cancelText.isNull() ) emit userCancelled( d->cancelText ); if ( isVisible() ) hide(); } class OCompletionBoxItem : public QListBoxItem { public: void reuse( const QString &text ) { setText( text ); } }; void OCompletionBox::insertItems( const QStringList& items, int index ) { bool block = signalsBlocked(); blockSignals( true ); insertStringList( items, index ); blockSignals( block ); d->down_workaround = true; } void OCompletionBox::setItems( const QStringList& items ) { bool block = signalsBlocked(); blockSignals( true ); QListBoxItem* item = firstItem(); if ( !item ) { insertStringList( items ); } else { for ( QStringList::ConstIterator it = items.begin(); it != items.end(); it++) { if ( item ) { ((OCompletionBoxItem*)item)->reuse( *it ); item = item->next(); } else { insertItem( new QListBoxText( *it ) ); } } QListBoxItem* tmp = item; while ( (item = tmp ) ) { tmp = item->next(); delete item; } triggerUpdate( false ); } blockSignals( block ); d->down_workaround = true; } void OCompletionBox::slotCurrentChanged() { d->down_workaround = false; } void OCompletionBox::slotItemClicked( QListBoxItem *item ) { if ( item ) { if ( d->down_workaround ) { d->down_workaround = false; emit highlighted( item->text() ); } hide(); emit activated( item->text() ); } } diff --git a/libopie2/qt3/opieui/ojanuswidget.cpp b/libopie2/qt3/opieui/ojanuswidget.cpp index 0a037ff..063e393 100644 --- a/libopie2/qt3/opieui/ojanuswidget.cpp +++ b/libopie2/qt3/opieui/ojanuswidget.cpp @@ -1,1116 +1,1116 @@ /* This file is part of the Opie Project Originally part of the KDE project (C) 1999-2000 Espen Sand (espensa@online.no) =. .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* QT */ #include <qbitmap.h> #include <qgrid.h> #include <qhbox.h> #include <qheader.h> #include <qlabel.h> #include <qlayout.h> #include <qobjectlist.h> #include <qpixmap.h> #include <qlistview.h> #include <qsplitter.h> #include <qtabwidget.h> #include <qvbox.h> #include <qwidgetstack.h> #include <qpainter.h> #include <qtimer.h> #include <qstyle.h> /* OPIE */ #include <opie2/odialog.h> #include <opie2/oseparator.h> #include <opie2/ojanuswidget.h> /*====================================================================================== * IconListItem *======================================================================================*/ class OJanusWidget::IconListItem : public QListBoxItem { public: IconListItem( QListBox *listbox, const QPixmap &pixmap, const QString &text ); virtual int height( const QListBox *lb ) const; virtual int width( const QListBox *lb ) const; int expandMinimumWidth( int width ); protected: const QPixmap &defaultPixmap(); void paint( QPainter *painter ); private: QPixmap mPixmap; int mMinimumWidth; }; template class QPtrList<QListViewItem>; /*====================================================================================== * OJanusWidget *======================================================================================*/ OJanusWidget::OJanusWidget( QWidget *parent, const char *name, int face ) : QWidget( parent, name, 0 ), mValid(false), mPageList(0), mTitleList(0), mFace(face), mTitleLabel(0), mActivePageWidget(0), mShowIconsInTreeList(false), d(0) { QVBoxLayout *topLayout = new QVBoxLayout( this ); if( mFace == TreeList || mFace == IconList ) { mPageList = new QPtrList<QWidget>; mTitleList = new QStringList(); QFrame *page; if( mFace == TreeList ) { QSplitter *splitter = new QSplitter( this ); topLayout->addWidget( splitter, 10 ); mTreeListResizeMode = QSplitter::KeepSize; mTreeList = new QListView( splitter ); mTreeList->addColumn( QString::fromLatin1("") ); mTreeList->header()->hide(); mTreeList->setRootIsDecorated(true); mTreeList->setSorting( -1 ); connect( mTreeList, SIGNAL(selectionChanged()), SLOT(slotShowPage()) ); - connect( mTreeList, SIGNAL(clicked(QListViewItem *)), SLOT(slotItemClicked(QListViewItem *))); + connect( mTreeList, SIGNAL(clicked(QListViewItem*)), SLOT(slotItemClicked(QListViewItem*))); // // Page area. Title at top with a separator below and a pagestack using // all available space at bottom. // QFrame *p = new QFrame( splitter ); QHBoxLayout *hbox = new QHBoxLayout( p, 0, 0 ); hbox->addSpacing( ODialog::spacingHint() ); page = new QFrame( p ); hbox->addWidget( page, 10 ); } else { QHBoxLayout *hbox = new QHBoxLayout( topLayout ); mIconList = new IconListBox( this ); QFont listFont( mIconList->font() ); listFont.setBold( true ); mIconList->setFont( listFont ); mIconList->verticalScrollBar()->installEventFilter( this ); hbox->addWidget( mIconList ); connect( mIconList, SIGNAL(selectionChanged()), SLOT(slotShowPage())); hbox->addSpacing( ODialog::spacingHint() ); page = new QFrame( this ); hbox->addWidget( page, 10 ); } // // Rest of page area. Title at top with a separator below and a // pagestack using all available space at bottom. // QVBoxLayout *vbox = new QVBoxLayout( page, 0, ODialog::spacingHint() ); mTitleLabel = new QLabel( QString::fromLatin1("Empty page"), page, "OJanusWidgetTitleLabel" ); vbox->addWidget( mTitleLabel ); QFont titleFont( mTitleLabel->font() ); titleFont.setBold( true ); mTitleLabel->setFont( titleFont ); mTitleSep = new OSeparator( page ); mTitleSep->setFrameStyle( QFrame::HLine|QFrame::Plain ); vbox->addWidget( mTitleSep ); mPageStack = new QWidgetStack( page ); - connect(mPageStack, SIGNAL(aboutToShow(QWidget *)), - this, SIGNAL(aboutToShowPage(QWidget *))); + connect(mPageStack, SIGNAL(aboutToShow(QWidget*)), + this, SIGNAL(aboutToShowPage(QWidget*))); vbox->addWidget( mPageStack, 10 ); } else if( mFace == Tabbed ) { mPageList = new QPtrList<QWidget>; mTabControl = new QTabWidget( this ); mTabControl->setMargin (ODialog::marginHint()); topLayout->addWidget( mTabControl, 10 ); } else if( mFace == Swallow ) { mSwallowPage = new QWidget( this ); topLayout->addWidget( mSwallowPage, 10 ); } else { mFace = Plain; mPlainPage = new QFrame( this ); topLayout->addWidget( mPlainPage, 10 ); } /* FIXME: Revise for Opie if ( kapp ) connect(kapp,SIGNAL(kdisplayFontChanged()),SLOT(slotFontChanged())); */ mValid = true; setSwallowedWidget(0); // Set default size if 'mFace' is Swallow. } OJanusWidget::~OJanusWidget() { delete mPageList; mPageList = 0; delete mTitleList; mTitleList = 0; } bool OJanusWidget::isValid() const { return( mValid ); } QFrame *OJanusWidget::plainPage() { return( mPlainPage ); } int OJanusWidget::face() const { return( mFace ); } QWidget *OJanusWidget::FindParent() { if( mFace == Tabbed ) { return mTabControl; } else { return this; } } QFrame *OJanusWidget::addPage( const QStringList &items, const QString &header, const QPixmap &pixmap ) { if( mValid == false ) { qDebug( "addPage: Invalid object" ); return( 0 ); } QFrame *page = new QFrame( FindParent(), "page" ); addPageWidget( page, items, header, pixmap ); return page; } void OJanusWidget::pageGone( QObject *obj ) { removePage( static_cast<QWidget*>( obj ) ); } void OJanusWidget::slotReopen( QListViewItem * item ) { if( item ) item->setOpen( true ); } QFrame *OJanusWidget::addPage( const QString &itemName, const QString &header, const QPixmap &pixmap ) { QStringList items; items << itemName; return addPage(items, header, pixmap); } QVBox *OJanusWidget::addVBoxPage( const QStringList &items, const QString &header, const QPixmap &pixmap ) { if( mValid == false ) { qDebug( "addPage: Invalid object" ); return( 0 ); } QVBox *page = new QVBox(FindParent() , "page" ); page->setSpacing( ODialog::spacingHint() ); addPageWidget( page, items, header, pixmap ); return page; } QVBox *OJanusWidget::addVBoxPage( const QString &itemName, const QString &header, const QPixmap &pixmap ) { QStringList items; items << itemName; return addVBoxPage(items, header, pixmap); } QHBox *OJanusWidget::addHBoxPage( const QStringList &items, const QString &header, const QPixmap &pixmap ) { if( mValid == false ) { qDebug( "addPage: Invalid object" ); return( 0 ); } QHBox *page = new QHBox(FindParent(), "page"); page->setSpacing( ODialog::spacingHint() ); addPageWidget( page, items, header, pixmap ); return page; } QHBox *OJanusWidget::addHBoxPage( const QString &itemName, const QString &header, const QPixmap &pixmap ) { QStringList items; items << itemName; return addHBoxPage(items, header, pixmap); } QGrid *OJanusWidget::addGridPage( int n, Orientation dir, const QStringList &items, const QString &header, const QPixmap &pixmap ) { if( mValid == false ) { qDebug( "addPage: Invalid object" ); return( 0 ); } QGrid *page = new QGrid( n, dir, FindParent(), "page" ); page->setSpacing( ODialog::spacingHint() ); addPageWidget( page, items, header, pixmap ); return page; } QGrid *OJanusWidget::addGridPage( int n, Orientation dir, const QString &itemName, const QString &header, const QPixmap &pixmap ) { QStringList items; items << itemName; return addGridPage(n, dir, items, header, pixmap); } void OJanusWidget::InsertTreeListItem(const QStringList &items, const QPixmap &pixmap, QFrame *page) { bool isTop = true; QListViewItem *curTop = 0, *child, *last, *newChild; unsigned int index = 1; QStringList curPath; for ( QStringList::ConstIterator it = items.begin(); it != items.end(); ++it, index++ ) { QString name = (*it); bool isPath = ( index != items.count() ); // Find the first child. if (isTop) { child = mTreeList->firstChild(); } else { child = curTop->firstChild(); } // Now search for a child with the current Name, and if it we doesn't // find it, then remember the location of the last child. for (last = 0; child && child->text(0) != name ; last = child, child = child->nextSibling()); if (last == 0 && child == 0) { // This node didn't have any children at all, lets just insert the // new child. if (isTop) newChild = new QListViewItem(mTreeList, name); else newChild = new QListViewItem(curTop, name); } else if (child != 0) { // we found the given name in this child. if (!isPath) { qDebug( "The element inserted was already in the TreeList box!" ); return; } else { // Ok we found the folder newChild = child; } } else { // the node had some children, but we didn't find the given name if (isTop) newChild = new QListViewItem(mTreeList, last, name); else newChild = new QListViewItem(curTop, last, name); } // Now make the element expandable if it is a path component, and make // ready for next loop if (isPath) { newChild->setExpandable(true); curTop = newChild; isTop = false; curPath << name; QString key = curPath.join("_/_"); if (mFolderIconMap.contains(key)) { QPixmap p = mFolderIconMap[key]; newChild->setPixmap(0,p); } } else { if (mShowIconsInTreeList) { newChild->setPixmap(0, pixmap); } mTreeListToPageStack.insert(newChild, page); } } } void OJanusWidget::addPageWidget( QFrame *page, const QStringList &items, const QString &header,const QPixmap &pixmap ) { connect(page, SIGNAL(destroyed(QObject*)), SLOT(pageGone(QObject*))); if( mFace == Tabbed ) { mTabControl->addTab (page, items.last()); mPageList->append (page); } else if( mFace == TreeList || mFace == IconList ) { mPageList->append( page ); mPageStack->addWidget( page, 0 ); if (items.count() == 0) { qDebug( "Invalid QStringList, with zero items" ); return; } if( mFace == TreeList ) { InsertTreeListItem(items, pixmap, page); } else // mFace == IconList { QString itemName = items.last(); IconListItem *item = new IconListItem( mIconList, pixmap, itemName ); // // 2000-06-01 Espen Sand: If I do this with Qt 2.1.1 all sorts of // strange things happen. With Qt <= 2.1 it worked but now I must // either specify the listbox in the constructor on the item // or as below, not both. // mIconList->insertItem( item ); // mIconListToPageStack.insert(item, page); mIconList->invalidateHeight(); mIconList->invalidateWidth(); if (mIconList->isVisible()) mIconList->updateWidth(); } // // Make sure the title label is sufficiently wide // QString lastName = items.last(); const QString &title = (header != QString::null ? header : lastName); QRect r = mTitleLabel->fontMetrics().boundingRect( title ); if( mTitleLabel->minimumWidth() < r.width() ) { mTitleLabel->setMinimumWidth( r.width() ); } mTitleList->append( title ); if( mTitleList->count() == 1 ) { showPage(0); } } else { qDebug( "OJanusWidget::addPageWidget: can only add a page in Tabbed, TreeList or IconList modes" ); } } void OJanusWidget::setFolderIcon(const QStringList &path, const QPixmap &pixmap) { QString key = path.join("_/_"); mFolderIconMap.insert(key,pixmap); } bool OJanusWidget::setSwallowedWidget( QWidget *widget ) { if( mFace != Swallow || mValid == false ) { return( false ); } // // Remove current layout and make a new. // if( mSwallowPage->layout() != 0 ) { delete mSwallowPage->layout(); } QGridLayout *gbox = new QGridLayout( mSwallowPage, 1, 1, 0 ); // // Hide old children // QObjectList *l = (QObjectList*)mSwallowPage->children(); // silence please for( uint i=0; i < l->count(); i++ ) { QObject *o = l->at(i); if( o->isWidgetType() ) { ((QWidget*)o)->hide(); } } // // Add new child or make default size // if( widget == 0 ) { gbox->addRowSpacing(0,100); gbox->addColSpacing(0,100); mSwallowPage->setMinimumSize(100,100); } else { if( widget->parent() != mSwallowPage ) { widget->reparent( mSwallowPage, 0, QPoint(0,0) ); } gbox->addWidget(widget, 0, 0 ); gbox->activate(); mSwallowPage->setMinimumSize( widget->minimumSize() ); } return( true ); } bool OJanusWidget::slotShowPage() { if( mValid == false ) { return( false ); } if( mFace == TreeList ) { QListViewItem *node = mTreeList->selectedItem(); if( node == 0 ) { return( false ); } QWidget *stackItem = mTreeListToPageStack[node]; return showPage(stackItem); } else if( mFace == IconList ) { QListBoxItem *node = mIconList->item( mIconList->currentItem() ); if( node == 0 ) { return( false ); } QWidget *stackItem = mIconListToPageStack[node]; return showPage(stackItem); } return( false ); } bool OJanusWidget::showPage( int index ) { if( mPageList == 0 || mValid == false ) { return( false ); } else { return showPage(mPageList->at(index)); } } bool OJanusWidget::showPage( QWidget *w ) { if( w == 0 || mValid == false ) { return( false ); } if( mFace == TreeList || mFace == IconList ) { mPageStack->raiseWidget( w ); mActivePageWidget = w; int index = mPageList->findRef( w ); mTitleLabel->setText( *mTitleList->at(index) ); if( mFace == TreeList ) { QMap<QListViewItem *, QWidget *>::Iterator it; for (it = mTreeListToPageStack.begin(); it != mTreeListToPageStack.end(); ++it){ QListViewItem *key = it.key(); QWidget *val = it.data(); if (val == w) { mTreeList->setSelected(key, true ); break; } } } else { QMap<QListBoxItem *, QWidget *>::Iterator it; for (it = mIconListToPageStack.begin(); it != mIconListToPageStack.end(); ++it){ QListBoxItem *key = it.key(); QWidget *val = it.data(); if (val == w) { mIconList->setSelected( key, true ); break; } } // // 2000-02-13 Espen Sand // Don't ask me why (because I don't know). If I select a page // with the mouse the page is not updated until it receives an // event. It seems this event get lost if the mouse is not moved // when released. The timer ensures the update // QTimer::singleShot( 0, mActivePageWidget, SLOT(update()) ); } } else if( mFace == Tabbed ) { mTabControl->showPage(w); mActivePageWidget = w; } else { return( false ); } return( true ); } int OJanusWidget::activePageIndex() const { if( mFace == TreeList) { QListViewItem *node = mTreeList->selectedItem(); if( node == 0 ) { return -1; } QWidget *stackItem = mTreeListToPageStack[node]; return mPageList->findRef(stackItem); } else if (mFace == IconList) { QListBoxItem *node = mIconList->item( mIconList->currentItem() ); if( node == 0 ) { return( false ); } QWidget *stackItem = mIconListToPageStack[node]; return mPageList->findRef(stackItem); } else if( mFace == Tabbed ) { QWidget *widget = mTabControl->currentPage(); return( widget == 0 ? -1 : mPageList->findRef( widget ) ); } else { return( -1 ); } } int OJanusWidget::pageIndex( QWidget *widget ) const { if( widget == 0 ) { return( -1 ); } else if( mFace == TreeList || mFace == IconList ) { return( mPageList->findRef( widget ) ); } else if( mFace == Tabbed ) { // // The user gets the real page widget with addVBoxPage(), addHBoxPage() // and addGridPage() but not with addPage() which returns a child of // the toplevel page. addPage() returns a QFrame so I check for that. // if( widget->isA("QFrame") ) { return( mPageList->findRef( widget->parentWidget() ) ); } else { return( mPageList->findRef( widget ) ); } } else { return( -1 ); } } void OJanusWidget::slotFontChanged() { #ifdef FIXME if ( mTitleLabel != 0 ) { mTitleLabel->setFont( KGlobalSettings::generalFont() ); QFont titleFont( mTitleLabel->font() ); titleFont.setBold( true ); mTitleLabel->setFont( titleFont ); } #endif if( mFace == IconList ) { QFont listFont( mIconList->font() ); listFont.setBold( true ); mIconList->setFont( listFont ); mIconList->invalidateHeight(); mIconList->invalidateWidth(); } } // makes the treelist behave like the list of kcontrol void OJanusWidget::slotItemClicked(QListViewItem *it) { if(it && (it->childCount()>0)) it->setOpen(!it->isOpen()); } void OJanusWidget::setFocus() { if( mValid == false ) { return; } if( mFace == TreeList ) { mTreeList->setFocus(); } if( mFace == IconList ) { mIconList->setFocus(); } else if( mFace == Tabbed ) { mTabControl->setFocus(); } else if( mFace == Swallow ) { mSwallowPage->setFocus(); } else if( mFace == Plain ) { mPlainPage->setFocus(); } } QSize OJanusWidget::minimumSizeHint() const { if( mFace == TreeList || mFace == IconList ) { QSize s1( ODialog::spacingHint(), ODialog::spacingHint()*2 ); QSize s2(0,0); QSize s3(0,0); QSize s4( mPageStack->sizeHint() ); if( mFace == TreeList ) { #if QT_VERSION < 300 s1.rwidth() += style().splitterWidth(); #else s1.rwidth() += style().pixelMetric( QStyle::PM_SplitterWidth ); #endif s2 = mTreeList->minimumSize(); } else { mIconList->updateMinimumHeight(); mIconList->updateWidth(); s2 = mIconList->minimumSize(); } if( mTitleLabel->isVisible() == true ) { s3 += mTitleLabel->sizeHint(); s3.rheight() += mTitleSep->minimumSize().height(); } // // Select the tallest item. It has only effect in IconList mode // int h1 = s1.rheight() + s3.rheight() + s4.height(); int h2 = QMAX( h1, s2.rheight() ); return( QSize( s1.width()+s2.width()+QMAX(s3.width(),s4.width()), h2 ) ); } else if( mFace == Tabbed ) { return( mTabControl->sizeHint() ); } else if( mFace == Swallow ) { return( mSwallowPage->minimumSize() ); } else if( mFace == Plain ) { return( mPlainPage->sizeHint() ); } else { return( QSize( 100, 100 ) ); // Should never happen though. } } QSize OJanusWidget::sizeHint() const { return( minimumSizeHint() ); } void OJanusWidget::setTreeListAutoResize( bool state ) { if( mFace == TreeList ) { mTreeListResizeMode = state == false ? QSplitter::KeepSize : QSplitter::Stretch; QSplitter *splitter = (QSplitter*)(mTreeList->parentWidget()); splitter->setResizeMode( mTreeList, mTreeListResizeMode ); } } void OJanusWidget::setIconListAllVisible( bool state ) { if( mFace == IconList ) { mIconList->setShowAll( state ); } } void OJanusWidget::setShowIconsInTreeList( bool state ) { mShowIconsInTreeList = state; } void OJanusWidget::setRootIsDecorated( bool state ) { if( mFace == TreeList ) { mTreeList->setRootIsDecorated(state); } } void OJanusWidget::unfoldTreeList( bool persist ) { if( mFace == TreeList ) { if( persist ) - connect( mTreeList, SIGNAL( collapsed( QListViewItem * ) ), this, SLOT( slotReopen( QListViewItem * ) ) ); + connect( mTreeList, SIGNAL( collapsed(QListViewItem*) ), this, SLOT( slotReopen(QListViewItem*) ) ); else - disconnect( mTreeList, SIGNAL( collapsed( QListViewItem * ) ), this, SLOT( slotReopen( QListViewItem * ) ) ); + disconnect( mTreeList, SIGNAL( collapsed(QListViewItem*) ), this, SLOT( slotReopen(QListViewItem*) ) ); for( QListViewItem * item = mTreeList->firstChild(); item; item = item->itemBelow() ) item->setOpen( true ); } } void OJanusWidget::showEvent( QShowEvent * ) { if( mFace == TreeList ) { QSplitter *splitter = (QSplitter*)(mTreeList->parentWidget()); splitter->setResizeMode( mTreeList, mTreeListResizeMode ); } } // // 2000-13-02 Espen Sand // It should be obvious that this eventfilter must only be // be installed on the vertical scrollbar of the mIconList. // bool OJanusWidget::eventFilter( QObject *o, QEvent *e ) { if( e->type() == QEvent::Show ) { IconListItem *item = (IconListItem*)mIconList->item(0); if( item != 0 ) { int lw = item->width( mIconList ); int sw = mIconList->verticalScrollBar()->sizeHint().width(); mIconList->setFixedWidth( lw+sw+mIconList->frameWidth()*2 ); } } else if( e->type() == QEvent::Hide ) { IconListItem *item = (IconListItem*)mIconList->item(0); if( item != 0 ) { int lw = item->width( mIconList ); mIconList->setFixedWidth( lw+mIconList->frameWidth()*2 ); } } return QWidget::eventFilter( o, e ); } // // Code for the icon list box // OJanusWidget::IconListBox::IconListBox( QWidget *parent, const char *name, WFlags f ) :QListBox( parent, name, f ), mShowAll(false), mHeightValid(false), mWidthValid(false) { } void OJanusWidget::IconListBox::updateMinimumHeight() { if( mShowAll == true && mHeightValid == false ) { int h = frameWidth()*2; for( QListBoxItem *i = item(0); i != 0; i = i->next() ) { h += i->height( this ); } setMinimumHeight( h ); mHeightValid = true; } } void OJanusWidget::IconListBox::updateWidth() { if( mWidthValid == false ) { int maxWidth = 10; for( QListBoxItem *i = item(0); i != 0; i = i->next() ) { int w = ((IconListItem *)i)->width(this); maxWidth = QMAX( w, maxWidth ); } for( QListBoxItem *i = item(0); i != 0; i = i->next() ) { ((IconListItem *)i)->expandMinimumWidth( maxWidth ); } if( verticalScrollBar()->isVisible() ) { maxWidth += verticalScrollBar()->sizeHint().width(); } setFixedWidth( maxWidth + frameWidth()*2 ); mWidthValid = true; } } void OJanusWidget::IconListBox::invalidateHeight() { mHeightValid = false; } void OJanusWidget::IconListBox::invalidateWidth() { mWidthValid = false; } void OJanusWidget::IconListBox::setShowAll( bool showAll ) { mShowAll = showAll; mHeightValid = false; } OJanusWidget::IconListItem::IconListItem( QListBox *listbox, const QPixmap &pixmap, const QString &text ) : QListBoxItem( listbox ) { mPixmap = pixmap; if( mPixmap.isNull() == true ) { mPixmap = defaultPixmap(); } setText( text ); mMinimumWidth = 0; } int OJanusWidget::IconListItem::expandMinimumWidth( int width ) { mMinimumWidth = QMAX( mMinimumWidth, width ); return( mMinimumWidth ); } const QPixmap &OJanusWidget::IconListItem::defaultPixmap() { static QPixmap *pix=0; if( pix == 0 ) { pix = new QPixmap( 32, 32 ); QPainter p( pix ); p.eraseRect( 0, 0, pix->width(), pix->height() ); p.setPen( Qt::red ); p.drawRect ( 0, 0, pix->width(), pix->height() ); p.end(); QBitmap mask( pix->width(), pix->height(), true ); mask.fill( Qt::black ); p.begin( &mask ); p.setPen( Qt::white ); p.drawRect ( 0, 0, pix->width(), pix->height() ); p.end(); pix->setMask( mask ); } return( *pix ); } void OJanusWidget::IconListItem::paint( QPainter *painter ) { QFontMetrics fm = painter->fontMetrics(); //int wt = fm.boundingRect(text()).width(); int wp = mPixmap.width(); int ht = fm.lineSpacing(); int hp = mPixmap.height(); painter->drawPixmap( (mMinimumWidth-wp)/2, 5, mPixmap ); if( text().isEmpty() == false ) { painter->drawText( 0, hp+7, mMinimumWidth, ht, Qt::AlignCenter, text() ); } } int OJanusWidget::IconListItem::height( const QListBox *lb ) const { if( text().isEmpty() == true ) { return( mPixmap.height() ); } else { return( mPixmap.height() + lb->fontMetrics().lineSpacing()+10 ); } } int OJanusWidget::IconListItem::width( const QListBox *lb ) const { int wt = lb->fontMetrics().boundingRect(text()).width()+10; int wp = mPixmap.width() + 10; int w = QMAX( wt, wp ); return( QMAX( w, mMinimumWidth ) ); } // Just remove the page from our stack of widgets. Do not modify the given widget in // any way. No memory leak occurs as parent is not changed. // Make this virtual in KDE 4.0. // Ravikiran Rajagopal <ravi@ee.eng.ohio-state.edu> void OJanusWidget::removePage( QWidget *page ) { if (!mPageList || !mPageList->containsRef(page)) return; int index = mPageList->findRef( page ); if ( mTitleList ) mTitleList->remove(mTitleList->at(index)); mPageList->removeRef(page); if ( mFace == TreeList ) { QMap<QListViewItem*, QWidget *>::Iterator i; for( i = mTreeListToPageStack.begin(); i != mTreeListToPageStack.end(); ++i ) if (i.data()==page) { delete i.key(); mPageStack->removeWidget(page); mTreeListToPageStack.remove(i); break; } } else if ( mFace == IconList ) { QMap<QListBoxItem*, QWidget *>::Iterator i; for( i = mIconListToPageStack.begin(); i != mIconListToPageStack.end(); ++i ) if (i.data()==page) { delete i.key(); mPageStack->removeWidget(page); mIconListToPageStack.remove(i); break; } } else // Tabbed { mTabControl->removePage(page); } } diff --git a/libopie2/qt3/opieui/olineedit.cpp b/libopie2/qt3/opieui/olineedit.cpp index 9cb0cff..6f66fc7 100644 --- a/libopie2/qt3/opieui/olineedit.cpp +++ b/libopie2/qt3/opieui/olineedit.cpp @@ -1,729 +1,729 @@ /* This file Copyright (C) 2003 Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> is part of the Copyright (C) 2001 Carsten Pfeiffer <pfeiffer@kde.org>, Dawit Alemayehu <adawit@kde.org> Opie Project Copyright (C) 1999 Preston Brown <pbrown@kde.org>, Patrick Ward <PAT_WARD@HP-USA-om5.om.hp.com> Copyright (C) 1997 Sven Radej (sven.radej@iname.com) =. .=l. Originally part of the KDE Project .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* QT */ #include <qapplication.h> #include <qclipboard.h> #include <qtimer.h> #include <qpopupmenu.h> /* OPIE */ #include <opie2/ocompletionbox.h> #include <opie2/olineedit.h> #include <opie2/oglobalsettings.h> typedef QString KURL; //FIXME: Revise for Opie /*====================================================================================== * OLineEditPrivate *======================================================================================*/ class OLineEdit::OLineEditPrivate { public: OLineEditPrivate() { grabReturnKeyEvents = false; handleURLDrops = true; completionBox = 0L; } ~OLineEditPrivate() { delete completionBox; } bool grabReturnKeyEvents; bool handleURLDrops; OCompletionBox *completionBox; }; /*====================================================================================== * OLineEdit *======================================================================================*/ OLineEdit::OLineEdit( const QString &string, QWidget *parent, const char *name ) : QLineEdit( string, parent, name ) { init(); } OLineEdit::OLineEdit( QWidget *parent, const char *name ) : QLineEdit( parent, name ) { init(); } OLineEdit::~OLineEdit () { delete d; } void OLineEdit::init() { d = new OLineEditPrivate; possibleTripleClick = false; // Enable the context menu by default. setContextMenuEnabled( true ); //OCursor::setAutoHideCursor( this, true, true ); installEventFilter( this ); } void OLineEdit::setCompletionMode( OGlobalSettings::Completion mode ) { OGlobalSettings::Completion oldMode = completionMode(); if ( oldMode != mode && oldMode == OGlobalSettings::CompletionPopup && d->completionBox && d->completionBox->isVisible() ) d->completionBox->hide(); // If the widgets echo mode is not Normal, no completion // feature will be enabled even if one is requested. if ( echoMode() != QLineEdit::Normal ) mode = OGlobalSettings::CompletionNone; // Override the request. OCompletionBase::setCompletionMode( mode ); } void OLineEdit::setCompletedText( const QString& t, bool marked ) { QString txt = text(); if ( t != txt ) { int curpos = marked ? txt.length() : t.length(); validateAndSet( t, curpos, curpos, t.length() ); } } void OLineEdit::setCompletedText( const QString& text ) { OGlobalSettings::Completion mode = completionMode(); bool marked = ( mode == OGlobalSettings::CompletionAuto || mode == OGlobalSettings::CompletionMan || mode == OGlobalSettings::CompletionPopup ); setCompletedText( text, marked ); } void OLineEdit::rotateText( OCompletionBase::KeyBindingType type ) { OCompletion* comp = compObj(); if ( comp && (type == OCompletionBase::PrevCompletionMatch || type == OCompletionBase::NextCompletionMatch ) ) { QString input = (type == OCompletionBase::PrevCompletionMatch) ? comp->previousMatch() : comp->nextMatch(); // Skip rotation if previous/next match is null or the same text if ( input.isNull() || input == displayText() ) return; #if QT_VERSION > 290 setCompletedText( input, hasSelectedText() ); #else setCompletedText( input, hasMarkedText() ); #endif } } void OLineEdit::makeCompletion( const QString& text ) { OCompletion *comp = compObj(); if ( !comp ) return; // No completion object... QString match = comp->makeCompletion( text ); OGlobalSettings::Completion mode = completionMode(); if ( mode == OGlobalSettings::CompletionPopup ) { if ( match.isNull() ) { if ( d->completionBox ) { d->completionBox->hide(); d->completionBox->clear(); } } else setCompletedItems( comp->allMatches() ); } else { // all other completion modes // If no match or the same match, simply return without completing. if ( match.isNull() || match == text ) return; setCompletedText( match ); } } void OLineEdit::setReadOnly(bool readOnly) { QPalette p = palette(); if (readOnly) { QColor color = p.color(QPalette::Disabled, QColorGroup::Background); p.setColor(QColorGroup::Base, color); p.setColor(QColorGroup::Background, color); } else { QColor color = p.color(QPalette::Normal, QColorGroup::Base); p.setColor(QColorGroup::Base, color); p.setColor(QColorGroup::Background, color); } setPalette(p); QLineEdit::setReadOnly (readOnly); } void OLineEdit::keyPressEvent( QKeyEvent *e ) { qDebug( "OLineEdit::keyPressEvent()" ); /* KKey key( e ); if ( KStdAccel::copy().contains( key ) ) { copy(); return; } else if ( KStdAccel::paste().contains( key ) ) { paste(); return; } else if ( KStdAccel::cut().contains( key ) ) { cut(); return; } else if ( KStdAccel::undo().contains( key ) ) { undo(); return; } else if ( KStdAccel::redo().contains( key ) ) { redo(); return; } else if ( KStdAccel::deleteWordBack().contains( key ) ) { cursorWordBackward(TRUE); if ( hasSelectedText() ) del(); e->accept(); return; } else if ( KStdAccel::deleteWordForward().contains( key ) ) { // Workaround for QT bug where cursorWordForward(TRUE); if ( hasSelectedText() ) del(); e->accept(); return; } */ // Filter key-events if EchoMode is normal & // completion mode is not set to CompletionNone if ( echoMode() == QLineEdit::Normal && completionMode() != OGlobalSettings::CompletionNone ) { KeyBindingMap keys = getKeyBindings(); OGlobalSettings::Completion mode = completionMode(); bool noModifier = (e->state() == NoButton || e->state()== ShiftButton); if ( (mode == OGlobalSettings::CompletionAuto || mode == OGlobalSettings::CompletionMan) && noModifier ) { QString keycode = e->text(); if ( !keycode.isNull() && keycode.unicode()->isPrint() ) { QLineEdit::keyPressEvent ( e ); QString txt = text(); int len = txt.length(); #if QT_VERSION > 290 if ( !hasSelectedText() && len && cursorPosition() == len ) #else if ( !hasMarkedText() && len && cursorPosition() == len ) #endif { if ( emitSignals() ) emit completion( txt ); if ( handleSignals() ) makeCompletion( txt ); e->accept(); } return; } } else if ( mode == OGlobalSettings::CompletionPopup && noModifier ) { qDebug( "OLineEdit::keyPressEvent() - global settings = CompletionPopup & noModifier" ); QString old_txt = text(); QLineEdit::keyPressEvent ( e ); QString txt = text(); int len = txt.length(); QString keycode = e->text(); if ( txt != old_txt && len && cursorPosition() == len && ( (!keycode.isNull() && keycode.unicode()->isPrint()) || e->key() == Key_Backspace ) ) { if ( emitSignals() ) emit completion( txt ); // emit when requested... if ( handleSignals() ) makeCompletion( txt ); // handle when requested... e->accept(); } else if (!len && d->completionBox && d->completionBox->isVisible()) d->completionBox->hide(); return; } /*else if ( mode == OGlobalSettings::CompletionShell ) { // Handles completion. KShortcut cut; if ( keys[TextCompletion].isNull() ) cut = KStdAccel::shortcut(KStdAccel::TextCompletion); else cut = keys[TextCompletion]; if ( cut.contains( key ) ) { // Emit completion if the completion mode is CompletionShell // and the cursor is at the end of the string. QString txt = text(); int len = txt.length(); if ( cursorPosition() == len && len != 0 ) { if ( emitSignals() ) emit completion( txt ); if ( handleSignals() ) makeCompletion( txt ); return; } } else if ( d->completionBox ) d->completionBox->hide(); } // handle rotation if ( mode != OGlobalSettings::CompletionNone ) { // Handles previous match KShortcut cut; if ( keys[PrevCompletionMatch].isNull() ) cut = KStdAccel::shortcut(KStdAccel::PrevCompletion); else cut = keys[PrevCompletionMatch]; if ( cut.contains( key ) ) { if ( emitSignals() ) emit textRotation( OCompletionBase::PrevCompletionMatch ); if ( handleSignals() ) rotateText( OCompletionBase::PrevCompletionMatch ); return; } // Handles next match if ( keys[NextCompletionMatch].isNull() ) cut = KStdAccel::key(KStdAccel::NextCompletion); else cut = keys[NextCompletionMatch]; if ( cut.contains( key ) ) { if ( emitSignals() ) emit textRotation( OCompletionBase::NextCompletionMatch ); if ( handleSignals() ) rotateText( OCompletionBase::NextCompletionMatch ); return; } } // substring completion if ( compObj() ) { KShortcut cut; if ( keys[SubstringCompletion].isNull() ) cut = KStdAccel::shortcut(KStdAccel::SubstringCompletion); else cut = keys[SubstringCompletion]; if ( cut.contains( key ) ) { if ( emitSignals() ) emit substringCompletion( text() ); if ( handleSignals() ) { setCompletedItems( compObj()->substringCompletion(text())); e->accept(); } return; } } */ } // Let QLineEdit handle any other keys events. QLineEdit::keyPressEvent ( e ); } void OLineEdit::mouseDoubleClickEvent( QMouseEvent* e ) { if ( e->button() == Qt::LeftButton ) { possibleTripleClick=true; QTimer::singleShot( QApplication::doubleClickInterval(),this, SLOT(tripleClickTimeout()) ); } QLineEdit::mouseDoubleClickEvent( e ); } void OLineEdit::mousePressEvent( QMouseEvent* e ) { if ( possibleTripleClick && e->button() == Qt::LeftButton ) { selectAll(); return; } QLineEdit::mousePressEvent( e ); } void OLineEdit::tripleClickTimeout() { possibleTripleClick=false; } QPopupMenu *OLineEdit::createPopupMenu() { // Return if popup menu is not enabled !! if ( !m_bEnableMenu ) return 0; #if QT_VERSION > 290 QPopupMenu *popup = QLineEdit::createPopupMenu(); #else QPopupMenu *popup = new QPopupMenu(); #warning OLineEdit is not fully functional on Qt2 #endif // completion object is present. if ( compObj() ) { QPopupMenu *subMenu = new QPopupMenu( popup ); - connect( subMenu, SIGNAL( activated( int ) ), - this, SLOT( completionMenuActivated( int ) ) ); + connect( subMenu, SIGNAL( activated(int) ), + this, SLOT( completionMenuActivated(int) ) ); popup->insertSeparator(); //popup->insertItem( SmallIconSet("completion"), i18n("Text Completion"), // subMenu ); popup->insertItem( tr("Text Completion"), subMenu ); subMenu->insertItem( tr("None"), NoCompletion ); subMenu->insertItem( tr("Manual"), ShellCompletion ); subMenu->insertItem( tr("Automatic"), AutoCompletion ); subMenu->insertItem( tr("Dropdown List"), PopupCompletion ); subMenu->insertItem( tr("Short Automatic"), SemiAutoCompletion ); //subMenu->setAccel( KStdAccel::completion(), ShellCompletion ); subMenu->setAccel( Key_Tab, ShellCompletion ); OGlobalSettings::Completion mode = completionMode(); subMenu->setItemChecked( NoCompletion, mode == OGlobalSettings::CompletionNone ); subMenu->setItemChecked( ShellCompletion, mode == OGlobalSettings::CompletionShell ); subMenu->setItemChecked( PopupCompletion, mode == OGlobalSettings::CompletionPopup ); subMenu->setItemChecked( AutoCompletion, mode == OGlobalSettings::CompletionAuto ); subMenu->setItemChecked( SemiAutoCompletion, mode == OGlobalSettings::CompletionMan ); if ( mode != OGlobalSettings::completionMode() ) { subMenu->insertSeparator(); subMenu->insertItem( tr("Default"), Default ); } } // ### do we really need this? Yes, Please do not remove! This // allows applications to extend the popup menu without having to // inherit from this class! (DA) emit aboutToShowContextMenu( popup ); return popup; } void OLineEdit::completionMenuActivated( int id ) { OGlobalSettings::Completion oldMode = completionMode(); switch ( id ) { case Default: setCompletionMode( OGlobalSettings::completionMode() ); break; case NoCompletion: setCompletionMode( OGlobalSettings::CompletionNone ); break; case AutoCompletion: setCompletionMode( OGlobalSettings::CompletionAuto ); break; case SemiAutoCompletion: setCompletionMode( OGlobalSettings::CompletionMan ); break; case ShellCompletion: setCompletionMode( OGlobalSettings::CompletionShell ); break; case PopupCompletion: setCompletionMode( OGlobalSettings::CompletionPopup ); break; default: return; } if ( oldMode != completionMode() ) { if ( oldMode == OGlobalSettings::CompletionPopup && d->completionBox && d->completionBox->isVisible() ) d->completionBox->hide(); emit completionModeChanged( completionMode() ); } } /*void OLineEdit::dropEvent(QDropEvent *e) { KURL::List urlList; if( d->handleURLDrops && KURLDrag::decode( e, urlList ) ) { QString dropText = text(); KURL::List::ConstIterator it; for( it = urlList.begin() ; it != urlList.end() ; ++it ) { if(!dropText.isEmpty()) dropText+=' '; dropText += (*it).prettyURL(); } validateAndSet( dropText, dropText.length(), 0, 0); e->accept(); } else QLineEdit::dropEvent(e); }*/ bool OLineEdit::eventFilter( QObject* o, QEvent* ev ) { if( o == this ) { //OCursor::autoHideEventFilter( this, ev ); if ( ev->type() == QEvent::AccelOverride ) { QKeyEvent *e = static_cast<QKeyEvent *>( ev ); // if (overrideAccel (e)) // { // e->accept(); // return true; // } } else if( ev->type() == QEvent::KeyPress ) { QKeyEvent *e = static_cast<QKeyEvent *>( ev ); if( e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter ) { bool trap = d->completionBox && d->completionBox->isVisible(); // Qt will emit returnPressed() itself if we return false if ( d->grabReturnKeyEvents || trap ) emit QLineEdit::returnPressed(); emit returnPressed( displayText() ); if ( trap ) d->completionBox->hide(); // Eat the event if the user asked for it, or if a completionbox was visible return d->grabReturnKeyEvents || trap; } } } return QLineEdit::eventFilter( o, ev ); } void OLineEdit::setURLDropsEnabled(bool enable) { d->handleURLDrops=enable; } bool OLineEdit::isURLDropsEnabled() const { return d->handleURLDrops; } void OLineEdit::setTrapReturnKey( bool grab ) { d->grabReturnKeyEvents = grab; } bool OLineEdit::trapReturnKey() const { return d->grabReturnKeyEvents; } /*void OLineEdit::setURL( const KURL& url ) { QLineEdit::setText( url.prettyURL() ); }*/ void OLineEdit::makeCompletionBox() { if ( d->completionBox ) return; d->completionBox = new OCompletionBox( this, "completion box" ); if ( handleSignals() ) { - connect( d->completionBox, SIGNAL(highlighted( const QString& )), - SLOT(setText( const QString& )) ); - connect( d->completionBox, SIGNAL(userCancelled( const QString& )), - SLOT(setText( const QString& )) ); + connect( d->completionBox, SIGNAL(highlighted(const QString&)), + SLOT(setText(const QString&)) ); + connect( d->completionBox, SIGNAL(userCancelled(const QString&)), + SLOT(setText(const QString&)) ); // Nice lil' hacklet ;) KComboBox doesn't know when the completionbox // is created (childEvent() is even more hacky, IMHO), so we simply // forward the completionbox' activated signal from here. if ( parentWidget() && parentWidget()->inherits("KComboBox") ) - connect( d->completionBox, SIGNAL( activated( const QString& )), - parentWidget(), SIGNAL( activated( const QString & ))); + connect( d->completionBox, SIGNAL( activated(const QString&)), + parentWidget(), SIGNAL( activated(const QString&))); } } /*bool OLineEdit::overrideAccel (const QKeyEvent* e) { KShortcut scKey; KKey key( e ); KeyBindingMap keys = getKeyBindings(); if (keys[TextCompletion].isNull()) scKey = KStdAccel::shortcut(KStdAccel::TextCompletion); else scKey = keys[TextCompletion]; if (scKey.contains( key )) return true; if (keys[NextCompletionMatch].isNull()) scKey = KStdAccel::shortcut(KStdAccel::NextCompletion); else scKey = keys[NextCompletionMatch]; if (scKey.contains( key )) return true; if (keys[PrevCompletionMatch].isNull()) scKey = KStdAccel::shortcut(KStdAccel::PrevCompletion); else scKey = keys[PrevCompletionMatch]; if (scKey.contains( key )) return true; if (KStdAccel::deleteWordBack().contains( key )) return true; if (KStdAccel::deleteWordForward().contains( key )) return true; if (d->completionBox && d->completionBox->isVisible ()) if (e->key () == Key_Backtab) return true; return false; }*/ void OLineEdit::setCompletedItems( const QStringList& items ) { QString txt = text(); if ( !items.isEmpty() && !(items.count() == 1 && txt == items.first()) ) { if ( !d->completionBox ) makeCompletionBox(); if ( !txt.isEmpty() ) d->completionBox->setCancelledText( txt ); d->completionBox->setItems( items ); d->completionBox->popup(); } else { if ( d->completionBox && d->completionBox->isVisible() ) d->completionBox->hide(); } } OCompletionBox * OLineEdit::completionBox( bool create ) { if ( create ) makeCompletionBox(); return d->completionBox; } void OLineEdit::setCompletionObject( OCompletion* comp, bool hsig ) { OCompletion *oldComp = compObj(); if ( oldComp && handleSignals() ) - disconnect( oldComp, SIGNAL( matches( const QStringList& )), - this, SLOT( setCompletedItems( const QStringList& ))); + disconnect( oldComp, SIGNAL( matches(const QStringList&)), + this, SLOT( setCompletedItems(const QStringList&))); if ( comp && hsig ) - connect( comp, SIGNAL( matches( const QStringList& )), - this, SLOT( setCompletedItems( const QStringList& ))); + connect( comp, SIGNAL( matches(const QStringList&)), + this, SLOT( setCompletedItems(const QStringList&))); OCompletionBase::setCompletionObject( comp, hsig ); } // QWidget::create() turns off mouse-Tracking which would break auto-hiding void OLineEdit::create( WId id, bool initializeWindow, bool destroyOldWindow ) { QLineEdit::create( id, initializeWindow, destroyOldWindow ); //OCursor::setAutoHideCursor( this, true, true ); } void OLineEdit::clear() { setText( QString::null ); } |