/* ====================================================================
* Copyright (c) 2003-2006, Martin Hauner
* http://subcommander.tigris.org
*
* Subcommander is licensed as described in the file doc/COPYING, which
* you should have received as part of this distribution.
* ====================================================================
*/
//sc
#include "config.h"
#include "RepositoryLvi.h"
#include "ListWidget.h"
#include "ScModel.h"
#include "Project.h"
#include "ActionStorage.h"
#include "CheckoutDialog.h"
#include "DiffDialog.h"
#include "LogDialog.h"
#include "SwitchDialog.h"
#include "RepositoryModel.h"
#include "CursorSupport.h"
#include "ErrorSupport.h"
#include "PostCmdResult.h"
#include "ExternProviderImpl.h"
#include "ColorId.h"
#include "ProjectLvi.h"
#include "ProjectFoldersWidget.h"
#include "DragDropMimeTypes.h"
#include "ProjectItemDragObject.h"
#include "dialogs/CopyDialogCmd.h"
#include "dialogs/CheckoutDialogCmd.h"
#include "commands/ScCmd.h"
#include "commands/CheckoutParam.h"
#include "commands/ListParam.h"
#include "commands/DiffParam.h"
#include "commands/SwitchParam.h"
#include "events/DialogEvent.h"
#include "events/LviOnItemEvent.h"
#include "events/EventSupport.h"
#include "sublib/ColorStorage.h"
#include "sublib/StringUtil.h"
#include "sublib/Utility.h"
#include "sublib/MessageBox.h"
#include "svn/ClientTypes.h"
#include "svn/Revision.h"
#include "svn/Error.h"
#include "util/Id.h"
#include "util/Guard.h"
#include "util/Compare.h"
// qt
#include <qpopupmenu.h>
#include <qdragobject.h>
#include <qclipboard.h>
#include <qapplication.h>
#include <qlineedit.h>
#include <qpainter.h>
#include <qcursor.h>
#include <qfiledialog.h>
#include <qaction.h>
// sys
#include <assert.h>
enum Actions
{
ActionCheckout,
ActionSwitch,
ActionDiff,
ActionLog,
ActionBranch,
ActionTag,
ItemActionEdit,
ItemActionRemove
};
static ActionStorage _actions;
static QPopupMenu* _menu = NULL;
RepositoryLvi::RepositoryLvi( QListViewItem* parent, RepositoryModel* rmodel,
Project* prj, const Project::Item& item )
: super(parent,""), _rpModel(rmodel), _prj(prj), _item(item), _root(true)
{
init( QString::fromUtf8(_item.getName()) );
}
RepositoryLvi::RepositoryLvi( RepositoryLvi* parent, RepositoryModel* rmodel,
Project* prj, QString repPath )
: super(parent,repPath), _rpModel(rmodel), _prj(prj), _root(false)
{
init( repPath );
}
RepositoryLvi::~RepositoryLvi()
{
}
void RepositoryLvi::setupActions( ProjectFoldersWidget* parent )
{
QAction* action;
action = new QAction( _q("&checkout.."), _q("Ctrl+Shift+C"), parent );
action->setStatusTip( _q("checkout a working copy from a repository") );
action->setEnabled(false);
parent->connect( action, SIGNAL(activated()), SLOT(checkout()) );
_actions.addAction( ActionCheckout, action );
action = new QAction( _q("&switch to.."), _q("Ctrl+Shift+S"), parent );
action->setStatusTip( _q("switch working copy to the selected repository url") );
action->setEnabled(false);
parent->connect( action, SIGNAL(activated()), SLOT(switchx()) );
_actions.addAction( ActionSwitch, action );
action = new QAction( _q("&diff.."), _q("Ctrl+Shift+D"), parent );
action->setStatusTip( _q("show the differences between repository paths") );
action->setEnabled(false);
parent->connect( action, SIGNAL(activated()), SLOT(diff()) );
_actions.addAction( ActionDiff, action );
action = new QAction( _q("&log.."), _q("Ctrl+Shift+L"), parent );
action->setStatusTip( _q("view the log history of the selected url") );
action->setEnabled(false);
parent->connect( action, SIGNAL(activated()), SLOT(log()) );
_actions.addAction( ActionLog, action );
action = new QAction( _q("&branch.."), _q("Ctrl+Shift+B"), parent );
action->setStatusTip( _q("create a branch from the selected repository url") );
action->setEnabled(false);
parent->connect( action, SIGNAL(activated()), SLOT(branch()) );
_actions.addAction( ActionBranch, action );
action = new QAction( _q("&tag.."), _q("Ctrl+Shift+T"), parent );
action->setStatusTip( _q("create a tag from the selected repository url") );
action->setEnabled(false);
parent->connect( action, SIGNAL(activated()), SLOT(tag()) );
_actions.addAction( ActionTag, action );
action = new QAction( _q("&edit.."), _q("Ctrl+E"), parent );
action->setStatusTip( _q("edit repository configuration") );
action->setEnabled(false);
parent->connect( action, SIGNAL(activated()), SLOT(editRpPrjItem()) );
_actions.addAction( ItemActionEdit, action );
action = new QAction( _q("&delete"), _q("CTRL+D"), parent );
action->setStatusTip( _q("delete repository") );
action->setEnabled(false);
parent->connect( action, SIGNAL(activated()), SLOT(delRpPrjItem()) );
_actions.addAction( ItemActionRemove, action );
{
_menu = new QPopupMenu(parent);
QAction* action;
action = _actions.getAction( ActionLog );
action->addTo(_menu);
_menu->insertSeparator();
action = _actions.getAction( ActionBranch );
action->addTo(_menu);
action = _actions.getAction( ActionTag );
action->addTo(_menu);
_menu->insertSeparator();
action = _actions.getAction( ActionCheckout );
action->addTo(_menu);
action = _actions.getAction( ActionSwitch );
action->addTo(_menu);
//action = _actions.getAction( ActionDiff );
//action->addTo(_menu);
_menu->insertSeparator();
action = _actions.getAction( ItemActionEdit );
action->addTo(_menu);
action = _actions.getAction( ItemActionRemove );
action->addTo(_menu);
}
}
QPopupMenu* RepositoryLvi::getMenu()
{
return _menu;
}
void RepositoryLvi::init( const QString& text )
{
setText( 0, text );
setPixmap( 0, QPixmap(getIconDir() + "BookmarkRepository.png") );
}
QString RepositoryLvi::getUrl() const
{
return QString::fromUtf8(_item.getSource());
}
QString RepositoryLvi::text( int column ) const
{
switch( column )
{
case 1:
{
if( isRoot() )
{
sc::String sRev = _item.getRevision()->toString();
QString qRev = QString("<@ %1>").arg((const char*)sRev);
return qRev;
}
break;
}
}
return super::text(column);
}
int RepositoryLvi::compare( QListViewItem* i, int col, bool ascending ) const
{
ScLvi* lvi = dynamic_cast<ScLvi*>(i);
if( lvi )
{
if( isRoot() )
{
return compare3( getSortPos(), lvi->getSortPos() );
}
else
{
return sc::compare( text(0), lvi->text(0) );
}
}
else
{
return super::compare(i,col,ascending);
}
}
bool RepositoryLvi::acceptDrop( const QMimeSource* mime ) const
{
return mime->provides( ScMimeTypeRepository )
|| mime->provides( ScMimeTypeWorkingCopy );
}
void RepositoryLvi::dropped( QDropEvent* e )
{
ProjectItem prjItem;
ProjectItemDragObject::decode(e,prjItem);
if( ! (prjItem._prjId == _prj->getId()) || prjItem._itemId == _item.getId() )
{
return;
}
_prj->moveItem( prjItem._itemId, _item.getId() );
((ProjectLvi*)parent())->updateBookmarks();
_rpModel->saveProject(_prj);
}
QDragObject* RepositoryLvi::dragObject()
{
ProjectItem prjItem(_prj->getId(),_item.getId());
return new ProjectItemDragObject( ScMimeTypeRepository, listView(), prjItem );
}
void RepositoryLvi::paintFocus( QPainter * p, const QColorGroup & cg, const QRect & r )
{
super::paintFocus(p,cg,r);
//if( isRunning() )
//{
//p->setPen( QColor(255,255,0) );
//p->drawRect( r );
//}
}
void RepositoryLvi::paintCell( QPainter *p, const QColorGroup & cg, int column, int width, int alignment )
{
QColorGroup g(cg);
if( column == 1 )
{
g.setColor( QColorGroup::Text, ColorStorage::getColor(ColorFaded) );
g.setColor( QColorGroup::HighlightedText, ColorStorage::getColor(ColorFaded) );
}
super::paintCell(p,g,column,width,alignment);
}
void RepositoryLvi::onItem()
{
postEvent( getTidObj(), new LviOnItemEvent(getRepositoryUrl()) );
}
void RepositoryLvi::pressed( bool refresh )
{
// TODO replace with visitor
ProjectFoldersWidget* pfw = dynamic_cast<ProjectFoldersWidget*>(listView());
pfw->list( getId(), _item.getSource(), _item.getRevision(), _prj );
}
void RepositoryLvi::renamed( const QString& text )
{
_item.setName( sc::String(text.utf8()) );
_prj->setItem(_item);
}
#if 0
case mCopy:
{
// TODO
QTextDrag* qtd = new QTextDrag( _repPath );
qtd->setSubtype( "utf8" );
QApplication::clipboard()->setData( qtd );
break;
}
#endif
void RepositoryLvi::contextMenuRequest( const QPoint& pos, int col )
{
_menu->exec(pos);
}
long RepositoryLvi::getSortPos() const
{
return _item.getSortPos();
}
bool RepositoryLvi::isRoot() const
{
return _root;
}
QString RepositoryLvi::getRepositoryUrl() const
{
if( isRoot() )
{
return getUrl();
}
else
{
return ((RepositoryLvi*)parent())->getRepositoryUrl() + "/" + text(0);
}
}
Project* RepositoryLvi::getProject() const
{
return _prj;
}
const Project::Item& RepositoryLvi::getProjectItem() const
{
return _item;
}
void RepositoryLvi::setProjectItem( const Project::Item& item )
{
_item = item;
init( QString::fromUtf8(_item.getName()) );
}
#if 0
// experimental
svn::Revnumber rev;
svn::Client* svn = getModel()->getClient();
svn::Error* err = svn->getHeadRevision( &rev, getRepositoryUrl().utf8() );
// experimental
#endif
void RepositoryLvi::checkout()
{
CheckoutDialogCmd co( listView(), getTid(), _rpModel );
QString srcPath(getRepositoryUrl());
QString dstPath = QString::fromUtf8(_prj->getCurWorkingCopyPath());
co.run( srcPath, dstPath, _prj );
ProjectLvi* prjlvi = getProjectLvi();
prjlvi->refresh();
}
void RepositoryLvi::switchx()
{
ExternProviderImpl externProvider(_rpModel);
SwitchDialog* dlg = new SwitchDialog(&externProvider,
_rpModel->isCmdRecursive(),listView());
dlg->enableRepositoryUrl(false);
QString url = getRepositoryUrl();
dlg->setRepositoryUrl(url);
QString wc = QString::fromUtf8(_prj->getCurWorkingCopyPath());
dlg->setWorkingCopyPath(wc);
int result = dlg->exec();
if( result != QDialog::Accepted )
{
return;
}
SwitchParam* param = new SwitchParam(sc::String(dlg->getWorkingCopyPath()),
sc::String(getRepositoryUrl().utf8()), dlg->getRevision(), dlg->isRecursive() );
PostCmdResult* pcres = new PostCmdResult( getTidObj() );
_rpModel->switchx( param, pcres );
}
void RepositoryLvi::diff( RepositoryLvi* lvi )
{
RepositoryLvi* secondLvi = 0;
if( lvi && !(lvi->getProject()->getId() == getProject()->getId()) )
{
msgWarning( _q("subcommander [diff]"),
_q("You can't run diff across project boundaries!"), _q("&Ok") );
return;
}
if( lvi && lvi != this )
{
secondLvi = lvi;
}
DiffDialog* dlg = new DiffDialog( _rpModel, true, new ExternProviderImpl(_rpModel), 0 );
QString url = getRepositoryUrl();
dlg->enablePathOrUrl1(false);
dlg->setPathOrUrl1(url);
dlg->setPathOrUrl2(url);
if( secondLvi )
{
QString url2 = secondLvi->getRepositoryUrl();
dlg->enablePathOrUrl2(true);
dlg->setPathOrUrl2(url2);
}
dlg->show();
}
void RepositoryLvi::log()
{
LogDialog* ldlg = new LogDialog( _rpModel, getProject(),
sc::String(getRepositoryUrl().utf8()), true );
ldlg->show();
}
void RepositoryLvi::branch()
{
CopyDialogCmd copy( listView(), getTid(), _rpModel );
QString srcPath(getRepositoryUrl());
QString dstPath(QString::fromUtf8(_prj->getBranchesUrl()));
copy.run( srcPath, dstPath );
}
void RepositoryLvi::tag()
{
CopyDialogCmd copy( listView(), getTid(), _rpModel );
QString srcPath(getRepositoryUrl());
QString dstPath(QString::fromUtf8(_prj->getTagsUrl().getStr()));
copy.run( srcPath, dstPath );
}
void RepositoryLvi::enableActions()
{
_actions.enableActions();
_actions.enableAction( ItemActionRemove, _item.isRepository() );
}
void RepositoryLvi::disableActions()
{
_actions.disableActions();
}
syntax highlighted by Code2HTML, v. 0.9.1