From 7f85319d8a842131c1eddd15d9f44128fe14c49a Mon Sep 17 00:00:00 2001 From: Dima Rogozin Date: Fri, 2 Jul 1999 20:20:51 +0000 Subject: [PATCH] QListView widget is introduced. svn path=/trunk/kdebase/kfind/; revision=24840 --- kfind/kfind.cpp | 2 - kfind/kfindtop.cpp | 4 - kfind/kfwin.cpp | 579 +++++++++++++++++++++++++++++++-------------- kfind/kfwin.h | 30 ++- 4 files changed, 425 insertions(+), 190 deletions(-) diff --git a/kfind/kfind.cpp b/kfind/kfind.cpp index 8ab4ec6a2b..dc36fd437c 100644 --- a/kfind/kfind.cpp +++ b/kfind/kfind.cpp @@ -75,8 +75,6 @@ Kfind::Kfind( QWidget *parent, const char *name, const char *searchPath ) win,SLOT(selectAll())); connect(parentWidget(),SIGNAL(unselectAll()), win,SLOT(unselectAll())); - connect(parentWidget(),SIGNAL(invertSelection()), - win,SLOT(invertSelection())); connect(&findProcess, SIGNAL(processExited(KProcess *)), this, SLOT(stopSearch())); diff --git a/kfind/kfindtop.cpp b/kfind/kfindtop.cpp index ccf9e4be50..8d18e67247 100644 --- a/kfind/kfindtop.cpp +++ b/kfind/kfindtop.cpp @@ -145,15 +145,12 @@ void KfindTop::menuInit() this,SIGNAL(selectAll()) ); editUnselectAll = _editMenu->insertItem(i18n("Unse&lect All"), this,SIGNAL(unselectAll()) ); - editInvertSelection = _editMenu->insertItem(i18n("&Invert Selection"), - this,SIGNAL(invertSelection()) ); _editMenu->setItemEnabled( undo , FALSE ); _editMenu->setItemEnabled( cut , FALSE ); _editMenu->setItemEnabled( editCopy , FALSE ); _editMenu->setItemEnabled( editSelectAll, FALSE ); _editMenu->setItemEnabled( editUnselectAll, FALSE ); - _editMenu->setItemEnabled( editInvertSelection, FALSE ); _optionMenu->insertItem(i18n("&Preferences ..."), this,SLOT(prefs())); @@ -240,7 +237,6 @@ void KfindTop::enableSaveResults(bool enable) _fileMenu->setItemEnabled(saveSearchM, enable); _editMenu->setItemEnabled(editSelectAll, enable); _editMenu->setItemEnabled(editUnselectAll, enable); - _editMenu->setItemEnabled(editInvertSelection, enable); } void KfindTop::enableMenuItems(bool enable) diff --git a/kfind/kfwin.cpp b/kfind/kfwin.cpp index b6c076bf8e..24c35acfb6 100644 --- a/kfind/kfwin.cpp +++ b/kfind/kfwin.cpp @@ -15,78 +15,150 @@ #include #include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include #include #include -#include #include #include #include #include #include -#include +#include +#include +#include #include #include #include #include -#include + +//#include +//#include #include "kfwin.h" #include "kfarch.h" #include "kfsave.h" -#include -#include - -#include - extern KfSaveOptions *saving; extern QList *archivers; +// see comment near use of this variable +static const char * egcsWorkaround = "%x %X"; + +// Permission strings +static QString perm[4] = { + QString(i18n( "Read-write" )), + QString(i18n( "Read-only" )), + QString(i18n( "Write-only" )), + QString(i18n( "Inaccessible" )) }; +#define RW 0 +#define RO 1 +#define WO 2 +#define NA 3 + +KfFileLVI::KfFileLVI(QListView* lv, QString file) + : QListViewItem(lv) +{ + fileInfo = new QFileInfo(file); + + QString size = QString("%1").arg(fileInfo->size()); + + // This code is copyed from QT qfiledialog.cpp + QDateTime epoch; + epoch.setTime_t( 0 ); + char date[256]; + time_t t1 = epoch.secsTo( fileInfo->lastModified() ); + struct tm * t2 = ::localtime( &t1 ); + // use a static const char here, so that egcs will not see + // the formatting string and give an incorrect warning. + if ( t2 && strftime( date, 255, egcsWorkaround, t2 ) <= 0 ) + strcpy(date, "????"); + // + + int perm_index; + if(fileInfo->isReadable()) + perm_index = fileInfo->isWritable() ? RW : RO; + else + perm_index = fileInfo->isWritable() ? WO : NA; + + // Fill the item with data + setText(0, fileInfo->fileName()); + setText(1, fileInfo->dir().path()); + setText(2, size); + setText(3, date); + setText(4, perm[perm_index]); +} + +KfFileLVI::~KfFileLVI() { + delete fileInfo; +} + +QString KfFileLVI::key(int column, bool) const +{ + // Returns time in secs from 1/1/1980. Used for sorting + if(column == 3) { + QDateTime epoch( QDate( 1980, 1, 1 ) ); + return QString().sprintf("%08d", epoch.secsTo(fileInfo->lastModified())); + } + + return text(column); +} + KfindWindow::KfindWindow( QWidget *parent, const char *name ) - : QListBox( parent, name ) - { - // topLevelWidget()->installEventFilter(lbx); - setMultiSelection(FALSE); + : QListView( parent, name ) +{ + // topLevelWidget()->installEventFilter(lbx); + setMultiSelection(TRUE); - connect(this , SIGNAL(highlighted(int)), - this, SLOT(highlighted()) ); - connect(this, SIGNAL(selected(int)), - this, SLOT( openBinding()) ); - }; + addColumn(i18n("Name")); + addColumn(i18n("In directory")); + addColumn(i18n("Size")); + setColumnAlignment(2, AlignRight); + addColumn(i18n("Modified")); + setColumnAlignment(3, AlignRight); + addColumn(i18n("Permissions")); + setColumnAlignment(4, AlignRight); -KfindWindow::~KfindWindow() -{} + // Disable autoresize for all columns + // Resizing is done by resetColumns() function + for(int i=0; i<5; i++) + setColumnWidthMode(i, Manual); + + /* TODO + connect(this, SIGNAL(rightButtonPressed(QListViewItem *, const QPoint &, int)), + this, SLOT(rightButtonPressed(QListViewItem *, const QPoint &, int))); + */ + + connect(this, SIGNAL(doubleClicked(QListViewItem *)), + this, SLOT(openBinding())); +} -void KfindWindow::beginSearch() { +void KfindWindow::beginSearch() +{ + haveSelection = false; + clear(); - + + resetColumns(); + startTimer(100); QString str = i18n("%1 file(s) found").arg(0); emit statusChanged(str.ascii()); } -void KfindWindow::endSearch() { +void KfindWindow::endSearch() +{ killTimers(); - QString str = i18n("%1 file(s) found").arg(count()); + QString str = i18n("%1 file(s) found").arg(childCount()); emit statusChanged(str.ascii()); } -void KfindWindow::timerEvent(QTimerEvent *) { - if(count() > 0) { - QString str = i18n("%1 file(s) found").arg(count()); +void KfindWindow::timerEvent(QTimerEvent *) +{ + if(childCount() > 0) { + QString str = i18n("%1 file(s) found").arg(childCount()); emit statusChanged(str.ascii()); } } @@ -96,9 +168,11 @@ void KfindWindow::timerEvent(QTimerEvent *) { #endif void KfindWindow::updateResults(const char *file ) - { +{ kdebug(KDEBUG_INFO, 1902, "UPDATERESULTs\n"); - + + printf("UPDATE\n"); + char str[PATH_MAX]; int count; @@ -132,8 +206,8 @@ void KfindWindow::updateResults(const char *file ) if (!(filename->exists())) strl->removeLast(); - insertStrList(strl,-1); - QString statusmsg = i18n("%1 file(s) found").arg(count); + // insertStrList(strl,-1); + QString statusmsg = i18n("%1 file(s) found").arg(childCount()); emit statusChanged(statusmsg.ascii()); unlink( file ); @@ -142,15 +216,23 @@ void KfindWindow::updateResults(const char *file ) delete strl; }; +void KfindWindow::insertItem(QString file) { + new KfFileLVI(this, file); +} + // copy to clipboard aka X11 selection -void KfindWindow::copySelection() { +void KfindWindow::copySelection() +{ QString s; - for(int i = 0; i < (int)count(); i++) - if(isSelected(i)) { - s.append(text(i)); + QListViewItem *item = firstChild(); + while(item != NULL) { + if(isSelected(item)) { + s.append(((KfFileLVI*)item)->fileInfo->absFilePath()); s.append(" "); } - + item = item->nextSibling(); + } + if(s.length() > 0) { QClipboard *cb = kapp->clipboard(); cb->clear(); @@ -159,105 +241,140 @@ void KfindWindow::copySelection() { } void KfindWindow::changeItem(const char */*itemName*/) - { - debug("CXHANGE ITEM CALLED\n"); - // changeItem(itemName,currentItem()); - }; - -void KfindWindow::selectAll() { - setAutoUpdate(FALSE); - for(int i = 0; i < (int)count(); i++) - setSelected(i, TRUE); - setAutoUpdate(TRUE); - repaint(); +{ + debug("CXHANGE ITEM CALLED\n"); + // changeItem(itemName,currentItem()); } -void KfindWindow::invertSelection() { - setAutoUpdate(FALSE); - for(int i = 0; i < (int)count(); i++) - setSelected(i, !isSelected(i)); - setAutoUpdate(TRUE); - repaint(); +void KfindWindow::selectAll() +{ + QListViewItem *item = firstChild(); + while(item != NULL) { + setSelected(item, TRUE); + item = item->nextSibling(); + } } -void KfindWindow::unselectAll() { - setAutoUpdate(FALSE); - for(int i = 0; i < (int)count(); i++) - setSelected(i, FALSE); - setAutoUpdate(TRUE); - repaint(); +void KfindWindow::unselectAll() +{ + QListViewItem *item = firstChild(); + while(item != NULL) { + setSelected(item, FALSE); + item = item->nextSibling(); + } } void KfindWindow::saveResults() { - uint items,item; - FILE *results; - QString filename; - - if ( saving->getSaveStandard() ) - { - filename = getenv("HOME"); - filename += "/.kfind-results.html"; + QListViewItem *item; + FILE *results; + QString filename; + + if ( saving->getSaveStandard() ) { + filename = getenv("HOME"); + filename += "/.kfind-results.html"; + } + else + filename = saving->getSaveFile(); + + results=fopen(filename.ascii(),"w"); + + if (results == 0L) + QMessageBox::warning(parentWidget(),i18n("Error"), + i18n("It wasn't possible to save results!"), + i18n("OK")); + else { + if ( saving->getSaveFormat() == "HTML" ) { + fprintf(results,"\n"); + fprintf(results,"\n", + i18n("KFind Results File").ascii()); + fprintf(results,"%sKFind Results File\n", + i18n("KFind Results File").ascii()); + fprintf(results,"

