00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "katefilelist.h"
00023 #include "katefilelist.moc"
00024
00025 #include "katedocmanager.h"
00026 #include "kateviewmanager.h"
00027 #include "katemainwindow.h"
00028
00029 #include <qapplication.h>
00030 #include <qpainter.h>
00031 #include <qpopupmenu.h>
00032 #include <qheader.h>
00033 #include <qcolor.h>
00034 #include <qcheckbox.h>
00035 #include <qhbox.h>
00036 #include <qlayout.h>
00037 #include <qgroupbox.h>
00038 #include <qlabel.h>
00039 #include <qwhatsthis.h>
00040
00041 #include <kiconloader.h>
00042 #include <kconfig.h>
00043 #include <klocale.h>
00044 #include <kglobalsettings.h>
00045 #include <kpassivepopup.h>
00046 #include <kdebug.h>
00047 #include <kapplication.h>
00048 #include <kstringhandler.h>
00049 #include <kcolorbutton.h>
00050 #include <kdialog.h>
00051
00052
00053
00054 class ToolTip : public QToolTip
00055 {
00056 public:
00057 ToolTip( QWidget *parent, KateFileList *lv )
00058 : QToolTip( parent ),
00059 m_listView( lv )
00060 {
00061 }
00062 virtual ~ToolTip() {};
00063
00064 void maybeTip( const QPoint &pos )
00065 {
00066 QListViewItem *i = m_listView->itemAt( pos );
00067 if ( ! i ) return;
00068
00069 KateFileListItem *item = ((KateFileListItem*)i);
00070 if ( ! item ) return;
00071
00072 tip( m_listView->itemRect( i ), m_listView->tooltip( item, 0 ) );
00073
00074 }
00075
00076 private:
00077 KateFileList *m_listView;
00078 };
00079
00080
00081
00082
00083 KateFileList::KateFileList (KateMainWindow *main,
00084 KateViewManager *_viewManager,
00085 QWidget * parent, const char * name )
00086 : KListView (parent, name)
00087 , m_sort( KateFileList::sortByID )
00088 {
00089 m_main = main;
00090 m_tooltip = new ToolTip( viewport(), this );
00091
00092
00093 m_viewShade = QColor( 51, 204, 255 );
00094 m_editShade = QColor( 255, 102, 153 );
00095 m_enableBgShading = false;
00096
00097 setFocusPolicy ( QWidget::NoFocus );
00098
00099 viewManager = _viewManager;
00100
00101 header()->hide();
00102 addColumn("Document Name");
00103
00104 setSelectionMode( QListView::Single );
00105 setSorting( 0, true );
00106 setShowToolTips( false );
00107
00108 setupActions ();
00109
00110 for (uint i = 0; i < KateDocManager::self()->documents(); i++)
00111 {
00112 slotDocumentCreated (KateDocManager::self()->document(i));
00113 slotModChanged (KateDocManager::self()->document(i));
00114 }
00115
00116 connect(KateDocManager::self(),SIGNAL(documentCreated(Kate::Document *)),
00117 this,SLOT(slotDocumentCreated(Kate::Document *)));
00118 connect(KateDocManager::self(),SIGNAL(documentDeleted(uint)),
00119 this,SLOT(slotDocumentDeleted(uint)));
00120
00121
00122
00123 connect(this,SIGNAL(selectionChanged(QListViewItem *)),
00124 this,SLOT(slotActivateView(QListViewItem *)));
00125 connect(viewManager,SIGNAL(viewChanged()), this,SLOT(slotViewChanged()));
00126 connect(this,SIGNAL(contextMenuRequested( QListViewItem *, const QPoint &, int )),
00127 this,SLOT(slotMenu ( QListViewItem *, const QPoint &, int )));
00128 }
00129
00130 KateFileList::~KateFileList ()
00131 {
00132 delete m_tooltip;
00133 }
00134
00135 void KateFileList::setupActions ()
00136 {
00137 windowNext = KStdAction::back(this, SLOT(slotPrevDocument()), m_main->actionCollection());
00138 windowPrev = KStdAction::forward(this, SLOT(slotNextDocument()), m_main->actionCollection());
00139 sortAction = new KSelectAction( i18n("Sort &By"), 0,
00140 m_main->actionCollection(), "filelist_sortby" );
00141 QStringList l;
00142 l << i18n("Opening Order") << i18n("Document Name") << i18n("URL");
00143 sortAction->setItems( l );
00144 connect( sortAction, SIGNAL(activated(int)), this, SLOT(setSortType(int)) );
00145 }
00146
00147 void KateFileList::updateActions ()
00148 {
00149 windowNext->setEnabled(KateDocManager::self()->documents() > 1);
00150 windowPrev->setEnabled(KateDocManager::self()->documents() > 1);
00151 }
00152
00153 void KateFileList::keyPressEvent(QKeyEvent *e) {
00154 if ( ( e->key() == Key_Return ) || ( e->key() == Key_Enter ) )
00155 {
00156 e->accept();
00157 slotActivateView( currentItem() );
00158 }
00159 else
00160 {
00161 KListView::keyPressEvent(e);
00162 }
00163 }
00164
00165
00166
00167
00168
00169 void KateFileList::contentsMousePressEvent( QMouseEvent *e )
00170 {
00171 if ( ! itemAt( contentsToViewport( e->pos() ) ) )
00172 return;
00173
00174 KListView::contentsMousePressEvent( e );
00175 }
00176
00177 void KateFileList::resizeEvent( QResizeEvent *e )
00178 {
00179 KListView::resizeEvent( e );
00180
00181
00182
00183
00184
00185
00186 int w = viewport()->width();
00187 if ( columnWidth( 0 ) < w )
00188 setColumnWidth( 0, w );
00189 }
00190
00191 void KateFileList::slotNextDocument()
00192 {
00193 if ( ! currentItem() || childCount() == 0 )
00194 return;
00195
00196
00197
00198 if ( currentItem()->nextSibling() )
00199 viewManager->activateView( ((KateFileListItem*)currentItem()->nextSibling())->documentNumber() );
00200 else
00201 viewManager->activateView( ((KateFileListItem *)firstChild())->documentNumber() );
00202 }
00203
00204 void KateFileList::slotPrevDocument()
00205 {
00206 if ( ! currentItem() || childCount() == 0 )
00207 return;
00208
00209
00210
00211 if ( currentItem()->itemAbove() )
00212 viewManager->activateView( ((KateFileListItem*)currentItem()->itemAbove())->documentNumber() );
00213 else
00214 viewManager->activateView( ((KateFileListItem *)lastItem())->documentNumber() );
00215 }
00216
00217 void KateFileList::slotDocumentCreated (Kate::Document *doc)
00218 {
00219 new KateFileListItem( this, doc );
00220 connect(doc,SIGNAL(modStateChanged(Kate::Document *)),this,SLOT(slotModChanged(Kate::Document *)));
00221 connect(doc,SIGNAL(nameChanged(Kate::Document *)),this,SLOT(slotNameChanged(Kate::Document *)));
00222 connect(doc,SIGNAL(modifiedOnDisc(Kate::Document *, bool, unsigned char)),this,SLOT(slotModifiedOnDisc(Kate::Document *, bool, unsigned char)));
00223
00224 sort();
00225 updateActions ();
00226 }
00227
00228 void KateFileList::slotDocumentDeleted (uint documentNumber)
00229 {
00230 QListViewItem * item = firstChild();
00231 while( item ) {
00232 if ( ((KateFileListItem *)item)->documentNumber() == documentNumber )
00233 {
00234
00235
00236
00237 removeItem( item );
00238
00239 break;
00240 }
00241 item = item->nextSibling();
00242 }
00243
00244 updateActions ();
00245 }
00246
00247 void KateFileList::slotActivateView( QListViewItem *item )
00248 {
00249 if ( ! item || item->rtti() != RTTI_KateFileListItem )
00250 return;
00251
00252 viewManager->activateView( ((KateFileListItem *)item)->documentNumber() );
00253 }
00254
00255 void KateFileList::slotModChanged (Kate::Document *doc)
00256 {
00257 if (!doc) return;
00258
00259 QListViewItem * item = firstChild();
00260 while( item )
00261 {
00262 if ( ((KateFileListItem *)item)->documentNumber() == doc->documentNumber() )
00263 break;
00264
00265 item = item->nextSibling();
00266 }
00267
00268 if ( ((KateFileListItem *)item)->document()->isModified() )
00269 {
00270 m_editHistory.removeRef( (KateFileListItem *)item );
00271 m_editHistory.prepend( (KateFileListItem *)item );
00272
00273 for ( uint i=0; i < m_editHistory.count(); i++ )
00274 {
00275 m_editHistory.at( i )->setEditHistPos( i+1 );
00276 repaintItem( m_editHistory.at( i ) );
00277 }
00278 }
00279 else
00280 repaintItem( item );
00281 }
00282
00283 void KateFileList::slotModifiedOnDisc (Kate::Document *doc, bool, unsigned char)
00284 {
00285 slotModChanged( doc );
00286 }
00287
00288 void KateFileList::slotNameChanged (Kate::Document *doc)
00289 {
00290 if (!doc) return;
00291
00292
00293
00294 QListViewItem * item = firstChild();
00295 while( item ) {
00296 if ( ((KateFileListItem*)item)->document() == doc )
00297 {
00298 item->setText( 0, doc->docName() );
00299 repaintItem( item );
00300 break;
00301 }
00302 item = item->nextSibling();
00303 }
00304 updateSort();
00305 }
00306
00307 void KateFileList::slotViewChanged ()
00308 {
00309 if (!viewManager->activeView()) return;
00310
00311 Kate::View *view = viewManager->activeView();
00312 uint dn = view->getDoc()->documentNumber();
00313
00314 QListViewItem * i = firstChild();
00315 while( i ) {
00316 if ( ((KateFileListItem *)i)->documentNumber() == dn )
00317 {
00318 break;
00319 }
00320 i = i->nextSibling();
00321 }
00322
00323 if ( ! i )
00324 return;
00325
00326 KateFileListItem *item = (KateFileListItem*)i;
00327 setCurrentItem( item );
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 m_viewHistory.removeRef( item );
00341 m_viewHistory.prepend( item );
00342
00343 for ( uint i=0; i < m_viewHistory.count(); i++ )
00344 {
00345 m_viewHistory.at( i )->setViewHistPos( i+1 );
00346 repaintItem( m_viewHistory.at( i ) );
00347 }
00348
00349 }
00350
00351 void KateFileList::slotMenu ( QListViewItem *item, const QPoint &p, int )
00352 {
00353 if (!item)
00354 return;
00355
00356 QPopupMenu *menu = (QPopupMenu*) ((viewManager->mainWindow())->factory()->container("filelist_popup", viewManager->mainWindow()));
00357
00358 if (menu)
00359 menu->exec(p);
00360 }
00361
00362 QString KateFileList::tooltip( QListViewItem *item, int )
00363 {
00364 KateFileListItem *i = ((KateFileListItem*)item);
00365 if ( ! i ) return QString::null;
00366
00367 QString str;
00368 const KateDocumentInfo *info = KateDocManager::self()->documentInfo(i->document());
00369
00370 if (info && info->modifiedOnDisc)
00371 {
00372 if (info->modifiedOnDiscReason == 1)
00373 str += i18n("<b>This file was changed (modified) on disk by another program.</b><br />");
00374 else if (info->modifiedOnDiscReason == 2)
00375 str += i18n("<b>This file was changed (created) on disk by another program.</b><br />");
00376 else if (info->modifiedOnDiscReason == 3)
00377 str += i18n("<b>This file was changed (deleted) on disk by another program.</b><br />");
00378 }
00379
00380 str += i->document()->url().prettyURL();
00381 return str;
00382 }
00383
00384
00385 void KateFileList::setSortType (int s)
00386 {
00387 m_sort = s;
00388 updateSort ();
00389 }
00390
00391 void KateFileList::updateSort ()
00392 {
00393 sort ();
00394 }
00395
00396 void KateFileList::readConfig( KConfig *config, const QString &group )
00397 {
00398 QString oldgroup = config->group();
00399 config->setGroup( group );
00400
00401 setSortType( config->readNumEntry( "Sort Type", sortByID ) );
00402 m_viewShade = config->readColorEntry( "View Shade", &m_viewShade );
00403 m_editShade = config->readColorEntry( "Edit Shade", &m_editShade );
00404 m_enableBgShading = config->readBoolEntry( "Shading Enabled", &m_enableBgShading );
00405
00406 sortAction->setCurrentItem( sortType() );
00407
00408 config->setGroup( oldgroup );
00409 }
00410
00411 void KateFileList::writeConfig( KConfig *config, const QString &group )
00412 {
00413 QString oldgroup = config->group();
00414 config->setGroup( group );
00415
00416 config->writeEntry( "Sort Type", m_sort );
00417 config->writeEntry( "View Shade", m_viewShade );
00418 config->writeEntry( "Edit Shade", m_editShade );
00419 config->writeEntry( "Shading Enabled", m_enableBgShading );
00420
00421 config->setGroup( oldgroup );
00422 }
00423
00424 void KateFileList::takeItem( QListViewItem *item )
00425 {
00426 if ( item->rtti() == RTTI_KateFileListItem )
00427 {
00428 m_editHistory.removeRef( (KateFileListItem*)item );
00429 m_viewHistory.removeRef( (KateFileListItem*)item );
00430 }
00431 QListView::takeItem( item );
00432 }
00433
00434
00435
00436 KateFileListItem::KateFileListItem( QListView* lv,
00437 Kate::Document *_doc )
00438 : QListViewItem( lv, _doc->docName() ),
00439 doc( _doc ),
00440 m_viewhistpos( 0 ),
00441 m_edithistpos( 0 ),
00442 m_docNumber( _doc->documentNumber() )
00443 {
00444 }
00445
00446 KateFileListItem::~KateFileListItem()
00447 {
00448 }
00449
00450 const QPixmap *KateFileListItem::pixmap ( int column ) const
00451 {
00452 if ( column == 0) {
00453 static QPixmap noPm = SmallIcon ("null");
00454 static QPixmap modPm = SmallIcon("modified");
00455 static QPixmap discPm = SmallIcon("modonhd");
00456 static QPixmap modmodPm = SmallIcon("modmod");
00457
00458 const KateDocumentInfo *info = KateDocManager::self()->documentInfo(doc);
00459
00460 if (info && info->modifiedOnDisc)
00461 return doc->isModified() ? &modmodPm : &discPm;
00462 else
00463 return doc->isModified() ? &modPm : &noPm;
00464 }
00465
00466 return 0;
00467 }
00468
00469 void KateFileListItem::paintCell( QPainter *painter, const QColorGroup & cg, int column, int width, int align )
00470 {
00471 KateFileList *fl = (KateFileList*)listView();
00472 if ( ! fl ) return;
00473
00474 if ( column == 0 )
00475 {
00476 QColorGroup cgNew = cg;
00477
00478
00479 if ( fl->shadingEnabled() && m_viewhistpos > 1 )
00480 {
00481 QColor b( cg.base() );
00482
00483 QColor shade = fl->viewShade();
00484 QColor eshade = fl->editShade();
00485 int hc = fl->histCount();
00486
00487
00488 if ( fl->shadingEnabled() && m_edithistpos > 0 )
00489 {
00490 int ec = fl->editHistCount();
00491 int v = hc-m_viewhistpos;
00492 int e = ec-m_edithistpos+1;
00493 e = e*e;
00494 int n = QMAX(v + e, 1);
00495 shade.setRgb(
00496 ((shade.red()*v) + (eshade.red()*e))/n,
00497 ((shade.green()*v) + (eshade.green()*e))/n,
00498 ((shade.blue()*v) + (eshade.blue()*e))/n
00499 );
00500 }
00501
00502
00503 float t = (0.5/hc)*(hc-m_viewhistpos+1);
00504 b.setRgb(
00505 (int)((b.red()*(1-t)) + (shade.red()*t)),
00506 (int)((b.green()*(1-t)) + (shade.green()*t)),
00507 (int)((b.blue()*(1-t)) + (shade.blue()*t))
00508 );
00509
00510 cgNew.setColor(QColorGroup::Base, b);
00511 }
00512
00513 QListViewItem::paintCell( painter, cgNew, column, width, align );
00514 }
00515 else
00516 QListViewItem::paintCell( painter, cg, column, width, align );
00517 }
00518
00519 int KateFileListItem::compare ( QListViewItem * i, int col, bool ascending ) const
00520 {
00521 if ( i->rtti() == RTTI_KateFileListItem )
00522 {
00523 switch( ((KateFileList*)listView())->sortType() )
00524 {
00525 case KateFileList::sortByID:
00526 {
00527
00528 int d = (int)doc->documentNumber() - ((KateFileListItem*)i)->documentNumber();
00529 return ascending ? d : -d;
00530 break;
00531 }
00532 case KateFileList::sortByURL:
00533 return doc->url().prettyURL().compare( ((KateFileListItem*)i)->document()->url().prettyURL() );
00534 break;
00535 default:
00536 return QListViewItem::compare( i, col, ascending );
00537 }
00538 }
00539 return 0;
00540 }
00541
00542
00543
00544 KFLConfigPage::KFLConfigPage( QWidget* parent, const char *name, KateFileList *fl )
00545 : Kate::ConfigPage( parent, name ),
00546 m_filelist( fl ),
00547 m_changed( false )
00548 {
00549 QVBoxLayout *lo1 = new QVBoxLayout( this );
00550 int spacing = KDialog::spacingHint();
00551 lo1->setSpacing( spacing );
00552
00553 QGroupBox *gb = new QGroupBox( 1, Qt::Horizontal, i18n("Background Shading"), this );
00554 lo1->addWidget( gb );
00555
00556 QWidget *g = new QWidget( gb );
00557 QGridLayout *lo = new QGridLayout( g, 2, 2 );
00558 lo->setSpacing( KDialog::spacingHint() );
00559 cbEnableShading = new QCheckBox( i18n("&Enable background shading"), g );
00560 lo->addMultiCellWidget( cbEnableShading, 1, 1, 0, 1 );
00561
00562 kcbViewShade = new KColorButton( g );
00563 lViewShade = new QLabel( kcbViewShade, i18n("&Viewed documents' shade:"), g );
00564 lo->addWidget( lViewShade, 2, 0 );
00565 lo->addWidget( kcbViewShade, 2, 1 );
00566
00567 kcbEditShade = new KColorButton( g );
00568 lEditShade = new QLabel( kcbEditShade, i18n("&Modified documents' shade:"), g );
00569 lo->addWidget( lEditShade, 3, 0 );
00570 lo->addWidget( kcbEditShade, 3, 1 );
00571
00572
00573 QHBox *hbSorting = new QHBox( this );
00574 lo1->addWidget( hbSorting );
00575 lSort = new QLabel( i18n("&Sort by:"), hbSorting );
00576 cmbSort = new QComboBox( hbSorting );
00577 lSort->setBuddy( cmbSort );
00578 QStringList l;
00579 l << i18n("Opening Order") << i18n("Document Name") << i18n("URL");
00580 cmbSort->insertStringList( l );
00581
00582 lo1->insertStretch( -1, 10 );
00583
00584 QWhatsThis::add( cbEnableShading, i18n(
00585 "When background shading is enabled, documents that have been viewed "
00586 "or edited within the current session will have a shaded background. "
00587 "The most recent documents have the strongest shade.") );
00588 QWhatsThis::add( kcbViewShade, i18n(
00589 "Set the color for shading viewed documents.") );
00590 QWhatsThis::add( kcbEditShade, i18n(
00591 "Set the color for modified documents. This color is blended into "
00592 "the color for viewed files. The most recently edited documents get "
00593 "most of this color.") );
00594
00595 QWhatsThis::add( cmbSort, i18n(
00596 "Set the sorting method for the documents.") );
00597
00598 reload();
00599
00600 slotEnableChanged();
00601 connect( cbEnableShading, SIGNAL(toggled(bool)), this, SLOT(slotMyChanged()) );
00602 connect( cbEnableShading, SIGNAL(toggled(bool)), this, SLOT(slotEnableChanged()) );
00603 connect( kcbViewShade, SIGNAL(changed(const QColor&)), this, SLOT(slotMyChanged()) );
00604 connect( kcbEditShade, SIGNAL(changed(const QColor&)), this, SLOT(slotMyChanged()) );
00605 connect( cmbSort, SIGNAL(activated(int)), this, SLOT(slotMyChanged()) );
00606 }
00607
00608 void KFLConfigPage::apply()
00609 {
00610 if ( ! m_changed )
00611 return;
00612 m_changed = false;
00613
00614
00615 m_filelist->m_viewShade = kcbViewShade->color();
00616 m_filelist->m_editShade = kcbEditShade->color();
00617 m_filelist->m_enableBgShading = cbEnableShading->isChecked();
00618 m_filelist->setSortType( cmbSort->currentItem() );
00619
00620 m_filelist->triggerUpdate();
00621 }
00622
00623 void KFLConfigPage::reload()
00624 {
00625
00626 KConfig *config = kapp->config();
00627 config->setGroup( "Filelist" );
00628 cbEnableShading->setChecked( config->readBoolEntry("Shading Enabled", &m_filelist->m_enableBgShading ) );
00629 kcbViewShade->setColor( config->readColorEntry("View Shade", &m_filelist->m_viewShade ) );
00630 kcbEditShade->setColor( config->readColorEntry("Edit Shade", &m_filelist->m_editShade ) );
00631 cmbSort->setCurrentItem( m_filelist->sortType() );
00632 m_changed = false;
00633 }
00634
00635 void KFLConfigPage::slotEnableChanged()
00636 {
00637 kcbViewShade->setEnabled( cbEnableShading->isChecked() );
00638 kcbEditShade->setEnabled( cbEnableShading->isChecked() );
00639 lViewShade->setEnabled( cbEnableShading->isChecked() );
00640 lEditShade->setEnabled( cbEnableShading->isChecked() );
00641 }
00642
00643 void KFLConfigPage::slotMyChanged()
00644 {
00645 m_changed = true;
00646 slotChanged();
00647 }
00648
00649
00650
00651
00652