kurlcombobox.cpp
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2000,2001 Carsten Pfeiffer <pfeiffer@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2, as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include <qdir.h> 00020 #include <qlistbox.h> 00021 00022 #include <kdebug.h> 00023 #include <kglobal.h> 00024 #include <kiconloader.h> 00025 #include <klocale.h> 00026 #include <kmimetype.h> 00027 00028 #include <kurlcombobox.h> 00029 00030 class KURLComboBox::KURLComboBoxPrivate 00031 { 00032 public: 00033 KURLComboBoxPrivate() { 00034 dirpix = SmallIcon(QString::fromLatin1("folder")); 00035 } 00036 00037 QPixmap dirpix; 00038 }; 00039 00040 00041 KURLComboBox::KURLComboBox( Mode mode, QWidget *parent, const char *name ) 00042 : KComboBox( parent, name ) 00043 { 00044 init( mode ); 00045 } 00046 00047 00048 KURLComboBox::KURLComboBox( Mode mode, bool rw, QWidget *parent, 00049 const char *name ) 00050 : KComboBox( rw, parent, name ) 00051 { 00052 init( mode ); 00053 } 00054 00055 00056 KURLComboBox::~KURLComboBox() 00057 { 00058 delete d; 00059 } 00060 00061 00062 void KURLComboBox::init( Mode mode ) 00063 { 00064 d = new KURLComboBoxPrivate(); 00065 00066 myMode = mode; 00067 urlAdded = false; 00068 myMaximum = 10; // default 00069 itemList.setAutoDelete( true ); 00070 defaultList.setAutoDelete( true ); 00071 setInsertionPolicy( NoInsertion ); 00072 setTrapReturnKey( true ); 00073 setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed )); 00074 00075 opendirPix = SmallIcon(QString::fromLatin1("folder_open")); 00076 00077 connect( this, SIGNAL( activated( int )), SLOT( slotActivated( int ))); 00078 } 00079 00080 00081 QStringList KURLComboBox::urls() const 00082 { 00083 kdDebug(250) << "::urls()" << endl; 00084 //static const QString &fileProt = KGlobal::staticQString("file:"); 00085 QStringList list; 00086 QString url; 00087 for ( int i = defaultList.count(); i < count(); i++ ) { 00088 url = text( i ); 00089 if ( !url.isEmpty() ) { 00090 //if ( url.at(0) == '/' ) 00091 // list.append( url.prepend( fileProt ) ); 00092 //else 00093 list.append( url ); 00094 } 00095 } 00096 00097 return list; 00098 } 00099 00100 00101 void KURLComboBox::addDefaultURL( const KURL& url, const QString& text ) 00102 { 00103 addDefaultURL( url, getPixmap( url ), text ); 00104 } 00105 00106 00107 void KURLComboBox::addDefaultURL( const KURL& url, const QPixmap& pix, 00108 const QString& text ) 00109 { 00110 KURLComboItem *item = new KURLComboItem; 00111 item->url = url; 00112 item->pixmap = pix; 00113 if ( text.isEmpty() ) 00114 if ( url.isLocalFile() ) 00115 item->text = url.path( myMode ); 00116 else 00117 item->text = url.prettyURL( myMode ); 00118 else 00119 item->text = text; 00120 00121 defaultList.append( item ); 00122 } 00123 00124 00125 void KURLComboBox::setDefaults() 00126 { 00127 clear(); 00128 itemMapper.clear(); 00129 00130 KURLComboItem *item; 00131 for ( unsigned int id = 0; id < defaultList.count(); id++ ) { 00132 item = defaultList.at( id ); 00133 insertURLItem( item ); 00134 } 00135 } 00136 00137 void KURLComboBox::setURLs( QStringList urls ) 00138 { 00139 setURLs( urls, RemoveBottom ); 00140 } 00141 00142 void KURLComboBox::setURLs( QStringList urls, OverLoadResolving remove ) 00143 { 00144 setDefaults(); 00145 itemList.clear(); 00146 00147 if ( urls.isEmpty() ) 00148 return; 00149 00150 QStringList::Iterator it = urls.begin(); 00151 00152 // kill duplicates 00153 QString text; 00154 while ( it != urls.end() ) { 00155 while ( urls.contains( *it ) > 1 ) { 00156 it = urls.remove( it ); 00157 continue; 00158 } 00159 ++it; 00160 } 00161 00162 // limit to myMaximum items 00163 /* Note: overload is an (old) C++ keyword, some compilers (KCC) choke 00164 on that, so call it Overload (capital 'O'). (matz) */ 00165 int Overload = urls.count() - myMaximum + defaultList.count(); 00166 while ( Overload > 0 ) { 00167 urls.remove((remove == RemoveBottom) ? urls.fromLast() : urls.begin()); 00168 Overload--; 00169 } 00170 00171 it = urls.begin(); 00172 00173 KURLComboItem *item = 0L; 00174 KURL u; 00175 00176 while ( it != urls.end() ) { 00177 if ( (*it).isEmpty() ) { 00178 ++it; 00179 continue; 00180 } 00181 u = KURL::fromPathOrURL( *it ); 00182 00183 // Don't restore if file doesn't exist anymore 00184 if (u.isLocalFile() && !QFile::exists(u.path())) { 00185 ++it; 00186 continue; 00187 } 00188 00189 item = new KURLComboItem; 00190 item->url = u; 00191 item->pixmap = getPixmap( u ); 00192 00193 if ( u.isLocalFile() ) 00194 item->text = u.path( myMode ); // don't show file:/ 00195 else 00196 item->text = *it; 00197 00198 insertURLItem( item ); 00199 itemList.append( item ); 00200 ++it; 00201 } 00202 } 00203 00204 00205 void KURLComboBox::setURL( const KURL& url ) 00206 { 00207 if ( url.isEmpty() ) 00208 return; 00209 00210 blockSignals( true ); 00211 00212 // check for duplicates 00213 QMap<int,const KURLComboItem*>::ConstIterator mit = itemMapper.begin(); 00214 QString urlToInsert = url.url(-1); 00215 while ( mit != itemMapper.end() ) { 00216 if ( urlToInsert == mit.data()->url.url(-1) ) { 00217 setCurrentItem( mit.key() ); 00218 00219 if ( myMode == Directories ) 00220 updateItem( mit.data(), mit.key(), opendirPix ); 00221 00222 blockSignals( false ); 00223 return; 00224 } 00225 ++mit; 00226 } 00227 00228 // not in the combo yet -> create a new item and insert it 00229 00230 // first remove the old item 00231 if ( urlAdded ) { 00232 itemList.removeLast(); 00233 urlAdded = false; 00234 } 00235 00236 setDefaults(); 00237 00238 QPtrListIterator<KURLComboItem> it( itemList ); 00239 for( ; it.current(); ++it ) 00240 insertURLItem( it.current() ); 00241 00242 KURLComboItem *item = new KURLComboItem; 00243 item->url = url; 00244 item->pixmap = getPixmap( url ); 00245 if ( url.isLocalFile() ) 00246 item->text = url.path( myMode ); 00247 else 00248 item->text = url.prettyURL( myMode ); 00249 kdDebug(250) << "setURL: text=" << item->text << endl; 00250 00251 int id = count(); 00252 QString text = /*isEditable() ? item->url.prettyURL( myMode ) : */ item->text; 00253 00254 if ( myMode == Directories ) 00255 KComboBox::insertItem( opendirPix, text, id ); 00256 else 00257 KComboBox::insertItem( item->pixmap, text, id ); 00258 itemMapper.insert( id, item ); 00259 itemList.append( item ); 00260 00261 setCurrentItem( id ); 00262 urlAdded = true; 00263 blockSignals( false ); 00264 } 00265 00266 00267 void KURLComboBox::slotActivated( int index ) 00268 { 00269 const KURLComboItem *item = itemMapper[ index ]; 00270 00271 if ( item ) { 00272 setURL( item->url ); 00273 emit urlActivated( item->url ); 00274 } 00275 } 00276 00277 00278 void KURLComboBox::insertURLItem( const KURLComboItem *item ) 00279 { 00280 // kdDebug(250) << "insertURLItem " << item->text << endl; 00281 int id = count(); 00282 KComboBox::insertItem( item->pixmap, item->text, id ); 00283 itemMapper.insert( id, item ); 00284 } 00285 00286 00287 void KURLComboBox::setMaxItems( int max ) 00288 { 00289 myMaximum = max; 00290 00291 if ( count() > myMaximum ) { 00292 int oldCurrent = currentItem(); 00293 00294 setDefaults(); 00295 00296 QPtrListIterator<KURLComboItem> it( itemList ); 00297 int Overload = itemList.count() - myMaximum + defaultList.count(); 00298 for ( int i = 0; i <= Overload; i++ ) 00299 ++it; 00300 00301 for( ; it.current(); ++it ) 00302 insertURLItem( it.current() ); 00303 00304 if ( count() > 0 ) { // restore the previous currentItem 00305 if ( oldCurrent >= count() ) 00306 oldCurrent = count() -1; 00307 setCurrentItem( oldCurrent ); 00308 } 00309 } 00310 } 00311 00312 00313 void KURLComboBox::removeURL( const KURL& url, bool checkDefaultURLs ) 00314 { 00315 QMap<int,const KURLComboItem*>::ConstIterator mit = itemMapper.begin(); 00316 while ( mit != itemMapper.end() ) { 00317 if ( url.url(-1) == mit.data()->url.url(-1) ) { 00318 if ( !itemList.remove( mit.data() ) && checkDefaultURLs ) 00319 defaultList.remove( mit.data() ); 00320 } 00321 ++mit; 00322 } 00323 00324 blockSignals( true ); 00325 setDefaults(); 00326 QPtrListIterator<KURLComboItem> it( itemList ); 00327 while ( it.current() ) { 00328 insertURLItem( *it ); 00329 ++it; 00330 } 00331 blockSignals( false ); 00332 } 00333 00334 00335 QPixmap KURLComboBox::getPixmap( const KURL& url ) const 00336 { 00337 if ( myMode == Directories ) 00338 return d->dirpix; 00339 else 00340 return KMimeType::pixmapForURL( url, 0, KIcon::Small ); 00341 } 00342 00343 00344 // updates "item" with pixmap "pixmap" and sets the URL instead of text 00345 // works around a Qt bug. 00346 void KURLComboBox::updateItem( const KURLComboItem *item, 00347 int index, const QPixmap& pixmap ) 00348 { 00349 // QComboBox::changeItem() doesn't honor the pixmap when 00350 // using an editable combobox, so we just remove and insert 00351 if ( editable() ) { 00352 removeItem( index ); 00353 insertItem( pixmap, 00354 item->url.isLocalFile() ? item->url.path( myMode ) : 00355 item->url.prettyURL( myMode ), 00356 index ); 00357 } 00358 else 00359 changeItem( pixmap, item->text, index ); 00360 } 00361 00362 00363 #include "kurlcombobox.moc"