From 4aed2c8219774f5d797760606b8489a92ddc5163 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- konqueror/listview/Makefile.am | 30 + konqueror/listview/konq_detailedlistview.desktop | 89 ++ konqueror/listview/konq_detailedlistview.rc | 52 + konqueror/listview/konq_infolistview.desktop | 87 ++ konqueror/listview/konq_infolistview.rc | 39 + konqueror/listview/konq_infolistviewitem.cc | 281 +++++ konqueror/listview/konq_infolistviewitem.h | 79 ++ konqueror/listview/konq_infolistviewwidget.cc | 383 ++++++ konqueror/listview/konq_infolistviewwidget.h | 89 ++ konqueror/listview/konq_listview.cc | 691 +++++++++++ konqueror/listview/konq_listview.h | 210 ++++ konqueror/listview/konq_listview.kcfg | 37 + konqueror/listview/konq_listviewitems.cc | 449 +++++++ konqueror/listview/konq_listviewitems.h | 123 ++ konqueror/listview/konq_listviewsettings.kcfgc | 4 + konqueror/listview/konq_listviewwidget.cc | 1416 ++++++++++++++++++++++ konqueror/listview/konq_listviewwidget.h | 270 +++++ konqueror/listview/konq_textview.desktop | 90 ++ konqueror/listview/konq_textview.rc | 35 + konqueror/listview/konq_textviewitem.cc | 232 ++++ konqueror/listview/konq_textviewitem.h | 75 ++ konqueror/listview/konq_textviewwidget.cc | 223 ++++ konqueror/listview/konq_textviewwidget.h | 54 + konqueror/listview/konq_treeview.desktop | 90 ++ konqueror/listview/konq_treeview.rc | 52 + konqueror/listview/konq_treeviewitem.cc | 96 ++ konqueror/listview/konq_treeviewitem.h | 79 ++ konqueror/listview/konq_treeviewwidget.cc | 307 +++++ konqueror/listview/konq_treeviewwidget.h | 67 + 29 files changed, 5729 insertions(+) create mode 100644 konqueror/listview/Makefile.am create mode 100644 konqueror/listview/konq_detailedlistview.desktop create mode 100644 konqueror/listview/konq_detailedlistview.rc create mode 100644 konqueror/listview/konq_infolistview.desktop create mode 100644 konqueror/listview/konq_infolistview.rc create mode 100644 konqueror/listview/konq_infolistviewitem.cc create mode 100644 konqueror/listview/konq_infolistviewitem.h create mode 100644 konqueror/listview/konq_infolistviewwidget.cc create mode 100644 konqueror/listview/konq_infolistviewwidget.h create mode 100644 konqueror/listview/konq_listview.cc create mode 100644 konqueror/listview/konq_listview.h create mode 100644 konqueror/listview/konq_listview.kcfg create mode 100644 konqueror/listview/konq_listviewitems.cc create mode 100644 konqueror/listview/konq_listviewitems.h create mode 100644 konqueror/listview/konq_listviewsettings.kcfgc create mode 100644 konqueror/listview/konq_listviewwidget.cc create mode 100644 konqueror/listview/konq_listviewwidget.h create mode 100644 konqueror/listview/konq_textview.desktop create mode 100644 konqueror/listview/konq_textview.rc create mode 100644 konqueror/listview/konq_textviewitem.cc create mode 100644 konqueror/listview/konq_textviewitem.h create mode 100644 konqueror/listview/konq_textviewwidget.cc create mode 100644 konqueror/listview/konq_textviewwidget.h create mode 100644 konqueror/listview/konq_treeview.desktop create mode 100644 konqueror/listview/konq_treeview.rc create mode 100644 konqueror/listview/konq_treeviewitem.cc create mode 100644 konqueror/listview/konq_treeviewitem.h create mode 100644 konqueror/listview/konq_treeviewwidget.cc create mode 100644 konqueror/listview/konq_treeviewwidget.h (limited to 'konqueror/listview') diff --git a/konqueror/listview/Makefile.am b/konqueror/listview/Makefile.am new file mode 100644 index 000000000..91dd33a10 --- /dev/null +++ b/konqueror/listview/Makefile.am @@ -0,0 +1,30 @@ + +INCLUDES = -I$(top_srcdir)/libkonq -I$(top_srcdir)/konqueror $(all_includes) + +kde_module_LTLIBRARIES = konq_listview.la + +METASOURCES = AUTO + +konq_listview_la_SOURCES = konq_listview.cc \ + konq_listviewwidget.cc konq_listviewitems.cc \ + konq_treeviewwidget.cc konq_treeviewitem.cc \ + konq_textviewwidget.cc konq_textviewitem.cc \ + konq_infolistviewwidget.cc konq_infolistviewitem.cc \ + konq_listviewsettings.kcfgc + +konq_listview_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +konq_listview_la_LIBADD = $(top_builddir)/libkonq/libkonq.la + +kde_services_DATA = konq_treeview.desktop konq_detailedlistview.desktop \ + konq_textview.desktop konq_infolistview.desktop + +rcdir = $(kde_datadir)/konqlistview +rc_DATA = konq_treeview.rc konq_detailedlistview.rc konq_textview.rc \ + konq_infolistview.rc + +kde_kcfg_DATA = konq_listview.kcfg + +####### Build rules +konq_listview.lo: konq_listviewsettings.h +konq_listviewsettings.lo: konq_listviewsettings.h +konq_listviewwidget.lo: konq_listviewsettings.h diff --git a/konqueror/listview/konq_detailedlistview.desktop b/konqueror/listview/konq_detailedlistview.desktop new file mode 100644 index 000000000..9dc4938bd --- /dev/null +++ b/konqueror/listview/konq_detailedlistview.desktop @@ -0,0 +1,89 @@ +[Desktop Entry] +Type=Service +Name=Detailed List View +Name[af]=Gedetaileerde Lys Besigtig +Name[ar]=عرض مفصل لوحي +Name[az]=Ətraflı Siyahı Görünüşü +Name[be]=Падрабязны спіс +Name[bg]=Подробен преглед +Name[bn]=বিস্তারিত তালিকা ভিউ +Name[br]=Gwell roll gant munudoù +Name[bs]=Pogled detaljne liste +Name[ca]=Vista de llista detallada +Name[cs]=Detailní pohled +Name[csb]=Wëzdrzatk z akùratną lëstą +Name[cy]=Golwg Rhestr Fanwl +Name[da]=Detaljeret listevisning +Name[de]=Detaillierte Ordneransicht +Name[el]=Προβολή λεπτομερούς λίστας +Name[eo]=Detala listrigardo +Name[es]=Vista de lista detallada +Name[et]=Vaade detailse nimekirjana +Name[eu]=Xehetasundun zerrenda ikuspegia +Name[fa]=نمای فهرست جزئیات +Name[fi]=Yksityiskohtainen listanäkymä +Name[fr]=Liste détaillée +Name[fy]=detaillearre werjefte +Name[ga]=Amharc Liosta Mion +Name[gl]=Vista en Lista Detallada +Name[he]=תצוגת פרטים +Name[hi]=विस्तृत सूची दृश्य +Name[hr]=Detaljan prikaz +Name[hu]=Lista (részletes) +Name[id]=Tampilan list secara detail +Name[is]=Ýtarleg sýn, listi +Name[it]=Vista a lista dettagliata +Name[ja]=詳細なリストビュー +Name[ka]=დაწვრილებითი დიის ხილვა +Name[kk]=Егжей-тегжейлі тізім +Name[km]=ទិដ្ឋភាព​បញ្ជី​លម្អិត +Name[lo]=ມຸມມອງແບບລາບລະອງດ +Name[lt]=Rodyti detalų sąrašą +Name[lv]=Detalizēta saraksta skatījums +Name[mk]=Преглед со детална листа +Name[mn]=Нарийвчилсан жагсаалтаар харах +Name[ms]=Paparan Senarai Terperinci +Name[mt]=Uri Lista Dettaljata +Name[nb]=Detaljert listevisning +Name[nds]=Detailleerte List +Name[ne]=विस्तृत सूची दृश्य +Name[nl]=Gedetailleerde weergave +Name[nn]=Detaljert listevising +Name[nso]=Pono yeo e Tseneletsego ya Palo +Name[pa]=ਵੇਰਵਾ ਸੂਚੀ ਝਲਕ +Name[pl]=Widok ze szczegółową listą +Name[pt]=Vista em Lista Detalhada +Name[pt_BR]=Visão de Lista Detalhada +Name[ro]=Vizualizare listă detaliată +Name[ru]=В виде подробного списка +Name[rw]=Igaragaza ry'Urutonde Rusesenguye +Name[se]=Bienalaš listočájeheapmi +Name[sk]=Detailný zoznam +Name[sl]=Pogled podrobnega seznama +Name[sr]=Детаљан приказ (листа) +Name[sr@Latn]=Detaljan prikaz (lista) +Name[sv]=Detaljerad listvy +Name[ta]=விவரமான பட்டியல் காட்சி +Name[te]=వివరణాత్మక జాబితా వీక్షణం +Name[tg]=Ба намуди саҳифаи ҷузъиёт +Name[th]=มุมมองแบบรายละเอียด +Name[tr]=Ayrıntılı Liste Görünümü +Name[tt]=Täfsille Tezmädä Küreneş +Name[uk]=Детальний вигляд списком +Name[uz]=Batafsil roʻyxat koʻrinishida +Name[uz@cyrillic]=Батафсил рўйхат кўринишида +Name[ven]=Mbonalelo ya mutevhe wo bviselwaho khagala +Name[vi]=Xem kiểu Danh sách Đầy đủ +Name[wa]=Vey en ene sipepieuse djivêye +Name[xh]=Imboniselo Yoluhlu Oluneenkcukacha +Name[zh_CN]=细节列表视图 +Name[zh_TW]=詳細的清單檢視 +Name[zu]=Umbukiso Woluhlu Oluneminingwane +MimeType=inode/directory +ServiceTypes=KParts/ReadOnlyPart,Browser/View +X-KDE-Library=konq_listview +X-KDE-BrowserView-Args=DetailedList +X-KDE-BrowserView-HideFromMenus=true +X-KDE-BrowserView-Built-Into=konqueror +Icon=view_detailed +InitialPreference=7 diff --git a/konqueror/listview/konq_detailedlistview.rc b/konqueror/listview/konq_detailedlistview.rc new file mode 100644 index 000000000..593e7f027 --- /dev/null +++ b/konqueror/listview/konq_detailedlistview.rc @@ -0,0 +1,52 @@ + + + + &Edit + Selection + + + + + + + + + &View + Icon Size + + + + + + + + + + + + + + Show Details + + + + + + + + + + + + + + + + + +Detailed Listview Toolbar + + + + + diff --git a/konqueror/listview/konq_infolistview.desktop b/konqueror/listview/konq_infolistview.desktop new file mode 100644 index 000000000..12186d8f7 --- /dev/null +++ b/konqueror/listview/konq_infolistview.desktop @@ -0,0 +1,87 @@ +[Desktop Entry] +Type=Service +Name=Info List View +Name[af]=Inligting Lys Besigtig +Name[ar]=عرض معلومات لوحي +Name[az]=Məlumat Siyahı Görünüşü +Name[be]=Інфармацыйны спіс +Name[bg]=Информационен преглед +Name[bn]=তথ্য তালিকা ভিউ +Name[bs]=Pogled info liste +Name[ca]=Vista de llista informativa +Name[cs]=Pohled s informačním seznamem +Name[csb]=Wëzdrzatk wëdowiédny lëstë +Name[cy]=Golwg Rhestr Gwybodaeth +Name[da]=Info-listevisning +Name[de]=Infolistenansicht +Name[el]=Προβολή λίστας πληροφοριών +Name[eo]=Inforigardo +Name[es]=Vista de lista de información +Name[et]=Infonimekirja vaade +Name[eu]=Info zerrenda ikuspegia +Name[fa]=نمای فهرست اطلاعات +Name[fi]=Infolistanäkymä +Name[fr]=Affichage de liste info +Name[fy]=Ynfolistwerjefte +Name[ga]=Amharc Liosta Eolais +Name[gl]=Vista en Lista Informativa +Name[he]=תצוגת רשימה +Name[hi]=जानकारी सूची दृश्य +Name[hr]=Prikaz info-popisa +Name[hu]=Lista (rövid) +Name[is]=Upplýsingalisti +Name[it]=Vista informazioni +Name[ja]=情報リストビュー +Name[ka]=სია აღწერით +Name[kk]=Мәліметті тізім +Name[km]=ទិដ្ឋភាព​ព័ត៌មាន​លម្អិត +Name[lo]=ມຸມມອງແບບໄອຄອນ +Name[lt]=Rodyti info sąrašą +Name[lv]=Info saraksta skatījums +Name[mk]=Преглед со инфо. листа +Name[mn]=Мэд. жагсаалтаар харах +Name[ms]=Paparan Senarai Maklumat +Name[mt]=Lista info. +Name[nb]=Infolistevisning +Name[nds]=Infolistansicht +Name[ne]=सूचना सूची दृश्य +Name[nl]=Infolijstweergave +Name[nn]=Infolistevising +Name[nso]=Pono ya Palo ya Tshedimoso +Name[pa]=ਜਾਣਕਾਰੀ ਸੂਚੀ ਝਲਕ +Name[pl]=Widok listy informacyjnej +Name[pt]=Vista em Lista com Informações +Name[pt_BR]=Visão de Lista de Informações +Name[ro]=Vizualizare listă de informații +Name[ru]=В виде списка с описанием +Name[rw]=Igaragaza Urutonde Amakuru +Name[se]=Diehtolistočájeheapmi +Name[sk]=Zoznam s informáciami +Name[sl]=Pogled seznama z informacijami +Name[sr]=Приказ инфо листе +Name[sr@Latn]=Prikaz info liste +Name[sv]=Info-listvy +Name[ta]=தகவல் பட்டியல் காட்சி +Name[te]=సమాచార జాబితా వీక్షణం +Name[tg]=Ба намуди саҳифаи иттилоот +Name[th]=มุมมองแบบรายการข้อมูล +Name[tr]=Bilgi Listesi Görünümü +Name[tt]=Qısqa Tezmädäy Küreneş +Name[uk]=Вигляд з інформацією про зміст +Name[uz]=Maʼlumotli roʻyxat koʻrinishida +Name[uz@cyrillic]=Маълумотли рўйхат кўринишида +Name[ven]=Mbonalelo ya mutevhe wa mafhungo +Name[vi]=Xem kiểu Danh sách Thông tin +Name[wa]=Vey les informåcions en ene djivêye +Name[xh]=Imboniselo Yoluhlu Lolwazi +Name[zh_CN]=信息列表视图 +Name[zh_TW]=資訊清單檢視 +Name[zu]=Umbukiso wohlu lolwazi +MimeType=inode/directory +ServiceTypes=KParts/ReadOnlyPart,Browser/View +X-KDE-Library=konq_listview +X-KDE-BrowserView-Args=InfoListView +X-KDE-BrowserView-HideFromMenus=true +X-KDE-BrowserView-Built-Into=konqueror +Icon=view_detailed +InitialPreference=7 diff --git a/konqueror/listview/konq_infolistview.rc b/konqueror/listview/konq_infolistview.rc new file mode 100644 index 000000000..280b2d0ce --- /dev/null +++ b/konqueror/listview/konq_infolistview.rc @@ -0,0 +1,39 @@ + + + + &Edit + Selection + + + + + + + + + &View + Icon Size + + + + + + + + + + + + + + + + + + +Info Listview Toolbar + + + + + diff --git a/konqueror/listview/konq_infolistviewitem.cc b/konqueror/listview/konq_infolistviewitem.cc new file mode 100644 index 000000000..02aac1d07 --- /dev/null +++ b/konqueror/listview/konq_infolistviewitem.cc @@ -0,0 +1,281 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Rolf Magnus + + 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 version 2.0 + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "konq_listview.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "konq_infolistviewitem.h" +#include "konq_infolistviewwidget.h" + +/************************************************************** + * + * KonqInfoListViewItem + * + **************************************************************/ +KonqInfoListViewItem::KonqInfoListViewItem( KonqInfoListViewWidget *_widget, KonqInfoListViewItem * _parent, KFileItem* _fileitem ) +:KonqBaseListViewItem( _widget,_parent,_fileitem ), m_ILVWidget(_widget) +{ + updateContents(); +} + +KonqInfoListViewItem::KonqInfoListViewItem( KonqInfoListViewWidget *_listViewWidget, KFileItem* _fileitem ) +:KonqBaseListViewItem(_listViewWidget,_fileitem), m_ILVWidget(_listViewWidget) +{ + updateContents(); +} + +void KonqInfoListViewItem::updateContents() +{ + // Set the pixmap + setDisabled( m_bDisabled ); + + // Set the text of each column + setText(0,m_fileitem->text()); + +#if 0 + if (S_ISDIR(m_fileitem->mode())) + sortChar='0'; + //now we have the first column, so let's do the rest + + for (unsigned int i=0; i(listView())->columnConfigInfo()[i]; + if (tmpColumn->displayThisOne) + { + switch (tmpColumn->udsId) + { + case KIO::UDS_USER: + setText(tmpColumn->displayInColumn,m_fileitem->user()); + break; + case KIO::UDS_GROUP: + setText(tmpColumn->displayInColumn,m_fileitem->group()); + break; + case KIO::UDS_FILE_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimeComment()); + break; + case KIO::UDS_MIME_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimetype()); + break; + case KIO::UDS_URL: + setText(tmpColumn->displayInColumn,m_fileitem->url().prettyURL()); + break; + case KIO::UDS_LINK_DEST: + setText(tmpColumn->displayInColumn,m_fileitem->linkDest()); + break; + case KIO::UDS_SIZE: + if ( static_cast(listView())->m_pSettings->fileSizeInBytes() ) + setText(tmpColumn->displayInColumn,KGlobal::locale()->formatNumber( m_fileitem->size(),0)+" "); + else + setText(tmpColumn->displayInColumn,KIO::convertSize(m_fileitem->size())+" "); + break; + case KIO::UDS_ACCESS: + setText(tmpColumn->displayInColumn,m_fileitem->permissionsString()); + break; + case KIO::UDS_MODIFICATION_TIME: + case KIO::UDS_ACCESS_TIME: + case KIO::UDS_CREATION_TIME: + { + QDateTime dt; + time_t _time = m_fileitem->time( tmpColumn->udsId ); + if ( _time != 0 ) + { + dt.setTime_t( _time ); + setText(tmpColumn->displayInColumn,KGlobal::locale()->formatDateTime(dt)); + } + } + break; + default: + break; + }; + }; + }; +#endif +} + +void KonqInfoListViewItem::gotMetaInfo() +{ + KFileMetaInfo info = item()->metaInfo(false); + + if (!info.isValid()) return; + + QStringList::ConstIterator it = m_ILVWidget->columnKeys().begin(); + for (int i = 1; it != m_ILVWidget->columnKeys().end(); ++it, ++i) + { + KFileMetaInfoItem kfmii = info.item(*it); + + m_columnTypes.append(kfmii.type()); + m_columnValues.append(kfmii.value()); + + if (!kfmii.isValid()) + continue; + + QString s = kfmii.string().simplifyWhiteSpace(); + setText(i, s.isNull() ? QString("") : s); + } +} + +int KonqInfoListViewItem::compare( QListViewItem *item, int col, bool ascending ) const +{ + if ( col == 0 ) + return KonqBaseListViewItem::compare( item, 0, ascending ); + + KonqInfoListViewItem *i = static_cast(item); + + int size1 = m_columnValues.size(); + int size2 = i->m_columnValues.size(); + + if ( size1 < col || size2 < col ) + return ascending ? ( size2 - size1 ) : ( size1 - size2 ); + + QVariant value1 = m_columnValues[ col-1 ]; + QVariant value2 = i->m_columnValues[ col-1 ]; + QVariant::Type type1 = m_columnTypes[ col-1 ]; + QVariant::Type type2 = i->m_columnTypes[ col-1 ]; + + if ( type1 != type2 ) + return ascending ? ( type1 - type2 ) : ( type2 - type1 ); + +#define KONQ_CASE( x ) \ + case QVariant::x:\ + return ( value1.to##x() > value2.to##x() ) ? 1 : ( value1.to##x() == value2.to##x() ) ? 0 : -1; + + switch( type1 ) { + KONQ_CASE( Bool ) + KONQ_CASE( Int ) + KONQ_CASE( LongLong ) + KONQ_CASE( UInt ) + KONQ_CASE( ULongLong ) + KONQ_CASE( Double ) + KONQ_CASE( Date ) + KONQ_CASE( Time ) + KONQ_CASE( DateTime ) + case QVariant::Size: + { + int w1 = value1.toSize().width(); + int w2 = value2.toSize().width(); + if ( w1 != w2 ) + return ( w1 > w2 ) ? 1 : -1; + int h1 = value1.toSize().height(); + int h2 = value2.toSize().height(); + return ( h1 > h2 ) ? 1 : ( h1 == h2 ) ? 0 : -1; + } + default: + break; + } +#undef KONQ_CASE + + QString text1 = text(col); + QString text2 = i->text(col); + + if ( text1.isEmpty() ) + return ascending ? 1 : -1; + if ( text2.isEmpty() ) + return ascending ? -1 : 1; + + return text1.lower().localeAwareCompare(text2.lower()); +} + +void KonqInfoListViewItem::setDisabled( bool disabled ) +{ + KonqBaseListViewItem::setDisabled( disabled ); + int iconSize = static_cast(listView())->iconSize(); + iconSize = iconSize ? iconSize : KGlobal::iconLoader()->currentSize( KIcon::Small ); // Default = small + setPixmap( 0, m_fileitem->pixmap( iconSize, state() ) ); +} + +void KonqInfoListViewItem::paintCell( QPainter *_painter, const QColorGroup & _cg, int _column, int _width, int _alignment ) +{ + QColorGroup cg( _cg ); + + if ( _column == 0 ) + { + _painter->setFont( m_pListViewWidget->itemFont() ); + } + + cg.setColor( QColorGroup::Text, m_pListViewWidget->itemColor() ); + + KListView *lv = static_cast< KListView* >( listView() ); + const QPixmap *pm = lv->viewport()->paletteBackgroundPixmap(); + if ( _column == 0 && isSelected() && !lv->allColumnsShowFocus() ) + { + int newWidth = width( lv->fontMetrics(), lv, _column ); + if ( newWidth > _width ) + newWidth = _width; + if ( pm && !pm->isNull() ) + { + cg.setBrush( QColorGroup::Base, QBrush( backgroundColor(_column), *pm ) ); + QPoint o = _painter->brushOrigin(); + _painter->setBrushOrigin( o.x() - lv->contentsX(), o.y() - lv->contentsY() ); + const QColorGroup::ColorRole crole = + QPalette::backgroundRoleFromMode( lv->viewport()->backgroundMode() ); + _painter->fillRect( newWidth, 0, _width - newWidth, height(), cg.brush( crole ) ); + _painter->setBrushOrigin( o ); + } + else + { + _painter->fillRect( newWidth, 0, _width - newWidth, height(), backgroundColor(_column) ); + } + + _width = newWidth; + } + + KListViewItem::paintCell( _painter, cg, _column, _width, _alignment ); +} + +void KonqInfoListViewItem::paintFocus( QPainter * _painter, const QColorGroup & cg, const QRect & _r ) +{ + QRect r( _r ); + QListView *lv = static_cast< QListView * >( listView() ); + r.setWidth( width( lv->fontMetrics(), lv, 0 ) ); + if ( r.right() > lv->header()->sectionRect( 0 ).right() ) + r.setRight( lv->header()->sectionRect( 0 ).right() ); + QListViewItem::paintFocus( _painter, cg, r ); +} + +#if 0 +void KonqBaseListViewItem::mimetypeFound() +{ + // Update icon + setDisabled( m_bDisabled ); + uint done = 0; + KonqBaseListViewWidget * lv = static_cast(listView()); + for (unsigned int i=0; icolumnConfigInfo()[i]; + if (lv->columnConfigInfo()[i].udsId==KIO::UDS_FILE_TYPE && tmpColumn->displayThisOne) + { + setText(tmpColumn->displayInColumn, m_fileitem->mimeComment()); + done++; + } + if (lv->columnConfigInfo()[i].udsId==KIO::UDS_MIME_TYPE && tmpColumn->displayThisOne) + { + setText(tmpColumn->displayInColumn, m_fileitem->mimetype()); + done++; + } + } +} + +#endif diff --git a/konqueror/listview/konq_infolistviewitem.h b/konqueror/listview/konq_infolistviewitem.h new file mode 100644 index 000000000..886ba66af --- /dev/null +++ b/konqueror/listview/konq_infolistviewitem.h @@ -0,0 +1,79 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Rolf Magnus + + 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 version 2.0 + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#ifndef __konq_infolistviewitems_h__ +#define __konq_infolistviewitems_h__ + +#include "konq_listview.h" +#include +#include + +// for mode_t +#include +#include +#include + +class QPainter; +class KFileItem; +class KonqInfoListViewWidget; + +/** + * One item in the info list + */ +class KonqInfoListViewItem : public KonqBaseListViewItem +{ + public: + /** + * Create an item in the tree toplevel representing a file + * @param _parent the parent widget, the tree view + * @param _fileitem the file item created by KDirLister + */ + KonqInfoListViewItem( KonqInfoListViewWidget *_listViewWidget, KFileItem* _fileitem ); + /** + * Create an item representing a file, inside a directory + * @param _treeview the parent tree view - now unused + * @param _parent the parent widget, a directory item in the tree view + * @param _fileitem the file item created by KDirLister + */ + KonqInfoListViewItem( KonqInfoListViewWidget *, KonqInfoListViewItem *_parent, KFileItem* _fileitem ); + + virtual ~KonqInfoListViewItem() { } + + virtual void paintCell( QPainter *_painter, const QColorGroup & cg, + int column, int width, int alignment ); + virtual void paintFocus( QPainter * _painter, const QColorGroup & cg, const QRect & r ); + virtual void updateContents(); + virtual void setDisabled( bool disabled ); + + virtual void gotMetaInfo(); + + virtual int compare(QListViewItem *item, int col, bool ascending) const; + + protected: + /** + * Parent tree view - the info list view widget + */ + KonqInfoListViewWidget* m_ILVWidget; + + private: + QValueVector m_columnTypes; + QValueVector m_columnValues; +}; + +#endif diff --git a/konqueror/listview/konq_infolistviewwidget.cc b/konqueror/listview/konq_infolistviewwidget.cc new file mode 100644 index 000000000..c9ef4b0e4 --- /dev/null +++ b/konqueror/listview/konq_infolistviewwidget.cc @@ -0,0 +1,383 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Rolf Magnus + Copyright (C) 2003 Waldo Bastian + + 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 version 2.0 + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include "konq_infolistviewwidget.h" +#include "konq_infolistviewwidget.moc" +#include "konq_infolistviewitem.h" +#include "konq_listview.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +KonqInfoListViewWidget::KonqInfoListViewWidget( KonqListView* parent, + QWidget* parentWidget) + : KonqBaseListViewWidget(parent, parentWidget) +{ + m_metaInfoJob = 0; + + m_mtSelector = new KSelectAction(i18n("View &As"), 0, this, + SLOT(slotSelectMimeType()), + parent->actionCollection(), "view_as" ); + + kdDebug(1203) << "created info list view\n"; +} + +KonqInfoListViewWidget::~KonqInfoListViewWidget() +{ + delete m_mtSelector; + delete m_metaInfoJob; +} + +void KonqInfoListViewWidget::slotSelectMimeType() +{ + QString comment = m_mtSelector->currentText(); + + // find the mime type by comment + QMapIterator it; + for (it = m_counts.begin(); it!=m_counts.end(); ++it) + { + if ((*it).mimetype->comment() == comment) + { + m_favorite = *it; + createFavoriteColumns(); + rebuildView(); + break; + } + } + +} + +void KonqInfoListViewWidget::createColumns() +{ + if (columns()<1) + { + // we can only create the minimum columns here, because we don't get the + // items, from which we determine the columns yet. + addColumn(i18n("Filename"), m_filenameColumnWidth); + } +} + +void KonqInfoListViewWidget::createFavoriteColumns() +{ + while (columns()>1) + { + kdDebug(1203) << "removing column " << columnText(columns()-1) << endl; + removeColumn(columns()-1); + } + + // we need to get the preferred keys of the favorite + const KFileMimeTypeInfo* mimeTypeInfo; + + if (m_favorite.mimetype && + (mimeTypeInfo = KFileMetaInfoProvider::self() + ->mimeTypeInfo(m_favorite.mimetype->name()))) + { + QStringList preferredCols = mimeTypeInfo->preferredKeys(); + m_columnKeys.clear(); //We create the columnKeys as we're creating + //the actual columns, to make sure they're synced + + // get the translations + QStringList groups = mimeTypeInfo->preferredGroups(); + if (groups.isEmpty()) groups = mimeTypeInfo->supportedGroups(); + + QStringList::Iterator prefKey = preferredCols.begin(); + for (; prefKey != preferredCols.end(); ++prefKey) + { + QStringList::Iterator group = groups.begin(); + for (; group != groups.end(); ++group) + { + const KFileMimeTypeInfo::GroupInfo* groupInfo = + mimeTypeInfo->groupInfo(*group); + if(groupInfo) + { + QStringList keys = groupInfo->supportedKeys(); + QStringList::Iterator key = keys.begin(); + for (; key != keys.end(); ++key) + { + if ( *key == *prefKey ) + { + const KFileMimeTypeInfo::ItemInfo* itemInfo = + groupInfo->itemInfo(*key); + addColumn(itemInfo->translatedKey()); + m_columnKeys.append(*key); + } + } + } + } + } + } + else + { + KonqBaseListViewWidget::createColumns(); + } + +} + +bool KonqInfoListViewWidget::openURL( const KURL &url ) +{ + bool ret = KonqBaseListViewWidget::openURL(url); + m_bTopLevelComplete = true; + return ret; +} + +void KonqInfoListViewWidget::rebuildView() +{ + // make a KFileItemList from all our Items + KFileItemList list; + + QListViewItemIterator it(this); + for (; it.current(); ++it) + { + list.append(static_cast(it.current())->item()); + } + + // now we can remove all the listview items + clear(); + + // and rebuild them + for (QPtrListIterator kit(list); kit.current(); ++kit) + { + KonqInfoListViewItem* tmp = new KonqInfoListViewItem( this, *kit ); +// if (m_goToFirstItem==false) +// if (m_itemFound==false) +// if (tmp->text(0)==m_itemToGoTo) +// { +//kdDebug() << "Line " << __LINE__ << endl; +// setCurrentItem(tmp); +//kdDebug() << "Line " << __LINE__ << endl; +// ensureItemVisible(tmp); +//kdDebug() << "Line " << __LINE__ << endl; +// emit selectionChanged(); + //selectCurrentItemAndEnableSelectedBySimpleMoveMode(); +// m_itemFound=true; +//kdDebug() << "Line " << __LINE__ << endl; +// }; + + tmp->gotMetaInfo(); + } + + + if ( !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } +} + +void KonqInfoListViewWidget::slotNewItems( const KFileItemList& list) +{ + slotStarted(); // ############# WHY? + for (QPtrListIterator kit ( list ); kit.current(); ++kit ) + { + KonqInfoListViewItem * tmp = new KonqInfoListViewItem( this, *kit ); + + if (!m_itemFound && tmp->text(0)==m_itemToGoTo) + { + setCurrentItem(tmp); + m_itemFound=true; + } + + if ( !m_itemsToSelect.isEmpty() ) { + QStringList::Iterator tsit = m_itemsToSelect.find( (*kit)->name() ); + if ( tsit != m_itemsToSelect.end() ) { + m_itemsToSelect.remove( tsit ); + setSelected( tmp, true ); + } + } + + if ( !(*kit)->isMimeTypeKnown() ) + m_pBrowserView->lstPendingMimeIconItems().append( tmp ); + } + m_pBrowserView->newItems( list ); + + if ( !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } + + slotUpdateBackground(); + + if ( !m_favorite.mimetype ) + determineCounts(list); + + kdDebug(1203) << " ------------------------ startin metainfo job ------\n"; + + // start getting metainfo from the files + if (m_metaInfoJob) + { + for (QPtrListIterator kit ( list ); kit.current(); ++kit ) + m_metaInfoTodo.append(kit.current()); + } + else + { + m_metaInfoJob = KIO::fileMetaInfo(list); + connect( m_metaInfoJob, SIGNAL( gotMetaInfo( const KFileItem*)), + this, SLOT( slotMetaInfo( const KFileItem*))); + connect( m_metaInfoJob, SIGNAL( result( KIO::Job*)), + this, SLOT( slotMetaInfoResult())); + } +} + +void KonqInfoListViewWidget::slotRefreshItems( const KFileItemList& list) +{ + kdDebug(1203) << " ------------------------ startin metainfo job ------\n"; + + // start getting metainfo from the files + if (m_metaInfoJob) + { + for (QPtrListIterator kit ( list ); kit.current(); ++kit ) + m_metaInfoTodo.append(kit.current()); + } + else + { + m_metaInfoJob = KIO::fileMetaInfo(list); + connect( m_metaInfoJob, SIGNAL( gotMetaInfo( const KFileItem*)), + this, SLOT( slotMetaInfo( const KFileItem*))); + connect( m_metaInfoJob, SIGNAL( result( KIO::Job*)), + this, SLOT( slotMetaInfoResult())); + } + KonqBaseListViewWidget::slotRefreshItems(list); +} + +void KonqInfoListViewWidget::slotDeleteItem( KFileItem * item ) +{ + m_metaInfoTodo.removeRef(item); + if (m_metaInfoJob) + m_metaInfoJob->removeItem(item); + + KonqBaseListViewWidget::slotDeleteItem(item); +} + +void KonqInfoListViewWidget::slotClear() +{ + m_metaInfoTodo.clear(); + delete m_metaInfoJob; + m_metaInfoJob = 0; + m_favorite = KonqILVMimeType(); + + KonqBaseListViewWidget::slotClear(); +} + +void KonqInfoListViewWidget::slotMetaInfo(const KFileItem* item) +{ + // need to search for the item (any better way?) + QListViewItemIterator it(this); + for (; it.current(); ++it) + { + if (static_cast(it.current())->item()==item) + { + static_cast(it.current())->gotMetaInfo(); + return; + } + } + + // we should never reach this place + Q_ASSERT(false); +} + +void KonqInfoListViewWidget::slotMetaInfoResult() +{ + m_metaInfoJob = 0; + if (m_metaInfoTodo.isEmpty()) + { + m_bTopLevelComplete = false; + kdDebug(1203) << "emitting completed!!!!!!!!!!!!!!!!\n"; + slotCompleted(); + } + else + { + m_metaInfoJob = KIO::fileMetaInfo(m_metaInfoTodo); + connect( m_metaInfoJob, SIGNAL( gotMetaInfo( const KFileItem*)), + this, SLOT( slotMetaInfo( const KFileItem*))); + connect( m_metaInfoJob, SIGNAL( result( KIO::Job*)), + this, SLOT( slotMetaInfoResult())); + m_metaInfoTodo.clear(); + } +} + +void KonqInfoListViewWidget::determineCounts(const KFileItemList& list) +{ + m_counts.clear(); + m_favorite = KonqILVMimeType(); + // get the counts + for (KFileItemListIterator it(list); it.current(); ++it) + { + QString mt = it.current()->mimetype(); + m_counts[mt].count++; + if (!m_counts[mt].mimetype) + m_counts[mt].mimetype = it.current()->determineMimeType(); + } + + // and look for the plugins + kdDebug(1203) << "counts are:\n"; + + KFileMetaInfoProvider* prov = KFileMetaInfoProvider::self(); + + QStringList mtlist; + + QMapIterator it; + for (it = m_counts.begin(); it!=m_counts.end(); ++it) + { + // look if there is a plugin for this mimetype + // and look for the "favorite" mimetype +#ifdef _GNUC +#warning ### change this +#endif + // this will load the plugin which we don't need because we delegate + // the job to the kioslave + (*it).hasPlugin = prov->plugin(it.key()); + + if ( (*it).hasPlugin) + { + mtlist << (*it).mimetype->comment(); + if (m_favorite.count <= (*it).count) + m_favorite = *it; + } + + kdDebug(1203) << it.key() << " -> " << (*it).count + << " item(s) / plugin: " + << ((*it).hasPlugin ? "yes" : "no ") << endl; + } + + m_mtSelector->setItems(mtlist); +// QPopupMenu* menu = m_mtSelector->popupMenu(); + + // insert the icons +// for (int i=0; icount(); ++i) +// { +// menu->changeItem(i, QIconSet(blah)); +// } + + if (m_favorite.mimetype) + { + m_mtSelector->setCurrentItem(mtlist.findIndex(m_favorite.mimetype->comment())); + kdDebug(1203) << "favorite mimetype is " << m_favorite.mimetype->name() << endl; + } + createFavoriteColumns(); +} + diff --git a/konqueror/listview/konq_infolistviewwidget.h b/konqueror/listview/konq_infolistviewwidget.h new file mode 100644 index 000000000..9d866dc1f --- /dev/null +++ b/konqueror/listview/konq_infolistviewwidget.h @@ -0,0 +1,89 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Rolf Magnus + + 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 version 2.0 + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef __KONQ_INFOLISTVIEWWIDGET_H__ +#define __KONQ_INFOLISTVIEWWIDGET_H__ + +#include "konq_listviewwidget.h" + +#include +#include +#include + +namespace KIO {class MetaInfoJob;} +class KonqListView; +class KSelectAction; + +/** + * The info list view + */ +class KonqInfoListViewWidget : public KonqBaseListViewWidget +{ +// friend class KonqTextViewItem; + Q_OBJECT + public: + KonqInfoListViewWidget( KonqListView *parent, QWidget *parentWidget ); + ~KonqInfoListViewWidget(); + + const QStringList columnKeys() {return m_columnKeys;} + + virtual bool openURL( const KURL &url ); + + protected slots: + // slots connected to the directory lister +// virtual void setComplete(); + virtual void slotNewItems( const KFileItemList & ); + virtual void slotRefreshItems( const KFileItemList & ); + virtual void slotDeleteItem( KFileItem * ); + virtual void slotClear(); + virtual void slotSelectMimeType(); + + void slotMetaInfo(const KFileItem*); + void slotMetaInfoResult(); + + protected: + void determineCounts(const KFileItemList& list); + void rebuildView(); + + virtual void createColumns(); + void createFavoriteColumns(); + + /** + * @internal + */ + struct KonqILVMimeType + { + KonqILVMimeType() : mimetype(0), count(0), hasPlugin(false) {}; + + KMimeType::Ptr mimetype; + int count; + bool hasPlugin; + }; + + // all the mimetypes + QMap m_counts; + QStringList m_columnKeys; + + KonqILVMimeType m_favorite; + + KSelectAction* m_mtSelector; + KIO::MetaInfoJob* m_metaInfoJob; + KFileItemList m_metaInfoTodo; +}; + +#endif diff --git a/konqueror/listview/konq_listview.cc b/konqueror/listview/konq_listview.cc new file mode 100644 index 000000000..1e67fce36 --- /dev/null +++ b/konqueror/listview/konq_listview.cc @@ -0,0 +1,691 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis + + 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. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "konq_listview.h" +#include "konq_textviewwidget.h" +#include "konq_treeviewwidget.h" +#include "konq_infolistviewwidget.h" +#include "konq_listviewsettings.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +KonqListViewFactory::KonqListViewFactory() +{ + s_instance = 0; + s_defaultViewProps = 0; +} + +KonqListViewFactory::~KonqListViewFactory() +{ + delete s_instance; + delete s_defaultViewProps; + + s_instance = 0; + s_defaultViewProps = 0; +} + +KParts::Part* KonqListViewFactory::createPartObject( QWidget *parentWidget, const char *, QObject *parent, const char *name, const char*, const QStringList &args ) +{ + if( args.count() < 1 ) + kdWarning() << "KonqListView: Missing Parameter" << endl; + + KParts::Part *obj = new KonqListView( parentWidget, parent, name, args.first() ); + return obj; +} + +KInstance *KonqListViewFactory::instance() +{ + if ( !s_instance ) + s_instance = new KInstance( "konqlistview" ); + return s_instance; +} + +KonqPropsView *KonqListViewFactory::defaultViewProps() +{ + if ( !s_defaultViewProps ) + s_defaultViewProps = new KonqPropsView( instance(),0L ); + //s_defaultViewProps = KonqPropsView::defaultProps( instance() ); + + return s_defaultViewProps; +} + +KInstance *KonqListViewFactory::s_instance = 0; +KonqPropsView *KonqListViewFactory::s_defaultViewProps = 0; + +K_EXPORT_COMPONENT_FACTORY( konq_listview, KonqListViewFactory ) + +ListViewBrowserExtension::ListViewBrowserExtension( KonqListView *listView ) + : KonqDirPartBrowserExtension( listView ) +{ + m_listView = listView; +} + +int ListViewBrowserExtension::xOffset() +{ + //kdDebug(1202) << k_funcinfo << endl; + return m_listView->listViewWidget()->contentsX(); +} + +int ListViewBrowserExtension::yOffset() +{ + //kdDebug(1202) << k_funcinfo << endl; + return m_listView->listViewWidget()->contentsY(); +} + +void ListViewBrowserExtension::updateActions() +{ + // This code is very related to KonqIconViewWidget::slotSelectionChanged + int canCopy = 0; + int canDel = 0; + int canTrash = 0; + bool bInTrash = false; + KFileItemList lstItems = m_listView->selectedFileItems(); + + for (KFileItem *item = lstItems.first(); item; item = lstItems.next()) + { + canCopy++; + KURL url = item->url(); + if ( url.directory(false) == KGlobalSettings::trashPath() ) + bInTrash = true; + if ( KProtocolInfo::supportsDeleting( url ) ) + canDel++; + if ( !item->localPath().isEmpty() ) + canTrash++; + } + + emit enableAction( "copy", canCopy > 0 ); + emit enableAction( "cut", canDel > 0 ); + emit enableAction( "trash", canDel > 0 && !bInTrash && canDel == canTrash ); + emit enableAction( "del", canDel > 0 ); + emit enableAction( "properties", lstItems.count() > 0 && KPropertiesDialog::canDisplay( lstItems ) ); + emit enableAction( "editMimeType", ( lstItems.count() == 1 ) ); + emit enableAction( "rename", ( m_listView->listViewWidget()->currentItem() != 0 )&& !bInTrash ); +} + +void ListViewBrowserExtension::copySelection( bool move ) +{ + KonqDrag *urlData = new KonqDrag( m_listView->listViewWidget()->selectedUrls(false), m_listView->listViewWidget()->selectedUrls(true), move ); + QApplication::clipboard()->setData( urlData ); +} + +void ListViewBrowserExtension::paste() +{ + KonqOperations::doPaste( m_listView->listViewWidget(), m_listView->url() ); +} + +void ListViewBrowserExtension::pasteTo( const KURL& url ) +{ + KonqOperations::doPaste( m_listView->listViewWidget(), url ); +} + +void ListViewBrowserExtension::rename() +{ + QListViewItem* item = m_listView->listViewWidget()->currentItem(); + Q_ASSERT ( item ); + m_listView->listViewWidget()->rename( item, 0 ); + + // Enhanced rename: Don't highlight the file extension. + KLineEdit* le = m_listView->listViewWidget()->renameLineEdit(); + if ( le ) { + const QString txt = le->text(); + QString pattern; + KMimeType::diagnoseFileName( txt, pattern ); + if (!pattern.isEmpty() && pattern.at(0)=='*' && pattern.find('*',1)==-1) + le->setSelection(0, txt.length()-pattern.stripWhiteSpace().length()+1); + else + { + int lastDot = txt.findRev('.'); + if (lastDot > 0) + le->setSelection(0, lastDot); + } + } +} + +void ListViewBrowserExtension::trash() +{ + KonqOperations::del(m_listView->listViewWidget(), + KonqOperations::TRASH, + m_listView->listViewWidget()->selectedUrls( true )); +} + +void ListViewBrowserExtension::reparseConfiguration() +{ + // m_pProps is a problem here (what is local, what is global ?) + // but settings is easy : + m_listView->listViewWidget()->initConfig(); +} + +void ListViewBrowserExtension::setSaveViewPropertiesLocally(bool value) +{ + m_listView->props()->setSaveViewPropertiesLocally( value ); +} + +void ListViewBrowserExtension::setNameFilter( const QString &nameFilter ) +{ + m_listView->setNameFilter( nameFilter ); +} + +void ListViewBrowserExtension::properties() +{ + (void) new KPropertiesDialog( m_listView->selectedFileItems() ); +} + +void ListViewBrowserExtension::editMimeType() +{ + KFileItemList items = m_listView->selectedFileItems(); + assert ( items.count() == 1 ); + KonqOperations::editMimeType( items.first()->mimetype() ); +} + +KonqListView::KonqListView( QWidget *parentWidget, QObject *parent, const char *name, const QString& mode ) + : KonqDirPart( parent, name ) +,m_headerTimer(0) +{ + setInstance( KonqListViewFactory::instance(), false ); + + // Create a properties instance for this view + // All the listview view modes inherit the same properties defaults... + m_pProps = new KonqPropsView( KonqListViewFactory::instance(), KonqListViewFactory::defaultViewProps() ); + + setBrowserExtension( new ListViewBrowserExtension( this ) ); + + QString xmlFile; + + if (mode=="TextView") + { + kdDebug(1202) << "Creating KonqTextViewWidget" << endl; + xmlFile = "konq_textview.rc"; + m_pListView=new KonqTextViewWidget(this, parentWidget); + } + else if (mode=="MixedTree") + { + kdDebug(1202) << "Creating KonqTreeViewWidget" << endl; + xmlFile = "konq_treeview.rc"; + m_pListView=new KonqTreeViewWidget(this,parentWidget); + } + else if (mode=="InfoListView") + { + kdDebug(1202) << "Creating KonqInfoListViewWidget" << endl; + xmlFile = "konq_infolistview.rc"; + m_pListView=new KonqInfoListViewWidget(this,parentWidget); + } + else + { + kdDebug(1202) << "Creating KonqDetailedListViewWidget" << endl; + xmlFile = "konq_detailedlistview.rc"; + m_pListView = new KonqBaseListViewWidget( this, parentWidget); + } + setWidget( m_pListView ); + setDirLister( m_pListView->m_dirLister ); + + m_mimeTypeResolver = new KMimeTypeResolver(this); + + setXMLFile( xmlFile ); + + setupActions(); + + m_pListView->confColumns.resize( 11 ); + m_pListView->confColumns[0].setData(I18N_NOOP("MimeType"),"Type",KIO::UDS_MIME_TYPE,m_paShowMimeType); + m_pListView->confColumns[1].setData(I18N_NOOP("Size"),"Size",KIO::UDS_SIZE,m_paShowSize); + m_pListView->confColumns[2].setData(I18N_NOOP("Modified"),"Date",KIO::UDS_MODIFICATION_TIME,m_paShowTime); + m_pListView->confColumns[3].setData(I18N_NOOP("Accessed"),"AccessDate",KIO::UDS_ACCESS_TIME,m_paShowAccessTime); + m_pListView->confColumns[4].setData(I18N_NOOP("Created"),"CreationDate",KIO::UDS_CREATION_TIME,m_paShowCreateTime); + m_pListView->confColumns[5].setData(I18N_NOOP("Permissions"),"Access",KIO::UDS_ACCESS,m_paShowPermissions); + m_pListView->confColumns[6].setData(I18N_NOOP("Owner"),"Owner",KIO::UDS_USER,m_paShowOwner); + m_pListView->confColumns[7].setData(I18N_NOOP("Group"),"Group",KIO::UDS_GROUP,m_paShowGroup); + m_pListView->confColumns[8].setData(I18N_NOOP("Link"),"Link",KIO::UDS_LINK_DEST,m_paShowLinkDest); + m_pListView->confColumns[9].setData(I18N_NOOP("URL"),"URL",KIO::UDS_URL,m_paShowURL); + // Note: File Type is in fact the mimetype comment. We use UDS_FILE_TYPE but that's not what we show in fact :/ + m_pListView->confColumns[10].setData(I18N_NOOP("File Type"),"Type",KIO::UDS_FILE_TYPE,m_paShowType); + + + connect( m_pListView, SIGNAL( selectionChanged() ), + m_extension, SLOT( updateActions() ) ); + connect( m_pListView, SIGNAL( selectionChanged() ), + this, SLOT( slotSelectionChanged() ) ); + + connect( m_pListView, SIGNAL( currentChanged(QListViewItem*) ), + m_extension, SLOT( updateActions() ) ); + connect(m_pListView->header(),SIGNAL(indexChange(int,int,int)),this,SLOT(headerDragged(int,int,int))); + connect(m_pListView->header(),SIGNAL(clicked(int)),this,SLOT(slotHeaderClicked(int))); + connect(m_pListView->header(),SIGNAL(sizeChange(int,int,int)),SLOT(slotHeaderSizeChanged())); + + // signals from konqdirpart (for BC reasons) + connect( this, SIGNAL( findOpened( KonqDirPart * ) ), SLOT( slotKFindOpened() ) ); + connect( this, SIGNAL( findClosed( KonqDirPart * ) ), SLOT( slotKFindClosed() ) ); + + loadPlugins( this, this, instance() ); +} + +KonqListView::~KonqListView() +{ + delete m_mimeTypeResolver; + delete m_pProps; +} + +void KonqListView::guiActivateEvent( KParts::GUIActivateEvent *event ) +{ + KonqDirPart::guiActivateEvent(event ); + //ReadOnlyPart::guiActivateEvent(event ); + ((ListViewBrowserExtension*)m_extension)->updateActions(); +} + +bool KonqListView::doOpenURL( const KURL &url ) +{ + KURL u( url ); + const QString prettyURL = url.pathOrURL(); + emit setWindowCaption( prettyURL ); + return m_pListView->openURL( url ); +} + +bool KonqListView::doCloseURL() +{ + m_pListView->stop(); + m_mimeTypeResolver->m_lstPendingMimeIconItems.clear(); + return true; +} + +void KonqListView::listingComplete() +{ + m_mimeTypeResolver->start( /*10*/ 0 ); +} + +void KonqListView::determineIcon( KonqBaseListViewItem * item ) +{ + //int oldSerial = item->pixmap(0)->serialNumber(); + + (void) item->item()->determineMimeType(); + + //QPixmap newIcon = item->item()->pixmap( m_parent->iconSize(), + // item->state() ); + //if ( oldSerial != newIcon.serialNumber() ) + // item->setPixmap( 0, newIcon ); + + // We also have columns to update, not only the icon + item->updateContents(); +} + +void KonqListView::saveState( QDataStream &stream ) +{ + //kdDebug(1202) << k_funcinfo << endl; + KonqDirPart::saveState( stream ); + m_pListView->saveState( stream ); +} + +void KonqListView::restoreState( QDataStream &stream ) +{ + //kdDebug(1202) << k_funcinfo << endl; + KonqDirPart::restoreState( stream ); + m_pListView->restoreState( stream ); +} + +void KonqListView::disableIcons( const KURL::List &lst ) +{ + m_pListView->disableIcons( lst ); +} + +void KonqListView::slotSelect() +{ + bool ok; + QString pattern = KInputDialog::getText( QString::null, + i18n( "Select files:" ), "*", &ok, m_pListView ); + if ( !ok ) + return; + + QRegExp re( pattern, true, true ); + + m_pListView->blockSignals( true ); + + for (KonqBaseListViewWidget::iterator it = m_pListView->begin(); it != m_pListView->end(); it++ ) + { + if ((m_pListView->automaticSelection()) && (it->isSelected())) + { + it->setSelected(FALSE); + //the following line is to prevent that more than one item were selected + //and now get deselected and automaticSelection() was true, this shouldn't happen + //but who knows, aleXXX + m_pListView->deactivateAutomaticSelection(); + }; + if ( re.exactMatch( it->text(0) ) ) + it->setSelected( TRUE); + }; + m_pListView->blockSignals( false ); + m_pListView->deactivateAutomaticSelection(); + emit m_pListView->selectionChanged(); + m_pListView->viewport()->update(); +} + +void KonqListView::slotUnselect() +{ + bool ok; + QString pattern = KInputDialog::getText( QString::null, + i18n( "Unselect files:" ), "*", &ok, m_pListView ); + if ( !ok ) + return; + + QRegExp re( pattern, TRUE, TRUE ); + + m_pListView->blockSignals(TRUE); + + for (KonqBaseListViewWidget::iterator it = m_pListView->begin(); it != m_pListView->end(); it++ ) + if ( re.exactMatch( it->text(0) ) ) + it->setSelected(FALSE); + + m_pListView->blockSignals(FALSE); + m_pListView->deactivateAutomaticSelection(); + emit m_pListView->selectionChanged(); + m_pListView->viewport()->update(); +} + +void KonqListView::slotSelectAll() +{ + m_pListView->selectAll(TRUE); + m_pListView->deactivateAutomaticSelection(); + emit m_pListView->selectionChanged(); +} + +void KonqListView::slotUnselectAll() +{ + m_pListView->selectAll(FALSE); + m_pListView->deactivateAutomaticSelection(); + emit m_pListView->selectionChanged(); +} + + +void KonqListView::slotInvertSelection() +{ + if ((m_pListView->automaticSelection()) + && (m_pListView->currentItem()!=0) + && (m_pListView->currentItem()->isSelected())) + m_pListView->currentItem()->setSelected(FALSE); + + m_pListView->invertSelection(); + m_pListView->deactivateAutomaticSelection(); + emit m_pListView->selectionChanged(); + m_pListView->viewport()->update(); +} + +void KonqListView::newIconSize( int size ) +{ + KonqDirPart::newIconSize( size ); + m_pListView->updateListContents(); +} + +void KonqListView::slotShowDot() +{ + m_pProps->setShowingDotFiles( m_paShowDot->isChecked() ); + m_pListView->m_dirLister->setShowingDotFiles( m_pProps->isShowingDotFiles() ); + m_pListView->m_dirLister->emitChanges(); +} + +void KonqListView::slotCaseInsensitive() +{ + m_pProps->setCaseInsensitiveSort( m_paCaseInsensitive->isChecked() ); + m_pListView->sort(); +} + +void KonqListView::slotColumnToggled() +{ + kdDebug(1202) << "::slotColumnToggled" << endl; + for (uint i=0; iNumberOfAtoms; i++) + { + m_pListView->confColumns[i].displayThisOne=!m_pListView->confColumns[i].toggleThisOne + || (m_pListView->confColumns[i].toggleThisOne->isChecked()&&m_pListView->confColumns[i].toggleThisOne->isEnabled()); + //this column has been enabled, the columns after it slide one column back + if ((m_pListView->confColumns[i].displayThisOne) && (m_pListView->confColumns[i].displayInColumn==-1)) + { + int maxColumn(0); + for (uint j=0; jNumberOfAtoms; j++) + if ((m_pListView->confColumns[j].displayInColumn>maxColumn) && (m_pListView->confColumns[j].displayThisOne)) + maxColumn=m_pListView->confColumns[j].displayInColumn; + m_pListView->confColumns[i].displayInColumn=maxColumn+1; + } + //this column has been disabled, the columns after it slide one column + if ((!m_pListView->confColumns[i].displayThisOne) && (m_pListView->confColumns[i].displayInColumn!=-1)) + { + for (uint j=0; jNumberOfAtoms; j++) + if (m_pListView->confColumns[j].displayInColumn>m_pListView->confColumns[i].displayInColumn) + m_pListView->confColumns[j].displayInColumn--; + m_pListView->confColumns[i].displayInColumn=-1; + } + } + + //create the new list contents + m_pListView->createColumns(); + m_pListView->updateListContents(); + + //save the config + QStringList lstColumns; + int currentColumn(m_pListView->m_filenameColumn+1); + for (int i=0; i<(int)m_pListView->NumberOfAtoms; i++) + { + kdDebug(1202)<<"checking: -"<confColumns[i].name<<"-"<confColumns[i].displayThisOne) && (currentColumn==m_pListView->confColumns[i].displayInColumn)) + { + lstColumns.append(m_pListView->confColumns[i].name); + kdDebug(1202)<<" adding"<url().protocol() ); + config.readConfig(); + config.setColumns( lstColumns ); + config.writeConfig(); + + // Update column sizes + slotHeaderSizeChanged(); +} + +void KonqListView::slotHeaderClicked(int sec) +{ + kdDebug(1202)<<"section: "<NumberOfAtoms; i++) + if (m_pListView->confColumns[i].displayInColumn==sec) clickedColumn=i; + kdDebug(1202)<<"atom index "<confColumns[clickedColumn].desktopFileName; + + if (nameOfSortColumn!=m_pListView->sortedByColumn) + { + m_pListView->sortedByColumn=nameOfSortColumn; + m_pListView->setAscending(TRUE); + } + else + m_pListView->setAscending(!m_pListView->ascending()); + + KonqListViewSettings config( m_pListView->url().protocol() ); + config.readConfig(); + config.setSortBy( nameOfSortColumn ); + config.setSortOrder( m_pListView->ascending() ); + config.writeConfig(); +} + +void KonqListView::headerDragged(int sec, int from, int to) +{ + kdDebug(1202)<<"section: "<currentItem()==0) + return 0L; + return static_cast(m_pListView->currentItem())->item(); +} + +void KonqListView::slotSaveAfterHeaderDrag() +{ + QStringList lstColumns; + + for ( int i=0; i < m_pListView->columns(); i++ ) + { + int section = m_pListView->header()->mapToSection( i ); + + // look for section + for ( uint j=0; j < m_pListView->NumberOfAtoms; j++ ) + { + if ( m_pListView->confColumns[j].displayInColumn == section ) + { + lstColumns.append( m_pListView->confColumns[j].name ); + break; + } + } + } + KonqListViewSettings config( m_pListView->url().protocol() ); + config.readConfig(); + config.setColumns( lstColumns ); + config.writeConfig(); + + // Update column sizes + slotHeaderSizeChanged(); +} + +void KonqListView::slotSaveColumnWidths() +{ + QValueList lstColumnWidths; + + for ( int i=0; i < m_pListView->columns(); i++ ) + { + int section = m_pListView->header()->mapToSection( i ); + + // look for section + for ( uint j=0; j < m_pListView->NumberOfAtoms; j++ ) + { + // Save size only if the column is found + if ( m_pListView->confColumns[j].displayInColumn == section ) + { + m_pListView->confColumns[j].width = m_pListView->columnWidth(section); + lstColumnWidths.append( m_pListView->confColumns[j].width ); + break; + } + } + } + KonqListViewSettings config( m_pListView->url().protocol() ); + config.readConfig(); + config.setColumnWidths( lstColumnWidths ); + + // size of current filename column + config.setFileNameColumnWidth( m_pListView->columnWidth(0) ); + config.writeConfig(); +} + +void KonqListView::slotHeaderSizeChanged() +{ + if ( !m_headerTimer ) + { + m_headerTimer = new QTimer( this ); + connect( m_headerTimer, SIGNAL( timeout() ), this, SLOT( slotSaveColumnWidths() ) ); + } + else + m_headerTimer->stop(); + + m_headerTimer->start( 250, true ); +} + +void KonqListView::slotKFindOpened() +{ + if ( m_pListView->m_dirLister ) + m_pListView->m_dirLister->setAutoUpdate( false ); +} + +void KonqListView::slotKFindClosed() +{ + if ( m_pListView->m_dirLister ) + m_pListView->m_dirLister->setAutoUpdate( true ); +} + +void KonqListView::setupActions() +{ + m_paShowTime=new KToggleAction(i18n("Show &Modification Time"), 0,this, SLOT(slotColumnToggled()), actionCollection(), "show_time" ); + m_paShowTime->setCheckedState(i18n("Hide &Modification Time")); + m_paShowType=new KToggleAction(i18n("Show &File Type"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_type" ); + m_paShowType->setCheckedState(i18n("Hide &File Type")); + m_paShowMimeType=new KToggleAction(i18n("Show MimeType"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_mimetype" ); + m_paShowMimeType->setCheckedState(i18n("Hide MimeType")); + m_paShowAccessTime=new KToggleAction(i18n("Show &Access Time"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_access_time" ); + m_paShowAccessTime->setCheckedState(i18n("Hide &Access Time")); + m_paShowCreateTime=new KToggleAction(i18n("Show &Creation Time"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_creation_time" ); + m_paShowCreateTime->setCheckedState(i18n("Hide &Creation Time")); + m_paShowLinkDest=new KToggleAction(i18n("Show &Link Destination"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_link_dest" ); + m_paShowLinkDest->setCheckedState(i18n("Hide &Link Destination")); + m_paShowSize=new KToggleAction(i18n("Show Filesize"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_size" ); + m_paShowSize->setCheckedState(i18n("Hide Filesize")); + m_paShowOwner=new KToggleAction(i18n("Show Owner"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_owner" ); + m_paShowOwner->setCheckedState(i18n("Hide Owner")); + m_paShowGroup=new KToggleAction(i18n("Show Group"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_group" ); + m_paShowGroup->setCheckedState(i18n("Hide Group")); + m_paShowPermissions=new KToggleAction(i18n("Show Permissions"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_permissions" ); + m_paShowPermissions->setCheckedState(i18n("Hide Permissions")); + m_paShowURL=new KToggleAction(i18n("Show URL"), 0, this, SLOT(slotColumnToggled()),actionCollection(), "show_url" ); + + m_paSelect = new KAction( i18n( "Se&lect..." ), CTRL+Key_Plus, this, SLOT( slotSelect() ), actionCollection(), "select" ); + m_paUnselect = new KAction( i18n( "Unselect..." ), CTRL+Key_Minus, this, SLOT( slotUnselect() ), actionCollection(), "unselect" ); + m_paSelectAll = KStdAction::selectAll( this, SLOT( slotSelectAll() ), actionCollection(), "selectall" ); + m_paUnselectAll = new KAction( i18n( "Unselect All" ), CTRL+Key_U, this, SLOT( slotUnselectAll() ), actionCollection(), "unselectall" ); + m_paInvertSelection = new KAction( i18n( "&Invert Selection" ), CTRL+Key_Asterisk, this, SLOT( slotInvertSelection() ), actionCollection(), "invertselection" ); + + m_paShowDot = new KToggleAction( i18n( "Show &Hidden Files" ), 0, this, SLOT( slotShowDot() ), actionCollection(), "show_dot" ); +// m_paShowDot->setCheckedState(i18n("Hide &Hidden Files")); + m_paCaseInsensitive = new KToggleAction(i18n("Case Insensitive Sort"), 0, this, SLOT(slotCaseInsensitive()),actionCollection(), "sort_caseinsensitive" ); + + newIconSize( KIcon::SizeSmall /* default size */ ); +} + +void KonqListView::slotSelectionChanged() +{ + bool itemSelected = selectedFileItems().count()>0; + m_paUnselect->setEnabled( itemSelected ); + m_paUnselectAll->setEnabled( itemSelected ); +// m_paInvertSelection->setEnabled( itemSelected ); +} + +#include "konq_listview.moc" + + diff --git a/konqueror/listview/konq_listview.h b/konqueror/listview/konq_listview.h new file mode 100644 index 000000000..b149b703c --- /dev/null +++ b/konqueror/listview/konq_listview.h @@ -0,0 +1,210 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis + + 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. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef __konq_listview_h__ +#define __konq_listview_h__ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include "konq_listviewwidget.h" + +class KAction; +class KToggleAction; +class ListViewBrowserExtension; + +class KonqListViewFactory : public KParts::Factory +{ +public: + KonqListViewFactory(); + virtual ~KonqListViewFactory(); + + virtual KParts::Part* createPartObject( QWidget *parentWidget, const char *, QObject *parent, const char *name, const char*, const QStringList &args ); + + static KInstance *instance(); + static KonqPropsView *defaultViewProps(); + +private: + static KInstance *s_instance; + static KonqPropsView *s_defaultViewProps; +}; + +/** + * The part for the tree view. It does quite nothing, just the + * konqueror interface. Most of the functionality is in the + * widget, KonqListViewWidget. + */ +class KonqListView : public KonqDirPart +{ + friend class KonqBaseListViewWidget; + Q_OBJECT + Q_PROPERTY( bool supportsUndo READ supportsUndo ) +public: + KonqListView( QWidget *parentWidget, QObject *parent, const char *name, const QString& mode ); + virtual ~KonqListView(); + + virtual const KFileItem * currentItem(); + virtual KFileItemList selectedFileItems() {return m_pListView->selectedFileItems();}; + + KonqBaseListViewWidget *listViewWidget() const { return m_pListView; } + + bool supportsUndo() const { return true; } + + virtual void saveState( QDataStream &stream ); + virtual void restoreState( QDataStream &stream ); + + // "Cut" icons : disable those whose URL is in lst, enable the others + virtual void disableIcons( const KURL::List & lst ); + + // See KMimeTypeResolver + void mimeTypeDeterminationFinished() {} + //int iconSize() { return m_pListView->iconSize(); } + void determineIcon( KonqBaseListViewItem * item ); + + QPtrList & lstPendingMimeIconItems() { return m_mimeTypeResolver->m_lstPendingMimeIconItems; } + void listingComplete(); + + virtual void newIconSize( int ); + +protected: + virtual bool doOpenURL( const KURL &url ); + virtual bool doCloseURL(); + virtual bool openFile() { return true; } + + void setupActions(); + void guiActivateEvent( KParts::GUIActivateEvent *event ); + +protected slots: + void slotSelect(); + void slotUnselect(); + void slotSelectAll(); + void slotUnselectAll(); + void slotInvertSelection(); + void slotCaseInsensitive(); + void slotSelectionChanged(); + + void slotShowDot(); + //this is called if a item in the submenu is toggled + //it saves the new configuration according to the menu items + //and calls createColumns() + //it adjusts the indece of the remaining columns + void slotColumnToggled(); + //this is called when the user changes the order of the + //columns by dragging them + //at this moment the columns haven't changed their order yet, so + //it starts a singleshottimer, after which the columns changed their order + //and then slotSaveAfterHeaderDrag is called + void headerDragged(int sec, int from, int to); + //saves the new order of the columns + void slotSaveAfterHeaderDrag(); + // column width changed + void slotHeaderSizeChanged(); + void slotSaveColumnWidths(); // delayed + void slotHeaderClicked(int sec); + + // This comes from KonqDirPart, it's for the "Find" feature + virtual void slotStarted() { m_pListView->slotStarted(); } + virtual void slotCanceled() { m_pListView->slotCanceled(); } + virtual void slotCompleted() { m_pListView->slotCompleted(); } + virtual void slotNewItems( const KFileItemList& lst ) { m_pListView->slotNewItems( lst ); } + virtual void slotDeleteItem( KFileItem * item ) { m_pListView->slotDeleteItem( item ); } + virtual void slotRefreshItems( const KFileItemList& lst ) { m_pListView->slotRefreshItems( lst ); } + virtual void slotClear() { m_pListView->slotClear(); } + virtual void slotRedirection( const KURL & u ) { m_pListView->slotRedirection( u ); } + + // Connected to KonqDirPart + void slotKFindOpened(); + void slotKFindClosed(); + +private: + + KonqBaseListViewWidget *m_pListView; + KMimeTypeResolver *m_mimeTypeResolver; + QTimer *m_headerTimer; + + KAction *m_paSelect; + KAction *m_paUnselect; + KAction *m_paSelectAll; + KAction *m_paUnselectAll; + KAction *m_paInvertSelection; + + KToggleAction *m_paCaseInsensitive; + + KToggleAction *m_paShowDot; + KToggleAction *m_paShowTime; + KToggleAction *m_paShowType; + KToggleAction *m_paShowMimeType; + KToggleAction *m_paShowAccessTime; + KToggleAction *m_paShowCreateTime; + KToggleAction *m_paShowLinkDest; + KToggleAction *m_paShowSize; + KToggleAction *m_paShowOwner; + KToggleAction *m_paShowGroup; + KToggleAction *m_paShowPermissions; + KToggleAction *m_paShowURL; +}; + +class ListViewBrowserExtension : public KonqDirPartBrowserExtension +{ + Q_OBJECT + friend class KonqListView; + friend class KonqBaseListViewWidget; + public: + ListViewBrowserExtension( KonqListView *listView ); + + virtual int xOffset(); + virtual int yOffset(); + + protected slots: + void updateActions(); + + void copy() { copySelection( false ); } + void cut() { copySelection( true ); } + void paste(); + void pasteTo( const KURL & ); + void rename(); + void trash(); + void del() { KonqOperations::del(m_listView->listViewWidget(), + KonqOperations::DEL, + m_listView->listViewWidget()->selectedUrls()); } + + void reparseConfiguration(); + void setSaveViewPropertiesLocally( bool value ); + void setNameFilter( const QString &nameFilter ); + // void refreshMimeTypes is missing + + void properties(); + void editMimeType(); + + private: + void copySelection( bool move ); + + KonqListView *m_listView; +}; + +#endif diff --git a/konqueror/listview/konq_listview.kcfg b/konqueror/listview/konq_listview.kcfg new file mode 100644 index 000000000..cd7d2bc68 --- /dev/null +++ b/konqueror/listview/konq_listview.kcfg @@ -0,0 +1,37 @@ + + + kapplication.h + + + + + + + FileName + + + + + true + + + + + 25 * KApplication::kApplication()->fontMetrics().width( "m" ) + + + + + + + + + + + + + + \ No newline at end of file diff --git a/konqueror/listview/konq_listviewitems.cc b/konqueror/listview/konq_listviewitems.cc new file mode 100644 index 000000000..f946856c4 --- /dev/null +++ b/konqueror/listview/konq_listviewitems.cc @@ -0,0 +1,449 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis + + 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. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "konq_listview.h" +#include +#include +#include +#include +#include +#include +#include +#include + +static QString retrieveExtraEntry( KFileItem* fileitem, int numExtra ) +{ + /// ######## SLOOOOW + KIO::UDSEntry::ConstIterator it = fileitem->entry().begin(); + const KIO::UDSEntry::ConstIterator end = fileitem->entry().end(); + int n = 0; + for( ; it != end; ++it ) + { + if ((*it).m_uds == KIO::UDS_EXTRA) + { + ++n; + if ( n == numExtra ) + { + return (*it).m_str; + } + } + } + return QString::null; +} + + +/************************************************************** + * + * KonqListViewItem + * + **************************************************************/ +KonqListViewItem::KonqListViewItem( KonqBaseListViewWidget *_listViewWidget, + KonqListViewItem * _parent, KFileItem* _fileitem ) + : KonqBaseListViewItem( _listViewWidget, _parent, _fileitem ), + m_pixmaps( listView()->columns() ) +{ + updateContents(); +} + +KonqListViewItem::KonqListViewItem( KonqBaseListViewWidget *_listViewWidget, KFileItem* _fileitem ) + : KonqBaseListViewItem( _listViewWidget, _fileitem ), + m_pixmaps( listView()->columns() ) +{ + updateContents(); +} + +KonqListViewItem::~KonqListViewItem() +{ + for ( QValueVector::iterator + it = m_pixmaps.begin(), itEnd = m_pixmaps.end(); + it != itEnd; ++it ) + delete *it; +} + +void KonqListViewItem::updateContents() +{ + // Set the pixmap + setDisabled( m_bDisabled ); + + // Set the text of each column + setText( 0, m_fileitem->text() ); + + // The order is: .dir (0), dir (1), .file (2), file (3) + sortChar = S_ISDIR( m_fileitem->mode() ) ? 1 : 3; + if ( m_fileitem->text()[0] == '.' ) + --sortChar; + + //now we have the first column, so let's do the rest + + int numExtra = 1; + for ( unsigned int i=0; iNumberOfAtoms; i++ ) + { + ColumnInfo *tmpColumn=&m_pListViewWidget->columnConfigInfo()[i]; + if (tmpColumn->displayThisOne) + { + switch (tmpColumn->udsId) + { + case KIO::UDS_USER: + setText(tmpColumn->displayInColumn,m_fileitem->user()); + break; + case KIO::UDS_GROUP: + setText(tmpColumn->displayInColumn,m_fileitem->group()); + break; + case KIO::UDS_FILE_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimeComment()); + break; + case KIO::UDS_MIME_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimetype()); + break; + case KIO::UDS_URL: + setText(tmpColumn->displayInColumn,m_fileitem->url().prettyURL()); + break; + case KIO::UDS_LINK_DEST: + setText(tmpColumn->displayInColumn,m_fileitem->linkDest()); + break; + case KIO::UDS_SIZE: + if ( m_pListViewWidget->m_pSettings->fileSizeInBytes() ) + setText(tmpColumn->displayInColumn,KGlobal::locale()->formatNumber( m_fileitem->size(),0)+" "); + else + setText(tmpColumn->displayInColumn,KIO::convertSize(m_fileitem->size())+" "); + break; + case KIO::UDS_ACCESS: + setText(tmpColumn->displayInColumn,m_fileitem->permissionsString()); + break; + case KIO::UDS_MODIFICATION_TIME: + case KIO::UDS_ACCESS_TIME: + case KIO::UDS_CREATION_TIME: + { + QDateTime dt; + time_t _time = m_fileitem->time( tmpColumn->udsId ); + if ( _time != 0 ) + { + dt.setTime_t( _time ); + setText(tmpColumn->displayInColumn,KGlobal::locale()->formatDateTime(dt)); + } + } + break; + case KIO::UDS_EXTRA: + { + const QString entryStr = retrieveExtraEntry( m_fileitem, numExtra ); + if ( tmpColumn->type == QVariant::DateTime ) + { + QDateTime dt = QDateTime::fromString( entryStr, Qt::ISODate ); + setText(tmpColumn->displayInColumn, + KGlobal::locale()->formatDateTime(dt)); + } + else // if ( tmpColumn->type == QVariant::String ) + setText(tmpColumn->displayInColumn, entryStr); + ++numExtra; + break; + } + default: + break; + }; + }; + }; +} + +void KonqListViewItem::setDisabled( bool disabled ) +{ + KonqBaseListViewItem::setDisabled( disabled ); + int iconSize = m_pListViewWidget->iconSize(); + iconSize = iconSize ? iconSize : KGlobal::iconLoader()->currentSize( KIcon::Small ); // Default = small + setPixmap( 0, m_fileitem->pixmap( iconSize, state() ) ); +} + +void KonqListViewItem::setActive( bool active ) +{ + if ( m_bActive == active ) + return; + + //#### Optimize away repaint if possible, like the iconview does? + KonqBaseListViewItem::setActive( active ); + int iconSize = m_pListViewWidget->iconSize(); + iconSize = iconSize ? iconSize : KGlobal::iconLoader()->currentSize( KIcon::Small ); // Default = small + setPixmap( 0, m_fileitem->pixmap( iconSize, state() ) ); +} + +void KonqListViewItem::setPixmap( int column, const QPixmap& pm ) +{ + if ( column < 0 ) + return; + + const QPixmap *current = pixmap( column ); + + if ( ( pm.isNull() && !current ) || + ( current && pm.serialNumber() == current->serialNumber() ) ) + return; + + int oldWidth = current ? current->width() : 0; + int oldHeight = current ? current->height() : 0; + + if ( (int)m_pixmaps.size() <= column ) + m_pixmaps.resize( column+1 ); + + delete current; + m_pixmaps[column] = pm.isNull() ? 0 : new QPixmap( pm ); + + int newWidth = pm.isNull() ? 0 : pm.width(); + int newHeight = pm.isNull() ? 0 : pm.height(); + + // If the height or width have changed then we're going to have to repaint + // this whole thing. Fortunately since most of the calls are coming from + // setActive() this is the uncommon case. + + if ( oldWidth != newWidth || oldHeight != newHeight ) + { + setup(); + widthChanged( column ); + invalidateHeight(); + return; + } + + // If we're just replacing the icon with another one its size -- i.e. a + // "highlighted" icon, don't bother repainting the whole widget. + + QListView *lv = m_pListViewWidget; + + int decorationWidth = lv->treeStepSize() * ( depth() + ( lv->rootIsDecorated() ? 1 : 0 ) ); + int x = lv->header()->sectionPos( column ) + decorationWidth + lv->itemMargin(); + int y = lv->itemPos( this ); + int w = newWidth; + int h = height(); + lv->repaintContents( x, y, w, h ); +} + +const QPixmap* KonqListViewItem::pixmap( int column ) const +{ + bool ok; + if ((int)m_pixmaps.count() <= column) + return 0; + + QPixmap *pm = m_pixmaps.at( column, &ok ); + if( !ok ) + return 0; + return pm; +} + +int KonqBaseListViewItem::compare( QListViewItem* item, int col, bool ascending ) const +{ + KonqListViewItem* k = static_cast( item ); + if ( sortChar != k->sortChar ) + // Dirs are always first, even when sorting in descending order + return !ascending ? k->sortChar - sortChar : sortChar - k->sortChar; + + int numExtra = 0; + for ( unsigned int i=0; iNumberOfAtoms; i++ ) + { + ColumnInfo *cInfo = &m_pListViewWidget->columnConfigInfo()[i]; + if ( cInfo->udsId == KIO::UDS_EXTRA ) + ++numExtra; + if ( col == cInfo->displayInColumn ) + { + switch ( cInfo->udsId ) + { + case KIO::UDS_MODIFICATION_TIME: + case KIO::UDS_ACCESS_TIME: + case KIO::UDS_CREATION_TIME: + { + time_t t1 = m_fileitem->time( cInfo->udsId ); + time_t t2 = k->m_fileitem->time( cInfo->udsId ); + return ( t1 > t2 ) ? 1 : ( t1 < t2 ) ? -1 : 0; + } + case KIO::UDS_SIZE: + { + KIO::filesize_t s1 = m_fileitem->size(); + KIO::filesize_t s2 = k->m_fileitem->size(); + return ( s1 > s2 ) ? 1 : ( s1 < s2 ) ? -1 : 0; + } + case KIO::UDS_EXTRA: + { + if ( cInfo->type & QVariant::DateTime ) { + const QString entryStr1 = retrieveExtraEntry( m_fileitem, numExtra ); + QDateTime dt1 = QDateTime::fromString( entryStr1, Qt::ISODate ); + const QString entryStr2 = retrieveExtraEntry( k->m_fileitem, numExtra ); + QDateTime dt2 = QDateTime::fromString( entryStr2, Qt::ISODate ); + return ( dt1 > dt2 ) ? 1 : ( dt1 < dt2 ) ? -1 : 0; + } + } + default: + break; + } + break; + } + } + if ( m_pListViewWidget->caseInsensitiveSort() ) + return text( col ).lower().localeAwareCompare( k->text( col ).lower() ); + else { + return m_pListViewWidget->m_pSettings->caseSensitiveCompare( text( col ), k->text( col ) ); + } +} + +void KonqListViewItem::paintCell( QPainter *_painter, const QColorGroup & _cg, int _column, int _width, int _alignment ) +{ + QColorGroup cg( _cg ); + + if ( _column == 0 ) + { + _painter->setFont( m_pListViewWidget->itemFont() ); + } + + cg.setColor( QColorGroup::Text, m_pListViewWidget->itemColor() ); + + KListView *lv = static_cast< KListView* >( listView() ); + const QPixmap *pm = lv->viewport()->paletteBackgroundPixmap(); + if ( _column == 0 && isSelected() && !lv->allColumnsShowFocus() ) + { + int newWidth = width( lv->fontMetrics(), lv, _column ); + if ( newWidth > _width ) + newWidth = _width; + if ( pm && !pm->isNull() ) + { + cg.setBrush( QColorGroup::Base, QBrush( backgroundColor(_column), *pm ) ); + QPoint o = _painter->brushOrigin(); + _painter->setBrushOrigin( o.x() - lv->contentsX(), o.y() - lv->contentsY() ); + const QColorGroup::ColorRole crole = + QPalette::backgroundRoleFromMode( lv->viewport()->backgroundMode() ); + _painter->fillRect( newWidth, 0, _width - newWidth, height(), cg.brush( crole ) ); + _painter->setBrushOrigin( o ); + } + else + { + _painter->fillRect( newWidth, 0, _width - newWidth, height(), backgroundColor(_column) ); + } + + _width = newWidth; + } + + KListViewItem::paintCell( _painter, cg, _column, _width, _alignment ); +} + +void KonqListViewItem::paintFocus( QPainter * _painter, const QColorGroup & cg, const QRect & _r ) +{ + QRect r( _r ); + QListView *lv = static_cast< QListView * >( listView() ); + r.setWidth( width( lv->fontMetrics(), lv, 0 ) ); + if ( r.right() > lv->header()->sectionRect( 0 ).right() ) + r.setRight( lv->header()->sectionRect( 0 ).right() ); + QListViewItem::paintFocus( _painter, cg, r ); +} + +const char* KonqBaseListViewItem::makeAccessString( const mode_t mode) +{ + static char buffer[ 12 ]; + + char uxbit,gxbit,oxbit; + + if ( (mode & (S_IXUSR|S_ISUID)) == (S_IXUSR|S_ISUID) ) + uxbit = 's'; + else if ( (mode & (S_IXUSR|S_ISUID)) == S_ISUID ) + uxbit = 'S'; + else if ( (mode & (S_IXUSR|S_ISUID)) == S_IXUSR ) + uxbit = 'x'; + else + uxbit = '-'; + + if ( (mode & (S_IXGRP|S_ISGID)) == (S_IXGRP|S_ISGID) ) + gxbit = 's'; + else if ( (mode & (S_IXGRP|S_ISGID)) == S_ISGID ) + gxbit = 'S'; + else if ( (mode & (S_IXGRP|S_ISGID)) == S_IXGRP ) + gxbit = 'x'; + else + gxbit = '-'; + + if ( (mode & (S_IXOTH|S_ISVTX)) == (S_IXOTH|S_ISVTX) ) + oxbit = 't'; + else if ( (mode & (S_IXOTH|S_ISVTX)) == S_ISVTX ) + oxbit = 'T'; + else if ( (mode & (S_IXOTH|S_ISVTX)) == S_IXOTH ) + oxbit = 'x'; + else + oxbit = '-'; + + buffer[0] = ((( mode & S_IRUSR ) == S_IRUSR ) ? 'r' : '-' ); + buffer[1] = ((( mode & S_IWUSR ) == S_IWUSR ) ? 'w' : '-' ); + buffer[2] = uxbit; + buffer[3] = ((( mode & S_IRGRP ) == S_IRGRP ) ? 'r' : '-' ); + buffer[4] = ((( mode & S_IWGRP ) == S_IWGRP ) ? 'w' : '-' ); + buffer[5] = gxbit; + buffer[6] = ((( mode & S_IROTH ) == S_IROTH ) ? 'r' : '-' ); + buffer[7] = ((( mode & S_IWOTH ) == S_IWOTH ) ? 'w' : '-' ); + buffer[8] = oxbit; + buffer[9] = 0; + + return buffer; +} + +KonqBaseListViewItem::KonqBaseListViewItem(KonqBaseListViewWidget *_listViewWidget, KFileItem* _fileitem) +:KListViewItem(_listViewWidget) +,sortChar(0) +,m_bDisabled(false) +,m_bActive(false) +,m_fileitem(_fileitem) +,m_pListViewWidget(_listViewWidget) +{} + +KonqBaseListViewItem::KonqBaseListViewItem(KonqBaseListViewWidget *_listViewWidget, KonqBaseListViewItem *_parent, KFileItem* _fileitem) +:KListViewItem(_parent) +,sortChar(0) +,m_bDisabled(false) +,m_bActive(false) +,m_fileitem(_fileitem) +,m_pListViewWidget(_listViewWidget) +{} + +KonqBaseListViewItem::~KonqBaseListViewItem() +{ + if (m_pListViewWidget->m_activeItem == this) + m_pListViewWidget->m_activeItem = 0; + if (m_pListViewWidget->m_dragOverItem == this) + m_pListViewWidget->m_dragOverItem = 0; + + if (m_pListViewWidget->m_selected) + m_pListViewWidget->m_selected->removeRef(this); +} + +QRect KonqBaseListViewItem::rect() const +{ + QRect r = m_pListViewWidget->itemRect(this); + return QRect( m_pListViewWidget->viewportToContents( r.topLeft() ), QSize( r.width(), r.height() ) ); +} + +void KonqBaseListViewItem::mimetypeFound() +{ + // Update icon + setDisabled( m_bDisabled ); + uint done = 0; + KonqBaseListViewWidget * lv = m_pListViewWidget; + for (unsigned int i=0; iNumberOfAtoms && done < 2; i++) + { + ColumnInfo *tmpColumn=&lv->columnConfigInfo()[i]; + if (lv->columnConfigInfo()[i].udsId==KIO::UDS_FILE_TYPE && tmpColumn->displayThisOne) + { + setText(tmpColumn->displayInColumn, m_fileitem->mimeComment()); + done++; + } + if (lv->columnConfigInfo()[i].udsId==KIO::UDS_MIME_TYPE && tmpColumn->displayThisOne) + { + setText(tmpColumn->displayInColumn, m_fileitem->mimetype()); + done++; + } + } +} + diff --git a/konqueror/listview/konq_listviewitems.h b/konqueror/listview/konq_listviewitems.h new file mode 100644 index 000000000..6e0cbc513 --- /dev/null +++ b/konqueror/listview/konq_listviewitems.h @@ -0,0 +1,123 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis + + 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. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef __konq_listviewitems_h__ +#define __konq_listviewitems_h__ + +#include +#include +#include + +#include + +// for mode_t +#include +#include +#include + +class QPainter; +class KFileItem; +class KonqBaseListViewWidget; + + +class KonqBaseListViewItem : public KListViewItem +{ + public: + KonqBaseListViewItem( KonqBaseListViewWidget *_listViewWidget, + KFileItem *_fileitem ); + KonqBaseListViewItem( KonqBaseListViewWidget *_treeViewWidget, + KonqBaseListViewItem *_parent, KFileItem *_fileitem ); + virtual ~KonqBaseListViewItem(); + + /** @return the file item held by this instance */ + KFileItem * item() { return m_fileitem; } + + void mimetypeFound(); + virtual void updateContents() = 0; + virtual void setDisabled( bool disabled ) { m_bDisabled = disabled; } + virtual void setActive ( bool active ) { m_bActive = active; } + virtual int compare( QListViewItem* i, int col, bool ascending ) const; + + int state() const + { + if (m_bDisabled) + return KIcon::DisabledState; + if (m_bActive) + return KIcon::ActiveState; + return KIcon::DefaultState; + } + + /** For KonqMimeTypeResolver */ + QRect rect() const; + + protected: + short int sortChar; + bool m_bDisabled; + bool m_bActive; + + /** Pointer to the file item in KDirLister's list */ + KFileItem* m_fileitem; + /** Parent tree view */ + KonqBaseListViewWidget* m_pListViewWidget; + + /** + * @deprecated Use KFileItem::permissionsString() instead + */ + static const char* makeAccessString( const mode_t mode ); +}; + +/** + * One item in the detailed list or in the tree (not text) + */ +class KonqListViewItem : public KonqBaseListViewItem +{ + public: + /** + * Create an item in the tree toplevel representing a file + * @param _parent the parent widget, the tree view + * @param _fileitem the file item created by KDirLister + */ + KonqListViewItem( KonqBaseListViewWidget *_parent, KFileItem *_fileitem ); + + /** + * Create an item representing a file, inside a directory + * @param _treeview the parent tree view + * @param _parent the parent widget, a directory item in the tree view + * @param _fileitem the file item created by KDirLister + */ + KonqListViewItem( KonqBaseListViewWidget *_treeview, + KonqListViewItem *_parent, KFileItem *_fileitem ); + + virtual ~KonqListViewItem(); + + virtual void paintCell( QPainter *_painter, const QColorGroup & cg, + int column, int width, int alignment ); + virtual void paintFocus( QPainter * _painter, const QColorGroup & cg, const QRect & r ); + virtual void updateContents(); + virtual void setDisabled( bool disabled ); + virtual void setActive ( bool active ); + + virtual void setPixmap( int column, const QPixmap & pm ); + virtual const QPixmap * pixmap( int column ) const; + +private: + QValueVector m_pixmaps; +}; + +#endif diff --git a/konqueror/listview/konq_listviewsettings.kcfgc b/konqueror/listview/konq_listviewsettings.kcfgc new file mode 100644 index 000000000..227521fe0 --- /dev/null +++ b/konqueror/listview/konq_listviewsettings.kcfgc @@ -0,0 +1,4 @@ +File=konq_listview.kcfg +ClassName=KonqListViewSettings +Singleton=false +Mutators=true \ No newline at end of file diff --git a/konqueror/listview/konq_listviewwidget.cc b/konqueror/listview/konq_listviewwidget.cc new file mode 100644 index 000000000..f3016b433 --- /dev/null +++ b/konqueror/listview/konq_listviewwidget.cc @@ -0,0 +1,1416 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis + 2001, 2002, 2004 Michael Brade + + 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. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "konq_listview.h" +#include "konq_listviewsettings.h" +#include "konq_listviewwidget.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +ColumnInfo::ColumnInfo() + :displayInColumn(-1) + ,name() + ,desktopFileName() + ,udsId(0) + ,type(QVariant::Invalid) + ,displayThisOne(false) + ,toggleThisOne(0) +{} + + +void ColumnInfo::setData(const QString& n, const QString& desktopName, int kioUds, + KToggleAction* someAction, int theWidth) +{ + displayInColumn=-1; + name=n; + desktopFileName=desktopName; + udsId=kioUds; + type=QVariant::Invalid; + displayThisOne=false; + toggleThisOne=someAction; + width=theWidth; +} + +void ColumnInfo::setData(const QString& n, const QString& desktopName, int kioUds, + QVariant::Type t, KToggleAction* someAction, int theWidth) +{ + displayInColumn=-1; + name=n; + desktopFileName=desktopName; + udsId=kioUds; + type=t; + displayThisOne=false; + toggleThisOne=someAction; + width=theWidth; +} + + +KonqBaseListViewWidget::KonqBaseListViewWidget( KonqListView *parent, QWidget *parentWidget) + : KListView(parentWidget) + ,sortedByColumn(0) + ,m_pBrowserView(parent) + ,m_dirLister(new KDirLister( true /*m_showIcons==false*/)) + ,m_dragOverItem(0) + ,m_activeItem(0) + ,m_selected(0) + ,m_scrollTimer(0) + ,m_rubber(0) + ,m_showIcons(true) + ,m_bCaseInsensitive(true) + ,m_bUpdateContentsPosAfterListing(false) + ,m_bAscending(true) + ,m_itemFound(false) + ,m_restored(false) + ,m_filenameColumn(0) + ,m_itemToGoTo("") + ,m_backgroundTimer(0) + ,m_fileTip(new KonqFileTip(this)) +{ + kdDebug(1202) << "+KonqBaseListViewWidget" << endl; + + m_dirLister->setMainWindow(topLevelWidget()); + + m_bTopLevelComplete = true; + + //Adjust KListView behaviour + setMultiSelection(true); + setSelectionModeExt( FileManager ); + setDragEnabled(true); + setItemsMovable(false); + + initConfig(); +#if 0 + connect( this, SIGNAL(rightButtonPressed(QListViewItem*,const QPoint&,int)), + this, SLOT(slotRightButtonPressed(QListViewItem*,const QPoint&,int))); +#endif + connect( this, SIGNAL(returnPressed( QListViewItem * )), + this, SLOT(slotReturnPressed( QListViewItem * )) ); + connect( this, SIGNAL( mouseButtonClicked( int, QListViewItem *, const QPoint&, int )), + this, SLOT( slotMouseButtonClicked2( int, QListViewItem *, const QPoint&, int )) ); + connect( this, SIGNAL(executed( QListViewItem * )), + this, SLOT(slotExecuted( QListViewItem * )) ); + + connect( this, SIGNAL(currentChanged( QListViewItem * )), + this, SLOT(slotCurrentChanged( QListViewItem * )) ); + connect( this, SIGNAL(itemRenamed( QListViewItem *, const QString &, int )), + this, SLOT(slotItemRenamed( QListViewItem *, const QString &, int )) ); + connect( this, SIGNAL(contextMenuRequested( QListViewItem *, const QPoint&, int )), + this, SLOT(slotPopupMenu( QListViewItem *, const QPoint&, int )) ); + connect( this, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()) ); + + connect( horizontalScrollBar(), SIGNAL(valueChanged( int )), + this, SIGNAL(viewportAdjusted()) ); + connect( verticalScrollBar(), SIGNAL(valueChanged( int )), + this, SIGNAL(viewportAdjusted()) ); + + // Connect the directory lister + connect( m_dirLister, SIGNAL(started( const KURL & )), + this, SLOT(slotStarted()) ); + connect( m_dirLister, SIGNAL(completed()), this, SLOT(slotCompleted()) ); + connect( m_dirLister, SIGNAL(canceled()), this, SLOT(slotCanceled()) ); + connect( m_dirLister, SIGNAL(clear()), this, SLOT(slotClear()) ); + connect( m_dirLister, SIGNAL(newItems( const KFileItemList & ) ), + this, SLOT(slotNewItems( const KFileItemList & )) ); + connect( m_dirLister, SIGNAL(deleteItem( KFileItem * )), + this, SLOT(slotDeleteItem( KFileItem * )) ); + connect( m_dirLister, SIGNAL(refreshItems( const KFileItemList & )), + this, SLOT( slotRefreshItems( const KFileItemList & )) ); + connect( m_dirLister, SIGNAL(redirection( const KURL & )), + this, SLOT(slotRedirection( const KURL & )) ); + connect( m_dirLister, SIGNAL(itemsFilteredByMime( const KFileItemList & )), + m_pBrowserView, SIGNAL(itemsFilteredByMime( const KFileItemList & )) ); + + connect( m_dirLister, SIGNAL(infoMessage( const QString& )), + m_pBrowserView->extension(), SIGNAL(infoMessage( const QString& )) ); + connect( m_dirLister, SIGNAL(percent( int )), + m_pBrowserView->extension(), SIGNAL(loadingProgress( int )) ); + connect( m_dirLister, SIGNAL(speed( int )), + m_pBrowserView->extension(), SIGNAL(speedProgress( int )) ); + + connect( header(), SIGNAL(sizeChange( int, int, int )), SLOT(slotUpdateBackground()) ); + + viewport()->setMouseTracking( true ); + viewport()->setFocusPolicy( QWidget::WheelFocus ); + setFocusPolicy( QWidget::WheelFocus ); + setAcceptDrops( true ); + + //looks better with the statusbar + setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + setShowSortIndicator( true ); +} + +KonqBaseListViewWidget::~KonqBaseListViewWidget() +{ + kdDebug(1202) << "-KonqBaseListViewWidget" << endl; + + delete m_selected; m_selected = 0; + + // TODO: this is a hack, better fix the connections of m_dirLister if possible! + m_dirLister->disconnect( this ); + delete m_dirLister; + + delete m_fileTip; +} + +void KonqBaseListViewWidget::readProtocolConfig( const KURL & url ) +{ + const QString protocol = url.protocol(); + KonqListViewSettings config( protocol ); + config.readConfig(); + sortedByColumn = config.sortBy(); + m_bAscending = config.sortOrder(); + + m_filenameColumnWidth = config.fileNameColumnWidth(); + + QStringList lstColumns = config.columns(); + QValueList lstColumnWidths = config.columnWidths(); + if (lstColumns.isEmpty()) + { + // Default column selection + lstColumns.append( "Size" ); + lstColumns.append( "File Type" ); + lstColumns.append( "Modified" ); + lstColumns.append( "Permissions" ); + lstColumns.append( "Owner" ); + lstColumns.append( "Group" ); + lstColumns.append( "Link" ); + } + + // Default number of columns + NumberOfAtoms = 11; + int extraIndex = NumberOfAtoms; + + // Check for any extra data + KProtocolInfo::ExtraFieldList extraFields = KProtocolInfo::extraFields(url); + NumberOfAtoms += extraFields.count(); + confColumns.resize( NumberOfAtoms ); + + KProtocolInfo::ExtraFieldList::Iterator extraFieldsIt = extraFields.begin(); + for ( int num = 1; extraFieldsIt != extraFields.end(); ++extraFieldsIt, ++num ) + { + const QString column = (*extraFieldsIt).name; + if ( lstColumns.find(column) == lstColumns.end() ) + lstColumns << column; + const QString type = (*extraFieldsIt).type; // ## TODO use when sorting + QVariant::Type t = QVariant::Invalid; + if ( type.lower() == "qstring" ) + t = QVariant::String; + else if ( type.lower() == "qdatetime" ) + t = QVariant::DateTime; + else + kdWarning() << "Unsupported ExtraType '" << type << "'" << endl; + confColumns[extraIndex++].setData( column, QString("Extra%1").arg(num), KIO::UDS_EXTRA, t, 0); + } + + //disable everything + for ( unsigned int i = 0; i < NumberOfAtoms; i++ ) + { + confColumns[i].displayThisOne = false; + confColumns[i].displayInColumn = -1; + if ( confColumns[i].toggleThisOne ) + { + confColumns[i].toggleThisOne->setChecked( false ); + confColumns[i].toggleThisOne->setEnabled( true ); + } + } + int currentColumn = m_filenameColumn + 1; + //check all columns in lstColumns + for ( unsigned int i = 0; i < lstColumns.count(); i++ ) + { + //search the column in confColumns + for ( unsigned int j = 0; j < NumberOfAtoms; j++ ) + { + if ( confColumns[j].name == *lstColumns.at(i) ) + { + confColumns[j].displayThisOne = true; + confColumns[j].displayInColumn = currentColumn; + if ( confColumns[j].toggleThisOne ) + confColumns[j].toggleThisOne->setChecked( true ); + currentColumn++; + + if ( i < lstColumnWidths.count() ) + confColumns[j].width = *lstColumnWidths.at(i); + else + { + // Default Column widths + ColumnInfo *tmpColumn = &confColumns[j]; + QString str; + + if ( tmpColumn->udsId == KIO::UDS_SIZE ) + str = KGlobal::locale()->formatNumber( 888888888, 0 ) + " "; + else if ( tmpColumn->udsId == KIO::UDS_ACCESS ) + str = "--Permissions--"; + else if ( tmpColumn->udsId == KIO::UDS_USER ) + str = "a_long_username"; + else if ( tmpColumn->udsId == KIO::UDS_GROUP ) + str = "a_groupname"; + else if ( tmpColumn->udsId == KIO::UDS_LINK_DEST ) + str = "a_quite_long_filename_for_link_dest"; + else if ( tmpColumn->udsId == KIO::UDS_FILE_TYPE ) + str = "a_long_comment_for_mimetype"; + else if ( tmpColumn->udsId == KIO::UDS_MIME_TYPE ) + str = "_a_long_/_mimetype_"; + else if ( tmpColumn->udsId == KIO::UDS_URL ) + str = "a_long_lonq_long_very_long_url"; + else if ( (tmpColumn->udsId & KIO::UDS_TIME) + || (tmpColumn->udsId == KIO::UDS_EXTRA && + (tmpColumn->type & QVariant::DateTime)) ) + { + QDateTime dt( QDate( 2000, 10, 10 ), QTime( 20, 20, 20 ) ); + str = KGlobal::locale()->formatDateTime( dt ) + "--"; + } + else + str = "it_is_the_default_width"; + + confColumns[j].width = fontMetrics().width(str); + } + break; + } + } + } + //check what the protocol provides + QStringList listingList = KProtocolInfo::listing( url ); + kdDebug(1202) << k_funcinfo << "protocol: " << protocol << endl; + + // Even if this is not given by the protocol, we can determine it. + // Please don't remove this ;-). It makes it possible to show the file type + // using the mimetype comment, which for most users is a nicer alternative + // than the raw mimetype name. + listingList.append( "MimeType" ); + for ( unsigned int i = 0; i < NumberOfAtoms; i++ ) + { + if ( confColumns[i].udsId == KIO::UDS_URL || + confColumns[i].udsId == KIO::UDS_MIME_TYPE || + !confColumns[i].displayThisOne ) + { + continue; + } + + QStringList::Iterator listIt = listingList.find( confColumns[i].desktopFileName ); + if ( listIt == listingList.end() ) // not found -> hide + { + //move all columns behind one to the front + for ( unsigned int l = 0; l < NumberOfAtoms; l++ ) + if ( confColumns[l].displayInColumn > confColumns[i].displayInColumn ) + confColumns[l].displayInColumn--; + + //disable this column + confColumns[i].displayThisOne = false; + if ( confColumns[i].toggleThisOne ) + { + confColumns[i].toggleThisOne->setEnabled( false ); + confColumns[i].toggleThisOne->setChecked( false ); + } + } + } +} + +void KonqBaseListViewWidget::createColumns() +{ + //this column is always required, so add it + if ( columns() < 1 ) + addColumn( i18n("Name"), m_filenameColumnWidth ); + setSorting( 0, true ); + + //remove all columns that will be re-added + for ( int i=columns()-1; i>m_filenameColumn; i--) + removeColumn(i); + + //now add the checked columns + int currentColumn = m_filenameColumn + 1; + for ( int i = 0; i < (int)NumberOfAtoms; i++ ) + { + if ( confColumns[i].displayThisOne && (confColumns[i].displayInColumn == currentColumn) ) + { + addColumn( i18n(confColumns[i].name.utf8()), confColumns[i].width ); + if ( sortedByColumn == confColumns[i].desktopFileName ) + setSorting( currentColumn, m_bAscending ); + if ( confColumns[i].udsId == KIO::UDS_SIZE ) + setColumnAlignment( currentColumn, AlignRight ); + i = -1; + currentColumn++; + } + } + if ( sortedByColumn == "FileName" ) + setSorting( 0, m_bAscending ); +} + +void KonqBaseListViewWidget::stop() +{ + m_dirLister->stop(); +} + +const KURL & KonqBaseListViewWidget::url() +{ + return m_url; +} + +void KonqBaseListViewWidget::initConfig() +{ + m_pSettings = KonqFMSettings::settings(); + + QFont stdFont( m_pSettings->standardFont() ); + setFont( stdFont ); + //TODO: create config GUI + QFont itemFont( m_pSettings->standardFont() ); + itemFont.setUnderline( m_pSettings->underlineLink() ); + setItemFont( itemFont ); + setItemColor( m_pSettings->normalTextColor() ); + + bool on = m_pSettings->showFileTips() && QToolTip::isGloballyEnabled(); + m_fileTip->setOptions( on, m_pSettings->showPreviewsInFileTips(), m_pSettings->numFileTips() ); + + updateListContents(); +} + +void KonqBaseListViewWidget::contentsMousePressEvent( QMouseEvent *e ) +{ + if ( m_rubber ) + { + drawRubber(); + delete m_rubber; + m_rubber = 0; + } + + delete m_selected; + m_selected = new QPtrList; + + QPoint vp = contentsToViewport( e->pos() ); + KonqBaseListViewItem* item = isExecuteArea( vp ) ? + static_cast( itemAt( vp ) ) : 0L; + + if ( item ) + KListView::contentsMousePressEvent( e ); + else { + if ( e->button() == LeftButton ) + { + if ( !( e->state() & ControlButton ) ) + setSelected( itemAt( vp ), false ); + m_rubber = new QRect( e->x(), e->y(), 0, 0 ); + m_fileTip->setItem( 0 ); + } + if ( e->button() != RightButton ) + QListView::contentsMousePressEvent( e ); + } + // Store list of selected items at mouse-press time. + // This is used when autoscrolling (why?) + // and during dnd (the target item is temporarily selected) + selectedItems( m_selected ); +} + +void KonqBaseListViewWidget::contentsMouseReleaseEvent( QMouseEvent *e ) +{ + if ( m_rubber ) + { + drawRubber(); + delete m_rubber; + m_rubber = 0; + } + + if ( m_scrollTimer ) + { + disconnect( m_scrollTimer, SIGNAL( timeout() ), + this, SLOT( slotAutoScroll() ) ); + m_scrollTimer->stop(); + delete m_scrollTimer; + m_scrollTimer = 0; + } + + delete m_selected; m_selected = 0; + KListView::contentsMouseReleaseEvent( e ); +} + +void KonqBaseListViewWidget::contentsMouseMoveEvent( QMouseEvent *e ) +{ + if ( m_rubber ) + { + slotAutoScroll(); + return; + } + + QPoint vp = contentsToViewport( e->pos() ); + KonqBaseListViewItem* item = isExecuteArea( vp ) ? + static_cast( itemAt( vp ) ) : 0; + + if ( item != m_activeItem ) + { + if ( m_activeItem != 0 ) + m_activeItem->setActive( false ); + + m_activeItem = item; + + if ( item ) + { + item->setActive( true ); + emit m_pBrowserView->setStatusBarText( item->item()->getStatusBarInfo() ); + m_pBrowserView->emitMouseOver( item->item() ); + + vp.setY( itemRect( item ).y() ); + QRect rect( viewportToContents( vp ), QSize(20, item->height()) ); + m_fileTip->setItem( item->item(), rect, item->pixmap( 0 ) ); + m_fileTip->setPreview( KGlobalSettings::showFilePreview( item->item()->url() ) ); + setShowToolTips( !m_pSettings->showFileTips() ); + } + else + { + reportItemCounts(); + m_pBrowserView->emitMouseOver( 0 ); + + m_fileTip->setItem( 0 ); + setShowToolTips( true ); + } + } + + KListView::contentsMouseMoveEvent( e ); +} + +void KonqBaseListViewWidget::contentsWheelEvent( QWheelEvent *e ) +{ + // when scrolling with mousewheel, stop possible pending filetip + m_fileTip->setItem( 0 ); + + if ( m_activeItem != 0 ) + { + m_activeItem->setActive( false ); + m_activeItem = 0; + } + + reportItemCounts(); + m_pBrowserView->emitMouseOver( 0 ); + KListView::contentsWheelEvent( e ); +} + +void KonqBaseListViewWidget::leaveEvent( QEvent *e ) +{ + if ( m_activeItem != 0 ) + { + m_activeItem->setActive( false ); + m_activeItem = 0; + } + + reportItemCounts(); + m_pBrowserView->emitMouseOver( 0 ); + + m_fileTip->setItem( 0 ); + + KListView::leaveEvent( e ); +} + +void KonqBaseListViewWidget::drawRubber() +{ + if ( !m_rubber ) + return; + + QPainter p; + p.begin( viewport() ); + p.setRasterOp( NotROP ); + p.setPen( QPen( color0, 1 ) ); + p.setBrush( NoBrush ); + + QPoint pt( m_rubber->x(), m_rubber->y() ); + pt = contentsToViewport( pt ); + style().drawPrimitive( QStyle::PE_FocusRect, &p, + QRect( pt.x(), pt.y(), m_rubber->width(), m_rubber->height() ), + colorGroup(), QStyle::Style_Default, colorGroup().base() ); + p.end(); +} + +void KonqBaseListViewWidget::slotAutoScroll() +{ + if ( !m_rubber ) + return; + + // this code assumes that all items have the same height + + const QPoint pos = viewport()->mapFromGlobal( QCursor::pos() ); + const QPoint vc = viewportToContents( pos ); + + if ( vc == m_rubber->bottomRight() ) + return; + + const int oldTop = m_rubber->normalize().top(); + const int oldBottom = m_rubber->normalize().bottom(); + + drawRubber(); + m_rubber->setBottomRight( vc ); + + QListViewItem *cur = itemAt( QPoint(0,0) ); + + bool block = signalsBlocked(); + blockSignals( true ); + + QRect nr = m_rubber->normalize(); + if ( cur ) + { + QRect rect = itemRect( cur ); + if ( !allColumnsShowFocus() ) + rect.setWidth( executeArea( cur ) ); + + rect = QRect( viewportToContents( rect.topLeft() ), + viewportToContents( rect.bottomRight() ) ); + + if ( !allColumnsShowFocus() ) + { + rect.setLeft( header()->sectionPos( 0 ) ); + rect.setWidth( rect.width() ); + } + else + { + rect.setLeft( 0 ); + rect.setWidth( header()->headerWidth() ); + } + + QRect r = rect; + QListViewItem *tmp = cur; + + while ( cur && rect.top() <= oldBottom ) + { + if ( rect.intersects( nr ) ) + { + if ( !cur->isSelected() && cur->isSelectable() ) + setSelected( cur, true ); + } else if ( !m_selected || !m_selected->contains( (KonqBaseListViewItem*)cur ) ) + setSelected( cur, false ); + + cur = cur->itemBelow(); + if (cur && !allColumnsShowFocus()) + rect.setWidth( executeArea( cur ) ); + rect.moveBy( 0, rect.height() ); + } + + rect = r; + rect.moveBy( 0, -rect.height() ); + cur = tmp->itemAbove(); + + while ( cur && rect.bottom() >= oldTop ) + { + if ( rect.intersects( nr ) ) + { + if ( !cur->isSelected() && cur->isSelectable() ) + setSelected( cur, true ); + } else if ( !m_selected || !m_selected->contains( (KonqBaseListViewItem*)cur ) ) + setSelected( cur, false ); + + cur = cur->itemAbove(); + if (cur && !allColumnsShowFocus()) + rect.setWidth( executeArea( cur ) ); + rect.moveBy( 0, -rect.height() ); + } + } + + blockSignals( block ); + emit selectionChanged(); + + drawRubber(); + + const int scroll_margin = 40; + ensureVisible( vc.x(), vc.y(), scroll_margin, scroll_margin ); + + if ( !QRect( scroll_margin, scroll_margin, + viewport()->width() - 2*scroll_margin, + viewport()->height() - 2*scroll_margin ).contains( pos ) ) + { + if ( !m_scrollTimer ) + { + m_scrollTimer = new QTimer( this ); + + connect( m_scrollTimer, SIGNAL( timeout() ), + this, SLOT( slotAutoScroll() ) ); + m_scrollTimer->start( 100, false ); + } + } + else if ( m_scrollTimer ) + { + disconnect( m_scrollTimer, SIGNAL( timeout() ), + this, SLOT( slotAutoScroll() ) ); + m_scrollTimer->stop(); + delete m_scrollTimer; + m_scrollTimer = 0; + } +} + +void KonqBaseListViewWidget::viewportPaintEvent( QPaintEvent *e ) +{ + drawRubber(); + KListView::viewportPaintEvent( e ); + drawRubber(); +} + +void KonqBaseListViewWidget::viewportResizeEvent(QResizeEvent * e) +{ + KListView::viewportResizeEvent(e); + emit viewportAdjusted(); +} + +void KonqBaseListViewWidget::viewportDragMoveEvent( QDragMoveEvent *_ev ) +{ + KonqBaseListViewItem *item = + isExecuteArea( _ev->pos() ) ? (KonqBaseListViewItem*)itemAt( _ev->pos() ) : 0L; + + // Unselect previous drag-over-item + if ( m_dragOverItem && m_dragOverItem != item ) + if ( !m_selected || !m_selected->contains( m_dragOverItem ) ) + setSelected( m_dragOverItem, false ); + + if ( !item ) + { + _ev->acceptAction(); + m_dragOverItem = 0L; + return; + } + + if ( item->item()->acceptsDrops() ) + { + _ev->acceptAction(); + if ( m_dragOverItem != item ) + { + setSelected( item, true ); + m_dragOverItem = item; + } + } + else + { + _ev->ignore(); + m_dragOverItem = 0L; + } +} + +void KonqBaseListViewWidget::viewportDragEnterEvent( QDragEnterEvent *_ev ) +{ + m_dragOverItem = 0L; + + // By default we accept any format + _ev->acceptAction(); +} + +void KonqBaseListViewWidget::viewportDragLeaveEvent( QDragLeaveEvent * ) +{ + if ( m_dragOverItem != 0L ) + setSelected( m_dragOverItem, false ); + m_dragOverItem = 0L; +} + +void KonqBaseListViewWidget::viewportDropEvent( QDropEvent *ev ) +{ + if ( m_dirLister->url().isEmpty() ) + return; + kdDebug() << "KonqBaseListViewWidget::viewportDropEvent" << endl; + if ( m_dragOverItem != 0L ) + setSelected( m_dragOverItem, false ); + m_dragOverItem = 0L; + + ev->accept(); + + // We dropped on an item only if we dropped on the Name column. + KonqBaseListViewItem *item = + isExecuteArea( ev->pos() ) ? (KonqBaseListViewItem*)itemAt( ev->pos() ) : 0; + + KFileItem * destItem = (item) ? item->item() : m_dirLister->rootItem(); + KURL u = destItem ? destItem->url() : url(); + if ( u.isEmpty() ) + return; + KonqOperations::doDrop( destItem /*may be 0L*/, u, ev, this ); +} + +void KonqBaseListViewWidget::startDrag() +{ + m_fileTip->setItem( 0 ); + KURL::List urls = selectedUrls( false ); + + QListViewItem * m_pressedItem = currentItem(); + + QPixmap pixmap2; + bool pixmap0Invalid = !m_pressedItem->pixmap(0) || m_pressedItem->pixmap(0)->isNull(); + + // Multiple URLs ? + if (( urls.count() > 1 ) || (pixmap0Invalid)) + { + int iconSize = m_pBrowserView->m_pProps->iconSize(); + iconSize = iconSize ? iconSize : KGlobal::iconLoader()->currentSize( KIcon::Small ); // Default = small + pixmap2 = DesktopIcon( "kmultiple", iconSize ); + if ( pixmap2.isNull() ) + kdWarning(1202) << "Could not find multiple pixmap" << endl; + } + + //KURLDrag *d = new KURLDrag( urls, viewport() ); + KonqDrag *drag= new KonqDrag( urls, selectedUrls(true), false, viewport() ); + if ( !pixmap2.isNull() ) + drag->setPixmap( pixmap2 ); + else if ( !pixmap0Invalid ) + drag->setPixmap( *m_pressedItem->pixmap( 0 ) ); + + drag->drag(); +} + +void KonqBaseListViewWidget::slotItemRenamed( QListViewItem *item, const QString &name, int col ) +{ + Q_ASSERT( col == 0 ); + Q_ASSERT( item != 0 ); + + // The correct behavior is to show the old name until the rename has successfully + // completed. Unfortunately, KListView forces us to allow the text to be changed + // before we try the rename, so set it back to the pre-rename state. + KonqBaseListViewItem *renamedItem = static_cast(item); + renamedItem->updateContents(); + + // Don't do anything if the user renamed to a blank name. + if( !name.isEmpty() ) + { + // Actually attempt the rename. If it succeeds, KDirLister will update the name. + KonqOperations::rename( this, renamedItem->item()->url(), KIO::encodeFileName( name ) ); + } + + // When the KListViewLineEdit loses focus, focus tends to go to the location bar... + setFocus(); +} + +void KonqBaseListViewWidget::reportItemCounts() +{ + KFileItemList lst = selectedFileItems(); + if ( !lst.isEmpty() ) + m_pBrowserView->emitCounts( lst ); + else + { + lst = visibleFileItems(); + m_pBrowserView->emitCounts( lst ); + } +} + +void KonqBaseListViewWidget::slotSelectionChanged() +{ + reportItemCounts(); + + KFileItemList lst = selectedFileItems(); + emit m_pBrowserView->m_extension->selectionInfo( lst ); +} + +void KonqBaseListViewWidget::slotMouseButtonClicked2( int _button, + QListViewItem *_item, const QPoint& pos, int ) +{ + if ( _button == MidButton ) + { + if ( _item && isExecuteArea( viewport()->mapFromGlobal(pos) ) ) + m_pBrowserView->mmbClicked( static_cast(_item)->item() ); + else // MMB on background + m_pBrowserView->mmbClicked( 0 ); + } +} + +void KonqBaseListViewWidget::slotExecuted( QListViewItem *item ) +{ + if ( !item ) + return; + m_fileTip->setItem( 0 ); + // isExecuteArea() checks whether the mouse pointer is + // over an area where an action should be triggered + // (i.e. the Name column, including pixmap and "+") + if ( isExecuteArea( viewport()->mapFromGlobal( QCursor::pos() ) ) ) + slotReturnPressed( item ); +} + +void KonqBaseListViewWidget::selectedItems( QPtrList *_list ) +{ + iterator it = begin(); + for ( ; it != end(); it++ ) + if ( it->isSelected() ) + _list->append( &*it ); +} + +KFileItemList KonqBaseListViewWidget::visibleFileItems() +{ + KFileItemList list; + KonqBaseListViewItem *item = static_cast(firstChild()); + while ( item ) + { + list.append( item->item() ); + item = static_cast(item->itemBelow()); + } + return list; +} + +KFileItemList KonqBaseListViewWidget::selectedFileItems() +{ + KFileItemList list; + iterator it = begin(); + for ( ; it != end(); it++ ) + if ( it->isSelected() ) + list.append( it->item() ); + return list; +} + +KURL::List KonqBaseListViewWidget::selectedUrls( bool mostLocal ) +{ + bool dummy; + KURL::List list; + iterator it = begin(); + for ( ; it != end(); it++ ) + if ( it->isSelected() ) + list.append( mostLocal ? it->item()->mostLocalURL( dummy ) : it->item()->url() ); + return list; +} + +KonqPropsView * KonqBaseListViewWidget::props() const +{ + return m_pBrowserView->m_pProps; +} + +void KonqBaseListViewWidget::slotReturnPressed( QListViewItem *_item ) +{ + if ( !_item ) + return; + KFileItem *fileItem = static_cast(_item)->item(); + if ( !fileItem ) + return; + + KURL url = fileItem->url(); + url.cleanPath(); + bool isIntoTrash = url.isLocalFile() && url.path(1).startsWith(KGlobalSettings::trashPath()); + if ( !isIntoTrash || (isIntoTrash && fileItem->isDir()) ) + m_pBrowserView->lmbClicked( fileItem ); + else + KMessageBox::information( 0, i18n("You must take the file out of the trash before being able to use it.") ); +} + +void KonqBaseListViewWidget::slotPopupMenu( QListViewItem *i, const QPoint &point, int c ) +{ + kdDebug(1202) << "KonqBaseListViewWidget::slotPopupMenu" << endl; + popupMenu( point, ( i != 0 && c == -1 ) ); // i != 0 && c == -1 when activated by keyboard +} + +void KonqBaseListViewWidget::popupMenu( const QPoint& _global, bool alwaysForSelectedFiles ) +{ + m_fileTip->setItem( 0 ); + + KFileItemList lstItems; + KParts::BrowserExtension::PopupFlags popupFlags = KParts::BrowserExtension::DefaultPopupItems; + + // Only consider a right-click on the name column as something + // related to the selection. On all the other columns, we want + // a popup for the current dir instead. + if ( alwaysForSelectedFiles || isExecuteArea( viewport()->mapFromGlobal( _global ) ) ) + { + QPtrList items; + selectedItems( &items ); + for ( KonqBaseListViewItem *item = items.first(); item; item = items.next() ) + lstItems.append( item->item() ); + } + + KFileItem *rootItem = 0L; + bool deleteRootItem = false; + if ( lstItems.count() == 0 ) // emit popup for background + { + clearSelection(); + + if ( m_dirLister->url().isEmpty() ) + return; + rootItem = m_dirLister->rootItem(); + if ( !rootItem ) + { + if ( url().isEmpty() ) + return; + // Maybe we want to do a stat to get full info about the root item + // (when we use permissions). For now create a dummy one. + rootItem = new KFileItem( S_IFDIR, (mode_t)-1, url() ); + deleteRootItem = true; + } + + lstItems.append( rootItem ); + popupFlags = KParts::BrowserExtension::ShowNavigationItems | KParts::BrowserExtension::ShowUp; + } + emit m_pBrowserView->extension()->popupMenu( 0, _global, lstItems, KParts::URLArgs(), popupFlags ); + + if ( deleteRootItem ) + delete rootItem; // we just created it +} + +void KonqBaseListViewWidget::updateListContents() +{ + for ( KonqBaseListViewWidget::iterator it = begin(); it != end(); it++ ) + it->updateContents(); +} + +bool KonqBaseListViewWidget::openURL( const KURL &url ) +{ + kdDebug(1202) << k_funcinfo << "protocol: " << url.protocol() + << " url: " << url.path() << endl; + + // The first time or new protocol? So create the columns first. + if ( columns() < 1 || url.protocol() != m_url.protocol() ) + { + readProtocolConfig( url ); + createColumns(); + } + + m_bTopLevelComplete = false; + m_itemFound = false; + + if ( m_itemToGoTo.isEmpty() && url.equals( m_url.upURL(), true ) ) + m_itemToGoTo = m_url.fileName( true ); + + // Check for new properties in the new dir + // newProps returns true the first time, and any time something might + // have changed. + bool newProps = m_pBrowserView->m_pProps->enterDir( url ); + + m_dirLister->setNameFilter( m_pBrowserView->nameFilter() ); + m_dirLister->setMimeFilter( m_pBrowserView->mimeFilter() ); + m_dirLister->setShowingDotFiles( m_pBrowserView->m_pProps->isShowingDotFiles() ); + + KParts::URLArgs args = m_pBrowserView->extension()->urlArgs(); + if ( args.reload ) + { + args.xOffset = contentsX(); + args.yOffset = contentsY(); + m_pBrowserView->extension()->setURLArgs( args ); + + if ( currentItem() && itemRect( currentItem() ).isValid() ) + m_itemToGoTo = currentItem()->text(0); + + m_pBrowserView->m_filesToSelect.clear(); + iterator it = begin(); + for( ; it != end(); it++ ) + if ( it->isSelected() ) + m_pBrowserView->m_filesToSelect += it->text(0); + } + + m_itemsToSelect = m_pBrowserView->m_filesToSelect; + if ( !m_itemsToSelect.isEmpty() && m_itemToGoTo.isEmpty() ) + m_itemToGoTo = m_itemsToSelect[0]; + + if ( columnWidthMode(0) == Maximum ) + setColumnWidth(0,50); + + m_url = url; + m_bUpdateContentsPosAfterListing = true; + + // Start the directory lister ! + m_dirLister->openURL( url, false /* new url */, args.reload ); + + // Apply properties and reflect them on the actions + // do it after starting the dir lister to avoid changing the properties + // of the old view + if ( newProps ) + { + m_pBrowserView->newIconSize( m_pBrowserView->m_pProps->iconSize() ); + m_pBrowserView->m_paShowDot->setChecked( m_pBrowserView->m_pProps->isShowingDotFiles() ); + if ( m_pBrowserView->m_paCaseInsensitive->isChecked() != m_pBrowserView->m_pProps->isCaseInsensitiveSort() ) { + m_pBrowserView->m_paCaseInsensitive->setChecked( m_pBrowserView->m_pProps->isCaseInsensitiveSort() ); + // This is in case openURL returned all items synchronously. + sort(); + } + + // It has to be "viewport()" - this is what KonqDirPart's slots act upon, + // and otherwise we get a color/pixmap in the square between the scrollbars. + m_pBrowserView->m_pProps->applyColors( viewport() ); + } + + return true; +} + +void KonqBaseListViewWidget::setComplete() +{ + kdDebug(1202) << k_funcinfo << "Update Contents Pos: " + << m_bUpdateContentsPosAfterListing << endl; + + m_bTopLevelComplete = true; + + // Alex: this flag is set when we are just finishing a voluntary listing, + // so do the go-to-item thing only under here. When we update the + // current directory automatically (e.g. after a file has been deleted), + // we don't want to go to the first item ! (David) + if ( m_bUpdateContentsPosAfterListing ) + { + m_bUpdateContentsPosAfterListing = false; + + if ( !m_itemFound ) + setCurrentItem( firstChild() ); + + if ( !m_restored && !m_pBrowserView->extension()->urlArgs().reload ) + ensureItemVisible( currentItem() ); + else + setContentsPos( m_pBrowserView->extension()->urlArgs().xOffset, + m_pBrowserView->extension()->urlArgs().yOffset ); + + emit selectionChanged(); + } + + m_itemToGoTo = ""; + m_restored = false; + + // Show totals + reportItemCounts(); + + m_pBrowserView->emitMouseOver( 0 ); + + if ( !isUpdatesEnabled() || !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } + + // Show "cut" icons as such + m_pBrowserView->slotClipboardDataChanged(); +} + +void KonqBaseListViewWidget::slotStarted() +{ + //kdDebug(1202) << k_funcinfo << endl; + + if (!m_bTopLevelComplete) + emit m_pBrowserView->started( 0 ); +} + +void KonqBaseListViewWidget::slotCompleted() +{ + //kdDebug(1202) << k_funcinfo << endl; + + setComplete(); + if ( m_bTopLevelComplete ) + emit m_pBrowserView->completed(); + m_pBrowserView->listingComplete(); +} + +void KonqBaseListViewWidget::slotCanceled() +{ + //kdDebug(1202) << k_funcinfo << endl; + + setComplete(); + emit m_pBrowserView->canceled( QString::null ); +} + +void KonqBaseListViewWidget::slotClear() +{ + //kdDebug(1202) << k_funcinfo << endl; + + m_activeItem = 0; + m_fileTip->setItem( 0 ); + delete m_selected; m_selected = 0; + m_pBrowserView->resetCount(); + m_pBrowserView->lstPendingMimeIconItems().clear(); + + viewport()->setUpdatesEnabled( false ); + setUpdatesEnabled( false ); + clear(); +} + +void KonqBaseListViewWidget::slotNewItems( const KFileItemList & entries ) +{ + //kdDebug(1202) << k_funcinfo << entries.count() << endl; + + for ( QPtrListIterator kit ( entries ); kit.current(); ++kit ) + { + KonqListViewItem * tmp = new KonqListViewItem( this, *kit ); + if ( !m_itemFound && tmp->text(0) == m_itemToGoTo ) + { + setCurrentItem( tmp ); + m_itemFound = true; + } + if ( !m_itemsToSelect.isEmpty() ) { + QStringList::Iterator tsit = m_itemsToSelect.find( (*kit)->name() ); + if ( tsit != m_itemsToSelect.end() ) { + m_itemsToSelect.remove( tsit ); + setSelected( tmp, true ); + } + } + if ( !(*kit)->isMimeTypeKnown() ) + m_pBrowserView->lstPendingMimeIconItems().append( tmp ); + } + m_pBrowserView->newItems( entries ); + + if ( !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } + slotUpdateBackground(); +} + +void KonqBaseListViewWidget::slotDeleteItem( KFileItem * _fileitem ) +{ + // new in 3.5.5 +#ifdef KPARTS_BROWSEREXTENSION_HAS_ITEMS_REMOVED + KFileItemList list; + list.append( _fileitem ); + emit m_pBrowserView->extension()->itemsRemoved( list ); +#else +#error "Your kdelibs doesn't have KParts::BrowserExtension::itemsRemoved, please update it to at least 3.5.5" +#endif + + iterator it = begin(); + for( ; it != end(); ++it ) + if ( (*it).item() == _fileitem ) + { + kdDebug(1202) << k_funcinfo << "removing " << _fileitem->url().url() << " from tree!" << endl; + + m_pBrowserView->deleteItem( _fileitem ); + m_pBrowserView->lstPendingMimeIconItems().remove( &(*it) ); + + if ( m_activeItem == &(*it) ) { + m_fileTip->setItem( 0 ); + m_activeItem = 0; + } + + delete &(*it); + // HACK HACK HACK: QListViewItem/KonqBaseListViewItem should + // take care and the source looks like it does; till the + // real bug is found, this fixes some crashes (malte) + emit selectionChanged(); + return; + } + + // This is needed for the case the root of the current view is deleted. + // I supposed slotUpdateBackground has to be called as well after an item + // was removed from a listview and was just forgotten previously (Brade). + // OK, but this code also gets activated when deleting a hidden file... (dfaure) + if ( !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } + slotUpdateBackground(); +} + +void KonqBaseListViewWidget::slotRefreshItems( const KFileItemList & entries ) +{ + //kdDebug(1202) << k_funcinfo << endl; + + QPtrListIterator kit ( entries ); + for ( ; kit.current(); ++kit ) + { + iterator it = begin(); + for ( ; it != end(); ++it ) + if ( (*it).item() == kit.current() ) + { + it->updateContents(); + break; + } + } + + reportItemCounts(); +} + +void KonqBaseListViewWidget::slotRedirection( const KURL & url ) +{ + kdDebug(1202) << k_funcinfo << url << endl; + + if ( (columns() < 1) || (url.protocol() != m_url.protocol()) ) + { + readProtocolConfig( url ); + createColumns(); + } + const QString prettyURL = url.pathOrURL(); + emit m_pBrowserView->extension()->setLocationBarURL( prettyURL ); + emit m_pBrowserView->setWindowCaption( prettyURL ); + m_pBrowserView->m_url = url; + m_url = url; +} + +KonqBaseListViewWidget::iterator& KonqBaseListViewWidget::iterator::operator++() +{ + if ( !m_p ) return *this; + KonqBaseListViewItem *i = (KonqBaseListViewItem *)m_p->firstChild(); + if ( i ) + { + m_p = i; + return *this; + } + i = (KonqBaseListViewItem *)m_p->nextSibling(); + if ( i ) + { + m_p = i; + return *this; + } + m_p = (KonqBaseListViewItem *)m_p->parent(); + + while ( m_p ) + { + if ( m_p->nextSibling() ) + break; + m_p = (KonqBaseListViewItem *)m_p->parent(); + } + + if ( m_p ) + m_p = (KonqBaseListViewItem *)m_p->nextSibling(); + + return *this; +} + +KonqBaseListViewWidget::iterator KonqBaseListViewWidget::iterator::operator++(int) +{ + KonqBaseListViewWidget::iterator it = *this; + if ( !m_p ) return it; + KonqBaseListViewItem *i = (KonqBaseListViewItem *)m_p->firstChild(); + if ( i ) + { + m_p = i; + return it; + } + i = (KonqBaseListViewItem *)m_p->nextSibling(); + if ( i ) + { + m_p = i; + return it; + } + m_p = (KonqBaseListViewItem *)m_p->parent(); + + while ( m_p ) + { + if ( m_p->nextSibling() ) + break; + m_p = (KonqBaseListViewItem *)m_p->parent(); + } + + if ( m_p ) + m_p = (KonqBaseListViewItem *)m_p->nextSibling(); + return it; +} + +void KonqBaseListViewWidget::paintEmptyArea( QPainter *p, const QRect &r ) +{ + const QPixmap *pm = viewport()->paletteBackgroundPixmap(); + + if (!pm || pm->isNull()) + p->fillRect(r, viewport()->backgroundColor()); + else + { + QRect devRect = p->xForm( r ); + int ax = (devRect.x() + contentsX()); + int ay = (devRect.y() + contentsY()); + /* kdDebug() << "KonqBaseListViewWidget::paintEmptyArea " + << r.x() << "," << r.y() << " " << r.width() << "x" << r.height() + << " drawing pixmap with offset " << ax << "," << ay + << endl;*/ + p->drawTiledPixmap(r, *pm, QPoint(ax, ay)); + } +} + +void KonqBaseListViewWidget::disableIcons( const KURL::List & lst ) +{ + iterator kit = begin(); + for( ; kit != end(); ++kit ) + { + bool bFound = false; + // Wow. This is ugly. Matching two lists together.... + // Some sorting to optimise this would be a good idea ? + for (KURL::List::ConstIterator it = lst.begin(); !bFound && it != lst.end(); ++it) + { + if ( (*kit).item()->url() == *it ) // *it is encoded already + { + bFound = true; + // maybe remove "it" from lst here ? + } + } + (*kit).setDisabled( bFound ); + } +} + +void KonqBaseListViewWidget::saveState( QDataStream & ds ) +{ + QString str; + if ( currentItem() ) + str = static_cast(currentItem())->item()->url().fileName(true); + ds << str << m_url; +} + +void KonqBaseListViewWidget::restoreState( QDataStream & ds ) +{ + m_restored = true; + + QString str; + KURL url; + ds >> str >> url; + if ( !str.isEmpty() ) + m_itemToGoTo = str; + + if ( columns() < 1 || url.protocol() != m_url.protocol() ) + { + readProtocolConfig( url ); + createColumns(); + } + m_url = url; + + m_bTopLevelComplete = false; + m_itemFound = false; +} + +void KonqBaseListViewWidget::slotUpdateBackground() +{ + if ( viewport()->paletteBackgroundPixmap() && !viewport()->paletteBackgroundPixmap()->isNull() ) + { + if ( !m_backgroundTimer ) + { + m_backgroundTimer = new QTimer( this ); + connect( m_backgroundTimer, SIGNAL( timeout() ), viewport(), SLOT( update() ) ); + } + else + m_backgroundTimer->stop(); + + m_backgroundTimer->start( 50, true ); + } +} + +bool KonqBaseListViewWidget::caseInsensitiveSort() const +{ + return m_pBrowserView->m_pProps->isCaseInsensitiveSort(); +} + +// based on isExecuteArea from klistview.cpp +int KonqBaseListViewWidget::executeArea( QListViewItem *_item ) +{ + if ( !_item ) + return 0; + + int width = treeStepSize() * ( _item->depth() + ( rootIsDecorated() ? 1 : 0 ) ); + width += itemMargin(); + int ca = AlignHorizontal_Mask & columnAlignment( 0 ); + if ( ca == AlignLeft || ca == AlignAuto ) + { + width += _item->width( fontMetrics(), this, 0 ); + if ( width > columnWidth( 0 ) ) + width = columnWidth( 0 ); + } + return width; +} + +#include "konq_listviewwidget.moc" diff --git a/konqueror/listview/konq_listviewwidget.h b/konqueror/listview/konq_listviewwidget.h new file mode 100644 index 000000000..bc4161862 --- /dev/null +++ b/konqueror/listview/konq_listviewwidget.h @@ -0,0 +1,270 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis + 2004 Michael Brade + + 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. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef __konq_listviewwidget_h__ +#define __konq_listviewwidget_h__ + +#include +#include + +#include +#include +#include +#include +#include +#include "konq_listviewitems.h" + +namespace KIO { class Job; } + +class QCursor; +class QRect; +class KDirLister; +class KonqFMSettings; +class ListViewPropertiesExtension; +class KToggleAction; +class KonqListView; +class KonqFileTip; +class ListViewBrowserExtension; +class QTimer; +class QFocusEvent; +class QDragMoveEvent; +class QDragEnterEvent; +class QDragLeaveEvent; +class QDropEvent; +class QPaintEvent; +class QResizeEvent; +class QMouseEvent; + +class ColumnInfo +{ +public: + ColumnInfo(); + void setData( const QString& n, const QString& desktopName, int kioUds, + KToggleAction *someAction, int theWith = -1 ); + void setData( const QString& n, const QString& desktopName, int kioUds /* UDS_EXTRA */, + QVariant::Type type, KToggleAction *someAction, int theWith = -1 ); + int displayInColumn; + QString name; + QString desktopFileName; + int udsId; + QVariant::Type type; // only used if udsId == UDS_EXTRA + bool displayThisOne; + KToggleAction *toggleThisOne; + int width; +}; + +/** + * The tree view widget (based on KListView). + * Most of the functionality is here. + */ +class KonqBaseListViewWidget : public KListView +{ + friend class KonqBaseListViewItem; + friend class KonqListView; + friend class ListViewBrowserExtension; + + Q_OBJECT +public: + KonqBaseListViewWidget( KonqListView *parent, QWidget *parentWidget ); + virtual ~KonqBaseListViewWidget(); + unsigned int NumberOfAtoms; + + virtual void stop(); + const KURL& url(); + + struct iterator + { + KonqBaseListViewItem *m_p; + + iterator() : m_p( 0L ) { } + iterator( KonqBaseListViewItem *_b ) : m_p( _b ) { } + iterator( const iterator& _it ) : m_p( _it.m_p ) { } + + KonqBaseListViewItem& operator*() { return *m_p; } + KonqBaseListViewItem *operator->() { return m_p; } + bool operator==( const iterator& _it ) { return ( m_p == _it.m_p ); } + bool operator!=( const iterator& _it ) { return ( m_p != _it.m_p ); } + iterator& operator++(); + iterator operator++(int); + }; + iterator begin() { iterator it( (KonqBaseListViewItem *)firstChild() ); return it; } + iterator end() { iterator it; return it; } + + virtual bool openURL( const KURL &url ); + + void selectedItems( QPtrList *_list ); + KFileItemList visibleFileItems(); + KFileItemList selectedFileItems(); + KURL::List selectedUrls( bool mostLocal = false ); + + /** @return the KonqListViewDir which handles the directory _url */ + //virtual KonqListViewDir *findDir ( const QString & _url ); + + /** + * @return the Properties instance for this view. Used by the items. + */ + KonqPropsView *props() const; + + //QPtrList *columnConfigInfo() { return &confColumns; }; + QValueVector& columnConfigInfo() { return confColumns; }; + QString sortedByColumn; + + virtual void setShowIcons( bool enable ) { m_showIcons = enable; } + virtual bool showIcons() { return m_showIcons; } + + void setItemFont( const QFont &f ) { m_itemFont = f; } + QFont itemFont() const { return m_itemFont; } + void setItemColor( const QColor &c ) { m_itemColor = c; } + QColor itemColor() const { return m_itemColor; } + int iconSize() const { return props()->iconSize(); } + + void setAscending( bool b ) { m_bAscending = b; } + bool ascending() const { return m_bAscending; } + bool caseInsensitiveSort() const; + + virtual void paintEmptyArea( QPainter *p, const QRect &r ); + + virtual void saveState( QDataStream & ); + virtual void restoreState( QDataStream & ); + + virtual void disableIcons( const KURL::List& lst ); + + KonqListView *m_pBrowserView; + KonqFMSettings *m_pSettings; + +signals: + void viewportAdjusted(); + +public slots: + //virtual void slotOnItem( KonqBaseListViewItem* _item ); + // The '2' was added to differentiate it from KListView::slotMouseButtonClicked() + void slotMouseButtonClicked2( int _button, QListViewItem *_item, const QPoint& pos, int ); + virtual void slotExecuted( QListViewItem *_item ); + void slotItemRenamed( QListViewItem *, const QString &, int ); + +protected slots: + void slotAutoScroll(); + + // from QListView + virtual void slotReturnPressed( QListViewItem *_item ); + virtual void slotCurrentChanged( QListViewItem *_item ) { slotOnItem( _item ); } + + // slots connected to the directory lister + virtual void slotStarted(); + virtual void slotCompleted(); + virtual void slotCanceled(); + virtual void slotClear(); + virtual void slotNewItems( const KFileItemList & ); + virtual void slotDeleteItem( KFileItem * ); + virtual void slotRefreshItems( const KFileItemList & ); + virtual void slotRedirection( const KURL & ); + void slotPopupMenu( QListViewItem *, const QPoint&, int ); + + // forces a repaint on column size changes / branch expansion + // when there is a background pixmap + void slotUpdateBackground(); + + //Notifies the browser view of the currently selected items + void slotSelectionChanged(); + virtual void reportItemCounts(); + +protected: + //creates the listview columns according to confColumns + virtual void createColumns(); + //reads the configuration for the columns of the current + //protocol, it is called when the protocol changes + //it checks/unchecks the menu items and sets confColumns + void readProtocolConfig( const KURL& url ); + //calls updateContents of every ListViewItem, called after + //the columns changed + void updateListContents(); + + //this is called in the constructor, so virtual would be nonsense + void initConfig(); + + virtual void startDrag(); + virtual void viewportDragMoveEvent( QDragMoveEvent *_ev ); + virtual void viewportDragEnterEvent( QDragEnterEvent *_ev ); + virtual void viewportDragLeaveEvent( QDragLeaveEvent *_ev ); + virtual void viewportDropEvent( QDropEvent *_ev ); + virtual void viewportPaintEvent( QPaintEvent *e ); + virtual void viewportResizeEvent( QResizeEvent *e ); + + virtual void drawRubber(); + virtual void contentsMousePressEvent( QMouseEvent *e ); + virtual void contentsMouseReleaseEvent( QMouseEvent *e ); + virtual void contentsMouseMoveEvent( QMouseEvent *e ); + virtual void contentsWheelEvent( QWheelEvent * e ); + + virtual void leaveEvent( QEvent *e ); + + /** Common method for slotCompleted and slotCanceled */ + virtual void setComplete(); + + //the second parameter is set to true when the menu shortcut is pressed, + //so the position of the mouse pointer doesn't matter when using keyboard, aleXXX + virtual void popupMenu( const QPoint& _global, bool alwaysForSelectedFiles = false ); + + //this one is called only by KListView, and this is friend anyways (Alex) + //KDirLister *dirLister() const { return m_dirLister; } + +protected: + int executeArea( QListViewItem *_item ); + + /** The directory lister for this URL */ + KDirLister *m_dirLister; + + //QPtrList confColumns; + // IMO there is really no need for an advanced data structure + //we have a fixed number of members, + //it consumes less memory and access should be faster (Alex) + // This might not be the case for ever... we should introduce custom fields in kio (David) + QValueVector confColumns; + + KonqBaseListViewItem *m_dragOverItem; + KonqBaseListViewItem *m_activeItem; + QPtrList *m_selected; + QTimer *m_scrollTimer; + + QFont m_itemFont; + QColor m_itemColor; + + QRect *m_rubber; + + bool m_bTopLevelComplete:1; + bool m_showIcons:1; + bool m_bCaseInsensitive:1; + bool m_bUpdateContentsPosAfterListing:1; + bool m_bAscending:1; + bool m_itemFound:1; + bool m_restored:1; + + int m_filenameColumn; + int m_filenameColumnWidth; + + KURL m_url; + + QString m_itemToGoTo; + QStringList m_itemsToSelect; + QTimer *m_backgroundTimer; + + KonqFileTip *m_fileTip; +}; + +#endif diff --git a/konqueror/listview/konq_textview.desktop b/konqueror/listview/konq_textview.desktop new file mode 100644 index 000000000..f5d4e5c98 --- /dev/null +++ b/konqueror/listview/konq_textview.desktop @@ -0,0 +1,90 @@ +[Desktop Entry] +Type=Service +Name=Text View +Name[af]=Teks Besigtig +Name[ar]=عرض نصي +Name[az]=Mətn Görünüşü +Name[be]=Тэкст +Name[bg]=Текстов преглед +Name[bn]=টেক্সট ভিউ +Name[br]=Gwel skrid +Name[bs]=Tekstualni pogled +Name[ca]=Vista de text +Name[cs]=Textový pohled +Name[csb]=Tekstowi wëzdrzatk +Name[cy]=Golwg Testun +Name[da]=Tekstvisning +Name[de]=Textansicht +Name[el]=Προβολή κειμένου +Name[eo]=Tekstrigardo +Name[es]=Vista de texto +Name[et]=Vaade tekstina +Name[eu]=Testu ikuspegia +Name[fa]=متن‌نما +Name[fi]=Tekstinäkymä +Name[fr]=Affichage de Texte +Name[fy]=Tekstwerjefte +Name[ga]=Amharc Téacs +Name[gl]=Vista de Texto +Name[he]=תצוגת טקסט +Name[hi]=पाठ दृश्य +Name[hr]=Tekstualni prikaz +Name[hu]=Szöveges +Name[id]=Tampilan Teks +Name[is]=Textasýn +Name[it]=Vista testuale +Name[ja]=テキストビュー +Name[ka]=ტექსტის სახით +Name[kk]=Жай мәтін тізім +Name[km]=ទិដ្ឋភាព​អត្ថបទ +Name[ko]=VideoText 뷰어 +Name[lo]=ມຸມມອງຂໍ້ຄວາມ +Name[lt]=Rodyti tekstą +Name[lv]=Teksta Skatījums +Name[mk]=Текстуален преглед +Name[mn]=Текстээр харах +Name[ms]=Paparan Teks +Name[mt]=Uri Kliem biss +Name[nb]=Tekstvisning +Name[nds]=Textansicht +Name[ne]=पाठ दृश्य +Name[nl]=Tekstweergave +Name[nn]=Tekstvising +Name[nso]=Pono ya Sengwalwana +Name[pa]=ਪਾਠ ਝਲਕ +Name[pl]=Widok tekstowy +Name[pt]=Vista em Texto +Name[pt_BR]=Visão Texto +Name[ro]=Vizualizare text +Name[ru]=В виде текста +Name[rw]=Igaragaza Umwandiko +Name[se]=Teakstačájeheapmi +Name[sk]=Textový pohľad +Name[sl]=Besedilni pogled +Name[sr]=Текстуални приказ +Name[sr@Latn]=Tekstualni prikaz +Name[sv]=Textvy +Name[ta]=உரை காட்சி +Name[te]=వచన వీక్షణం +Name[tg]=Ба намуди матн +Name[th]=มุมมองแบบข้อความ +Name[tr]=Metin Görünümü +Name[tt]=Mätenle Küreneş +Name[uk]=Текстовий вигляд +Name[uz]=Matn koʻrinishida +Name[uz@cyrillic]=Матн кўринишида +Name[ven]=Mbonalelo ya Manwalwa +Name[vi]=Xem kiểu Văn bản +Name[wa]=Vey e môde tecse +Name[xh]=Imboniselo Yombhalo +Name[zh_CN]=文本视图 +Name[zh_TW]=文字檢視 +Name[zu]=Umbukiso wombhalo +MimeType=inode/directory +ServiceTypes=Browser/View +X-KDE-Library=konq_listview +X-KDE-BrowserView-Args=TextView +X-KDE-BrowserView-HideFromMenus=true +X-KDE-BrowserView-Built-Into=konqueror +Icon=view_text +InitialPreference=6 diff --git a/konqueror/listview/konq_textview.rc b/konqueror/listview/konq_textview.rc new file mode 100644 index 000000000..612deb5cb --- /dev/null +++ b/konqueror/listview/konq_textview.rc @@ -0,0 +1,35 @@ + + + + &Edit + Selection + + + + + + + + + &View + + + Show Details + + + + + + + + + + + + + + + + + + diff --git a/konqueror/listview/konq_textviewitem.cc b/konqueror/listview/konq_textviewitem.cc new file mode 100644 index 000000000..71d1de833 --- /dev/null +++ b/konqueror/listview/konq_textviewitem.cc @@ -0,0 +1,232 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis + + 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. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "konq_textviewitem.h" +#include "konq_settings.h" + +#include +#include +#include + +int KonqTextViewItem::compare( QListViewItem *item, int col, bool ascending ) const +{ + if (col==1) + return KonqBaseListViewItem::compare(item, 0, ascending); + return KonqBaseListViewItem::compare(item, col, ascending); +} + +/*QString KonqTextViewItem::key( int _column, bool asc) const +{ + if (_column==1) return key(0,asc); + QString tmp = QString::number( sortChar ); + //check if it is a time column + if (_column>1) + { + KonqTextViewWidget* lv = static_cast(listView()); + for (unsigned int i=0; iNumberOfAtoms; i++) + { + ColumnInfo *cInfo=&lv->columnConfigInfo()[i]; + if (_column==cInfo->displayInColumn) + { + if ((cInfo->udsId==KIO::UDS_MODIFICATION_TIME) + || (cInfo->udsId==KIO::UDS_ACCESS_TIME) + || (cInfo->udsId==KIO::UDS_CREATION_TIME)) + { + tmp += QString::number( m_fileitem->time(cInfo->udsId) ).rightJustify( 14, '0' ); + return tmp; + } + else if (cInfo->udsId==KIO::UDS_SIZE) + { + tmp += KIO::number( m_fileitem->size() ).rightJustify( 20, '0' ); + return tmp; + } + else break; + + }; + }; + }; + tmp+=text(_column); + return tmp; +}*/ + +void KonqTextViewItem::updateContents() +{ + QString tmp; + KIO::filesize_t size=m_fileitem->size(); + mode_t m=m_fileitem->mode(); + + // The order is: .dir (0), dir (1), .file (2), file (3) + sortChar = S_ISDIR( m_fileitem->mode() ) ? 1 : 3; + if ( m_fileitem->text()[0] == '.' ) + --sortChar; + + if (m_fileitem->isLink()) + { + if (S_ISDIR(m)) + { + type=KTVI_DIRLINK; + tmp="~"; + } + else if ((S_ISREG(m)) || (S_ISCHR(m)) || (S_ISBLK(m)) || (S_ISSOCK(m)) || (S_ISFIFO(m))) + { + tmp="@"; + type=KTVI_REGULARLINK; + } + else + { + tmp="!"; + type=KTVI_UNKNOWN; + size=0; + }; + } + else if (S_ISREG(m)) + { + if ((m_fileitem->permissions() & (S_IXUSR|S_IXGRP|S_IXOTH)) !=0 ) + { + tmp="*"; + type=KTVI_EXEC; + } + else + { + tmp=""; + type=KTVI_REGULAR; + }; + } + else if (S_ISDIR(m)) + { + type=KTVI_DIR; + tmp="/"; + } + else if (S_ISCHR(m)) + { + type=KTVI_CHARDEV; + tmp="-"; + } + else if (S_ISBLK(m)) + { + type=KTVI_BLOCKDEV; + tmp="+"; + } + else if (S_ISSOCK(m)) + { + type=KTVI_SOCKET; + tmp="="; + } + else if (S_ISFIFO(m)) + { + type=KTVI_FIFO; + tmp=">"; + } + else + { + tmp="!"; + type=KTVI_UNKNOWN; + size=0; + }; + setText(1,tmp); + setText(0,m_fileitem->text()); + //now we have the first two columns, so let's do the rest + KonqTextViewWidget* lv = static_cast(listView()); + + for (unsigned int i=0; iNumberOfAtoms; i++) + { + ColumnInfo *tmpColumn=&lv->confColumns[i]; + if (tmpColumn->displayThisOne) + { + switch (tmpColumn->udsId) + { + case KIO::UDS_USER: + setText(tmpColumn->displayInColumn,m_fileitem->user()); + break; + case KIO::UDS_GROUP: + setText(tmpColumn->displayInColumn,m_fileitem->group()); + break; + case KIO::UDS_LINK_DEST: + setText(tmpColumn->displayInColumn,m_fileitem->linkDest()); + break; + case KIO::UDS_FILE_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimeComment()); + break; + case KIO::UDS_MIME_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimetype()); + break; + case KIO::UDS_URL: + setText(tmpColumn->displayInColumn,m_fileitem->url().prettyURL()); + break; + case KIO::UDS_SIZE: + if ( static_cast(listView())->m_pSettings->fileSizeInBytes() ) + setText(tmpColumn->displayInColumn,KGlobal::locale()->formatNumber(size, 0)+" "); + else + setText(tmpColumn->displayInColumn,KIO::convertSize(size)+" "); + break; + case KIO::UDS_ACCESS: + setText(tmpColumn->displayInColumn,m_fileitem->permissionsString()); + break; + case KIO::UDS_MODIFICATION_TIME: + case KIO::UDS_ACCESS_TIME: + case KIO::UDS_CREATION_TIME: + for( KIO::UDSEntry::ConstIterator it = m_fileitem->entry().begin(); it != m_fileitem->entry().end(); it++ ) + { + if ((*it).m_uds==(unsigned int)tmpColumn->udsId) + { + QDateTime dt; + dt.setTime_t((time_t) (*it).m_long); + setText(tmpColumn->displayInColumn,KGlobal::locale()->formatDateTime(dt)); + break; + }; + + }; + break; + default: + break; + }; + }; + }; +} + +void KonqTextViewItem::paintCell( QPainter *_painter, const QColorGroup & _cg, int _column, int _width, int _alignment ) +{ + QColorGroup cg( _cg ); + cg.setColor(QColorGroup::Text, static_cast(listView())->colors[type]); + // Don't do that! Keep things readable whatever the selection background color is +// cg.setColor(QColorGroup::HighlightedText, static_cast(listView())->highlight[type]); +// cg.setColor(QColorGroup::Highlight, Qt::darkGray); + + KListViewItem::paintCell( _painter, cg, _column, _width, _alignment ); +} + +/*void KonqTextViewItem::paintFocus( QPainter *_p, const QColorGroup &_cg, const QRect &_r ) +{ + listView()->style().drawFocusRect( _p, _r, _cg, + isSelected() ? &_cg.highlight() : &_cg.base(), isSelected() ); + + QPixmap pix( _r.width(), _r.height() ); + bitBlt( &pix, 0, 0, _p->device(), _r.left(), _r.top(), _r.width(), _r.height() ); + QImage im = pix.convertToImage(); + im = KImageEffect::fade( im, 0.25, Qt::black ); + _p->drawImage( _r.topLeft(), im ); +}*/ + +void KonqTextViewItem::setup() +{ + widthChanged(); + int h(listView()->fontMetrics().height()); + if ( h % 2 > 0 ) h++; + setHeight(h); +} diff --git a/konqueror/listview/konq_textviewitem.h b/konqueror/listview/konq_textviewitem.h new file mode 100644 index 000000000..413016bea --- /dev/null +++ b/konqueror/listview/konq_textviewitem.h @@ -0,0 +1,75 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis + + 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. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef __konq_textviewitem_h__ +#define __konq_textviewitem_h__ + +#include +#include +#include +#include +#include "konq_listviewitems.h" +#include "konq_textviewwidget.h" + +class KFileItem; +class QPainter; + +#define KTVI_REGULAR 0 +#define KTVI_REGULARLINK 1 +#define KTVI_EXEC 2 +#define KTVI_DIR 3 +#define KTVI_DIRLINK 4 +#define KTVI_BADLINK 5 +#define KTVI_SOCKET 6 +#define KTVI_CHARDEV 7 +#define KTVI_BLOCKDEV 8 +#define KTVI_FIFO 9 +#define KTVI_UNKNOWN 10 + + +class KonqTextViewItem : public KonqBaseListViewItem +{ + public: + /** + * Create an item in the text toplevel representing a file + * @param _parent the parent widget, the text view + * @param _fileitem the file item created by KDirLister + */ + KonqTextViewItem( KonqTextViewWidget *_parent, KFileItem* _fileitem ); + virtual ~KonqTextViewItem() {/*cerr<<"~KonqTextViewItem: "< + + 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. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "konq_listview.h" +#include "konq_textviewitem.h" + +#include + +#include +#include + +#include +#include + + +KonqTextViewWidget::KonqTextViewWidget( KonqListView *parent, QWidget *parentWidget ) +:KonqBaseListViewWidget(parent,parentWidget) +{ + kdDebug(1202) << "+KonqTextViewWidget" << endl; + m_filenameColumn=1; + + // David: This breaks dropping things towards the current directory + // using the columns != Name. + // I know, but I want to have it this way and I use it all the time. + // If I want to have free space, I disable some columns. + // If people don't like it, they can use a different view type. Alex + setAllColumnsShowFocus(TRUE); + setRootIsDecorated(false); + + colors[KTVI_REGULAR]=Qt::black; + colors[KTVI_EXEC]=QColor(0,170,0); + colors[KTVI_REGULARLINK]=Qt::black; + colors[KTVI_DIR]=Qt::black; + colors[KTVI_DIRLINK]=Qt::black; + colors[KTVI_BADLINK]=Qt::red; + colors[KTVI_SOCKET]=Qt::magenta; + colors[KTVI_FIFO]=Qt::magenta; + colors[KTVI_UNKNOWN]=Qt::red; + colors[KTVI_CHARDEV]=Qt::blue; + colors[KTVI_BLOCKDEV]=Qt::blue; + + m_showIcons=FALSE; +} + +KonqTextViewWidget::~KonqTextViewWidget() +{} + +void KonqTextViewWidget::createColumns() +{ + if (columns()<2) + { + addColumn( i18n("Name"), m_filenameColumnWidth ); + addColumn( " ", fontMetrics().width("@") + 2 ); + setColumnAlignment( 1, AlignRight ); + //this way the column with the name has the index 0 and + //so the "jump to filename beginning with this character" works + header()->moveSection( 0, 2 ); + } + KonqBaseListViewWidget::createColumns(); +} + +void KonqTextViewWidget::slotNewItems( const KFileItemList & entries ) +{ + //kdDebug(1202) << k_funcinfo << entries.count() << endl; + + for ( QPtrListIterator kit ( entries ); kit.current(); ++kit ) + { + KonqTextViewItem *tmp = new KonqTextViewItem( this, *kit ); + if ( !m_itemFound && tmp->text(0) == m_itemToGoTo ) + { + setCurrentItem( tmp ); + m_itemFound = true; + } + if ( !m_itemsToSelect.isEmpty() ) { + QStringList::Iterator tsit = m_itemsToSelect.find( (*kit)->name() ); + if ( tsit != m_itemsToSelect.end() ) { + m_itemsToSelect.remove( tsit ); + setSelected( tmp, true ); + } + } + + } + + m_pBrowserView->newItems( entries ); + + if ( !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } + slotUpdateBackground(); +} + +void KonqTextViewWidget::setComplete() +{ + kdDebug(1202) << k_funcinfo << "Update Contents Pos: " + << m_bUpdateContentsPosAfterListing << endl; + + m_bTopLevelComplete = true; + + // Alex: this flag is set when we are just finishing a voluntary listing, + // so do the go-to-item thing only under here. When we update the + // current directory automatically (e.g. after a file has been deleted), + // we don't want to go to the first item ! (David) + if ( m_bUpdateContentsPosAfterListing ) + { + m_bUpdateContentsPosAfterListing = false; + + if ( !m_itemFound ) + setCurrentItem( firstChild() ); + + if ( !m_restored && !m_pBrowserView->extension()->urlArgs().reload ) + ensureItemVisible( currentItem() ); + else + setContentsPos( m_pBrowserView->extension()->urlArgs().xOffset, + m_pBrowserView->extension()->urlArgs().yOffset ); + + activateAutomaticSelection(); + emit selectionChanged(); + } + + m_itemToGoTo = ""; + m_restored = false; + + // Show "cut" icons as such + m_pBrowserView->slotClipboardDataChanged(); + // Show totals + slotOnViewport(); + + if ( !isUpdatesEnabled() || !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } +} + +bool KonqTextViewWidget::isExecuteArea( const QPoint& point ) +{ + if (!itemAt( point ) ) + return false; + int x=point.x(); + + int offset = 0; + int width = columnWidth( 0 ); + int pos = header()->mapToIndex( 0 ); + + for ( int index = 0; index < pos; index++ ) + offset += columnWidth( header()->mapToSection( index ) ); + + return ( x > offset && x < ( offset + width ) ); +} + +/*void KonqTextViewWidget::viewportDragMoveEvent( QDragMoveEvent *_ev ) +{ + KonqBaseListViewItem *item = + isNameColumn( _ev->pos() ) ? (KonqBaseListViewItem*)itemAt( _ev->pos() ) : 0L; + + if ( !item ) + { + if ( m_dragOverItem ) + setSelected( m_dragOverItem, false ); + _ev->accept(); + return; + } + + if ( m_dragOverItem == item ) + return; // No change + + if ( m_dragOverItem != 0L ) + setSelected( m_dragOverItem, false ); + + if ( item->item()->acceptsDrops() ) + { + _ev->accept(); + setSelected( item, true ); + m_dragOverItem = item; + } + else + { + _ev->ignore(); + m_dragOverItem = 0L; + } +} + +void KonqTextViewWidget::viewportDropEvent( QDropEvent *ev ) +{ + if ( m_dirLister->url().isEmpty() ) + return; + kdDebug() << "KonqTextViewWidget::viewportDropEvent" << endl; + if ( m_dragOverItem != 0L ) + setSelected( m_dragOverItem, false ); + m_dragOverItem = 0L; + + ev->accept(); + + // We dropped on an item only if we dropped on the Name column. + KonqBaseListViewItem *item = + isNameColumn( ev->pos() ) ? (KonqBaseListViewItem*)itemAt( ev->pos() ) : 0; + + KFileItem * destItem = (item) ? item->item() : m_dirLister->rootItem(); // may be 0 + KonqOperations::doDrop( destItem, destItem ? destItem->url() : url(), ev, this ); +}*/ + + +#include "konq_textviewwidget.moc" diff --git a/konqueror/listview/konq_textviewwidget.h b/konqueror/listview/konq_textviewwidget.h new file mode 100644 index 000000000..f799286ff --- /dev/null +++ b/konqueror/listview/konq_textviewwidget.h @@ -0,0 +1,54 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis + + 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. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef __konq_textviewwidget_h__ +#define __konq_textviewwidget_h__ + +#include "konq_listviewwidget.h" + +#include + +class KonqListView; +class KonqTextViewItem; + +/** + * The text view + */ +class KonqTextViewWidget : public KonqBaseListViewWidget +{ + friend class KonqTextViewItem; + Q_OBJECT + public: + KonqTextViewWidget( KonqListView *parent, QWidget *parentWidget ); + ~KonqTextViewWidget(); + virtual bool isExecuteArea( const QPoint& point ); + + protected slots: + // slots connected to the directory lister + virtual void setComplete(); + virtual void slotNewItems( const KFileItemList & ); + protected: +// bool isNameColumn(const QPoint& point ); +// virtual void viewportDragMoveEvent( QDragMoveEvent *_ev ); +// virtual void viewportDropEvent( QDropEvent *ev ); + virtual void createColumns(); + + QColor colors[11]; +}; + +#endif diff --git a/konqueror/listview/konq_treeview.desktop b/konqueror/listview/konq_treeview.desktop new file mode 100644 index 000000000..3fcce32db --- /dev/null +++ b/konqueror/listview/konq_treeview.desktop @@ -0,0 +1,90 @@ +[Desktop Entry] +Type=Service +Name=Tree View +Name[af]=Boom Besigtig +Name[ar]=عرض شجري +Name[az]=Ağaç Görünüşü +Name[be]=Дрэва +Name[bg]=Дървовиден преглед +Name[bn]=ট্রি ভিউ +Name[br]=Gwel gwezenn +Name[bs]=Pogled stabla +Name[ca]=Vista d'arbre +Name[cs]=Stromový pohled +Name[csb]=Wëzdrzatk drzéwiã +Name[cy]=Golwg Coeden +Name[da]=Trævisning +Name[de]=Baumansicht +Name[el]=Προβολή δέντρου +Name[eo]=Arba rigardo +Name[es]=Vista en árbol +Name[et]=Vaade puuna +Name[eu]=Zuhaitz erako ikuspegia +Name[fa]=درخت‌نما +Name[fi]=Puunäkymä +Name[fr]=Affichage en arborescence +Name[fy]=Beamstruktuerwerjefte +Name[ga]=Amharc Crainn +Name[gl]=Vista de Árbore +Name[he]=תצוגת עץ +Name[hi]=ट्री दृश्य +Name[hr]=Prikaz stabla +Name[hu]=Fastruktúra +Name[id]=Tampilan Pohon +Name[is]=Trjáasýn +Name[it]=Vista ad albero +Name[ja]=ツリービュー +Name[ka]=ხის სახით +Name[kk]=Бұтақ түрінде +Name[km]=ទិដ្ឋភាព​មែកធាង +Name[lo]=ມຸມມອງແບບລາຍການຕົ້ນໄມ້ +Name[lt]=Rodyti medį +Name[lv]=Koka Skatījums +Name[mk]=Преглед со стебло +Name[mn]=Модоор харах +Name[ms]=Paparan Pepohon +Name[mt]=Uri Friegħi +Name[nb]=Trevisning +Name[nds]=Boomansicht +Name[ne]=ट्रि दृश्य +Name[nl]=Boomstructuurweergave +Name[nn]=Trevising +Name[nso]=Pono ya Mohlare +Name[pa]=ਲੜੀ ਝਲਕ +Name[pl]=Widok drzewa +Name[pt]=Vista em Árvore +Name[pt_BR]=Visão em Árvore +Name[ro]=Vizualizare arborescentă +Name[ru]=В виде дерева +Name[rw]=Igaragaza Igiti +Name[se]=Muorračájeheapmi +Name[sk]=Stromová štruktúra +Name[sl]=Drevesni pogled +Name[sr]=Приказ стабла +Name[sr@Latn]=Prikaz stabla +Name[sv]=Trädvy +Name[ta]=மரக் காட்சி +Name[te]=ట్రీ వీక్షణం +Name[tg]=Ба намуди дарахт +Name[th]=มุมมองแบบรายการต้นไม้ +Name[tr]=Ağaç Görünümü +Name[tt]=Ağaçlı Küreneş +Name[uk]=Вигляд структури каталогів +Name[uz]=Daraxt koʻrinishida +Name[uz@cyrillic]=Дарахт кўринишида +Name[ven]=Mbonalelo ya Muri +Name[vi]=Xem kiểu Cây +Name[wa]=Vey come èn åbe +Name[xh]=Imboniselo Yomthi +Name[zh_CN]=树视图 +Name[zh_TW]=樹狀瀏覽 +Name[zu]=Umbukiso Wesihlahla +MimeType=inode/directory +ServiceTypes=KParts/ReadOnlyPart,Browser/View +X-KDE-Library=konq_listview +X-KDE-BrowserView-Args=MixedTree +X-KDE-BrowserView-HideFromMenus=true +X-KDE-BrowserView-HierarchicalView=true +X-KDE-BrowserView-Built-Into=konqueror +Icon=view_tree +InitialPreference=8 diff --git a/konqueror/listview/konq_treeview.rc b/konqueror/listview/konq_treeview.rc new file mode 100644 index 000000000..7f8981779 --- /dev/null +++ b/konqueror/listview/konq_treeview.rc @@ -0,0 +1,52 @@ + + + + &Edit + Selection + + + + + + + + + &View + Icon Size + + + + + + + + + + + + + + Show Details + + + + + + + + + + + + + + + + + +Treeview Toolbar + + + + + diff --git a/konqueror/listview/konq_treeviewitem.cc b/konqueror/listview/konq_treeviewitem.cc new file mode 100644 index 000000000..09b9d941b --- /dev/null +++ b/konqueror/listview/konq_treeviewitem.cc @@ -0,0 +1,96 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis + 2001, 2002, 2004 Michael Brade + + 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. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "konq_treeviewwidget.h" +#include "konq_listview.h" + + +KonqListViewDir::KonqListViewDir( KonqTreeViewWidget *_parent, KFileItem* _fileitem ) + : KonqListViewItem( _parent, _fileitem ) +{ + setExpandable( true ); + m_bComplete = false; +} + +KonqListViewDir::KonqListViewDir( KonqTreeViewWidget *_treeview, KonqListViewDir *_parent, KFileItem *_fileitem ) + : KonqListViewItem( _treeview, _parent, _fileitem ) +{ + setExpandable( true ); + m_bComplete = false; +} + +void KonqListViewDir::setOpen( bool _open ) +{ + open( _open, false ); +} + +void KonqListViewDir::open( bool _open, bool _reload ) +{ + if ( _open != isOpen() || _reload ) + { + KonqTreeViewWidget *treeView = static_cast(m_pListViewWidget); + + if ( _open ) + { + if ( !m_bComplete || _reload ) // complete it before opening + treeView->openSubFolder( this, _reload ); + else + { + // we need to add the items to the counts for the statusbar + KFileItemList lst; + lst.setAutoDelete( false ); + + QListViewItem* it = firstChild(); + while ( it ) + { + lst.append( static_cast(it)->item() ); + it = it->nextSibling(); + } + + // tell the view about the new items to count + treeView->m_pBrowserView->newItems( lst ); + } + } + else + { + treeView->stopListingSubFolder( this ); + + QListViewItem* it = firstChild(); + while ( it ) + { + // unselect the items in the closed folder + treeView->setSelected( it, false ); + // delete the item from the counts for the statusbar + KFileItem* item = static_cast(it)->item(); + treeView->m_pBrowserView->deleteItem( item ); + it = it->nextSibling(); + } + } + + QListViewItem::setOpen( _open ); + treeView->slotOnViewport(); + } +} + +QString KonqListViewDir::url( int _trailing ) +{ + return item()->url().url( _trailing ); +} + diff --git a/konqueror/listview/konq_treeviewitem.h b/konqueror/listview/konq_treeviewitem.h new file mode 100644 index 000000000..5341a811a --- /dev/null +++ b/konqueror/listview/konq_treeviewitem.h @@ -0,0 +1,79 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis + + 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. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef __konq_treeviewitem_h__ +#define __konq_treeviewitem_h__ + +#include +#include "konq_listviewitems.h" + +class KFileItem; +class KonqTreeViewWidget; + +/** + * An item specialized for directories + */ +class KonqListViewDir : public KonqListViewItem +{ +public: + /** + * Create an item in the tree toplevel representing a directory + * @param _parent the parent widget, the tree view + * @param _fileitem the file item created by KDirLister + */ + KonqListViewDir( KonqTreeViewWidget *_parent, KFileItem *_fileitem ); + + /** + * Create an item representing a directory, inside a directory + * @param _treeview the parent tree view + * @param _parent the parent widget, a directory item in the tree view + * @param _fileitem the file item created by KDirLister + */ + KonqListViewDir( KonqTreeViewWidget *_treeview, KonqListViewDir *_parent, KFileItem *_fileitem ); + + /** + * Called when user opens the directory (inherited from QListViewItem). + * Just calls @ref #open(). + */ + virtual void setOpen( bool _open ); + + /** + * Called by setOpen, called when opening the directoy via restoreState and called + * when the user presses "Reload". + * Checks whether its contents are known (@see #setComplete) or whether + * to reload the directory. + */ + void open( bool _open, bool _reload ); + + /** + * Set to true when contents are completely known (one sublevel only). + */ + virtual void setComplete( bool _b ) { m_bComplete = _b; } + + /** + * URL of this directory + * @param _trailing set to true for a trailing slash (see KURL) + */ + QString url( int _trailing ); + +protected: + bool m_bComplete; +}; + +#endif diff --git a/konqueror/listview/konq_treeviewwidget.cc b/konqueror/listview/konq_treeviewwidget.cc new file mode 100644 index 000000000..67844fa3d --- /dev/null +++ b/konqueror/listview/konq_treeviewwidget.cc @@ -0,0 +1,307 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis + 2001, 2002, 2004 Michael Brade + + 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. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "konq_listview.h" +#include "konq_treeviewwidget.h" + +#include +#include + +template class QDict; + + +KonqTreeViewWidget::KonqTreeViewWidget( KonqListView *parent, QWidget *parentWidget) + : KonqBaseListViewWidget( parent, parentWidget ) +{ + kdDebug(1202) << "+KonqTreeViewWidget" << endl; + + setRootIsDecorated( true ); + setTreeStepSize( 20 ); + + connect( m_dirLister, SIGNAL( completed( const KURL & ) ), + this, SLOT( slotCompleted( const KURL & ) ) ); + connect( m_dirLister, SIGNAL( clear( const KURL & ) ), + this, SLOT( slotClear( const KURL & ) ) ); + connect( m_dirLister, SIGNAL( redirection( const KURL &, const KURL & ) ), + this, SLOT( slotRedirection( const KURL &, const KURL & ) ) ); +} + +KonqTreeViewWidget::~KonqTreeViewWidget() +{ + kdDebug(1202) << "-KonqTreeViewWidget" << endl; + + // Remove all items + clear(); + // Clear dict + m_dictSubDirs.clear(); +} + +bool KonqTreeViewWidget::openURL( const KURL &url ) +{ + //kdDebug(1202) << k_funcinfo << url.prettyURL() << endl; + + if ( m_pBrowserView->extension()->urlArgs().reload ) + { + QDictIterator it( m_dictSubDirs ); + for (; it.current(); ++it ) + if ( it.current()->isOpen() ) + m_urlsToReload.append( it.current()->url( -1 ) ); + + // Someone could press reload while the listing is still in progess + // -> move the items that are not opened yet to m_urlsToReload. + // We don't need to check for doubled items since remove() removes + // all occurrences. + m_urlsToReload += m_urlsToOpen; + m_urlsToOpen.clear(); + } + + return KonqBaseListViewWidget::openURL( url ); +} + +void KonqTreeViewWidget::saveState( QDataStream &stream ) +{ + QStringList openDirList; + + QDictIterator it( m_dictSubDirs ); + for (; it.current(); ++it ) + { + if ( it.current()->isOpen() ) + openDirList.append( it.current()->url( -1 ) ); + } + + stream << openDirList; + KonqBaseListViewWidget::saveState( stream ); +} + +void KonqTreeViewWidget::restoreState( QDataStream &stream ) +{ + stream >> m_urlsToOpen; + KonqBaseListViewWidget::restoreState( stream ); +} + +void KonqTreeViewWidget::slotCompleted() +{ + // This is necessary because after reloading it could happen that a + // previously opened subdirectory was deleted and this would still + // be queued for opening. + m_urlsToReload.clear(); + m_urlsToOpen.clear(); + + KonqBaseListViewWidget::slotCompleted(); +} + +void KonqTreeViewWidget::slotCompleted( const KURL & _url ) +{ + // do nothing if the view itself is finished + if ( m_url.equals( _url, true ) ) + return; + + KonqListViewDir *dir = m_dictSubDirs[ _url.url(-1) ]; + if ( dir ) + dir->setComplete( true ); + else + kdWarning() << "KonqTreeViewWidget::slotCompleted : dir " << _url.url(-1) << " not found in dict!" << endl; + + if ( !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } +} + +void KonqTreeViewWidget::slotClear() +{ + kdDebug(1202) << k_funcinfo << endl; + + m_dictSubDirs.clear(); + KonqBaseListViewWidget::slotClear(); +} + +void KonqTreeViewWidget::slotClear( const KURL & _url ) +{ + // normally this means we have to delete only the contents of directory _url + // but we are allowed to delete the subdirs as well since the opening of + // subdirs happens level per level. If a subdir is deleted with delete, all + // its children will be deleted by Qt immediately! + + kdDebug(1202) << k_funcinfo << _url << endl; + + KonqListViewDir *item = m_dictSubDirs[_url.url(-1)]; + if ( item ) + { + // search all subdirs of _url (item) + QDictIterator it( m_dictSubDirs ); + while ( it.current() ) + { + if ( !_url.equals( it.currentKey(), true ) + && _url.isParentOf( it.currentKey() ) ) + { + m_urlsToOpen.remove( it.currentKey() ); + m_urlsToReload.remove( it.currentKey() ); + m_dictSubDirs.remove( it.currentKey() ); // do last, it changes it.currentKey()!! + } + else + ++it; + } + + // Remark: This code works only if we have exactly one tree which is the + // case for Konqy's treeview. It will break if m_dictSubDirs contains two + // subdirectories where only one of them will have its items deleted by + // the following code. + + // delete all child items, their fileitems are no longer valid + QListViewItem *child; + while ( (child = item->firstChild()) ) + delete child; + + // only if we really deleted something update the statusbar + reportItemCounts(); + } +} + +void KonqTreeViewWidget::slotRedirection( const KURL &oldUrl, const KURL &newUrl ) +{ + kdDebug(1202) << k_funcinfo << oldUrl.url() << " -> " << newUrl.url() << endl; + + KonqListViewDir *dir = m_dictSubDirs.take( oldUrl.url(-1) ); + Q_ASSERT( dir ); + m_dictSubDirs.insert( newUrl.url(-1), dir ); + // TODO: do we need to rename the fileitem in dir as well? +} + +void KonqTreeViewWidget::slotNewItems( const KFileItemList &entries ) +{ + if (!entries.count()) + return; + // Find parent item - it's the same for all the items + QPtrListIterator kit( entries ); + KURL dir( (*kit)->url().upURL() ); + + KonqListViewDir *parentDir = 0L; + if ( !m_url.equals( dir, true ) ) // ignore trailing slash + parentDir = m_dictSubDirs[ dir.url(-1) ]; + + if ( !parentDir ) // hack for zeroconf://domain/type/service listed in zeroconf:/type/ dir + { + dir.setHost( QString::null ); + parentDir = m_dictSubDirs[ dir.url(-1) ]; + } + + for ( ; kit.current(); ++kit ) + { + KonqListViewDir *dirItem = 0; + KonqListViewItem *fileItem = 0; + + if ( parentDir ) // adding under a directory item + { + if ( (*kit)->isDir() ) + { + dirItem = new KonqListViewDir( this, parentDir, *kit ); + m_dictSubDirs.insert( (*kit)->url().url(-1), dirItem ); + } + else + fileItem = new KonqListViewItem( this, parentDir, *kit ); + } + else // adding on the toplevel + { + if ( (*kit)->isDir() ) + { + dirItem = new KonqListViewDir( this, *kit ); + m_dictSubDirs.insert( (*kit)->url().url(-1), dirItem ); + } + else + fileItem = new KonqListViewItem( this, *kit ); + } + + if ( !m_itemFound ) + { + if ( fileItem && fileItem->text(0) == m_itemToGoTo ) + { + setCurrentItem( fileItem ); + m_itemFound = true; + } + else if ( dirItem && dirItem->text(0) == m_itemToGoTo ) + { + setCurrentItem( dirItem ); + m_itemFound = true; + } + } + + if ( !m_itemsToSelect.isEmpty() ) { + QStringList::Iterator tsit = m_itemsToSelect.find( (*kit)->name() ); + if ( tsit != m_itemsToSelect.end() ) { + m_itemsToSelect.remove( tsit ); + setSelected( fileItem ? fileItem : dirItem, true ); + } + } + + if ( fileItem && !(*kit)->isMimeTypeKnown() ) + m_pBrowserView->lstPendingMimeIconItems().append( fileItem ); + + if ( dirItem ) + { + QString u = (*kit)->url().url( 0 ); + if ( m_urlsToOpen.remove( u ) ) + dirItem->open( true, false ); + else if ( m_urlsToReload.remove( u ) ) + dirItem->open( true, true ); + } + } + + if ( !viewport()->isUpdatesEnabled() ) + { + viewport()->setUpdatesEnabled( true ); + setUpdatesEnabled( true ); + triggerUpdate(); + } + + // counts for the statusbar + m_pBrowserView->newItems( entries ); + slotUpdateBackground(); +} + +void KonqTreeViewWidget::slotDeleteItem( KFileItem *_fileItem ) +{ + QString url = _fileItem->url().url(-1); + + // Check if this item is in m_dictSubDirs, and if yes, then remove it + slotClear( _fileItem->url() ); + + m_dictSubDirs.remove( url ); + m_urlsToOpen.remove( url ); + m_urlsToReload.remove( url ); + + KonqBaseListViewWidget::slotDeleteItem( _fileItem ); +} + +void KonqTreeViewWidget::openSubFolder( KonqListViewDir* _dir, bool _reload ) +{ + m_dirLister->openURL( _dir->item()->url(), true /* keep existing data */, _reload ); + slotUpdateBackground(); +} + +void KonqTreeViewWidget::stopListingSubFolder( KonqListViewDir* _dir ) +{ + m_dirLister->stop( _dir->item()->url() ); + slotUpdateBackground(); +} + +#include "konq_treeviewwidget.moc" diff --git a/konqueror/listview/konq_treeviewwidget.h b/konqueror/listview/konq_treeviewwidget.h new file mode 100644 index 000000000..86119a8bf --- /dev/null +++ b/konqueror/listview/konq_treeviewwidget.h @@ -0,0 +1,67 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis + + 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. + + 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef __konq_treeviewwidget_h__ +#define __konq_treeviewwidget_h__ + +#include "konq_listviewwidget.h" +#include "konq_treeviewitem.h" +#include +#include +#include + +class KonqListView; + + +class KonqTreeViewWidget : public KonqBaseListViewWidget +{ + friend class KonqListViewDir; + + Q_OBJECT +public: + KonqTreeViewWidget( KonqListView *parent, QWidget *parentWidget ); + virtual ~KonqTreeViewWidget(); + + virtual bool openURL( const KURL &url ); + + virtual void saveState( QDataStream &stream ); + virtual void restoreState( QDataStream &stream ); + +protected slots: + // slots connected to the directory lister + virtual void slotCompleted(); + virtual void slotCompleted( const KURL & ); + virtual void slotClear(); + virtual void slotClear( const KURL & ); + virtual void slotRedirection( const KURL &, const KURL & ); + virtual void slotNewItems( const KFileItemList & ); + virtual void slotDeleteItem( KFileItem *_fileTtem ); + +protected: + KonqListViewDir *findDir( const QString &_url ); + + void openSubFolder( KonqListViewDir *_dir, bool _reload ); + void stopListingSubFolder( KonqListViewDir *_dir ); + + // URL -> item (for directories only) + QDict m_dictSubDirs; + + QStringList m_urlsToOpen, m_urlsToReload; +}; + +#endif -- cgit v1.2.3