%s

\n", + i18n("KFind Results File").ascii()); + fprintf(results,"

\n"); + + item = firstChild(); + while(item != NULL) { + QString path=((KfFileLVI*)item)->fileInfo->absFilePath(); + fprintf(results,"

file:%s\n", + path.ascii(), path.ascii()); + item = item->nextSibling(); } - else - filename = saving->getSaveFile(); + fprintf(results,"

\n"); + } + else { + item = firstChild(); + while(item != NULL) { + QString path=((KfFileLVI*)item)->fileInfo->absFilePath(); + fprintf(results,"%s\n", path.ascii()); + item = item->nextSibling(); + } + } - results=fopen(filename.ascii(),"w"); + fclose(results); + QMessageBox::information(parentWidget(), + i18n("Information"), + i18n("Results were saved to file\n")+ + filename, + i18n("OK")); + } +} - items=count(); - if (results==0L) - QMessageBox::warning(parentWidget(),i18n("Error"), - i18n("It wasn't possible to save results!"), - i18n("OK")); - else - { - if ( saving->getSaveFormat() == "HTML" ) - { - fprintf(results,"\n"); - fprintf(results,"\n", - i18n("KFind Results File").ascii()); - fprintf(results,"%sKFind Results File\n", - i18n("KFind Results File").ascii()); - fprintf(results,"

%s

\n", - i18n("KFind Results File").ascii()); - fprintf(results,"

\n"); - - item=0; - while(item!=items) - { - fprintf(results,"

file:%s\n", - text(item).ascii(),text(item).ascii()); - item++; - }; - fprintf(results,"

\n"); - } - else - { - item=0; - while(item!=items) - { - fprintf(results,"%s\n", text(item).ascii()); - item++; - }; - - }; - fclose(results); - QMessageBox::information(parentWidget(), - i18n("Information"), - i18n("Results were saved to file\n")+ - filename, - i18n("OK")); - }; - }; +// This function is called when selection is changed (both selected/deselected) +// It notifies the parent about selection status and enables/disables menubar +void KfindWindow::selectionChanged(bool selectionMade) +{ + if(selectionMade) { + if(!haveSelection) { + haveSelection = true; + emit resultSelected(true); + } + } + else { + // If user made deselection we want to check if any items left selected. + // If no items are selected disable menubar. + QListViewItem *item = firstChild(); + while(item != NULL) { + if(isSelected(item)) + break; + item = item->nextSibling(); + } + + // Item equal to NULL means we do not have any selection + if(item == NULL) { + haveSelection = false; + emit resultSelected(false); + } + } +} -void KfindWindow::highlighted() - { - emit resultSelected(true); - }; +// Currently disabled +void KfindWindow::rightButtonPressed(QListViewItem */*ci*/, + const QPoint &/*pos*/, int) { + /* + QStringList urls; + QListViewItem *item = firstChild(); + while(item != NULL) { + if(isSelected(item)) { + urls.append("file:" + ((KfFileLVI*)item)->fileInfo->absFilePath()); + } + item = item->nextSibling(); + } + KonqPopupMenu popup(urls, + 0, + "file:" + ((KfFileLVI*)ci)->fileInfo->absFilePath(), + FALSE, + FALSE, + FALSE); + popup.exec(pos); + */ +} +// Currently disables. Should work using KonqPopupMenu(). void KfindWindow::deleteFiles() { - QString tmp = i18n("Do you really want to delete file:\n%1") + /* QString tmp = i18n("Do you really want to delete file:\n%1") .arg(text(currentItem())); if (!QMessageBox::information(parentWidget(), i18n("Delete File - Find Files"), @@ -323,44 +440,41 @@ void KfindWindow::deleteFiles() delete file; }; + */ }; void KfindWindow::fileProperties() - { - QString tmp= "file:"; - - QFileInfo *fileInfo = new QFileInfo(text(currentItem())); - if (fileInfo->isDir()) - tmp.append(fileInfo->filePath()); - else - tmp.append(text(currentItem())); - (void) new PropertiesDialog(tmp); - }; +{ + QString tmp= "file:"; + QFileInfo *fileInfo = ((KfFileLVI *)currentItem())->fileInfo; + if (fileInfo->isDir()) + tmp += fileInfo->filePath(); + else + tmp += fileInfo->absFilePath(); + (void) new PropertiesDialog(tmp); +} void KfindWindow::openFolder() - { - QString tmp; +{ + QString tmp= "file:"; + QFileInfo *fileInfo = ((KfFileLVI *)currentItem())->fileInfo; + if (fileInfo->isDir()) + tmp += fileInfo->filePath(); + else + tmp += fileInfo->dirPath(); + (void) new KRun(tmp); +} - QFileInfo *fileInfo = new QFileInfo(text(currentItem())); - if (fileInfo->isDir()) - tmp = "file:" + fileInfo->filePath(); - else - tmp = "file:" + fileInfo->dirPath(); - - (void) new KRun(tmp); - }; - -void KfindWindow::openBinding() - { - QString tmp= "file:"; - - QFileInfo *fileInfo = new QFileInfo(text(currentItem())); - if (fileInfo->isDir()) - tmp.append(fileInfo->filePath()); - else - tmp.append(text(currentItem())); - (void) new KRun( tmp ); - }; +void KfindWindow::openBinding() +{ + QString tmp= "file:"; + QFileInfo *fileInfo = ((KfFileLVI*)currentItem())->fileInfo; + if (fileInfo->isDir()) + tmp += fileInfo->filePath(); + else + tmp += fileInfo->absFilePath(); + (void) new KRun( tmp ); +} void KfindWindow::addToArchive() { @@ -384,12 +498,11 @@ void KfindWindow::addToArchive() execAddToArchive(arch,filename); else QMessageBox::warning(parentWidget(),i18n("Error"), - i18n("Couldn't recognize archive type!"), - i18n("OK")); + i18n("Couldn't recognize archive type!"), + i18n("OK")); +} -}; - -void KfindWindow::execAddToArchive(KfArchiver *arch,QString archname) +void KfindWindow::execAddToArchive(KfArchiver *arch, QString archname) { QFileInfo archiv(archname); QString buffer,pom; @@ -416,33 +529,143 @@ void KfindWindow::execAddToArchive(KfArchiver *arch,QString archname) { pos = buffer.find(" "); pom = buffer.left(pos); - if ( pom=="%d" ) { - QFileInfo *fileInfo = new QFileInfo(text(currentItem())); + QFileInfo *fileInfo = ((KfFileLVI*)currentItem())->fileInfo; pom = fileInfo->dirPath(TRUE)+'/'; - }; - + } + if ( pom=="%a" ) pom = archname; if ( pom=="%f" ) - pom = text(currentItem()); - + pom = ((KfFileLVI*)currentItem())->fileInfo->absFilePath();; + if ( pom=="%n" ) { - QFileInfo *fileInfo = new QFileInfo(text(currentItem())); + QFileInfo *fileInfo = ((KfFileLVI*)currentItem())->fileInfo; pom = fileInfo->fileName(); - }; - + } + archProcess << pom; - + if (pos==-1) pos = buffer.length(); buffer = buffer.remove(0,pos+1); - }; - + } + if ( !archProcess.start(KProcess::DontCare) ) warning(i18n("Error while creating child process!").ascii()); -}; +} +// Resizes QListView to ocuppy all space +void KfindWindow::resizeEvent(QResizeEvent *e) { + resetColumns(); + QListView::resizeEvent(e); +} + +// The following to functions are an attemp to implement MS-like selection +// (Control/Shift style). Not very elegant. + +void KfindWindow::contentsMousePressEvent(QMouseEvent *e) { + + QListViewItem *item = itemAt(contentsToViewport(e->pos())); + if(item == NULL) { // Just in case. Should not happen + QListView::contentsMousePressEvent(e); + return; + } + + // We want to execute QListView::contentsMousePressEvent(e), but + // we do not want it to change selection and current item. + // To do it we store current item and make the item we click on unselectable. + // We restore all this after the contentsMousePressEvent() call + QListViewItem *anchor; + if(e->state() & ShiftButton) + anchor = currentItem(); + item->setSelectable(FALSE); + + QListView::contentsMousePressEvent(e); + + item->setSelectable(TRUE); + if(e->state() & ShiftButton) + setCurrentItem(anchor); + + // No analize what we got and make our selections + + // No modifiers + if(!(e->state() & ControlButton) && + !(e->state() & ShiftButton)) { + clearSelection(); + setSelected(item, TRUE); + selectionChanged(TRUE); + return; + } + + // Control + if(e->state() & ControlButton) { + setSelected(item, !isSelected(item)); + selectionChanged(isSelected(item)); + return; + } + + // Shift + if(e->state() & ShiftButton) { + bool down = itemPos(currentItem()) < itemPos(item); + + // Selects area from the current item to our item + QListViewItem *i = currentItem(); + if(down) { + while(i != item) { + setSelected(i, TRUE); + i = i->itemBelow(); + } + } + else { + while(i != item) { + setSelected(i, TRUE); + i = i->itemAbove(); + } + } + setSelected(item, TRUE); + } +} + +void KfindWindow::contentsMouseReleaseEvent(QMouseEvent *e) { + + QListViewItem *item = itemAt(contentsToViewport(e->pos())); + if(item == NULL) { // Just in case. Should not happen + QListView::contentsMouseReleaseEvent(e); + return; + } + + // See comment for the contentsMousePressEvent() function. + // We just want to disable any selection/current item changes. + QListViewItem *anchor; + if(e->state() & ShiftButton) + anchor = currentItem(); + item->setSelectable(FALSE); + + QListView::contentsMouseReleaseEvent(e); + + item->setSelectable(TRUE); + if(e->state() & ShiftButton) + setCurrentItem(anchor); +} + +void KfindWindow::resetColumns() { + + + QFontMetrics fm = fontMetrics(); + int perm_w = fm.width(perm[RO]) + 15; + int size_w = fm.width("0000000") + 15; + int mod_w = fm.width("00/00/00 00:00:00") + 15; + int free_space = width() - perm_w - size_w - mod_w; + int name_w = (int)(free_space*0.3); // 30% + int dir_w = free_space - name_w; // 70% + + setColumnWidth(0, name_w); + setColumnWidth(1, dir_w); + setColumnWidth(2, size_w); + setColumnWidth(3, mod_w); + setColumnWidth(4, perm_w); +} diff --git a/kfind/kfwin.h b/kfind/kfwin.h index 41e49fddc7..0269d96ba1 100644 --- a/kfind/kfwin.h +++ b/kfind/kfwin.h @@ -7,16 +7,27 @@ #ifndef KFWIN_H #define KFWIN_H -#include +#include class KfArchiver; +class QFileInfo; -class KfindWindow: public QListBox +class KfFileLVI : public QListViewItem +{ + public: + KfFileLVI(QListView* lv, QString file); + ~KfFileLVI(); + + QString key(int column, bool) const; + + QFileInfo *fileInfo; +}; + +class KfindWindow: public QListView { Q_OBJECT public: KfindWindow( QWidget * parent = 0, const char * name = 0 ); - virtual ~KfindWindow(); virtual void timerEvent(QTimerEvent *); @@ -27,13 +38,14 @@ public: void copySelection(); + void insertItem(QString str); + public slots: void selectAll(); void unselectAll(); - void invertSelection(); private slots: - void highlighted(); + void rightButtonPressed(QListViewItem *, const QPoint &, int); void deleteFiles(); void fileProperties(); void openFolder(); @@ -43,13 +55,19 @@ private slots: void openBinding(); protected: + void resizeEvent(QResizeEvent *e); + void contentsMouseReleaseEvent(QMouseEvent *e); + void contentsMousePressEvent(QMouseEvent *e); signals: void resultSelected(bool); void statusChanged(const char *); private: - void execAddToArchive(KfArchiver *arch,QString filename); + bool haveSelection; + void execAddToArchive(KfArchiver *arch, QString filename); + void resetColumns(); + void selectionChanged(bool selectionMade); }; #endif