/*************************************************************************** cfileslist.cpp - description ------------------- begin : Tue Sep 17 2002 copyright : (C) 2002-2005 by Serghei Amelian email : serghei.amelian@gmail.com ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "cfileslist.h" #include #include #include #include #include #include #include #include #include #include #include #if(defined BDB || defined GDBM) #include "caliasesdatabase.h" #include "alias.h" #include #include extern CAliasesDatabase *db; extern QLabel *sender; #endif #include "../pix/image.img" #include "../pix/image_new.img" #include "../pix/folder.img" #include "../pix/folder_red.img" #include "../pix/trash.img" CFileListItem::CFileListItem(const QString &file, FileType type, QListView *parent, bool recent) : QListViewItem(parent), type(type), recent(recent) { QPixmap pix; p = (CFilesList*)parent; setText(0, file); isReadable = true; if(type == Folder) { QFileInfo fi(file); if(fi.isReadable()) pix.loadFromData(folder_png, len_folder_png); else { pix.loadFromData(folder_red_png, len_folder_red_png); isReadable = false; } setPixmap(0, pix); return; } else if(type == File) { if(recent) pix.loadFromData(image_new_png, len_image_new_png); else pix.loadFromData(image_png, len_image_png); } setPixmap(0, pix); TIFF *tif = TIFFOpen(file.utf8(), "r"); if(tif) { char *_sender; if(TIFFGetField(tif, TIFFTAG_IMAGEDESCRIPTION, &_sender)) { id = QString(_sender).section('\n', 0, 0); cidName = QString(_sender).section('\n', 1, 1); cidNumber = QString(_sender).section('\n', 2, 2); } else { id = QString::null; cidName = QString::null; cidNumber = QString::null; } #if(defined BDB || defined GDBM) replaceIdWithRealName(); #else sender = id; #endif // (defined BDB || defined GDBM) char *_time; if(TIFFGetField(tif, TIFFTAG_DATETIME, &_time)) time = _time; TIFFClose(tif); QFileInfo f(file); int _size = f.size(); size = QString::number(_size / 1024); } showFields(); } void CFileListItem::showFields() { if(p->colSender) setText(p->colSender, sender); if(p->colCidName) setText(p->colCidName, cidName); if(p->colCidNumber) setText(p->colCidNumber, cidNumber); if(p->colTime) setText(p->colTime, time); if(p->colSize) setText(p->colSize, size + "K"); } QString CFileListItem::key(int column, bool) const { if(column == 3) return QString::number(type) + size.rightJustify(10, '0'); else return QString::number(type) + text(column); } void CFileListItem::setRecent(bool recent) { QPixmap pix; if(recent) pix.loadFromData(image_new_png, len_image_new_png); else pix.loadFromData(image_png, len_image_png); setPixmap(0, pix); } void CFileListItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment) { QListViewItem::paintCell(p, cg, column, width, alignment); // if(parentList->enabledGrid) { p->setPen(QColor(0xAA, 0xAA, 0xAA)); p->drawLine(width - 1, 0, width - 1, height()); p->drawLine(0, height() - 1, width - 1, height() - 1); } } #if(defined BDB || defined GDBM) void CFileListItem::replaceIdWithRealName() { QString realName = 0; if(db->isOK && !id.isNull()) realName = db->get(id); sender = realName ? realName : id; } #endif // (defined BDB || defined GDBM) CFilesList::CFilesList(QWidget *parent, const char *name) : QListView(parent,name), autoRefreshTime(0), autoRefreshActive(false), hand(false) { setAllColumnsShowFocus(true); setShowSortIndicator (true); addColumn(tr("File")); colSender = colTime = colSize = 0; connect(this, SIGNAL(clicked(QListViewItem*)), this, SLOT(action(QListViewItem*))); connect(this, SIGNAL(returnPressed(QListViewItem*)), this, SLOT(action(QListViewItem*))); connect(this, SIGNAL(spacePressed(QListViewItem*)), this, SLOT(action(QListViewItem*))); connect(&timer, SIGNAL(timeout()), this, SLOT(refresh())); connect(this, SIGNAL(contextMenuRequested(QListViewItem *, const QPoint &, int)), this, SLOT(contextMenu(QListViewItem *, const QPoint &, int))); } CFilesList::~CFilesList() { } void CFilesList::load() { QApplication::setOverrideCursor(waitCursor); stopTimer(); clear(); emit changePath(QDir::current().path()); { QDir path; path.setFilter(QDir::Dirs); const QFileInfoList *list = path.entryInfoList(); // directories QFileInfoListIterator it( *list ); QFileInfo *fi; ++it; ++it; while((fi = it.current()) != 0) { new CFileListItem(fi->fileName(), Folder, this); ++it; } } // files { QDir path; path.setFilter(QDir::Files); path.setNameFilter("*.tiff *.tif *.TIF *.TIFF"); const QFileInfoList *list = path.entryInfoList(); // check new files QFileInfoListIterator it( *list ); QFileInfo *fi; while((fi = it.current()) != 0) { if(fi->isReadable()) new CFileListItem(fi->fileName(), File, this); ++it; } } QListViewItem *item = firstChild(); if(item) { setSelected(item, true); } QApplication::restoreOverrideCursor(); startTimer(); } void CFilesList::refresh() { QApplication::setOverrideCursor(waitCursor); stopTimer(); CFileListItem *newFile = 0; { QDir path; path.setFilter(QDir::Dirs); const QFileInfoList *list = path.entryInfoList(); // check new directories { QFileInfoListIterator it( *list ); QFileInfo *fi; ++it; ++it; while((fi = it.current()) != 0) { if(!findItem(fi->fileName(), 0)) new CFileListItem(fi->fileName(), Folder, this); ++it; } } // check removed directories { QListViewItem *item = firstChild(); while(item) { if(((CFileListItem*)item)->type != Folder) { item = item->nextSibling(); continue; } bool found = false; QFileInfoListIterator it( *list ); QFileInfo *fi; while((fi = it.current()) != 0 && !found) { found = (item->text(0) == fi->fileName()); ++it; } if(!found) { QListViewItem *itemForDelete = item; item = item->nextSibling(); delete itemForDelete; } else { item = item->nextSibling(); } } } } { QDir path; path.setFilter(QDir::Files); path.setNameFilter("*.tiff *.tif *.TIF *.TIFF"); const QFileInfoList *list = path.entryInfoList(); // check new files { QFileInfoListIterator it( *list ); QFileInfo *fi; while((fi = it.current()) != 0) { if(fi->isReadable() && !findItem(fi->fileName(), 0)) { if(!newFile) newFile = new CFileListItem(fi->fileName(), File, this, true); else new CFileListItem(fi->fileName(), File, this, true); } ++it; } } // check removed files { QListViewItem *item = firstChild(); while(item) { if(((CFileListItem*)item)->type != File) { item = item->nextSibling(); continue; } bool found = false; QFileInfoListIterator it( *list ); QFileInfo *fi; while((fi = it.current()) != 0 && !found) { found = (item->text(0) == fi->fileName() && fi->isReadable()); ++it; } if(!found) { QListViewItem *itemForDelete = item; item = item->nextSibling(); delete itemForDelete; } else { item = item->nextSibling(); } } } } QApplication::restoreOverrideCursor(); if(newFile) { setCurrentItem(newFile); QMessageBox::information(this, tr("QFaxReader Notification"), tr("You have received a new facsimile.")); } startTimer(); } void CFilesList::action(QListViewItem *item) { if(!item) return; if(!((CFileListItem*)item)->isReadable) return; if(((CFileListItem*)item)->type == Folder) { QDir::setCurrent(item->text(0)); load(); } else if(((CFileListItem*)item)->type == File) { emit open(item->text(0)); if(((CFileListItem*)item)->recent) ((CFileListItem*)item)->setRecent(false); } } void CFilesList::up() { QString dir = QDir::current().canonicalPath(); dir = dir.mid(dir.findRev('/') + 1); if(!dir.stripWhiteSpace().length()) return; QDir::setCurrent(".."); load(); for(CFileListItem *item = (CFileListItem*)firstChild(); item != 0; item = (CFileListItem*)item->nextSibling()) if(item->type == Folder && item->text(0) == dir) { setCurrentItem(item); setSelected(item, true); ensureItemVisible(item); return; } } void CFilesList::startTimer() { stopTimer(); if(autoRefreshActive) timer.start(autoRefreshTime * 60000, true); } void CFilesList::stopTimer() { if(timer.isActive()) timer.stop(); } // CONTEXT MENU void CFilesList::contextMenu(QListViewItem * item, const QPoint & pos, int) { if(!item) return; QPopupMenu popup(this); QPixmap pix; pix.loadFromData(trash_png, len_trash_png); popup.insertItem(pix, tr("&Delete"), this, SLOT(deleteFacsimile())); popup.insertItem(tr("&Rename"), this, SLOT(renameFacsimile())); #if(defined BDB || defined GDBM) popup.insertSeparator(); popup.insertItem(tr("&Alias"), this, SLOT(alias()), 0, 1); if(((CFileListItem*)item)->type == Folder || !db->isOK) popup.setItemEnabled(1, false); #endif // (defined BDB || defined GDBM) popup.exec(pos); } void CFilesList::deleteFacsimile() { CFileListItem *item = (CFileListItem*)currentItem(); if(!item) return; QString msg = tr("Do you really want to delete") + " " + QString(item->text(0)) + ""; if(item->type == File) msg.append("\n" + tr("received from") + " " + QString(item->text(1)) + ""); if(0 == QMessageBox::warning(0, item->type == Folder ? tr("Delete directory") : tr("Delete facsimile"), msg + "?", tr("Yes"), tr("No"), 0, 0, 1)) { QDir dir; bool ok; if(item->type == File) ok = dir.remove(item->text(0)); else ok = dir.rmdir(item->text(0)); if(ok) { delete item; item = (CFileListItem*)currentItem(); if(item) { item->setSelected(true); if(item->type == File) emit open(item->text(0)); else emit signalClose(); } else emit signalClose(); } else QMessageBox::information(0, tr("Information"), tr("Deleting failed.\nDetails: ") + QString(strerror(errno)) + "."); } } void CFilesList::renameFacsimile() { CFileListItem *item = (CFileListItem*)currentItem(); if(!item) return; QString oldName = item->text(0); bool ok; QString newName = QInputDialog::getText("Rename", tr("Type new filename for facsimile"), QLineEdit::Normal, oldName, &ok, this); // try to guess if the user was typed extension QString ext = newName.section('.', -1); if(0 == ext.length() || 4 < ext.length() || -1 == ext.find('.')) newName.append(".tif"); if(ok && !newName.isEmpty() && oldName != newName) { QDir dir; if(!dir.exists(newName)) if(dir.rename(oldName, newName)) { item->setText(0, newName); refresh(); } else QMessageBox::information(0, tr("Information"), tr("Renaming failed.\nDetails: ") + QString(strerror(errno)) + "."); else QMessageBox::information(0, tr("Information"), tr("Renaming failed.\nDetails: ") + newName + tr(" already exists.")); } } void CFilesList::alias() { #if(defined BDB || defined GDBM) CFileListItem *item = (CFileListItem*)currentItem(); if(!item) return; if(item->id.isEmpty()) { QMessageBox::information(this, tr("QFaxReader Alias"), tr("Sender of this facsimile is unknown.")); return; } uiAlias dialog; dialog.setMaximumSize(dialog.size()); dialog.setMinimumSize(dialog.size()); dialog.id->setText(item->id); dialog.realName->setText(db->get(item->id)); dialog.realName->setFocus(); dialog.realName->selectAll(); if(dialog.exec()) { if(dialog.realName->text().length()) // if length realName > 0, store { if(db->store(dialog.id->text(), dialog.realName->text())) { if(::sender->text().length()) ::sender->setText(tr("Sender: ") + dialog.realName->text()); reReadAliases(); } else QMessageBox::warning(0, tr("Warning"), tr("Storing alias is failed.\nDetails: ") + QString(strerror(errno))); } else // if length realName == 0, delete { if(db->drop(dialog.id->text())) { if(::sender->text().length()) ::sender->setText(tr("Sender: ") + dialog.id->text()); reReadAliases(); } else QMessageBox::warning(0, tr("Warning"), tr("Delete alias is failed.\nDetails: ") + QString(strerror(errno))); } } #endif // (defined BDB || defined GDBM) } void CFilesList::reReadAliases() { #if(defined BDB || defined GDBM) for(CFileListItem *item = (CFileListItem*)firstChild(); item != 0; item = (CFileListItem*)item->nextSibling()) if(item->type == File) item->replaceIdWithRealName(); #endif // (defined BDB || defined GDBM) } void CFilesList::applyColumnsOptions(bool sender, bool cidName, bool cidNumber, bool time, bool size) { bool modify = (sender != (bool)colSender) || (cidName != (bool)colCidName) || (cidNumber != (bool)colCidNumber) || (time != (bool)colTime) || (size != (bool)colSize); if(!modify) return; int col = 1; colSender = (sender ? col++ : 0); colCidName = (cidName ? col++ : 0); colCidNumber = (cidNumber ? col++ : 0); colTime = (time ? col++ : 0); colSize = (size ? col++ : 0); if(col > columns()) for(int i = columns(); i < col; i++) addColumn(0); else for(int i = columns() - 1; i >= col; i--) removeColumn(i); if(sender) { setColumnText(colSender, tr("Sender")); } if(cidName) { setColumnText(colCidName, tr("CID Name")); } if(cidNumber) { setColumnText(colCidNumber, tr("CID Number")); } if(time) { setColumnText(colTime, tr("Time")); } if(size) { setColumnText(colSize, tr("Size")); } for(CFileListItem *item = (CFileListItem*)firstChild(); item != 0; item = (CFileListItem*)item->nextSibling()) if(item->type == File) item->showFields(); } void CFilesList::keyPressEvent(QKeyEvent *e) { if(e->key() == Key_Backspace) up(); else QListView::keyPressEvent(e); } void CFilesList::contentsMouseMoveEvent(QMouseEvent *e) { bool item = (NULL != itemAt(contentsToViewport(e->pos()))); if(item && !hand) { viewport()->setCursor(QCursor::PointingHandCursor); hand = true; } else if(!item && hand) { viewport()->unsetCursor(); hand = false; } }