diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-03 02:15:56 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-03 02:15:56 +0000 |
commit | 50b48aec6ddd451a6d1709c0942477b503457663 (patch) | |
tree | a9ece53ec06fd0a2819de7a2a6de997193566626 /src/k3bfiletreecombobox.cpp | |
download | k3b-50b48aec6ddd451a6d1709c0942477b503457663.tar.gz k3b-50b48aec6ddd451a6d1709c0942477b503457663.zip |
Added abandoned KDE3 version of K3B
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/k3b@1084400 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/k3bfiletreecombobox.cpp')
-rw-r--r-- | src/k3bfiletreecombobox.cpp | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/src/k3bfiletreecombobox.cpp b/src/k3bfiletreecombobox.cpp new file mode 100644 index 0000000..ce9b6b7 --- /dev/null +++ b/src/k3bfiletreecombobox.cpp @@ -0,0 +1,393 @@ +/* + * + * $Id: k3bfiletreecombobox.cpp 619556 2007-01-03 17:38:12Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <[email protected]> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + + +#include "k3bfiletreecombobox.h" +#include "k3bfiletreeview.h" + +#include <k3bdevicemanager.h> +#include <k3bdevice.h> +#include <k3bcore.h> +#include <k3bglobals.h> + +#include <qrect.h> +#include <qapplication.h> +#include <qstyle.h> +#include <qlistbox.h> +#include <qheader.h> +#include <qevent.h> +#include <qpainter.h> +#include <qpalette.h> +#include <qdrawutil.h> +#include <qdir.h> + +#include <kdebug.h> +#include <kiconloader.h> +#include <kurlcompletion.h> +#include <kuser.h> + + +class K3bFileTreeComboBox::Private +{ +public: + Private() { + poppedUp = false; + ignoreNextMouseClick = false; + } + bool poppedUp; + bool ignoreNextMouseClick; // used when the view was hidden with the arrow button + + KURLCompletion* urlCompletion; +}; + + +K3bFileTreeComboBox::K3bFileTreeComboBox( QWidget* parent, const char* name ) + : KComboBox( true, parent, name ) +{ + d = new Private; + + d->urlCompletion = new KURLCompletion(); + setCompletionObject( d->urlCompletion ); + + m_fileTreeView = new K3bFileTreeView( this ); + m_fileTreeView->hide(); + m_fileTreeView->reparent( this, WType_Popup, QPoint(0,0), false ); + m_fileTreeView->header()->hide(); + m_fileTreeView->installEventFilter(this); + + m_fileTreeView->addDefaultBranches(); + m_fileTreeView->addCdDeviceBranches( k3bcore->deviceManager() ); + + // HACK! Why the hell is QComboBox that closed??? + listBox()->insertItem( "HACK" ); + + connect( m_fileTreeView, SIGNAL(deviceExecuted(K3bDevice::Device*)), + this, SLOT(slotDeviceExecuted(K3bDevice::Device*)) ); + connect( m_fileTreeView, SIGNAL(urlExecuted(const KURL&)), + this, SLOT(slotUrlExecuted(const KURL&)) ); + + connect( lineEdit(), SIGNAL(returnPressed()), + this, SLOT(slotGoUrl()) ); + + // TODO: subclass KURLCompletition to support the dev:/ stuff and block any non-local urls +} + + +K3bFileTreeComboBox::~K3bFileTreeComboBox() +{ + delete d->urlCompletion; + delete d; +} + + +void K3bFileTreeComboBox::slotDeviceExecuted( K3bDevice::Device* dev ) +{ + setDevice( dev ); + popdown(); + emit deviceExecuted( dev ); +} + + +void K3bFileTreeComboBox::slotUrlExecuted( const KURL& url ) +{ + setUrl( url ); + emit urlExecuted( url ); +} + + +void K3bFileTreeComboBox::setUrl( const KURL& url ) +{ + setEditText( SmallIcon("folder"), K3b::convertToLocalUrl(url).path() ); + popdown(); +} + + +void K3bFileTreeComboBox::setDevice( K3bDevice::Device* dev ) +{ + setEditText( SmallIcon("cdrom_unmount"), dev->vendor() + " " + dev->description() + " (" + dev->blockDeviceName() + ")" ); +} + + +void K3bFileTreeComboBox::setEditText( const QPixmap& pix, const QString& t ) +{ + // QComboBox::changeItem() doesn't honor the pixmap when + // using an editable combobox, so we just remove and insert + + setUpdatesEnabled( false ); + lineEdit()->setUpdatesEnabled( false ); + + removeItem(0); + insertItem( pix, t, 0 ); + lineEdit()->setText( t ); + + setUpdatesEnabled( true ); + lineEdit()->setUpdatesEnabled( true ); + update(); +} + + +void K3bFileTreeComboBox::setCurrentItem( int ) +{ + // the current item is always 0 due to the ugly but quite smart HACK ;) +} + + +void K3bFileTreeComboBox::setCurrentText( const QString& ) +{ +} + + +void K3bFileTreeComboBox::popup() +{ + // code mainly from qcombobox.cpp + + m_fileTreeView->triggerUpdate(); + int w = QMAX( m_fileTreeView->sizeHint().width(), width() ); + int h = m_fileTreeView->sizeHint().height(); + QRect screen = QApplication::desktop()->availableGeometry( this ); + int sx = screen.x(); // screen pos + int sy = screen.y(); + int sw = screen.width(); // screen width + int sh = screen.height(); // screen height + QPoint pos = mapToGlobal( QPoint(0,height()) ); + // ## Similar code is in QPopupMenu + int x = pos.x(); + int y = pos.y(); + + // the complete widget must be visible + if ( x + w > sx + sw ) + x = sx+sw - w; + if ( x < sx ) + x = sx; + if (y + h > sy+sh && y - h - height() >= 0 ) + y = y - h - height(); + + QRect rect = + style().querySubControlMetrics( QStyle::CC_ComboBox, this, + QStyle::SC_ComboBoxListBoxPopup, + QStyleOption( x, y, w, h ) ); + // work around older styles that don't implement the combobox + // listbox popup subcontrol + if ( rect.isNull() ) + rect.setRect( x, y, w, h ); + + m_fileTreeView->setGeometry( rect ); + m_fileTreeView->raise(); + + // TODO: somehow set the current item + + m_fileTreeView->show(); + d->poppedUp = true; + d->ignoreNextMouseClick = false; +} + + +void K3bFileTreeComboBox::popdown() +{ + m_fileTreeView->hide(); + d->poppedUp = false; + repaint(); // repaint the arrow +} + + +void K3bFileTreeComboBox::slotGoUrl() +{ + QString p = currentText(); + + // check for a media url or a device string + if( K3bDevice::Device* dev = K3b::urlToDevice( p ) ) { + emit deviceExecuted( dev ); + return; + } + + // check for our own internal format + else if( p.contains("/dev/") ) { + int pos1 = p.findRev('('); + int pos2 = p.findRev(')'); + QString devStr = p.mid( pos1+1, pos2-pos1-1 ); + if( K3bDevice::Device* dev = k3bcore->deviceManager()->findDevice( devStr ) ) { + emit deviceExecuted( dev ); + return; + } + } + + // no device -> select url + + // + // Properly replace home dirs. + // a single ~ will be replaced with the current user's home dir + // while for example "~ftp" will be replaced by the home dir of user + // ftp + // + // TODO: move this to k3bglobals + + // to expand another user's home dir we need a tilde followed by a user name + static QRegExp someUsersHomeDir( "\\~([^/]+)" ); + int pos = 0; + while( ( pos = someUsersHomeDir.search( p, pos ) ) != -1 ) { + KUser user( someUsersHomeDir.cap(1) ); + if( user.isValid() ) + p.replace( pos, someUsersHomeDir.cap(1).length() + 1, user.homeDir() ); + else + ++pos; // skip this ~ + } + + // now replace the unmatched tildes with our home dir + p.replace( "~", K3b::prepareDir( QDir::homeDirPath() ) ); + + + lineEdit()->setText( p ); + KURL url; + url.setPath( p ); + emit urlExecuted( url ); +} + + +bool K3bFileTreeComboBox::eventFilter( QObject* o, QEvent* e ) +{ + if( dynamic_cast<K3bFileTreeView*>(o) == m_fileTreeView ) { + if( e->type() == QEvent::DragLeave ) { + // the user dragged a dir from the filetree + // now + popdown(); + return true; + } + else if( e->type() == QEvent::KeyPress ) { + QKeyEvent *k = (QKeyEvent *)e; + if( k->key() == Qt::Key_Escape ) { + popdown(); + return true; + } + } + else if( e->type() == QEvent::MouseButtonPress ) { + QMouseEvent* me = (QMouseEvent*)e; + if ( !m_fileTreeView->rect().contains( me->pos() ) ) { + QRect arrowRect = style().querySubControlMetrics( QStyle::CC_ComboBox, this, + QStyle::SC_ComboBoxArrow); + arrowRect = QStyle::visualRect(arrowRect, this); + + // Correction for motif style, where arrow is smaller + // and thus has a rect that doesn't fit the button. + arrowRect.setHeight( QMAX( height() - (2 * arrowRect.y()), arrowRect.height() ) ); + + if ( arrowRect.contains( mapFromGlobal(me->globalPos()) ) ) { + d->ignoreNextMouseClick = true; // in the case we hit the arrow button + } + popdown(); + } + return false; // we need this in the listview + } + + return false; + } + else + return KComboBox::eventFilter(o, e); +} + + +void K3bFileTreeComboBox::mousePressEvent( QMouseEvent* e ) +{ + // mainly from qcombobox.cpp + + if ( e->button() != LeftButton ) + return; + if ( d->ignoreNextMouseClick ) { + d->ignoreNextMouseClick = FALSE; + return; + } + + QRect arrowRect = style().querySubControlMetrics( QStyle::CC_ComboBox, this, + QStyle::SC_ComboBoxArrow); + arrowRect = QStyle::visualRect(arrowRect, this); + + // Correction for motif style, where arrow is smaller + // and thus has a rect that doesn't fit the button. + arrowRect.setHeight( QMAX( height() - (2 * arrowRect.y()), arrowRect.height() ) ); + + if ( arrowRect.contains( e->pos() ) ) { + popup(); + repaint( FALSE ); + } +} + + +void K3bFileTreeComboBox::keyPressEvent( QKeyEvent* e ) +{ + if( e->key() == Qt::Key_Escape ) { + popdown(); + } + KComboBox::keyPressEvent(e); +} + + +void K3bFileTreeComboBox::paintEvent( QPaintEvent* ) +{ + // a lot of code from qcombobox.cpp + + // we only need this since there is no way to change the status of the arrow-button + + QPainter p( this ); + const QColorGroup & g = colorGroup(); + p.setPen(g.text()); + + QStyle::SFlags flags = QStyle::Style_Default; + if (isEnabled()) + flags |= QStyle::Style_Enabled; + if (hasFocus()) + flags |= QStyle::Style_HasFocus; + + if ( width() < 5 || height() < 5 ) { + qDrawShadePanel( &p, rect(), g, FALSE, 2, + &g.brush( QColorGroup::Button ) ); + return; + } + + // bool reverse = QApplication::reverseLayout(); + + style().drawComplexControl( QStyle::CC_ComboBox, &p, this, rect(), g, + flags, QStyle::SC_All, + (d->poppedUp ? + QStyle::SC_ComboBoxArrow : + QStyle::SC_None )); + + QRect re = style().querySubControlMetrics( QStyle::CC_ComboBox, this, + QStyle::SC_ComboBoxEditField ); + re = QStyle::visualRect(re, this); + p.setClipRect( re ); + +// QListBoxItem * item = listBox()->item( 0 ); +// if ( item ) { +// // we calculate the QListBoxTexts height (ignoring strut) +// int itemh = d->listBox()->fontMetrics().lineSpacing() + 2; +// p.translate( re.x(), re.y() + (re.height() - itemh)/2 ); +// item->paint( &p ); +// } +// } else if ( d->listBox() && d->listBox()->item( 0 ) ) { + p.setClipping( FALSE ); + QListBoxItem * item = listBox()->item( 0 ); + const QPixmap *pix = item->pixmap(); + if ( pix ) { + p.fillRect( re.x(), re.y(), pix->width() + 4, re.height(), + colorGroup().brush( QColorGroup::Base ) ); + p.drawPixmap( re.x() + 2, re.y() + + ( re.height() - pix->height() ) / 2, *pix ); + } +// } + p.setClipping( FALSE ); +} + + +#include "k3bfiletreecombobox.moc" + |