Changeset 13866
- Timestamp:
- Jan 25, 2013, 6:37:11 PM (8 years ago)
- Location:
- trunk/qt
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/qt/file-tree.cc
r13849 r13866 31 31 enum 32 32 { 33 34 35 36 37 33 COL_NAME, 34 COL_PROGRESS, 35 COL_WANTED, 36 COL_PRIORITY, 37 NUM_COLUMNS 38 38 }; 39 39 … … 45 45 FileTreeItem :: getMyChildRows() 46 46 { 47 const size_t n = childCount();48 49 50 while( myFirstUnhashedRow < n)47 const size_t n = childCount(); 48 49 // ensure that all the rows are hashed 50 while (myFirstUnhashedRow < n) 51 51 { 52 52 myChildRows.insert (myChildren[myFirstUnhashedRow]->name(), myFirstUnhashedRow); … … 54 54 } 55 55 56 57 } 58 59 60 FileTreeItem :: ~FileTreeItem( 61 { 62 assert( myChildren.isEmpty( ));63 64 if( myParent != 0)65 { 66 const int pos = row();67 68 myParent->myChildren.removeAt( pos);69 myParent->myChildRows.remove( name());70 71 } 72 } 73 74 void 75 FileTreeItem :: appendChild ( FileTreeItem * child)76 { 77 78 79 80 56 return myChildRows; 57 } 58 59 60 FileTreeItem :: ~FileTreeItem() 61 { 62 assert(myChildren.isEmpty()); 63 64 if (myParent != 0) 65 { 66 const int pos = row(); 67 assert ((pos>=0) && "couldn't find child in parent's lookup"); 68 myParent->myChildren.removeAt(pos); 69 myParent->myChildRows.remove(name()); 70 myParent->myFirstUnhashedRow = pos; 71 } 72 } 73 74 void 75 FileTreeItem :: appendChild (FileTreeItem * child) 76 { 77 const size_t n = childCount(); 78 child->myParent = this; 79 myChildren.append (child); 80 myFirstUnhashedRow = n; 81 81 } 82 82 83 83 FileTreeItem * 84 FileTreeItem :: child (const QString& filename 84 FileTreeItem :: child (const QString& filename) 85 85 { 86 86 FileTreeItem * item(0); … … 97 97 98 98 int 99 FileTreeItem :: row( 100 { 101 102 103 if( myParent)104 { 105 106 107 } 108 109 99 FileTreeItem :: row() const 100 { 101 int i(-1); 102 103 if(myParent) 104 { 105 i = myParent->getMyChildRows().value (name(), -1); 106 assert (this == myParent->myChildren[i]); 107 } 108 109 return i; 110 110 } 111 111 … … 122 122 else if (role == Qt::DisplayRole) 123 123 { 124 switch( column)124 switch(column) 125 125 { 126 126 case COL_NAME: … … 146 146 147 147 void 148 FileTreeItem :: getSubtreeSize ( uint64_t& have, uint64_t& total) const149 { 150 151 152 153 foreach( const FileTreeItem * i, myChildren)154 i->getSubtreeSize( have, total);148 FileTreeItem :: getSubtreeSize (uint64_t& have, uint64_t& total) const 149 { 150 have += myHaveSize; 151 total += myTotalSize; 152 153 foreach(const FileTreeItem * i, myChildren) 154 i->getSubtreeSize(have, total); 155 155 } 156 156 157 157 double 158 FileTreeItem :: progress( ) const 159 { 160 double d(0); 161 uint64_t have(0), total(0); 162 getSubtreeSize( have, total ); 163 if( total ) 164 d = have / (double)total; 165 return d; 158 FileTreeItem :: progress () const 159 { 160 double d(0); 161 uint64_t have(0), total(0); 162 163 getSubtreeSize(have, total); 164 if (total) 165 d = have / (double)total; 166 167 return d; 166 168 } 167 169 168 170 QString 169 FileTreeItem :: fileSizeName () const170 { 171 172 173 getSubtreeSize( have, total);174 str = QString( name() + " (%1)" ).arg( Formatter::sizeToString( total ));175 171 FileTreeItem :: fileSizeName () const 172 { 173 uint64_t have(0), total(0); 174 QString str; 175 getSubtreeSize(have, total); 176 str = QString(name() + " (%1)").arg(Formatter::sizeToString(total)); 177 return str; 176 178 } 177 179 178 180 bool 179 FileTreeItem :: update( int index, bool wanted, int priority, uint64_t totalSize, uint64_t haveSize, bool torrentChanged ) 180 { 181 bool changed = false; 182 183 if( myIndex != index ) 184 { 185 myIndex = index; 186 changed = true; 187 } 188 if( torrentChanged && myIsWanted != wanted ) 189 { 190 myIsWanted = wanted; 191 changed = true; 192 } 193 if( torrentChanged && myPriority != priority ) 194 { 195 myPriority = priority; 196 changed = true; 197 } 198 if( myTotalSize != totalSize ) 199 { 200 myTotalSize = totalSize; 201 changed = true; 202 } 203 if( myHaveSize != haveSize ) 204 { 205 myHaveSize = haveSize; 206 changed = true; 207 } 208 209 return changed; 181 FileTreeItem :: update (int index, 182 bool wanted, 183 int priority, 184 uint64_t totalSize, 185 uint64_t haveSize, 186 bool torrentChanged) 187 { 188 bool changed = false; 189 190 if (myIndex != index) 191 { 192 myIndex = index; 193 changed = true; 194 } 195 196 if (torrentChanged && myIsWanted != wanted) 197 { 198 myIsWanted = wanted; 199 changed = true; 200 } 201 202 if (torrentChanged && myPriority != priority) 203 { 204 myPriority = priority; 205 changed = true; 206 } 207 208 if (myTotalSize != totalSize) 209 { 210 myTotalSize = totalSize; 211 changed = true; 212 } 213 214 if (myHaveSize != haveSize) 215 { 216 myHaveSize = haveSize; 217 changed = true; 218 } 219 220 return changed; 210 221 } 211 222 212 223 QString 213 FileTreeItem :: priorityString () const214 { 215 const int i( priority( ));216 if( i == LOW ) return tr( "Low");217 if( i == HIGH ) return tr( "High");218 if( i == NORMAL ) return tr( "Normal");219 return tr( "Mixed");224 FileTreeItem :: priorityString () const 225 { 226 const int i(priority()); 227 if(i == LOW) return tr("Low"); 228 if(i == HIGH) return tr("High"); 229 if(i == NORMAL) return tr("Normal"); 230 return tr("Mixed"); 220 231 } 221 232 222 233 int 223 FileTreeItem :: priority( ) const 224 { 225 int i( 0 ); 226 227 if( myChildren.isEmpty( ) ) switch( myPriority ) { 228 case TR_PRI_LOW: i |= LOW; break; 229 case TR_PRI_HIGH: i |= HIGH; break; 230 default: i |= NORMAL; break; 231 } 232 233 foreach( const FileTreeItem * child, myChildren ) 234 i |= child->priority( ); 235 236 return i; 237 } 238 239 void 240 FileTreeItem :: setSubtreePriority( int i, QSet<int>& ids ) 241 { 242 if( myPriority != i ) { 243 myPriority = i; 244 if( myIndex >= 0 ) 245 ids.insert( myIndex ); 246 } 247 248 foreach( FileTreeItem * child, myChildren ) 249 child->setSubtreePriority( i, ids ); 250 } 251 252 void 253 FileTreeItem :: twiddlePriority( QSet<int>& ids, int& p ) 254 { 255 const int old( priority( ) ); 256 257 if ( old & LOW ) p = TR_PRI_NORMAL; 258 else if( old & NORMAL ) p = TR_PRI_HIGH; 259 else p = TR_PRI_LOW; 260 261 setSubtreePriority( p, ids ); 234 FileTreeItem :: priority () const 235 { 236 int i(0); 237 238 if(myChildren.isEmpty()) switch(myPriority) 239 { 240 case TR_PRI_LOW: 241 i |= LOW; 242 break; 243 244 case TR_PRI_HIGH: 245 i |= HIGH; 246 break; 247 248 default: 249 i |= NORMAL; 250 break; 251 } 252 253 foreach(const FileTreeItem * child, myChildren) 254 i |= child->priority(); 255 256 return i; 257 } 258 259 void 260 FileTreeItem :: setSubtreePriority (int i, QSet<int>& ids) 261 { 262 if (myPriority != i) 263 { 264 myPriority = i; 265 266 if (myIndex >= 0) 267 ids.insert (myIndex); 268 } 269 270 foreach (FileTreeItem * child, myChildren) 271 child->setSubtreePriority (i, ids); 272 } 273 274 void 275 FileTreeItem :: twiddlePriority (QSet<int>& ids, int& p) 276 { 277 const int old(priority()); 278 279 if (old & LOW) 280 p = TR_PRI_NORMAL; 281 else if (old & NORMAL) 282 p = TR_PRI_HIGH; 283 else 284 p = TR_PRI_LOW; 285 286 setSubtreePriority (p, ids); 262 287 } 263 288 264 289 int 265 FileTreeItem :: isSubtreeWanted( ) const 266 { 267 if( myChildren.isEmpty( ) ) 268 return myIsWanted ? Qt::Checked : Qt::Unchecked; 269 270 int wanted( -1 ); 271 foreach( const FileTreeItem * child, myChildren ) { 272 const int childWanted = child->isSubtreeWanted( ); 273 if( wanted == -1 ) 274 wanted = childWanted; 275 if( wanted != childWanted ) 276 wanted = Qt::PartiallyChecked; 277 if( wanted == Qt::PartiallyChecked ) 278 return wanted; 279 } 280 281 return wanted; 282 } 283 284 void 285 FileTreeItem :: setSubtreeWanted( bool b, QSet<int>& ids ) 286 { 287 if( myIsWanted != b ) { 288 myIsWanted = b; 289 if( myIndex >= 0 ) 290 ids.insert( myIndex ); 291 } 292 293 foreach( FileTreeItem * child, myChildren ) 294 child->setSubtreeWanted( b, ids ); 295 } 296 297 void 298 FileTreeItem :: twiddleWanted( QSet<int>& ids, bool& wanted ) 299 { 300 wanted = isSubtreeWanted( ) != Qt::Checked; 301 setSubtreeWanted( wanted, ids ); 290 FileTreeItem :: isSubtreeWanted () const 291 { 292 if(myChildren.isEmpty()) 293 return myIsWanted ? Qt::Checked : Qt::Unchecked; 294 295 int wanted(-1); 296 foreach (const FileTreeItem * child, myChildren) 297 { 298 const int childWanted = child->isSubtreeWanted(); 299 300 if(wanted == -1) 301 wanted = childWanted; 302 303 if(wanted != childWanted) 304 wanted = Qt::PartiallyChecked; 305 306 if(wanted == Qt::PartiallyChecked) 307 return wanted; 308 } 309 310 return wanted; 311 } 312 313 void 314 FileTreeItem :: setSubtreeWanted (bool b, QSet<int>& ids) 315 { 316 if(myIsWanted != b) 317 { 318 myIsWanted = b; 319 320 if (myIndex >= 0) 321 ids.insert(myIndex); 322 } 323 324 foreach (FileTreeItem * child, myChildren) 325 child->setSubtreeWanted (b, ids); 326 } 327 328 void 329 FileTreeItem :: twiddleWanted (QSet<int>& ids, bool& wanted) 330 { 331 wanted = isSubtreeWanted() != Qt::Checked; 332 setSubtreeWanted (wanted, ids); 302 333 } 303 334 … … 307 338 ***/ 308 339 309 FileTreeModel :: FileTreeModel ( QObject *parent):310 311 { 312 rootItem = new FileTreeItem( -1);313 } 314 315 FileTreeModel :: ~FileTreeModel( 316 { 317 clear();318 319 340 FileTreeModel :: FileTreeModel (QObject *parent): 341 QAbstractItemModel(parent) 342 { 343 rootItem = new FileTreeItem(-1); 344 } 345 346 FileTreeModel :: ~FileTreeModel() 347 { 348 clear(); 349 350 delete rootItem; 320 351 } 321 352 322 353 QVariant 323 FileTreeModel :: data ( const QModelIndex &index, int role) const324 { 325 326 327 328 329 330 331 332 333 354 FileTreeModel :: data (const QModelIndex &index, int role) const 355 { 356 QVariant value; 357 358 if (index.isValid()) 359 { 360 FileTreeItem * i = static_cast<FileTreeItem*>(index.internalPointer()); 361 value = i->data (index.column(), role); 362 } 363 364 return value; 334 365 } 335 366 336 367 Qt::ItemFlags 337 FileTreeModel :: flags ( const QModelIndex& index) const338 { 339 int i( Qt::ItemIsSelectable | Qt::ItemIsEnabled);340 341 if( index.column( ) == COL_NAME)342 343 344 if( index.column( ) == COL_WANTED)345 346 347 368 FileTreeModel :: flags (const QModelIndex& index) const 369 { 370 int i(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 371 372 if(index.column() == COL_NAME) 373 i |= Qt::ItemIsEditable; 374 375 if(index.column() == COL_WANTED) 376 i |= Qt::ItemIsUserCheckable | Qt::ItemIsTristate; 377 378 return (Qt::ItemFlags)i; 348 379 } 349 380 … … 373 404 374 405 QVariant 375 FileTreeModel :: headerData( int column, Qt::Orientation orientation, int role ) const 376 { 377 QVariant data; 378 379 if( orientation==Qt::Horizontal && role==Qt::DisplayRole ) { 380 switch( column ) { 381 case COL_NAME: data.setValue( tr( "File" ) ); break; 382 case COL_PROGRESS: data.setValue( tr( "Progress" ) ); break; 383 case COL_WANTED: data.setValue( tr( "Download" ) ); break; 384 case COL_PRIORITY: data.setValue( tr( "Priority" ) ); break; 385 default: break; 386 } 387 } 388 389 return data; 406 FileTreeModel :: headerData(int column, Qt::Orientation orientation, int role) const 407 { 408 QVariant data; 409 410 if(orientation==Qt::Horizontal && role==Qt::DisplayRole) 411 { 412 switch (column) 413 { 414 case COL_NAME: 415 data.setValue (tr("File")); 416 break; 417 418 case COL_PROGRESS: 419 data.setValue (tr("Progress")); 420 break; 421 422 case COL_WANTED: 423 data.setValue (tr("Download")); 424 break; 425 426 case COL_PRIORITY: 427 data.setValue (tr("Priority")); 428 break; 429 430 default: 431 break; 432 } 433 } 434 435 return data; 390 436 } 391 437 392 438 QModelIndex 393 FileTreeModel :: index( int row, int column, const QModelIndex& parent ) const 394 { 395 QModelIndex i; 396 397 if( !hasIndex( row, column, parent ) ) 398 { 399 std::cerr << " I don't have this index " << std::endl; 400 } 401 else 402 { 403 FileTreeItem * parentItem; 404 405 if( !parent.isValid( ) ) 406 parentItem = rootItem; 407 else 408 parentItem = static_cast<FileTreeItem*>(parent.internalPointer()); 409 410 FileTreeItem * childItem = parentItem->child( row ); 411 412 if( childItem ) 413 i = createIndex( row, column, childItem ); 414 415 //std::cerr << "FileTreeModel::index(row("<<row<<"),col("<<column<<"),parent("<<qPrintable(parentItem->name())<<")) is returning " << qPrintable(childItem->name()) << ": internalPointer " << i.internalPointer() << " row " << i.row() << " col " << i.column() << std::endl; 439 FileTreeModel :: index (int row, int column, const QModelIndex& parent) const 440 { 441 QModelIndex i; 442 443 if (!hasIndex (row, column, parent)) 444 { 445 std::cerr << " I don't have this index " << std::endl; 446 } 447 else 448 { 449 FileTreeItem * parentItem; 450 451 if(!parent.isValid()) 452 parentItem = rootItem; 453 else 454 parentItem = static_cast<FileTreeItem*>(parent.internalPointer()); 455 456 FileTreeItem * childItem = parentItem->child(row); 457 458 if (childItem) 459 i = createIndex(row, column, childItem); 416 460 } 417 461 … … 420 464 421 465 QModelIndex 422 FileTreeModel :: parent ( const QModelIndex& child) const423 { 424 return parent( child, 0); // QAbstractItemModel::parent() wants col 0466 FileTreeModel :: parent (const QModelIndex& child) const 467 { 468 return parent (child, 0); // QAbstractItemModel::parent() wants col 0 425 469 } 426 470 427 471 QModelIndex 428 FileTreeModel :: parent ( const QModelIndex& child, int column) const429 { 430 if( !child.isValid( ))431 return QModelIndex();432 433 434 435 return indexOf( childItem->parent( ), column);472 FileTreeModel :: parent (const QModelIndex& child, int column) const 473 { 474 if (!child.isValid()) 475 return QModelIndex(); 476 477 FileTreeItem * childItem = static_cast<FileTreeItem*>(child.internalPointer()); 478 479 return indexOf (childItem->parent(), column); 436 480 } 437 481 438 482 int 439 FileTreeModel :: rowCount ( const QModelIndex& parent) const440 { 441 442 443 if( !parent.isValid( ))444 445 446 447 448 483 FileTreeModel :: rowCount (const QModelIndex& parent) const 484 { 485 FileTreeItem * parentItem; 486 487 if (!parent.isValid()) 488 parentItem = rootItem; 489 else 490 parentItem = static_cast<FileTreeItem*>(parent.internalPointer()); 491 492 return parentItem->childCount(); 449 493 } 450 494 451 495 int 452 FileTreeModel :: columnCount ( const QModelIndex &parent) const453 { 454 Q_UNUSED( parent);455 456 496 FileTreeModel :: columnCount (const QModelIndex &parent) const 497 { 498 Q_UNUSED(parent); 499 500 return 4; 457 501 } 458 502 459 503 QModelIndex 460 FileTreeModel :: indexOf ( FileTreeItem * item, int column) const461 { 462 if( !item || item==rootItem)463 return QModelIndex();464 465 return createIndex( item->row( ), column, item);466 } 467 468 void 469 FileTreeModel :: clearSubtree ( const QModelIndex& top)470 { 471 size_t i = rowCount( top);472 473 while( i > 0)474 clearSubtree( index( --i, 0, top ));504 FileTreeModel :: indexOf (FileTreeItem * item, int column) const 505 { 506 if (!item || item==rootItem) 507 return QModelIndex(); 508 509 return createIndex(item->row(), column, item); 510 } 511 512 void 513 FileTreeModel :: clearSubtree (const QModelIndex& top) 514 { 515 size_t i = rowCount (top); 516 517 while (i > 0) 518 clearSubtree(index(--i, 0, top)); 475 519 476 520 delete static_cast<FileTreeItem*>(top.internalPointer()); … … 478 522 479 523 void 480 FileTreeModel :: clear ()481 { 482 clearSubtree( QModelIndex( ));483 484 reset();485 } 486 487 void 488 FileTreeModel :: addFile (int index,524 FileTreeModel :: clear () 525 { 526 clearSubtree (QModelIndex()); 527 528 reset (); 529 } 530 531 void 532 FileTreeModel :: addFile (int index, 489 533 const QString & filename, 490 534 bool wanted, … … 493 537 uint64_t have, 494 538 QList<QModelIndex> & rowsAdded, 495 bool torrentChanged ) 496 { 497 FileTreeItem * i( rootItem ); 498 499 foreach( QString token, filename.split( QChar::fromAscii('/') ) ) 500 { 501 FileTreeItem * child( i->child( token ) ); 502 if( !child ) 503 { 504 QModelIndex parentIndex( indexOf( i, 0 ) ); 505 const int n( i->childCount( ) ); 506 beginInsertRows( parentIndex, n, n ); 507 i->appendChild(( child = new FileTreeItem( -1, token ))); 508 endInsertRows( ); 509 rowsAdded.append( indexOf( child, 0 ) ); 510 } 511 i = child; 512 } 513 514 if( i != rootItem ) 515 if( i->update( index, wanted, priority, size, have, torrentChanged ) ) 516 dataChanged( indexOf( i, 0 ), indexOf( i, NUM_COLUMNS-1 ) ); 517 } 518 519 void 520 FileTreeModel :: parentsChanged( const QModelIndex& index, int column ) 521 { 522 QModelIndex walk = index; 523 524 for( ;; ) { 525 walk = parent( walk, column ); 526 if( !walk.isValid( ) ) 527 break; 528 dataChanged( walk, walk ); 529 } 530 } 531 532 void 533 FileTreeModel :: subtreeChanged( const QModelIndex& index, int column ) 534 { 535 const int childCount = rowCount( index ); 536 if( !childCount ) 537 return; 538 539 // tell everyone that this tier changed 540 dataChanged( index.child(0,column), index.child(childCount-1,column) ); 541 542 // walk the subtiers 543 for( int i=0; i<childCount; ++i ) 544 subtreeChanged( index.child(i,column), column ); 545 } 546 547 void 548 FileTreeModel :: clicked( const QModelIndex& index ) 549 { 550 const int column( index.column( ) ); 551 552 if( !index.isValid( ) ) 553 return; 554 555 if( column == COL_WANTED ) 556 { 557 FileTreeItem * item( static_cast<FileTreeItem*>(index.internalPointer())); 558 bool want; 559 QSet<int> fileIds; 560 item->twiddleWanted( fileIds, want ); 561 emit wantedChanged( fileIds, want ); 562 563 dataChanged( index, index ); 564 parentsChanged( index, column ); 565 subtreeChanged( index, column ); 566 } 567 else if( column == COL_PRIORITY ) 568 { 569 FileTreeItem * item( static_cast<FileTreeItem*>(index.internalPointer())); 570 int priority; 571 QSet<int>fileIds; 572 item->twiddlePriority( fileIds, priority ); 573 emit priorityChanged( fileIds, priority ); 574 575 dataChanged( index, index ); 576 parentsChanged( index, column ); 577 subtreeChanged( index, column ); 539 bool torrentChanged) 540 { 541 FileTreeItem * i(rootItem); 542 543 foreach (QString token, filename.split(QChar::fromAscii('/'))) 544 { 545 FileTreeItem * child(i->child(token)); 546 if (!child) 547 { 548 QModelIndex parentIndex (indexOf(i, 0)); 549 const int n (i->childCount()); 550 beginInsertRows (parentIndex, n, n); 551 i->appendChild ((child = new FileTreeItem(-1, token))); 552 endInsertRows (); 553 rowsAdded.append (indexOf(child, 0)); 554 } 555 i = child; 556 } 557 558 if (i != rootItem) 559 if (i->update (index, wanted, priority, size, have, torrentChanged)) 560 dataChanged (indexOf(i, 0), indexOf(i, NUM_COLUMNS-1)); 561 } 562 563 void 564 FileTreeModel :: parentsChanged (const QModelIndex& index, int column) 565 { 566 QModelIndex walk = index; 567 568 for (;;) 569 { 570 walk = parent(walk, column); 571 if(!walk.isValid()) 572 break; 573 574 dataChanged(walk, walk); 575 } 576 } 577 578 void 579 FileTreeModel :: subtreeChanged (const QModelIndex& index, int column) 580 { 581 const int childCount = rowCount (index); 582 if (!childCount) 583 return; 584 585 // tell everyone that this tier changed 586 dataChanged (index.child(0,column), index.child(childCount-1,column)); 587 588 // walk the subtiers 589 for (int i=0; i<childCount; ++i) 590 subtreeChanged (index.child(i,column), column); 591 } 592 593 void 594 FileTreeModel :: clicked (const QModelIndex& index) 595 { 596 const int column (index.column()); 597 598 if (!index.isValid()) 599 return; 600 601 if (column == COL_WANTED) 602 { 603 bool want; 604 QSet<int> file_ids; 605 FileTreeItem * item; 606 607 item = static_cast<FileTreeItem*>(index.internalPointer()); 608 item->twiddleWanted (file_ids, want); 609 emit wantedChanged (file_ids, want); 610 611 dataChanged (index, index); 612 parentsChanged (index, column); 613 subtreeChanged (index, column); 614 } 615 else if (column == COL_PRIORITY) 616 { 617 int priority; 618 QSet<int> file_ids; 619 FileTreeItem * item; 620 621 item = static_cast<FileTreeItem*>(index.internalPointer()); 622 item->twiddlePriority (file_ids, priority); 623 emit priorityChanged (file_ids, priority); 624 625 dataChanged(index, index); 626 parentsChanged(index, column); 627 subtreeChanged(index, column); 578 628 } 579 629 } … … 584 634 585 635 QSize 586 FileTreeDelegate :: sizeHint( const QStyleOptionViewItem& item, const QModelIndex& index ) const 587 { 588 QSize size; 589 590 switch( index.column( ) ) 591 { 592 case COL_NAME: { 593 const QFontMetrics fm( item.font ); 594 const QString text = index.data().toString(); 595 const int iconSize = QApplication::style()->pixelMetric( QStyle::PM_SmallIconSize ); 596 size.rwidth() = HIG::PAD_SMALL + iconSize; 597 size.rheight() = std::max( iconSize, fm.height( ) ); 598 break; 599 } 600 601 case COL_PROGRESS: 602 case COL_WANTED: 603 size = QSize( 20, 1 ); 604 break; 605 606 default: { 607 const QFontMetrics fm( item.font ); 608 const QString text = index.data().toString(); 609 size = fm.size( 0, text ); 610 break; 611 } 612 } 613 614 size.rheight() += 8; // make the spacing a little nicer 615 return size; 616 } 617 618 void 619 FileTreeDelegate :: paint( QPainter * painter, 636 FileTreeDelegate :: sizeHint(const QStyleOptionViewItem& item, const QModelIndex& index) const 637 { 638 QSize size; 639 640 switch(index.column()) 641 { 642 case COL_NAME: 643 { 644 const QFontMetrics fm(item.font); 645 const QString text = index.data().toString(); 646 const int iconSize = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize); 647 size.rwidth() = HIG::PAD_SMALL + iconSize; 648 size.rheight() = std::max(iconSize, fm.height()); 649 break; 650 } 651 652 case COL_PROGRESS: 653 case COL_WANTED: 654 size = QSize(20, 1); 655 break; 656 657 default: 658 { 659 const QFontMetrics fm(item.font); 660 const QString text = index.data().toString(); 661 size = fm.size(0, text); 662 break; 663 } 664 } 665 666 size.rheight() += 8; // make the spacing a little nicer 667 return size; 668 } 669 670 void 671 FileTreeDelegate :: paint (QPainter * painter, 620 672 const QStyleOptionViewItem & option, 621 const QModelIndex & index ) const 622 { 623 const int column( index.column( ) ); 624 625 if( ( column != COL_PROGRESS ) && ( column != COL_WANTED ) && ( column != COL_NAME ) ) 626 { 627 QItemDelegate::paint(painter, option, index); 628 return; 629 } 630 631 QStyle * style( QApplication :: style( ) ); 632 if( option.state & QStyle::State_Selected ) 633 painter->fillRect( option.rect, option.palette.highlight( ) ); 634 painter->save(); 635 if( option.state & QStyle::State_Selected ) 636 painter->setBrush(option.palette.highlightedText()); 637 638 if( column == COL_NAME ) 639 { 640 // draw the file icon 641 static const int iconSize( style->pixelMetric( QStyle :: PM_SmallIconSize ) ); 642 const QRect iconArea( option.rect.x(), 643 option.rect.y() + (option.rect.height()-iconSize)/2, 644 iconSize, iconSize ); 645 QIcon icon; 646 if( index.model()->hasChildren( index ) ) 647 icon = style->standardIcon( QStyle::StandardPixmap( QStyle::SP_DirOpenIcon ) ); 648 else 649 { 650 QString name = index.data().toString(); 651 icon = Utils :: guessMimeIcon( name.left( name.lastIndexOf( " (" ) ) ); 652 } 653 icon.paint( painter, iconArea, Qt::AlignCenter, QIcon::Normal, QIcon::On ); 654 655 // draw the name 656 QStyleOptionViewItem tmp( option ); 657 tmp.rect.setWidth( option.rect.width( ) - iconArea.width( ) - HIG::PAD_SMALL ); 658 tmp.rect.moveRight( option.rect.right( ) ); 659 QItemDelegate::paint( painter, tmp, index ); 660 } 661 else if( column == COL_PROGRESS ) 662 { 663 QStyleOptionProgressBar p; 664 p.state = option.state | QStyle::State_Small; 665 p.direction = QApplication::layoutDirection(); 666 p.rect = option.rect; 667 p.rect.setSize( QSize( option.rect.width()-2, option.rect.height()-8 ) ); 668 p.rect.moveCenter( option.rect.center( ) ); 669 p.fontMetrics = QApplication::fontMetrics(); 670 p.minimum = 0; 671 p.maximum = 100; 672 p.textAlignment = Qt::AlignCenter; 673 p.textVisible = true; 674 p.progress = (int)(100.0*index.data().toDouble()); 675 p.text = QString( ).sprintf( "%d%%", p.progress ); 676 style->drawControl( QStyle::CE_ProgressBar, &p, painter ); 677 } 678 else if( column == COL_WANTED ) 679 { 680 QStyleOptionButton o; 681 o.state = option.state; 682 o.direction = QApplication::layoutDirection(); 683 o.rect.setSize( QSize( 20, option.rect.height( ) ) ); 684 o.rect.moveCenter( option.rect.center( ) ); 685 o.fontMetrics = QApplication::fontMetrics(); 686 switch( index.data().toInt() ) { 687 case Qt::Unchecked: o.state |= QStyle::State_Off; break; 688 case Qt::Checked: o.state |= QStyle::State_On; break; 689 default: o.state |= QStyle::State_NoChange;break; 690 } 691 style->drawControl( QStyle::CE_CheckBox, &o, painter ); 692 } 693 694 painter->restore( ); 673 const QModelIndex & index) const 674 { 675 const int column(index.column()); 676 677 if ((column != COL_PROGRESS) && (column != COL_WANTED) && (column != COL_NAME)) 678 { 679 QItemDelegate::paint(painter, option, index); 680 return; 681 } 682 683 QStyle * style(QApplication :: style()); 684 if (option.state & QStyle::State_Selected) 685 painter->fillRect(option.rect, option.palette.highlight()); 686 painter->save(); 687 if (option.state & QStyle::State_Selected) 688 painter->setBrush(option.palette.highlightedText()); 689 690 if (column == COL_NAME) 691 { 692 // draw the file icon 693 static const int iconSize(style->pixelMetric(QStyle :: PM_SmallIconSize)); 694 const QRect iconArea(option.rect.x(), 695 option.rect.y() + (option.rect.height()-iconSize)/2, 696 iconSize, iconSize); 697 QIcon icon; 698 if (index.model()->hasChildren(index)) 699 { 700 icon = style->standardIcon(QStyle::StandardPixmap(QStyle::SP_DirOpenIcon)); 701 } 702 else 703 { 704 QString name = index.data().toString(); 705 icon = Utils :: guessMimeIcon (name.left(name.lastIndexOf(" ("))); 706 } 707 icon.paint(painter, iconArea, Qt::AlignCenter, QIcon::Normal, QIcon::On); 708 709 // draw the name 710 QStyleOptionViewItem tmp(option); 711 tmp.rect.setWidth(option.rect.width() - iconArea.width() - HIG::PAD_SMALL); 712 tmp.rect.moveRight(option.rect.right()); 713 QItemDelegate::paint(painter, tmp, index); 714 } 715 else if(column == COL_PROGRESS) 716 { 717 QStyleOptionProgressBar p; 718 p.state = option.state | QStyle::State_Small; 719 p.direction = QApplication::layoutDirection(); 720 p.rect = option.rect; 721 p.rect.setSize(QSize(option.rect.width()-2, option.rect.height()-8)); 722 p.rect.moveCenter(option.rect.center()); 723 p.fontMetrics = QApplication::fontMetrics(); 724 p.minimum = 0; 725 p.maximum = 100; 726 p.textAlignment = Qt::AlignCenter; 727 p.textVisible = true; 728 p.progress = (int)(100.0*index.data().toDouble()); 729 p.text = QString().sprintf("%d%%", p.progress); 730 style->drawControl(QStyle::CE_ProgressBar, &p, painter); 731 } 732 else if(column == COL_WANTED) 733 { 734 QStyleOptionButton o; 735 o.state = option.state; 736 o.direction = QApplication::layoutDirection(); 737 o.rect.setSize(QSize(20, option.rect.height())); 738 o.rect.moveCenter(option.rect.center()); 739 o.fontMetrics = QApplication::fontMetrics(); 740 switch(index.data().toInt()) 741 { 742 case Qt::Unchecked: o.state |= QStyle::State_Off; break; 743 case Qt::Checked: o.state |= QStyle::State_On; break; 744 default: o.state |= QStyle::State_NoChange;break; 745 } 746 style->drawControl(QStyle::CE_CheckBox, &o, painter); 747 } 748 749 painter->restore(); 695 750 } 696 751 … … 701 756 ****/ 702 757 703 FileTreeView :: FileTreeView ( QWidget * parent):704 QTreeView( parent),705 myModel( this),706 myProxy( new QSortFilterProxyModel( )),707 myDelegate( this)708 { 709 setSortingEnabled( true);710 setAlternatingRowColors( true);711 setSelectionBehavior( QAbstractItemView::SelectRows);712 setSelectionMode( QAbstractItemView::ExtendedSelection);713 myProxy->setSourceModel( &myModel);714 setModel( myProxy);715 setItemDelegate( &myDelegate);716 setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff);717 sortByColumn( COL_NAME, Qt::AscendingOrder);718 installEventFilter( this);719 720 for( int i=0; i<NUM_COLUMNS; ++i)721 header()->setResizeMode( i, QHeaderView::Interactive);722 723 connect(this, SIGNAL(clicked(const QModelIndex&)),724 this, SLOT(onClicked(const QModelIndex&)));725 726 connect(&myModel, SIGNAL(priorityChanged(const QSet<int>&, int)),727 728 729 connect(&myModel, SIGNAL(wantedChanged(const QSet<int>&, bool)),730 731 732 connect(&myModel, SIGNAL(pathEdited(const QString&, const QString&)),733 734 } 735 736 FileTreeView :: ~FileTreeView ()737 { 738 739 } 740 741 void 742 FileTreeView :: onClicked ( const QModelIndex& proxyIndex)743 { 744 const QModelIndex modelIndex = myProxy->mapToSource( proxyIndex);745 myModel.clicked( modelIndex);758 FileTreeView :: FileTreeView (QWidget * parent): 759 QTreeView (parent), 760 myModel (this), 761 myProxy (new QSortFilterProxyModel()), 762 myDelegate (this) 763 { 764 setSortingEnabled (true); 765 setAlternatingRowColors (true); 766 setSelectionBehavior (QAbstractItemView::SelectRows); 767 setSelectionMode (QAbstractItemView::ExtendedSelection); 768 myProxy->setSourceModel (&myModel); 769 setModel (myProxy); 770 setItemDelegate (&myDelegate); 771 setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff); 772 sortByColumn (COL_NAME, Qt::AscendingOrder); 773 installEventFilter (this); 774 775 for (int i=0; i<NUM_COLUMNS; ++i) 776 header()->setResizeMode(i, QHeaderView::Interactive); 777 778 connect (this, SIGNAL(clicked(const QModelIndex&)), 779 this, SLOT(onClicked(const QModelIndex&))); 780 781 connect (&myModel, SIGNAL(priorityChanged(const QSet<int>&, int)), 782 this, SIGNAL(priorityChanged(const QSet<int>&, int))); 783 784 connect (&myModel, SIGNAL(wantedChanged(const QSet<int>&, bool)), 785 this, SIGNAL(wantedChanged(const QSet<int>&, bool))); 786 787 connect (&myModel, SIGNAL(pathEdited(const QString&, const QString&)), 788 this, SIGNAL(pathEdited(const QString&, const QString&))); 789 } 790 791 FileTreeView :: ~FileTreeView () 792 { 793 myProxy->deleteLater(); 794 } 795 796 void 797 FileTreeView :: onClicked (const QModelIndex& proxyIndex) 798 { 799 const QModelIndex modelIndex = myProxy->mapToSource(proxyIndex); 800 myModel.clicked(modelIndex); 746 801 } 747 802 748 803 bool 749 FileTreeView :: eventFilter( QObject * o, QEvent * event ) 750 { 751 if( o != this ) 752 return false; 753 754 // this is kind of a hack to get the last three columns be the 755 // right size, and to have the filename column use whatever 756 // space is left over... 757 if( event->type() == QEvent::Resize ) 758 { 759 QResizeEvent * r = dynamic_cast<QResizeEvent*>(event); 760 int left = r->size().width(); 761 const QFontMetrics fontMetrics( font( ) ); 762 for( int column=0; column<NUM_COLUMNS; ++column ) { 763 if( column == COL_NAME ) 764 continue; 765 if( isColumnHidden( column ) ) 766 continue; 767 const QString header = myModel.headerData( column, Qt::Horizontal ).toString( ) + " "; 768 const int width = fontMetrics.size( 0, header ).width( ); 769 setColumnWidth( column, width ); 804 FileTreeView :: eventFilter (QObject * o, QEvent * event) 805 { 806 if (o != this) 807 return false; 808 809 // this is kind of a hack to get the last three columns be the 810 // right size, and to have the filename column use whatever 811 // space is left over... 812 if (event->type() == QEvent::Resize) 813 { 814 QResizeEvent * r = dynamic_cast<QResizeEvent*>(event); 815 int left = r->size().width(); 816 const QFontMetrics fontMetrics(font()); 817 for (int column=0; column<NUM_COLUMNS; ++column) 818 { 819 if (column == COL_NAME) 820 continue; 821 if (isColumnHidden(column)) 822 continue; 823 const QString header = myModel.headerData (column, Qt::Horizontal).toString() + " "; 824 const int width = fontMetrics.size (0, header).width(); 825 setColumnWidth (column, width); 770 826 left -= width; 771 827 } 772 left -= 20; // not sure why this is necessary. it works in different themes + font sizes though... 773 setColumnWidth( COL_NAME, std::max(left,0) ); 774 return false; 775 } 776 777 // handle using the keyboard to toggle the 778 // wanted/unwanted state or the file priority 779 else if( event->type() == QEvent::KeyPress ) 780 { 781 switch( dynamic_cast<QKeyEvent*>(event)->key() ) 782 { 783 case Qt::Key_Space: 784 foreach( QModelIndex i, selectionModel()->selectedRows(COL_WANTED) ) 785 clicked( i ); 786 return false; 787 788 case Qt::Key_Enter: 789 case Qt::Key_Return: 790 foreach( QModelIndex i, selectionModel()->selectedRows(COL_PRIORITY) ) 791 clicked( i ); 792 return false; 793 } 794 } 795 796 return false; 797 } 798 799 void 800 FileTreeView :: update( const FileList& files ) 801 { 802 update( files, true ); 803 } 804 805 void 806 FileTreeView :: update( const FileList& files, bool torrentChanged ) 807 { 808 foreach( const TrFile file, files ) { 809 QList<QModelIndex> added; 810 myModel.addFile( file.index, file.filename, file.wanted, file.priority, file.size, file.have, added, torrentChanged ); 811 foreach( QModelIndex i, added ) 812 expand( myProxy->mapFromSource( i ) ); 813 } 814 } 815 816 void 817 FileTreeView :: clear( ) 818 { 819 myModel.clear( ); 820 } 828 left -= 20; // not sure why this is necessary. it works in different themes + font sizes though... 829 setColumnWidth(COL_NAME, std::max(left,0)); 830 return false; 831 } 832 833 // handle using the keyboard to toggle the 834 // wanted/unwanted state or the file priority 835 else if(event->type() == QEvent::KeyPress) 836 { 837 switch(dynamic_cast<QKeyEvent*>(event)->key()) 838 { 839 case Qt::Key_Space: 840 foreach (QModelIndex i, selectionModel()->selectedRows(COL_WANTED)) 841 clicked (i); 842 return false; 843 844 case Qt::Key_Enter: 845 case Qt::Key_Return: 846 foreach (QModelIndex i, selectionModel()->selectedRows(COL_PRIORITY)) 847 clicked (i); 848 return false; 849 } 850 } 851 852 return false; 853 } 854 855 void 856 FileTreeView :: update (const FileList& files) 857 { 858 update(files, true); 859 } 860 861 void 862 FileTreeView :: update (const FileList& files, bool torrentChanged) 863 { 864 foreach (const TrFile file, files) 865 { 866 QList<QModelIndex> added; 867 myModel.addFile (file.index, file.filename, file.wanted, file.priority, file.size, file.have, added, torrentChanged); 868 foreach (QModelIndex i, added) 869 expand(myProxy->mapFromSource(i)); 870 } 871 } 872 873 void 874 FileTreeView :: clear () 875 { 876 myModel.clear(); 877 } -
trunk/qt/file-tree.h
r13849 r13866 36 36 class FileTreeItem: public QObject 37 37 { 38 38 Q_OBJECT; 39 39 40 40 enum { LOW=(1<<0), NORMAL=(1<<1), HIGH=(1<<2) }; 41 41 42 public: 43 virtual ~FileTreeItem( ); 44 FileTreeItem( int fileIndex, const QString& name="" ): 45 myIndex(fileIndex), myParent(0), myName(name), 46 myPriority(0), myIsWanted(0), 47 myHaveSize(0), myTotalSize(0), 48 myFirstUnhashedRow(0) { } 42 public: 49 43 50 public: 51 void appendChild( FileTreeItem *child ); 52 FileTreeItem * child( const QString& filename ); 53 FileTreeItem * child( int row ) { return myChildren.at( row ); } 54 int childCount( ) const { return myChildren.size( ); } 55 FileTreeItem * parent( ) { return myParent; } 56 const FileTreeItem * parent( ) const { return myParent; } 57 int row( ) const; 58 const QString& name( ) const { return myName; } 59 QVariant data( int column, int role ) const; 60 bool update( int index, bool want, int priority, uint64_t total, uint64_t have, bool torrentChanged ); 61 void twiddleWanted( QSet<int>& fileIds, bool& ); 62 void twiddlePriority( QSet<int>& fileIds, int& ); 44 virtual ~FileTreeItem(); 63 45 64 private:65 void setSubtreePriority( int priority, QSet<int>& fileIds );66 void setSubtreeWanted( bool, QSet<int>& fileIds );67 QString priorityString( ) const;68 void getSubtreeSize( uint64_t& have, uint64_t& total ) const;69 QString fileSizeName( ) const;70 double progress( ) const;71 int priority( ) const;72 int isSubtreeWanted( ) const;46 FileTreeItem (int fileIndex, const QString& name=""): 47 myIndex (fileIndex), 48 myParent (0), 49 myName (name), 50 myPriority (0), 51 myIsWanted (0), 52 myHaveSize (0), 53 myTotalSize (0), 54 myFirstUnhashedRow (0) { } 73 55 74 int myIndex; 75 FileTreeItem * myParent; 76 QList<FileTreeItem*> myChildren; 77 QHash<QString,int> myChildRows; 78 QHash<QString,int>& getMyChildRows(); 79 const QString myName; 80 int myPriority; 81 bool myIsWanted; 82 uint64_t myHaveSize; 83 uint64_t myTotalSize; 84 size_t myFirstUnhashedRow; 56 public: 57 void appendChild (FileTreeItem *child); 58 FileTreeItem * child (const QString& filename); 59 FileTreeItem * child (int row) { return myChildren.at(row); } 60 int childCount () const { return myChildren.size(); } 61 FileTreeItem * parent () { return myParent; } 62 const FileTreeItem * parent () const { return myParent; } 63 int row () const; 64 const QString& name () const { return myName; } 65 QVariant data (int column, int role) const; 66 bool update (int index, bool want, int priority, uint64_t total, uint64_t have, bool torrentChanged); 67 void twiddleWanted (QSet<int>& fileIds, bool&); 68 void twiddlePriority (QSet<int>& fileIds, int&); 69 70 private: 71 void setSubtreePriority (int priority, QSet<int>& fileIds); 72 void setSubtreeWanted (bool, QSet<int>& fileIds); 73 QString priorityString () const; 74 void getSubtreeSize (uint64_t& have, uint64_t& total) const; 75 QString fileSizeName () const; 76 double progress () const; 77 int priority () const; 78 int isSubtreeWanted () const; 79 80 int myIndex; 81 FileTreeItem * myParent; 82 QList<FileTreeItem*> myChildren; 83 QHash<QString,int> myChildRows; 84 QHash<QString,int>& getMyChildRows(); 85 const QString myName; 86 int myPriority; 87 bool myIsWanted; 88 uint64_t myHaveSize; 89 uint64_t myTotalSize; 90 size_t myFirstUnhashedRow; 85 91 }; 86 92 87 93 class FileTreeModel: public QAbstractItemModel 88 94 { 89 95 Q_OBJECT 90 96 91 92 FileTreeModel(QObject *parent = 0);93 ~FileTreeModel();97 public: 98 FileTreeModel (QObject *parent = 0); 99 ~FileTreeModel (); 94 100 95 96 QVariant data( const QModelIndex &index, int role = Qt::DisplayRole) const;97 Qt::ItemFlags flags( const QModelIndex& index) const;98 QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;99 QModelIndex index( int row, int column, const QModelIndex& parent = QModelIndex()) const;100 QModelIndex parent( const QModelIndex& child) const;101 QModelIndex parent( const QModelIndex& child, int column) const;102 int rowCount( const QModelIndex& parent = QModelIndex( )) const;103 int columnCount( const QModelIndex &parent = QModelIndex( )) const;104 virtual bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole);101 public: 102 QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const; 103 Qt::ItemFlags flags (const QModelIndex& index) const; 104 QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; 105 QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex()) const; 106 QModelIndex parent (const QModelIndex& child) const; 107 QModelIndex parent (const QModelIndex& child, int column) const; 108 int rowCount (const QModelIndex& parent = QModelIndex()) const; 109 int columnCount (const QModelIndex &parent = QModelIndex()) const; 110 virtual bool setData (const QModelIndex & index, const QVariant & value, int role = Qt::EditRole); 105 111 106 107 void priorityChanged( const QSet<int>& fileIndices, int);108 void wantedChanged( const QSet<int>& fileIndices, bool);109 112 signals: 113 void priorityChanged (const QSet<int>& fileIndices, int); 114 void wantedChanged (const QSet<int>& fileIndices, bool); 115 void pathEdited (const QString& oldpath, const QString& newname); 110 116 111 112 void clear();113 void addFile(int index, const QString& filename,114 115 116 117 bool torrentChanged);117 public: 118 void clear (); 119 void addFile (int index, const QString& filename, 120 bool wanted, int priority, 121 uint64_t size, uint64_t have, 122 QList<QModelIndex>& rowsAdded, 123 bool torrentChanged); 118 124 119 120 void clearSubtree( const QModelIndex &);121 QModelIndex indexOf( FileTreeItem *, int column) const;122 void parentsChanged( const QModelIndex &, int column);123 void subtreeChanged( const QModelIndex &, int column);125 private: 126 void clearSubtree (const QModelIndex &); 127 QModelIndex indexOf (FileTreeItem *, int column) const; 128 void parentsChanged (const QModelIndex &, int column); 129 void subtreeChanged (const QModelIndex &, int column); 124 130 125 126 131 private: 132 FileTreeItem * rootItem; 127 133 128 129 void clicked ( const QModelIndex & index);134 public slots: 135 void clicked (const QModelIndex & index); 130 136 }; 131 137 132 138 class FileTreeDelegate: public QItemDelegate 133 139 { 134 140 Q_OBJECT 135 141 136 137 FileTreeDelegate( QObject * parent=0 ): QItemDelegate( parent) { }138 virtual ~FileTreeDelegate() { }142 public: 143 FileTreeDelegate (QObject * parent=0): QItemDelegate(parent) { } 144 virtual ~FileTreeDelegate() { } 139 145 140 141 virtual QSize sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const;142 virtual void paint(QPainter*, const QStyleOptionViewItem&, const QModelIndex&) const;146 public: 147 virtual QSize sizeHint (const QStyleOptionViewItem&, const QModelIndex&) const; 148 virtual void paint (QPainter*, const QStyleOptionViewItem&, const QModelIndex&) const; 143 149 }; 144 150 145 151 class FileTreeView: public QTreeView 146 152 { 147 153 Q_OBJECT 148 154 149 150 FileTreeView( QWidget * parent=0);151 virtual ~FileTreeView();152 void clear();153 void update( const FileList& files);154 void update( const FileList& files, bool torrentChanged);155 public: 156 FileTreeView (QWidget * parent=0); 157 virtual ~FileTreeView (); 158 void clear (); 159 void update (const FileList& files); 160 void update (const FileList& files, bool torrentChanged); 155 161 156 157 void priorityChanged( const QSet<int>& fileIndices, int);158 void wantedChanged( const QSet<int>& fileIndices, bool);159 162 signals: 163 void priorityChanged (const QSet<int>& fileIndices, int); 164 void wantedChanged (const QSet<int>& fileIndices, bool); 165 void pathEdited (const QString& oldpath, const QString& newname); 160 166 161 162 bool eventFilter( QObject *, QEvent *);167 protected: 168 bool eventFilter (QObject *, QEvent *); 163 169 164 165 166 167 170 private: 171 FileTreeModel myModel; 172 QSortFilterProxyModel * myProxy; 173 FileTreeDelegate myDelegate; 168 174 169 170 void onClicked ( const QModelIndex & index);175 public slots: 176 void onClicked (const QModelIndex & index); 171 177 }; 172 178
Note: See TracChangeset
for help on using the changeset viewer.