📄 kfilesimpleview.cpp
字号:
// -*- c++ -*-/* This file is part of the KDE libraries Copyright (C) 1997 Stephan Kulow <coolo@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/#include "kdir.h"#include <qpixmap.h>#include "kfilesimpleview.h"#include "qkeycode.h"#include <qpainter.h>#include <kapp.h>#include "config-kfile.h"KFileSimpleView::KFileSimpleView(bool s, QDir::SortSpec sorting, QWidget *parent, const char *name) : QTableView(parent, name), KFileInfoContents(s,sorting), cellWidths(0){ QWidget::setFocusPolicy(QWidget::StrongFocus); width_max = 100; width_length = 0; width_array = new uint[width_max]; setLineWidth( 2 ); setFrameStyle( Panel | Sunken ); cellWidths = new int[1]; cellWidths[0] = -1; rowsVisible = 1; setCellHeight( fontMetrics().lineSpacing() + 5); setCellWidth(0); setTableFlags(Tbl_autoHScrollBar | Tbl_cutCellsV | Tbl_smoothHScrolling | Tbl_snapToGrid ); curCol = curRow = 0; // QTableView::setNumCols(0); QTableView::setNumRows(1); setBackgroundMode( PaletteBase ); touched = false;}KFileSimpleView::~KFileSimpleView(){ delete [] cellWidths; delete [] width_array;}void KFileSimpleView::setNumCols(int count){ debugC("setNumCols %d", count); delete [] cellWidths; cellWidths = new int[count]; for (int i = 0; i < count; i++) cellWidths[i] = -1; QTableView::setNumCols(count);}void KFileSimpleView::setAutoUpdate(bool f){ QTableView::setAutoUpdate(f);}void KFileSimpleView::highlightItem(unsigned int i){ debugC("highlightItem %d", i); int col = i / rowsVisible; highlightItem( i - rowsVisible * col, col );}void KFileSimpleView::highlightItem(int row, int col){ debugC("highlightItem %d %d", row, col); if ( row < 0 || col < 0 ) return; if (col * rowsVisible + row >= static_cast<int>(count())) return; bool oneColOnly = leftCell() == lastColVisible(); int cx; if (!colXPos ( col , &cx )) cx = 0; int edge = leftCell(); // find left edge if ( col < edge || cx < 0) { edge = edge - curCol + col; if (edge < 0) edge = 0; setLeftCell( edge ); } edge = lastColVisible(); if ( col > edge ) { if ( !oneColOnly ) setLeftCell( leftCell() + col - edge + 1 ); else setLeftCell( col ); } edge = topCell(); if ( row < edge ) { setTopCell( edge - 1 ); } edge = lastRowVisible(); if ( row >= edge ) { if ( !oneColOnly ) setTopCell( topCell() + 1 ); } // make sure, selected column is completely visible while ( col > leftCell() && !isColCompletelyVisible( col ) ) { setLeftCell( leftCell()+1 ); } if (curCol != static_cast<int>(col) || curRow != static_cast<int>(row)) { int oldRow = curRow; int oldCol = curCol; curCol = col; curRow = row; updateCell( oldRow, oldCol); updateCell( row, col ); }}bool KFileSimpleView::isColCompletelyVisible( int col ){ if ( !colIsVisible(col) ) // out of visible area return false; else if ( col < lastColVisible() ) // visible and not last column return true; else { // last column, may be clipped int tableWidth = 0; for ( int i = leftCell(); i <= lastColVisible(); i++ ) { tableWidth += cellWidth( i ); } return ( viewWidth() >= tableWidth ); }}void KFileSimpleView::clearView(){ setNumCols(1); pixmaps.clear(); curCol = curRow = hasFocus() ? 0 : -1; width_length = 0;}void KFileSimpleView::paintCell( QPainter *p, int row, int col){ uint index = col * rowsVisible + row; int w = cellWidth( col ); // width of cell in pixels int h = cellHeight( row ); // height of cell in pixels int x2 = w - 1; int y2 = h - 1; if ( (row == curRow) && (col == curCol) ) { // if we are on current cell, if ( hasFocus() ) { p->fillRect(0, 0, x2, y2, kapp->selectColor); p->setPen( kapp->selectTextColor ); } else { // no focus => draw only a dashed line around current item p->setPen( DotLine ); // used dashed line to p->drawRect( 0, 0, x2, y2 ); // draw rect along cell edges p->setPen( SolidLine ); // restore to normal p->setPen( kapp->windowTextColor ); } } else // not on current cell, use the normal color p->setPen( kapp->windowTextColor ); if (index < count()) { p->drawPixmap(0, 1, *pixmaps.at(index)); p->drawText(3 + pixmaps.at(index)->width(), 15, text(index)); }}void KFileSimpleView::keyPressEvent( QKeyEvent* e ){ int newRow = curRow; // store previous current cell int newCol = curCol; int oldRow = curRow; int oldCol = curCol; int lastItem = 0; int jump = 0; bool oneColOnly = leftCell() == lastColVisible(); // do nothing, when there are no entries if ( count() == 0 ) return; // if user scrolled current item out of view via scrollbar and then // tries to scroll via keyboard, make item visible before going on if ( !colIsVisible( curCol ) ) { setLeftCell( curCol ); } switch( e->key() ) { // Look at the key code case Key_Left: if( newCol > 0 ) newCol--; else newRow = 0; break; case Key_Right: // Correspondingly... if( newCol < numCols()-1 ) newCol++; else newRow = (count() % numRows()) - 1; if (newCol * rowsVisible + oldRow >= static_cast<int>(count())) newRow = count() - rowsVisible * newCol - 1; break; case Key_Up: if( newRow >= 0 ) { newRow--; if (newRow == -1) if (newCol == 0) newRow = 0; else { newRow = rowsVisible - 1; newCol--; } } break; case Key_Down: if( newRow <= numRows()-1 ) { newRow++; if (newRow >= numRows() && curCol < numCols()-1) { newRow = 0; newCol++; } } break; case Key_Home: newRow = 0; newCol = 0; break; case Key_End: newRow = count() % numRows() - 1; // calc last item in last col newCol = numCols() - 1; break; case Key_PageUp: if ( oneColOnly ) jump = 1; else jump = lastColVisible() - leftCell(); // num of cols we want to jump if ( curCol - jump < 0 ) { newRow = 0; newCol = 0; } else newCol = curCol - jump; if ( curCol == newCol ) newRow = 0; break; case Key_PageDown: if ( oneColOnly ) jump = 1; else jump = lastColVisible() - leftCell(); lastItem = count() % numRows() - 1; // last item in last col if ( curCol + jump >= numCols() ) { // too far, just go to last col newCol = numCols() - 1; newRow = lastItem; } else { newCol += jump; if ( newCol == numCols()-1 && curRow > lastItem ) newRow = lastItem; else if ( curCol == newCol ) newRow = lastItem; else newRow = curRow; } break; case Key_Enter: case Key_Return: select( curCol * rowsVisible + curRow ); return; break; default: { if ((e->ascii() >= 'a' && e->ascii() <= 'z') || (e->ascii() >= 'A' && e->ascii() <= 'Z')) { char tmp[2] = " "; tmp[0] = e->ascii(); QString res = findCompletion(tmp); if (!res.isNull()) debugC("found %s",res.data()); } else e->ignore(); } return; } // newRow may be -1 when the last column is completely filled with entries // and the user tries to go rightwards (End, RightArrow, PageDown) // the last entry shall be selected, then (numRows()-1) if ( newRow < 0 ) newRow = numRows() - 1; if ( newCol >= numCols() ) newCol = numCols() -1; highlightItem( newRow, newCol ); if ( curRow != oldRow || curCol != oldCol ) highlight( curRow + curCol * rowsVisible );}bool KFileSimpleView::insertItem(const KFileInfo *i, int index){ if (index == -1) // -1 = append to the end index = pixmaps.count(); if (numCols() * rowsVisible < static_cast<int>(count())) setNumCols(numCols() + 1); if (i->isDir()) { if (i->isReadable()) pixmaps.insert(index, folder_pixmap); else pixmaps.insert(index, locked_folder); } else { if (i->isReadable()) pixmaps.insert(index, file_pixmap); else pixmaps.insert(index, locked_file); } int curCol = index / rowsVisible; for (int j = curCol; j < numCols(); j++) cellWidths[ j ] = -1; // reset values uint size = fontMetrics().width( i->fileName() ); insertArray(size, index); return colIsVisible(curCol) || curCol < leftCell() ;}int KFileSimpleView::cellWidth ( int col ){ if (cellWidths[col] == -1) { // debugC("not cached %d", col); int offset = col * rowsVisible; int width = 100; for (int j = 0; offset + j < static_cast<int>(width_length) && j < rowsVisible; j++) { int w = width_array[offset + j]; if (width < w) width = w; } cellWidths[col] = width + file_pixmap->width() + 9; } // debugC("cellWidth %d %d", col, cellWidths[col]); return cellWidths[col];}void KFileSimpleView::resizeEvent ( QResizeEvent *e ){ int index = curCol * rowsVisible + curRow; if ( index < 0 ) index = 0; QTableView::resizeEvent(e); rowsVisible = viewHeight() / cellHeight(); if (!rowIsVisible(rowsVisible)) rowsVisible--; int cols; if (rowsVisible <= 0) rowsVisible = 1; setNumRows(rowsVisible); cols = count() / rowsVisible + 1; if ( static_cast<int>(count()) <= rowsVisible * (cols-1) && cols >= 1) cols--; // if last col is completely filled, we calc'ed 1 col too much setNumCols(cols); QTableView::repaint(true); highlightItem( index );}void KFileSimpleView::mousePressEvent( QMouseEvent* e ){ int oldRow = curRow; // store previous current cell int oldCol = curCol; QPoint clickedPos = e->pos(); // extract pointer position curRow = findRow( clickedPos.y() ); // map to row; set current cell if (curRow > static_cast<int>(rowsVisible)) curRow = rowsVisible; curCol = findCol( clickedPos.x() ); // map to col; set current cell uint index = curCol * rowsVisible + curRow; if ( index >= count()) { curCol = oldCol; curRow = oldRow; return; } if ( (curRow != oldRow) // if current cell has moved, || (curCol != oldCol) ) { updateCell( oldRow, oldCol ); // erase previous marking updateCell( curRow, curCol ); // show new current cell } if ( useSingle() && isDir(index)) select( index ); else highlight( index );}void KFileSimpleView::mouseDoubleClickEvent ( QMouseEvent *e ){ int oldRow = curRow; int oldCol = curCol; QPoint clickedPos = e->pos(); curRow = findRow( clickedPos.y() ); if (curRow > static_cast<int>(rowsVisible)) curRow = rowsVisible; curCol = findCol( clickedPos.x() ); uint index = curCol * rowsVisible + curRow; if ( index >= count()) { curCol = oldCol; curRow = oldRow; return; } if ( (curRow != oldRow) || (curCol != oldCol) ) { updateCell( oldRow, oldCol ); updateCell( curRow, curCol ); } select( index );}void KFileSimpleView::focusInEvent ( QFocusEvent * ){ if (curRow < 0 || curCol < 0) curRow = curCol = 0; updateCell( curRow, curCol );}void KFileSimpleView::focusOutEvent ( QFocusEvent * ){ updateCell( curRow, curCol );}void KFileSimpleView::insertArray(uint item, uint pos){ // debug("insert %s %d", item->fileName(), pos); if (width_length == width_max) { width_max *= 2; uint *newArray = new uint[width_max]; int found = 0; for (uint j = 0; j < width_length; j++) { if (j == pos) { found = 1; newArray[j] = item; } newArray[j+found] = width_array[j]; } if (!found) newArray[pos] = item; delete [] width_array; width_array = newArray; width_length++; return; } // faster repositioning (very fast :) memmove(width_array + pos+1, width_array + pos, (width_max - 1 - pos) * sizeof(uint)); width_array[pos] = item; width_length++;}#include "kfilesimpleview.moc"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -