summaryrefslogtreecommitdiffstats
path: root/parts/fileview/vcsfiletreewidgetimpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'parts/fileview/vcsfiletreewidgetimpl.cpp')
-rw-r--r--parts/fileview/vcsfiletreewidgetimpl.cpp353
1 files changed, 353 insertions, 0 deletions
diff --git a/parts/fileview/vcsfiletreewidgetimpl.cpp b/parts/fileview/vcsfiletreewidgetimpl.cpp
new file mode 100644
index 00000000..1db873ed
--- /dev/null
+++ b/parts/fileview/vcsfiletreewidgetimpl.cpp
@@ -0,0 +1,353 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Mario Scalas *
+ * *
+ * 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 <qpainter.h>
+#include <qheader.h>
+#include <qpopupmenu.h>
+#include <kxmlguiclient.h>
+#include <kaction.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kdeversion.h>
+
+//#include <kdevproject.h>
+#include <urlutil.h>
+#include <domutil.h>
+
+#include "fileviewpart.h"
+#include "filetreewidget.h"
+#include "fileitemfactory.h"
+#include "vcsfiletreewidgetimpl.h"
+#include "vcscolorsconfigwidget.h"
+
+using namespace filetreeview;
+
+///////////////////////////////////////////////////////////////////////////////
+// class VCSFileTreeViewItem
+///////////////////////////////////////////////////////////////////////////////
+
+#define FILENAME_COLUMN 0
+#define STATUS_COLUMN 1
+#define WORKREVISION_COLUMN 2
+#define REPOREVISION_COLUMN 3
+
+class VCSFileTreeViewItem : public filetreeview::FileTreeViewItem
+{
+public:
+ VCSFileTreeViewItem( KFileTreeViewItem* parent, KFileItem* item, KFileTreeBranch* branch, bool pf )
+ : FileTreeViewItem( parent, item, branch, pf ), m_statusColor( &FileViewPart::vcsColors.unknown ) {}
+ VCSFileTreeViewItem( KFileTreeView* parent, KFileItem* item, KFileTreeBranch* branch )
+ : FileTreeViewItem( parent, item, branch ), m_statusColor( &FileViewPart::vcsColors.unknown ) {}
+ virtual void paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int alignment )
+ {
+ // paint cell in a different color depending on VCS state
+ QColorGroup mycg( cg );
+ mycg.setColor( QColorGroup::Base, *m_statusColor );
+ FileTreeViewItem::paintCell( p, mycg, column, width, alignment );
+ }
+ void setVCSInfo( const VCSFileInfo &info );
+
+ QString fileName() const { return text( FILENAME_COLUMN ); }
+ QString workingRev() const { return text( WORKREVISION_COLUMN ); }
+ QString repositoryRev() const { return text( REPOREVISION_COLUMN ); }
+ QString status() const { return text( STATUS_COLUMN ); }
+ void setFileName( const QString &p ) { setText( FILENAME_COLUMN, p ); }
+ void setWorkingRev( const QString &p ) { setText( WORKREVISION_COLUMN, p ); }
+ void setRepositoryRev( const QString &p ) { setText( REPOREVISION_COLUMN, p ); }
+ void setStatus( const VCSFileInfo::FileState status );
+
+private:
+ QColor *m_statusColor; // cached
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+void VCSFileTreeViewItem::setVCSInfo( const VCSFileInfo &info )
+{
+ //setFileName( info.fileName );
+ setRepositoryRev( info.repoRevision );
+ setWorkingRev( info.workRevision );
+ setStatus( info.state );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void VCSFileTreeViewItem::setStatus( const VCSFileInfo::FileState status )
+{
+ setText( STATUS_COLUMN, VCSFileInfo::state2String( status ) );
+ // Update color too
+ switch (status)
+ {
+ case VCSFileInfo::Added:
+ m_statusColor = &FileViewPart::vcsColors.added;
+ break;
+ case VCSFileInfo::Uptodate:
+ m_statusColor = &FileViewPart::vcsColors.updated;
+ break;
+ case VCSFileInfo::Modified:
+ m_statusColor = &FileViewPart::vcsColors.modified;
+ break;
+ case VCSFileInfo::Conflict:
+ m_statusColor = &FileViewPart::vcsColors.conflict;
+ break;
+ case VCSFileInfo::Sticky:
+ m_statusColor = &FileViewPart::vcsColors.sticky;
+ break;
+ case VCSFileInfo::NeedsCheckout:
+ m_statusColor = &FileViewPart::vcsColors.needsCheckout;
+ break;
+ case VCSFileInfo::NeedsPatch:
+ m_statusColor = &FileViewPart::vcsColors.needsPatch;
+ break;
+ case VCSFileInfo::Unknown:
+ m_statusColor = &FileViewPart::vcsColors.unknown;
+ break;
+ case VCSFileInfo::Directory:
+ default:
+ // No color change
+ m_statusColor = &FileViewPart::vcsColors.defaultColor;
+ //kdDebug() << "MyFileTreeViewItem::paintCell(): Unknown color!" << endl;
+ break;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// class VCSFileTreeBranchItem
+///////////////////////////////////////////////////////////////////////////////
+
+class VCSFileTreeBranchItem : public filetreeview::FileTreeBranchItem
+{
+public:
+ VCSFileTreeBranchItem( KFileTreeView* view, const KURL& url, const QString& name, const QPixmap& pix,
+ KDevVCSFileInfoProvider *vcsInfoProvider )
+ : FileTreeBranchItem( view, url, name, pix ), m_vcsInfoProvider( vcsInfoProvider ) {}
+// virtual ~VCSFileTreeBranchItem() {}
+ virtual KFileTreeViewItem* createTreeViewItem( KFileTreeViewItem* parent, KFileItem* fileItem );
+
+private:
+ KDevVCSFileInfoProvider *m_vcsInfoProvider;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+KFileTreeViewItem* VCSFileTreeBranchItem::createTreeViewItem( KFileTreeViewItem* parent, KFileItem* fileItem )
+{
+// kdDebug(9017) << "MyFileTreeBranch::createTreeViewItem(): " + fileItem->url().path() << endl;
+ if (!parent || !fileItem)
+ return 0;
+
+ FileTreeWidget *lv = static_cast<filetreeview::FileTreeViewItem*>( parent )->listView();
+ const KURL fileURL = fileItem->url();
+ const bool isDirectory = lv->isInProject( fileURL.path() );
+
+ VCSFileTreeViewItem *newItem = new VCSFileTreeViewItem( parent, fileItem, this, isDirectory );
+
+// QString fileName = fileURL.fileName();
+// QString dirName = URLUtil::extractPathNameRelative( lv->projectDirectory(), fileURL.directory() );
+
+// const VCSFileInfoMap &vcsFiles = *m_vcsInfoProvider->status( dirName );
+// kdDebug(9017) << "Dir has " << vcsFiles.count() << " registered files!" << endl;
+// if (vcsFiles.contains( fileName ))
+// newItem->setVCSInfo( vcsFiles[ fileName ] );
+// else
+// kdDebug(9017) << "!!!No VCS info for this file!!!" << endl;
+ return newItem;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// class VCSFileItemFactory
+///////////////////////////////////////////////////////////////////////////////
+
+class VCSBranchItemFactory : public filetreeview::BranchItemFactory
+{
+public:
+ VCSBranchItemFactory( KDevVCSFileInfoProvider *vcsInfoProvider ) : m_vcsInfoProvider( vcsInfoProvider ) {}
+ virtual filetreeview::FileTreeBranchItem *makeBranchItem( KFileTreeView* view, const KURL& url, const QString& name, const QPixmap& pix )
+ {
+ return new VCSFileTreeBranchItem( view, url, name, pix, m_vcsInfoProvider );
+ }
+private:
+ KDevVCSFileInfoProvider *m_vcsInfoProvider;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// class VCSFileTreeWidgetImpl
+///////////////////////////////////////////////////////////////////////////////
+
+VCSFileTreeWidgetImpl::VCSFileTreeWidgetImpl( FileTreeWidget *parent, KDevVCSFileInfoProvider *infoProvider )
+ : FileTreeViewWidgetImpl( parent, "vcsfiletreewidgetimpl" ),
+ m_actionToggleShowVCSFields( 0 ), m_actionSyncWithRepository( 0 ), m_vcsInfoProvider( infoProvider ),
+ m_isSyncingWithRepository( false ), m_vcsStatusRequestedItem( 0 )
+{
+ kdDebug(9017) << "VCSFileTreeWidgetImpl::VCSFileTreeWidgetImpl()" << endl;
+
+ Q_ASSERT( m_vcsInfoProvider );
+ setBranchItemFactory( new VCSBranchItemFactory( m_vcsInfoProvider ) );
+
+ // Update the #define order on top if you change this order!
+ parent->addColumn( "Filename" );
+ parent->addColumn( "Status" );
+ parent->addColumn( "Work" );
+ parent->addColumn( "Repo" );
+
+ connect( m_vcsInfoProvider, SIGNAL(statusReady(const VCSFileInfoMap&, void *)),
+ this, SLOT(vcsDirStatusReady(const VCSFileInfoMap&, void*)) );
+ // Harakiri itself if the infoProvider object is destroyed since we cannot work anymore :-(
+ connect( m_vcsInfoProvider, SIGNAL(destroyed()), SIGNAL(implementationInvalidated()) );
+
+ m_actionToggleShowVCSFields = new KToggleAction( i18n("Show VCS Fields"), KShortcut(),
+ this, "actiontoggleshowvcsfieldstoggleaction" );
+ m_actionToggleShowVCSFields->setCheckedState(i18n("Hide VCS Fields"));
+ QString aboutAction = i18n("<b>Show VCS fields</b><p>Shows <b>Revision</b> and <b>Timestamp</b> for each file contained in VCS repository.");
+ m_actionToggleShowVCSFields->setWhatsThis( aboutAction );
+ connect( m_actionToggleShowVCSFields, SIGNAL(toggled(bool)), this, SLOT(slotToggleShowVCSFields(bool)) );
+
+ m_actionSyncWithRepository = new KAction( i18n( "Sync with Repository"), KShortcut(),
+ this, SLOT(slotSyncWithRepository()), this, "actionsyncwithrepository" );
+ aboutAction = i18n("<b>Sync with repository</b><p>Synchronize file status with remote repository.");
+ m_actionSyncWithRepository->setWhatsThis( aboutAction );
+
+ QDomDocument &dom = projectDom();
+ m_actionToggleShowVCSFields->setChecked( DomUtil::readBoolEntry(dom, "/kdevfileview/tree/showvcsfields") );
+ slotToggleShowVCSFields( showVCSFields() ); // show or hide fields depending on read settings
+ connect( parent, SIGNAL(expanded(QListViewItem*)), this, SLOT(slotDirectoryExpanded(QListViewItem*)));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+VCSFileTreeWidgetImpl::~VCSFileTreeWidgetImpl()
+{
+ kdDebug(9017) << "VCSFileTreeWidgetImpl::~VCSFileTreeWidgetImpl()" << endl;
+
+ QDomDocument &dom = projectDom();
+ DomUtil::writeBoolEntry( dom, "/kdevfileview/tree/showvcsfields", showVCSFields() );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool VCSFileTreeWidgetImpl::canReloadTree() const
+{
+ return !m_isSyncingWithRepository;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void VCSFileTreeWidgetImpl::fillPopupMenu( QPopupMenu *popupMenu, QListViewItem *item ) const
+{
+ FileTreeViewWidgetImpl::fillPopupMenu( popupMenu, item );
+
+ // Submenu for visualization options
+ m_actionToggleShowVCSFields->plug( popupMenu );
+ // Give a change for syncing status with remote repository: a file info provider must
+ // be available and the item must be a project directory
+ FileTreeViewItem *fileItem = static_cast<FileTreeViewItem *>( item );
+ if (fileItem->isDir())
+ {
+ m_vcsStatusRequestedItem = fileItem;
+ popupMenu->insertSeparator();
+ m_actionSyncWithRepository->plug( popupMenu );
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void VCSFileTreeWidgetImpl::slotToggleShowVCSFields( bool checked )
+{
+ kdDebug(9017) << "VCSFileTreeWidgetImpl::slotToggleShowVCSFields()" << endl;
+
+ if (checked)
+ {
+ setColumnWidth( 0, contentsWidth() / 2 ); // "Filename"
+ setColumnWidth( 1, contentsWidth() / 4 ); // "status"
+ setColumnWidth( 2, contentsWidth() / 5 ); // "work revision"
+ setColumnWidth( 3, contentsWidth() / 5 ); // "repository revision"
+ header()->show();
+ }
+ else
+ {
+ setColumnWidth( 3 ,0 ); // Hide columns
+ setColumnWidth( 2 ,0 );
+ setColumnWidth( 1, 0 );
+ setColumnWidth( 0, contentsWidth() ); // Make the "Filename" column to occupy all the row
+ header()->hide();
+ }
+
+ triggerUpdate();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool VCSFileTreeWidgetImpl::showVCSFields() const
+{
+ return m_actionToggleShowVCSFields->isChecked();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void VCSFileTreeWidgetImpl::vcsDirStatusReady( const VCSFileInfoMap &modifiedFiles, void *callerData )
+{
+ kdDebug(9017) << "VCSFileTreeWidgetImpl::vcsDirStatusReady(const VCSFileInfoMap &, void*)" << endl;
+
+ VCSFileTreeViewItem *item = static_cast<VCSFileTreeViewItem*>( callerData );
+// Q_ASSERT( item ); // this must _not_ fail!
+ if( !item ){
+ kdDebug(9017) << "static_cast<VCSFileTreeViewItem*>( callerData ) failed" << endl;
+ return;
+ }
+ // Update vcs file info for all childs in this tree folder ...
+ item = static_cast<VCSFileTreeViewItem*>( item->firstChild() );
+ while (item)
+ {
+ const QString fileName = item->fileName();
+ kdDebug(9017) << "Widget item filename is: " << fileName << endl;
+ if (modifiedFiles.contains( fileName ))
+ {
+ const VCSFileInfo &vcsInfo = modifiedFiles[ fileName ];
+ kdDebug(9017) << "Nice! Found info for this file: " << vcsInfo.toString() << endl;
+ item->setVCSInfo( modifiedFiles[ fileName ] );
+ }
+ else
+ kdDebug(9017) << "Map does not contain anything useful about this file ;-( " << fileName << endl;
+ item = static_cast<VCSFileTreeViewItem*>( item->nextSibling() );
+ }
+ triggerUpdate();
+
+ m_isSyncingWithRepository = false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void VCSFileTreeWidgetImpl::slotSyncWithRepository()
+{
+ kdDebug(9017) << "VCSFileTreeWidgetImpl::slotSyncWithRepository()" << endl;
+ const VCSFileTreeViewItem *myFileItem = static_cast<VCSFileTreeViewItem *>( m_vcsStatusRequestedItem );
+ const QString relDirPath = URLUtil::extractPathNameRelative( projectDirectory(), myFileItem->fileItem()->url().path() );
+ kdDebug(9017) << "VCS Info requested for: " << relDirPath << endl;
+ m_vcsInfoProvider->requestStatus( relDirPath, m_vcsStatusRequestedItem );
+ m_isSyncingWithRepository = true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void VCSFileTreeWidgetImpl::slotDirectoryExpanded( QListViewItem* aItem )
+{
+ VCSFileTreeViewItem *item = static_cast<VCSFileTreeViewItem *>( aItem );
+ if( !item ) return;
+
+ const QString relDirPath = URLUtil::extractPathNameRelative( projectDirectory(), item->fileItem()->url().path() );
+ kdDebug(9017) << "ASync VCS Info requested for: " << relDirPath << endl;
+ m_vcsInfoProvider->requestStatus( relDirPath, item, false, false );
+
+// m_isSyncingWithRepository = true;
+
+}
+
+#include "vcsfiletreewidgetimpl.moc"