diff options
Diffstat (limited to 'konqueror/listview')
30 files changed, 6020 insertions, 0 deletions
diff --git a/konqueror/listview/CMakeLists.txt b/konqueror/listview/CMakeLists.txt new file mode 100644 index 000000000..02ab59564 --- /dev/null +++ b/konqueror/listview/CMakeLists.txt @@ -0,0 +1,55 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/libkonq + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TDE_LIBRARY_DIRS} + ${TQT_LIBRARY_DIRS} +) + + +##### other data ################################ + +install( FILES + konq_treeview.desktop konq_detailedlistview.desktop + konq_textview.desktop konq_infolistview.desktop + DESTINATION ${SERVICES_INSTALL_DIR} ) + +install( FILES + konq_treeview.rc konq_detailedlistview.rc + konq_textview.rc konq_infolistview.rc + DESTINATION ${DATA_INSTALL_DIR}/konqlistview ) + +install( FILES konq_listview.kcfg DESTINATION ${KCFG_INSTALL_DIR} ) + + +##### konq_listview (module) #################### + +set( target konq_listview ) + +set( ${target}_SRCS + 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 +) + +tde_add_kpart( ${target} AUTOMOC + SOURCES ${${target}_SRCS} + LINK konq-shared + DESTINATION ${PLUGIN_INSTALL_DIR} +) 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..2e16d061f --- /dev/null +++ b/konqueror/listview/konq_detailedlistview.desktop @@ -0,0 +1,88 @@ +[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 +X-TDE-ServiceTypes=KParts/ReadOnlyPart,Browser/View +X-TDE-Library=konq_listview +X-TDE-BrowserView-Args=DetailedList +X-TDE-BrowserView-HideFromMenus=true +Icon=view_detailed +X-TDE-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 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="KonqDetailedListView" version="11"> +<MenuBar> + <Menu name="edit"><text>&Edit</text> + <Menu name="selection"><text>Selection</text> + <Action name="select"/> + <Action name="unselect"/> + <Separator/> + <Action name="selectall"/> + <Action name="unselectall"/> + <Action name="invertselection"/> + </Menu> + </Menu> + <Menu name="view"><text>&View</text> + <Menu name="iconview_mode"><text>Icon Size</text> + <Action name="modedefault"/> + <Separator/> + <Action name="modeenormous"/> + <Action name="modehuge"/> + <Action name="modelarge"/> + <Action name="modemedium"/> + <Action name="modesmallmedium"/> + <Action name="modesmall"/> + </Menu> + <Separator/> + <Action name="show_dot"/> + <Action name="sort_caseinsensitive"/> + <!--<Action name="sort_directoriesfirst" /> TODO --> + <Menu name="listview_show"><text>Show Details</text> + <TearOffHandle /> + <Action name="show_size"/> + <Action name="show_type"/> + <Action name="show_mimetype"/> + <Action name="show_url"/> + <Action name="show_time"/> + <Action name="show_access_time"/> + <Action name="show_creation_time"/> + <Action name="show_permissions"/> + <Action name="show_owner"/> + <Action name="show_group"/> + <Action name="show_link_dest"/> + </Menu> + <Separator/> + <Action name="bgsettings"/> + </Menu> +</MenuBar> +<ToolBar name="mainToolBar"><text>Detailed Listview Toolbar</text> + <Separator/> + <Action name="incIconSize" /> + <Action name="decIconSize" /> +</ToolBar> +</kpartgui> diff --git a/konqueror/listview/konq_infolistview.desktop b/konqueror/listview/konq_infolistview.desktop new file mode 100644 index 000000000..b076af7db --- /dev/null +++ b/konqueror/listview/konq_infolistview.desktop @@ -0,0 +1,86 @@ +[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 +X-TDE-ServiceTypes=KParts/ReadOnlyPart,Browser/View +X-TDE-Library=konq_listview +X-TDE-BrowserView-Args=InfoListView +X-TDE-BrowserView-HideFromMenus=true +Icon=view_detailed +X-TDE-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 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="KonqInfoListView" version="12"> +<MenuBar> + <Menu name="edit"><text>&Edit</text> + <Menu name="selection"><text>Selection</text> + <Action name="select"/> + <Action name="unselect"/> + <Separator/> + <Action name="selectall"/> + <Action name="unselectall"/> + <Action name="invertselection"/> + </Menu> + </Menu> + <Menu name="view"><text>&View</text> + <Menu name="iconview_mode"><text>Icon Size</text> + <Action name="modedefault"/> + <Separator/> + <Action name="modeenormous"/> + <Action name="modehuge"/> + <Action name="modelarge"/> + <Action name="modemedium"/> + <Action name="modesmallmedium"/> + <Action name="modesmall"/> + </Menu> + <Separator/> + <Action name="show_dot"/> + <Action name="sort_caseinsensitive"/> + <!--<Action name="sort_directoriesfirst" /> TODO --> + <Action name="view_as"/> + <Separator/> + <Action name="bgsettings"/> + </Menu> +</MenuBar> +<ToolBar name="mainToolBar"><text>Info Listview Toolbar</text> + <Separator/> + <Action name="incIconSize" /> + <Action name="decIconSize" /> +</ToolBar> +</kpartgui> diff --git a/konqueror/listview/konq_infolistviewitem.cc b/konqueror/listview/konq_infolistviewitem.cc new file mode 100644 index 000000000..18efb3f8f --- /dev/null +++ b/konqueror/listview/konq_infolistviewitem.cc @@ -0,0 +1,280 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Rolf Magnus <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation 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 <konq_settings.h> +#include <tdefilemetainfo.h> +#include <kdebug.h> +#include <tdelocale.h> +#include <assert.h> +#include <stdio.h> +#include <tqpainter.h> +#include <tqheader.h> +#include <kiconloader.h> +#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<KonqBaseListViewWidget::NumberOfAtoms; i++) + { + ColumnInfo *tmpColumn=&static_cast<KonqBaseListViewWidget *>(listView())->columnConfigInfo()[i]; + if (tmpColumn->displayThisOne) + { + switch (tmpColumn->udsId) + { + case TDEIO::UDS_USER: + setText(tmpColumn->displayInColumn,m_fileitem->user()); + break; + case TDEIO::UDS_GROUP: + setText(tmpColumn->displayInColumn,m_fileitem->group()); + break; + case TDEIO::UDS_FILE_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimeComment()); + break; + case TDEIO::UDS_MIME_TYPE: + setText(tmpColumn->displayInColumn,m_fileitem->mimetype()); + break; + case TDEIO::UDS_URL: + setText(tmpColumn->displayInColumn,m_fileitem->url().prettyURL()); + break; + case TDEIO::UDS_LINK_DEST: + setText(tmpColumn->displayInColumn,m_fileitem->linkDest()); + break; + case TDEIO::UDS_SIZE: + if ( static_cast<KonqBaseListViewWidget *>(listView())->m_pSettings->fileSizeInBytes() ) + setText(tmpColumn->displayInColumn,TDEGlobal::locale()->formatNumber( m_fileitem->size(),0)+" "); + else + setText(tmpColumn->displayInColumn,TDEIO::convertSize(m_fileitem->size())+" "); + break; + case TDEIO::UDS_ACCESS: + setText(tmpColumn->displayInColumn,m_fileitem->permissionsString()); + break; + case TDEIO::UDS_MODIFICATION_TIME: + case TDEIO::UDS_ACCESS_TIME: + case TDEIO::UDS_CREATION_TIME: + { + TQDateTime dt; + time_t _time = m_fileitem->time( tmpColumn->udsId ); + if ( _time != 0 ) + { + dt.setTime_t( _time ); + setText(tmpColumn->displayInColumn,TDEGlobal::locale()->formatDateTime(dt)); + } + } + break; + default: + break; + }; + }; + }; +#endif +} + +void KonqInfoListViewItem::gotMetaInfo() +{ + KFileMetaInfo info = item()->metaInfo(false); + + if (!info.isValid()) return; + + TQStringList::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; + + TQString s = kfmii.string().simplifyWhiteSpace(); + setText(i, s.isNull() ? TQString("") : s); + } +} + +int KonqInfoListViewItem::compare( TQListViewItem *item, int col, bool ascending ) const +{ + if ( col == 0 ) + return KonqBaseListViewItem::compare( item, 0, ascending ); + + KonqInfoListViewItem *i = static_cast<KonqInfoListViewItem *>(item); + + int size1 = m_columnValues.size(); + int size2 = i->m_columnValues.size(); + + if ( size1 < col || size2 < col ) + return ascending ? ( size2 - size1 ) : ( size1 - size2 ); + + TQVariant value1 = m_columnValues[ col-1 ]; + TQVariant value2 = i->m_columnValues[ col-1 ]; + TQVariant::Type type1 = m_columnTypes[ col-1 ]; + TQVariant::Type type2 = i->m_columnTypes[ col-1 ]; + + if ( type1 != type2 ) + return ascending ? ( type1 - type2 ) : ( type2 - type1 ); + +#define KONQ_CASE( x ) \ + case TQVariant::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 TQVariant::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 + + TQString text1 = text(col); + TQString 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<KonqBaseListViewWidget *>(listView())->iconSize(); + iconSize = iconSize ? iconSize : TDEGlobal::iconLoader()->currentSize( TDEIcon::Small ); // Default = small + setPixmap( 0, m_fileitem->pixmap( iconSize, state() ) ); +} + +void KonqInfoListViewItem::paintCell( TQPainter *_painter, const TQColorGroup & _cg, int _column, int _width, int _alignment ) +{ + TQColorGroup cg( _cg ); + + if ( _column == 0 ) + { + _painter->setFont( m_pListViewWidget->itemFont() ); + } + + cg.setColor( TQColorGroup::Text, m_pListViewWidget->itemColor() ); + + TDEListView *lv = static_cast< TDEListView* >( listView() ); + const TQPixmap *pm = TQT_TQPIXMAP_CONST(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( TQColorGroup::Base, TQBrush( backgroundColor(_column), *pm ) ); + TQPoint o = _painter->brushOrigin(); + _painter->setBrushOrigin( o.x() - lv->contentsX(), o.y() - lv->contentsY() ); + const TQColorGroup::ColorRole crole = + TQPalette::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; + } + + TDEListViewItem::paintCell( _painter, cg, _column, _width, _alignment ); +} + +void KonqInfoListViewItem::paintFocus( TQPainter * _painter, const TQColorGroup & cg, const TQRect & _r ) +{ + TQRect r( _r ); + TQListView *lv = static_cast< TQListView * >( listView() ); + r.setWidth( width( lv->fontMetrics(), lv, 0 ) ); + if ( r.right() > lv->header()->sectionRect( 0 ).right() ) + r.setRight( lv->header()->sectionRect( 0 ).right() ); + TQListViewItem::paintFocus( _painter, cg, r ); +} + +void KonqInfoListViewItem::mimetypeFound() +{ +#if 0 + // Update icon + setDisabled( m_bDisabled ); + uint done = 0; + KonqBaseListViewWidget * lv = m_pListViewWidget; + for (unsigned int i=0; i<m_pListViewWidget->NumberOfAtoms && done < 2; i++) + { + ColumnInfo *tmpColumn=&lv->columnConfigInfo()[i]; + if (lv->columnConfigInfo()[i].udsId==TDEIO::UDS_FILE_TYPE && tmpColumn->displayThisOne) + { + setText(tmpColumn->displayInColumn, m_fileitem->mimeComment()); + done++; + } + if (lv->columnConfigInfo()[i].udsId==TDEIO::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..f4ee2d32a --- /dev/null +++ b/konqueror/listview/konq_infolistviewitem.h @@ -0,0 +1,80 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Rolf Magnus <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation 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 <tqstring.h> +#include <kicontheme.h> + +// for mode_t +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +class TQPainter; +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( TQPainter *_painter, const TQColorGroup & cg, + int column, int width, int alignment ); + virtual void paintFocus( TQPainter * _painter, const TQColorGroup & cg, const TQRect & r ); + virtual void mimetypeFound(); + virtual void updateContents(); + virtual void setDisabled( bool disabled ); + + virtual void gotMetaInfo(); + + virtual int compare(TQListViewItem *item, int col, bool ascending) const; + + protected: + /** + * Parent tree view - the info list view widget + */ + KonqInfoListViewWidget* m_ILVWidget; + + private: + TQValueVector<TQVariant::Type> m_columnTypes; + TQValueVector<TQVariant> m_columnValues; +}; + +#endif diff --git a/konqueror/listview/konq_infolistviewwidget.cc b/konqueror/listview/konq_infolistviewwidget.cc new file mode 100644 index 000000000..e835f1cb3 --- /dev/null +++ b/konqueror/listview/konq_infolistviewwidget.cc @@ -0,0 +1,384 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Rolf Magnus <[email protected]> + Copyright (C) 2003 Waldo Bastian <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation 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 <tdelocale.h> +#include <tdefilemetainfo.h> +#include <kdebug.h> +#include <tdeaction.h> +#include <kservicetype.h> +#include <kuserprofile.h> +#include <tdeio/metainfojob.h> + +#include <tqstringlist.h> + +KonqInfoListViewWidget::KonqInfoListViewWidget( KonqListView* parent, + TQWidget* parentWidget) + : KonqBaseListViewWidget(parent, parentWidget) +{ + m_metaInfoJob = 0; + + m_mtSelector = new TDESelectAction(i18n("View &As"), 0, TQT_TQOBJECT(this), + TQT_SLOT(slotSelectMimeType()), + parent->actionCollection(), "view_as" ); + + kdDebug(1203) << "created info list view\n"; +} + +KonqInfoListViewWidget::~KonqInfoListViewWidget() +{ + delete m_mtSelector; + delete m_metaInfoJob; +} + +void KonqInfoListViewWidget::slotSelectMimeType() +{ + TQString comment = m_mtSelector->currentText(); + + // find the mime type by comment + TQMapIterator<TQString, KonqILVMimeType> 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()))) + { + TQStringList 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 + TQStringList groups = mimeTypeInfo->preferredGroups(); + if (groups.isEmpty()) groups = mimeTypeInfo->supportedGroups(); + + TQStringList::Iterator prefKey = preferredCols.begin(); + for (; prefKey != preferredCols.end(); ++prefKey) + { + TQStringList::Iterator group = groups.begin(); + for (; group != groups.end(); ++group) + { + const KFileMimeTypeInfo::GroupInfo* groupInfo = + mimeTypeInfo->groupInfo(*group); + if(groupInfo) + { + TQStringList keys = groupInfo->supportedKeys(); + TQStringList::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; + + TQListViewItemIterator it(this); + for (; it.current(); ++it) + { + list.append(static_cast<KonqInfoListViewItem*>(it.current())->item()); + } + + // now we can remove all the listview items + clear(); + + // and rebuild them + for (TQPtrListIterator<KFileItem> 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 (TQPtrListIterator<KFileItem> 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() ) { + TQStringList::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 (TQPtrListIterator<KFileItem> kit ( list ); kit.current(); ++kit ) + m_metaInfoTodo.append(kit.current()); + } + else + { + m_metaInfoJob = TDEIO::fileMetaInfo(list); + connect( m_metaInfoJob, TQT_SIGNAL( gotMetaInfo( const KFileItem*)), + this, TQT_SLOT( slotMetaInfo( const KFileItem*))); + connect( m_metaInfoJob, TQT_SIGNAL( result( TDEIO::Job*)), + this, TQT_SLOT( slotMetaInfoResult())); + } +} + +void KonqInfoListViewWidget::slotRefreshItems( const KFileItemList& list) +{ + kdDebug(1203) << " ------------------------ startin metainfo job ------\n"; + + // start getting metainfo from the files + if (m_metaInfoJob) + { + for (TQPtrListIterator<KFileItem> kit ( list ); kit.current(); ++kit ) + m_metaInfoTodo.append(kit.current()); + } + else + { + m_metaInfoJob = TDEIO::fileMetaInfo(list); + connect( m_metaInfoJob, TQT_SIGNAL( gotMetaInfo( const KFileItem*)), + this, TQT_SLOT( slotMetaInfo( const KFileItem*))); + connect( m_metaInfoJob, TQT_SIGNAL( result( TDEIO::Job*)), + this, TQT_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?) + TQListViewItemIterator it(this); + for (; it.current(); ++it) + { + if (static_cast<KonqInfoListViewItem*>(it.current())->item()==item) + { + static_cast<KonqInfoListViewItem*>(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 = TDEIO::fileMetaInfo(m_metaInfoTodo); + connect( m_metaInfoJob, TQT_SIGNAL( gotMetaInfo( const KFileItem*)), + this, TQT_SLOT( slotMetaInfo( const KFileItem*))); + connect( m_metaInfoJob, TQT_SIGNAL( result( TDEIO::Job*)), + this, TQT_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) + { + TQString 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(); + + TQStringList mtlist; + + TQMapIterator<TQString, KonqILVMimeType> 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 tdeioslave + (*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); +// TQPopupMenu* menu = m_mtSelector->popupMenu(); + + // insert the icons +// for (int i=0; i<menu->count(); ++i) +// { +// menu->changeItem(i, TQIconSet(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..258a20090 --- /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 <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation 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 <kurl.h> +#include <tqmap.h> +#include <tqpair.h> + +namespace TDEIO {class MetaInfoJob;} +class KonqListView; +class TDESelectAction; + +/** + * The info list view + */ +class KonqInfoListViewWidget : public KonqBaseListViewWidget +{ +// friend class KonqTextViewItem; + Q_OBJECT + public: + KonqInfoListViewWidget( KonqListView *parent, TQWidget *parentWidget ); + ~KonqInfoListViewWidget(); + + const TQStringList 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 + TQMap<TQString, KonqILVMimeType > m_counts; + TQStringList m_columnKeys; + + KonqILVMimeType m_favorite; + + TDESelectAction* m_mtSelector; + TDEIO::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..8c9369a4c --- /dev/null +++ b/konqueror/listview/konq_listview.cc @@ -0,0 +1,719 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 <tdeaction.h> +#include <tdeapplication.h> +#include <kdebug.h> +#include <kdirlister.h> +#include <kinputdialog.h> +#include <tdelocale.h> +#include <konq_drag.h> +#include <kpropertiesdialog.h> +#include <kstdaction.h> +#include <kprotocolinfo.h> +#include <klineedit.h> +#include <kmimetype.h> + +#include <tqapplication.h> +#include <tqclipboard.h> +#include <tqheader.h> +#include <tqregexp.h> + +#include <assert.h> +#include <string.h> +#include <sys/stat.h> +#include <time.h> +#include <unistd.h> +#include <kinstance.h> + +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( TQWidget *parentWidget, const char *, TQObject *parent, const char *name, const char*, const TQStringList &args ) +{ + if( args.count() < 1 ) + kdWarning() << "KonqListView: Missing Parameter" << endl; + + KParts::Part *obj = new KonqListView( parentWidget, parent, name, args.first() ); + return obj; +} + +TDEInstance *KonqListViewFactory::instance() +{ + if ( !s_instance ) + s_instance = new TDEInstance( "konqlistview" ); + return s_instance; +} + +KonqPropsView *KonqListViewFactory::defaultViewProps() +{ + if ( !s_defaultViewProps ) + s_defaultViewProps = new KonqPropsView( instance(),0L ); + //s_defaultViewProps = KonqPropsView::defaultProps( instance() ); + + return s_defaultViewProps; +} + +TDEInstance *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) == TDEGlobalSettings::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 ); + TQApplication::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() +{ + TQListViewItem* item = m_listView->listViewWidget()->currentItem(); + Q_ASSERT ( item ); + + // Update shurtcuts for the 'rename and move' actions. Must be done every time since the + // shortcuts may have been changed by the user in the meanwhile + const TDEShortcut moveNextSC=m_listView->m_paRenameMoveNext->shortcut(); + const TDEShortcut movePrevSC=m_listView->m_paRenameMovePrev->shortcut(); + m_listView->listViewWidget()->setRenameSettings(TDEListViewRenameSettings( + !(moveNextSC.isNull() && movePrevSC.isNull()), moveNextSC, movePrevSC)); + + m_listView->listViewWidget()->rename( item, 0 ); + + // Enhanced rename: Don't highlight the file extension. + KLineEdit* le = m_listView->listViewWidget()->renameLineEdit(); + if ( le ) { + const TQString txt = le->text(); + TQString 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 TQString &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( TQWidget *parentWidget, TQObject *parent, const char *name, const TQString& 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 ) ); + + TQString 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<KonqBaseListViewItem,KonqListView>(this); + + setXMLFile( xmlFile ); + + setupActions(); + + m_pListView->confColumns.resize( 11 ); + m_pListView->confColumns[0].setData(I18N_NOOP("MimeType"),"Type",TDEIO::UDS_MIME_TYPE,m_paShowMimeType); + m_pListView->confColumns[1].setData(I18N_NOOP("Size"),"Size",TDEIO::UDS_SIZE,m_paShowSize); + m_pListView->confColumns[2].setData(I18N_NOOP("Modified"),"Date",TDEIO::UDS_MODIFICATION_TIME,m_paShowTime); + m_pListView->confColumns[3].setData(I18N_NOOP("Accessed"),"AccessDate",TDEIO::UDS_ACCESS_TIME,m_paShowAccessTime); + m_pListView->confColumns[4].setData(I18N_NOOP("Created"),"CreationDate",TDEIO::UDS_CREATION_TIME,m_paShowCreateTime); + m_pListView->confColumns[5].setData(I18N_NOOP("Permissions"),"Access",TDEIO::UDS_ACCESS,m_paShowPermissions); + m_pListView->confColumns[6].setData(I18N_NOOP("Owner"),"Owner",TDEIO::UDS_USER,m_paShowOwner); + m_pListView->confColumns[7].setData(I18N_NOOP("Group"),"Group",TDEIO::UDS_GROUP,m_paShowGroup); + m_pListView->confColumns[8].setData(I18N_NOOP("Link"),"Link",TDEIO::UDS_LINK_DEST,m_paShowLinkDest); + m_pListView->confColumns[9].setData(I18N_NOOP("URL"),"URL",TDEIO::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",TDEIO::UDS_FILE_TYPE,m_paShowType); + + + connect( m_pListView, TQT_SIGNAL( selectionChanged() ), + m_extension, TQT_SLOT( updateActions() ) ); + connect( m_pListView, TQT_SIGNAL( selectionChanged() ), + this, TQT_SLOT( slotSelectionChanged() ) ); + + connect( m_pListView, TQT_SIGNAL( currentChanged(TQListViewItem*) ), + m_extension, TQT_SLOT( updateActions() ) ); + connect(m_pListView->header(),TQT_SIGNAL(indexChange(int,int,int)),this,TQT_SLOT(headerDragged(int,int,int))); + connect(m_pListView->header(),TQT_SIGNAL(clicked(int)),this,TQT_SLOT(slotHeaderClicked(int))); + connect(m_pListView->header(),TQT_SIGNAL(sizeChange(int,int,int)),TQT_SLOT(slotHeaderSizeChanged())); + + // signals from konqdirpart (for BC reasons) + connect( this, TQT_SIGNAL( findOpened( KonqDirPart * ) ), TQT_SLOT( slotKFindOpened() ) ); + connect( this, TQT_SIGNAL( findClosed( KonqDirPart * ) ), TQT_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 TQString 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(); + + //TQPixmap newIcon = item->item()->pixmap( m_parent->iconSize(), + // item->state() ); + //if ( oldSerial != newIcon.serialNumber() ) + // item->setPixmap( 0, newIcon ); + + if (item->item()->isMimeTypeKnown()) { + item->mimetypeFound(); + } + + // We also have columns to update, not only the icon + item->updateContents(); +} + +void KonqListView::saveState( TQDataStream &stream ) +{ + //kdDebug(1202) << k_funcinfo << endl; + KonqDirPart::saveState( stream ); + m_pListView->saveState( stream ); +} + +void KonqListView::restoreState( TQDataStream &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; + TQString pattern = KInputDialog::getText( TQString::null, + i18n( "Select files:" ), "*", &ok, m_pListView ); + if ( !ok ) + return; + + TQRegExp 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; + TQString pattern = KInputDialog::getText( TQString::null, + i18n( "Unselect files:" ), "*", &ok, m_pListView ); + if ( !ok ) + return; + + TQRegExp 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; i<m_pListView->NumberOfAtoms; 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; j<m_pListView->NumberOfAtoms; 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; j<m_pListView->NumberOfAtoms; 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 + TQStringList lstColumns; + int currentColumn(m_pListView->m_filenameColumn+1); + for (int i=0; i<(int)m_pListView->NumberOfAtoms; i++) + { + kdDebug(1202)<<"checking: -"<<m_pListView->confColumns[i].name<<"-"<<endl; + if ((m_pListView->confColumns[i].displayThisOne) && (currentColumn==m_pListView->confColumns[i].displayInColumn)) + { + lstColumns.append(m_pListView->confColumns[i].name); + kdDebug(1202)<<" adding"<<endl; + currentColumn++; + i=-1; + } + } + KonqListViewSettings config( m_pListView->url().protocol() ); + config.readConfig(); + config.setColumns( lstColumns ); + config.writeConfig(); + + // Update column sizes + slotHeaderSizeChanged(); +} + +void KonqListView::slotHeaderClicked(int sec) +{ + kdDebug(1202)<<"section: "<<sec<<" clicked"<<endl; + int clickedColumn(-1); + for (uint i=0; i<m_pListView->NumberOfAtoms; i++) + if (m_pListView->confColumns[i].displayInColumn==sec) clickedColumn=i; + kdDebug(1202)<<"atom index "<<clickedColumn<<endl; + TQString nameOfSortColumn; + //we clicked the file name column + if (clickedColumn==-1) + nameOfSortColumn="FileName"; + else + nameOfSortColumn=m_pListView->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: "<<sec<<" fromIndex: "<<from<<" toIndex "<<to<<endl; + //at this point the columns aren't moved yet, so I let the listview + //rearrange the stuff and use a single shot timer + TQTimer::singleShot(200,this,TQT_SLOT(slotSaveAfterHeaderDrag())); +} + +const KFileItem * KonqListView::currentItem() +{ + if (m_pListView==0 || m_pListView->currentItem()==0) + return 0L; + return static_cast<KonqListViewItem *>(m_pListView->currentItem())->item(); +} + +void KonqListView::slotSaveAfterHeaderDrag() +{ + TQStringList 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() +{ + TQValueList<int> 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 TQTimer( this ); + connect( m_headerTimer, TQT_SIGNAL( timeout() ), this, TQT_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 TDEToggleAction(i18n("Show &Modification Time"), 0,this, TQT_SLOT(slotColumnToggled()), actionCollection(), "show_time" ); + m_paShowTime->setCheckedState(i18n("Hide &Modification Time")); + m_paShowType=new TDEToggleAction(i18n("Show &File Type"), 0, this, TQT_SLOT(slotColumnToggled()),actionCollection(), "show_type" ); + m_paShowType->setCheckedState(i18n("Hide &File Type")); + m_paShowMimeType=new TDEToggleAction(i18n("Show MimeType"), 0, this, TQT_SLOT(slotColumnToggled()),actionCollection(), "show_mimetype" ); + m_paShowMimeType->setCheckedState(i18n("Hide MimeType")); + m_paShowAccessTime=new TDEToggleAction(i18n("Show &Access Time"), 0, this, TQT_SLOT(slotColumnToggled()),actionCollection(), "show_access_time" ); + m_paShowAccessTime->setCheckedState(i18n("Hide &Access Time")); + m_paShowCreateTime=new TDEToggleAction(i18n("Show &Creation Time"), 0, this, TQT_SLOT(slotColumnToggled()),actionCollection(), "show_creation_time" ); + m_paShowCreateTime->setCheckedState(i18n("Hide &Creation Time")); + m_paShowLinkDest=new TDEToggleAction(i18n("Show &Link Destination"), 0, this, TQT_SLOT(slotColumnToggled()),actionCollection(), "show_link_dest" ); + m_paShowLinkDest->setCheckedState(i18n("Hide &Link Destination")); + m_paShowSize=new TDEToggleAction(i18n("Show Filesize"), 0, this, TQT_SLOT(slotColumnToggled()),actionCollection(), "show_size" ); + m_paShowSize->setCheckedState(i18n("Hide Filesize")); + m_paShowOwner=new TDEToggleAction(i18n("Show Owner"), 0, this, TQT_SLOT(slotColumnToggled()),actionCollection(), "show_owner" ); + m_paShowOwner->setCheckedState(i18n("Hide Owner")); + m_paShowGroup=new TDEToggleAction(i18n("Show Group"), 0, this, TQT_SLOT(slotColumnToggled()),actionCollection(), "show_group" ); + m_paShowGroup->setCheckedState(i18n("Hide Group")); + m_paShowPermissions=new TDEToggleAction(i18n("Show Permissions"), 0, this, TQT_SLOT(slotColumnToggled()),actionCollection(), "show_permissions" ); + m_paShowPermissions->setCheckedState(i18n("Hide Permissions")); + m_paShowURL=new TDEToggleAction(i18n("Show URL"), 0, this, TQT_SLOT(slotColumnToggled()),actionCollection(), "show_url" ); + + m_paSelect = new TDEAction( i18n( "Se&lect..." ), CTRL+Key_Plus, this, TQT_SLOT( slotSelect() ), actionCollection(), "select" ); + m_paUnselect = new TDEAction( i18n( "Unselect..." ), CTRL+Key_Minus, this, TQT_SLOT( slotUnselect() ), actionCollection(), "unselect" ); + m_paSelectAll = KStdAction::selectAll( this, TQT_SLOT( slotSelectAll() ), actionCollection(), "selectall" ); + m_paUnselectAll = new TDEAction( i18n( "Unselect All" ), CTRL+Key_U, this, TQT_SLOT( slotUnselectAll() ), actionCollection(), "unselectall" ); + m_paInvertSelection = new TDEAction( i18n( "&Invert Selection" ), CTRL+Key_Asterisk, this, TQT_SLOT( slotInvertSelection() ), actionCollection(), "invertselection" ); + + // These 2 actions are 'fake' actions. They are defined so that the keyboard shortcuts + // can be set from the 'Configure Shortcuts..." dialog. + // The real actions are performed in the TDEListViewLineEdit::keyPressEvent() in tdeui + m_paRenameMoveNext = new TDEAction(i18n( "&Rename and move to next item" ), Key_Tab, + NULL, NULL, actionCollection(), "renameMoveNext" ); + m_paRenameMoveNext->setWhatsThis(i18n("Pressing this button completes the current rename operation," + "moves to the next item and starts a new rename operation.")); + m_paRenameMoveNext->setToolTip( i18n("Complete rename operation and move the next item")); + m_paRenameMoveNext->setEnabled(false); + m_paRenameMovePrev = new TDEAction( i18n( "&Rename and move to previous item" ), SHIFT+Key_BackTab, + NULL, NULL, actionCollection(), "renameMovePrev" ); + m_paRenameMovePrev->setWhatsThis(i18n("Pressing this button completes the current rename operation," + "moves to the previous item and starts a new rename operation.")); + m_paRenameMovePrev->setToolTip( i18n("Complete rename operation and move the previous item")); + m_paRenameMovePrev->setEnabled(false); + + m_paShowDot = new TDEToggleAction( i18n( "Show &Hidden Files" ), 0, this, TQT_SLOT( slotShowDot() ), actionCollection(), "show_dot" ); +// m_paShowDot->setCheckedState(i18n("Hide &Hidden Files")); + m_paCaseInsensitive = new TDEToggleAction(i18n("Case Insensitive Sort"), 0, this, TQT_SLOT(slotCaseInsensitive()),actionCollection(), "sort_caseinsensitive" ); + + newIconSize( TDEIcon::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..4c3719bd0 --- /dev/null +++ b/konqueror/listview/konq_listview.h @@ -0,0 +1,217 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 <tdeparts/browserextension.h> +#include <tdeglobalsettings.h> +#include <konq_operations.h> +#include <tdeparts/factory.h> +#include <konq_dirpart.h> +#include <kmimetyperesolver.h> + +#include <tqvaluelist.h> +#include <tqlistview.h> +#include <tqstringlist.h> + +#include <konq_propsview.h> +#include "konq_listviewwidget.h" + +class TDEAction; +class TDEToggleAction; +class ListViewBrowserExtension; + +class KonqListViewFactory : public KParts::Factory +{ +public: + KonqListViewFactory(); + virtual ~KonqListViewFactory(); + + virtual KParts::Part* createPartObject( TQWidget *parentWidget, const char *, TQObject *parent, const char *name, const char*, const TQStringList &args ); + + static TDEInstance *instance(); + static KonqPropsView *defaultViewProps(); + +private: + static TDEInstance *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; + friend class ListViewBrowserExtension; + Q_OBJECT + TQ_PROPERTY( bool supportsUndo READ supportsUndo ) +public: + KonqListView( TQWidget *parentWidget, TQObject *parent, const char *name, const TQString& 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( TQDataStream &stream ); + virtual void restoreState( TQDataStream &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 ); + + TQPtrList<KonqBaseListViewItem> & 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<KonqBaseListViewItem,KonqListView> *m_mimeTypeResolver; + TQTimer *m_headerTimer; + + TDEAction *m_paSelect; + TDEAction *m_paUnselect; + TDEAction *m_paSelectAll; + TDEAction *m_paUnselectAll; + TDEAction *m_paInvertSelection; + + // These 2 actions are 'fake' actions. They are defined so that the keyboard shortcuts + // can be set from the 'Configure Shortcuts..." dialog. + // The real actions are performed in the TDEListViewLineEdit::keyPressEvent() in tdeui + TDEAction *m_paRenameMoveNext; + TDEAction *m_paRenameMovePrev; + + TDEToggleAction *m_paCaseInsensitive; + + TDEToggleAction *m_paShowDot; + TDEToggleAction *m_paShowTime; + TDEToggleAction *m_paShowType; + TDEToggleAction *m_paShowMimeType; + TDEToggleAction *m_paShowAccessTime; + TDEToggleAction *m_paShowCreateTime; + TDEToggleAction *m_paShowLinkDest; + TDEToggleAction *m_paShowSize; + TDEToggleAction *m_paShowOwner; + TDEToggleAction *m_paShowGroup; + TDEToggleAction *m_paShowPermissions; + TDEToggleAction *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 TQString &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..bce9798a6 --- /dev/null +++ b/konqueror/listview/konq_listview.kcfg @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 + http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" > + <include>tdeapplication.h</include> + <kcfgfile name="konquerorrc"> + <parameter name="Protocol" /> + </kcfgfile> + + <group name="ListView_$(Protocol)"> + <entry key="SortBy" type="String"> + <default>FileName</default> + <label>List is sorted by this item</label> + <whatsthis></whatsthis> + </entry> + <entry key="SortOrder" type="Bool"> + <default>true</default> + <label>Sort Order</label> + <whatsthis></whatsthis> + </entry> + <entry key="FileNameColumnWidth" type="Int"> + <default code="true">25 * TDEApplication::kApplication()->fontMetrics().width( "m" )</default> + <label>Width of the FileName Column</label> + <whatsthis></whatsthis> + </entry> + <entry key="Columns" type="StringList"> + <label>Columns</label> + <whatsthis></whatsthis> + </entry> + <entry key="ColumnWidths" type="IntList"> + <label>Widths of the Columns</label> + <whatsthis></whatsthis> + </entry> + </group> + +</kcfg>
\ 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..45ff99c1c --- /dev/null +++ b/konqueror/listview/konq_listviewitems.cc @@ -0,0 +1,459 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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_settings.h> +#include <kdebug.h> +#include <tdelocale.h> +#include <assert.h> +#include <stdio.h> +#include <tqpainter.h> +#include <tqheader.h> +#include <kiconloader.h> + +static TQString retrieveExtraEntry( KFileItem* fileitem, int numExtra ) +{ + /// ######## SLOOOOW + TDEIO::UDSEntry::ConstIterator it = fileitem->entry().begin(); + const TDEIO::UDSEntry::ConstIterator end = fileitem->entry().end(); + int n = 0; + for( ; it != end; ++it ) + { + if ((*it).m_uds == TDEIO::UDS_EXTRA) + { + ++n; + if ( n == numExtra ) + { + return (*it).m_str; + } + } + } + return TQString::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 ( TQValueVector<TQPixmap*>::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; i<m_pListViewWidget->NumberOfAtoms; i++ ) + { + ColumnInfo *tmpColumn=&m_pListViewWidget->columnConfigInfo()[i]; + if (tmpColumn->displayThisOne) + { + switch (tmpColumn->udsId) + { + case TDEIO::UDS_USER: + setText(tmpColumn->displayInColumn,m_fileitem->user()); + break; + case TDEIO::UDS_GROUP: + setText(tmpColumn->displayInColumn,m_fileitem->group()); + break; + case TDEIO::UDS_FILE_TYPE: + if (m_fileitem->isMimeTypeKnown()) { + setText(tmpColumn->displayInColumn,m_fileitem->mimeComment()); + } + break; + case TDEIO::UDS_MIME_TYPE: + if (m_fileitem->isMimeTypeKnown()) { + setText(tmpColumn->displayInColumn,m_fileitem->mimetype()); + } + break; + case TDEIO::UDS_URL: + setText(tmpColumn->displayInColumn,m_fileitem->url().prettyURL()); + break; + case TDEIO::UDS_LINK_DEST: + setText(tmpColumn->displayInColumn,m_fileitem->linkDest()); + break; + case TDEIO::UDS_SIZE: + if ( m_pListViewWidget->m_pSettings->fileSizeInBytes() ) + setText(tmpColumn->displayInColumn,TDEGlobal::locale()->formatNumber( m_fileitem->size(),0)+" "); + else + setText(tmpColumn->displayInColumn,TDEIO::convertSize(m_fileitem->size())+" "); + break; + case TDEIO::UDS_ACCESS: + setText(tmpColumn->displayInColumn,m_fileitem->permissionsString()); + break; + case TDEIO::UDS_MODIFICATION_TIME: + case TDEIO::UDS_ACCESS_TIME: + case TDEIO::UDS_CREATION_TIME: + { + TQDateTime dt; + time_t _time = m_fileitem->time( tmpColumn->udsId ); + if ( _time != 0 ) + { + dt.setTime_t( _time ); + setText(tmpColumn->displayInColumn, TDEGlobal::locale()->formatDateTime(dt)); + } + else + { + setText(tmpColumn->displayInColumn, TQString::null); + } + } + break; + case TDEIO::UDS_EXTRA: + { + const TQString entryStr = retrieveExtraEntry( m_fileitem, numExtra ); + if ( tmpColumn->type == TQVariant::DateTime ) + { + TQDateTime dt = TQT_TQDATETIME_OBJECT(TQDateTime::fromString( entryStr, Qt::ISODate )); + setText(tmpColumn->displayInColumn, + TDEGlobal::locale()->formatDateTime(dt)); + } + else // if ( tmpColumn->type == TQVariant::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 : TDEGlobal::iconLoader()->currentSize( TDEIcon::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 : TDEGlobal::iconLoader()->currentSize( TDEIcon::Small ); // Default = small + setPixmap( 0, m_fileitem->pixmap( iconSize, state() ) ); +} + +void KonqListViewItem::setPixmap( int column, const TQPixmap& pm ) +{ + if ( column < 0 ) + return; + + const TQPixmap *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 TQPixmap( 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. + + TQListView *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 TQPixmap* KonqListViewItem::pixmap( int column ) const +{ + bool ok; + if ((int)m_pixmaps.count() <= column) + return 0; + + TQPixmap *pm = m_pixmaps.at( column, &ok ); + if( !ok ) + return 0; + return pm; +} + +int KonqBaseListViewItem::compare( TQListViewItem* item, int col, bool ascending ) const +{ + KonqListViewItem* k = static_cast<KonqListViewItem*>( 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; i<m_pListViewWidget->NumberOfAtoms; i++ ) + { + ColumnInfo *cInfo = &m_pListViewWidget->columnConfigInfo()[i]; + if ( cInfo->udsId == TDEIO::UDS_EXTRA ) + ++numExtra; + if ( col == cInfo->displayInColumn ) + { + switch ( cInfo->udsId ) + { + case TDEIO::UDS_MODIFICATION_TIME: + case TDEIO::UDS_ACCESS_TIME: + case TDEIO::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 TDEIO::UDS_SIZE: + { + TDEIO::filesize_t s1 = m_fileitem->size(); + TDEIO::filesize_t s2 = k->m_fileitem->size(); + return ( s1 > s2 ) ? 1 : ( s1 < s2 ) ? -1 : 0; + } + case TDEIO::UDS_EXTRA: + { + if ( cInfo->type & TQVariant::DateTime ) { + const TQString entryStr1 = retrieveExtraEntry( m_fileitem, numExtra ); + TQDateTime dt1 = TQT_TQDATETIME_OBJECT(TQDateTime::fromString( entryStr1, Qt::ISODate )); + const TQString entryStr2 = retrieveExtraEntry( k->m_fileitem, numExtra ); + TQDateTime dt2 = TQT_TQDATETIME_OBJECT(TQDateTime::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( TQPainter *_painter, const TQColorGroup & _cg, int _column, int _width, int _alignment ) +{ + TQColorGroup cg( _cg ); + + if ( _column == 0 ) + { + _painter->setFont( m_pListViewWidget->itemFont() ); + } + + cg.setColor( TQColorGroup::Text, m_pListViewWidget->itemColor() ); + + TDEListView *lv = static_cast< TDEListView* >( listView() ); + const TQPixmap *pm = TQT_TQPIXMAP_CONST(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( TQColorGroup::Base, TQBrush( backgroundColor(_column), *pm ) ); + TQPoint o = _painter->brushOrigin(); + _painter->setBrushOrigin( o.x() - lv->contentsX(), o.y() - lv->contentsY() ); + const TQColorGroup::ColorRole crole = + TQPalette::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; + } + + TDEListViewItem::paintCell( _painter, cg, _column, _width, _alignment ); +} + +void KonqListViewItem::paintFocus( TQPainter * _painter, const TQColorGroup & cg, const TQRect & _r ) +{ + TQRect r( _r ); + TQListView *lv = static_cast< TQListView * >( listView() ); + r.setWidth( width( lv->fontMetrics(), lv, 0 ) ); + if ( r.right() > lv->header()->sectionRect( 0 ).right() ) + r.setRight( lv->header()->sectionRect( 0 ).right() ); + TQListViewItem::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) +:TDEListViewItem(_listViewWidget) +,sortChar(0) +,m_bDisabled(false) +,m_bActive(false) +,m_fileitem(_fileitem) +,m_fileitemURL(_fileitem->url()) +,m_pListViewWidget(_listViewWidget) +{} + +KonqBaseListViewItem::KonqBaseListViewItem(KonqBaseListViewWidget *_listViewWidget, KonqBaseListViewItem *_parent, KFileItem* _fileitem) +:TDEListViewItem(_parent) +,sortChar(0) +,m_bDisabled(false) +,m_bActive(false) +,m_fileitem(_fileitem) +,m_fileitemURL(_fileitem->url()) +,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); +} + +TQRect KonqBaseListViewItem::rect() const +{ + TQRect r = m_pListViewWidget->itemRect(this); + return TQRect( m_pListViewWidget->viewportToContents( r.topLeft() ), TQSize( r.width(), r.height() ) ); +} + +void KonqBaseListViewItem::mimetypeFound() +{ + // Update icon + setDisabled( m_bDisabled ); + uint done = 0; + KonqBaseListViewWidget * lv = m_pListViewWidget; + for (unsigned int i=0; i<m_pListViewWidget->NumberOfAtoms && done < 2; i++) + { + ColumnInfo *tmpColumn=&lv->columnConfigInfo()[i]; + if (lv->columnConfigInfo()[i].udsId==TDEIO::UDS_FILE_TYPE && tmpColumn->displayThisOne) + { + setText(tmpColumn->displayInColumn, m_fileitem->mimeComment()); + done++; + } + if (lv->columnConfigInfo()[i].udsId==TDEIO::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..2e2827519 --- /dev/null +++ b/konqueror/listview/konq_listviewitems.h @@ -0,0 +1,126 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 <tdelistview.h> +#include <tqstring.h> +#include <kicontheme.h> + +#include <tqvaluevector.h> + +// for mode_t +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +class TQPainter; +class KFileItem; +class KonqBaseListViewWidget; + + +class KonqBaseListViewItem : public TDEListViewItem +{ + 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; } + + virtual 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( TQListViewItem* i, int col, bool ascending ) const; + + int state() const + { + if (m_bDisabled) + return TDEIcon::DisabledState; + if (m_bActive) + return TDEIcon::ActiveState; + return TDEIcon::DefaultState; + } + + /** For KonqMimeTypeResolver */ + TQRect rect() const; + + protected: + short int sortChar; + bool m_bDisabled; + bool m_bActive; + + /** Pointer to the file item in KDirLister's list + * Don't use this unless you absolutely have to! */ + KFileItem* m_fileitem; + /** URL of file item */ + KURL m_fileitemURL; + /** 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( TQPainter *_painter, const TQColorGroup & cg, + int column, int width, int alignment ); + virtual void paintFocus( TQPainter * _painter, const TQColorGroup & cg, const TQRect & r ); + virtual void updateContents(); + virtual void setDisabled( bool disabled ); + virtual void setActive ( bool active ); + + virtual void setPixmap( int column, const TQPixmap & pm ); + virtual const TQPixmap * pixmap( int column ) const; + +private: + TQValueVector<TQPixmap *> m_pixmaps; +}; + +#endif diff --git a/konqueror/listview/konq_listviewsettings.kcfgc b/konqueror/listview/konq_listviewsettings.kcfgc new file mode 100644 index 000000000..b4f9c2859 --- /dev/null +++ b/konqueror/listview/konq_listviewsettings.kcfgc @@ -0,0 +1,4 @@ +File=konq_listview.kcfg +ClassName=KonqListViewSettings +Singleton=false +Mutators=true diff --git a/konqueror/listview/konq_listviewwidget.cc b/konqueror/listview/konq_listviewwidget.cc new file mode 100644 index 000000000..0f245a5c5 --- /dev/null +++ b/konqueror/listview/konq_listviewwidget.cc @@ -0,0 +1,1565 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + 2001, 2002, 2004 Michael Brade <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 <konq_filetip.h> +#include <konq_drag.h> +#include <konq_settings.h> + +#include <kdebug.h> +#include <kdirlister.h> +#include <tdelocale.h> +#include <kprotocolinfo.h> +#include <tdeaction.h> +#include <kurldrag.h> +#include <tdemessagebox.h> +#include <kiconloader.h> +#include <kiconeffect.h> + +#include <tqheader.h> +#include <tqpainter.h> +#include <tqstyle.h> +#include <tqtimer.h> +#include <tqevent.h> +#include <tqcursor.h> +#include <tqtooltip.h> + +#include <stdlib.h> +#include <assert.h> + +ColumnInfo::ColumnInfo() + :displayInColumn(-1) + ,name() + ,desktopFileName() + ,udsId(0) + ,type(TQVariant::Invalid) + ,displayThisOne(false) + ,toggleThisOne(0) +{} + + +void ColumnInfo::setData(const TQString& n, const TQString& desktopName, int kioUds, + TDEToggleAction* someAction, int theWidth) +{ + displayInColumn=-1; + name=n; + desktopFileName=desktopName; + udsId=kioUds; + type=TQVariant::Invalid; + displayThisOne=false; + toggleThisOne=someAction; + width=theWidth; +} + +void ColumnInfo::setData(const TQString& n, const TQString& desktopName, int kioUds, + TQVariant::Type t, TDEToggleAction* someAction, int theWidth) +{ + displayInColumn=-1; + name=n; + desktopFileName=desktopName; + udsId=kioUds; + type=t; + displayThisOne=false; + toggleThisOne=someAction; + width=theWidth; +} + + +KonqBaseListViewWidget::KonqBaseListViewWidget( KonqListView *parent, TQWidget *parentWidget) + : TDEListView(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 TDEListView behaviour + setMultiSelection(true); + setSelectionModeExt( FileManager ); + setDragEnabled(true); + setItemsMovable(false); + setUseSmallExecuteArea(true); + + initConfig(); +#if 0 + connect( this, TQT_SIGNAL(rightButtonPressed(TQListViewItem*,const TQPoint&,int)), + this, TQT_SLOT(slotRightButtonPressed(TQListViewItem*,const TQPoint&,int))); +#endif + connect( this, TQT_SIGNAL(returnPressed( TQListViewItem * )), + this, TQT_SLOT(slotReturnPressed( TQListViewItem * )) ); + connect( this, TQT_SIGNAL(mouseButtonClicked( int, TQListViewItem *, const TQPoint&, int )), + this, TQT_SLOT(slotMouseButtonClicked2( int, TQListViewItem *, const TQPoint&, int )) ); + connect( this, TQT_SIGNAL(executed( TQListViewItem * )), + this, TQT_SLOT(slotExecuted( TQListViewItem * )) ); + connect( this, TQT_SIGNAL(currentChanged( TQListViewItem * )), + this, TQT_SLOT(slotCurrentChanged( TQListViewItem * )) ); + connect( this, TQT_SIGNAL(itemRenamed( TQListViewItem *, const TQString &, int )), + this, TQT_SLOT(slotItemRenamed( TQListViewItem *, const TQString &, int )) ); + connect( this, TQT_SIGNAL(contextMenuRequested( TQListViewItem *, const TQPoint&, int )), + this, TQT_SLOT(slotPopupMenu( TQListViewItem *, const TQPoint&, int )) ); + connect( this, TQT_SIGNAL(renameNext( TQListViewItem *, int )), + this, TQT_SLOT(slotRenameNextItem( TQListViewItem*, int)) ); + connect( this, TQT_SIGNAL(renamePrev( TQListViewItem *, int )), + this, TQT_SLOT(slotRenamePrevItem( TQListViewItem*, int)) ); + connect( this, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(slotSelectionChanged()) ); + + connect( horizontalScrollBar(), TQT_SIGNAL(valueChanged( int )), + this, TQT_SIGNAL(viewportAdjusted()) ); + connect( verticalScrollBar(), TQT_SIGNAL(valueChanged( int )), + this, TQT_SIGNAL(viewportAdjusted()) ); + + // Connect the directory lister + connect( m_dirLister, TQT_SIGNAL(started( const KURL & )), + this, TQT_SLOT(slotStarted()) ); + connect( m_dirLister, TQT_SIGNAL(completed()), this, TQT_SLOT(slotCompleted()) ); + connect( m_dirLister, TQT_SIGNAL(canceled()), this, TQT_SLOT(slotCanceled()) ); + connect( m_dirLister, TQT_SIGNAL(clear()), this, TQT_SLOT(slotClear()) ); + connect( m_dirLister, TQT_SIGNAL(newItems( const KFileItemList & ) ), + this, TQT_SLOT(slotNewItems( const KFileItemList & )) ); + connect( m_dirLister, TQT_SIGNAL(deleteItem( KFileItem * )), + this, TQT_SLOT(slotDeleteItem( KFileItem * )) ); + connect( m_dirLister, TQT_SIGNAL(refreshItems( const KFileItemList & )), + this, TQT_SLOT( slotRefreshItems( const KFileItemList & )) ); + connect( m_dirLister, TQT_SIGNAL(redirection( const KURL & )), + this, TQT_SLOT(slotRedirection( const KURL & )) ); + connect( m_dirLister, TQT_SIGNAL(itemsFilteredByMime( const KFileItemList & )), + m_pBrowserView, TQT_SIGNAL(itemsFilteredByMime( const KFileItemList & )) ); + + connect( m_dirLister, TQT_SIGNAL(infoMessage( const TQString& )), + m_pBrowserView->extension(), TQT_SIGNAL(infoMessage( const TQString& )) ); + connect( m_dirLister, TQT_SIGNAL(percent( int )), + m_pBrowserView->extension(), TQT_SIGNAL(loadingProgress( int )) ); + connect( m_dirLister, TQT_SIGNAL(speed( int )), + m_pBrowserView->extension(), TQT_SIGNAL(speedProgress( int )) ); + + connect( header(), TQT_SIGNAL(sizeChange( int, int, int )), TQT_SLOT(slotUpdateBackground()) ); + + viewport()->setMouseTracking( true ); + viewport()->setFocusPolicy( TQ_WheelFocus ); + setFocusPolicy( TQ_WheelFocus ); + setAcceptDrops( true ); + + //looks better with the statusbar + setFrameStyle( TQFrame::StyledPanel | TQFrame::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 TQString protocol = url.protocol(); + KonqListViewSettings config( protocol ); + config.readConfig(); + sortedByColumn = config.sortBy(); + m_bAscending = config.sortOrder(); + + m_filenameColumnWidth = config.fileNameColumnWidth(); + + TQStringList lstColumns = config.columns(); + TQValueList<int> 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 TQString column = (*extraFieldsIt).name; + if ( lstColumns.find(column) == lstColumns.end() ) + lstColumns << column; + const TQString type = (*extraFieldsIt).type; // ## TODO use when sorting + TQVariant::Type t = TQVariant::Invalid; + if ( type.lower() == TQString(TQSTRING_OBJECT_NAME_STRING).lower() ) + t = TQVariant::String; + else if ( type.lower() == TQString(TQDATETIME_OBJECT_NAME_STRING).lower() ) + t = TQVariant::DateTime; + else + kdWarning() << "Unsupported ExtraType '" << type << "'" << endl; + confColumns[extraIndex++].setData( column, TQString("Extra%1").arg(num), TDEIO::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]; + TQString str; + + if ( tmpColumn->udsId == TDEIO::UDS_SIZE ) + str = TDEGlobal::locale()->formatNumber( 888888888, 0 ) + " "; + else if ( tmpColumn->udsId == TDEIO::UDS_ACCESS ) + str = "--Permissions--"; + else if ( tmpColumn->udsId == TDEIO::UDS_USER ) + str = "a_long_username"; + else if ( tmpColumn->udsId == TDEIO::UDS_GROUP ) + str = "a_groupname"; + else if ( tmpColumn->udsId == TDEIO::UDS_LINK_DEST ) + str = "a_quite_long_filename_for_link_dest"; + else if ( tmpColumn->udsId == TDEIO::UDS_FILE_TYPE ) + str = "a_long_comment_for_mimetype"; + else if ( tmpColumn->udsId == TDEIO::UDS_MIME_TYPE ) + str = "_a_long_/_mimetype_"; + else if ( tmpColumn->udsId == TDEIO::UDS_URL ) + str = "a_long_lonq_long_very_long_url"; + else if ( (tmpColumn->udsId & TDEIO::UDS_TIME) + || (tmpColumn->udsId == TDEIO::UDS_EXTRA && + (tmpColumn->type & TQVariant::DateTime)) ) + { + TQDateTime dt( TQDate( 2000, 10, 10 ), TQTime( 20, 20, 20 ) ); + str = TDEGlobal::locale()->formatDateTime( dt ) + "--"; + } + else + str = "it_is_the_default_width"; + + confColumns[j].width = fontMetrics().width(str); + } + break; + } + } + } + //check what the protocol provides + TQStringList 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 == TDEIO::UDS_URL || + confColumns[i].udsId == TDEIO::UDS_MIME_TYPE || + !confColumns[i].displayThisOne ) + { + continue; + } + + TQStringList::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 == TDEIO::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(); + + TQFont stdFont( m_pSettings->standardFont() ); + setFont( stdFont ); + //TODO: create config GUI + TQFont itemFont( m_pSettings->standardFont() ); + itemFont.setUnderline( m_pSettings->underlineLink() ); + setItemFont( itemFont ); + setItemColor( m_pSettings->normalTextColor() ); + + bool on = m_pSettings->showFileTips() && TQToolTip::isGloballyEnabled(); + m_fileTip->setOptions( on, m_pSettings->showPreviewsInFileTips(), m_pSettings->numFileTips() ); + + updateListContents(); +} + +void KonqBaseListViewWidget::contentsMousePressEvent( TQMouseEvent *e ) { + if ( m_rubber ) { + TQRect r( m_rubber->normalize() ); + delete m_rubber; + m_rubber = 0; + repaintContents( r, FALSE ); + } + + delete m_selected; + m_selected = new TQPtrList<KonqBaseListViewItem>; + + TQPoint vp = contentsToViewport( e->pos() ); + KonqBaseListViewItem* item = isExecuteArea( vp ) ? + static_cast<KonqBaseListViewItem*>( itemAt( vp ) ) : 0L; + + if ( item ) { + TDEListView::contentsMousePressEvent( e ); + } + else { + if ( e->button() == Qt::LeftButton ) { + m_rubber = new TQRect( e->x(), e->y(), 0, 0 ); + clearSelection(); + emit selectionChanged(); + m_fileTip->setItem( 0 ); + } + if ( e->button() != Qt::RightButton ) { + TQListView::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( TQMouseEvent *e ) { + if ( m_rubber ) { + resetKeyboardSelectionOperation(); + TQRect r( m_rubber->normalize() ); + delete m_rubber; + m_rubber = 0; + repaintContents( r, FALSE ); + } + + if ( m_scrollTimer ) { + disconnect( m_scrollTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotAutoScroll() ) ); + m_scrollTimer->stop(); + delete m_scrollTimer; + m_scrollTimer = 0; + } + + delete m_selected; m_selected = 0; + TDEListView::contentsMouseReleaseEvent( e ); +} + +void KonqBaseListViewWidget::contentsMouseMoveEvent( TQMouseEvent *e ) +{ + if ( m_rubber ) + { + slotAutoScroll(); + return; + } + + TQPoint vp = contentsToViewport( e->pos() ); + KonqBaseListViewItem* item = isExecuteArea( vp ) ? + static_cast<KonqBaseListViewItem *>( 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() ); + TQRect rect( viewportToContents( vp ), TQSize(20, item->height()) ); + m_fileTip->setItem( item->item(), rect, item->pixmap( 0 ) ); + m_fileTip->setPreview( TDEGlobalSettings::showFilePreview( item->item()->url() ) ); + setShowToolTips( !m_pSettings->showFileTips() ); + } + else + { + reportItemCounts(); + m_pBrowserView->emitMouseOver( 0 ); + + m_fileTip->setItem( 0 ); + setShowToolTips( true ); + } + } + + TDEListView::contentsMouseMoveEvent( e ); +} + +void KonqBaseListViewWidget::contentsWheelEvent( TQWheelEvent *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 ); + TDEListView::contentsWheelEvent( e ); +} + +void KonqBaseListViewWidget::leaveEvent( TQEvent *e ) +{ + if ( m_activeItem != 0 ) + { + m_activeItem->setActive( false ); + m_activeItem = 0; + } + + reportItemCounts(); + m_pBrowserView->emitMouseOver( 0 ); + + m_fileTip->setItem( 0 ); + + TDEListView::leaveEvent( e ); +} + +void KonqBaseListViewWidget::drawRubber( TQPainter *p ) +{ + if ( !m_rubber ) + return; + + p->setRasterOp( NotROP ); + p->setPen( TQPen( color0, 1 ) ); + p->setBrush( NoBrush ); + + TQPoint pt( m_rubber->x(), m_rubber->y() ); + pt = contentsToViewport( pt ); + style().tqdrawPrimitive( TQStyle::PE_RubberBand, p, + TQRect( pt.x(), pt.y(), m_rubber->width(), m_rubber->height() ), + colorGroup(), TQStyle::Style_Default, colorGroup().base() ); +} + +void KonqBaseListViewWidget::slotAutoScroll() +{ + if ( !m_rubber ) + return; + + // this code assumes that all items have the same height + + const TQPoint pos = viewport()->mapFromGlobal( TQCursor::pos() ); + const TQPoint vc = viewportToContents( pos ); + TQListViewItem *at = itemAt( vc ); + + if ( vc == m_rubber->bottomRight() ) + return; + + TQRect oldRubber = *m_rubber; + + const int oldTop = m_rubber->normalize().top(); + const int oldBottom = m_rubber->normalize().bottom(); + + + m_rubber->setBottomRight( vc ); + + TQListViewItem *cur = itemAt( TQPoint(0,0) ); + + bool block = signalsBlocked(); + blockSignals( true ); + + TQRect rr; + TQRect nr = m_rubber->normalize(); + bool changed = FALSE; + + if ( cur ) + { + TQRect rect; + if ( allColumnsShowFocus() ) + rect = itemRect( cur ); + else { + rect = itemRect( cur ); + rect.setWidth( executeArea( cur ) ); + } + + + rect = TQRect( 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() ); + } + + TQRect r = rect; + TQListViewItem *tmp = cur; + + while ( cur && rect.top() <= oldBottom ) + { + if ( rect.intersects( nr ) ) + { + if ( !cur->isSelected() && cur->isSelectable() ) + { + setSelected( cur, true ); + setActiveMultiSelectItem( at ); + changed = TRUE; + rr = rr.unite( itemRect( cur ) ); + } + } + else + { + if ( cur->isSelected() ) + { + changed = TRUE; + rr = rr.unite( itemRect( cur ) ); + } + + if ( !m_selected || !m_selected->contains( (KonqBaseListViewItem*)cur ) ) + { + setSelected( cur, false ); + setActiveMultiSelectItem( at ); + } + } + + + 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 ); + setActiveMultiSelectItem( at ); + changed = TRUE; + rr = rr.unite( itemRect( cur ) ); + } + } + else + { + if ( cur->isSelected() ) + { + changed = TRUE; + rr = rr.unite( itemRect( cur ) ); + } + + if ( !m_selected || !m_selected->contains( (KonqBaseListViewItem*)cur ) ) + { + setSelected( cur, false ); + setActiveMultiSelectItem( at ); + } + } + + + cur = cur->itemAbove(); + if (cur && !allColumnsShowFocus()) + rect.setWidth( executeArea( cur ) ); + rect.moveBy( 0, -rect.height() ); + } + } + + blockSignals( block ); + emit selectionChanged(); + + TQRect allRect = oldRubber.normalize(); + if ( changed ) + { + allRect |= rr.normalize(); + } + allRect |= m_rubber->normalize(); + TQPoint point = contentsToViewport( allRect.topLeft() ); + allRect = TQRect( point.x(), point.y(), allRect.width(), allRect.height() ); + allRect &= viewport()->rect(); + allRect.addCoords( -2, -2, 2, 2 ); + + TQPixmap backrubber( viewport()->rect().size() ); + backrubber.fill( viewport(), viewport()->rect().topLeft() ); + + TQPainter p( &backrubber ); + p.save(); + drawContentsOffset( &p, + contentsX(), + contentsY(), + contentsX() + allRect.left(), contentsY() + allRect.top(), + allRect.width(), allRect.height() ); + p.restore(); + drawRubber( &p ); + p.end(); + bitBlt( viewport(), allRect.topLeft(), &backrubber, allRect ); + + const int scroll_margin = 40; + ensureVisible( vc.x(), vc.y(), scroll_margin, scroll_margin ); + + if ( !TQRect( scroll_margin, scroll_margin, + viewport()->width() - 2*scroll_margin, + viewport()->height() - 2*scroll_margin ).contains( pos ) ) + { + if ( !m_scrollTimer ) + { + m_scrollTimer = new TQTimer( this ); + + connect( m_scrollTimer, TQT_SIGNAL( timeout() ), + this, TQT_SLOT( slotAutoScroll() ) ); + m_scrollTimer->start( 100, false ); + } + } + else if ( m_scrollTimer ) + { + disconnect( m_scrollTimer, TQT_SIGNAL( timeout() ), + this, TQT_SLOT( slotAutoScroll() ) ); + m_scrollTimer->stop(); + delete m_scrollTimer; + m_scrollTimer = 0; + } +} + +void KonqBaseListViewWidget::viewportPaintEvent( TQPaintEvent *e ) +{ + + TDEListView::viewportPaintEvent( e ); + + TQPainter p( viewport() ); + drawRubber( &p ); + p.end(); +} + +void KonqBaseListViewWidget::viewportResizeEvent(TQResizeEvent * e) +{ + TDEListView::viewportResizeEvent(e); + emit viewportAdjusted(); +} + +void KonqBaseListViewWidget::viewportDragMoveEvent( TQDragMoveEvent *_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( TQDragEnterEvent *_ev ) +{ + m_dragOverItem = 0L; + + // By default we accept any format + _ev->acceptAction(); +} + +void KonqBaseListViewWidget::viewportDragLeaveEvent( TQDragLeaveEvent * ) +{ + if ( m_dragOverItem != 0L ) + setSelected( m_dragOverItem, false ); + m_dragOverItem = 0L; +} + +void KonqBaseListViewWidget::viewportDropEvent( TQDropEvent *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 ); + + TQListViewItem * m_pressedItem = currentItem(); + + TQPixmap 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 : TDEGlobal::iconLoader()->currentSize( TDEIcon::Small ); // Default = small + pixmap2 = DesktopIcon( "application-vnd.tde.tdemultiple", 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( TQListViewItem *item, const TQString &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, TDEListView 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<KonqBaseListViewItem*>(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(), TDEIO::encodeFileName( name ) ); + } + + // When the TDEListViewLineEdit loses focus, focus tends to go to the location bar... + setFocus(); +} + +void KonqBaseListViewWidget::slotRenameNextItem(TQListViewItem *item, int) +{ + TQListViewItem *nextItem = item->itemBelow(); + if (!nextItem) + { + nextItem=this->firstChild(); + if (!nextItem) + return; + } + + deactivateAutomaticSelection(); + setCurrentItem(nextItem); + ListViewBrowserExtension *lvbe = dynamic_cast<ListViewBrowserExtension*>(m_pBrowserView->m_extension); + if (lvbe) + lvbe->rename(); +} + +void KonqBaseListViewWidget::slotRenamePrevItem(TQListViewItem *item, int) +{ + TQListViewItem *prevItem = item->itemAbove(); + if (!prevItem) + { + prevItem=this->lastItem(); + if (!prevItem) + return; + } + + deactivateAutomaticSelection(); + setCurrentItem(prevItem); + ListViewBrowserExtension *lvbe = dynamic_cast<ListViewBrowserExtension*>(m_pBrowserView->m_extension); + if (lvbe) + lvbe->rename(); +} + +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, + TQListViewItem *_item, const TQPoint& pos, int ) +{ + if ( _button == Qt::MidButton ) + { + if ( _item && isExecuteArea( viewport()->mapFromGlobal(pos) ) ) + m_pBrowserView->mmbClicked( static_cast<KonqBaseListViewItem *>(_item)->item() ); + else // MMB on background + m_pBrowserView->mmbClicked( 0 ); + } +} + +void KonqBaseListViewWidget::slotExecuted( TQListViewItem *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( TQCursor::pos() ) ) ) + slotReturnPressed( item ); +} + +void KonqBaseListViewWidget::selectedItems( TQPtrList<KonqBaseListViewItem> *_list ) +{ + iterator it = begin(); + for ( ; it != end(); it++ ) + if ( it->isSelected() ) + _list->append( &*it ); +} + +KFileItemList KonqBaseListViewWidget::visibleFileItems() +{ + KFileItemList list; + KonqBaseListViewItem *item = static_cast<KonqBaseListViewItem *>(firstChild()); + while ( item ) + { + list.append( item->item() ); + item = static_cast<KonqBaseListViewItem *>(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( TQListViewItem *_item ) +{ + if ( !_item ) + return; + KFileItem *fileItem = static_cast<KonqBaseListViewItem *>(_item)->item(); + if ( !fileItem ) + return; + + KURL url = fileItem->url(); + url.cleanPath(); + bool isIntoTrash = url.isLocalFile() && url.path(1).startsWith(TDEGlobalSettings::trashPath()); + if ( !isIntoTrash || (isIntoTrash && fileItem->isDir()) ) + { + m_pBrowserView->lmbClicked( fileItem ); + + if (_item->pixmap(0) != 0) + { + // Rect of the TQListViewItem's pixmap area. + TQRect rect = _item->listView()->itemRect(_item); + + // calculate nesting depth + int nestingDepth = 0; + for (TQListViewItem *currentItem = _item->parent(); + currentItem != 0; + currentItem = currentItem->parent()) + nestingDepth++; + + // no parent no indent + if (_item->parent() == 0) + nestingDepth = 0; + + // Root decoration means additional indent + if (_item->listView()->rootIsDecorated()) + nestingDepth++; + + // set recalculated rect + rect.setLeft(_item->listView()->itemMargin() + _item->listView()->treeStepSize() * nestingDepth); + rect.setWidth(_item->pixmap(0)->width()); + + // gather pixmap + TQPixmap *pix = new TQPixmap(*(_item->pixmap(0))); + + // call the icon effect if enabled + if (TDEGlobalSettings::showKonqIconActivationEffect() == true) { + TDEIconEffect::visualActivate(viewport(), rect, pix); + } + + // clean up + delete(pix); + } + } + else + KMessageBox::information( 0, i18n("You must take the file out of the trash before being able to use it.") ); +} + +void KonqBaseListViewWidget::slotPopupMenu( TQListViewItem *i, const TQPoint &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 TQPoint& _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 ) ) ) + { + TQPtrList<KonqBaseListViewItem> 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( TQString::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 ( TQPtrListIterator<KFileItem> 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() ) { + TQStringList::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 TDEPARTS_BROWSEREXTENSION_HAS_ITEMS_REMOVED + KFileItemList list; + list.append( _fileitem ); + emit m_pBrowserView->extension()->itemsRemoved( list ); +#else +#error "Your tdelibs 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: TQListViewItem/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; + + TQPtrListIterator<KFileItem> 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 TQString 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( TQPainter *p, const TQRect &r ) +{ + const TQPixmap *pm = TQT_TQPIXMAP_CONST(viewport()->paletteBackgroundPixmap()); + + if (!pm || pm->isNull()) + p->fillRect(r, viewport()->backgroundColor()); + else + { + TQRect 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, TQPoint(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( TQDataStream & ds ) +{ + TQString str; + if ( currentItem() ) + str = static_cast<KonqBaseListViewItem*>(currentItem())->item()->url().fileName(true); + ds << str << m_url; +} + +void KonqBaseListViewWidget::restoreState( TQDataStream & ds ) +{ + m_restored = true; + + TQString 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 TQTimer( this ); + connect( m_backgroundTimer, TQT_SIGNAL( timeout() ), viewport(), TQT_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 tdelistview.cpp +int KonqBaseListViewWidget::executeArea( TQListViewItem *_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..ae79e5c03 --- /dev/null +++ b/konqueror/listview/konq_listviewwidget.h @@ -0,0 +1,274 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + 2004 Michael Brade <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 <tqvaluelist.h> +#include <tqvaluevector.h> + +#include <kurl.h> +#include <tdefileitem.h> +#include <tdelistview.h> +#include <tdeparts/browserextension.h> +#include <konq_propsview.h> +#include "konq_listviewitems.h" + +namespace TDEIO { class Job; } + +class TQCursor; +class TQRect; +class KDirLister; +class KonqFMSettings; +class ListViewPropertiesExtension; +class TDEToggleAction; +class KonqListView; +class KonqFileTip; +class ListViewBrowserExtension; +class TQTimer; +class TQFocusEvent; +class TQDragMoveEvent; +class TQDragEnterEvent; +class TQDragLeaveEvent; +class TQDropEvent; +class TQPaintEvent; +class TQResizeEvent; +class TQMouseEvent; + +class ColumnInfo +{ +public: + ColumnInfo(); + void setData( const TQString& n, const TQString& desktopName, int kioUds, + TDEToggleAction *someAction, int theWith = -1 ); + void setData( const TQString& n, const TQString& desktopName, int kioUds /* UDS_EXTRA */, + TQVariant::Type type, TDEToggleAction *someAction, int theWith = -1 ); + int displayInColumn; + TQString name; + TQString desktopFileName; + int udsId; + TQVariant::Type type; // only used if udsId == UDS_EXTRA + bool displayThisOne; + TDEToggleAction *toggleThisOne; + int width; +}; + +/** + * The tree view widget (based on TDEListView). + * Most of the functionality is here. + */ +class KonqBaseListViewWidget : public TDEListView +{ + friend class KonqBaseListViewItem; + friend class KonqListView; + friend class ListViewBrowserExtension; + + Q_OBJECT + +public: + KonqBaseListViewWidget( KonqListView *parent, TQWidget *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( TQPtrList<KonqBaseListViewItem> *_list ); + KFileItemList visibleFileItems(); + KFileItemList selectedFileItems(); + KURL::List selectedUrls( bool mostLocal = false ); + + /** @return the KonqListViewDir which handles the directory _url */ + //virtual KonqListViewDir *findDir ( const TQString & _url ); + + /** + * @return the Properties instance for this view. Used by the items. + */ + KonqPropsView *props() const; + + //TQPtrList<ColumnInfo> *columnConfigInfo() { return &confColumns; }; + TQValueVector<ColumnInfo>& columnConfigInfo() { return confColumns; }; + TQString sortedByColumn; + + virtual void setShowIcons( bool enable ) { m_showIcons = enable; } + virtual bool showIcons() { return m_showIcons; } + + void setItemFont( const TQFont &f ) { m_itemFont = f; } + TQFont itemFont() const { return m_itemFont; } + void setItemColor( const TQColor &c ) { m_itemColor = c; } + TQColor 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( TQPainter *p, const TQRect &r ); + + virtual void saveState( TQDataStream & ); + virtual void restoreState( TQDataStream & ); + + 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 TDEListView::slotMouseButtonClicked() + void slotMouseButtonClicked2( int _button, TQListViewItem *_item, const TQPoint& pos, int ); + virtual void slotExecuted( TQListViewItem *_item ); + void slotItemRenamed( TQListViewItem *, const TQString &, int ); + void slotRenameNextItem(TQListViewItem *item, int col); + void slotRenamePrevItem(TQListViewItem *item, int col); + +protected slots: + void slotAutoScroll(); + + // from TQListView + virtual void slotReturnPressed( TQListViewItem *_item ); + virtual void slotCurrentChanged( TQListViewItem *_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( TQListViewItem *, const TQPoint&, 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( TQDragMoveEvent *_ev ); + virtual void viewportDragEnterEvent( TQDragEnterEvent *_ev ); + virtual void viewportDragLeaveEvent( TQDragLeaveEvent *_ev ); + virtual void viewportDropEvent( TQDropEvent *_ev ); + virtual void viewportPaintEvent( TQPaintEvent *e ); + virtual void viewportResizeEvent( TQResizeEvent *e ); + + virtual void drawRubber( TQPainter * ); + virtual void contentsMousePressEvent( TQMouseEvent *e ); + virtual void contentsMouseReleaseEvent( TQMouseEvent *e ); + virtual void contentsMouseMoveEvent( TQMouseEvent *e ); + virtual void contentsWheelEvent( TQWheelEvent * e ); + + virtual void leaveEvent( TQEvent *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 TQPoint& _global, bool alwaysForSelectedFiles = false ); + + //this one is called only by TDEListView, and this is friend anyways (Alex) + //KDirLister *dirLister() const { return m_dirLister; } + +protected: + int executeArea( TQListViewItem *_item ); + + /** The directory lister for this URL */ + KDirLister *m_dirLister; + + //TQPtrList<ColumnInfo> 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 tdeio (David) + TQValueVector<ColumnInfo> confColumns; + + KonqBaseListViewItem *m_dragOverItem; + KonqBaseListViewItem *m_activeItem; + TQPtrList<KonqBaseListViewItem> *m_selected; + TQTimer *m_scrollTimer; + + TQFont m_itemFont; + TQColor m_itemColor; + + TQRect *m_rubber; + TQPixmap *m_backrubber; + + 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; + + TQString m_itemToGoTo; + TQStringList m_itemsToSelect; + TQTimer *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..3f44f0543 --- /dev/null +++ b/konqueror/listview/konq_textview.desktop @@ -0,0 +1,89 @@ +[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 +X-TDE-ServiceTypes=Browser/View +X-TDE-Library=konq_listview +X-TDE-BrowserView-Args=TextView +X-TDE-BrowserView-HideFromMenus=true +Icon=view_text +X-TDE-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 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="KonqTextView" version="5"> +<MenuBar> + <Menu name="edit"><text>&Edit</text> + <Menu name="selection"><text>Selection</text> + <Action name="select"/> + <Action name="unselect"/> + <Separator/> + <Action name="selectall"/> + <Action name="unselectall"/> + <Action name="invertselection"/> + </Menu> +</Menu> + <Menu name="view"><text>&View</text> + <Action name="show_dot" /> + <Action name="sort_caseinsensitive"/> + <Menu name="listview_show"><text>Show Details</text> + <TearOffHandle /> + <Action name="show_size"/> + <Action name="show_time"/> + <Action name="show_type"/> + <Action name="show_mimetype"/> + <Action name="show_url"/> + <Action name="show_access_time"/> + <Action name="show_creation_time"/> + <Action name="show_permissions"/> + <Action name="show_owner"/> + <Action name="show_group"/> + <Action name="show_link_dest"/> + </Menu> + <Separator/> + <Action name="bgsettings"/> + </Menu> +</MenuBar> +</kpartgui> diff --git a/konqueror/listview/konq_textviewitem.cc b/konqueror/listview/konq_textviewitem.cc new file mode 100644 index 000000000..1076e10af --- /dev/null +++ b/konqueror/listview/konq_textviewitem.cc @@ -0,0 +1,258 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 <assert.h> +#include <stdio.h> +#include <tdeglobal.h> + +int KonqTextViewItem::compare( TQListViewItem *item, int col, bool ascending ) const +{ + if (col==1) + return KonqBaseListViewItem::compare(item, 0, ascending); + return KonqBaseListViewItem::compare(item, col, ascending); +} + +/*TQString KonqTextViewItem::key( int _column, bool asc) const +{ + if (_column==1) return key(0,asc); + TQString tmp = TQString::number( sortChar ); + //check if it is a time column + if (_column>1) + { + KonqTextViewWidget* lv = static_cast<KonqTextViewWidget *>(listView()); + for (unsigned int i=0; i<lv->NumberOfAtoms; i++) + { + ColumnInfo *cInfo=&lv->columnConfigInfo()[i]; + if (_column==cInfo->displayInColumn) + { + if ((cInfo->udsId==TDEIO::UDS_MODIFICATION_TIME) + || (cInfo->udsId==TDEIO::UDS_ACCESS_TIME) + || (cInfo->udsId==TDEIO::UDS_CREATION_TIME)) + { + tmp += TQString::number( m_fileitem->time(cInfo->udsId) ).rightJustify( 14, '0' ); + return tmp; + } + else if (cInfo->udsId==TDEIO::UDS_SIZE) + { + tmp += TDEIO::number( m_fileitem->size() ).rightJustify( 20, '0' ); + return tmp; + } + else break; + + }; + }; + }; + tmp+=text(_column); + return tmp; +}*/ + +void KonqTextViewItem::updateContents() +{ + TQString tmp; + TDEIO::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<KonqTextViewWidget *>(listView()); + + for (unsigned int i=0; i<lv->NumberOfAtoms; i++) + { + ColumnInfo *tmpColumn=&lv->confColumns[i]; + if (tmpColumn->displayThisOne) + { + switch (tmpColumn->udsId) + { + case TDEIO::UDS_USER: + setText(tmpColumn->displayInColumn,m_fileitem->user()); + break; + case TDEIO::UDS_GROUP: + setText(tmpColumn->displayInColumn,m_fileitem->group()); + break; + case TDEIO::UDS_LINK_DEST: + setText(tmpColumn->displayInColumn,m_fileitem->linkDest()); + break; + case TDEIO::UDS_FILE_TYPE: + if (m_fileitem->isMimeTypeKnown()) { + setText(tmpColumn->displayInColumn,m_fileitem->mimeComment()); + } + break; + case TDEIO::UDS_MIME_TYPE: + if (m_fileitem->isMimeTypeKnown()) { + setText(tmpColumn->displayInColumn,m_fileitem->mimetype()); + } + break; + case TDEIO::UDS_URL: + setText(tmpColumn->displayInColumn,m_fileitem->url().prettyURL()); + break; + case TDEIO::UDS_SIZE: + if ( static_cast<KonqBaseListViewWidget *>(listView())->m_pSettings->fileSizeInBytes() ) + setText(tmpColumn->displayInColumn,TDEGlobal::locale()->formatNumber(size, 0)+" "); + else + setText(tmpColumn->displayInColumn,TDEIO::convertSize(size)+" "); + break; + case TDEIO::UDS_ACCESS: + setText(tmpColumn->displayInColumn,m_fileitem->permissionsString()); + break; + case TDEIO::UDS_MODIFICATION_TIME: + case TDEIO::UDS_ACCESS_TIME: + case TDEIO::UDS_CREATION_TIME: + for( TDEIO::UDSEntry::ConstIterator it = m_fileitem->entry().begin(); it != m_fileitem->entry().end(); it++ ) + { + if ((*it).m_uds==(unsigned int)tmpColumn->udsId) + { + TQDateTime dt; + dt.setTime_t((time_t) (*it).m_long); + setText(tmpColumn->displayInColumn,TDEGlobal::locale()->formatDateTime(dt)); + break; + }; + + }; + break; + default: + break; + }; + }; + }; +} + +void KonqTextViewItem::paintCell( TQPainter *_painter, const TQColorGroup & _cg, int _column, int _width, int _alignment ) +{ + TQColorGroup cg( _cg ); + cg.setColor(TQColorGroup::Text, static_cast<KonqTextViewWidget *>(listView())->colors[type]); + // Don't do that! Keep things readable whatever the selection background color is +// cg.setColor(TQColorGroup::HighlightedText, static_cast<KonqTextViewWidget *>(listView())->highlight[type]); +// cg.setColor(TQColorGroup::Highlight, Qt::darkGray); + + TDEListViewItem::paintCell( _painter, cg, _column, _width, _alignment ); +} + +/*void KonqTextViewItem::paintFocus( TQPainter *_p, const TQColorGroup &_cg, const TQRect &_r ) +{ + listView()->style().drawFocusRect( _p, _r, _cg, + isSelected() ? &_cg.highlight() : &_cg.base(), isSelected() ); + + TQPixmap pix( _r.width(), _r.height() ); + bitBlt( &pix, 0, 0, _p->device(), _r.left(), _r.top(), _r.width(), _r.height() ); + TQImage 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); +} + +void KonqTextViewItem::mimetypeFound() +{ + // Update icon + setDisabled( m_bDisabled ); + uint done = 0; + KonqBaseListViewWidget * lv = m_pListViewWidget; + for (unsigned int i=0; i<m_pListViewWidget->NumberOfAtoms && done < 2; i++) + { + ColumnInfo *tmpColumn=&lv->columnConfigInfo()[i]; + if (lv->columnConfigInfo()[i].udsId==TDEIO::UDS_FILE_TYPE && tmpColumn->displayThisOne) + { + setText(tmpColumn->displayInColumn, m_fileitem->mimeComment()); + done++; + } + if (lv->columnConfigInfo()[i].udsId==TDEIO::UDS_MIME_TYPE && tmpColumn->displayThisOne) + { + setText(tmpColumn->displayInColumn, m_fileitem->mimetype()); + done++; + } + } +}
\ No newline at end of file diff --git a/konqueror/listview/konq_textviewitem.h b/konqueror/listview/konq_textviewitem.h new file mode 100644 index 000000000..57be5a7c3 --- /dev/null +++ b/konqueror/listview/konq_textviewitem.h @@ -0,0 +1,76 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 <tqlistview.h> +#include <tqstring.h> +#include <tdeio/global.h> +#include <tdelocale.h> +#include "konq_listviewitems.h" +#include "konq_textviewwidget.h" + +class KFileItem; +class TQPainter; + +#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: "<<text(1)<<endl;*/ }; + virtual int compare( TQListViewItem* i, int col, bool ascending ) const; +// virtual TQString key( int _column, bool asc) const; + /** Call this before destroying the text view (decreases reference count + * on the view)*/ + virtual void paintCell( TQPainter *_painter, const TQColorGroup & _cg, int _column, int _width, int _alignment ); +// virtual void paintFocus( TQPainter *_painter, const TQColorGroup & _cg, const TQRect & r ); + virtual void mimetypeFound(); + virtual void updateContents(); + + protected: + virtual void setup(); + int type; +}; + +inline KonqTextViewItem::KonqTextViewItem( KonqTextViewWidget *_parent, KFileItem* _fileitem ) +:KonqBaseListViewItem( _parent,_fileitem ) +{ + updateContents(); +} + +#endif diff --git a/konqueror/listview/konq_textviewwidget.cc b/konqueror/listview/konq_textviewwidget.cc new file mode 100644 index 000000000..ab227899a --- /dev/null +++ b/konqueror/listview/konq_textviewwidget.cc @@ -0,0 +1,224 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 <tqheader.h> + +#include <kdebug.h> +#include <kdirlister.h> + +#include <stdlib.h> +#include <assert.h> + + +KonqTextViewWidget::KonqTextViewWidget( KonqListView *parent, TQWidget *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]=TQColor(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 ( TQPtrListIterator<KFileItem> 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() ) { + TQStringList::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 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 TQPoint& 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( TQDragMoveEvent *_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( TQDropEvent *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..06a5cbbb5 --- /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 <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 <kurl.h> + +class KonqListView; +class KonqTextViewItem; + +/** + * The text view + */ +class KonqTextViewWidget : public KonqBaseListViewWidget +{ + friend class KonqTextViewItem; + Q_OBJECT + public: + KonqTextViewWidget( KonqListView *parent, TQWidget *parentWidget ); + ~KonqTextViewWidget(); + virtual bool isExecuteArea( const TQPoint& point ); + + protected slots: + // slots connected to the directory lister + virtual void setComplete(); + virtual void slotNewItems( const KFileItemList & ); + protected: +// bool isNameColumn(const TQPoint& point ); +// virtual void viewportDragMoveEvent( TQDragMoveEvent *_ev ); +// virtual void viewportDropEvent( TQDropEvent *ev ); + virtual void createColumns(); + + TQColor colors[11]; +}; + +#endif diff --git a/konqueror/listview/konq_treeview.desktop b/konqueror/listview/konq_treeview.desktop new file mode 100644 index 000000000..3169cba48 --- /dev/null +++ b/konqueror/listview/konq_treeview.desktop @@ -0,0 +1,89 @@ +[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 +X-TDE-ServiceTypes=KParts/ReadOnlyPart,Browser/View +X-TDE-Library=konq_listview +X-TDE-BrowserView-Args=MixedTree +X-TDE-BrowserView-HideFromMenus=true +X-TDE-BrowserView-HierarchicalView=true +Icon=view_tree +X-TDE-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 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="KonqTreeView" version="10"> +<MenuBar> + <Menu name="edit"><text>&Edit</text> + <Menu name="selection"><text>Selection</text> + <Action name="select"/> + <Action name="unselect"/> + <Separator/> + <Action name="selectall"/> + <Action name="unselectall"/> + <Action name="invertselection"/> + </Menu> + </Menu> + <Menu name="view"><text>&View</text> + <Menu name="iconview_mode"><text>Icon Size</text> + <Action name="modedefault"/> + <Separator/> + <Action name="modeenormous"/> + <Action name="modehuge"/> + <Action name="modelarge"/> + <Action name="modemedium"/> + <Action name="modesmallmedium"/> + <Action name="modesmall"/> + </Menu> + <Separator/> + <Action name="show_dot"/> + <Action name="sort_caseinsensitive"/> + <!--<Action name="sort_directoriesfirst" /> TODO --> + <Menu name="listview_show"><text>Show Details</text> + <TearOffHandle /> + <Action name="show_size"/> + <Action name="show_type"/> + <Action name="show_mimetype"/> + <Action name="show_url"/> + <Action name="show_time"/> + <Action name="show_access_time"/> + <Action name="show_creation_time"/> + <Action name="show_permissions"/> + <Action name="show_owner"/> + <Action name="show_group"/> + <Action name="show_link_dest"/> + </Menu> + <Separator/> + <Action name="bgsettings"/> + </Menu> +</MenuBar> +<ToolBar name="mainToolBar"><text>Treeview Toolbar</text> + <Separator/> + <Action name="incIconSize" /> + <Action name="decIconSize" /> +</ToolBar> +</kpartgui> diff --git a/konqueror/listview/konq_treeviewitem.cc b/konqueror/listview/konq_treeviewitem.cc new file mode 100644 index 000000000..12953c401 --- /dev/null +++ b/konqueror/listview/konq_treeviewitem.cc @@ -0,0 +1,101 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + 2001, 2002, 2004 Michael Brade <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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<KonqTreeViewWidget *>(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 ); + + TQListViewItem* it = firstChild(); + while ( it ) + { + lst.append( static_cast<KonqListViewItem*>(it)->item() ); + it = it->nextSibling(); + } + + // tell the view about the new items to count + treeView->m_pBrowserView->newItems( lst ); + } + } + else + { + treeView->stopListingSubFolder( this ); + + TQListViewItem* 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<KonqListViewItem*>(it)->item(); + treeView->m_pBrowserView->deleteItem( item ); + it = it->nextSibling(); + } + } + + TQListViewItem::setOpen( _open ); + treeView->slotOnViewport(); + } +} + +KURL KonqListViewDir::kurl() +{ + return m_fileitemURL; +} + +TQString KonqListViewDir::url( int _trailing ) +{ + return m_fileitemURL.url( _trailing ); +} + diff --git a/konqueror/listview/konq_treeviewitem.h b/konqueror/listview/konq_treeviewitem.h new file mode 100644 index 000000000..6dcc1bb79 --- /dev/null +++ b/konqueror/listview/konq_treeviewitem.h @@ -0,0 +1,84 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 <tqstring.h> +#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 TQListViewItem). + * 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 + */ + KURL kurl(); + + /** + * URL of this directory + * @param _trailing set to true for a trailing slash (see KURL) + */ + TQString 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..77adc4b61 --- /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 <[email protected]> + 2001, 2002, 2004 Michael Brade <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 <kdirlister.h> +#include <kdebug.h> + +template class TQDict<KonqListViewDir>; + + +KonqTreeViewWidget::KonqTreeViewWidget( KonqListView *parent, TQWidget *parentWidget) + : KonqBaseListViewWidget( parent, parentWidget ) +{ + kdDebug(1202) << "+KonqTreeViewWidget" << endl; + + setRootIsDecorated( true ); + setTreeStepSize( 20 ); + + connect( m_dirLister, TQT_SIGNAL( completed( const KURL & ) ), + this, TQT_SLOT( slotCompleted( const KURL & ) ) ); + connect( m_dirLister, TQT_SIGNAL( clear( const KURL & ) ), + this, TQT_SLOT( slotClear( const KURL & ) ) ); + connect( m_dirLister, TQT_SIGNAL( redirection( const KURL &, const KURL & ) ), + this, TQT_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 ) + { + TQDictIterator<KonqListViewDir> 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( TQDataStream &stream ) +{ + TQStringList openDirList; + + TQDictIterator<KonqListViewDir> 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( TQDataStream &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) + TQDictIterator<KonqListViewDir> 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 + TQListViewItem *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 + TQPtrListIterator<KFileItem> 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( TQString::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() ) { + TQStringList::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 ) + { + TQString 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 ) +{ + TQString 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->kurl(), true /* keep existing data */, _reload ); + slotUpdateBackground(); +} + +void KonqTreeViewWidget::stopListingSubFolder( KonqListViewDir* _dir ) +{ + m_dirLister->stop( _dir->kurl() ); + 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..01b85ddf6 --- /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 <[email protected]> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 <tqdict.h> +#include <kurl.h> +#include <tdelistview.h> + +class KonqListView; + + +class KonqTreeViewWidget : public KonqBaseListViewWidget +{ + friend class KonqListViewDir; + + Q_OBJECT +public: + KonqTreeViewWidget( KonqListView *parent, TQWidget *parentWidget ); + virtual ~KonqTreeViewWidget(); + + virtual bool openURL( const KURL &url ); + + virtual void saveState( TQDataStream &stream ); + virtual void restoreState( TQDataStream &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 TQString &_url ); + + void openSubFolder( KonqListViewDir *_dir, bool _reload ); + void stopListingSubFolder( KonqListViewDir *_dir ); + + // URL -> item (for directories only) + TQDict<KonqListViewDir> m_dictSubDirs; + + TQStringList m_urlsToOpen, m_urlsToReload; +}; + +#endif |